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_devout.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_devout_class_init(AgsCoreAudioDevoutClass *core_audio_devout);
44 void ags_core_audio_devout_connectable_interface_init(AgsConnectableInterface *connectable);
45 void ags_core_audio_devout_soundcard_interface_init(AgsSoundcardInterface *soundcard);
46 void ags_core_audio_devout_init(AgsCoreAudioDevout *core_audio_devout);
47 void ags_core_audio_devout_set_property(GObject *gobject,
48 guint prop_id,
49 const GValue *value,
50 GParamSpec *param_spec);
51 void ags_core_audio_devout_get_property(GObject *gobject,
52 guint prop_id,
53 GValue *value,
54 GParamSpec *param_spec);
55 void ags_core_audio_devout_dispose(GObject *gobject);
56 void ags_core_audio_devout_finalize(GObject *gobject);
57
58 AgsUUID* ags_core_audio_devout_get_uuid(AgsConnectable *connectable);
59 gboolean ags_core_audio_devout_has_resource(AgsConnectable *connectable);
60 gboolean ags_core_audio_devout_is_ready(AgsConnectable *connectable);
61 void ags_core_audio_devout_add_to_registry(AgsConnectable *connectable);
62 void ags_core_audio_devout_remove_from_registry(AgsConnectable *connectable);
63 xmlNode* ags_core_audio_devout_list_resource(AgsConnectable *connectable);
64 xmlNode* ags_core_audio_devout_xml_compose(AgsConnectable *connectable);
65 void ags_core_audio_devout_xml_parse(AgsConnectable *connectable,
66 xmlNode *node);
67 gboolean ags_core_audio_devout_is_connected(AgsConnectable *connectable);
68 void ags_core_audio_devout_connect(AgsConnectable *connectable);
69 void ags_core_audio_devout_disconnect(AgsConnectable *connectable);
70
71 void ags_core_audio_devout_set_device(AgsSoundcard *soundcard,
72 gchar *device);
73 gchar* ags_core_audio_devout_get_device(AgsSoundcard *soundcard);
74
75 void ags_core_audio_devout_set_presets(AgsSoundcard *soundcard,
76 guint channels,
77 guint rate,
78 guint buffer_size,
79 guint format);
80 void ags_core_audio_devout_get_presets(AgsSoundcard *soundcard,
81 guint *channels,
82 guint *rate,
83 guint *buffer_size,
84 guint *format);
85
86 void ags_core_audio_devout_list_cards(AgsSoundcard *soundcard,
87 GList **card_id, GList **card_name);
88 void ags_core_audio_devout_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_devout_get_capability(AgsSoundcard *soundcard);
94
95 gboolean ags_core_audio_devout_is_starting(AgsSoundcard *soundcard);
96 gboolean ags_core_audio_devout_is_playing(AgsSoundcard *soundcard);
97
98 gchar* ags_core_audio_devout_get_uptime(AgsSoundcard *soundcard);
99
100 void ags_core_audio_devout_port_init(AgsSoundcard *soundcard,
101 GError **error);
102 void ags_core_audio_devout_port_play(AgsSoundcard *soundcard,
103 GError **error);
104 void ags_core_audio_devout_port_free(AgsSoundcard *soundcard);
105
106 void ags_core_audio_devout_tic(AgsSoundcard *soundcard);
107 void ags_core_audio_devout_offset_changed(AgsSoundcard *soundcard,
108 guint note_offset);
109
110 void ags_core_audio_devout_set_bpm(AgsSoundcard *soundcard,
111 gdouble bpm);
112 gdouble ags_core_audio_devout_get_bpm(AgsSoundcard *soundcard);
113
114 void ags_core_audio_devout_set_delay_factor(AgsSoundcard *soundcard,
115 gdouble delay_factor);
116 gdouble ags_core_audio_devout_get_delay_factor(AgsSoundcard *soundcard);
117
118 gdouble ags_core_audio_devout_get_absolute_delay(AgsSoundcard *soundcard);
119
120 gdouble ags_core_audio_devout_get_delay(AgsSoundcard *soundcard);
121 guint ags_core_audio_devout_get_attack(AgsSoundcard *soundcard);
122
123 void* ags_core_audio_devout_get_buffer(AgsSoundcard *soundcard);
124 void* ags_core_audio_devout_get_next_buffer(AgsSoundcard *soundcard);
125 void* ags_core_audio_devout_get_prev_buffer(AgsSoundcard *soundcard);
126
127 void ags_core_audio_devout_lock_buffer(AgsSoundcard *soundcard,
128 void *buffer);
129 void ags_core_audio_devout_unlock_buffer(AgsSoundcard *soundcard,
130 void *buffer);
131
132 guint ags_core_audio_devout_get_delay_counter(AgsSoundcard *soundcard);
133
134 void ags_core_audio_devout_set_start_note_offset(AgsSoundcard *soundcard,
135 guint start_note_offset);
136 guint ags_core_audio_devout_get_start_note_offset(AgsSoundcard *soundcard);
137
138 void ags_core_audio_devout_set_note_offset(AgsSoundcard *soundcard,
139 guint note_offset);
140 guint ags_core_audio_devout_get_note_offset(AgsSoundcard *soundcard);
141
142 void ags_core_audio_devout_set_note_offset_absolute(AgsSoundcard *soundcard,
143 guint note_offset);
144 guint ags_core_audio_devout_get_note_offset_absolute(AgsSoundcard *soundcard);
145
146 void ags_core_audio_devout_set_loop(AgsSoundcard *soundcard,
147 guint loop_left, guint loop_right,
148 gboolean do_loop);
149 void ags_core_audio_devout_get_loop(AgsSoundcard *soundcard,
150 guint *loop_left, guint *loop_right,
151 gboolean *do_loop);
152
153 guint ags_core_audio_devout_get_loop_offset(AgsSoundcard *soundcard);
154
155 guint ags_core_audio_devout_get_sub_block_count(AgsSoundcard *soundcard);
156
157 gboolean ags_core_audio_devout_trylock_sub_block(AgsSoundcard *soundcard,
158 void *buffer, guint sub_block);
159 void ags_core_audio_devout_unlock_sub_block(AgsSoundcard *soundcard,
160 void *buffer, guint sub_block);
161
162 /**
163 * SECTION:ags_core_audio_devout
164 * @short_description: Output to soundcard
165 * @title: AgsCoreAudioDevout
166 * @section_id:
167 * @include: ags/audio/core-audio/ags_core_audio_devout.h
168 *
169 * #AgsCoreAudioDevout represents a soundcard and supports output.
170 */
171
172 enum{
173 PROP_0,
174 PROP_DEVICE,
175 PROP_DSP_CHANNELS,
176 PROP_PCM_CHANNELS,
177 PROP_FORMAT,
178 PROP_BUFFER_SIZE,
179 PROP_SAMPLERATE,
180 PROP_BUFFER,
181 PROP_BPM,
182 PROP_DELAY_FACTOR,
183 PROP_ATTACK,
184 PROP_CORE_AUDIO_CLIENT,
185 PROP_CORE_AUDIO_PORT,
186 PROP_CHANNEL,
187 };
188
189 static gpointer ags_core_audio_devout_parent_class = NULL;
190
191 GType
ags_core_audio_devout_get_type(void)192 ags_core_audio_devout_get_type (void)
193 {
194 static volatile gsize g_define_type_id__volatile = 0;
195
196 if(g_once_init_enter (&g_define_type_id__volatile)){
197 GType ags_type_core_audio_devout = 0;
198
199 static const GTypeInfo ags_core_audio_devout_info = {
200 sizeof(AgsCoreAudioDevoutClass),
201 NULL, /* base_init */
202 NULL, /* base_finalize */
203 (GClassInitFunc) ags_core_audio_devout_class_init,
204 NULL, /* class_finalize */
205 NULL, /* class_data */
206 sizeof(AgsCoreAudioDevout),
207 0, /* n_preallocs */
208 (GInstanceInitFunc) ags_core_audio_devout_init,
209 };
210
211 static const GInterfaceInfo ags_connectable_interface_info = {
212 (GInterfaceInitFunc) ags_core_audio_devout_connectable_interface_init,
213 NULL, /* interface_finalize */
214 NULL, /* interface_data */
215 };
216
217 static const GInterfaceInfo ags_soundcard_interface_info = {
218 (GInterfaceInitFunc) ags_core_audio_devout_soundcard_interface_init,
219 NULL, /* interface_finalize */
220 NULL, /* interface_data */
221 };
222
223 ags_type_core_audio_devout = g_type_register_static(G_TYPE_OBJECT,
224 "AgsCoreAudioDevout",
225 &ags_core_audio_devout_info,
226 0);
227
228 g_type_add_interface_static(ags_type_core_audio_devout,
229 AGS_TYPE_CONNECTABLE,
230 &ags_connectable_interface_info);
231
232 g_type_add_interface_static(ags_type_core_audio_devout,
233 AGS_TYPE_SOUNDCARD,
234 &ags_soundcard_interface_info);
235
236 g_once_init_leave(&g_define_type_id__volatile, ags_type_core_audio_devout);
237 }
238
239 return g_define_type_id__volatile;
240 }
241
242 void
ags_core_audio_devout_class_init(AgsCoreAudioDevoutClass * core_audio_devout)243 ags_core_audio_devout_class_init(AgsCoreAudioDevoutClass *core_audio_devout)
244 {
245 GObjectClass *gobject;
246 GParamSpec *param_spec;
247
248 ags_core_audio_devout_parent_class = g_type_class_peek_parent(core_audio_devout);
249
250 /* GObjectClass */
251 gobject = (GObjectClass *) core_audio_devout;
252
253 gobject->set_property = ags_core_audio_devout_set_property;
254 gobject->get_property = ags_core_audio_devout_get_property;
255
256 gobject->dispose = ags_core_audio_devout_dispose;
257 gobject->finalize = ags_core_audio_devout_finalize;
258
259 /* properties */
260 /**
261 * AgsCoreAudioDevout:device:
262 *
263 * The core audio soundcard indentifier
264 *
265 * Since: 3.0.0
266 */
267 param_spec = g_param_spec_string("device",
268 i18n_pspec("the device identifier"),
269 i18n_pspec("The device to perform output to"),
270 "ags-core-audio-devout-0",
271 G_PARAM_READABLE | G_PARAM_WRITABLE);
272 g_object_class_install_property(gobject,
273 PROP_DEVICE,
274 param_spec);
275
276 /**
277 * AgsCoreAudioDevout:dsp-channels:
278 *
279 * The dsp channel count
280 *
281 * Since: 3.0.0
282 */
283 param_spec = g_param_spec_uint("dsp-channels",
284 i18n_pspec("count of DSP channels"),
285 i18n_pspec("The count of DSP channels to use"),
286 1,
287 64,
288 2,
289 G_PARAM_READABLE | G_PARAM_WRITABLE);
290 g_object_class_install_property(gobject,
291 PROP_DSP_CHANNELS,
292 param_spec);
293
294 /**
295 * AgsCoreAudioDevout:pcm-channels:
296 *
297 * The pcm channel count
298 *
299 * Since: 3.0.0
300 */
301 param_spec = g_param_spec_uint("pcm-channels",
302 i18n_pspec("count of PCM channels"),
303 i18n_pspec("The count of PCM channels to use"),
304 1,
305 64,
306 2,
307 G_PARAM_READABLE | G_PARAM_WRITABLE);
308 g_object_class_install_property(gobject,
309 PROP_PCM_CHANNELS,
310 param_spec);
311
312 /**
313 * AgsCoreAudioDevout:format:
314 *
315 * The precision of the buffer
316 *
317 * Since: 3.0.0
318 */
319 param_spec = g_param_spec_uint("format",
320 i18n_pspec("precision of buffer"),
321 i18n_pspec("The precision to use for a frame"),
322 1,
323 64,
324 AGS_SOUNDCARD_DEFAULT_FORMAT,
325 G_PARAM_READABLE | G_PARAM_WRITABLE);
326 g_object_class_install_property(gobject,
327 PROP_FORMAT,
328 param_spec);
329
330 /**
331 * AgsCoreAudioDevout:buffer-size:
332 *
333 * The buffer size
334 *
335 * Since: 3.0.0
336 */
337 param_spec = g_param_spec_uint("buffer-size",
338 i18n_pspec("frame count of a buffer"),
339 i18n_pspec("The count of frames a buffer contains"),
340 1,
341 44100,
342 940,
343 G_PARAM_READABLE | G_PARAM_WRITABLE);
344 g_object_class_install_property(gobject,
345 PROP_BUFFER_SIZE,
346 param_spec);
347
348 /**
349 * AgsCoreAudioDevout:samplerate:
350 *
351 * The samplerate
352 *
353 * Since: 3.0.0
354 */
355 param_spec = g_param_spec_uint("samplerate",
356 i18n_pspec("frames per second"),
357 i18n_pspec("The frames count played during a second"),
358 8000,
359 96000,
360 44100,
361 G_PARAM_READABLE | G_PARAM_WRITABLE);
362 g_object_class_install_property(gobject,
363 PROP_SAMPLERATE,
364 param_spec);
365
366 /**
367 * AgsCoreAudioDevout:buffer:
368 *
369 * The buffer
370 *
371 * Since: 3.0.0
372 */
373 param_spec = g_param_spec_pointer("buffer",
374 i18n_pspec("the buffer"),
375 i18n_pspec("The buffer to play"),
376 G_PARAM_READABLE);
377 g_object_class_install_property(gobject,
378 PROP_BUFFER,
379 param_spec);
380
381 /**
382 * AgsCoreAudioDevout:bpm:
383 *
384 * Beats per minute
385 *
386 * Since: 3.0.0
387 */
388 param_spec = g_param_spec_double("bpm",
389 i18n_pspec("beats per minute"),
390 i18n_pspec("Beats per minute to use"),
391 1.0,
392 240.0,
393 120.0,
394 G_PARAM_READABLE | G_PARAM_WRITABLE);
395 g_object_class_install_property(gobject,
396 PROP_BPM,
397 param_spec);
398
399 /**
400 * AgsCoreAudioDevout:delay-factor:
401 *
402 * tact
403 *
404 * Since: 3.0.0
405 */
406 param_spec = g_param_spec_double("delay-factor",
407 i18n_pspec("delay factor"),
408 i18n_pspec("The delay factor"),
409 0.0,
410 16.0,
411 1.0,
412 G_PARAM_READABLE | G_PARAM_WRITABLE);
413 g_object_class_install_property(gobject,
414 PROP_DELAY_FACTOR,
415 param_spec);
416
417 /**
418 * AgsCoreAudioDevout:attack:
419 *
420 * Attack of the buffer
421 *
422 * Since: 3.0.0
423 */
424 param_spec = g_param_spec_pointer("attack",
425 i18n_pspec("attack of buffer"),
426 i18n_pspec("The attack to use for the buffer"),
427 G_PARAM_READABLE);
428 g_object_class_install_property(gobject,
429 PROP_ATTACK,
430 param_spec);
431
432
433 /**
434 * AgsCoreAudioDevout:core-audio-client:
435 *
436 * The assigned #AgsCoreAudioClient
437 *
438 * Since: 3.0.0
439 */
440 param_spec = g_param_spec_object("core-audio-client",
441 i18n_pspec("core audio client object"),
442 i18n_pspec("The core audio client object"),
443 AGS_TYPE_CORE_AUDIO_CLIENT,
444 G_PARAM_READABLE | G_PARAM_WRITABLE);
445 g_object_class_install_property(gobject,
446 PROP_CORE_AUDIO_CLIENT,
447 param_spec);
448
449 /**
450 * AgsCoreAudioDevout:core-audio-port:
451 *
452 * The assigned #AgsCoreAudioPort
453 *
454 * Since: 3.0.0
455 */
456 param_spec = g_param_spec_pointer("core-audio-port",
457 i18n_pspec("core audio port object"),
458 i18n_pspec("The core audio port object"),
459 G_PARAM_READABLE | G_PARAM_WRITABLE);
460 g_object_class_install_property(gobject,
461 PROP_CORE_AUDIO_PORT,
462 param_spec);
463 }
464
465 GQuark
ags_core_audio_devout_error_quark()466 ags_core_audio_devout_error_quark()
467 {
468 return(g_quark_from_static_string("ags-core_audio_devout-error-quark"));
469 }
470
471 void
ags_core_audio_devout_connectable_interface_init(AgsConnectableInterface * connectable)472 ags_core_audio_devout_connectable_interface_init(AgsConnectableInterface *connectable)
473 {
474 connectable->get_uuid = ags_core_audio_devout_get_uuid;
475 connectable->has_resource = ags_core_audio_devout_has_resource;
476
477 connectable->is_ready = ags_core_audio_devout_is_ready;
478 connectable->add_to_registry = ags_core_audio_devout_add_to_registry;
479 connectable->remove_from_registry = ags_core_audio_devout_remove_from_registry;
480
481 connectable->list_resource = ags_core_audio_devout_list_resource;
482 connectable->xml_compose = ags_core_audio_devout_xml_compose;
483 connectable->xml_parse = ags_core_audio_devout_xml_parse;
484
485 connectable->is_connected = ags_core_audio_devout_is_connected;
486 connectable->connect = ags_core_audio_devout_connect;
487 connectable->disconnect = ags_core_audio_devout_disconnect;
488
489 connectable->connect_connection = NULL;
490 connectable->disconnect_connection = NULL;
491 }
492
493 void
ags_core_audio_devout_soundcard_interface_init(AgsSoundcardInterface * soundcard)494 ags_core_audio_devout_soundcard_interface_init(AgsSoundcardInterface *soundcard)
495 {
496 soundcard->set_device = ags_core_audio_devout_set_device;
497 soundcard->get_device = ags_core_audio_devout_get_device;
498
499 soundcard->set_presets = ags_core_audio_devout_set_presets;
500 soundcard->get_presets = ags_core_audio_devout_get_presets;
501
502 soundcard->list_cards = ags_core_audio_devout_list_cards;
503 soundcard->pcm_info = ags_core_audio_devout_pcm_info;
504 soundcard->get_capability = ags_core_audio_devout_get_capability;
505
506 soundcard->is_available = NULL;
507
508 soundcard->is_starting = ags_core_audio_devout_is_starting;
509 soundcard->is_playing = ags_core_audio_devout_is_playing;
510 soundcard->is_recording = NULL;
511
512 soundcard->get_uptime = ags_core_audio_devout_get_uptime;
513
514 soundcard->play_init = ags_core_audio_devout_port_init;
515 soundcard->play = ags_core_audio_devout_port_play;
516
517 soundcard->record_init = NULL;
518 soundcard->record = NULL;
519
520 soundcard->stop = ags_core_audio_devout_port_free;
521
522 soundcard->tic = ags_core_audio_devout_tic;
523 soundcard->offset_changed = ags_core_audio_devout_offset_changed;
524
525 soundcard->set_bpm = ags_core_audio_devout_set_bpm;
526 soundcard->get_bpm = ags_core_audio_devout_get_bpm;
527
528 soundcard->set_delay_factor = ags_core_audio_devout_set_delay_factor;
529 soundcard->get_delay_factor = ags_core_audio_devout_get_delay_factor;
530
531 soundcard->get_absolute_delay = ags_core_audio_devout_get_absolute_delay;
532
533 soundcard->get_delay = ags_core_audio_devout_get_delay;
534 soundcard->get_attack = ags_core_audio_devout_get_attack;
535
536 soundcard->get_buffer = ags_core_audio_devout_get_buffer;
537 soundcard->get_next_buffer = ags_core_audio_devout_get_next_buffer;
538 soundcard->get_prev_buffer = ags_core_audio_devout_get_prev_buffer;
539
540 soundcard->lock_buffer = ags_core_audio_devout_lock_buffer;
541 soundcard->unlock_buffer = ags_core_audio_devout_unlock_buffer;
542
543 soundcard->get_delay_counter = ags_core_audio_devout_get_delay_counter;
544
545 soundcard->set_start_note_offset = ags_core_audio_devout_set_start_note_offset;
546 soundcard->get_start_note_offset = ags_core_audio_devout_get_start_note_offset;
547
548 soundcard->set_note_offset = ags_core_audio_devout_set_note_offset;
549 soundcard->get_note_offset = ags_core_audio_devout_get_note_offset;
550
551 soundcard->set_note_offset_absolute = ags_core_audio_devout_set_note_offset_absolute;
552 soundcard->get_note_offset_absolute = ags_core_audio_devout_get_note_offset_absolute;
553
554 soundcard->set_loop = ags_core_audio_devout_set_loop;
555 soundcard->get_loop = ags_core_audio_devout_get_loop;
556
557 soundcard->get_loop_offset = ags_core_audio_devout_get_loop_offset;
558
559 soundcard->get_sub_block_count = ags_core_audio_devout_get_sub_block_count;
560
561 soundcard->trylock_sub_block = ags_core_audio_devout_trylock_sub_block;
562 soundcard->unlock_sub_block = ags_core_audio_devout_unlock_sub_block;
563 }
564
565 void
ags_core_audio_devout_init(AgsCoreAudioDevout * core_audio_devout)566 ags_core_audio_devout_init(AgsCoreAudioDevout *core_audio_devout)
567 {
568 AgsConfig *config;
569
570 gchar *str;
571 gchar *segmentation;
572
573 guint denominator, numerator;
574 guint i;
575
576 /* flags */
577 core_audio_devout->flags = 0;
578 g_atomic_int_set(&(core_audio_devout->sync_flags),
579 AGS_CORE_AUDIO_DEVOUT_PASS_THROUGH);
580
581 /* devout mutex */
582 g_rec_mutex_init(&(core_audio_devout->obj_mutex));
583
584 /* uuid */
585 core_audio_devout->uuid = ags_uuid_alloc();
586 ags_uuid_generate(core_audio_devout->uuid);
587
588 /* presets */
589 config = ags_config_get_instance();
590
591 core_audio_devout->dsp_channels = ags_soundcard_helper_config_get_dsp_channels(config);
592 core_audio_devout->pcm_channels = ags_soundcard_helper_config_get_pcm_channels(config);
593
594 core_audio_devout->samplerate = ags_soundcard_helper_config_get_samplerate(config);
595 core_audio_devout->buffer_size = ags_soundcard_helper_config_get_buffer_size(config);
596 core_audio_devout->format = ags_soundcard_helper_config_get_format(config);
597
598 /* */
599 core_audio_devout->card_uri = NULL;
600 core_audio_devout->core_audio_client = NULL;
601
602 core_audio_devout->port_name = NULL;
603 core_audio_devout->core_audio_port = NULL;
604
605 /* buffer */
606 core_audio_devout->buffer_mutex = (GRecMutex **) malloc(8 * sizeof(GRecMutex *));
607
608 for(i = 0; i < 8; i++){
609 core_audio_devout->buffer_mutex[i] = (GRecMutex *) malloc(sizeof(GRecMutex));
610
611 g_rec_mutex_init(core_audio_devout->buffer_mutex[i]);
612 }
613
614 core_audio_devout->sub_block_count = AGS_SOUNDCARD_DEFAULT_SUB_BLOCK_COUNT;
615 core_audio_devout->sub_block_mutex = (GRecMutex **) malloc(8 * core_audio_devout->sub_block_count * core_audio_devout->pcm_channels * sizeof(GRecMutex *));
616
617 for(i = 0; i < 8 * core_audio_devout->sub_block_count * core_audio_devout->pcm_channels; i++){
618 core_audio_devout->sub_block_mutex[i] = (GRecMutex *) malloc(sizeof(GRecMutex));
619
620 g_rec_mutex_init(core_audio_devout->sub_block_mutex[i]);
621 }
622
623 core_audio_devout->buffer = (void **) malloc(8 * sizeof(void*));
624
625 core_audio_devout->buffer[0] = NULL;
626 core_audio_devout->buffer[1] = NULL;
627 core_audio_devout->buffer[2] = NULL;
628 core_audio_devout->buffer[3] = NULL;
629 core_audio_devout->buffer[4] = NULL;
630 core_audio_devout->buffer[5] = NULL;
631 core_audio_devout->buffer[6] = NULL;
632 core_audio_devout->buffer[7] = NULL;
633
634 ags_core_audio_devout_realloc_buffer(core_audio_devout);
635
636 /* bpm */
637 core_audio_devout->bpm = AGS_SOUNDCARD_DEFAULT_BPM;
638
639 /* delay factor */
640 core_audio_devout->delay_factor = AGS_SOUNDCARD_DEFAULT_DELAY_FACTOR;
641
642 /* segmentation */
643 segmentation = ags_config_get_value(config,
644 AGS_CONFIG_GENERIC,
645 "segmentation");
646
647 if(segmentation != NULL){
648 sscanf(segmentation, "%d/%d",
649 &denominator,
650 &numerator);
651
652 core_audio_devout->delay_factor = 1.0 / numerator * (numerator / denominator);
653
654 g_free(segmentation);
655 }
656
657 /* delay and attack */
658 core_audio_devout->delay = (gdouble *) malloc((int) 2 * AGS_SOUNDCARD_DEFAULT_PERIOD *
659 sizeof(gdouble));
660
661 core_audio_devout->attack = (guint *) malloc((int) 2 * AGS_SOUNDCARD_DEFAULT_PERIOD *
662 sizeof(guint));
663
664 ags_core_audio_devout_adjust_delay_and_attack(core_audio_devout);
665
666 /* counters */
667 core_audio_devout->tact_counter = 0.0;
668 core_audio_devout->delay_counter = 0.0;
669 core_audio_devout->tic_counter = 0;
670
671 core_audio_devout->start_note_offset = 0;
672 core_audio_devout->note_offset = 0;
673 core_audio_devout->note_offset_absolute = 0;
674
675 core_audio_devout->loop_left = AGS_SOUNDCARD_DEFAULT_LOOP_LEFT;
676 core_audio_devout->loop_right = AGS_SOUNDCARD_DEFAULT_LOOP_RIGHT;
677
678 core_audio_devout->do_loop = FALSE;
679
680 core_audio_devout->loop_offset = 0;
681
682 /* callback mutex */
683 g_mutex_init(&(core_audio_devout->callback_mutex));
684
685 g_cond_init(&(core_audio_devout->callback_cond));
686
687 /* callback finish mutex */
688 g_mutex_init(&(core_audio_devout->callback_finish_mutex));
689
690 g_cond_init(&(core_audio_devout->callback_finish_cond));
691 }
692
693 void
ags_core_audio_devout_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)694 ags_core_audio_devout_set_property(GObject *gobject,
695 guint prop_id,
696 const GValue *value,
697 GParamSpec *param_spec)
698 {
699 AgsCoreAudioDevout *core_audio_devout;
700
701 GRecMutex *core_audio_devout_mutex;
702
703 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(gobject);
704
705 /* get core_audio devout mutex */
706 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
707
708 switch(prop_id){
709 case PROP_DEVICE:
710 {
711 char *device;
712
713 device = (char *) g_value_get_string(value);
714
715 g_rec_mutex_lock(core_audio_devout_mutex);
716
717 core_audio_devout->card_uri = g_strdup(device);
718
719 g_rec_mutex_unlock(core_audio_devout_mutex);
720 }
721 break;
722 case PROP_DSP_CHANNELS:
723 {
724 guint dsp_channels;
725
726 dsp_channels = g_value_get_uint(value);
727
728 g_rec_mutex_lock(core_audio_devout_mutex);
729
730 if(dsp_channels == core_audio_devout->dsp_channels){
731 g_rec_mutex_unlock(core_audio_devout_mutex);
732
733 return;
734 }
735
736 core_audio_devout->dsp_channels = dsp_channels;
737
738 g_rec_mutex_unlock(core_audio_devout_mutex);
739 }
740 break;
741 case PROP_PCM_CHANNELS:
742 {
743 guint pcm_channels, old_pcm_channels;
744 guint i;
745
746 pcm_channels = g_value_get_uint(value);
747
748 g_rec_mutex_lock(core_audio_devout_mutex);
749
750 if(pcm_channels == core_audio_devout->pcm_channels){
751 g_rec_mutex_unlock(core_audio_devout_mutex);
752
753 return;
754 }
755
756 old_pcm_channels = core_audio_devout->pcm_channels;
757
758 /* destroy if less pcm-channels */
759 for(i = 8 * core_audio_devout->sub_block_count * pcm_channels; i < 8 * core_audio_devout->sub_block_count * old_pcm_channels; i++){
760 g_rec_mutex_clear(core_audio_devout->sub_block_mutex[i]);
761
762 free(core_audio_devout->sub_block_mutex[i]);
763 }
764
765 core_audio_devout->sub_block_mutex = (GRecMutex **) realloc(core_audio_devout->sub_block_mutex,
766 8 * core_audio_devout->sub_block_count * pcm_channels * sizeof(GRecMutex *));
767
768 /* create if more pcm-channels */
769 for(i = 8 * core_audio_devout->sub_block_count * old_pcm_channels; i < 8 * core_audio_devout->sub_block_count * pcm_channels; i++){
770 core_audio_devout->sub_block_mutex[i] = (GRecMutex *) malloc(sizeof(GRecMutex));
771
772 g_rec_mutex_init(core_audio_devout->sub_block_mutex[i]);
773 }
774
775 core_audio_devout->pcm_channels = pcm_channels;
776
777 g_rec_mutex_unlock(core_audio_devout_mutex);
778
779 ags_core_audio_devout_realloc_buffer(core_audio_devout);
780 }
781 break;
782 case PROP_FORMAT:
783 {
784 guint format;
785
786 format = g_value_get_uint(value);
787
788 g_rec_mutex_lock(core_audio_devout_mutex);
789
790 if(format == core_audio_devout->format){
791 g_rec_mutex_unlock(core_audio_devout_mutex);
792
793 return;
794 }
795
796 core_audio_devout->format = format;
797
798 g_rec_mutex_unlock(core_audio_devout_mutex);
799
800 ags_core_audio_devout_realloc_buffer(core_audio_devout);
801 }
802 break;
803 case PROP_BUFFER_SIZE:
804 {
805 guint buffer_size;
806
807 buffer_size = g_value_get_uint(value);
808
809 g_rec_mutex_lock(core_audio_devout_mutex);
810
811 if(buffer_size == core_audio_devout->buffer_size){
812 g_rec_mutex_unlock(core_audio_devout_mutex);
813
814 return;
815 }
816
817 core_audio_devout->buffer_size = buffer_size;
818
819 g_rec_mutex_unlock(core_audio_devout_mutex);
820
821 ags_core_audio_devout_realloc_buffer(core_audio_devout);
822 ags_core_audio_devout_adjust_delay_and_attack(core_audio_devout);
823 }
824 break;
825 case PROP_SAMPLERATE:
826 {
827 guint samplerate;
828
829 samplerate = g_value_get_uint(value);
830
831 g_rec_mutex_lock(core_audio_devout_mutex);
832
833 if(samplerate == core_audio_devout->samplerate){
834 g_rec_mutex_unlock(core_audio_devout_mutex);
835
836 return;
837 }
838
839 core_audio_devout->samplerate = samplerate;
840
841 g_rec_mutex_unlock(core_audio_devout_mutex);
842
843 ags_core_audio_devout_realloc_buffer(core_audio_devout);
844 ags_core_audio_devout_adjust_delay_and_attack(core_audio_devout);
845 }
846 break;
847 case PROP_BUFFER:
848 {
849 //TODO:JK: implement me
850 }
851 break;
852 case PROP_BPM:
853 {
854 gdouble bpm;
855
856 bpm = g_value_get_double(value);
857
858 g_rec_mutex_lock(core_audio_devout_mutex);
859
860 core_audio_devout->bpm = bpm;
861
862 g_rec_mutex_unlock(core_audio_devout_mutex);
863
864 ags_core_audio_devout_adjust_delay_and_attack(core_audio_devout);
865 }
866 break;
867 case PROP_DELAY_FACTOR:
868 {
869 gdouble delay_factor;
870
871 delay_factor = g_value_get_double(value);
872
873 g_rec_mutex_lock(core_audio_devout_mutex);
874
875 core_audio_devout->delay_factor = delay_factor;
876
877 g_rec_mutex_unlock(core_audio_devout_mutex);
878
879 ags_core_audio_devout_adjust_delay_and_attack(core_audio_devout);
880 }
881 break;
882 case PROP_CORE_AUDIO_CLIENT:
883 {
884 AgsCoreAudioClient *core_audio_client;
885
886 core_audio_client = (AgsCoreAudioClient *) g_value_get_object(value);
887
888 g_rec_mutex_lock(core_audio_devout_mutex);
889
890 if(core_audio_devout->core_audio_client == (GObject *) core_audio_client){
891 g_rec_mutex_unlock(core_audio_devout_mutex);
892
893 return;
894 }
895
896 if(core_audio_devout->core_audio_client != NULL){
897 g_object_unref(G_OBJECT(core_audio_devout->core_audio_client));
898 }
899
900 if(core_audio_client != NULL){
901 g_object_ref(core_audio_client);
902 }
903
904 core_audio_devout->core_audio_client = (GObject *) core_audio_client;
905
906 g_rec_mutex_unlock(core_audio_devout_mutex);
907 }
908 break;
909 case PROP_CORE_AUDIO_PORT:
910 {
911 AgsCoreAudioPort *core_audio_port;
912
913 core_audio_port = (AgsCoreAudioPort *) g_value_get_pointer(value);
914
915 g_rec_mutex_lock(core_audio_devout_mutex);
916
917 if(!AGS_IS_CORE_AUDIO_PORT(core_audio_port) ||
918 g_list_find(core_audio_devout->core_audio_port, core_audio_port) != NULL){
919 g_rec_mutex_unlock(core_audio_devout_mutex);
920
921 return;
922 }
923
924 g_object_ref(core_audio_port);
925 core_audio_devout->core_audio_port = g_list_append(core_audio_devout->core_audio_port,
926 core_audio_port);
927
928 g_rec_mutex_unlock(core_audio_devout_mutex);
929 }
930 break;
931 default:
932 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
933 break;
934 }
935 }
936
937 void
ags_core_audio_devout_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)938 ags_core_audio_devout_get_property(GObject *gobject,
939 guint prop_id,
940 GValue *value,
941 GParamSpec *param_spec)
942 {
943 AgsCoreAudioDevout *core_audio_devout;
944
945 GRecMutex *core_audio_devout_mutex;
946
947 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(gobject);
948
949 /* get core_audio devout mutex */
950 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
951
952 switch(prop_id){
953 case PROP_DEVICE:
954 {
955 g_rec_mutex_lock(core_audio_devout_mutex);
956
957 g_value_set_string(value, core_audio_devout->card_uri);
958
959 g_rec_mutex_unlock(core_audio_devout_mutex);
960 }
961 break;
962 case PROP_DSP_CHANNELS:
963 {
964 g_rec_mutex_lock(core_audio_devout_mutex);
965
966 g_value_set_uint(value, core_audio_devout->dsp_channels);
967
968 g_rec_mutex_unlock(core_audio_devout_mutex);
969 }
970 break;
971 case PROP_PCM_CHANNELS:
972 {
973 g_rec_mutex_lock(core_audio_devout_mutex);
974
975 g_value_set_uint(value, core_audio_devout->pcm_channels);
976
977 g_rec_mutex_unlock(core_audio_devout_mutex);
978 }
979 break;
980 case PROP_FORMAT:
981 {
982 g_rec_mutex_lock(core_audio_devout_mutex);
983
984 g_value_set_uint(value, core_audio_devout->format);
985
986 g_rec_mutex_unlock(core_audio_devout_mutex);
987 }
988 break;
989 case PROP_BUFFER_SIZE:
990 {
991 g_rec_mutex_lock(core_audio_devout_mutex);
992
993 g_value_set_uint(value, core_audio_devout->buffer_size);
994
995 g_rec_mutex_unlock(core_audio_devout_mutex);
996 }
997 break;
998 case PROP_SAMPLERATE:
999 {
1000 g_rec_mutex_lock(core_audio_devout_mutex);
1001
1002 g_value_set_uint(value, core_audio_devout->samplerate);
1003
1004 g_rec_mutex_unlock(core_audio_devout_mutex);
1005 }
1006 break;
1007 case PROP_BUFFER:
1008 {
1009 g_rec_mutex_lock(core_audio_devout_mutex);
1010
1011 g_value_set_pointer(value, core_audio_devout->buffer);
1012
1013 g_rec_mutex_unlock(core_audio_devout_mutex);
1014 }
1015 break;
1016 case PROP_BPM:
1017 {
1018 g_rec_mutex_lock(core_audio_devout_mutex);
1019
1020 g_value_set_double(value, core_audio_devout->bpm);
1021
1022 g_rec_mutex_unlock(core_audio_devout_mutex);
1023 }
1024 break;
1025 case PROP_DELAY_FACTOR:
1026 {
1027 g_rec_mutex_lock(core_audio_devout_mutex);
1028
1029 g_value_set_double(value, core_audio_devout->delay_factor);
1030
1031 g_rec_mutex_unlock(core_audio_devout_mutex);
1032 }
1033 break;
1034 case PROP_ATTACK:
1035 {
1036 g_rec_mutex_lock(core_audio_devout_mutex);
1037
1038 g_value_set_pointer(value, core_audio_devout->attack);
1039
1040 g_rec_mutex_unlock(core_audio_devout_mutex);
1041 }
1042 break;
1043 case PROP_CORE_AUDIO_CLIENT:
1044 {
1045 g_rec_mutex_lock(core_audio_devout_mutex);
1046
1047 g_value_set_object(value, core_audio_devout->core_audio_client);
1048
1049 g_rec_mutex_unlock(core_audio_devout_mutex);
1050 }
1051 break;
1052 case PROP_CORE_AUDIO_PORT:
1053 {
1054 g_rec_mutex_lock(core_audio_devout_mutex);
1055
1056 g_value_set_pointer(value,
1057 g_list_copy_deep(core_audio_devout->core_audio_port,
1058 (GCopyFunc) g_object_ref,
1059 NULL));
1060
1061 g_rec_mutex_unlock(core_audio_devout_mutex);
1062 }
1063 break;
1064 default:
1065 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
1066 break;
1067 }
1068 }
1069
1070 void
ags_core_audio_devout_dispose(GObject * gobject)1071 ags_core_audio_devout_dispose(GObject *gobject)
1072 {
1073 AgsCoreAudioDevout *core_audio_devout;
1074
1075 GList *list;
1076
1077 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(gobject);
1078
1079 /* core_audio client */
1080 if(core_audio_devout->core_audio_client != NULL){
1081 g_object_unref(core_audio_devout->core_audio_client);
1082
1083 core_audio_devout->core_audio_client = NULL;
1084 }
1085
1086 /* core_audio port */
1087 g_list_free_full(core_audio_devout->core_audio_port,
1088 g_object_unref);
1089
1090 core_audio_devout->core_audio_port = NULL;
1091
1092 /* call parent */
1093 G_OBJECT_CLASS(ags_core_audio_devout_parent_class)->dispose(gobject);
1094 }
1095
1096 void
ags_core_audio_devout_finalize(GObject * gobject)1097 ags_core_audio_devout_finalize(GObject *gobject)
1098 {
1099 AgsCoreAudioDevout *core_audio_devout;
1100
1101 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(gobject);
1102
1103 /* free output buffer */
1104 free(core_audio_devout->buffer[0]);
1105 free(core_audio_devout->buffer[1]);
1106 free(core_audio_devout->buffer[2]);
1107 free(core_audio_devout->buffer[3]);
1108 free(core_audio_devout->buffer[4]);
1109 free(core_audio_devout->buffer[5]);
1110 free(core_audio_devout->buffer[6]);
1111 free(core_audio_devout->buffer[7]);
1112
1113 /* free buffer array */
1114 free(core_audio_devout->buffer);
1115
1116 /* free AgsAttack */
1117 free(core_audio_devout->attack);
1118
1119 /* core_audio client */
1120 if(core_audio_devout->core_audio_client != NULL){
1121 g_object_unref(core_audio_devout->core_audio_client);
1122 }
1123
1124 /* core_audio port */
1125 g_list_free_full(core_audio_devout->core_audio_port,
1126 g_object_unref);
1127
1128 /* call parent */
1129 G_OBJECT_CLASS(ags_core_audio_devout_parent_class)->finalize(gobject);
1130 }
1131
1132 AgsUUID*
ags_core_audio_devout_get_uuid(AgsConnectable * connectable)1133 ags_core_audio_devout_get_uuid(AgsConnectable *connectable)
1134 {
1135 AgsCoreAudioDevout *core_audio_devout;
1136
1137 AgsUUID *ptr;
1138
1139 GRecMutex *core_audio_devout_mutex;
1140
1141 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(connectable);
1142
1143 /* get core_audio devout signal mutex */
1144 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1145
1146 /* get UUID */
1147 g_rec_mutex_lock(core_audio_devout_mutex);
1148
1149 ptr = core_audio_devout->uuid;
1150
1151 g_rec_mutex_unlock(core_audio_devout_mutex);
1152
1153 return(ptr);
1154 }
1155
1156 gboolean
ags_core_audio_devout_has_resource(AgsConnectable * connectable)1157 ags_core_audio_devout_has_resource(AgsConnectable *connectable)
1158 {
1159 return(FALSE);
1160 }
1161
1162 gboolean
ags_core_audio_devout_is_ready(AgsConnectable * connectable)1163 ags_core_audio_devout_is_ready(AgsConnectable *connectable)
1164 {
1165 AgsCoreAudioDevout *core_audio_devout;
1166
1167 gboolean is_ready;
1168
1169 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(connectable);
1170
1171 /* check is added */
1172 is_ready = ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_ADDED_TO_REGISTRY);
1173
1174 return(is_ready);
1175 }
1176
1177 void
ags_core_audio_devout_add_to_registry(AgsConnectable * connectable)1178 ags_core_audio_devout_add_to_registry(AgsConnectable *connectable)
1179 {
1180 AgsCoreAudioDevout *core_audio_devout;
1181
1182 if(ags_connectable_is_ready(connectable)){
1183 return;
1184 }
1185
1186 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(connectable);
1187
1188 ags_core_audio_devout_set_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_ADDED_TO_REGISTRY);
1189 }
1190
1191 void
ags_core_audio_devout_remove_from_registry(AgsConnectable * connectable)1192 ags_core_audio_devout_remove_from_registry(AgsConnectable *connectable)
1193 {
1194 AgsCoreAudioDevout *core_audio_devout;
1195
1196 if(!ags_connectable_is_ready(connectable)){
1197 return;
1198 }
1199
1200 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(connectable);
1201
1202 ags_core_audio_devout_unset_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_ADDED_TO_REGISTRY);
1203 }
1204
1205 xmlNode*
ags_core_audio_devout_list_resource(AgsConnectable * connectable)1206 ags_core_audio_devout_list_resource(AgsConnectable *connectable)
1207 {
1208 xmlNode *node;
1209
1210 node = NULL;
1211
1212 //TODO:JK: implement me
1213
1214 return(node);
1215 }
1216
1217 xmlNode*
ags_core_audio_devout_xml_compose(AgsConnectable * connectable)1218 ags_core_audio_devout_xml_compose(AgsConnectable *connectable)
1219 {
1220 xmlNode *node;
1221
1222 node = NULL;
1223
1224 //TODO:JK: implement me
1225
1226 return(node);
1227 }
1228
1229 void
ags_core_audio_devout_xml_parse(AgsConnectable * connectable,xmlNode * node)1230 ags_core_audio_devout_xml_parse(AgsConnectable *connectable,
1231 xmlNode *node)
1232 {
1233 //TODO:JK: implement me
1234 }
1235
1236 gboolean
ags_core_audio_devout_is_connected(AgsConnectable * connectable)1237 ags_core_audio_devout_is_connected(AgsConnectable *connectable)
1238 {
1239 AgsCoreAudioDevout *core_audio_devout;
1240
1241 gboolean is_connected;
1242
1243 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(connectable);
1244
1245 /* check is connected */
1246 is_connected = ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_CONNECTED);
1247
1248 return(is_connected);
1249 }
1250
1251 void
ags_core_audio_devout_connect(AgsConnectable * connectable)1252 ags_core_audio_devout_connect(AgsConnectable *connectable)
1253 {
1254 AgsCoreAudioDevout *core_audio_devout;
1255
1256 if(ags_connectable_is_connected(connectable)){
1257 return;
1258 }
1259
1260 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(connectable);
1261
1262 ags_core_audio_devout_set_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_CONNECTED);
1263 }
1264
1265 void
ags_core_audio_devout_disconnect(AgsConnectable * connectable)1266 ags_core_audio_devout_disconnect(AgsConnectable *connectable)
1267 {
1268
1269 AgsCoreAudioDevout *core_audio_devout;
1270
1271 if(!ags_connectable_is_connected(connectable)){
1272 return;
1273 }
1274
1275 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(connectable);
1276
1277 ags_core_audio_devout_unset_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_CONNECTED);
1278 }
1279
1280 /**
1281 * ags_core_audio_devout_test_flags:
1282 * @core_audio_devout: the #AgsCoreAudioDevout
1283 * @flags: the flags
1284 *
1285 * Test @flags to be set on @core_audio_devout.
1286 *
1287 * Returns: %TRUE if flags are set, else %FALSE
1288 *
1289 * Since: 3.0.0
1290 */
1291 gboolean
ags_core_audio_devout_test_flags(AgsCoreAudioDevout * core_audio_devout,guint flags)1292 ags_core_audio_devout_test_flags(AgsCoreAudioDevout *core_audio_devout, guint flags)
1293 {
1294 gboolean retval;
1295
1296 GRecMutex *core_audio_devout_mutex;
1297
1298 if(!AGS_IS_CORE_AUDIO_DEVOUT(core_audio_devout)){
1299 return(FALSE);
1300 }
1301
1302 /* get core_audio devout mutex */
1303 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1304
1305 /* test */
1306 g_rec_mutex_lock(core_audio_devout_mutex);
1307
1308 retval = (flags & (core_audio_devout->flags)) ? TRUE: FALSE;
1309
1310 g_rec_mutex_unlock(core_audio_devout_mutex);
1311
1312 return(retval);
1313 }
1314
1315 /**
1316 * ags_core_audio_devout_set_flags:
1317 * @core_audio_devout: the #AgsCoreAudioDevout
1318 * @flags: see #AgsCoreAudioDevoutFlags-enum
1319 *
1320 * Enable a feature of @core_audio_devout.
1321 *
1322 * Since: 3.0.0
1323 */
1324 void
ags_core_audio_devout_set_flags(AgsCoreAudioDevout * core_audio_devout,guint flags)1325 ags_core_audio_devout_set_flags(AgsCoreAudioDevout *core_audio_devout, guint flags)
1326 {
1327 GRecMutex *core_audio_devout_mutex;
1328
1329 if(!AGS_IS_CORE_AUDIO_DEVOUT(core_audio_devout)){
1330 return;
1331 }
1332
1333 /* get core_audio devout mutex */
1334 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1335
1336 //TODO:JK: add more?
1337
1338 /* set flags */
1339 g_rec_mutex_lock(core_audio_devout_mutex);
1340
1341 core_audio_devout->flags |= flags;
1342
1343 g_rec_mutex_unlock(core_audio_devout_mutex);
1344 }
1345
1346 /**
1347 * ags_core_audio_devout_unset_flags:
1348 * @core_audio_devout: the #AgsCoreAudioDevout
1349 * @flags: see #AgsCoreAudioDevoutFlags-enum
1350 *
1351 * Disable a feature of @core_audio_devout.
1352 *
1353 * Since: 3.0.0
1354 */
1355 void
ags_core_audio_devout_unset_flags(AgsCoreAudioDevout * core_audio_devout,guint flags)1356 ags_core_audio_devout_unset_flags(AgsCoreAudioDevout *core_audio_devout, guint flags)
1357 {
1358 GRecMutex *core_audio_devout_mutex;
1359
1360 if(!AGS_IS_CORE_AUDIO_DEVOUT(core_audio_devout)){
1361 return;
1362 }
1363
1364 /* get core_audio devout mutex */
1365 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1366
1367 //TODO:JK: add more?
1368
1369 /* unset flags */
1370 g_rec_mutex_lock(core_audio_devout_mutex);
1371
1372 core_audio_devout->flags &= (~flags);
1373
1374 g_rec_mutex_unlock(core_audio_devout_mutex);
1375 }
1376
1377 void
ags_core_audio_devout_set_device(AgsSoundcard * soundcard,gchar * device)1378 ags_core_audio_devout_set_device(AgsSoundcard *soundcard,
1379 gchar *device)
1380 {
1381 AgsCoreAudioDevout *core_audio_devout;
1382
1383 GList *core_audio_port, *core_audio_port_start;
1384
1385 gchar *str;
1386
1387 guint pcm_channels;
1388 int ret;
1389 guint nth_card;
1390 guint i;
1391
1392 GRecMutex *core_audio_devout_mutex;
1393
1394 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
1395
1396 /* get core_audio devout mutex */
1397 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1398
1399 /* check device */
1400 g_rec_mutex_lock(core_audio_devout_mutex);
1401
1402 if(core_audio_devout->card_uri == device ||
1403 (core_audio_devout->card_uri != NULL &&
1404 !g_ascii_strcasecmp(core_audio_devout->card_uri,
1405 device))){
1406 g_rec_mutex_unlock(core_audio_devout_mutex);
1407
1408 return;
1409 }
1410
1411 if(!g_str_has_prefix(device,
1412 "ags-core_audio-devout-")){
1413 g_rec_mutex_unlock(core_audio_devout_mutex);
1414
1415 g_warning("invalid core_audioaudio device prefix");
1416
1417 return;
1418 }
1419
1420 ret = sscanf(device,
1421 "ags-core_audio-devout-%u",
1422 &nth_card);
1423
1424 if(ret != 1){
1425 g_rec_mutex_unlock(core_audio_devout_mutex);
1426
1427 g_warning("invalid core_audioaudio device specifier");
1428
1429 return;
1430 }
1431
1432 g_free(core_audio_devout->card_uri);
1433 core_audio_devout->card_uri = g_strdup(device);
1434
1435 /* apply name to port */
1436 g_rec_mutex_lock(core_audio_devout_mutex);
1437
1438 core_audio_port_start =
1439 core_audio_port = g_list_copy(core_audio_devout->core_audio_port);
1440
1441 g_rec_mutex_unlock(core_audio_devout_mutex);
1442
1443 str = g_strdup_printf("ags-soundcard%d",
1444 nth_card);
1445
1446 g_object_set(core_audio_port->data,
1447 "port-name", str,
1448 NULL);
1449 g_free(str);
1450
1451 g_list_free(core_audio_port_start);
1452 }
1453
1454 gchar*
ags_core_audio_devout_get_device(AgsSoundcard * soundcard)1455 ags_core_audio_devout_get_device(AgsSoundcard *soundcard)
1456 {
1457 AgsCoreAudioDevout *core_audio_devout;
1458
1459 gchar *device;
1460
1461 GRecMutex *core_audio_devout_mutex;
1462
1463 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
1464
1465 /* get core_audio devout mutex */
1466 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1467
1468 device = NULL;
1469
1470 /* get device */
1471 g_rec_mutex_lock(core_audio_devout_mutex);
1472
1473 device = g_strdup(core_audio_devout->card_uri);
1474
1475 g_rec_mutex_unlock(core_audio_devout_mutex);
1476
1477 return(device);
1478 }
1479
1480 void
ags_core_audio_devout_set_presets(AgsSoundcard * soundcard,guint channels,guint rate,guint buffer_size,guint format)1481 ags_core_audio_devout_set_presets(AgsSoundcard *soundcard,
1482 guint channels,
1483 guint rate,
1484 guint buffer_size,
1485 guint format)
1486 {
1487 AgsCoreAudioDevout *core_audio_devout;
1488
1489 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
1490
1491 g_object_set(core_audio_devout,
1492 "pcm-channels", channels,
1493 "samplerate", rate,
1494 "buffer-size", buffer_size,
1495 "format", format,
1496 NULL);
1497 }
1498
1499 void
ags_core_audio_devout_get_presets(AgsSoundcard * soundcard,guint * channels,guint * rate,guint * buffer_size,guint * format)1500 ags_core_audio_devout_get_presets(AgsSoundcard *soundcard,
1501 guint *channels,
1502 guint *rate,
1503 guint *buffer_size,
1504 guint *format)
1505 {
1506 AgsCoreAudioDevout *core_audio_devout;
1507
1508 GRecMutex *core_audio_devout_mutex;
1509
1510 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
1511
1512 /* get core_audio devout mutex */
1513 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1514
1515 /* get presets */
1516 g_rec_mutex_lock(core_audio_devout_mutex);
1517
1518 if(channels != NULL){
1519 *channels = core_audio_devout->pcm_channels;
1520 }
1521
1522 if(rate != NULL){
1523 *rate = core_audio_devout->samplerate;
1524 }
1525
1526 if(buffer_size != NULL){
1527 *buffer_size = core_audio_devout->buffer_size;
1528 }
1529
1530 if(format != NULL){
1531 *format = core_audio_devout->format;
1532 }
1533
1534 g_rec_mutex_unlock(core_audio_devout_mutex);
1535 }
1536
1537 void
ags_core_audio_devout_list_cards(AgsSoundcard * soundcard,GList ** card_id,GList ** card_name)1538 ags_core_audio_devout_list_cards(AgsSoundcard *soundcard,
1539 GList **card_id, GList **card_name)
1540 {
1541 AgsCoreAudioClient *core_audio_client;
1542 AgsCoreAudioDevout *core_audio_devout;
1543
1544 AgsApplicationContext *application_context;
1545
1546 GList *list_start, *list;
1547
1548 gchar *card_uri;
1549 gchar *client_name;
1550
1551 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
1552
1553 application_context = ags_application_context_get_instance();
1554
1555 if(card_id != NULL){
1556 *card_id = NULL;
1557 }
1558
1559 if(card_name != NULL){
1560 *card_name = NULL;
1561 }
1562
1563 list =
1564 list_start = ags_sound_provider_get_soundcard(AGS_SOUND_PROVIDER(application_context));
1565
1566 while(list != NULL){
1567 if(AGS_IS_CORE_AUDIO_DEVOUT(list->data)){
1568 if(card_id != NULL){
1569 card_uri = ags_soundcard_get_device(AGS_SOUNDCARD(list->data));
1570
1571 if(AGS_CORE_AUDIO_DEVOUT(list->data)->card_uri != NULL){
1572 *card_id = g_list_prepend(*card_id,
1573 card_uri);
1574 }else{
1575 *card_id = g_list_prepend(*card_id,
1576 g_strdup("(null)"));
1577
1578 g_warning("ags_core_audio_devout_list_cards() - card id (null)");
1579 }
1580 }
1581
1582 if(card_name != NULL){
1583 g_object_get(list->data,
1584 "core_audio-client", &core_audio_client,
1585 NULL);
1586
1587 if(core_audio_client != NULL){
1588 /* get client name */
1589 g_object_get(core_audio_client,
1590 "client-name", &client_name,
1591 NULL);
1592
1593 *card_name = g_list_prepend(*card_name,
1594 client_name);
1595
1596 g_object_unref(core_audio_client);
1597 }else{
1598 *card_name = g_list_prepend(*card_name,
1599 g_strdup("(null)"));
1600
1601 g_warning("ags_core_audio_devout_list_cards() - core_audioaudio client not connected (null)");
1602 }
1603 }
1604 }
1605
1606 list = list->next;
1607 }
1608
1609 g_list_free_full(list_start,
1610 g_object_unref);
1611
1612 if(card_id != NULL && *card_id != NULL){
1613 *card_id = g_list_reverse(*card_id);
1614 }
1615
1616 if(card_name != NULL && *card_name != NULL){
1617 *card_name = g_list_reverse(*card_name);
1618 }
1619 }
1620
1621 void
ags_core_audio_devout_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)1622 ags_core_audio_devout_pcm_info(AgsSoundcard *soundcard,
1623 char *card_id,
1624 guint *channels_min, guint *channels_max,
1625 guint *rate_min, guint *rate_max,
1626 guint *buffer_size_min, guint *buffer_size_max,
1627 GError **error)
1628 {
1629 if(channels_min != NULL){
1630 *channels_min = 1;
1631 }
1632
1633 if(channels_max != NULL){
1634 *channels_max = 1024;
1635 }
1636
1637 if(rate_min != NULL){
1638 *rate_min = 8000;
1639 }
1640
1641 if(rate_max != NULL){
1642 *rate_max = 192000;
1643 }
1644
1645 if(buffer_size_min != NULL){
1646 *buffer_size_min = 64;
1647 }
1648
1649 if(buffer_size_max != NULL){
1650 *buffer_size_max = 8192;
1651 }
1652 }
1653
1654 guint
ags_core_audio_devout_get_capability(AgsSoundcard * soundcard)1655 ags_core_audio_devout_get_capability(AgsSoundcard *soundcard)
1656 {
1657 return(AGS_SOUNDCARD_CAPABILITY_PLAYBACK);
1658 }
1659
1660 gboolean
ags_core_audio_devout_is_starting(AgsSoundcard * soundcard)1661 ags_core_audio_devout_is_starting(AgsSoundcard *soundcard)
1662 {
1663 AgsCoreAudioDevout *core_audio_devout;
1664
1665 gboolean is_starting;
1666
1667 GRecMutex *core_audio_devout_mutex;
1668
1669 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
1670
1671 /* get core_audio devout mutex */
1672 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1673
1674 /* check is starting */
1675 g_rec_mutex_lock(core_audio_devout_mutex);
1676
1677 is_starting = ((AGS_CORE_AUDIO_DEVOUT_START_PLAY & (core_audio_devout->flags)) != 0) ? TRUE: FALSE;
1678
1679 g_rec_mutex_unlock(core_audio_devout_mutex);
1680
1681 return(is_starting);
1682 }
1683
1684 gboolean
ags_core_audio_devout_is_playing(AgsSoundcard * soundcard)1685 ags_core_audio_devout_is_playing(AgsSoundcard *soundcard)
1686 {
1687 AgsCoreAudioDevout *core_audio_devout;
1688
1689 gboolean is_playing;
1690
1691 GRecMutex *core_audio_devout_mutex;
1692
1693 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
1694
1695 /* get core_audio devout mutex */
1696 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1697
1698 /* check is starting */
1699 g_rec_mutex_lock(core_audio_devout_mutex);
1700
1701 is_playing = ((AGS_CORE_AUDIO_DEVOUT_PLAY & (core_audio_devout->flags)) != 0) ? TRUE: FALSE;
1702
1703 g_rec_mutex_unlock(core_audio_devout_mutex);
1704
1705 return(is_playing);
1706 }
1707
1708 gchar*
ags_core_audio_devout_get_uptime(AgsSoundcard * soundcard)1709 ags_core_audio_devout_get_uptime(AgsSoundcard *soundcard)
1710 {
1711 gchar *uptime;
1712
1713 if(ags_soundcard_is_playing(soundcard)){
1714 guint samplerate;
1715 guint buffer_size;
1716
1717 guint note_offset;
1718 gdouble bpm;
1719 gdouble delay_factor;
1720
1721 gdouble delay;
1722
1723 ags_soundcard_get_presets(soundcard,
1724 NULL,
1725 &samplerate,
1726 &buffer_size,
1727 NULL);
1728
1729 note_offset = ags_soundcard_get_note_offset_absolute(soundcard);
1730
1731 bpm = ags_soundcard_get_bpm(soundcard);
1732 delay_factor = ags_soundcard_get_delay_factor(soundcard);
1733
1734 /* calculate delays */
1735 delay = ags_soundcard_get_absolute_delay(soundcard);
1736
1737 uptime = ags_time_get_uptime_from_offset(note_offset,
1738 bpm,
1739 delay,
1740 delay_factor);
1741 }else{
1742 uptime = g_strdup(AGS_TIME_ZERO);
1743 }
1744
1745 return(uptime);
1746 }
1747
1748 void
ags_core_audio_devout_port_init(AgsSoundcard * soundcard,GError ** error)1749 ags_core_audio_devout_port_init(AgsSoundcard *soundcard,
1750 GError **error)
1751 {
1752 AgsCoreAudioPort *core_audio_port;
1753 AgsCoreAudioDevout *core_audio_devout;
1754
1755 guint format, word_size;
1756 gboolean use_cache;
1757
1758 GRecMutex *core_audio_port_mutex;
1759 GRecMutex *core_audio_devout_mutex;
1760
1761 if(ags_soundcard_is_playing(soundcard)){
1762 return;
1763 }
1764
1765 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
1766
1767 /* get core-audio devout mutex */
1768 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1769
1770 /* port */
1771 g_rec_mutex_lock(core_audio_devout_mutex);
1772
1773 core_audio_port = (AgsCoreAudioPort *) core_audio_devout->core_audio_port->data;
1774
1775 g_rec_mutex_unlock(core_audio_devout_mutex);
1776
1777 /* get port mutex */
1778 core_audio_port_mutex = AGS_CORE_AUDIO_PORT_GET_OBJ_MUTEX(core_audio_port);
1779
1780 /* check use cache */
1781 g_rec_mutex_lock(core_audio_port_mutex);
1782
1783 use_cache = core_audio_port->use_cache;
1784
1785 if(use_cache){
1786 core_audio_port->completed_cache = 0;
1787 core_audio_port->current_cache = 1;
1788 }
1789
1790 g_rec_mutex_unlock(core_audio_port_mutex);
1791
1792 /* retrieve word size */
1793 g_rec_mutex_lock(core_audio_devout_mutex);
1794
1795 switch(core_audio_devout->format){
1796 case AGS_SOUNDCARD_SIGNED_8_BIT:
1797 {
1798 word_size = sizeof(gint8);
1799 }
1800 break;
1801 case AGS_SOUNDCARD_SIGNED_16_BIT:
1802 {
1803 word_size = sizeof(gint16);
1804 }
1805 break;
1806 case AGS_SOUNDCARD_SIGNED_24_BIT:
1807 {
1808 //NOTE:JK: The 24-bit linear samples use 32-bit physical space
1809 word_size = sizeof(gint32);
1810 }
1811 break;
1812 case AGS_SOUNDCARD_SIGNED_32_BIT:
1813 {
1814 word_size = sizeof(gint32);
1815 }
1816 break;
1817 case AGS_SOUNDCARD_SIGNED_64_BIT:
1818 {
1819 word_size = sizeof(gint64);
1820 }
1821 break;
1822 default:
1823 g_rec_mutex_unlock(core_audio_devout_mutex);
1824
1825 g_warning("ags_core_audio_devout_port_init(): unsupported word size");
1826
1827 return;
1828 }
1829
1830 /* prepare for playback */
1831 core_audio_devout->flags |= (AGS_CORE_AUDIO_DEVOUT_BUFFER7 |
1832 AGS_CORE_AUDIO_DEVOUT_START_PLAY |
1833 AGS_CORE_AUDIO_DEVOUT_PLAY |
1834 AGS_CORE_AUDIO_DEVOUT_NONBLOCKING);
1835
1836 memset(core_audio_devout->buffer[0], 0, core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
1837 memset(core_audio_devout->buffer[1], 0, core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
1838 memset(core_audio_devout->buffer[2], 0, core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
1839 memset(core_audio_devout->buffer[3], 0, core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
1840 memset(core_audio_devout->buffer[4], 0, core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
1841 memset(core_audio_devout->buffer[5], 0, core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
1842 memset(core_audio_devout->buffer[6], 0, core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
1843 memset(core_audio_devout->buffer[7], 0, core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
1844
1845 /* */
1846 core_audio_devout->tact_counter = 0.0;
1847 core_audio_devout->delay_counter = floor(ags_soundcard_get_absolute_delay(AGS_SOUNDCARD(core_audio_devout)));
1848 core_audio_devout->tic_counter = 0;
1849
1850 core_audio_devout->flags |= (AGS_CORE_AUDIO_DEVOUT_INITIALIZED |
1851 AGS_CORE_AUDIO_DEVOUT_START_PLAY |
1852 AGS_CORE_AUDIO_DEVOUT_PLAY);
1853
1854 g_atomic_int_or(&(core_audio_devout->sync_flags),
1855 AGS_CORE_AUDIO_DEVOUT_INITIAL_CALLBACK);
1856
1857 g_rec_mutex_unlock(core_audio_devout_mutex);
1858 }
1859
1860 void
ags_core_audio_devout_port_play(AgsSoundcard * soundcard,GError ** error)1861 ags_core_audio_devout_port_play(AgsSoundcard *soundcard,
1862 GError **error)
1863 {
1864 AgsCoreAudioClient *core_audio_client;
1865 AgsCoreAudioDevout *core_audio_devout;
1866 AgsCoreAudioPort *core_audio_port;
1867
1868 AgsTicDevice *tic_device;
1869 AgsClearBuffer *clear_buffer;
1870 AgsSwitchBufferFlag *switch_buffer_flag;
1871
1872 AgsTaskLauncher *task_launcher;
1873
1874 AgsApplicationContext *application_context;
1875
1876 GList *task;
1877 guint word_size;
1878 gboolean use_cache;
1879 gboolean core_audio_client_activated;
1880
1881 GRecMutex *core_audio_devout_mutex;
1882 GRecMutex *core_audio_client_mutex;
1883 GRecMutex *core_audio_port_mutex;
1884 GMutex *callback_mutex;
1885 GMutex *callback_finish_mutex;
1886
1887 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
1888
1889 application_context = ags_application_context_get_instance();
1890
1891 /* get core-audio devout mutex */
1892 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
1893
1894 /* client */
1895 g_rec_mutex_lock(core_audio_devout_mutex);
1896
1897 core_audio_client = (AgsCoreAudioClient *) core_audio_devout->core_audio_client;
1898 core_audio_port = (AgsCoreAudioPort *) core_audio_devout->core_audio_port->data;
1899
1900 callback_mutex = &(core_audio_devout->callback_mutex);
1901 callback_finish_mutex = &(core_audio_devout->callback_finish_mutex);
1902
1903 /* do playback */
1904 core_audio_devout->flags &= (~AGS_CORE_AUDIO_DEVOUT_START_PLAY);
1905
1906 if((AGS_CORE_AUDIO_DEVOUT_INITIALIZED & (core_audio_devout->flags)) == 0){
1907 g_rec_mutex_unlock(core_audio_devout_mutex);
1908
1909 return;
1910 }
1911
1912 switch(core_audio_devout->format){
1913 case AGS_SOUNDCARD_SIGNED_16_BIT:
1914 {
1915 word_size = sizeof(gint16);
1916 }
1917 break;
1918 case AGS_SOUNDCARD_SIGNED_24_BIT:
1919 {
1920 //NOTE:JK: The 24-bit linear samples use 32-bit physical space
1921 word_size = sizeof(gint32);
1922 }
1923 break;
1924 case AGS_SOUNDCARD_SIGNED_32_BIT:
1925 {
1926 word_size = sizeof(gint32);
1927 }
1928 break;
1929 default:
1930 g_rec_mutex_unlock(core_audio_devout_mutex);
1931
1932 g_warning("ags_core_audio_devout_port_play(): unsupported word size");
1933
1934 return;
1935 }
1936
1937 g_rec_mutex_unlock(core_audio_devout_mutex);
1938
1939 /* get port mutex */
1940 core_audio_port_mutex = AGS_CORE_AUDIO_PORT_GET_OBJ_MUTEX(core_audio_port);
1941
1942 /* check use cache */
1943 g_rec_mutex_lock(core_audio_port_mutex);
1944
1945 use_cache = core_audio_port->use_cache;
1946
1947 g_rec_mutex_unlock(core_audio_port_mutex);
1948
1949 if(use_cache){
1950 void *buffer;
1951
1952 guint current_cache;
1953 guint completed_cache;
1954 guint write_cache;
1955 guint cache_buffer_size;
1956 guint cache_offset;
1957 guint pcm_channels;
1958 guint buffer_size;
1959 guint format;
1960
1961 struct timespec idle_time = {
1962 0,
1963 0,
1964 };
1965
1966 idle_time.tv_nsec = ags_core_audio_port_get_latency(core_audio_port) / 8;
1967
1968 g_rec_mutex_lock(core_audio_port_mutex);
1969
1970 completed_cache = core_audio_port->completed_cache;
1971
1972 cache_buffer_size = core_audio_port->cache_buffer_size;
1973
1974 cache_offset = core_audio_port->cache_offset;
1975
1976 g_rec_mutex_unlock(core_audio_port_mutex);
1977
1978 if(completed_cache == 3){
1979 write_cache = 0;
1980 }else{
1981 write_cache = completed_cache + 1;
1982 }
1983
1984 /* wait until ready */
1985 g_rec_mutex_lock(core_audio_port_mutex);
1986
1987 current_cache = core_audio_port->current_cache;
1988
1989 g_rec_mutex_unlock(core_audio_port_mutex);
1990
1991 while(write_cache == current_cache){
1992 nanosleep(&idle_time, NULL);
1993
1994 g_rec_mutex_lock(core_audio_port_mutex);
1995
1996 current_cache = core_audio_port->current_cache;
1997
1998 g_rec_mutex_unlock(core_audio_port_mutex);
1999 }
2000
2001 /* fill cache */
2002 g_rec_mutex_lock(core_audio_devout_mutex);
2003
2004 pcm_channels = core_audio_devout->pcm_channels;
2005 buffer_size = core_audio_devout->buffer_size;
2006 format = core_audio_devout->format;
2007
2008 g_rec_mutex_unlock(core_audio_devout_mutex);
2009
2010 buffer = ags_soundcard_get_buffer(AGS_SOUNDCARD(core_audio_devout));
2011
2012 // g_message("w %d", write_cache);
2013
2014 switch(format){
2015 case AGS_SOUNDCARD_SIGNED_16_BIT:
2016 {
2017 if(cache_offset == 0){
2018 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[write_cache], 1,
2019 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S16);
2020 }
2021
2022 if(buffer != NULL){
2023 ags_audio_buffer_util_copy_s16_to_s16((gint16 *) core_audio_port->cache[write_cache] + (pcm_channels * cache_offset), 1,
2024 (gint16 *) buffer, 1,
2025 pcm_channels * buffer_size);
2026 }
2027 }
2028 break;
2029 case AGS_SOUNDCARD_SIGNED_24_BIT:
2030 {
2031 if(cache_offset == 0){
2032 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[write_cache], 1,
2033 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S32);
2034 }
2035
2036 if(buffer != NULL){
2037 ags_audio_buffer_util_copy_s24_to_s24((gint32 *) core_audio_port->cache[write_cache] + (pcm_channels * cache_offset), 1,
2038 (gint32 *) buffer, 1,
2039 pcm_channels * buffer_size);
2040 }
2041 }
2042 break;
2043 case AGS_SOUNDCARD_SIGNED_32_BIT:
2044 {
2045 if(cache_offset == 0){
2046 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[write_cache], 1,
2047 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S32);
2048 }
2049
2050 if(buffer != NULL){
2051 ags_audio_buffer_util_copy_s32_to_s32((gint32 *) core_audio_port->cache[write_cache] + (pcm_channels * cache_offset), 1,
2052 (gint32 *) buffer, 1,
2053 pcm_channels * buffer_size);
2054 }
2055 }
2056 break;
2057 }
2058
2059 /* seek cache */
2060 if(cache_offset + buffer_size >= cache_buffer_size){
2061 g_rec_mutex_lock(core_audio_port_mutex);
2062
2063 core_audio_port->completed_cache = write_cache;
2064 core_audio_port->cache_offset = 0;
2065
2066 g_rec_mutex_unlock(core_audio_port_mutex);
2067 }else{
2068 g_rec_mutex_lock(core_audio_port_mutex);
2069
2070 core_audio_port->cache_offset += buffer_size;
2071
2072 g_rec_mutex_unlock(core_audio_port_mutex);
2073 }
2074 }else{
2075 /* get client mutex */
2076 core_audio_client_mutex = AGS_CORE_AUDIO_CLIENT_GET_OBJ_MUTEX(core_audio_client);
2077
2078 /* get activated */
2079 g_rec_mutex_lock(core_audio_client_mutex);
2080
2081 core_audio_client_activated = ((AGS_CORE_AUDIO_CLIENT_ACTIVATED & (core_audio_client->flags)) != 0) ? TRUE: FALSE;
2082
2083 g_rec_mutex_unlock(core_audio_client_mutex);
2084
2085 if(core_audio_client_activated){
2086 while((AGS_CORE_AUDIO_DEVOUT_PASS_THROUGH & (g_atomic_int_get(&(core_audio_devout->sync_flags)))) != 0){
2087 usleep(4);
2088 }
2089
2090 /* signal */
2091 if((AGS_CORE_AUDIO_DEVOUT_INITIAL_CALLBACK & (g_atomic_int_get(&(core_audio_devout->sync_flags)))) == 0){
2092 g_mutex_lock(callback_mutex);
2093
2094 g_atomic_int_or(&(core_audio_devout->sync_flags),
2095 AGS_CORE_AUDIO_DEVOUT_CALLBACK_DONE);
2096
2097 if((AGS_CORE_AUDIO_DEVOUT_CALLBACK_WAIT & (g_atomic_int_get(&(core_audio_devout->sync_flags)))) != 0){
2098 g_cond_signal(&(core_audio_devout->callback_cond));
2099 }
2100
2101 g_mutex_unlock(callback_mutex);
2102 // }
2103
2104 /* wait callback */
2105 g_mutex_lock(callback_finish_mutex);
2106
2107 if((AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_DONE & (g_atomic_int_get(&(core_audio_devout->sync_flags)))) == 0){
2108 g_atomic_int_or(&(core_audio_devout->sync_flags),
2109 AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_WAIT);
2110
2111 while((AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_DONE & (g_atomic_int_get(&(core_audio_devout->sync_flags)))) == 0 &&
2112 (AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_WAIT & (g_atomic_int_get(&(core_audio_devout->sync_flags)))) != 0){
2113 g_cond_wait(&(core_audio_devout->callback_finish_cond),
2114 callback_finish_mutex);
2115 }
2116 }
2117
2118 g_atomic_int_and(&(core_audio_devout->sync_flags),
2119 (~(AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_WAIT |
2120 AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_DONE)));
2121
2122 g_mutex_unlock(callback_finish_mutex);
2123 }else{
2124 g_atomic_int_and(&(core_audio_devout->sync_flags),
2125 (~AGS_CORE_AUDIO_DEVOUT_INITIAL_CALLBACK));
2126 }
2127 }
2128 }
2129
2130 /* update soundcard */
2131 task_launcher = ags_concurrency_provider_get_task_launcher(AGS_CONCURRENCY_PROVIDER(application_context));
2132
2133 task = NULL;
2134
2135 /* tic soundcard */
2136 tic_device = ags_tic_device_new((GObject *) core_audio_devout);
2137 task = g_list_append(task,
2138 tic_device);
2139
2140 /* reset - clear buffer */
2141 clear_buffer = ags_clear_buffer_new((GObject *) core_audio_devout);
2142 task = g_list_append(task,
2143 clear_buffer);
2144
2145 /* reset - switch buffer flags */
2146 switch_buffer_flag = ags_switch_buffer_flag_new((GObject *) core_audio_devout);
2147 task = g_list_append(task,
2148 switch_buffer_flag);
2149
2150 /* append tasks */
2151 ags_task_launcher_add_task_all(task_launcher,
2152 task);
2153
2154 /* unref */
2155 g_object_unref(task_launcher);
2156 }
2157
2158 void
ags_core_audio_devout_port_free(AgsSoundcard * soundcard)2159 ags_core_audio_devout_port_free(AgsSoundcard *soundcard)
2160 {
2161 AgsCoreAudioPort *core_audio_port;
2162 AgsCoreAudioDevout *core_audio_devout;
2163
2164 guint pcm_channels;
2165 guint cache_buffer_size;
2166 guint word_size;
2167 gboolean use_cache;
2168
2169 GRecMutex *core_audio_port_mutex;
2170 GRecMutex *core_audio_devout_mutex;
2171 GMutex *callback_mutex;
2172 GMutex *callback_finish_mutex;
2173
2174 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2175
2176 /* get core-audio devout mutex */
2177 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2178
2179 /* port */
2180 g_rec_mutex_lock(core_audio_devout_mutex);
2181
2182 core_audio_port = (AgsCoreAudioPort *) core_audio_devout->core_audio_port->data;
2183 pcm_channels = core_audio_devout->pcm_channels;
2184
2185 g_rec_mutex_unlock(core_audio_devout_mutex);
2186
2187 /* get port mutex */
2188 core_audio_port_mutex = AGS_CORE_AUDIO_PORT_GET_OBJ_MUTEX(core_audio_port);
2189
2190 /* check use cache */
2191 g_rec_mutex_lock(core_audio_port_mutex);
2192
2193 cache_buffer_size = core_audio_port->cache_buffer_size;
2194 use_cache = core_audio_port->use_cache;
2195
2196 if(use_cache){
2197 core_audio_port->completed_cache = 0;
2198 core_audio_port->current_cache = 0;
2199 core_audio_port->cache_offset = 0;
2200 }
2201
2202 switch(core_audio_port->format){
2203 case AGS_SOUNDCARD_SIGNED_16_BIT:
2204 {
2205 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[0], 1,
2206 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S16);
2207 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[1], 1,
2208 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S16);
2209 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[2], 1,
2210 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S16);
2211 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[3], 1,
2212 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S16);
2213 }
2214 break;
2215 case AGS_SOUNDCARD_SIGNED_24_BIT:
2216 {
2217 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[0], 1,
2218 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S32);
2219 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[1], 1,
2220 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S32);
2221 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[2], 1,
2222 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S32);
2223 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[3], 1,
2224 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S32);
2225 }
2226 break;
2227 case AGS_SOUNDCARD_SIGNED_32_BIT:
2228 {
2229 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[0], 1,
2230 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S32);
2231 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[1], 1,
2232 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S32);
2233 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[2], 1,
2234 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S32);
2235 ags_audio_buffer_util_clear_buffer(core_audio_port->cache[3], 1,
2236 pcm_channels * cache_buffer_size, AGS_AUDIO_BUFFER_UTIL_S32);
2237 }
2238 break;
2239 }
2240
2241 g_rec_mutex_unlock(core_audio_port_mutex);
2242
2243 /* */
2244 g_rec_mutex_lock(core_audio_devout_mutex);
2245
2246 if((AGS_CORE_AUDIO_DEVOUT_INITIALIZED & (core_audio_devout->flags)) == 0){
2247 g_rec_mutex_unlock(core_audio_devout_mutex);
2248
2249 return;
2250 }
2251
2252 callback_mutex = &(core_audio_devout->callback_mutex);
2253 callback_finish_mutex = &(core_audio_devout->callback_finish_mutex);
2254
2255 // g_atomic_int_or(&(AGS_THREAD(application_context->main_loop)->flags),
2256 // AGS_THREAD_TIMING);
2257
2258 core_audio_devout->flags &= (~(AGS_CORE_AUDIO_DEVOUT_BUFFER0 |
2259 AGS_CORE_AUDIO_DEVOUT_BUFFER1 |
2260 AGS_CORE_AUDIO_DEVOUT_BUFFER2 |
2261 AGS_CORE_AUDIO_DEVOUT_BUFFER3 |
2262 AGS_CORE_AUDIO_DEVOUT_BUFFER4 |
2263 AGS_CORE_AUDIO_DEVOUT_BUFFER5 |
2264 AGS_CORE_AUDIO_DEVOUT_BUFFER6 |
2265 AGS_CORE_AUDIO_DEVOUT_BUFFER7 |
2266 AGS_CORE_AUDIO_DEVOUT_PLAY));
2267
2268 g_atomic_int_or(&(core_audio_devout->sync_flags),
2269 AGS_CORE_AUDIO_DEVOUT_PASS_THROUGH);
2270 g_atomic_int_and(&(core_audio_devout->sync_flags),
2271 (~AGS_CORE_AUDIO_DEVOUT_INITIAL_CALLBACK));
2272
2273 /* signal callback */
2274 g_rec_mutex_lock(callback_mutex);
2275
2276 g_atomic_int_or(&(core_audio_devout->sync_flags),
2277 AGS_CORE_AUDIO_DEVOUT_CALLBACK_DONE);
2278
2279 if((AGS_CORE_AUDIO_DEVOUT_CALLBACK_WAIT & (g_atomic_int_get(&(core_audio_devout->sync_flags)))) != 0){
2280 g_cond_signal(&(core_audio_devout->callback_cond));
2281 }
2282
2283 g_rec_mutex_unlock(callback_mutex);
2284
2285 /* signal thread */
2286 g_rec_mutex_lock(callback_finish_mutex);
2287
2288 g_atomic_int_or(&(core_audio_devout->sync_flags),
2289 AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_DONE);
2290
2291 if((AGS_CORE_AUDIO_DEVOUT_CALLBACK_FINISH_WAIT & (g_atomic_int_get(&(core_audio_devout->sync_flags)))) != 0){
2292 g_cond_signal(&(core_audio_devout->callback_finish_cond));
2293 }
2294
2295 g_rec_mutex_unlock(callback_finish_mutex);
2296
2297 /* */
2298 core_audio_devout->note_offset = core_audio_devout->start_note_offset;
2299 core_audio_devout->note_offset_absolute = core_audio_devout->start_note_offset;
2300
2301 switch(core_audio_devout->format){
2302 case AGS_SOUNDCARD_SIGNED_8_BIT:
2303 {
2304 word_size = sizeof(gint8);
2305 }
2306 break;
2307 case AGS_SOUNDCARD_SIGNED_16_BIT:
2308 {
2309 word_size = sizeof(gint16);
2310 }
2311 break;
2312 case AGS_SOUNDCARD_SIGNED_24_BIT:
2313 {
2314 word_size = sizeof(gint32);
2315 }
2316 break;
2317 case AGS_SOUNDCARD_SIGNED_32_BIT:
2318 {
2319 word_size = sizeof(gint32);
2320 }
2321 break;
2322 case AGS_SOUNDCARD_SIGNED_64_BIT:
2323 {
2324 word_size = sizeof(gint64);
2325 }
2326 break;
2327 default:
2328 word_size = 0;
2329
2330 g_critical("ags_core_audio_devout_free(): unsupported word size");
2331 }
2332
2333 g_rec_mutex_unlock(core_audio_devout_mutex);
2334
2335 if(core_audio_devout->core_audio_port != NULL){
2336 core_audio_port = core_audio_devout->core_audio_port->data;
2337
2338 while(!g_atomic_int_get(&(core_audio_port->is_empty))) usleep(500000);
2339 }
2340
2341 g_rec_mutex_lock(core_audio_devout_mutex);
2342
2343 memset(core_audio_devout->buffer[0], 0, (size_t) core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
2344 memset(core_audio_devout->buffer[1], 0, (size_t) core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
2345 memset(core_audio_devout->buffer[2], 0, (size_t) core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
2346 memset(core_audio_devout->buffer[3], 0, (size_t) core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
2347 memset(core_audio_devout->buffer[4], 0, (size_t) core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
2348 memset(core_audio_devout->buffer[5], 0, (size_t) core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
2349 memset(core_audio_devout->buffer[6], 0, (size_t) core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
2350 memset(core_audio_devout->buffer[7], 0, (size_t) core_audio_devout->pcm_channels * core_audio_devout->buffer_size * word_size);
2351
2352 g_rec_mutex_unlock(core_audio_devout_mutex);
2353 }
2354
2355 void
ags_core_audio_devout_tic(AgsSoundcard * soundcard)2356 ags_core_audio_devout_tic(AgsSoundcard *soundcard)
2357 {
2358 AgsCoreAudioDevout *core_audio_devout;
2359
2360 gdouble delay;
2361 gdouble delay_counter;
2362 guint note_offset_absolute;
2363 guint note_offset;
2364 guint loop_left, loop_right;
2365 gboolean do_loop;
2366
2367 GRecMutex *core_audio_devout_mutex;
2368
2369 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2370
2371 /* get core_audio devout mutex */
2372 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2373
2374 /* determine if attack should be switched */
2375 g_rec_mutex_lock(core_audio_devout_mutex);
2376
2377 delay = core_audio_devout->delay[core_audio_devout->tic_counter];
2378 delay_counter = core_audio_devout->delay_counter;
2379
2380 note_offset = core_audio_devout->note_offset;
2381 note_offset_absolute = core_audio_devout->note_offset_absolute;
2382
2383 loop_left = core_audio_devout->loop_left;
2384 loop_right = core_audio_devout->loop_right;
2385
2386 do_loop = core_audio_devout->do_loop;
2387
2388 g_rec_mutex_unlock(core_audio_devout_mutex);
2389
2390 if(delay_counter + 1.0 >= floor(delay)){
2391 if(do_loop &&
2392 note_offset + 1 == loop_right){
2393 ags_soundcard_set_note_offset(soundcard,
2394 loop_left);
2395 }else{
2396 ags_soundcard_set_note_offset(soundcard,
2397 note_offset + 1);
2398 }
2399
2400 ags_soundcard_set_note_offset_absolute(soundcard,
2401 note_offset_absolute + 1);
2402
2403 /* delay */
2404 ags_soundcard_offset_changed(soundcard,
2405 note_offset);
2406
2407 /* reset - delay counter */
2408 g_rec_mutex_lock(core_audio_devout_mutex);
2409
2410 core_audio_devout->delay_counter = delay_counter + 1.0 - delay;
2411 core_audio_devout->tact_counter += 1.0;
2412
2413 g_rec_mutex_unlock(core_audio_devout_mutex);
2414 }else{
2415 g_rec_mutex_lock(core_audio_devout_mutex);
2416
2417 core_audio_devout->delay_counter += 1.0;
2418
2419 g_rec_mutex_unlock(core_audio_devout_mutex);
2420 }
2421 }
2422
2423 void
ags_core_audio_devout_offset_changed(AgsSoundcard * soundcard,guint note_offset)2424 ags_core_audio_devout_offset_changed(AgsSoundcard *soundcard,
2425 guint note_offset)
2426 {
2427 AgsCoreAudioDevout *core_audio_devout;
2428
2429 GRecMutex *core_audio_devout_mutex;
2430
2431 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2432
2433 /* get core_audio devout mutex */
2434 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2435
2436 /* offset changed */
2437 g_rec_mutex_lock(core_audio_devout_mutex);
2438
2439 core_audio_devout->tic_counter += 1;
2440
2441 if(core_audio_devout->tic_counter == AGS_SOUNDCARD_DEFAULT_PERIOD){
2442 /* reset - tic counter i.e. modified delay index within period */
2443 core_audio_devout->tic_counter = 0;
2444 }
2445
2446 g_rec_mutex_unlock(core_audio_devout_mutex);
2447 }
2448
2449 void
ags_core_audio_devout_set_bpm(AgsSoundcard * soundcard,gdouble bpm)2450 ags_core_audio_devout_set_bpm(AgsSoundcard *soundcard,
2451 gdouble bpm)
2452 {
2453 AgsCoreAudioDevout *core_audio_devout;
2454
2455 GRecMutex *core_audio_devout_mutex;
2456
2457 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2458
2459 /* get core_audio devout mutex */
2460 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2461
2462 /* set bpm */
2463 g_rec_mutex_lock(core_audio_devout_mutex);
2464
2465 core_audio_devout->bpm = bpm;
2466
2467 g_rec_mutex_unlock(core_audio_devout_mutex);
2468
2469 ags_core_audio_devout_adjust_delay_and_attack(core_audio_devout);
2470 }
2471
2472 gdouble
ags_core_audio_devout_get_bpm(AgsSoundcard * soundcard)2473 ags_core_audio_devout_get_bpm(AgsSoundcard *soundcard)
2474 {
2475 AgsCoreAudioDevout *core_audio_devout;
2476
2477 gdouble bpm;
2478
2479 GRecMutex *core_audio_devout_mutex;
2480
2481 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2482
2483 /* get core_audio devout mutex */
2484 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2485
2486 /* get bpm */
2487 g_rec_mutex_lock(core_audio_devout_mutex);
2488
2489 bpm = core_audio_devout->bpm;
2490
2491 g_rec_mutex_unlock(core_audio_devout_mutex);
2492
2493 return(bpm);
2494 }
2495
2496 void
ags_core_audio_devout_set_delay_factor(AgsSoundcard * soundcard,gdouble delay_factor)2497 ags_core_audio_devout_set_delay_factor(AgsSoundcard *soundcard,
2498 gdouble delay_factor)
2499 {
2500 AgsCoreAudioDevout *core_audio_devout;
2501
2502 GRecMutex *core_audio_devout_mutex;
2503
2504 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2505
2506 /* get core_audio devout mutex */
2507 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2508
2509 /* set delay factor */
2510 g_rec_mutex_lock(core_audio_devout_mutex);
2511
2512 core_audio_devout->delay_factor = delay_factor;
2513
2514 g_rec_mutex_unlock(core_audio_devout_mutex);
2515
2516 ags_core_audio_devout_adjust_delay_and_attack(core_audio_devout);
2517 }
2518
2519 gdouble
ags_core_audio_devout_get_delay_factor(AgsSoundcard * soundcard)2520 ags_core_audio_devout_get_delay_factor(AgsSoundcard *soundcard)
2521 {
2522 AgsCoreAudioDevout *core_audio_devout;
2523
2524 gdouble delay_factor;
2525
2526 GRecMutex *core_audio_devout_mutex;
2527
2528 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2529
2530 /* get core_audio devout mutex */
2531 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2532
2533 /* get delay factor */
2534 g_rec_mutex_lock(core_audio_devout_mutex);
2535
2536 delay_factor = core_audio_devout->delay_factor;
2537
2538 g_rec_mutex_unlock(core_audio_devout_mutex);
2539
2540 return(delay_factor);
2541 }
2542
2543 gdouble
ags_core_audio_devout_get_delay(AgsSoundcard * soundcard)2544 ags_core_audio_devout_get_delay(AgsSoundcard *soundcard)
2545 {
2546 AgsCoreAudioDevout *core_audio_devout;
2547
2548 guint delay_index;
2549 gdouble delay;
2550
2551 GRecMutex *core_audio_devout_mutex;
2552
2553 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2554
2555 /* get core_audio devout mutex */
2556 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2557
2558 /* get delay */
2559 g_rec_mutex_lock(core_audio_devout_mutex);
2560
2561 delay_index = core_audio_devout->tic_counter;
2562
2563 delay = core_audio_devout->delay[delay_index];
2564
2565 g_rec_mutex_unlock(core_audio_devout_mutex);
2566
2567 return(delay);
2568 }
2569
2570 gdouble
ags_core_audio_devout_get_absolute_delay(AgsSoundcard * soundcard)2571 ags_core_audio_devout_get_absolute_delay(AgsSoundcard *soundcard)
2572 {
2573 AgsCoreAudioDevout *core_audio_devout;
2574
2575 gdouble absolute_delay;
2576
2577 GRecMutex *core_audio_devout_mutex;
2578
2579 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2580
2581 /* get core_audio devout mutex */
2582 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2583
2584 /* get absolute delay */
2585 g_rec_mutex_lock(core_audio_devout_mutex);
2586
2587 absolute_delay = (60.0 * (((gdouble) core_audio_devout->samplerate / (gdouble) core_audio_devout->buffer_size) / (gdouble) core_audio_devout->bpm) * ((1.0 / 16.0) * (1.0 / (gdouble) core_audio_devout->delay_factor)));
2588
2589 g_rec_mutex_unlock(core_audio_devout_mutex);
2590
2591 return(absolute_delay);
2592 }
2593
2594 guint
ags_core_audio_devout_get_attack(AgsSoundcard * soundcard)2595 ags_core_audio_devout_get_attack(AgsSoundcard *soundcard)
2596 {
2597 AgsCoreAudioDevout *core_audio_devout;
2598
2599 guint attack_index;
2600 guint attack;
2601
2602 GRecMutex *core_audio_devout_mutex;
2603
2604 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2605
2606 /* get core_audio devout mutex */
2607 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2608
2609 /* get attack */
2610 g_rec_mutex_lock(core_audio_devout_mutex);
2611
2612 attack_index = core_audio_devout->tic_counter;
2613
2614 attack = core_audio_devout->attack[attack_index];
2615
2616 g_rec_mutex_unlock(core_audio_devout_mutex);
2617
2618 return(attack);
2619 }
2620
2621 void*
ags_core_audio_devout_get_buffer(AgsSoundcard * soundcard)2622 ags_core_audio_devout_get_buffer(AgsSoundcard *soundcard)
2623 {
2624 AgsCoreAudioDevout *core_audio_devout;
2625
2626 void *buffer;
2627
2628 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2629
2630 if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER0)){
2631 buffer = core_audio_devout->buffer[0];
2632 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER1)){
2633 buffer = core_audio_devout->buffer[1];
2634 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER2)){
2635 buffer = core_audio_devout->buffer[2];
2636 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER3)){
2637 buffer = core_audio_devout->buffer[3];
2638 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER4)){
2639 buffer = core_audio_devout->buffer[4];
2640 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER5)){
2641 buffer = core_audio_devout->buffer[5];
2642 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER6)){
2643 buffer = core_audio_devout->buffer[6];
2644 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER7)){
2645 buffer = core_audio_devout->buffer[7];
2646 }else{
2647 buffer = NULL;
2648 }
2649
2650 return(buffer);
2651 }
2652
2653 void*
ags_core_audio_devout_get_next_buffer(AgsSoundcard * soundcard)2654 ags_core_audio_devout_get_next_buffer(AgsSoundcard *soundcard)
2655 {
2656 AgsCoreAudioDevout *core_audio_devout;
2657
2658 void *buffer;
2659
2660 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2661
2662 if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER0)){
2663 buffer = core_audio_devout->buffer[1];
2664 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER1)){
2665 buffer = core_audio_devout->buffer[2];
2666 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER2)){
2667 buffer = core_audio_devout->buffer[3];
2668 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER3)){
2669 buffer = core_audio_devout->buffer[4];
2670 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER4)){
2671 buffer = core_audio_devout->buffer[5];
2672 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER5)){
2673 buffer = core_audio_devout->buffer[6];
2674 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER6)){
2675 buffer = core_audio_devout->buffer[7];
2676 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER7)){
2677 buffer = core_audio_devout->buffer[0];
2678 }else{
2679 buffer = NULL;
2680 }
2681
2682 return(buffer);
2683 }
2684
2685 void*
ags_core_audio_devout_get_prev_buffer(AgsSoundcard * soundcard)2686 ags_core_audio_devout_get_prev_buffer(AgsSoundcard *soundcard)
2687 {
2688 AgsCoreAudioDevout *core_audio_devout;
2689
2690 void *buffer;
2691
2692 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2693
2694 if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER0)){
2695 buffer = core_audio_devout->buffer[7];
2696 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER1)){
2697 buffer = core_audio_devout->buffer[0];
2698 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER2)){
2699 buffer = core_audio_devout->buffer[1];
2700 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER3)){
2701 buffer = core_audio_devout->buffer[2];
2702 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER4)){
2703 buffer = core_audio_devout->buffer[3];
2704 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER5)){
2705 buffer = core_audio_devout->buffer[4];
2706 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER6)){
2707 buffer = core_audio_devout->buffer[5];
2708 }else if(ags_core_audio_devout_test_flags(core_audio_devout, AGS_CORE_AUDIO_DEVOUT_BUFFER7)){
2709 buffer = core_audio_devout->buffer[6];
2710 }else{
2711 buffer = NULL;
2712 }
2713
2714 return(buffer);
2715 }
2716
2717 void
ags_core_audio_devout_lock_buffer(AgsSoundcard * soundcard,void * buffer)2718 ags_core_audio_devout_lock_buffer(AgsSoundcard *soundcard,
2719 void *buffer)
2720 {
2721 AgsCoreAudioDevout *core_audio_devout;
2722
2723 GRecMutex *buffer_mutex;
2724
2725 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2726
2727 buffer_mutex = NULL;
2728
2729 if(core_audio_devout->buffer != NULL){
2730 if(buffer == core_audio_devout->buffer[0]){
2731 buffer_mutex = core_audio_devout->buffer_mutex[0];
2732 }else if(buffer == core_audio_devout->buffer[1]){
2733 buffer_mutex = core_audio_devout->buffer_mutex[1];
2734 }else if(buffer == core_audio_devout->buffer[2]){
2735 buffer_mutex = core_audio_devout->buffer_mutex[2];
2736 }else if(buffer == core_audio_devout->buffer[3]){
2737 buffer_mutex = core_audio_devout->buffer_mutex[3];
2738 }else if(buffer == core_audio_devout->buffer[4]){
2739 buffer_mutex = core_audio_devout->buffer_mutex[4];
2740 }else if(buffer == core_audio_devout->buffer[5]){
2741 buffer_mutex = core_audio_devout->buffer_mutex[5];
2742 }else if(buffer == core_audio_devout->buffer[6]){
2743 buffer_mutex = core_audio_devout->buffer_mutex[6];
2744 }else if(buffer == core_audio_devout->buffer[7]){
2745 buffer_mutex = core_audio_devout->buffer_mutex[7];
2746 }
2747 }
2748
2749 if(buffer_mutex != NULL){
2750 g_rec_mutex_lock(buffer_mutex);
2751 }
2752 }
2753
2754 void
ags_core_audio_devout_unlock_buffer(AgsSoundcard * soundcard,void * buffer)2755 ags_core_audio_devout_unlock_buffer(AgsSoundcard *soundcard,
2756 void *buffer)
2757 {
2758 AgsCoreAudioDevout *core_audio_devout;
2759
2760 GRecMutex *buffer_mutex;
2761
2762 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2763
2764 buffer_mutex = NULL;
2765
2766 if(core_audio_devout->buffer != NULL){
2767 if(buffer == core_audio_devout->buffer[0]){
2768 buffer_mutex = core_audio_devout->buffer_mutex[0];
2769 }else if(buffer == core_audio_devout->buffer[1]){
2770 buffer_mutex = core_audio_devout->buffer_mutex[1];
2771 }else if(buffer == core_audio_devout->buffer[2]){
2772 buffer_mutex = core_audio_devout->buffer_mutex[2];
2773 }else if(buffer == core_audio_devout->buffer[3]){
2774 buffer_mutex = core_audio_devout->buffer_mutex[3];
2775 }else if(buffer == core_audio_devout->buffer[4]){
2776 buffer_mutex = core_audio_devout->buffer_mutex[4];
2777 }else if(buffer == core_audio_devout->buffer[5]){
2778 buffer_mutex = core_audio_devout->buffer_mutex[5];
2779 }else if(buffer == core_audio_devout->buffer[6]){
2780 buffer_mutex = core_audio_devout->buffer_mutex[6];
2781 }else if(buffer == core_audio_devout->buffer[7]){
2782 buffer_mutex = core_audio_devout->buffer_mutex[7];
2783 }
2784 }
2785
2786 if(buffer_mutex != NULL){
2787 g_rec_mutex_unlock(buffer_mutex);
2788 }
2789 }
2790
2791 guint
ags_core_audio_devout_get_delay_counter(AgsSoundcard * soundcard)2792 ags_core_audio_devout_get_delay_counter(AgsSoundcard *soundcard)
2793 {
2794 AgsCoreAudioDevout *core_audio_devout;
2795
2796 guint delay_counter;
2797
2798 GRecMutex *core_audio_devout_mutex;
2799
2800 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2801
2802 /* get core_audio devout mutex */
2803 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2804
2805 /* delay counter */
2806 g_rec_mutex_lock(core_audio_devout_mutex);
2807
2808 delay_counter = core_audio_devout->delay_counter;
2809
2810 g_rec_mutex_unlock(core_audio_devout_mutex);
2811
2812 return(delay_counter);
2813 }
2814
2815 void
ags_core_audio_devout_set_start_note_offset(AgsSoundcard * soundcard,guint start_note_offset)2816 ags_core_audio_devout_set_start_note_offset(AgsSoundcard *soundcard,
2817 guint start_note_offset)
2818 {
2819 AgsCoreAudioDevout *core_audio_devout;
2820
2821 GRecMutex *core_audio_devout_mutex;
2822
2823 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2824
2825 /* get core_audio devout mutex */
2826 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2827
2828 /* set note offset */
2829 g_rec_mutex_lock(core_audio_devout_mutex);
2830
2831 core_audio_devout->start_note_offset = start_note_offset;
2832
2833 g_rec_mutex_unlock(core_audio_devout_mutex);
2834 }
2835
2836 guint
ags_core_audio_devout_get_start_note_offset(AgsSoundcard * soundcard)2837 ags_core_audio_devout_get_start_note_offset(AgsSoundcard *soundcard)
2838 {
2839 AgsCoreAudioDevout *core_audio_devout;
2840
2841 guint start_note_offset;
2842
2843 GRecMutex *core_audio_devout_mutex;
2844
2845 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2846
2847 /* get core_audio devout mutex */
2848 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2849
2850 /* set note offset */
2851 g_rec_mutex_lock(core_audio_devout_mutex);
2852
2853 start_note_offset = core_audio_devout->start_note_offset;
2854
2855 g_rec_mutex_unlock(core_audio_devout_mutex);
2856
2857 return(start_note_offset);
2858 }
2859
2860 void
ags_core_audio_devout_set_note_offset(AgsSoundcard * soundcard,guint note_offset)2861 ags_core_audio_devout_set_note_offset(AgsSoundcard *soundcard,
2862 guint note_offset)
2863 {
2864 AgsCoreAudioDevout *core_audio_devout;
2865
2866 GRecMutex *core_audio_devout_mutex;
2867
2868 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2869
2870 /* get core_audio devout mutex */
2871 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2872
2873 /* set note offset */
2874 g_rec_mutex_lock(core_audio_devout_mutex);
2875
2876 core_audio_devout->note_offset = note_offset;
2877
2878 g_rec_mutex_unlock(core_audio_devout_mutex);
2879 }
2880
2881 guint
ags_core_audio_devout_get_note_offset(AgsSoundcard * soundcard)2882 ags_core_audio_devout_get_note_offset(AgsSoundcard *soundcard)
2883 {
2884 AgsCoreAudioDevout *core_audio_devout;
2885
2886 guint note_offset;
2887
2888 GRecMutex *core_audio_devout_mutex;
2889
2890 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2891
2892 /* get core_audio devout mutex */
2893 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2894
2895 /* set note offset */
2896 g_rec_mutex_lock(core_audio_devout_mutex);
2897
2898 note_offset = core_audio_devout->note_offset;
2899
2900 g_rec_mutex_unlock(core_audio_devout_mutex);
2901
2902 return(note_offset);
2903 }
2904
2905 void
ags_core_audio_devout_set_note_offset_absolute(AgsSoundcard * soundcard,guint note_offset_absolute)2906 ags_core_audio_devout_set_note_offset_absolute(AgsSoundcard *soundcard,
2907 guint note_offset_absolute)
2908 {
2909 AgsCoreAudioDevout *core_audio_devout;
2910
2911 GRecMutex *core_audio_devout_mutex;
2912
2913 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2914
2915 /* get core_audio devout mutex */
2916 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2917
2918 /* set note offset */
2919 g_rec_mutex_lock(core_audio_devout_mutex);
2920
2921 core_audio_devout->note_offset_absolute = note_offset_absolute;
2922
2923 g_rec_mutex_unlock(core_audio_devout_mutex);
2924 }
2925
2926 guint
ags_core_audio_devout_get_note_offset_absolute(AgsSoundcard * soundcard)2927 ags_core_audio_devout_get_note_offset_absolute(AgsSoundcard *soundcard)
2928 {
2929 AgsCoreAudioDevout *core_audio_devout;
2930
2931 guint note_offset_absolute;
2932
2933 GRecMutex *core_audio_devout_mutex;
2934
2935 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2936
2937 /* get core_audio devout mutex */
2938 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2939
2940 /* set note offset */
2941 g_rec_mutex_lock(core_audio_devout_mutex);
2942
2943 note_offset_absolute = core_audio_devout->note_offset_absolute;
2944
2945 g_rec_mutex_unlock(core_audio_devout_mutex);
2946
2947 return(note_offset_absolute);
2948 }
2949
2950 void
ags_core_audio_devout_set_loop(AgsSoundcard * soundcard,guint loop_left,guint loop_right,gboolean do_loop)2951 ags_core_audio_devout_set_loop(AgsSoundcard *soundcard,
2952 guint loop_left, guint loop_right,
2953 gboolean do_loop)
2954 {
2955 AgsCoreAudioDevout *core_audio_devout;
2956
2957 GRecMutex *core_audio_devout_mutex;
2958
2959 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2960
2961 /* get core_audio devout mutex */
2962 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2963
2964 /* set loop */
2965 g_rec_mutex_lock(core_audio_devout_mutex);
2966
2967 core_audio_devout->loop_left = loop_left;
2968 core_audio_devout->loop_right = loop_right;
2969 core_audio_devout->do_loop = do_loop;
2970
2971 if(do_loop){
2972 core_audio_devout->loop_offset = core_audio_devout->note_offset;
2973 }
2974
2975 g_rec_mutex_unlock(core_audio_devout_mutex);
2976 }
2977
2978 void
ags_core_audio_devout_get_loop(AgsSoundcard * soundcard,guint * loop_left,guint * loop_right,gboolean * do_loop)2979 ags_core_audio_devout_get_loop(AgsSoundcard *soundcard,
2980 guint *loop_left, guint *loop_right,
2981 gboolean *do_loop)
2982 {
2983 AgsCoreAudioDevout *core_audio_devout;
2984
2985 GRecMutex *core_audio_devout_mutex;
2986
2987 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
2988
2989 /* get core_audio devout mutex */
2990 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
2991
2992 /* get loop */
2993 g_rec_mutex_lock(core_audio_devout_mutex);
2994
2995 if(loop_left != NULL){
2996 *loop_left = core_audio_devout->loop_left;
2997 }
2998
2999 if(loop_right != NULL){
3000 *loop_right = core_audio_devout->loop_right;
3001 }
3002
3003 if(do_loop != NULL){
3004 *do_loop = core_audio_devout->do_loop;
3005 }
3006
3007 g_rec_mutex_unlock(core_audio_devout_mutex);
3008 }
3009
3010 guint
ags_core_audio_devout_get_loop_offset(AgsSoundcard * soundcard)3011 ags_core_audio_devout_get_loop_offset(AgsSoundcard *soundcard)
3012 {
3013 AgsCoreAudioDevout *core_audio_devout;
3014
3015 guint loop_offset;
3016
3017 GRecMutex *core_audio_devout_mutex;
3018
3019 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
3020
3021 /* get core_audio devout mutex */
3022 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
3023
3024 /* get loop offset */
3025 g_rec_mutex_lock(core_audio_devout_mutex);
3026
3027 loop_offset = core_audio_devout->loop_offset;
3028
3029 g_rec_mutex_unlock(core_audio_devout_mutex);
3030
3031 return(loop_offset);
3032 }
3033
3034 guint
ags_core_audio_devout_get_sub_block_count(AgsSoundcard * soundcard)3035 ags_core_audio_devout_get_sub_block_count(AgsSoundcard *soundcard)
3036 {
3037 AgsCoreAudioDevout *core_audio_devout;
3038
3039 guint sub_block_count;
3040
3041 GRecMutex *core_audio_devout_mutex;
3042
3043 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
3044
3045 /* get core_audio devout mutex */
3046 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
3047
3048 /* get loop offset */
3049 g_rec_mutex_lock(core_audio_devout_mutex);
3050
3051 sub_block_count = core_audio_devout->sub_block_count;
3052
3053 g_rec_mutex_unlock(core_audio_devout_mutex);
3054
3055 return(sub_block_count);
3056 }
3057
3058 gboolean
ags_core_audio_devout_trylock_sub_block(AgsSoundcard * soundcard,void * buffer,guint sub_block)3059 ags_core_audio_devout_trylock_sub_block(AgsSoundcard *soundcard,
3060 void *buffer, guint sub_block)
3061 {
3062 AgsCoreAudioDevout *core_audio_devout;
3063
3064 guint pcm_channels;
3065 guint sub_block_count;
3066 gboolean success;
3067
3068 GRecMutex *core_audio_devout_mutex;
3069 GRecMutex *sub_block_mutex;
3070
3071 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
3072
3073 /* get core_audio devout mutex */
3074 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
3075
3076 /* get loop offset */
3077 g_rec_mutex_lock(core_audio_devout_mutex);
3078
3079 pcm_channels = core_audio_devout->pcm_channels;
3080 sub_block_count = core_audio_devout->sub_block_count;
3081
3082 g_rec_mutex_unlock(core_audio_devout_mutex);
3083
3084 sub_block_mutex = NULL;
3085
3086 success = FALSE;
3087
3088 if(core_audio_devout->buffer != NULL){
3089 if(buffer == core_audio_devout->buffer[0]){
3090 sub_block_mutex = core_audio_devout->sub_block_mutex[sub_block];
3091 }else if(buffer == core_audio_devout->buffer[1]){
3092 sub_block_mutex = core_audio_devout->sub_block_mutex[pcm_channels * sub_block_count + sub_block];
3093 }else if(buffer == core_audio_devout->buffer[2]){
3094 sub_block_mutex = core_audio_devout->sub_block_mutex[2 * pcm_channels * sub_block_count + sub_block];
3095 }else if(buffer == core_audio_devout->buffer[3]){
3096 sub_block_mutex = core_audio_devout->sub_block_mutex[3 * pcm_channels * sub_block_count + sub_block];
3097 }else if(buffer == core_audio_devout->buffer[4]){
3098 sub_block_mutex = core_audio_devout->sub_block_mutex[4 * pcm_channels * sub_block_count + sub_block];
3099 }else if(buffer == core_audio_devout->buffer[5]){
3100 sub_block_mutex = core_audio_devout->sub_block_mutex[5 * pcm_channels * sub_block_count + sub_block];
3101 }else if(buffer == core_audio_devout->buffer[6]){
3102 sub_block_mutex = core_audio_devout->sub_block_mutex[6 * pcm_channels * sub_block_count + sub_block];
3103 }else if(buffer == core_audio_devout->buffer[7]){
3104 sub_block_mutex = core_audio_devout->sub_block_mutex[7 * pcm_channels * sub_block_count + sub_block];
3105 }
3106 }
3107
3108 if(sub_block_mutex != NULL){
3109 if(g_rec_mutex_trylock(sub_block_mutex)){
3110 success = TRUE;
3111 }
3112 }
3113
3114 return(success);
3115 }
3116
3117 void
ags_core_audio_devout_unlock_sub_block(AgsSoundcard * soundcard,void * buffer,guint sub_block)3118 ags_core_audio_devout_unlock_sub_block(AgsSoundcard *soundcard,
3119 void *buffer, guint sub_block)
3120 {
3121 AgsCoreAudioDevout *core_audio_devout;
3122
3123 guint pcm_channels;
3124 guint sub_block_count;
3125
3126 GRecMutex *core_audio_devout_mutex;
3127 GRecMutex *sub_block_mutex;
3128
3129 core_audio_devout = AGS_CORE_AUDIO_DEVOUT(soundcard);
3130
3131 /* get core_audio devout mutex */
3132 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
3133
3134 /* get loop offset */
3135 g_rec_mutex_lock(core_audio_devout_mutex);
3136
3137 pcm_channels = core_audio_devout->pcm_channels;
3138 sub_block_count = core_audio_devout->sub_block_count;
3139
3140 g_rec_mutex_unlock(core_audio_devout_mutex);
3141
3142 sub_block_mutex = NULL;
3143
3144 if(core_audio_devout->buffer != NULL){
3145 if(buffer == core_audio_devout->buffer[0]){
3146 sub_block_mutex = core_audio_devout->sub_block_mutex[sub_block];
3147 }else if(buffer == core_audio_devout->buffer[1]){
3148 sub_block_mutex = core_audio_devout->sub_block_mutex[pcm_channels * sub_block_count + sub_block];
3149 }else if(buffer == core_audio_devout->buffer[2]){
3150 sub_block_mutex = core_audio_devout->sub_block_mutex[2 * pcm_channels * sub_block_count + sub_block];
3151 }else if(buffer == core_audio_devout->buffer[3]){
3152 sub_block_mutex = core_audio_devout->sub_block_mutex[3 * pcm_channels * sub_block_count + sub_block];
3153 }else if(buffer == core_audio_devout->buffer[4]){
3154 sub_block_mutex = core_audio_devout->sub_block_mutex[4 * pcm_channels * sub_block_count + sub_block];
3155 }else if(buffer == core_audio_devout->buffer[5]){
3156 sub_block_mutex = core_audio_devout->sub_block_mutex[5 * pcm_channels * sub_block_count + sub_block];
3157 }else if(buffer == core_audio_devout->buffer[6]){
3158 sub_block_mutex = core_audio_devout->sub_block_mutex[6 * pcm_channels * sub_block_count + sub_block];
3159 }else if(buffer == core_audio_devout->buffer[7]){
3160 sub_block_mutex = core_audio_devout->sub_block_mutex[7 * pcm_channels * sub_block_count + sub_block];
3161 }
3162 }
3163
3164 if(sub_block_mutex != NULL){
3165 g_rec_mutex_unlock(sub_block_mutex);
3166 }
3167 }
3168
3169 /**
3170 * ags_core_audio_devout_switch_buffer_flag:
3171 * @core_audio_devout: an #AgsCoreAudioDevout
3172 *
3173 * The buffer flag indicates the currently played buffer.
3174 *
3175 * Since: 3.0.0
3176 */
3177 void
ags_core_audio_devout_switch_buffer_flag(AgsCoreAudioDevout * core_audio_devout)3178 ags_core_audio_devout_switch_buffer_flag(AgsCoreAudioDevout *core_audio_devout)
3179 {
3180 GRecMutex *core_audio_devout_mutex;
3181
3182 if(!AGS_IS_CORE_AUDIO_DEVOUT(core_audio_devout)){
3183 return;
3184 }
3185
3186 /* get core_audio devout mutex */
3187 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
3188
3189 /* switch buffer flag */
3190 g_rec_mutex_lock(core_audio_devout_mutex);
3191
3192 if((AGS_CORE_AUDIO_DEVOUT_BUFFER0 & (core_audio_devout->flags)) != 0){
3193 core_audio_devout->flags &= (~AGS_CORE_AUDIO_DEVOUT_BUFFER0);
3194 core_audio_devout->flags |= AGS_CORE_AUDIO_DEVOUT_BUFFER1;
3195 }else if((AGS_CORE_AUDIO_DEVOUT_BUFFER1 & (core_audio_devout->flags)) != 0){
3196 core_audio_devout->flags &= (~AGS_CORE_AUDIO_DEVOUT_BUFFER1);
3197 core_audio_devout->flags |= AGS_CORE_AUDIO_DEVOUT_BUFFER2;
3198 }else if((AGS_CORE_AUDIO_DEVOUT_BUFFER2 & (core_audio_devout->flags)) != 0){
3199 core_audio_devout->flags &= (~AGS_CORE_AUDIO_DEVOUT_BUFFER2);
3200 core_audio_devout->flags |= AGS_CORE_AUDIO_DEVOUT_BUFFER3;
3201 }else if((AGS_CORE_AUDIO_DEVOUT_BUFFER3 & (core_audio_devout->flags)) != 0){
3202 core_audio_devout->flags &= (~AGS_CORE_AUDIO_DEVOUT_BUFFER3);
3203 core_audio_devout->flags |= AGS_CORE_AUDIO_DEVOUT_BUFFER4;
3204 }else if((AGS_CORE_AUDIO_DEVOUT_BUFFER4 & (core_audio_devout->flags)) != 0){
3205 core_audio_devout->flags &= (~AGS_CORE_AUDIO_DEVOUT_BUFFER4);
3206 core_audio_devout->flags |= AGS_CORE_AUDIO_DEVOUT_BUFFER5;
3207 }else if((AGS_CORE_AUDIO_DEVOUT_BUFFER5 & (core_audio_devout->flags)) != 0){
3208 core_audio_devout->flags &= (~AGS_CORE_AUDIO_DEVOUT_BUFFER5);
3209 core_audio_devout->flags |= AGS_CORE_AUDIO_DEVOUT_BUFFER6;
3210 }else if((AGS_CORE_AUDIO_DEVOUT_BUFFER6 & (core_audio_devout->flags)) != 0){
3211 core_audio_devout->flags &= (~AGS_CORE_AUDIO_DEVOUT_BUFFER6);
3212 core_audio_devout->flags |= AGS_CORE_AUDIO_DEVOUT_BUFFER7;
3213 }else if((AGS_CORE_AUDIO_DEVOUT_BUFFER7 & (core_audio_devout->flags)) != 0){
3214 core_audio_devout->flags &= (~AGS_CORE_AUDIO_DEVOUT_BUFFER7);
3215 core_audio_devout->flags |= AGS_CORE_AUDIO_DEVOUT_BUFFER0;
3216 }
3217
3218 g_rec_mutex_unlock(core_audio_devout_mutex);
3219 }
3220
3221 /**
3222 * ags_core_audio_devout_adjust_delay_and_attack:
3223 * @core_audio_devout: the #AgsCoreAudioDevout
3224 *
3225 * Calculate delay and attack and reset it.
3226 *
3227 * Since: 3.0.0
3228 */
3229 void
ags_core_audio_devout_adjust_delay_and_attack(AgsCoreAudioDevout * core_audio_devout)3230 ags_core_audio_devout_adjust_delay_and_attack(AgsCoreAudioDevout *core_audio_devout)
3231 {
3232 if(!AGS_IS_CORE_AUDIO_DEVOUT(core_audio_devout)){
3233 return;
3234 }
3235
3236 ags_soundcard_util_adjust_delay_and_attack(core_audio_devout);
3237 }
3238
3239 /**
3240 * ags_core_audio_devout_realloc_buffer:
3241 * @core_audio_devout: the #AgsCoreAudioDevout
3242 *
3243 * Reallocate the internal audio buffer.
3244 *
3245 * Since: 3.0.0
3246 */
3247 void
ags_core_audio_devout_realloc_buffer(AgsCoreAudioDevout * core_audio_devout)3248 ags_core_audio_devout_realloc_buffer(AgsCoreAudioDevout *core_audio_devout)
3249 {
3250 guint pcm_channels;
3251 guint buffer_size;
3252 guint format;
3253 guint word_size;
3254
3255 GRecMutex *core_audio_devout_mutex;
3256
3257 if(!AGS_IS_CORE_AUDIO_DEVOUT(core_audio_devout)){
3258 return;
3259 }
3260
3261 /* get core_audio devout mutex */
3262 core_audio_devout_mutex = AGS_CORE_AUDIO_DEVOUT_GET_OBJ_MUTEX(core_audio_devout);
3263
3264 /* get word size */
3265 g_rec_mutex_lock(core_audio_devout_mutex);
3266
3267 pcm_channels = core_audio_devout->pcm_channels;
3268 buffer_size = core_audio_devout->buffer_size;
3269
3270 format = core_audio_devout->format;
3271
3272 g_rec_mutex_unlock(core_audio_devout_mutex);
3273
3274 switch(format){
3275 case AGS_SOUNDCARD_SIGNED_16_BIT:
3276 {
3277 word_size = sizeof(gint16);
3278 }
3279 break;
3280 case AGS_SOUNDCARD_SIGNED_24_BIT:
3281 {
3282 word_size = sizeof(gint32);
3283 }
3284 break;
3285 case AGS_SOUNDCARD_SIGNED_32_BIT:
3286 {
3287 word_size = sizeof(gint32);
3288 }
3289 break;
3290 default:
3291 g_warning("ags_core_audio_devout_realloc_buffer(): unsupported word size");
3292 return;
3293 }
3294
3295 /* AGS_CORE_AUDIO_DEVOUT_BUFFER_0 */
3296 if(core_audio_devout->buffer[0] != NULL){
3297 free(core_audio_devout->buffer[0]);
3298 }
3299
3300 core_audio_devout->buffer[0] = (void *) malloc(pcm_channels * buffer_size * word_size);
3301
3302 /* AGS_CORE_AUDIO_DEVOUT_BUFFER_1 */
3303 if(core_audio_devout->buffer[1] != NULL){
3304 free(core_audio_devout->buffer[1]);
3305 }
3306
3307 core_audio_devout->buffer[1] = (void *) malloc(pcm_channels * buffer_size * word_size);
3308
3309 /* AGS_CORE_AUDIO_DEVOUT_BUFFER_2 */
3310 if(core_audio_devout->buffer[2] != NULL){
3311 free(core_audio_devout->buffer[2]);
3312 }
3313
3314 core_audio_devout->buffer[2] = (void *) malloc(pcm_channels * buffer_size * word_size);
3315
3316 /* AGS_CORE_AUDIO_DEVOUT_BUFFER_3 */
3317 if(core_audio_devout->buffer[3] != NULL){
3318 free(core_audio_devout->buffer[3]);
3319 }
3320
3321 core_audio_devout->buffer[3] = (void *) malloc(pcm_channels * buffer_size * word_size);
3322
3323 /* AGS_CORE_AUDIO_DEVOUT_BUFFER_4 */
3324 if(core_audio_devout->buffer[4] != NULL){
3325 free(core_audio_devout->buffer[4]);
3326 }
3327
3328 core_audio_devout->buffer[4] = (void *) malloc(pcm_channels * buffer_size * word_size);
3329
3330 /* AGS_CORE_AUDIO_DEVOUT_BUFFER_5 */
3331 if(core_audio_devout->buffer[5] != NULL){
3332 free(core_audio_devout->buffer[5]);
3333 }
3334
3335 core_audio_devout->buffer[5] = (void *) malloc(pcm_channels * buffer_size * word_size);
3336
3337 /* AGS_CORE_AUDIO_DEVOUT_BUFFER_6 */
3338 if(core_audio_devout->buffer[6] != NULL){
3339 free(core_audio_devout->buffer[6]);
3340 }
3341
3342 core_audio_devout->buffer[6] = (void *) malloc(pcm_channels * buffer_size * word_size);
3343
3344 /* AGS_CORE_AUDIO_DEVOUT_BUFFER_7 */
3345 if(core_audio_devout->buffer[7] != NULL){
3346 free(core_audio_devout->buffer[7]);
3347 }
3348
3349 core_audio_devout->buffer[7] = (void *) malloc(pcm_channels * buffer_size * word_size);
3350 }
3351
3352 /**
3353 * ags_core_audio_devout_new:
3354 *
3355 * Creates a new instance of #AgsCoreAudioDevout.
3356 *
3357 * Returns: a new #AgsCoreAudioDevout
3358 *
3359 * Since: 3.0.0
3360 */
3361 AgsCoreAudioDevout*
ags_core_audio_devout_new()3362 ags_core_audio_devout_new()
3363 {
3364 AgsCoreAudioDevout *core_audio_devout;
3365
3366 core_audio_devout = (AgsCoreAudioDevout *) g_object_new(AGS_TYPE_CORE_AUDIO_DEVOUT,
3367 NULL);
3368
3369 return(core_audio_devout);
3370 }
3371