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/audio/core-audio/ags_core_audio_devin.h>
21
22 #include <ags/audio/ags_sound_provider.h>
23 #include <ags/audio/ags_soundcard_util.h>
24 #include <ags/audio/ags_audio_buffer_util.h>
25
26 #include <ags/audio/core-audio/ags_core_audio_server.h>
27 #include <ags/audio/core-audio/ags_core_audio_client.h>
28 #include <ags/audio/core-audio/ags_core_audio_port.h>
29
30 #include <ags/audio/task/ags_tic_device.h>
31 #include <ags/audio/task/ags_clear_buffer.h>
32 #include <ags/audio/task/ags_switch_buffer_flag.h>
33
34 #include <ags/audio/thread/ags_audio_loop.h>
35
36 #include <string.h>
37 #include <math.h>
38 #include <time.h>
39
40 #include <ags/config.h>
41 #include <ags/i18n.h>
42
43 void ags_core_audio_devin_class_init(AgsCoreAudioDevinClass *core_audio_devin);
44 void ags_core_audio_devin_connectable_interface_init(AgsConnectableInterface *connectable);
45 void ags_core_audio_devin_soundcard_interface_init(AgsSoundcardInterface *soundcard);
46 void ags_core_audio_devin_init(AgsCoreAudioDevin *core_audio_devin);
47 void ags_core_audio_devin_set_property(GObject *gobject,
48 guint prop_id,
49 const GValue *value,
50 GParamSpec *param_spec);
51 void ags_core_audio_devin_get_property(GObject *gobject,
52 guint prop_id,
53 GValue *value,
54 GParamSpec *param_spec);
55 void ags_core_audio_devin_dispose(GObject *gobject);
56 void ags_core_audio_devin_finalize(GObject *gobject);
57
58 AgsUUID* ags_core_audio_devin_get_uuid(AgsConnectable *connectable);
59 gboolean ags_core_audio_devin_has_resource(AgsConnectable *connectable);
60 gboolean ags_core_audio_devin_is_ready(AgsConnectable *connectable);
61 void ags_core_audio_devin_add_to_registry(AgsConnectable *connectable);
62 void ags_core_audio_devin_remove_from_registry(AgsConnectable *connectable);
63 xmlNode* ags_core_audio_devin_list_resource(AgsConnectable *connectable);
64 xmlNode* ags_core_audio_devin_xml_compose(AgsConnectable *connectable);
65 void ags_core_audio_devin_xml_parse(AgsConnectable *connectable,
66 xmlNode *node);
67 gboolean ags_core_audio_devin_is_connected(AgsConnectable *connectable);
68 void ags_core_audio_devin_connect(AgsConnectable *connectable);
69 void ags_core_audio_devin_disconnect(AgsConnectable *connectable);
70
71 void ags_core_audio_devin_set_device(AgsSoundcard *soundcard,
72 gchar *device);
73 gchar* ags_core_audio_devin_get_device(AgsSoundcard *soundcard);
74
75 void ags_core_audio_devin_set_presets(AgsSoundcard *soundcard,
76 guint channels,
77 guint rate,
78 guint buffer_size,
79 guint format);
80 void ags_core_audio_devin_get_presets(AgsSoundcard *soundcard,
81 guint *channels,
82 guint *rate,
83 guint *buffer_size,
84 guint *format);
85
86 void ags_core_audio_devin_list_cards(AgsSoundcard *soundcard,
87 GList **card_id, GList **card_name);
88 void ags_core_audio_devin_pcm_info(AgsSoundcard *soundcard, gchar *card_id,
89 guint *channels_min, guint *channels_max,
90 guint *rate_min, guint *rate_max,
91 guint *buffer_size_min, guint *buffer_size_max,
92 GError **error);
93 guint ags_core_audio_devin_get_capability(AgsSoundcard *soundcard);
94
95 gboolean ags_core_audio_devin_is_starting(AgsSoundcard *soundcard);
96 gboolean ags_core_audio_devin_is_recording(AgsSoundcard *soundcard);
97
98 gchar* ags_core_audio_devin_get_uptime(AgsSoundcard *soundcard);
99
100 void ags_core_audio_devin_port_init(AgsSoundcard *soundcard,
101 GError **error);
102 void ags_core_audio_devin_port_record(AgsSoundcard *soundcard,
103 GError **error);
104 void ags_core_audio_devin_port_free(AgsSoundcard *soundcard);
105
106 void ags_core_audio_devin_tic(AgsSoundcard *soundcard);
107 void ags_core_audio_devin_offset_changed(AgsSoundcard *soundcard,
108 guint note_offset);
109
110 void ags_core_audio_devin_set_bpm(AgsSoundcard *soundcard,
111 gdouble bpm);
112 gdouble ags_core_audio_devin_get_bpm(AgsSoundcard *soundcard);
113
114 void ags_core_audio_devin_set_delay_factor(AgsSoundcard *soundcard,
115 gdouble delay_factor);
116 gdouble ags_core_audio_devin_get_delay_factor(AgsSoundcard *soundcard);
117
118 gdouble ags_core_audio_devin_get_absolute_delay(AgsSoundcard *soundcard);
119
120 gdouble ags_core_audio_devin_get_delay(AgsSoundcard *soundcard);
121 guint ags_core_audio_devin_get_attack(AgsSoundcard *soundcard);
122
123 void* ags_core_audio_devin_get_buffer(AgsSoundcard *soundcard);
124 void* ags_core_audio_devin_get_next_buffer(AgsSoundcard *soundcard);
125 void* ags_core_audio_devin_get_prev_buffer(AgsSoundcard *soundcard);
126
127 void ags_core_audio_devin_lock_buffer(AgsSoundcard *soundcard,
128 void *buffer);
129 void ags_core_audio_devin_unlock_buffer(AgsSoundcard *soundcard,
130 void *buffer);
131
132 guint ags_core_audio_devin_get_delay_counter(AgsSoundcard *soundcard);
133
134 void ags_core_audio_devin_set_start_note_offset(AgsSoundcard *soundcard,
135 guint start_note_offset);
136 guint ags_core_audio_devin_get_start_note_offset(AgsSoundcard *soundcard);
137
138 void ags_core_audio_devin_set_note_offset(AgsSoundcard *soundcard,
139 guint note_offset);
140 guint ags_core_audio_devin_get_note_offset(AgsSoundcard *soundcard);
141
142 void ags_core_audio_devin_set_note_offset_absolute(AgsSoundcard *soundcard,
143 guint note_offset);
144 guint ags_core_audio_devin_get_note_offset_absolute(AgsSoundcard *soundcard);
145
146 void ags_core_audio_devin_set_loop(AgsSoundcard *soundcard,
147 guint loop_left, guint loop_right,
148 gboolean do_loop);
149 void ags_core_audio_devin_get_loop(AgsSoundcard *soundcard,
150 guint *loop_left, guint *loop_right,
151 gboolean *do_loop);
152
153 guint ags_core_audio_devin_get_loop_offset(AgsSoundcard *soundcard);
154
155 /**
156 * SECTION:ags_core_audio_devin
157 * @short_description: Output to soundcard
158 * @title: AgsCoreAudioDevin
159 * @section_id:
160 * @include: ags/audio/core-audio/ags_core_audio_devin.h
161 *
162 * #AgsCoreAudioDevin represents a soundcard and supports output.
163 */
164
165 enum{
166 PROP_0,
167 PROP_DEVICE,
168 PROP_DSP_CHANNELS,
169 PROP_PCM_CHANNELS,
170 PROP_FORMAT,
171 PROP_BUFFER_SIZE,
172 PROP_SAMPLERATE,
173 PROP_BUFFER,
174 PROP_BPM,
175 PROP_DELAY_FACTOR,
176 PROP_ATTACK,
177 PROP_CORE_AUDIO_CLIENT,
178 PROP_CORE_AUDIO_PORT,
179 PROP_CHANNEL,
180 };
181
182 static gpointer ags_core_audio_devin_parent_class = NULL;
183
184 GType
ags_core_audio_devin_get_type(void)185 ags_core_audio_devin_get_type (void)
186 {
187 static volatile gsize g_define_type_id__volatile = 0;
188
189 if(g_once_init_enter (&g_define_type_id__volatile)){
190 GType ags_type_core_audio_devin = 0;
191
192 static const GTypeInfo ags_core_audio_devin_info = {
193 sizeof(AgsCoreAudioDevinClass),
194 NULL, /* base_init */
195 NULL, /* base_finalize */
196 (GClassInitFunc) ags_core_audio_devin_class_init,
197 NULL, /* class_finalize */
198 NULL, /* class_data */
199 sizeof(AgsCoreAudioDevin),
200 0, /* n_preallocs */
201 (GInstanceInitFunc) ags_core_audio_devin_init,
202 };
203
204 static const GInterfaceInfo ags_connectable_interface_info = {
205 (GInterfaceInitFunc) ags_core_audio_devin_connectable_interface_init,
206 NULL, /* interface_finalize */
207 NULL, /* interface_data */
208 };
209
210 static const GInterfaceInfo ags_soundcard_interface_info = {
211 (GInterfaceInitFunc) ags_core_audio_devin_soundcard_interface_init,
212 NULL, /* interface_finalize */
213 NULL, /* interface_data */
214 };
215
216 ags_type_core_audio_devin = g_type_register_static(G_TYPE_OBJECT,
217 "AgsCoreAudioDevin",
218 &ags_core_audio_devin_info,
219 0);
220
221 g_type_add_interface_static(ags_type_core_audio_devin,
222 AGS_TYPE_CONNECTABLE,
223 &ags_connectable_interface_info);
224
225 g_type_add_interface_static(ags_type_core_audio_devin,
226 AGS_TYPE_SOUNDCARD,
227 &ags_soundcard_interface_info);
228
229 g_once_init_leave(&g_define_type_id__volatile, ags_type_core_audio_devin);
230 }
231
232 return g_define_type_id__volatile;
233 }
234
235 void
ags_core_audio_devin_class_init(AgsCoreAudioDevinClass * core_audio_devin)236 ags_core_audio_devin_class_init(AgsCoreAudioDevinClass *core_audio_devin)
237 {
238 GObjectClass *gobject;
239 GParamSpec *param_spec;
240
241 ags_core_audio_devin_parent_class = g_type_class_peek_parent(core_audio_devin);
242
243 /* GObjectClass */
244 gobject = (GObjectClass *) core_audio_devin;
245
246 gobject->set_property = ags_core_audio_devin_set_property;
247 gobject->get_property = ags_core_audio_devin_get_property;
248
249 gobject->dispose = ags_core_audio_devin_dispose;
250 gobject->finalize = ags_core_audio_devin_finalize;
251
252 /* properties */
253 /**
254 * AgsCoreAudioDevin:device:
255 *
256 * The core audio soundcard indentifier
257 *
258 * Since: 3.0.0
259 */
260 param_spec = g_param_spec_string("device",
261 i18n_pspec("the device identifier"),
262 i18n_pspec("The device to perform output to"),
263 "ags-core-audio-devin-0",
264 G_PARAM_READABLE | G_PARAM_WRITABLE);
265 g_object_class_install_property(gobject,
266 PROP_DEVICE,
267 param_spec);
268
269 /**
270 * AgsCoreAudioDevin:dsp-channels:
271 *
272 * The dsp channel count
273 *
274 * Since: 3.0.0
275 */
276 param_spec = g_param_spec_uint("dsp-channels",
277 i18n_pspec("count of DSP channels"),
278 i18n_pspec("The count of DSP channels to use"),
279 1,
280 64,
281 2,
282 G_PARAM_READABLE | G_PARAM_WRITABLE);
283 g_object_class_install_property(gobject,
284 PROP_DSP_CHANNELS,
285 param_spec);
286
287 /**
288 * AgsCoreAudioDevin:pcm-channels:
289 *
290 * The pcm channel count
291 *
292 * Since: 3.0.0
293 */
294 param_spec = g_param_spec_uint("pcm-channels",
295 i18n_pspec("count of PCM channels"),
296 i18n_pspec("The count of PCM channels to use"),
297 1,
298 64,
299 2,
300 G_PARAM_READABLE | G_PARAM_WRITABLE);
301 g_object_class_install_property(gobject,
302 PROP_PCM_CHANNELS,
303 param_spec);
304
305 /**
306 * AgsCoreAudioDevin:format:
307 *
308 * The precision of the buffer
309 *
310 * Since: 3.0.0
311 */
312 param_spec = g_param_spec_uint("format",
313 i18n_pspec("precision of buffer"),
314 i18n_pspec("The precision to use for a frame"),
315 1,
316 64,
317 AGS_SOUNDCARD_DEFAULT_FORMAT,
318 G_PARAM_READABLE | G_PARAM_WRITABLE);
319 g_object_class_install_property(gobject,
320 PROP_FORMAT,
321 param_spec);
322
323 /**
324 * AgsCoreAudioDevin:buffer-size:
325 *
326 * The buffer size
327 *
328 * Since: 3.0.0
329 */
330 param_spec = g_param_spec_uint("buffer-size",
331 i18n_pspec("frame count of a buffer"),
332 i18n_pspec("The count of frames a buffer contains"),
333 1,
334 44100,
335 940,
336 G_PARAM_READABLE | G_PARAM_WRITABLE);
337 g_object_class_install_property(gobject,
338 PROP_BUFFER_SIZE,
339 param_spec);
340
341 /**
342 * AgsCoreAudioDevin:samplerate:
343 *
344 * The samplerate
345 *
346 * Since: 3.0.0
347 */
348 param_spec = g_param_spec_uint("samplerate",
349 i18n_pspec("frames per second"),
350 i18n_pspec("The frames count played during a second"),
351 8000,
352 96000,
353 44100,
354 G_PARAM_READABLE | G_PARAM_WRITABLE);
355 g_object_class_install_property(gobject,
356 PROP_SAMPLERATE,
357 param_spec);
358
359 /**
360 * AgsCoreAudioDevin:buffer:
361 *
362 * The buffer
363 *
364 * Since: 3.0.0
365 */
366 param_spec = g_param_spec_pointer("buffer",
367 i18n_pspec("the buffer"),
368 i18n_pspec("The buffer to play"),
369 G_PARAM_READABLE);
370 g_object_class_install_property(gobject,
371 PROP_BUFFER,
372 param_spec);
373
374 /**
375 * AgsCoreAudioDevin:bpm:
376 *
377 * Beats per minute
378 *
379 * Since: 3.0.0
380 */
381 param_spec = g_param_spec_double("bpm",
382 i18n_pspec("beats per minute"),
383 i18n_pspec("Beats per minute to use"),
384 1.0,
385 240.0,
386 120.0,
387 G_PARAM_READABLE | G_PARAM_WRITABLE);
388 g_object_class_install_property(gobject,
389 PROP_BPM,
390 param_spec);
391
392 /**
393 * AgsCoreAudioDevin:delay-factor:
394 *
395 * tact
396 *
397 * Since: 3.0.0
398 */
399 param_spec = g_param_spec_double("delay-factor",
400 i18n_pspec("delay factor"),
401 i18n_pspec("The delay factor"),
402 0.0,
403 16.0,
404 1.0,
405 G_PARAM_READABLE | G_PARAM_WRITABLE);
406 g_object_class_install_property(gobject,
407 PROP_DELAY_FACTOR,
408 param_spec);
409
410 /**
411 * AgsCoreAudioDevin:attack:
412 *
413 * Attack of the buffer
414 *
415 * Since: 3.0.0
416 */
417 param_spec = g_param_spec_pointer("attack",
418 i18n_pspec("attack of buffer"),
419 i18n_pspec("The attack to use for the buffer"),
420 G_PARAM_READABLE);
421 g_object_class_install_property(gobject,
422 PROP_ATTACK,
423 param_spec);
424
425
426 /**
427 * AgsCoreAudioDevin:core-audio-client:
428 *
429 * The assigned #AgsCoreAudioClient
430 *
431 * Since: 3.0.0
432 */
433 param_spec = g_param_spec_object("core-audio-client",
434 i18n_pspec("core audio client object"),
435 i18n_pspec("The core audio client object"),
436 AGS_TYPE_CORE_AUDIO_CLIENT,
437 G_PARAM_READABLE | G_PARAM_WRITABLE);
438 g_object_class_install_property(gobject,
439 PROP_CORE_AUDIO_CLIENT,
440 param_spec);
441
442 /**
443 * AgsCoreAudioDevin:core-audio-port:
444 *
445 * The assigned #AgsCoreAudioPort
446 *
447 * Since: 3.0.0
448 */
449 param_spec = g_param_spec_pointer("core-audio-port",
450 i18n_pspec("core audio port object"),
451 i18n_pspec("The core audio port object"),
452 G_PARAM_READABLE | G_PARAM_WRITABLE);
453 g_object_class_install_property(gobject,
454 PROP_CORE_AUDIO_PORT,
455 param_spec);
456 }
457
458 GQuark
ags_core_audio_devin_error_quark()459 ags_core_audio_devin_error_quark()
460 {
461 return(g_quark_from_static_string("ags-core_audio_devin-error-quark"));
462 }
463
464 void
ags_core_audio_devin_connectable_interface_init(AgsConnectableInterface * connectable)465 ags_core_audio_devin_connectable_interface_init(AgsConnectableInterface *connectable)
466 {
467 //TODO:JK: implement me
468 }
469
470 void
ags_core_audio_devin_soundcard_interface_init(AgsSoundcardInterface * soundcard)471 ags_core_audio_devin_soundcard_interface_init(AgsSoundcardInterface *soundcard)
472 {
473 soundcard->set_device = ags_core_audio_devin_set_device;
474 soundcard->get_device = ags_core_audio_devin_get_device;
475
476 soundcard->set_presets = ags_core_audio_devin_set_presets;
477 soundcard->get_presets = ags_core_audio_devin_get_presets;
478
479 soundcard->list_cards = ags_core_audio_devin_list_cards;
480 soundcard->pcm_info = ags_core_audio_devin_pcm_info;
481 soundcard->get_capability = ags_core_audio_devin_get_capability;
482
483 soundcard->is_available = NULL;
484
485 soundcard->is_starting = ags_core_audio_devin_is_starting;
486 soundcard->is_playing = NULL;
487 soundcard->is_recording = ags_core_audio_devin_is_recording;
488
489 soundcard->get_uptime = ags_core_audio_devin_get_uptime;
490
491 soundcard->play_init = NULL;
492 soundcard->play = NULL;
493
494 soundcard->record_init = ags_core_audio_devin_port_init;
495 soundcard->record = ags_core_audio_devin_port_record;
496
497 soundcard->stop = ags_core_audio_devin_port_free;
498
499 soundcard->tic = ags_core_audio_devin_tic;
500 soundcard->offset_changed = ags_core_audio_devin_offset_changed;
501
502 soundcard->set_bpm = ags_core_audio_devin_set_bpm;
503 soundcard->get_bpm = ags_core_audio_devin_get_bpm;
504
505 soundcard->set_delay_factor = ags_core_audio_devin_set_delay_factor;
506 soundcard->get_delay_factor = ags_core_audio_devin_get_delay_factor;
507
508 soundcard->get_absolute_delay = ags_core_audio_devin_get_absolute_delay;
509
510 soundcard->get_delay = ags_core_audio_devin_get_delay;
511 soundcard->get_attack = ags_core_audio_devin_get_attack;
512
513 soundcard->get_buffer = ags_core_audio_devin_get_buffer;
514 soundcard->get_next_buffer = ags_core_audio_devin_get_next_buffer;
515 soundcard->get_prev_buffer = ags_core_audio_devin_get_prev_buffer;
516
517 soundcard->lock_buffer = ags_core_audio_devin_lock_buffer;
518 soundcard->unlock_buffer = ags_core_audio_devin_unlock_buffer;
519
520 soundcard->get_delay_counter = ags_core_audio_devin_get_delay_counter;
521
522 soundcard->set_start_note_offset = ags_core_audio_devin_set_start_note_offset;
523 soundcard->get_start_note_offset = ags_core_audio_devin_get_start_note_offset;
524
525 soundcard->set_note_offset = ags_core_audio_devin_set_note_offset;
526 soundcard->get_note_offset = ags_core_audio_devin_get_note_offset;
527
528 soundcard->set_note_offset_absolute = ags_core_audio_devin_set_note_offset_absolute;
529 soundcard->get_note_offset_absolute = ags_core_audio_devin_get_note_offset_absolute;
530
531 soundcard->set_loop = ags_core_audio_devin_set_loop;
532 soundcard->get_loop = ags_core_audio_devin_get_loop;
533
534 soundcard->get_loop_offset = ags_core_audio_devin_get_loop_offset;
535 }
536
537 void
ags_core_audio_devin_init(AgsCoreAudioDevin * core_audio_devin)538 ags_core_audio_devin_init(AgsCoreAudioDevin *core_audio_devin)
539 {
540 AgsConfig *config;
541
542 gchar *str;
543 gchar *segmentation;
544
545 guint denominator, numerator;
546 guint i;
547
548 /* flags */
549 core_audio_devin->flags = 0;
550 g_atomic_int_set(&(core_audio_devin->sync_flags),
551 AGS_CORE_AUDIO_DEVIN_PASS_THROUGH);
552
553 /* devin mutex */
554 g_rec_mutex_init(&(core_audio_devin->obj_mutex));
555
556 /* uuid */
557 core_audio_devin->uuid = ags_uuid_alloc();
558 ags_uuid_generate(core_audio_devin->uuid);
559
560 /* presets */
561 config = ags_config_get_instance();
562
563 core_audio_devin->dsp_channels = ags_soundcard_helper_config_get_dsp_channels(config);
564 core_audio_devin->pcm_channels = ags_soundcard_helper_config_get_pcm_channels(config);
565
566 core_audio_devin->samplerate = ags_soundcard_helper_config_get_samplerate(config);
567 core_audio_devin->buffer_size = ags_soundcard_helper_config_get_buffer_size(config);
568 core_audio_devin->format = ags_soundcard_helper_config_get_format(config);
569
570 /* */
571 core_audio_devin->card_uri = NULL;
572 core_audio_devin->core_audio_client = NULL;
573
574 core_audio_devin->port_name = NULL;
575 core_audio_devin->core_audio_port = NULL;
576
577 /* buffer */
578 core_audio_devin->buffer_mutex = (GRecMutex **) malloc(8 * sizeof(GRecMutex *));
579
580 for(i = 0; i < 8; i++){
581 core_audio_devin->buffer_mutex[i] = (GRecMutex *) malloc(sizeof(GRecMutex));
582
583 g_rec_mutex_init(core_audio_devin->buffer_mutex[i]);
584 }
585
586 core_audio_devin->buffer = (void **) malloc(8 * sizeof(void*));
587
588 core_audio_devin->buffer[0] = NULL;
589 core_audio_devin->buffer[1] = NULL;
590 core_audio_devin->buffer[2] = NULL;
591 core_audio_devin->buffer[3] = NULL;
592 core_audio_devin->buffer[4] = NULL;
593 core_audio_devin->buffer[5] = NULL;
594 core_audio_devin->buffer[6] = NULL;
595 core_audio_devin->buffer[7] = NULL;
596
597 ags_core_audio_devin_realloc_buffer(core_audio_devin);
598
599 /* bpm */
600 core_audio_devin->bpm = AGS_SOUNDCARD_DEFAULT_BPM;
601
602 /* delay factor */
603 core_audio_devin->delay_factor = AGS_SOUNDCARD_DEFAULT_DELAY_FACTOR;
604
605 /* segmentation */
606 segmentation = ags_config_get_value(config,
607 AGS_CONFIG_GENERIC,
608 "segmentation");
609
610 if(segmentation != NULL){
611 sscanf(segmentation, "%d/%d",
612 &denominator,
613 &numerator);
614
615 core_audio_devin->delay_factor = 1.0 / numerator * (numerator / denominator);
616
617 g_free(segmentation);
618 }
619
620 /* delay and attack */
621 core_audio_devin->delay = (gdouble *) malloc((int) 2 * AGS_SOUNDCARD_DEFAULT_PERIOD *
622 sizeof(gdouble));
623
624 core_audio_devin->attack = (guint *) malloc((int) 2 * AGS_SOUNDCARD_DEFAULT_PERIOD *
625 sizeof(guint));
626
627 ags_core_audio_devin_adjust_delay_and_attack(core_audio_devin);
628
629 /* counters */
630 core_audio_devin->tact_counter = 0.0;
631 core_audio_devin->delay_counter = 0.0;
632 core_audio_devin->tic_counter = 0;
633
634 core_audio_devin->start_note_offset = 0;
635 core_audio_devin->note_offset = 0;
636 core_audio_devin->note_offset_absolute = 0;
637
638 core_audio_devin->loop_left = AGS_SOUNDCARD_DEFAULT_LOOP_LEFT;
639 core_audio_devin->loop_right = AGS_SOUNDCARD_DEFAULT_LOOP_RIGHT;
640
641 core_audio_devin->do_loop = FALSE;
642
643 core_audio_devin->loop_offset = 0;
644
645 /* callback mutex */
646 g_mutex_init(&(core_audio_devin->callback_mutex));
647
648 g_cond_init(&(core_audio_devin->callback_cond));
649
650 /* callback finish mutex */
651 g_mutex_init(&(core_audio_devin->callback_finish_mutex));
652
653 g_cond_init(&(core_audio_devin->callback_finish_cond));
654 }
655
656 void
ags_core_audio_devin_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)657 ags_core_audio_devin_set_property(GObject *gobject,
658 guint prop_id,
659 const GValue *value,
660 GParamSpec *param_spec)
661 {
662 AgsCoreAudioDevin *core_audio_devin;
663
664 GRecMutex *core_audio_devin_mutex;
665
666 core_audio_devin = AGS_CORE_AUDIO_DEVIN(gobject);
667
668 /* get core_audio devin mutex */
669 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
670
671 switch(prop_id){
672 case PROP_DEVICE:
673 {
674 char *device;
675
676 device = (char *) g_value_get_string(value);
677
678 g_rec_mutex_lock(core_audio_devin_mutex);
679
680 core_audio_devin->card_uri = g_strdup(device);
681
682 g_rec_mutex_unlock(core_audio_devin_mutex);
683 }
684 break;
685 case PROP_DSP_CHANNELS:
686 {
687 guint dsp_channels;
688
689 dsp_channels = g_value_get_uint(value);
690
691 g_rec_mutex_lock(core_audio_devin_mutex);
692
693 if(dsp_channels == core_audio_devin->dsp_channels){
694 g_rec_mutex_unlock(core_audio_devin_mutex);
695
696 return;
697 }
698
699 core_audio_devin->dsp_channels = dsp_channels;
700
701 g_rec_mutex_unlock(core_audio_devin_mutex);
702 }
703 break;
704 case PROP_PCM_CHANNELS:
705 {
706 guint pcm_channels;
707
708 pcm_channels = g_value_get_uint(value);
709
710 g_rec_mutex_lock(core_audio_devin_mutex);
711
712 if(pcm_channels == core_audio_devin->pcm_channels){
713 g_rec_mutex_unlock(core_audio_devin_mutex);
714
715 return;
716 }
717
718 core_audio_devin->pcm_channels = pcm_channels;
719
720 g_rec_mutex_unlock(core_audio_devin_mutex);
721
722 ags_core_audio_devin_realloc_buffer(core_audio_devin);
723 }
724 break;
725 case PROP_FORMAT:
726 {
727 guint format;
728
729 format = g_value_get_uint(value);
730
731 g_rec_mutex_lock(core_audio_devin_mutex);
732
733 if(format == core_audio_devin->format){
734 g_rec_mutex_unlock(core_audio_devin_mutex);
735
736 return;
737 }
738
739 core_audio_devin->format = format;
740
741 g_rec_mutex_unlock(core_audio_devin_mutex);
742
743 ags_core_audio_devin_realloc_buffer(core_audio_devin);
744 }
745 break;
746 case PROP_BUFFER_SIZE:
747 {
748 guint buffer_size;
749
750 buffer_size = g_value_get_uint(value);
751
752 g_rec_mutex_lock(core_audio_devin_mutex);
753
754 if(buffer_size == core_audio_devin->buffer_size){
755 g_rec_mutex_unlock(core_audio_devin_mutex);
756
757 return;
758 }
759
760 core_audio_devin->buffer_size = buffer_size;
761
762 g_rec_mutex_unlock(core_audio_devin_mutex);
763
764 ags_core_audio_devin_realloc_buffer(core_audio_devin);
765 ags_core_audio_devin_adjust_delay_and_attack(core_audio_devin);
766 }
767 break;
768 case PROP_SAMPLERATE:
769 {
770 guint samplerate;
771
772 samplerate = g_value_get_uint(value);
773
774 g_rec_mutex_lock(core_audio_devin_mutex);
775
776 if(samplerate == core_audio_devin->samplerate){
777 g_rec_mutex_unlock(core_audio_devin_mutex);
778
779 return;
780 }
781
782 core_audio_devin->samplerate = samplerate;
783
784 g_rec_mutex_unlock(core_audio_devin_mutex);
785
786 ags_core_audio_devin_realloc_buffer(core_audio_devin);
787 ags_core_audio_devin_adjust_delay_and_attack(core_audio_devin);
788 }
789 break;
790 case PROP_BUFFER:
791 {
792 //TODO:JK: implement me
793 }
794 break;
795 case PROP_BPM:
796 {
797 gdouble bpm;
798
799 bpm = g_value_get_double(value);
800
801 g_rec_mutex_lock(core_audio_devin_mutex);
802
803 core_audio_devin->bpm = bpm;
804
805 g_rec_mutex_unlock(core_audio_devin_mutex);
806
807 ags_core_audio_devin_adjust_delay_and_attack(core_audio_devin);
808 }
809 break;
810 case PROP_DELAY_FACTOR:
811 {
812 gdouble delay_factor;
813
814 delay_factor = g_value_get_double(value);
815
816 g_rec_mutex_lock(core_audio_devin_mutex);
817
818 core_audio_devin->delay_factor = delay_factor;
819
820 g_rec_mutex_unlock(core_audio_devin_mutex);
821
822 ags_core_audio_devin_adjust_delay_and_attack(core_audio_devin);
823 }
824 break;
825 case PROP_CORE_AUDIO_CLIENT:
826 {
827 AgsCoreAudioClient *core_audio_client;
828
829 core_audio_client = (AgsCoreAudioClient *) g_value_get_object(value);
830
831 g_rec_mutex_lock(core_audio_devin_mutex);
832
833 if(core_audio_devin->core_audio_client == (GObject *) core_audio_client){
834 g_rec_mutex_unlock(core_audio_devin_mutex);
835
836 return;
837 }
838
839 if(core_audio_devin->core_audio_client != NULL){
840 g_object_unref(G_OBJECT(core_audio_devin->core_audio_client));
841 }
842
843 if(core_audio_client != NULL){
844 g_object_ref(core_audio_client);
845 }
846
847 core_audio_devin->core_audio_client = (GObject *) core_audio_client;
848
849 g_rec_mutex_unlock(core_audio_devin_mutex);
850 }
851 break;
852 case PROP_CORE_AUDIO_PORT:
853 {
854 AgsCoreAudioPort *core_audio_port;
855
856 core_audio_port = (AgsCoreAudioPort *) g_value_get_pointer(value);
857
858 g_rec_mutex_lock(core_audio_devin_mutex);
859
860 if(!AGS_IS_CORE_AUDIO_PORT(core_audio_port) ||
861 g_list_find(core_audio_devin->core_audio_port, core_audio_port) != NULL){
862 g_rec_mutex_unlock(core_audio_devin_mutex);
863
864 return;
865 }
866
867 g_object_ref(core_audio_port);
868 core_audio_devin->core_audio_port = g_list_append(core_audio_devin->core_audio_port,
869 core_audio_port);
870
871 g_rec_mutex_unlock(core_audio_devin_mutex);
872 }
873 break;
874 default:
875 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
876 break;
877 }
878 }
879
880 void
ags_core_audio_devin_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)881 ags_core_audio_devin_get_property(GObject *gobject,
882 guint prop_id,
883 GValue *value,
884 GParamSpec *param_spec)
885 {
886 AgsCoreAudioDevin *core_audio_devin;
887
888 GRecMutex *core_audio_devin_mutex;
889
890 core_audio_devin = AGS_CORE_AUDIO_DEVIN(gobject);
891
892 /* get core_audio devin mutex */
893 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
894
895 switch(prop_id){
896 case PROP_DEVICE:
897 {
898 g_rec_mutex_lock(core_audio_devin_mutex);
899
900 g_value_set_string(value, core_audio_devin->card_uri);
901
902 g_rec_mutex_unlock(core_audio_devin_mutex);
903 }
904 break;
905 case PROP_DSP_CHANNELS:
906 {
907 g_rec_mutex_lock(core_audio_devin_mutex);
908
909 g_value_set_uint(value, core_audio_devin->dsp_channels);
910
911 g_rec_mutex_unlock(core_audio_devin_mutex);
912 }
913 break;
914 case PROP_PCM_CHANNELS:
915 {
916 g_rec_mutex_lock(core_audio_devin_mutex);
917
918 g_value_set_uint(value, core_audio_devin->pcm_channels);
919
920 g_rec_mutex_unlock(core_audio_devin_mutex);
921 }
922 break;
923 case PROP_FORMAT:
924 {
925 g_rec_mutex_lock(core_audio_devin_mutex);
926
927 g_value_set_uint(value, core_audio_devin->format);
928
929 g_rec_mutex_unlock(core_audio_devin_mutex);
930 }
931 break;
932 case PROP_BUFFER_SIZE:
933 {
934 g_rec_mutex_lock(core_audio_devin_mutex);
935
936 g_value_set_uint(value, core_audio_devin->buffer_size);
937
938 g_rec_mutex_unlock(core_audio_devin_mutex);
939 }
940 break;
941 case PROP_SAMPLERATE:
942 {
943 g_rec_mutex_lock(core_audio_devin_mutex);
944
945 g_value_set_uint(value, core_audio_devin->samplerate);
946
947 g_rec_mutex_unlock(core_audio_devin_mutex);
948 }
949 break;
950 case PROP_BUFFER:
951 {
952 g_rec_mutex_lock(core_audio_devin_mutex);
953
954 g_value_set_pointer(value, core_audio_devin->buffer);
955
956 g_rec_mutex_unlock(core_audio_devin_mutex);
957 }
958 break;
959 case PROP_BPM:
960 {
961 g_rec_mutex_lock(core_audio_devin_mutex);
962
963 g_value_set_double(value, core_audio_devin->bpm);
964
965 g_rec_mutex_unlock(core_audio_devin_mutex);
966 }
967 break;
968 case PROP_DELAY_FACTOR:
969 {
970 g_rec_mutex_lock(core_audio_devin_mutex);
971
972 g_value_set_double(value, core_audio_devin->delay_factor);
973
974 g_rec_mutex_unlock(core_audio_devin_mutex);
975 }
976 break;
977 case PROP_ATTACK:
978 {
979 g_rec_mutex_lock(core_audio_devin_mutex);
980
981 g_value_set_pointer(value, core_audio_devin->attack);
982
983 g_rec_mutex_unlock(core_audio_devin_mutex);
984 }
985 break;
986 case PROP_CORE_AUDIO_CLIENT:
987 {
988 g_rec_mutex_lock(core_audio_devin_mutex);
989
990 g_value_set_object(value, core_audio_devin->core_audio_client);
991
992 g_rec_mutex_unlock(core_audio_devin_mutex);
993 }
994 break;
995 case PROP_CORE_AUDIO_PORT:
996 {
997 g_rec_mutex_lock(core_audio_devin_mutex);
998
999 g_value_set_pointer(value,
1000 g_list_copy_deep(core_audio_devin->core_audio_port,
1001 (GCopyFunc) g_object_ref,
1002 NULL));
1003
1004 g_rec_mutex_unlock(core_audio_devin_mutex);
1005 }
1006 break;
1007 default:
1008 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
1009 break;
1010 }
1011 }
1012
1013 void
ags_core_audio_devin_dispose(GObject * gobject)1014 ags_core_audio_devin_dispose(GObject *gobject)
1015 {
1016 AgsCoreAudioDevin *core_audio_devin;
1017
1018 GList *list;
1019
1020 core_audio_devin = AGS_CORE_AUDIO_DEVIN(gobject);
1021
1022 //TODO:JK: implement me
1023
1024 /* call parent */
1025 G_OBJECT_CLASS(ags_core_audio_devin_parent_class)->dispose(gobject);
1026 }
1027
1028 void
ags_core_audio_devin_finalize(GObject * gobject)1029 ags_core_audio_devin_finalize(GObject *gobject)
1030 {
1031 AgsCoreAudioDevin *core_audio_devin;
1032
1033 core_audio_devin = AGS_CORE_AUDIO_DEVIN(gobject);
1034
1035 //TODO:JK: implement me
1036
1037 /* call parent */
1038 G_OBJECT_CLASS(ags_core_audio_devin_parent_class)->finalize(gobject);
1039 }
1040
1041 /**
1042 * ags_core_audio_devin_test_flags:
1043 * @core_audio_devin: the #AgsCoreAudioDevin
1044 * @flags: the flags
1045 *
1046 * Test @flags to be set on @core_audio_devin.
1047 *
1048 * Returns: %TRUE if flags are set, else %FALSE
1049 *
1050 * Since: 3.0.0
1051 */
1052 gboolean
ags_core_audio_devin_test_flags(AgsCoreAudioDevin * core_audio_devin,guint flags)1053 ags_core_audio_devin_test_flags(AgsCoreAudioDevin *core_audio_devin, guint flags)
1054 {
1055 gboolean retval;
1056
1057 GRecMutex *core_audio_devin_mutex;
1058
1059 if(!AGS_IS_CORE_AUDIO_DEVIN(core_audio_devin)){
1060 return(FALSE);
1061 }
1062
1063 /* get core_audio devin mutex */
1064 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1065
1066 /* test */
1067 g_rec_mutex_lock(core_audio_devin_mutex);
1068
1069 retval = (flags & (core_audio_devin->flags)) ? TRUE: FALSE;
1070
1071 g_rec_mutex_unlock(core_audio_devin_mutex);
1072
1073 return(retval);
1074 }
1075
1076 /**
1077 * ags_core_audio_devin_set_flags:
1078 * @core_audio_devin: the #AgsCoreAudioDevin
1079 * @flags: see #AgsCoreAudioDevinFlags-enum
1080 *
1081 * Enable a feature of @core_audio_devin.
1082 *
1083 * Since: 3.0.0
1084 */
1085 void
ags_core_audio_devin_set_flags(AgsCoreAudioDevin * core_audio_devin,guint flags)1086 ags_core_audio_devin_set_flags(AgsCoreAudioDevin *core_audio_devin, guint flags)
1087 {
1088 GRecMutex *core_audio_devin_mutex;
1089
1090 if(!AGS_IS_CORE_AUDIO_DEVIN(core_audio_devin)){
1091 return;
1092 }
1093
1094 /* get core_audio devin mutex */
1095 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1096
1097 //TODO:JK: add more?
1098
1099 /* set flags */
1100 g_rec_mutex_lock(core_audio_devin_mutex);
1101
1102 core_audio_devin->flags |= flags;
1103
1104 g_rec_mutex_unlock(core_audio_devin_mutex);
1105 }
1106
1107 /**
1108 * ags_core_audio_devin_unset_flags:
1109 * @core_audio_devin: the #AgsCoreAudioDevin
1110 * @flags: see #AgsCoreAudioDevinFlags-enum
1111 *
1112 * Disable a feature of @core_audio_devin.
1113 *
1114 * Since: 3.0.0
1115 */
1116 void
ags_core_audio_devin_unset_flags(AgsCoreAudioDevin * core_audio_devin,guint flags)1117 ags_core_audio_devin_unset_flags(AgsCoreAudioDevin *core_audio_devin, guint flags)
1118 {
1119 GRecMutex *core_audio_devin_mutex;
1120
1121 if(!AGS_IS_CORE_AUDIO_DEVIN(core_audio_devin)){
1122 return;
1123 }
1124
1125 /* get core_audio devin mutex */
1126 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1127
1128 //TODO:JK: add more?
1129
1130 /* unset flags */
1131 g_rec_mutex_lock(core_audio_devin_mutex);
1132
1133 core_audio_devin->flags &= (~flags);
1134
1135 g_rec_mutex_unlock(core_audio_devin_mutex);
1136 }
1137
1138 void
ags_core_audio_devin_set_device(AgsSoundcard * soundcard,gchar * device)1139 ags_core_audio_devin_set_device(AgsSoundcard *soundcard,
1140 gchar *device)
1141 {
1142 AgsCoreAudioDevin *core_audio_devin;
1143
1144 GList *core_audio_port, *core_audio_port_start;
1145
1146 gchar *str;
1147
1148 guint pcm_channels;
1149 int ret;
1150 guint nth_card;
1151 guint i;
1152
1153 GRecMutex *core_audio_devin_mutex;
1154
1155 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1156
1157 /* get core_audio devin mutex */
1158 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1159
1160 /* check device */
1161 g_rec_mutex_lock(core_audio_devin_mutex);
1162
1163 if(core_audio_devin->card_uri == device ||
1164 (core_audio_devin->card_uri != NULL &&
1165 !g_ascii_strcasecmp(core_audio_devin->card_uri,
1166 device))){
1167 g_rec_mutex_unlock(core_audio_devin_mutex);
1168
1169 return;
1170 }
1171
1172 if(!g_str_has_prefix(device,
1173 "ags-core-audio-devin-")){
1174 g_rec_mutex_unlock(core_audio_devin_mutex);
1175
1176 g_warning("invalid CoreAudio device prefix");
1177
1178 return;
1179 }
1180
1181 ret = sscanf(device,
1182 "ags-core-audio-devin-%u",
1183 &nth_card);
1184
1185 if(ret != 1){
1186 g_rec_mutex_unlock(core_audio_devin_mutex);
1187
1188 g_warning("invalid CoreAudio device specifier");
1189
1190 return;
1191 }
1192
1193 g_free(core_audio_devin->card_uri);
1194 core_audio_devin->card_uri = g_strdup(device);
1195
1196 /* apply name to port */
1197 pcm_channels = core_audio_devin->pcm_channels;
1198
1199 core_audio_port_start =
1200 core_audio_port = g_list_copy(core_audio_devin->core_audio_port);
1201
1202 g_rec_mutex_unlock(core_audio_devin_mutex);
1203
1204 for(i = 0; i < pcm_channels && core_audio_port != NULL; i++){
1205 str = g_strdup_printf("ags-soundcard%d-%04d",
1206 nth_card,
1207 i);
1208
1209 g_object_set(core_audio_port->data,
1210 "port-name", str,
1211 NULL);
1212 g_free(str);
1213
1214 core_audio_port = core_audio_port->next;
1215 }
1216
1217 g_list_free(core_audio_port_start);
1218 }
1219
1220 gchar*
ags_core_audio_devin_get_device(AgsSoundcard * soundcard)1221 ags_core_audio_devin_get_device(AgsSoundcard *soundcard)
1222 {
1223 AgsCoreAudioDevin *core_audio_devin;
1224
1225 gchar *device;
1226
1227 GRecMutex *core_audio_devin_mutex;
1228
1229 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1230
1231 /* get core_audio devin mutex */
1232 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1233
1234 device = NULL;
1235
1236 /* get device */
1237 g_rec_mutex_lock(core_audio_devin_mutex);
1238
1239 device = g_strdup(core_audio_devin->card_uri);
1240
1241 g_rec_mutex_unlock(core_audio_devin_mutex);
1242
1243 return(device);
1244 }
1245
1246 void
ags_core_audio_devin_set_presets(AgsSoundcard * soundcard,guint channels,guint rate,guint buffer_size,guint format)1247 ags_core_audio_devin_set_presets(AgsSoundcard *soundcard,
1248 guint channels,
1249 guint rate,
1250 guint buffer_size,
1251 guint format)
1252 {
1253 AgsCoreAudioDevin *core_audio_devin;
1254
1255 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1256
1257 g_object_set(core_audio_devin,
1258 "pcm-channels", channels,
1259 "samplerate", rate,
1260 "buffer-size", buffer_size,
1261 "format", format,
1262 NULL);
1263 }
1264
1265 void
ags_core_audio_devin_get_presets(AgsSoundcard * soundcard,guint * channels,guint * rate,guint * buffer_size,guint * format)1266 ags_core_audio_devin_get_presets(AgsSoundcard *soundcard,
1267 guint *channels,
1268 guint *rate,
1269 guint *buffer_size,
1270 guint *format)
1271 {
1272 AgsCoreAudioDevin *core_audio_devin;
1273
1274 GRecMutex *core_audio_devin_mutex;
1275
1276 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1277
1278 /* get core_audio devin mutex */
1279 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1280
1281 /* get presets */
1282 g_rec_mutex_lock(core_audio_devin_mutex);
1283
1284 if(channels != NULL){
1285 *channels = core_audio_devin->pcm_channels;
1286 }
1287
1288 if(rate != NULL){
1289 *rate = core_audio_devin->samplerate;
1290 }
1291
1292 if(buffer_size != NULL){
1293 *buffer_size = core_audio_devin->buffer_size;
1294 }
1295
1296 if(format != NULL){
1297 *format = core_audio_devin->format;
1298 }
1299
1300 g_rec_mutex_unlock(core_audio_devin_mutex);
1301 }
1302
1303 /**
1304 * ags_core_audio_devin_list_cards:
1305 * @soundcard: the #AgsSoundcard
1306 * @card_id: CORE_AUDIO identifier
1307 * @card_name: card name
1308 *
1309 * List available soundcards.
1310 *
1311 * Since: 3.0.0
1312 */
1313 void
ags_core_audio_devin_list_cards(AgsSoundcard * soundcard,GList ** card_id,GList ** card_name)1314 ags_core_audio_devin_list_cards(AgsSoundcard *soundcard,
1315 GList **card_id, GList **card_name)
1316 {
1317 AgsCoreAudioClient *core_audio_client;
1318 AgsCoreAudioDevin *core_audio_devin;
1319
1320 AgsApplicationContext *application_context;
1321
1322 GList *list_start, *list;
1323
1324 gchar *card_uri;
1325 gchar *client_name;
1326
1327 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1328
1329 application_context = ags_application_context_get_instance();
1330
1331 if(card_id != NULL){
1332 *card_id = NULL;
1333 }
1334
1335 if(card_name != NULL){
1336 *card_name = NULL;
1337 }
1338
1339 list =
1340 list_start = ags_sound_provider_get_soundcard(AGS_SOUND_PROVIDER(application_context));
1341
1342 while(list != NULL){
1343 if(AGS_IS_CORE_AUDIO_DEVIN(list->data)){
1344 if(card_id != NULL){
1345 card_uri = ags_soundcard_get_device(AGS_SOUNDCARD(list->data));
1346
1347 if(AGS_CORE_AUDIO_DEVIN(list->data)->card_uri != NULL){
1348 *card_id = g_list_prepend(*card_id,
1349 card_uri);
1350 }else{
1351 *card_id = g_list_prepend(*card_id,
1352 g_strdup("(null)"));
1353
1354 g_warning("ags_core_audio_devin_list_cards() - card id (null)");
1355 }
1356 }
1357
1358 if(card_name != NULL){
1359 g_object_get(list->data,
1360 "core_audio-client", &core_audio_client,
1361 NULL);
1362
1363 if(core_audio_client != NULL){
1364 /* get client name */
1365 g_object_get(core_audio_client,
1366 "client-name", &client_name,
1367 NULL);
1368
1369 *card_name = g_list_prepend(*card_name,
1370 client_name);
1371
1372 g_object_unref(core_audio_client);
1373 }else{
1374 *card_name = g_list_prepend(*card_name,
1375 g_strdup("(null)"));
1376
1377 g_warning("ags_core_audio_devin_list_cards() - CORE_AUDIO client not connected (null)");
1378 }
1379 }
1380 }
1381
1382 list = list->next;
1383 }
1384
1385 g_list_free_full(list_start,
1386 g_object_unref);
1387
1388 if(card_id != NULL && *card_id != NULL){
1389 *card_id = g_list_reverse(*card_id);
1390 }
1391
1392 if(card_name != NULL && *card_name != NULL){
1393 *card_name = g_list_reverse(*card_name);
1394 }
1395 }
1396
1397 void
ags_core_audio_devin_pcm_info(AgsSoundcard * soundcard,char * card_id,guint * channels_min,guint * channels_max,guint * rate_min,guint * rate_max,guint * buffer_size_min,guint * buffer_size_max,GError ** error)1398 ags_core_audio_devin_pcm_info(AgsSoundcard *soundcard,
1399 char *card_id,
1400 guint *channels_min, guint *channels_max,
1401 guint *rate_min, guint *rate_max,
1402 guint *buffer_size_min, guint *buffer_size_max,
1403 GError **error)
1404 {
1405 if(channels_min != NULL){
1406 *channels_min = 1;
1407 }
1408
1409 if(channels_max != NULL){
1410 *channels_max = 1024;
1411 }
1412
1413 if(rate_min != NULL){
1414 *rate_min = 8000;
1415 }
1416
1417 if(rate_max != NULL){
1418 *rate_max = 192000;
1419 }
1420
1421 if(buffer_size_min != NULL){
1422 *buffer_size_min = 64;
1423 }
1424
1425 if(buffer_size_max != NULL){
1426 *buffer_size_max = 8192;
1427 }
1428 }
1429
1430 guint
ags_core_audio_devin_get_capability(AgsSoundcard * soundcard)1431 ags_core_audio_devin_get_capability(AgsSoundcard *soundcard)
1432 {
1433 return(AGS_SOUNDCARD_CAPABILITY_CAPTURE);
1434 }
1435
1436 gboolean
ags_core_audio_devin_is_starting(AgsSoundcard * soundcard)1437 ags_core_audio_devin_is_starting(AgsSoundcard *soundcard)
1438 {
1439 AgsCoreAudioDevin *core_audio_devin;
1440
1441 gboolean is_starting;
1442
1443 GRecMutex *core_audio_devin_mutex;
1444
1445 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1446
1447 /* get core_audio devin mutex */
1448 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1449
1450 /* check is starting */
1451 g_rec_mutex_lock(core_audio_devin_mutex);
1452
1453 is_starting = ((AGS_CORE_AUDIO_DEVIN_START_RECORD & (core_audio_devin->flags)) != 0) ? TRUE: FALSE;
1454
1455 g_rec_mutex_unlock(core_audio_devin_mutex);
1456
1457 return(is_starting);
1458 }
1459
1460 gboolean
ags_core_audio_devin_is_recording(AgsSoundcard * soundcard)1461 ags_core_audio_devin_is_recording(AgsSoundcard *soundcard)
1462 {
1463 AgsCoreAudioDevin *core_audio_devin;
1464
1465 gboolean is_playing;
1466
1467 GRecMutex *core_audio_devin_mutex;
1468
1469 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1470
1471 /* get core_audio devin mutex */
1472 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1473
1474 /* check is starting */
1475 g_rec_mutex_lock(core_audio_devin_mutex);
1476
1477 is_playing = ((AGS_CORE_AUDIO_DEVIN_RECORD & (core_audio_devin->flags)) != 0) ? TRUE: FALSE;
1478
1479 g_rec_mutex_unlock(core_audio_devin_mutex);
1480
1481 return(is_playing);
1482 }
1483
1484 gchar*
ags_core_audio_devin_get_uptime(AgsSoundcard * soundcard)1485 ags_core_audio_devin_get_uptime(AgsSoundcard *soundcard)
1486 {
1487 gchar *uptime;
1488
1489 if(ags_soundcard_is_playing(soundcard)){
1490 guint samplerate;
1491 guint buffer_size;
1492
1493 guint note_offset;
1494 gdouble bpm;
1495 gdouble delay_factor;
1496
1497 gdouble delay;
1498
1499 ags_soundcard_get_presets(soundcard,
1500 NULL,
1501 &samplerate,
1502 &buffer_size,
1503 NULL);
1504
1505 note_offset = ags_soundcard_get_note_offset_absolute(soundcard);
1506
1507 bpm = ags_soundcard_get_bpm(soundcard);
1508 delay_factor = ags_soundcard_get_delay_factor(soundcard);
1509
1510 /* calculate delays */
1511 delay = ags_soundcard_get_absolute_delay(soundcard);
1512
1513 uptime = ags_time_get_uptime_from_offset(note_offset,
1514 bpm,
1515 delay,
1516 delay_factor);
1517 }else{
1518 uptime = g_strdup(AGS_TIME_ZERO);
1519 }
1520
1521 return(uptime);
1522 }
1523
1524 void
ags_core_audio_devin_port_init(AgsSoundcard * soundcard,GError ** error)1525 ags_core_audio_devin_port_init(AgsSoundcard *soundcard,
1526 GError **error)
1527 {
1528 AgsCoreAudioDevin *core_audio_devin;
1529
1530 guint format, word_size;
1531
1532 GRecMutex *core_audio_devin_mutex;
1533
1534 if(ags_soundcard_is_recording(soundcard)){
1535 return;
1536 }
1537
1538 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1539
1540 /* get core-audio devin mutex */
1541 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1542
1543 /* retrieve word size */
1544 g_rec_mutex_lock(core_audio_devin_mutex);
1545
1546 switch(core_audio_devin->format){
1547 case AGS_SOUNDCARD_SIGNED_8_BIT:
1548 {
1549 word_size = sizeof(gint8);
1550 }
1551 break;
1552 case AGS_SOUNDCARD_SIGNED_16_BIT:
1553 {
1554 word_size = sizeof(gint16);
1555 }
1556 break;
1557 case AGS_SOUNDCARD_SIGNED_24_BIT:
1558 {
1559 //NOTE:JK: The 24-bit linear samples use 32-bit physical space
1560 word_size = sizeof(gint32);
1561 }
1562 break;
1563 case AGS_SOUNDCARD_SIGNED_32_BIT:
1564 {
1565 word_size = sizeof(gint32);
1566 }
1567 break;
1568 case AGS_SOUNDCARD_SIGNED_64_BIT:
1569 {
1570 word_size = sizeof(gint64);
1571 }
1572 break;
1573 default:
1574 g_rec_mutex_unlock(core_audio_devin_mutex);
1575
1576 g_warning("ags_core_audio_devin_port_init(): unsupported word size");
1577
1578 return;
1579 }
1580
1581 /* prepare for playback */
1582 core_audio_devin->flags |= (AGS_CORE_AUDIO_DEVIN_BUFFER7 |
1583 AGS_CORE_AUDIO_DEVIN_START_RECORD |
1584 AGS_CORE_AUDIO_DEVIN_RECORD |
1585 AGS_CORE_AUDIO_DEVIN_NONBLOCKING);
1586
1587 memset(core_audio_devin->buffer[0], 0, core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1588 memset(core_audio_devin->buffer[1], 0, core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1589 memset(core_audio_devin->buffer[2], 0, core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1590 memset(core_audio_devin->buffer[3], 0, core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1591 memset(core_audio_devin->buffer[4], 0, core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1592 memset(core_audio_devin->buffer[5], 0, core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1593 memset(core_audio_devin->buffer[6], 0, core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1594 memset(core_audio_devin->buffer[7], 0, core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1595
1596 /* */
1597 core_audio_devin->tact_counter = 0.0;
1598 core_audio_devin->delay_counter = floor(ags_soundcard_get_absolute_delay(AGS_SOUNDCARD(core_audio_devin)));
1599 core_audio_devin->tic_counter = 0;
1600
1601 core_audio_devin->flags |= (AGS_CORE_AUDIO_DEVIN_INITIALIZED |
1602 AGS_CORE_AUDIO_DEVIN_START_RECORD |
1603 AGS_CORE_AUDIO_DEVIN_RECORD);
1604
1605 g_atomic_int_or(&(core_audio_devin->sync_flags),
1606 AGS_CORE_AUDIO_DEVIN_INITIAL_CALLBACK);
1607
1608 g_rec_mutex_unlock(core_audio_devin_mutex);
1609 }
1610
1611 void
ags_core_audio_devin_port_record(AgsSoundcard * soundcard,GError ** error)1612 ags_core_audio_devin_port_record(AgsSoundcard *soundcard,
1613 GError **error)
1614 {
1615 AgsCoreAudioClient *core_audio_client;
1616 AgsCoreAudioDevin *core_audio_devin;
1617
1618 AgsTicDevice *tic_device;
1619 AgsClearBuffer *clear_buffer;
1620 AgsSwitchBufferFlag *switch_buffer_flag;
1621
1622 AgsTaskLauncher *task_launcher;
1623
1624 AgsApplicationContext *application_context;
1625
1626 GList *task;
1627 guint word_size;
1628 gboolean core_audio_client_activated;
1629
1630 GRecMutex *core_audio_devin_mutex;
1631 GRecMutex *core_audio_client_mutex;
1632 GMutex *callback_mutex;
1633 GMutex *callback_finish_mutex;
1634
1635 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1636
1637 application_context = ags_application_context_get_instance();
1638
1639 /* get core-audio devin mutex */
1640 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1641
1642 /* client */
1643 g_rec_mutex_lock(core_audio_devin_mutex);
1644
1645 core_audio_client = (AgsCoreAudioClient *) core_audio_devin->core_audio_client;
1646
1647 callback_mutex = &(core_audio_devin->callback_mutex);
1648 callback_finish_mutex = &(core_audio_devin->callback_finish_mutex);
1649
1650 /* do playback */
1651 core_audio_devin->flags &= (~AGS_CORE_AUDIO_DEVIN_START_RECORD);
1652
1653 switch(core_audio_devin->format){
1654 case AGS_SOUNDCARD_SIGNED_16_BIT:
1655 {
1656 word_size = sizeof(gint16);
1657 }
1658 break;
1659 case AGS_SOUNDCARD_SIGNED_24_BIT:
1660 {
1661 //NOTE:JK: The 24-bit linear samples use 32-bit physical space
1662 word_size = sizeof(gint32);
1663 }
1664 break;
1665 case AGS_SOUNDCARD_SIGNED_32_BIT:
1666 {
1667 word_size = sizeof(gint32);
1668 }
1669 break;
1670 default:
1671 g_rec_mutex_unlock(core_audio_devin_mutex);
1672
1673 g_warning("ags_core_audio_devin_port_record(): unsupported word size");
1674
1675 return;
1676 }
1677
1678 g_rec_mutex_unlock(core_audio_devin_mutex);
1679
1680 /* get client mutex */
1681 core_audio_client_mutex = AGS_CORE_AUDIO_CLIENT_GET_OBJ_MUTEX(core_audio_client);
1682
1683 /* get activated */
1684 g_rec_mutex_lock(core_audio_client_mutex);
1685
1686 core_audio_client_activated = ((AGS_CORE_AUDIO_CLIENT_ACTIVATED & (core_audio_client->flags)) != 0) ? TRUE: FALSE;
1687
1688 g_rec_mutex_unlock(core_audio_client_mutex);
1689
1690 if(core_audio_client_activated){
1691 while((AGS_CORE_AUDIO_DEVIN_PASS_THROUGH & (g_atomic_int_get(&(core_audio_devin->sync_flags)))) != 0){
1692 usleep(4);
1693 }
1694
1695 /* signal */
1696 if((AGS_CORE_AUDIO_DEVIN_INITIAL_CALLBACK & (g_atomic_int_get(&(core_audio_devin->sync_flags)))) == 0){
1697 g_mutex_lock(callback_mutex);
1698
1699 g_atomic_int_or(&(core_audio_devin->sync_flags),
1700 AGS_CORE_AUDIO_DEVIN_CALLBACK_DONE);
1701
1702 if((AGS_CORE_AUDIO_DEVIN_CALLBACK_WAIT & (g_atomic_int_get(&(core_audio_devin->sync_flags)))) != 0){
1703 g_cond_signal(&(core_audio_devin->callback_cond));
1704 }
1705
1706 g_mutex_unlock(callback_mutex);
1707 // }
1708
1709 /* wait callback */
1710 g_mutex_lock(callback_finish_mutex);
1711
1712 if((AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_DONE & (g_atomic_int_get(&(core_audio_devin->sync_flags)))) == 0){
1713 g_atomic_int_or(&(core_audio_devin->sync_flags),
1714 AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_WAIT);
1715
1716 while((AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_DONE & (g_atomic_int_get(&(core_audio_devin->sync_flags)))) == 0 &&
1717 (AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_WAIT & (g_atomic_int_get(&(core_audio_devin->sync_flags)))) != 0){
1718 g_cond_wait(&(core_audio_devin->callback_finish_cond),
1719 callback_finish_mutex);
1720 }
1721 }
1722
1723 g_atomic_int_and(&(core_audio_devin->sync_flags),
1724 (~(AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_WAIT |
1725 AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_DONE)));
1726
1727 g_mutex_unlock(callback_finish_mutex);
1728 }else{
1729 g_atomic_int_and(&(core_audio_devin->sync_flags),
1730 (~AGS_CORE_AUDIO_DEVIN_INITIAL_CALLBACK));
1731 }
1732 }
1733
1734 /* update soundcard */
1735 task_launcher = ags_concurrency_provider_get_task_launcher(AGS_CONCURRENCY_PROVIDER(application_context));
1736
1737 task = NULL;
1738
1739 /* tic soundcard */
1740 tic_device = ags_tic_device_new((GObject *) core_audio_devin);
1741 task = g_list_append(task,
1742 tic_device);
1743
1744 /* reset - clear buffer */
1745 clear_buffer = ags_clear_buffer_new((GObject *) core_audio_devin);
1746 task = g_list_append(task,
1747 clear_buffer);
1748
1749 /* reset - switch buffer flags */
1750 switch_buffer_flag = ags_switch_buffer_flag_new((GObject *) core_audio_devin);
1751 task = g_list_append(task,
1752 switch_buffer_flag);
1753
1754 /* append tasks */
1755 ags_task_launcher_add_task_all(task_launcher,
1756 task);
1757
1758 /* unref */
1759 g_object_unref(task_launcher);
1760 }
1761
1762 void
ags_core_audio_devin_port_free(AgsSoundcard * soundcard)1763 ags_core_audio_devin_port_free(AgsSoundcard *soundcard)
1764 {
1765 AgsCoreAudioPort *core_audio_port;
1766 AgsCoreAudioDevin *core_audio_devin;
1767
1768 guint word_size;
1769
1770 GRecMutex *core_audio_devin_mutex;
1771 GMutex *callback_mutex;
1772 GMutex *callback_finish_mutex;
1773
1774 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1775
1776 /* get core-audio devin mutex */
1777 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1778
1779 /* */
1780 g_rec_mutex_lock(core_audio_devin_mutex);
1781
1782 callback_mutex = &(core_audio_devin->callback_mutex);
1783 callback_finish_mutex = &(core_audio_devin->callback_finish_mutex);
1784
1785 // g_atomic_int_or(&(AGS_THREAD(application_context->main_loop)->flags),
1786 // AGS_THREAD_TIMING);
1787
1788 core_audio_devin->flags &= (~(AGS_CORE_AUDIO_DEVIN_BUFFER0 |
1789 AGS_CORE_AUDIO_DEVIN_BUFFER1 |
1790 AGS_CORE_AUDIO_DEVIN_BUFFER2 |
1791 AGS_CORE_AUDIO_DEVIN_BUFFER3 |
1792 AGS_CORE_AUDIO_DEVIN_BUFFER4 |
1793 AGS_CORE_AUDIO_DEVIN_BUFFER5 |
1794 AGS_CORE_AUDIO_DEVIN_BUFFER6 |
1795 AGS_CORE_AUDIO_DEVIN_BUFFER7 |
1796 AGS_CORE_AUDIO_DEVIN_RECORD));
1797
1798 g_atomic_int_or(&(core_audio_devin->sync_flags),
1799 AGS_CORE_AUDIO_DEVIN_PASS_THROUGH);
1800 g_atomic_int_and(&(core_audio_devin->sync_flags),
1801 (~AGS_CORE_AUDIO_DEVIN_INITIAL_CALLBACK));
1802
1803 /* signal callback */
1804 g_mutex_lock(callback_mutex);
1805
1806 g_atomic_int_or(&(core_audio_devin->sync_flags),
1807 AGS_CORE_AUDIO_DEVIN_CALLBACK_DONE);
1808
1809 if((AGS_CORE_AUDIO_DEVIN_CALLBACK_WAIT & (g_atomic_int_get(&(core_audio_devin->sync_flags)))) != 0){
1810 g_cond_signal(&(core_audio_devin->callback_cond));
1811 }
1812
1813 g_mutex_unlock(callback_mutex);
1814
1815 /* signal thread */
1816 g_mutex_lock(callback_finish_mutex);
1817
1818 g_atomic_int_or(&(core_audio_devin->sync_flags),
1819 AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_DONE);
1820
1821 if((AGS_CORE_AUDIO_DEVIN_CALLBACK_FINISH_WAIT & (g_atomic_int_get(&(core_audio_devin->sync_flags)))) != 0){
1822 g_cond_signal(&(core_audio_devin->callback_finish_cond));
1823 }
1824
1825 g_mutex_unlock(callback_finish_mutex);
1826
1827 /* */
1828 core_audio_devin->note_offset = core_audio_devin->start_note_offset;
1829 core_audio_devin->note_offset_absolute = core_audio_devin->start_note_offset;
1830
1831 switch(core_audio_devin->format){
1832 case AGS_SOUNDCARD_SIGNED_8_BIT:
1833 {
1834 word_size = sizeof(gint8);
1835 }
1836 break;
1837 case AGS_SOUNDCARD_SIGNED_16_BIT:
1838 {
1839 word_size = sizeof(gint16);
1840 }
1841 break;
1842 case AGS_SOUNDCARD_SIGNED_24_BIT:
1843 {
1844 word_size = sizeof(gint32);
1845 }
1846 break;
1847 case AGS_SOUNDCARD_SIGNED_32_BIT:
1848 {
1849 word_size = sizeof(gint32);
1850 }
1851 break;
1852 case AGS_SOUNDCARD_SIGNED_64_BIT:
1853 {
1854 word_size = sizeof(gint64);
1855 }
1856 break;
1857 default:
1858 word_size = 0;
1859
1860 g_critical("ags_core_audio_devin_free(): unsupported word size");
1861 }
1862
1863 g_rec_mutex_unlock(core_audio_devin_mutex);
1864
1865 if(core_audio_devin->core_audio_port != NULL){
1866 core_audio_port = core_audio_devin->core_audio_port->data;
1867
1868 while(!g_atomic_int_get(&(core_audio_port->is_empty))) usleep(500000);
1869 }
1870
1871 g_rec_mutex_lock(core_audio_devin_mutex);
1872
1873 memset(core_audio_devin->buffer[0], 0, (size_t) core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1874 memset(core_audio_devin->buffer[1], 0, (size_t) core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1875 memset(core_audio_devin->buffer[2], 0, (size_t) core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1876 memset(core_audio_devin->buffer[3], 0, (size_t) core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1877 memset(core_audio_devin->buffer[4], 0, (size_t) core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1878 memset(core_audio_devin->buffer[5], 0, (size_t) core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1879 memset(core_audio_devin->buffer[6], 0, (size_t) core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1880 memset(core_audio_devin->buffer[7], 0, (size_t) core_audio_devin->pcm_channels * core_audio_devin->buffer_size * word_size);
1881
1882 g_rec_mutex_unlock(core_audio_devin_mutex);
1883 }
1884
1885 void
ags_core_audio_devin_tic(AgsSoundcard * soundcard)1886 ags_core_audio_devin_tic(AgsSoundcard *soundcard)
1887 {
1888 AgsCoreAudioDevin *core_audio_devin;
1889
1890 gdouble delay;
1891 gdouble delay_counter;
1892 guint note_offset_absolute;
1893 guint note_offset;
1894 guint loop_left, loop_right;
1895 gboolean do_loop;
1896
1897 GRecMutex *core_audio_devin_mutex;
1898
1899 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1900
1901 /* get core_audio devin mutex */
1902 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1903
1904 /* determine if attack should be switched */
1905 g_rec_mutex_lock(core_audio_devin_mutex);
1906
1907 delay = core_audio_devin->delay[core_audio_devin->tic_counter];
1908 delay_counter = core_audio_devin->delay_counter;
1909
1910 note_offset = core_audio_devin->note_offset;
1911 note_offset_absolute = core_audio_devin->note_offset_absolute;
1912
1913 loop_left = core_audio_devin->loop_left;
1914 loop_right = core_audio_devin->loop_right;
1915
1916 do_loop = core_audio_devin->do_loop;
1917
1918 g_rec_mutex_unlock(core_audio_devin_mutex);
1919
1920 if(delay_counter + 1.0 >= floor(delay)){
1921 if(do_loop &&
1922 note_offset + 1 == loop_right){
1923 ags_soundcard_set_note_offset(soundcard,
1924 loop_left);
1925 }else{
1926 ags_soundcard_set_note_offset(soundcard,
1927 note_offset + 1);
1928 }
1929
1930 ags_soundcard_set_note_offset_absolute(soundcard,
1931 note_offset_absolute + 1);
1932
1933 /* delay */
1934 ags_soundcard_offset_changed(soundcard,
1935 note_offset);
1936
1937 /* reset - delay counter */
1938 g_rec_mutex_lock(core_audio_devin_mutex);
1939
1940 core_audio_devin->delay_counter = delay_counter + 1.0 - delay;
1941 core_audio_devin->tact_counter += 1.0;
1942
1943 g_rec_mutex_unlock(core_audio_devin_mutex);
1944 }else{
1945 g_rec_mutex_lock(core_audio_devin_mutex);
1946
1947 core_audio_devin->delay_counter += 1.0;
1948
1949 g_rec_mutex_unlock(core_audio_devin_mutex);
1950 }
1951 }
1952
1953 void
ags_core_audio_devin_offset_changed(AgsSoundcard * soundcard,guint note_offset)1954 ags_core_audio_devin_offset_changed(AgsSoundcard *soundcard,
1955 guint note_offset)
1956 {
1957 AgsCoreAudioDevin *core_audio_devin;
1958
1959 GRecMutex *core_audio_devin_mutex;
1960
1961 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1962
1963 /* get core_audio devin mutex */
1964 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1965
1966 /* offset changed */
1967 g_rec_mutex_lock(core_audio_devin_mutex);
1968
1969 core_audio_devin->tic_counter += 1;
1970
1971 if(core_audio_devin->tic_counter == AGS_SOUNDCARD_DEFAULT_PERIOD){
1972 /* reset - tic counter i.e. modified delay index within period */
1973 core_audio_devin->tic_counter = 0;
1974 }
1975
1976 g_rec_mutex_unlock(core_audio_devin_mutex);
1977 }
1978
1979 void
ags_core_audio_devin_set_bpm(AgsSoundcard * soundcard,gdouble bpm)1980 ags_core_audio_devin_set_bpm(AgsSoundcard *soundcard,
1981 gdouble bpm)
1982 {
1983 AgsCoreAudioDevin *core_audio_devin;
1984
1985 GRecMutex *core_audio_devin_mutex;
1986
1987 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
1988
1989 /* get core_audio devin mutex */
1990 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
1991
1992 /* set bpm */
1993 g_rec_mutex_lock(core_audio_devin_mutex);
1994
1995 core_audio_devin->bpm = bpm;
1996
1997 g_rec_mutex_unlock(core_audio_devin_mutex);
1998
1999 ags_core_audio_devin_adjust_delay_and_attack(core_audio_devin);
2000 }
2001
2002 gdouble
ags_core_audio_devin_get_bpm(AgsSoundcard * soundcard)2003 ags_core_audio_devin_get_bpm(AgsSoundcard *soundcard)
2004 {
2005 AgsCoreAudioDevin *core_audio_devin;
2006
2007 gdouble bpm;
2008
2009 GRecMutex *core_audio_devin_mutex;
2010
2011 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2012
2013 /* get core_audio devin mutex */
2014 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2015
2016 /* get bpm */
2017 g_rec_mutex_lock(core_audio_devin_mutex);
2018
2019 bpm = core_audio_devin->bpm;
2020
2021 g_rec_mutex_unlock(core_audio_devin_mutex);
2022
2023 return(bpm);
2024 }
2025
2026 void
ags_core_audio_devin_set_delay_factor(AgsSoundcard * soundcard,gdouble delay_factor)2027 ags_core_audio_devin_set_delay_factor(AgsSoundcard *soundcard,
2028 gdouble delay_factor)
2029 {
2030 AgsCoreAudioDevin *core_audio_devin;
2031
2032 GRecMutex *core_audio_devin_mutex;
2033
2034 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2035
2036 /* get core_audio devin mutex */
2037 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2038
2039 /* set delay factor */
2040 g_rec_mutex_lock(core_audio_devin_mutex);
2041
2042 core_audio_devin->delay_factor = delay_factor;
2043
2044 g_rec_mutex_unlock(core_audio_devin_mutex);
2045
2046 ags_core_audio_devin_adjust_delay_and_attack(core_audio_devin);
2047 }
2048
2049 gdouble
ags_core_audio_devin_get_delay_factor(AgsSoundcard * soundcard)2050 ags_core_audio_devin_get_delay_factor(AgsSoundcard *soundcard)
2051 {
2052 AgsCoreAudioDevin *core_audio_devin;
2053
2054 gdouble delay_factor;
2055
2056 GRecMutex *core_audio_devin_mutex;
2057
2058 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2059
2060 /* get core_audio devin mutex */
2061 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2062
2063 /* get delay factor */
2064 g_rec_mutex_lock(core_audio_devin_mutex);
2065
2066 delay_factor = core_audio_devin->delay_factor;
2067
2068 g_rec_mutex_unlock(core_audio_devin_mutex);
2069
2070 return(delay_factor);
2071 }
2072
2073 gdouble
ags_core_audio_devin_get_delay(AgsSoundcard * soundcard)2074 ags_core_audio_devin_get_delay(AgsSoundcard *soundcard)
2075 {
2076 AgsCoreAudioDevin *core_audio_devin;
2077
2078 guint delay_index;
2079 gdouble delay;
2080
2081 GRecMutex *core_audio_devin_mutex;
2082
2083 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2084
2085 /* get core_audio devin mutex */
2086 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2087
2088 /* get delay */
2089 g_rec_mutex_lock(core_audio_devin_mutex);
2090
2091 delay_index = core_audio_devin->tic_counter;
2092
2093 delay = core_audio_devin->delay[delay_index];
2094
2095 g_rec_mutex_unlock(core_audio_devin_mutex);
2096
2097 return(delay);
2098 }
2099
2100 gdouble
ags_core_audio_devin_get_absolute_delay(AgsSoundcard * soundcard)2101 ags_core_audio_devin_get_absolute_delay(AgsSoundcard *soundcard)
2102 {
2103 AgsCoreAudioDevin *core_audio_devin;
2104
2105 gdouble absolute_delay;
2106
2107 GRecMutex *core_audio_devin_mutex;
2108
2109 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2110
2111 /* get core_audio devin mutex */
2112 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2113
2114 /* get absolute delay */
2115 g_rec_mutex_lock(core_audio_devin_mutex);
2116
2117 absolute_delay = (60.0 * (((gdouble) core_audio_devin->samplerate / (gdouble) core_audio_devin->buffer_size) / (gdouble) core_audio_devin->bpm) * ((1.0 / 16.0) * (1.0 / (gdouble) core_audio_devin->delay_factor)));
2118
2119 g_rec_mutex_unlock(core_audio_devin_mutex);
2120
2121 return(absolute_delay);
2122 }
2123
2124 guint
ags_core_audio_devin_get_attack(AgsSoundcard * soundcard)2125 ags_core_audio_devin_get_attack(AgsSoundcard *soundcard)
2126 {
2127 AgsCoreAudioDevin *core_audio_devin;
2128
2129 guint attack_index;
2130 guint attack;
2131
2132 GRecMutex *core_audio_devin_mutex;
2133
2134 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2135
2136 /* get core_audio devin mutex */
2137 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2138
2139 /* get attack */
2140 g_rec_mutex_lock(core_audio_devin_mutex);
2141
2142 attack_index = core_audio_devin->tic_counter;
2143
2144 attack = core_audio_devin->attack[attack_index];
2145
2146 g_rec_mutex_unlock(core_audio_devin_mutex);
2147
2148 return(attack);
2149 }
2150
2151 void*
ags_core_audio_devin_get_buffer(AgsSoundcard * soundcard)2152 ags_core_audio_devin_get_buffer(AgsSoundcard *soundcard)
2153 {
2154 AgsCoreAudioDevin *core_audio_devin;
2155
2156 void *buffer;
2157
2158 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2159
2160 if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER0)){
2161 buffer = core_audio_devin->buffer[0];
2162 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER1)){
2163 buffer = core_audio_devin->buffer[1];
2164 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER2)){
2165 buffer = core_audio_devin->buffer[2];
2166 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER3)){
2167 buffer = core_audio_devin->buffer[3];
2168 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER4)){
2169 buffer = core_audio_devin->buffer[4];
2170 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER5)){
2171 buffer = core_audio_devin->buffer[5];
2172 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER6)){
2173 buffer = core_audio_devin->buffer[6];
2174 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER7)){
2175 buffer = core_audio_devin->buffer[7];
2176 }else{
2177 buffer = NULL;
2178 }
2179
2180 return(buffer);
2181 }
2182
2183 void*
ags_core_audio_devin_get_next_buffer(AgsSoundcard * soundcard)2184 ags_core_audio_devin_get_next_buffer(AgsSoundcard *soundcard)
2185 {
2186 AgsCoreAudioDevin *core_audio_devin;
2187
2188 void *buffer;
2189
2190 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2191
2192 // g_message("next - 0x%0x", ((AGS_CORE_AUDIO_DEVIN_BUFFER0 |
2193 // AGS_CORE_AUDIO_DEVIN_BUFFER1 |
2194 // AGS_CORE_AUDIO_DEVIN_BUFFER2 |
2195 // AGS_CORE_AUDIO_DEVIN_BUFFER3) & (core_audio_devin->flags)));
2196
2197 if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER0)){
2198 buffer = core_audio_devin->buffer[1];
2199 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER1)){
2200 buffer = core_audio_devin->buffer[2];
2201 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER2)){
2202 buffer = core_audio_devin->buffer[3];
2203 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER3)){
2204 buffer = core_audio_devin->buffer[4];
2205 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER4)){
2206 buffer = core_audio_devin->buffer[5];
2207 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER5)){
2208 buffer = core_audio_devin->buffer[6];
2209 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER6)){
2210 buffer = core_audio_devin->buffer[7];
2211 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER7)){
2212 buffer = core_audio_devin->buffer[0];
2213 }else{
2214 buffer = NULL;
2215 }
2216
2217 return(buffer);
2218 }
2219
2220 void*
ags_core_audio_devin_get_prev_buffer(AgsSoundcard * soundcard)2221 ags_core_audio_devin_get_prev_buffer(AgsSoundcard *soundcard)
2222 {
2223 AgsCoreAudioDevin *core_audio_devin;
2224
2225 void *buffer;
2226
2227 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2228
2229 if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER0)){
2230 buffer = core_audio_devin->buffer[7];
2231 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER1)){
2232 buffer = core_audio_devin->buffer[0];
2233 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER2)){
2234 buffer = core_audio_devin->buffer[1];
2235 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER3)){
2236 buffer = core_audio_devin->buffer[2];
2237 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER4)){
2238 buffer = core_audio_devin->buffer[3];
2239 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER5)){
2240 buffer = core_audio_devin->buffer[4];
2241 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER6)){
2242 buffer = core_audio_devin->buffer[5];
2243 }else if(ags_core_audio_devin_test_flags(core_audio_devin, AGS_CORE_AUDIO_DEVIN_BUFFER7)){
2244 buffer = core_audio_devin->buffer[6];
2245 }else{
2246 buffer = NULL;
2247 }
2248
2249 return(buffer);
2250 }
2251
2252 void
ags_core_audio_devin_lock_buffer(AgsSoundcard * soundcard,void * buffer)2253 ags_core_audio_devin_lock_buffer(AgsSoundcard *soundcard,
2254 void *buffer)
2255 {
2256 AgsCoreAudioDevin *core_audio_devin;
2257
2258 GRecMutex *buffer_mutex;
2259
2260 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2261
2262 buffer_mutex = NULL;
2263
2264 if(core_audio_devin->buffer != NULL){
2265 if(buffer == core_audio_devin->buffer[0]){
2266 buffer_mutex = core_audio_devin->buffer_mutex[0];
2267 }else if(buffer == core_audio_devin->buffer[1]){
2268 buffer_mutex = core_audio_devin->buffer_mutex[1];
2269 }else if(buffer == core_audio_devin->buffer[2]){
2270 buffer_mutex = core_audio_devin->buffer_mutex[2];
2271 }else if(buffer == core_audio_devin->buffer[3]){
2272 buffer_mutex = core_audio_devin->buffer_mutex[3];
2273 }else if(buffer == core_audio_devin->buffer[4]){
2274 buffer_mutex = core_audio_devin->buffer_mutex[4];
2275 }else if(buffer == core_audio_devin->buffer[5]){
2276 buffer_mutex = core_audio_devin->buffer_mutex[5];
2277 }else if(buffer == core_audio_devin->buffer[6]){
2278 buffer_mutex = core_audio_devin->buffer_mutex[6];
2279 }else if(buffer == core_audio_devin->buffer[7]){
2280 buffer_mutex = core_audio_devin->buffer_mutex[7];
2281 }
2282 }
2283
2284 if(buffer_mutex != NULL){
2285 g_rec_mutex_lock(buffer_mutex);
2286 }
2287 }
2288
2289 void
ags_core_audio_devin_unlock_buffer(AgsSoundcard * soundcard,void * buffer)2290 ags_core_audio_devin_unlock_buffer(AgsSoundcard *soundcard,
2291 void *buffer)
2292 {
2293 AgsCoreAudioDevin *core_audio_devin;
2294
2295 GRecMutex *buffer_mutex;
2296
2297 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2298
2299 buffer_mutex = NULL;
2300
2301 if(core_audio_devin->buffer != NULL){
2302 if(buffer == core_audio_devin->buffer[0]){
2303 buffer_mutex = core_audio_devin->buffer_mutex[0];
2304 }else if(buffer == core_audio_devin->buffer[1]){
2305 buffer_mutex = core_audio_devin->buffer_mutex[1];
2306 }else if(buffer == core_audio_devin->buffer[2]){
2307 buffer_mutex = core_audio_devin->buffer_mutex[2];
2308 }else if(buffer == core_audio_devin->buffer[3]){
2309 buffer_mutex = core_audio_devin->buffer_mutex[3];
2310 }else if(buffer == core_audio_devin->buffer[4]){
2311 buffer_mutex = core_audio_devin->buffer_mutex[4];
2312 }else if(buffer == core_audio_devin->buffer[5]){
2313 buffer_mutex = core_audio_devin->buffer_mutex[5];
2314 }else if(buffer == core_audio_devin->buffer[6]){
2315 buffer_mutex = core_audio_devin->buffer_mutex[6];
2316 }else if(buffer == core_audio_devin->buffer[7]){
2317 buffer_mutex = core_audio_devin->buffer_mutex[7];
2318 }
2319 }
2320
2321 if(buffer_mutex != NULL){
2322 g_rec_mutex_unlock(buffer_mutex);
2323 }
2324 }
2325
2326 guint
ags_core_audio_devin_get_delay_counter(AgsSoundcard * soundcard)2327 ags_core_audio_devin_get_delay_counter(AgsSoundcard *soundcard)
2328 {
2329 AgsCoreAudioDevin *core_audio_devin;
2330
2331 guint delay_counter;
2332
2333 GRecMutex *core_audio_devin_mutex;
2334
2335 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2336
2337 /* get core_audio devin mutex */
2338 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2339
2340 /* delay counter */
2341 g_rec_mutex_lock(core_audio_devin_mutex);
2342
2343 delay_counter = core_audio_devin->delay_counter;
2344
2345 g_rec_mutex_unlock(core_audio_devin_mutex);
2346
2347 return(delay_counter);
2348 }
2349
2350 void
ags_core_audio_devin_set_note_offset(AgsSoundcard * soundcard,guint note_offset)2351 ags_core_audio_devin_set_note_offset(AgsSoundcard *soundcard,
2352 guint note_offset)
2353 {
2354 AgsCoreAudioDevin *core_audio_devin;
2355
2356 GRecMutex *core_audio_devin_mutex;
2357
2358 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2359
2360 /* get core_audio devin mutex */
2361 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2362
2363 /* set note offset */
2364 g_rec_mutex_lock(core_audio_devin_mutex);
2365
2366 core_audio_devin->note_offset = note_offset;
2367
2368 g_rec_mutex_unlock(core_audio_devin_mutex);
2369 }
2370
2371 guint
ags_core_audio_devin_get_start_note_offset(AgsSoundcard * soundcard)2372 ags_core_audio_devin_get_start_note_offset(AgsSoundcard *soundcard)
2373 {
2374 AgsCoreAudioDevin *core_audio_devin;
2375
2376 guint start_note_offset;
2377
2378 GRecMutex *core_audio_devin_mutex;
2379
2380 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2381
2382 /* get core_audio devin mutex */
2383 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2384
2385 /* set note offset */
2386 g_rec_mutex_lock(core_audio_devin_mutex);
2387
2388 start_note_offset = core_audio_devin->start_note_offset;
2389
2390 g_rec_mutex_unlock(core_audio_devin_mutex);
2391
2392 return(start_note_offset);
2393 }
2394
2395 void
ags_core_audio_devin_set_start_note_offset(AgsSoundcard * soundcard,guint start_note_offset)2396 ags_core_audio_devin_set_start_note_offset(AgsSoundcard *soundcard,
2397 guint start_note_offset)
2398 {
2399 AgsCoreAudioDevin *core_audio_devin;
2400
2401 GRecMutex *core_audio_devin_mutex;
2402
2403 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2404
2405 /* get core_audio devin mutex */
2406 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2407
2408 /* set note offset */
2409 g_rec_mutex_lock(core_audio_devin_mutex);
2410
2411 core_audio_devin->start_note_offset = start_note_offset;
2412
2413 g_rec_mutex_unlock(core_audio_devin_mutex);
2414 }
2415
2416 guint
ags_core_audio_devin_get_note_offset(AgsSoundcard * soundcard)2417 ags_core_audio_devin_get_note_offset(AgsSoundcard *soundcard)
2418 {
2419 AgsCoreAudioDevin *core_audio_devin;
2420
2421 guint note_offset;
2422
2423 GRecMutex *core_audio_devin_mutex;
2424
2425 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2426
2427 /* get core_audio devin mutex */
2428 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2429
2430 /* set note offset */
2431 g_rec_mutex_lock(core_audio_devin_mutex);
2432
2433 note_offset = core_audio_devin->note_offset;
2434
2435 g_rec_mutex_unlock(core_audio_devin_mutex);
2436
2437 return(note_offset);
2438 }
2439
2440 void
ags_core_audio_devin_set_note_offset_absolute(AgsSoundcard * soundcard,guint note_offset_absolute)2441 ags_core_audio_devin_set_note_offset_absolute(AgsSoundcard *soundcard,
2442 guint note_offset_absolute)
2443 {
2444 AgsCoreAudioDevin *core_audio_devin;
2445
2446 GRecMutex *core_audio_devin_mutex;
2447
2448 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2449
2450 /* get core_audio devin mutex */
2451 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2452
2453 /* set note offset */
2454 g_rec_mutex_lock(core_audio_devin_mutex);
2455
2456 core_audio_devin->note_offset_absolute = note_offset_absolute;
2457
2458 g_rec_mutex_unlock(core_audio_devin_mutex);
2459 }
2460
2461 guint
ags_core_audio_devin_get_note_offset_absolute(AgsSoundcard * soundcard)2462 ags_core_audio_devin_get_note_offset_absolute(AgsSoundcard *soundcard)
2463 {
2464 AgsCoreAudioDevin *core_audio_devin;
2465
2466 guint note_offset_absolute;
2467
2468 GRecMutex *core_audio_devin_mutex;
2469
2470 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2471
2472 /* get core_audio devin mutex */
2473 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2474
2475 /* set note offset */
2476 g_rec_mutex_lock(core_audio_devin_mutex);
2477
2478 note_offset_absolute = core_audio_devin->note_offset_absolute;
2479
2480 g_rec_mutex_unlock(core_audio_devin_mutex);
2481
2482 return(note_offset_absolute);
2483 }
2484
2485 void
ags_core_audio_devin_set_loop(AgsSoundcard * soundcard,guint loop_left,guint loop_right,gboolean do_loop)2486 ags_core_audio_devin_set_loop(AgsSoundcard *soundcard,
2487 guint loop_left, guint loop_right,
2488 gboolean do_loop)
2489 {
2490 AgsCoreAudioDevin *core_audio_devin;
2491
2492 GRecMutex *core_audio_devin_mutex;
2493
2494 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2495
2496 /* get core_audio devin mutex */
2497 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2498
2499 /* set loop */
2500 g_rec_mutex_lock(core_audio_devin_mutex);
2501
2502 core_audio_devin->loop_left = loop_left;
2503 core_audio_devin->loop_right = loop_right;
2504 core_audio_devin->do_loop = do_loop;
2505
2506 if(do_loop){
2507 core_audio_devin->loop_offset = core_audio_devin->note_offset;
2508 }
2509
2510 g_rec_mutex_unlock(core_audio_devin_mutex);
2511 }
2512
2513 void
ags_core_audio_devin_get_loop(AgsSoundcard * soundcard,guint * loop_left,guint * loop_right,gboolean * do_loop)2514 ags_core_audio_devin_get_loop(AgsSoundcard *soundcard,
2515 guint *loop_left, guint *loop_right,
2516 gboolean *do_loop)
2517 {
2518 AgsCoreAudioDevin *core_audio_devin;
2519
2520 GRecMutex *core_audio_devin_mutex;
2521
2522 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2523
2524 /* get core_audio devin mutex */
2525 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2526
2527 /* get loop */
2528 g_rec_mutex_lock(core_audio_devin_mutex);
2529
2530 if(loop_left != NULL){
2531 *loop_left = core_audio_devin->loop_left;
2532 }
2533
2534 if(loop_right != NULL){
2535 *loop_right = core_audio_devin->loop_right;
2536 }
2537
2538 if(do_loop != NULL){
2539 *do_loop = core_audio_devin->do_loop;
2540 }
2541
2542 g_rec_mutex_unlock(core_audio_devin_mutex);
2543 }
2544
2545 guint
ags_core_audio_devin_get_loop_offset(AgsSoundcard * soundcard)2546 ags_core_audio_devin_get_loop_offset(AgsSoundcard *soundcard)
2547 {
2548 AgsCoreAudioDevin *core_audio_devin;
2549
2550 guint loop_offset;
2551
2552 GRecMutex *core_audio_devin_mutex;
2553
2554 core_audio_devin = AGS_CORE_AUDIO_DEVIN(soundcard);
2555
2556 /* get core_audio devin mutex */
2557 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2558
2559 /* get loop offset */
2560 g_rec_mutex_lock(core_audio_devin_mutex);
2561
2562 loop_offset = core_audio_devin->loop_offset;
2563
2564 g_rec_mutex_unlock(core_audio_devin_mutex);
2565
2566 return(loop_offset);
2567 }
2568
2569
2570 /**
2571 * ags_core_audio_devin_switch_buffer_flag:
2572 * @core_audio_devin: an #AgsCoreAudioDevin
2573 *
2574 * The buffer flag indicates the currently played buffer.
2575 *
2576 * Since: 3.0.0
2577 */
2578 void
ags_core_audio_devin_switch_buffer_flag(AgsCoreAudioDevin * core_audio_devin)2579 ags_core_audio_devin_switch_buffer_flag(AgsCoreAudioDevin *core_audio_devin)
2580 {
2581 GRecMutex *core_audio_devin_mutex;
2582
2583 if(!AGS_IS_CORE_AUDIO_DEVIN(core_audio_devin)){
2584 return;
2585 }
2586
2587 /* get core_audio devin mutex */
2588 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2589
2590 /* switch buffer flag */
2591 g_rec_mutex_lock(core_audio_devin_mutex);
2592
2593 if((AGS_CORE_AUDIO_DEVIN_BUFFER0 & (core_audio_devin->flags)) != 0){
2594 core_audio_devin->flags &= (~AGS_CORE_AUDIO_DEVIN_BUFFER0);
2595 core_audio_devin->flags |= AGS_CORE_AUDIO_DEVIN_BUFFER1;
2596 }else if((AGS_CORE_AUDIO_DEVIN_BUFFER1 & (core_audio_devin->flags)) != 0){
2597 core_audio_devin->flags &= (~AGS_CORE_AUDIO_DEVIN_BUFFER1);
2598 core_audio_devin->flags |= AGS_CORE_AUDIO_DEVIN_BUFFER2;
2599 }else if((AGS_CORE_AUDIO_DEVIN_BUFFER2 & (core_audio_devin->flags)) != 0){
2600 core_audio_devin->flags &= (~AGS_CORE_AUDIO_DEVIN_BUFFER2);
2601 core_audio_devin->flags |= AGS_CORE_AUDIO_DEVIN_BUFFER3;
2602 }else if((AGS_CORE_AUDIO_DEVIN_BUFFER3 & (core_audio_devin->flags)) != 0){
2603 core_audio_devin->flags &= (~AGS_CORE_AUDIO_DEVIN_BUFFER3);
2604 core_audio_devin->flags |= AGS_CORE_AUDIO_DEVIN_BUFFER4;
2605 }else if((AGS_CORE_AUDIO_DEVIN_BUFFER4 & (core_audio_devin->flags)) != 0){
2606 core_audio_devin->flags &= (~AGS_CORE_AUDIO_DEVIN_BUFFER4);
2607 core_audio_devin->flags |= AGS_CORE_AUDIO_DEVIN_BUFFER5;
2608 }else if((AGS_CORE_AUDIO_DEVIN_BUFFER5 & (core_audio_devin->flags)) != 0){
2609 core_audio_devin->flags &= (~AGS_CORE_AUDIO_DEVIN_BUFFER5);
2610 core_audio_devin->flags |= AGS_CORE_AUDIO_DEVIN_BUFFER6;
2611 }else if((AGS_CORE_AUDIO_DEVIN_BUFFER6 & (core_audio_devin->flags)) != 0){
2612 core_audio_devin->flags &= (~AGS_CORE_AUDIO_DEVIN_BUFFER6);
2613 core_audio_devin->flags |= AGS_CORE_AUDIO_DEVIN_BUFFER7;
2614 }else if((AGS_CORE_AUDIO_DEVIN_BUFFER7 & (core_audio_devin->flags)) != 0){
2615 core_audio_devin->flags &= (~AGS_CORE_AUDIO_DEVIN_BUFFER7);
2616 core_audio_devin->flags |= AGS_CORE_AUDIO_DEVIN_BUFFER0;
2617 }
2618
2619 g_rec_mutex_unlock(core_audio_devin_mutex);
2620 }
2621
2622 /**
2623 * ags_core_audio_devin_adjust_delay_and_attack:
2624 * @core_audio_devin: the #AgsCoreAudioDevin
2625 *
2626 * Calculate delay and attack and reset it.
2627 *
2628 * Since: 3.0.0
2629 */
2630 void
ags_core_audio_devin_adjust_delay_and_attack(AgsCoreAudioDevin * core_audio_devin)2631 ags_core_audio_devin_adjust_delay_and_attack(AgsCoreAudioDevin *core_audio_devin)
2632 {
2633 if(!AGS_IS_CORE_AUDIO_DEVIN(core_audio_devin)){
2634 return;
2635 }
2636
2637 ags_soundcard_util_adjust_delay_and_attack(core_audio_devin);
2638 }
2639
2640 /**
2641 * ags_core_audio_devin_realloc_buffer:
2642 * @core_audio_devin: the #AgsCoreAudioDevin
2643 *
2644 * Reallocate the internal audio buffer.
2645 *
2646 * Since: 3.0.0
2647 */
2648 void
ags_core_audio_devin_realloc_buffer(AgsCoreAudioDevin * core_audio_devin)2649 ags_core_audio_devin_realloc_buffer(AgsCoreAudioDevin *core_audio_devin)
2650 {
2651 guint pcm_channels;
2652 guint buffer_size;
2653 guint format;
2654 guint word_size;
2655
2656 GRecMutex *core_audio_devin_mutex;
2657
2658 if(!AGS_IS_CORE_AUDIO_DEVIN(core_audio_devin)){
2659 return;
2660 }
2661
2662 /* get core_audio devin mutex */
2663 core_audio_devin_mutex = AGS_CORE_AUDIO_DEVIN_GET_OBJ_MUTEX(core_audio_devin);
2664
2665 /* get word size */
2666 g_rec_mutex_lock(core_audio_devin_mutex);
2667
2668 pcm_channels = core_audio_devin->pcm_channels;
2669 buffer_size = core_audio_devin->buffer_size;
2670
2671 format = core_audio_devin->format;
2672
2673 g_rec_mutex_unlock(core_audio_devin_mutex);
2674
2675 switch(format){
2676 case AGS_SOUNDCARD_SIGNED_16_BIT:
2677 {
2678 word_size = sizeof(gint16);
2679 }
2680 break;
2681 case AGS_SOUNDCARD_SIGNED_24_BIT:
2682 {
2683 word_size = sizeof(gint32);
2684 }
2685 break;
2686 case AGS_SOUNDCARD_SIGNED_32_BIT:
2687 {
2688 word_size = sizeof(gint32);
2689 }
2690 break;
2691 default:
2692 g_warning("ags_core_audio_devin_realloc_buffer(): unsupported word size");
2693 return;
2694 }
2695
2696 /* AGS_CORE_AUDIO_DEVIN_BUFFER_0 */
2697 if(core_audio_devin->buffer[0] != NULL){
2698 free(core_audio_devin->buffer[0]);
2699 }
2700
2701 core_audio_devin->buffer[0] = (void *) malloc(pcm_channels * buffer_size * word_size);
2702
2703 /* AGS_CORE_AUDIO_DEVIN_BUFFER_1 */
2704 if(core_audio_devin->buffer[1] != NULL){
2705 free(core_audio_devin->buffer[1]);
2706 }
2707
2708 core_audio_devin->buffer[1] = (void *) malloc(pcm_channels * buffer_size * word_size);
2709
2710 /* AGS_CORE_AUDIO_DEVIN_BUFFER_2 */
2711 if(core_audio_devin->buffer[2] != NULL){
2712 free(core_audio_devin->buffer[2]);
2713 }
2714
2715 core_audio_devin->buffer[2] = (void *) malloc(pcm_channels * buffer_size * word_size);
2716
2717 /* AGS_CORE_AUDIO_DEVIN_BUFFER_3 */
2718 if(core_audio_devin->buffer[3] != NULL){
2719 free(core_audio_devin->buffer[3]);
2720 }
2721
2722 core_audio_devin->buffer[3] = (void *) malloc(pcm_channels * buffer_size * word_size);
2723
2724 /* AGS_CORE_AUDIO_DEVIN_BUFFER_4 */
2725 if(core_audio_devin->buffer[4] != NULL){
2726 free(core_audio_devin->buffer[4]);
2727 }
2728
2729 core_audio_devin->buffer[4] = (void *) malloc(pcm_channels * buffer_size * word_size);
2730
2731 /* AGS_CORE_AUDIO_DEVIN_BUFFER_5 */
2732 if(core_audio_devin->buffer[5] != NULL){
2733 free(core_audio_devin->buffer[5]);
2734 }
2735
2736 core_audio_devin->buffer[5] = (void *) malloc(pcm_channels * buffer_size * word_size);
2737
2738 /* AGS_CORE_AUDIO_DEVIN_BUFFER_6 */
2739 if(core_audio_devin->buffer[6] != NULL){
2740 free(core_audio_devin->buffer[6]);
2741 }
2742
2743 core_audio_devin->buffer[6] = (void *) malloc(pcm_channels * buffer_size * word_size);
2744
2745 /* AGS_CORE_AUDIO_DEVIN_BUFFER_7 */
2746 if(core_audio_devin->buffer[7] != NULL){
2747 free(core_audio_devin->buffer[7]);
2748 }
2749
2750 core_audio_devin->buffer[7] = (void *) malloc(pcm_channels * buffer_size * word_size);
2751 }
2752
2753 /**
2754 * ags_core_audio_devin_new:
2755 *
2756 * Creates a new instance of #AgsCoreAudioDevin.
2757 *
2758 * Returns: a new #AgsCoreAudioDevin
2759 *
2760 * Since: 3.0.0
2761 */
2762 AgsCoreAudioDevin*
ags_core_audio_devin_new()2763 ags_core_audio_devin_new()
2764 {
2765 AgsCoreAudioDevin *core_audio_devin;
2766
2767 core_audio_devin = (AgsCoreAudioDevin *) g_object_new(AGS_TYPE_CORE_AUDIO_DEVIN,
2768 NULL);
2769
2770 return(core_audio_devin);
2771 }
2772