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