1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2020 Joël Krähemann
3 *
4 * This file is part of GSequencer.
5 *
6 * GSequencer is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GSequencer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GSequencer. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <ags/object/ags_sequencer.h>
21
22 void ags_sequencer_class_init(AgsSequencerInterface *ginterface);
23
24 /**
25 * SECTION:ags_sequencer
26 * @short_description: unique access to sequencers
27 * @title: AgsSequencer
28 * @section_id: AgsSequencer
29 * @include: ags/object/ags_sequencer.h
30 *
31 * The #AgsSequencer interface gives you a unique access to MIDI devices.
32 */
33
34 GType
ags_sequencer_get_type()35 ags_sequencer_get_type()
36 {
37 static volatile gsize g_define_type_id__volatile = 0;
38
39 if(g_once_init_enter (&g_define_type_id__volatile)){
40 GType ags_type_sequencer = 0;
41
42 ags_type_sequencer = g_type_register_static_simple(G_TYPE_INTERFACE,
43 "AgsSequencer",
44 sizeof(AgsSequencerInterface),
45 (GClassInitFunc) ags_sequencer_class_init,
46 0, NULL, 0);
47
48 g_once_init_leave(&g_define_type_id__volatile, ags_type_sequencer);
49 }
50
51 return g_define_type_id__volatile;
52 }
53
54 GQuark
ags_sequencer_error_quark()55 ags_sequencer_error_quark()
56 {
57 return(g_quark_from_static_string("ags-sequencer-error-quark"));
58 }
59
60 void
ags_sequencer_class_init(AgsSequencerInterface * ginterface)61 ags_sequencer_class_init(AgsSequencerInterface *ginterface)
62 {
63 /**
64 * AgsSequencer::tic:
65 * @sequencer: the #AgsSequencer object
66 *
67 * The ::tic signal is emitted every tic of the sequencer. This notifies
68 * about a newly played buffer.
69 *
70 * Since: 3.0.0
71 */
72 g_signal_new("tic",
73 G_TYPE_FROM_INTERFACE(ginterface),
74 G_SIGNAL_RUN_LAST,
75 G_STRUCT_OFFSET(AgsSequencerInterface, tic),
76 NULL, NULL,
77 g_cclosure_marshal_VOID__VOID,
78 G_TYPE_NONE, 0);
79
80 /**
81 * AgsSequencer::offset-changed:
82 * @sequencer: the #AgsSequencer object
83 * @note_offset: new notation offset
84 *
85 * The ::offset-changed signal notifies about changed position within
86 * notation.
87 *
88 * Since: 3.0.0
89 */
90 g_signal_new("offset-changed",
91 G_TYPE_FROM_INTERFACE(ginterface),
92 G_SIGNAL_RUN_LAST,
93 G_STRUCT_OFFSET(AgsSequencerInterface, offset_changed),
94 NULL, NULL,
95 g_cclosure_marshal_VOID__UINT,
96 G_TYPE_NONE, 1,
97 G_TYPE_UINT);
98 }
99
100 /**
101 * ags_sequencer_set_device:
102 * @sequencer: the #AgsSequencer
103 * @card_id: the device to set
104 *
105 * Set device.
106 *
107 * Since: 3.0.0
108 */
109 void
ags_sequencer_set_device(AgsSequencer * sequencer,gchar * card_id)110 ags_sequencer_set_device(AgsSequencer *sequencer,
111 gchar *card_id)
112 {
113 AgsSequencerInterface *sequencer_interface;
114
115 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
116 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
117 g_return_if_fail(sequencer_interface->set_device);
118 sequencer_interface->set_device(sequencer,
119 card_id);
120 }
121
122 /**
123 * ags_sequencer_get_device:
124 * @sequencer: the #AgsSequencer
125 *
126 * Get device.
127 *
128 * Returns: the device's identifier
129 *
130 * Since: 3.0.0
131 */
132 gchar*
ags_sequencer_get_device(AgsSequencer * sequencer)133 ags_sequencer_get_device(AgsSequencer *sequencer)
134 {
135 AgsSequencerInterface *sequencer_interface;
136
137 g_return_val_if_fail(AGS_IS_SEQUENCER(sequencer), NULL);
138 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
139 g_return_val_if_fail(sequencer_interface->get_device, NULL);
140
141 return(sequencer_interface->get_device(sequencer));
142 }
143
144 /**
145 * ags_sequencer_list_cards:
146 * @sequencer: the #AgsSequencer
147 * @card_id: (element-type utf8) (out callee-allocates) (array zero-terminated=1) (transfer full): a list containing card ids
148 * @card_name: (element-type utf8) (out callee-allocates) (array zero-terminated=1) (transfer full): a list containing card names
149 *
150 * Retrieve @card_id and @card_name as a list of strings.
151 *
152 * Since: 3.0.0
153 */
154 void
ags_sequencer_list_cards(AgsSequencer * sequencer,GList ** card_id,GList ** card_name)155 ags_sequencer_list_cards(AgsSequencer *sequencer,
156 GList **card_id, GList **card_name)
157 {
158 AgsSequencerInterface *sequencer_interface;
159
160 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
161 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
162 g_return_if_fail(sequencer_interface->list_cards);
163 sequencer_interface->list_cards(sequencer, card_id, card_name);
164 }
165
166 /**
167 * ags_sequencer_is_starting:
168 * @sequencer: the #AgsSequencer
169 *
170 * Get starting.
171 *
172 * Returns: %TRUE if starting, else %FALSE
173 *
174 * Since: 3.0.0
175 */
176 gboolean
ags_sequencer_is_starting(AgsSequencer * sequencer)177 ags_sequencer_is_starting(AgsSequencer *sequencer)
178 {
179 AgsSequencerInterface *sequencer_interface;
180
181 g_return_val_if_fail(AGS_IS_SEQUENCER(sequencer), FALSE);
182 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
183 g_return_val_if_fail(sequencer_interface->is_starting, FALSE);
184
185 return(sequencer_interface->is_starting(sequencer));
186 }
187
188 /**
189 * ags_sequencer_is_playing:
190 * @sequencer: the #AgsSequencer
191 *
192 * Get playing.
193 *
194 * Returns: %TRUE if playing, else %FALSE
195 *
196 * Since: 3.0.0
197 */
198 gboolean
ags_sequencer_is_playing(AgsSequencer * sequencer)199 ags_sequencer_is_playing(AgsSequencer *sequencer)
200 {
201 AgsSequencerInterface *sequencer_interface;
202
203 g_return_val_if_fail(AGS_IS_SEQUENCER(sequencer), FALSE);
204 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
205 g_return_val_if_fail(sequencer_interface->is_playing, FALSE);
206
207 return(sequencer_interface->is_playing(sequencer));
208 }
209
210 /**
211 * ags_sequencer_is_recording:
212 * @sequencer: the #AgsSequencer
213 *
214 * Get recording.
215 *
216 * Returns: %TRUE if recording, else %FALSE
217 *
218 * Since: 3.0.0
219 */
220 gboolean
ags_sequencer_is_recording(AgsSequencer * sequencer)221 ags_sequencer_is_recording(AgsSequencer *sequencer)
222 {
223 AgsSequencerInterface *sequencer_interface;
224
225 g_return_val_if_fail(AGS_IS_SEQUENCER(sequencer), FALSE);
226 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
227 g_return_val_if_fail(sequencer_interface->is_recording, FALSE);
228
229 return(sequencer_interface->is_recording(sequencer));
230 }
231
232 /**
233 * ags_sequencer_play_init:
234 * @sequencer: the #AgsSequencer
235 * @error: an error that may occure
236 *
237 * Initializes the sequencer for playback.
238 *
239 * Since: 3.0.0
240 */
241 void
ags_sequencer_play_init(AgsSequencer * sequencer,GError ** error)242 ags_sequencer_play_init(AgsSequencer *sequencer,
243 GError **error)
244 {
245 AgsSequencerInterface *sequencer_interface;
246
247 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
248 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
249 g_return_if_fail(sequencer_interface->play_init);
250 sequencer_interface->play_init(sequencer,
251 error);
252 }
253
254 /**
255 * ags_sequencer_play:
256 * @sequencer: the #AgsSequencer
257 * @error: an error that may occure
258 *
259 * Plays the current buffer of sequencer.
260 *
261 * Since: 3.0.0
262 */
263 void
ags_sequencer_play(AgsSequencer * sequencer,GError ** error)264 ags_sequencer_play(AgsSequencer *sequencer,
265 GError **error)
266 {
267 AgsSequencerInterface *sequencer_interface;
268
269 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
270 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
271 g_return_if_fail(sequencer_interface->play);
272 sequencer_interface->play(sequencer,
273 error);
274 }
275
276 /**
277 * ags_sequencer_record_init:
278 * @sequencer: the #AgsSequencer
279 * @error: an error that may occure
280 *
281 * Initializes the sequencer for recording.
282 *
283 * Since: 3.0.0
284 */
285 void
ags_sequencer_record_init(AgsSequencer * sequencer,GError ** error)286 ags_sequencer_record_init(AgsSequencer *sequencer,
287 GError **error)
288 {
289 AgsSequencerInterface *sequencer_interface;
290
291 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
292 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
293 g_return_if_fail(sequencer_interface->record_init);
294 sequencer_interface->record_init(sequencer,
295 error);
296 }
297
298 /**
299 * ags_sequencer_record:
300 * @sequencer: the #AgsSequencer
301 * @error: an error that may occure
302 *
303 * Records the current buffer of sequencer.
304 *
305 * Since: 3.0.0
306 */
307 void
ags_sequencer_record(AgsSequencer * sequencer,GError ** error)308 ags_sequencer_record(AgsSequencer *sequencer,
309 GError **error)
310 {
311 AgsSequencerInterface *sequencer_interface;
312
313 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
314 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
315 g_return_if_fail(sequencer_interface->record);
316 sequencer_interface->record(sequencer,
317 error);
318 }
319
320 /**
321 * ags_sequencer_stop:
322 * @sequencer: the #AgsSequencer
323 *
324 * Stops the sequencer from playing to it.
325 *
326 * Since: 3.0.0
327 */
328 void
ags_sequencer_stop(AgsSequencer * sequencer)329 ags_sequencer_stop(AgsSequencer *sequencer)
330 {
331 AgsSequencerInterface *sequencer_interface;
332
333 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
334 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
335 g_return_if_fail(sequencer_interface->stop);
336 sequencer_interface->stop(sequencer);
337 }
338
339 /**
340 * ags_sequencer_tic:
341 * @sequencer: the #AgsSequencer
342 *
343 * Every call to play may generate a tic.
344 *
345 * Since: 3.0.0
346 */
347 void
ags_sequencer_tic(AgsSequencer * sequencer)348 ags_sequencer_tic(AgsSequencer *sequencer)
349 {
350 AgsSequencerInterface *sequencer_interface;
351
352 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
353 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
354 g_return_if_fail(sequencer_interface->tic);
355 sequencer_interface->tic(sequencer);
356 }
357
358 /**
359 * ags_sequencer_offset_changed:
360 * @sequencer: the #AgsSequencer
361 * @note_offset: the note offset
362 *
363 * Callback when counter expires minor note offset.
364 *
365 * Since: 3.0.0
366 */
367 void
ags_sequencer_offset_changed(AgsSequencer * sequencer,guint note_offset)368 ags_sequencer_offset_changed(AgsSequencer *sequencer,
369 guint note_offset)
370 {
371 AgsSequencerInterface *sequencer_interface;
372
373 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
374 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
375 g_return_if_fail(sequencer_interface->offset_changed);
376 sequencer_interface->offset_changed(sequencer,
377 note_offset);
378 }
379
380 /**
381 * ags_sequencer_get_buffer:
382 * @sequencer: the #AgsSequencer
383 * @buffer_length: the buffer's length
384 *
385 * Get current playback buffer.
386 *
387 * Returns: current playback buffer
388 *
389 * Since: 3.0.0
390 */
391 void*
ags_sequencer_get_buffer(AgsSequencer * sequencer,guint * buffer_length)392 ags_sequencer_get_buffer(AgsSequencer *sequencer,
393 guint *buffer_length)
394 {
395 AgsSequencerInterface *sequencer_interface;
396
397 g_return_val_if_fail(AGS_IS_SEQUENCER(sequencer), NULL);
398 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
399 g_return_val_if_fail(sequencer_interface->get_buffer, NULL);
400
401 return(sequencer_interface->get_buffer(sequencer,
402 buffer_length));
403 }
404
405 /**
406 * ags_sequencer_get_next_buffer:
407 * @sequencer: the #AgsSequencer
408 * @buffer_length: the buffer's length
409 *
410 * Get future playback buffer.
411 *
412 * Returns: next playback buffer
413 *
414 * Since: 3.0.0
415 */
416 void*
ags_sequencer_get_next_buffer(AgsSequencer * sequencer,guint * buffer_length)417 ags_sequencer_get_next_buffer(AgsSequencer *sequencer,
418 guint *buffer_length)
419 {
420 AgsSequencerInterface *sequencer_interface;
421
422 g_return_val_if_fail(AGS_IS_SEQUENCER(sequencer), NULL);
423 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
424 g_return_val_if_fail(sequencer_interface->get_next_buffer, NULL);
425
426 return(sequencer_interface->get_next_buffer(sequencer,
427 buffer_length));
428 }
429
430 /**
431 * ags_sequencer_lock_buffer:
432 * @sequencer: the #AgsSequencer
433 * @buffer: the buffer to lock
434 *
435 * Lock @buffer.
436 *
437 * Since: 3.0.0
438 */
439 void
ags_sequencer_lock_buffer(AgsSequencer * sequencer,void * buffer)440 ags_sequencer_lock_buffer(AgsSequencer *sequencer,
441 void *buffer)
442 {
443 AgsSequencerInterface *sequencer_interface;
444
445 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
446 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
447 g_return_if_fail(sequencer_interface->lock_buffer);
448
449 sequencer_interface->lock_buffer(sequencer,
450 buffer);
451 }
452
453 /**
454 * ags_sequencer_unlock_buffer:
455 * @sequencer: the #AgsSequencer
456 * @buffer: the buffer to unlock
457 *
458 * Unlock @buffer.
459 *
460 * Since: 3.0.0
461 */
462 void
ags_sequencer_unlock_buffer(AgsSequencer * sequencer,void * buffer)463 ags_sequencer_unlock_buffer(AgsSequencer *sequencer,
464 void *buffer)
465 {
466 AgsSequencerInterface *sequencer_interface;
467
468 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
469 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
470 g_return_if_fail(sequencer_interface->unlock_buffer);
471
472 sequencer_interface->unlock_buffer(sequencer,
473 buffer);
474 }
475
476 /**
477 * ags_sequencer_set_bpm:
478 * @sequencer: the #AgsSequencer
479 * @bpm: the bpm to set
480 *
481 * Set current playback bpm.
482 *
483 * Since: 3.0.0
484 */
485 void
ags_sequencer_set_bpm(AgsSequencer * sequencer,gdouble bpm)486 ags_sequencer_set_bpm(AgsSequencer *sequencer,
487 gdouble bpm)
488 {
489 AgsSequencerInterface *sequencer_interface;
490
491 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
492 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
493 g_return_if_fail(sequencer_interface->set_bpm);
494 sequencer_interface->set_bpm(sequencer,
495 bpm);
496 }
497
498 /**
499 * ags_sequencer_get_bpm:
500 * @sequencer: the #AgsSequencer
501 *
502 * Get current playback bpm.
503 *
504 * Returns: bpm
505 *
506 * Since: 3.0.0
507 */
508 gdouble
ags_sequencer_get_bpm(AgsSequencer * sequencer)509 ags_sequencer_get_bpm(AgsSequencer *sequencer)
510 {
511 AgsSequencerInterface *sequencer_interface;
512
513 g_return_val_if_fail(AGS_IS_SEQUENCER(sequencer), G_MAXUINT);
514 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
515 g_return_val_if_fail(sequencer_interface->get_bpm, G_MAXUINT);
516
517 return(sequencer_interface->get_bpm(sequencer));
518 }
519
520 /**
521 * ags_sequencer_set_delay_factor:
522 * @sequencer: the #AgsSequencer
523 * @delay_factor: the delay factor to set
524 *
525 * Set current playback delay factor.
526 *
527 * Since: 3.0.0
528 */
529 void
ags_sequencer_set_delay_factor(AgsSequencer * sequencer,gdouble delay_factor)530 ags_sequencer_set_delay_factor(AgsSequencer *sequencer,
531 gdouble delay_factor)
532 {
533 AgsSequencerInterface *sequencer_interface;
534
535 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
536 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
537 g_return_if_fail(sequencer_interface->set_delay_factor);
538 sequencer_interface->set_delay_factor(sequencer,
539 delay_factor);
540 }
541
542 /**
543 * ags_sequencer_get_delay_factor:
544 * @sequencer: the #AgsSequencer
545 *
546 * Get current playback delay factor.
547 *
548 * Returns: delay factor
549 *
550 * Since: 3.0.0
551 */
552 gdouble
ags_sequencer_get_delay_factor(AgsSequencer * sequencer)553 ags_sequencer_get_delay_factor(AgsSequencer *sequencer)
554 {
555 AgsSequencerInterface *sequencer_interface;
556
557 g_return_val_if_fail(AGS_IS_SEQUENCER(sequencer), G_MAXUINT);
558 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
559 g_return_val_if_fail(sequencer_interface->get_delay_factor, G_MAXUINT);
560
561 return(sequencer_interface->get_delay_factor(sequencer));
562 }
563
564 /**
565 * ags_sequencer_get_start_note_offset:
566 * @sequencer: the #AgsSequencer
567 *
568 * Get start playback note offset.
569 *
570 * Returns: the start note offset
571 *
572 * Since: 3.0.0
573 */
574 guint
ags_sequencer_get_start_note_offset(AgsSequencer * sequencer)575 ags_sequencer_get_start_note_offset(AgsSequencer *sequencer)
576 {
577 AgsSequencerInterface *sequencer_interface;
578
579 g_return_val_if_fail(AGS_IS_SEQUENCER(sequencer), G_MAXUINT);
580 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
581 g_return_val_if_fail(sequencer_interface->get_start_note_offset, G_MAXUINT);
582
583 return(sequencer_interface->get_start_note_offset(sequencer));
584 }
585
586 /**
587 * ags_sequencer_set_start_note_offset:
588 * @sequencer: the #AgsSequencer
589 * @start_note_offset: the start note offset to set
590 *
591 * Set start playback note offset.
592 *
593 * Since: 3.0.0
594 */
595 void
ags_sequencer_set_start_note_offset(AgsSequencer * sequencer,guint start_note_offset)596 ags_sequencer_set_start_note_offset(AgsSequencer *sequencer,
597 guint start_note_offset)
598 {
599 AgsSequencerInterface *sequencer_interface;
600
601 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
602 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
603 g_return_if_fail(sequencer_interface->set_start_note_offset);
604 sequencer_interface->set_start_note_offset(sequencer,
605 start_note_offset);
606 }
607
608 /**
609 * ags_sequencer_get_note_offset:
610 * @sequencer: the #AgsSequencer
611 *
612 * Get current playback note offset.
613 *
614 * Returns: offset
615 *
616 * Since: 3.0.0
617 */
618 guint
ags_sequencer_get_note_offset(AgsSequencer * sequencer)619 ags_sequencer_get_note_offset(AgsSequencer *sequencer)
620 {
621 AgsSequencerInterface *sequencer_interface;
622
623 g_return_val_if_fail(AGS_IS_SEQUENCER(sequencer), G_MAXUINT);
624 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
625 g_return_val_if_fail(sequencer_interface->get_note_offset, G_MAXUINT);
626
627 return(sequencer_interface->get_note_offset(sequencer));
628 }
629
630 /**
631 * ags_sequencer_set_note_offset:
632 * @sequencer: the #AgsSequencer
633 * @note_offset: the note offset to set
634 *
635 * Set current playback note offset.
636 *
637 * Since: 3.0.0
638 */
639 void
ags_sequencer_set_note_offset(AgsSequencer * sequencer,guint note_offset)640 ags_sequencer_set_note_offset(AgsSequencer *sequencer,
641 guint note_offset)
642 {
643 AgsSequencerInterface *sequencer_interface;
644
645 g_return_if_fail(AGS_IS_SEQUENCER(sequencer));
646 sequencer_interface = AGS_SEQUENCER_GET_INTERFACE(sequencer);
647 g_return_if_fail(sequencer_interface->set_note_offset);
648 sequencer_interface->set_note_offset(sequencer,
649 note_offset);
650 }
651