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/recall/ags_play_lv2_audio_run.h>
21 #include <ags/audio/recall/ags_play_lv2_audio.h>
22
23 #include <ags/plugin/ags_lv2_manager.h>
24 #include <ags/plugin/ags_lv2_plugin.h>
25 #include <ags/plugin/ags_plugin_port.h>
26
27 #include <ags/audio/ags_recall_id.h>
28 #include <ags/audio/ags_recall_container.h>
29 #include <ags/audio/ags_port.h>
30 #include <ags/audio/ags_audio_buffer_util.h>
31
32 #include <ags/audio/recall/ags_delay_audio.h>
33 #include <ags/audio/recall/ags_delay_audio_run.h>
34 #include <ags/audio/recall/ags_count_beats_audio.h>
35 #include <ags/audio/recall/ags_count_beats_audio_run.h>
36
37 #include <ags/audio/thread/ags_audio_loop.h>
38 #include <ags/audio/thread/ags_soundcard_thread.h>
39
40 #include <lv2.h>
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <sys/types.h>
46 #include <unistd.h>
47
48 #include <ags/i18n.h>
49
50 void ags_play_lv2_audio_run_class_init(AgsPlayLv2AudioRunClass *play_lv2_audio_run);
51 void ags_play_lv2_audio_run_connectable_interface_init(AgsConnectableInterface *connectable);
52 void ags_play_lv2_audio_run_init(AgsPlayLv2AudioRun *play_lv2_audio_run);
53 void ags_play_lv2_audio_run_set_property(GObject *gobject,
54 guint prop_id,
55 const GValue *value,
56 GParamSpec *param_spec);
57 void ags_play_lv2_audio_run_get_property(GObject *gobject,
58 guint prop_id,
59 GValue *value,
60 GParamSpec *param_spec);
61 void ags_play_lv2_audio_run_dispose(GObject *gobject);
62 void ags_play_lv2_audio_run_finalize(GObject *gobject);
63
64 void ags_play_lv2_audio_run_connect(AgsConnectable *connectable);
65 void ags_play_lv2_audio_run_disconnect(AgsConnectable *connectable);
66 void ags_play_lv2_audio_run_connect_connection(AgsConnectable *connectable,
67 GObject *connection);
68 void ags_play_lv2_audio_run_disconnect_connection(AgsConnectable *connectable,
69 GObject *connection);
70
71 void ags_play_lv2_audio_run_run_init_pre(AgsRecall *recall);
72 void ags_play_lv2_audio_run_run_pre(AgsRecall *recall);
73
74 void ags_play_lv2_audio_run_resolve_dependency(AgsRecall *recall);
75
76 void ags_play_lv2_audio_run_alloc_input_callback(AgsDelayAudioRun *delay_audio_run,
77 guint nth_run,
78 gdouble delay, guint attack,
79 AgsPlayLv2AudioRun *play_lv2_audio_run);
80
81 /**
82 * SECTION:ags_play_lv2_audio_run
83 * @short_description: play lv2
84 * @title: AgsPlayLv2AudioRun
85 * @section_id:
86 * @include: ags/audio/recall/ags_play_lv2_audio_run.h
87 *
88 * The #AgsPlayLv2AudioRun class play lv2.
89 */
90
91 enum{
92 PROP_0,
93 PROP_DELAY_AUDIO_RUN,
94 PROP_COUNT_BEATS_AUDIO_RUN,
95 PROP_DESTINATION,
96 PROP_NOTATION,
97 };
98
99 static gpointer ags_play_lv2_audio_run_parent_class = NULL;
100 static AgsConnectableInterface* ags_play_lv2_audio_run_parent_connectable_interface;
101
102 GType
ags_play_lv2_audio_run_get_type()103 ags_play_lv2_audio_run_get_type()
104 {
105 static volatile gsize g_define_type_id__volatile = 0;
106
107 if(g_once_init_enter (&g_define_type_id__volatile)){
108 GType ags_type_play_lv2_audio_run;
109
110 static const GTypeInfo ags_play_lv2_audio_run_info = {
111 sizeof (AgsPlayLv2AudioRunClass),
112 NULL, /* base_init */
113 NULL, /* base_finalize */
114 (GClassInitFunc) ags_play_lv2_audio_run_class_init,
115 NULL, /* class_finalize */
116 NULL, /* class_data */
117 sizeof (AgsPlayLv2AudioRun),
118 0, /* n_preallocs */
119 (GInstanceInitFunc) ags_play_lv2_audio_run_init,
120 };
121
122 static const GInterfaceInfo ags_connectable_interface_info = {
123 (GInterfaceInitFunc) ags_play_lv2_audio_run_connectable_interface_init,
124 NULL, /* interface_finalize */
125 NULL, /* interface_data */
126 };
127
128 ags_type_play_lv2_audio_run = g_type_register_static(AGS_TYPE_RECALL_AUDIO_RUN,
129 "AgsPlayLv2AudioRun",
130 &ags_play_lv2_audio_run_info,
131 0);
132
133 g_type_add_interface_static(ags_type_play_lv2_audio_run,
134 AGS_TYPE_CONNECTABLE,
135 &ags_connectable_interface_info);
136
137 g_once_init_leave (&g_define_type_id__volatile, ags_type_play_lv2_audio_run);
138 }
139
140 return g_define_type_id__volatile;
141 }
142
143 void
ags_play_lv2_audio_run_class_init(AgsPlayLv2AudioRunClass * play_lv2_audio_run)144 ags_play_lv2_audio_run_class_init(AgsPlayLv2AudioRunClass *play_lv2_audio_run)
145 {
146 GObjectClass *gobject;
147 AgsRecallClass *recall;
148
149 GParamSpec *param_spec;
150
151 ags_play_lv2_audio_run_parent_class = g_type_class_peek_parent(play_lv2_audio_run);
152
153 /* GObjectClass */
154 gobject = (GObjectClass *) play_lv2_audio_run;
155
156 gobject->set_property = ags_play_lv2_audio_run_set_property;
157 gobject->get_property = ags_play_lv2_audio_run_get_property;
158
159 gobject->dispose = ags_play_lv2_audio_run_dispose;
160 gobject->finalize = ags_play_lv2_audio_run_finalize;
161
162 /* properties */
163 /**
164 * AgsPlayLv2AudioRun:delay-audio-run:
165 *
166 * The delay audio run dependency.
167 *
168 * Since: 3.0.0
169 */
170 param_spec = g_param_spec_object("delay-audio-run",
171 i18n_pspec("assigned AgsDelayAudioRun"),
172 i18n_pspec("the AgsDelayAudioRun which emits lv2_alloc_input signal"),
173 AGS_TYPE_DELAY_AUDIO_RUN,
174 G_PARAM_READABLE | G_PARAM_WRITABLE);
175 g_object_class_install_property(gobject,
176 PROP_DELAY_AUDIO_RUN,
177 param_spec);
178
179 /**
180 * AgsPlayLv2AudioRun:count-beats-audio-run:
181 *
182 * The count beats audio run dependency.
183 *
184 * Since: 3.0.0
185 */
186 param_spec = g_param_spec_object("count-beats-audio-run",
187 i18n_pspec("assigned AgsCountBeatsAudioRun"),
188 i18n_pspec("the AgsCountBeatsAudioRun which just counts"),
189 AGS_TYPE_COUNT_BEATS_AUDIO_RUN,
190 G_PARAM_READABLE | G_PARAM_WRITABLE);
191 g_object_class_install_property(gobject,
192 PROP_COUNT_BEATS_AUDIO_RUN,
193 param_spec);
194
195 /**
196 * AgsPlayLv2AudioRun:destination:
197 *
198 * The destination's audio signal.
199 *
200 * Since: 3.0.0
201 */
202 param_spec = g_param_spec_object("destination",
203 i18n_pspec("destination"),
204 i18n_pspec("The destination audio signal"),
205 AGS_TYPE_AUDIO_SIGNAL,
206 G_PARAM_READABLE | G_PARAM_WRITABLE);
207 g_object_class_install_property(gobject,
208 PROP_DESTINATION,
209 param_spec);
210
211 /**
212 * AgsPlayLv2AudioRun:notation:
213 *
214 * The notation containing the notes.
215 *
216 * Since: 3.0.0
217 */
218 param_spec = g_param_spec_object("notation",
219 i18n_pspec("assigned AgsNotation"),
220 i18n_pspec("The AgsNotation containing notes"),
221 AGS_TYPE_NOTATION,
222 G_PARAM_READABLE | G_PARAM_WRITABLE);
223 g_object_class_install_property(gobject,
224 PROP_NOTATION,
225 param_spec);
226
227 /* AgsRecallClass */
228 recall = (AgsRecallClass *) play_lv2_audio_run;
229
230 recall->resolve_dependency = ags_play_lv2_audio_run_resolve_dependency;
231
232 recall->run_init_pre = ags_play_lv2_audio_run_run_init_pre;
233 recall->run_pre = ags_play_lv2_audio_run_run_pre;
234 }
235
236 void
ags_play_lv2_audio_run_connectable_interface_init(AgsConnectableInterface * connectable)237 ags_play_lv2_audio_run_connectable_interface_init(AgsConnectableInterface *connectable)
238 {
239 ags_play_lv2_audio_run_parent_connectable_interface = g_type_interface_peek_parent(connectable);
240
241 connectable->connect = ags_play_lv2_audio_run_connect;
242 connectable->disconnect = ags_play_lv2_audio_run_disconnect;
243
244 connectable->connect_connection = ags_play_lv2_audio_run_connect_connection;
245 connectable->disconnect_connection = ags_play_lv2_audio_run_disconnect_connection;
246 }
247
248 void
ags_play_lv2_audio_run_init(AgsPlayLv2AudioRun * play_lv2_audio_run)249 ags_play_lv2_audio_run_init(AgsPlayLv2AudioRun *play_lv2_audio_run)
250 {
251 ags_recall_set_ability_flags((AgsRecall *) play_lv2_audio_run, (AGS_SOUND_ABILITY_SEQUENCER |
252 AGS_SOUND_ABILITY_NOTATION |
253 AGS_SOUND_ABILITY_WAVE |
254 AGS_SOUND_ABILITY_MIDI));
255
256 AGS_RECALL(play_lv2_audio_run)->name = "ags-play-lv2";
257 AGS_RECALL(play_lv2_audio_run)->version = AGS_RECALL_DEFAULT_VERSION;
258 AGS_RECALL(play_lv2_audio_run)->build_id = AGS_RECALL_DEFAULT_BUILD_ID;
259 AGS_RECALL(play_lv2_audio_run)->xml_type = "ags-play-lv2-audio-run";
260 AGS_RECALL(play_lv2_audio_run)->port = NULL;
261
262 play_lv2_audio_run->lv2_handle = NULL;
263
264 play_lv2_audio_run->port_data = NULL;
265
266 play_lv2_audio_run->input = NULL;
267 play_lv2_audio_run->output = NULL;
268
269 play_lv2_audio_run->event_port = NULL;
270 play_lv2_audio_run->atom_port = NULL;
271
272 play_lv2_audio_run->delta_time = 0;
273
274 play_lv2_audio_run->event_buffer = NULL;
275 play_lv2_audio_run->event_count = NULL;
276
277 play_lv2_audio_run->key_on = 0;
278
279 play_lv2_audio_run->worker_handle = NULL;
280
281 play_lv2_audio_run->delay_audio_run = NULL;
282 play_lv2_audio_run->count_beats_audio_run = NULL;
283
284 play_lv2_audio_run->destination = NULL;
285
286 play_lv2_audio_run->notation = NULL;
287
288 play_lv2_audio_run->timestamp = ags_timestamp_new();
289 g_object_ref(play_lv2_audio_run->timestamp);
290
291 play_lv2_audio_run->timestamp->flags &= (~AGS_TIMESTAMP_UNIX);
292 play_lv2_audio_run->timestamp->flags |= AGS_TIMESTAMP_OFFSET;
293
294 play_lv2_audio_run->timestamp->timer.ags_offset.offset = 0;
295 }
296
297 void
ags_play_lv2_audio_run_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)298 ags_play_lv2_audio_run_set_property(GObject *gobject,
299 guint prop_id,
300 const GValue *value,
301 GParamSpec *param_spec)
302 {
303 AgsPlayLv2AudioRun *play_lv2_audio_run;
304
305 GRecMutex *recall_mutex;
306
307 play_lv2_audio_run = AGS_PLAY_LV2_AUDIO_RUN(gobject);
308
309 /* get recall mutex */
310 recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(play_lv2_audio_run);
311
312 switch(prop_id){
313 case PROP_DELAY_AUDIO_RUN:
314 {
315 AgsDelayAudioRun *delay_audio_run, *old_delay_audio_run;
316
317 gboolean is_template;
318
319 delay_audio_run = g_value_get_object(value);
320 old_delay_audio_run = NULL;
321
322 g_rec_mutex_lock(recall_mutex);
323
324 if(delay_audio_run == play_lv2_audio_run->delay_audio_run){
325 g_rec_mutex_unlock(recall_mutex);
326
327 return;
328 }
329
330 if(play_lv2_audio_run->delay_audio_run != NULL){
331 old_delay_audio_run = play_lv2_audio_run->delay_audio_run;
332
333 g_object_unref(G_OBJECT(play_lv2_audio_run->delay_audio_run));
334 }
335
336 if(delay_audio_run != NULL){
337 g_object_ref(delay_audio_run);
338 }
339
340 g_rec_mutex_unlock(recall_mutex);
341
342 /* check template */
343 if(delay_audio_run != NULL &&
344 ags_recall_test_flags((AgsRecall *) play_lv2_audio_run, AGS_RECALL_TEMPLATE)){
345 is_template = TRUE;
346 }else{
347 is_template = FALSE;
348 }
349
350 /* old - dependency/connection */
351 if(is_template){
352 if(old_delay_audio_run != NULL){
353 AgsRecallDependency *recall_dependency;
354
355 GList *list;
356
357 recall_dependency = NULL;
358 list = ags_recall_dependency_find_dependency(AGS_RECALL(play_lv2_audio_run)->recall_dependency,
359 (GObject *) old_delay_audio_run);
360
361 if(list != NULL){
362 recall_dependency = list->data;
363 }
364
365 ags_recall_remove_recall_dependency(AGS_RECALL(play_lv2_audio_run),
366 recall_dependency);
367 }
368 }else{
369 if(ags_connectable_is_connected(AGS_CONNECTABLE(play_lv2_audio_run))){
370 ags_connectable_disconnect_connection(AGS_CONNECTABLE(play_lv2_audio_run),
371 (GObject *) old_delay_audio_run);
372 }
373 }
374
375 /* new - dependency/connection */
376 g_rec_mutex_lock(recall_mutex);
377
378 play_lv2_audio_run->delay_audio_run = delay_audio_run;
379
380 g_rec_mutex_unlock(recall_mutex);
381
382 if(delay_audio_run != NULL){
383 if(is_template){
384 ags_recall_add_recall_dependency(AGS_RECALL(play_lv2_audio_run),
385 ags_recall_dependency_new((GObject *) delay_audio_run));
386 }else{
387 if(ags_connectable_is_connected(AGS_CONNECTABLE(play_lv2_audio_run))){
388 ags_connectable_connect_connection(AGS_CONNECTABLE(play_lv2_audio_run),
389 (GObject *) delay_audio_run);
390 }
391 }
392 }
393 }
394 break;
395 case PROP_COUNT_BEATS_AUDIO_RUN:
396 {
397 AgsCountBeatsAudioRun *count_beats_audio_run, *old_count_beats_audio_run;
398
399 gboolean is_template;
400
401 count_beats_audio_run = g_value_get_object(value);
402 old_count_beats_audio_run = NULL;
403
404 g_rec_mutex_lock(recall_mutex);
405
406 if(count_beats_audio_run == play_lv2_audio_run->count_beats_audio_run){
407 g_rec_mutex_unlock(recall_mutex);
408
409 return;
410 }
411
412 if((AGS_RECALL_TEMPLATE & (AGS_RECALL(play_lv2_audio_run)->flags)) != 0){
413 is_template = TRUE;
414 }else{
415 is_template = FALSE;
416 }
417
418 if(play_lv2_audio_run->count_beats_audio_run != NULL){
419 old_count_beats_audio_run = play_lv2_audio_run->count_beats_audio_run;
420
421 g_object_unref(G_OBJECT(play_lv2_audio_run->count_beats_audio_run));
422 }
423
424 if(count_beats_audio_run != NULL){
425 g_object_ref(count_beats_audio_run);
426 }
427
428 play_lv2_audio_run->count_beats_audio_run = count_beats_audio_run;
429
430 g_rec_mutex_unlock(recall_mutex);
431
432 /* check template */
433 if(count_beats_audio_run != NULL &&
434 ags_recall_test_flags((AgsRecall *) play_lv2_audio_run, AGS_RECALL_TEMPLATE)){
435 is_template = TRUE;
436 }else{
437 is_template = FALSE;
438 }
439
440 /* dependency - remove */
441 if(is_template){
442 if(old_count_beats_audio_run != NULL){
443 AgsRecallDependency *recall_dependency;
444
445 GList *list;
446
447 recall_dependency = NULL;
448 list = ags_recall_dependency_find_dependency(AGS_RECALL(play_lv2_audio_run)->recall_dependency,
449 (GObject *) old_count_beats_audio_run);
450
451 if(list != NULL){
452 recall_dependency = list->data;
453 }
454
455 ags_recall_remove_recall_dependency(AGS_RECALL(play_lv2_audio_run),
456 recall_dependency);
457 }
458 }
459
460 /* dependency - add */
461 if(is_template &&
462 count_beats_audio_run != NULL){
463 ags_recall_add_recall_dependency(AGS_RECALL(play_lv2_audio_run),
464 ags_recall_dependency_new((GObject *) count_beats_audio_run));
465 }
466 }
467 break;
468 case PROP_DESTINATION:
469 {
470 AgsAudioSignal *destination;
471
472 destination = (AgsAudioSignal *) g_value_get_object(value);
473
474 g_rec_mutex_lock(recall_mutex);
475
476 if(play_lv2_audio_run->destination == (GObject *) destination){
477 g_rec_mutex_unlock(recall_mutex);
478
479 return;
480 }
481
482 if(play_lv2_audio_run->destination != NULL){
483 g_object_unref(play_lv2_audio_run->destination);
484 }
485
486 if(destination != NULL){
487 g_object_ref(destination);
488 }
489
490 play_lv2_audio_run->destination = (GObject *) destination;
491
492 g_rec_mutex_unlock(recall_mutex);
493 }
494 break;
495 case PROP_NOTATION:
496 {
497 AgsNotation *notation;
498
499 notation = (AgsNotation *) g_value_get_object(value);
500
501 g_rec_mutex_lock(recall_mutex);
502
503 if(play_lv2_audio_run->notation == notation){
504 g_rec_mutex_unlock(recall_mutex);
505
506 return;
507 }
508
509 if(play_lv2_audio_run->notation != NULL){
510 g_object_unref(play_lv2_audio_run->notation);
511 }
512
513 if(notation != NULL){
514 g_object_ref(notation);
515 }
516
517 play_lv2_audio_run->notation = notation;
518
519 g_rec_mutex_unlock(recall_mutex);
520 }
521 break;
522 default:
523 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
524 break;
525 };
526 }
527
528 void
ags_play_lv2_audio_run_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)529 ags_play_lv2_audio_run_get_property(GObject *gobject,
530 guint prop_id,
531 GValue *value,
532 GParamSpec *param_spec)
533 {
534 AgsPlayLv2AudioRun *play_lv2_audio_run;
535
536 GRecMutex *recall_mutex;
537
538 play_lv2_audio_run = AGS_PLAY_LV2_AUDIO_RUN(gobject);
539
540 /* get recall mutex */
541 recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(play_lv2_audio_run);
542
543 switch(prop_id){
544 case PROP_DELAY_AUDIO_RUN:
545 {
546 g_rec_mutex_lock(recall_mutex);
547
548 g_value_set_object(value, G_OBJECT(play_lv2_audio_run->delay_audio_run));
549
550 g_rec_mutex_unlock(recall_mutex);
551 }
552 break;
553 case PROP_COUNT_BEATS_AUDIO_RUN:
554 {
555 g_rec_mutex_lock(recall_mutex);
556
557 g_value_set_object(value, G_OBJECT(play_lv2_audio_run->count_beats_audio_run));
558
559 g_rec_mutex_unlock(recall_mutex);
560 }
561 break;
562 case PROP_DESTINATION:
563 {
564 g_rec_mutex_lock(recall_mutex);
565
566 g_value_set_object(value, play_lv2_audio_run->destination);
567
568 g_rec_mutex_unlock(recall_mutex);
569 }
570 break;
571 case PROP_NOTATION:
572 {
573 g_rec_mutex_lock(recall_mutex);
574
575 g_value_set_object(value, play_lv2_audio_run->notation);
576
577 g_rec_mutex_unlock(recall_mutex);
578 }
579 break;
580 default:
581 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
582 break;
583 };
584 }
585
586 void
ags_play_lv2_audio_run_dispose(GObject * gobject)587 ags_play_lv2_audio_run_dispose(GObject *gobject)
588 {
589 AgsPlayLv2AudioRun *play_lv2_audio_run;
590
591 play_lv2_audio_run = AGS_PLAY_LV2_AUDIO_RUN(gobject);
592
593 /* delay audio run */
594 if(play_lv2_audio_run->delay_audio_run != NULL){
595 g_object_unref(G_OBJECT(play_lv2_audio_run->delay_audio_run));
596
597 play_lv2_audio_run->delay_audio_run = NULL;
598 }
599
600 /* count beats audio run */
601 if(play_lv2_audio_run->count_beats_audio_run != NULL){
602 g_object_unref(G_OBJECT(play_lv2_audio_run->count_beats_audio_run));
603
604 play_lv2_audio_run->count_beats_audio_run = NULL;
605 }
606
607 /* notation */
608 if(play_lv2_audio_run->notation != NULL){
609 g_object_unref(G_OBJECT(play_lv2_audio_run->notation));
610
611 play_lv2_audio_run->notation = NULL;
612 }
613
614 /* call parent */
615 G_OBJECT_CLASS(ags_play_lv2_audio_run_parent_class)->dispose(gobject);
616 }
617
618 void
ags_play_lv2_audio_run_finalize(GObject * gobject)619 ags_play_lv2_audio_run_finalize(GObject *gobject)
620 {
621 AgsPlayLv2AudioRun *play_lv2_audio_run;
622
623 play_lv2_audio_run = AGS_PLAY_LV2_AUDIO_RUN(gobject);
624
625 g_free(play_lv2_audio_run->port_data);
626
627 g_free(play_lv2_audio_run->input);
628 g_free(play_lv2_audio_run->output);
629
630 //FIXME:JK: memory leak
631 g_free(play_lv2_audio_run->event_port);
632 g_free(play_lv2_audio_run->atom_port);
633
634 /* delay audio run */
635 if(play_lv2_audio_run->delay_audio_run != NULL){
636 g_object_unref(G_OBJECT(play_lv2_audio_run->delay_audio_run));
637 }
638
639 /* count beats audio run */
640 if(play_lv2_audio_run->count_beats_audio_run != NULL){
641 g_object_unref(G_OBJECT(play_lv2_audio_run->count_beats_audio_run));
642 }
643
644 /* notation */
645 if(play_lv2_audio_run->notation != NULL){
646 g_object_unref(G_OBJECT(play_lv2_audio_run->notation));
647 }
648
649 /* timestamp */
650 if(play_lv2_audio_run->timestamp != NULL){
651 g_object_unref(G_OBJECT(play_lv2_audio_run->timestamp));
652 }
653
654 /* call parent */
655 G_OBJECT_CLASS(ags_play_lv2_audio_run_parent_class)->finalize(gobject);
656 }
657
658 void
ags_play_lv2_audio_run_connect(AgsConnectable * connectable)659 ags_play_lv2_audio_run_connect(AgsConnectable *connectable)
660 {
661 AgsPlayLv2AudioRun *play_lv2_audio_run;
662 AgsDelayAudioRun *delay_audio_run;
663
664 if(ags_connectable_is_connected(connectable)){
665 return;
666 }
667
668 play_lv2_audio_run = AGS_PLAY_LV2_AUDIO_RUN(connectable);
669
670 g_object_get(play_lv2_audio_run,
671 "delay-audio-run", &delay_audio_run,
672 NULL);
673
674 ags_connectable_connect_connection(connectable, (GObject *) delay_audio_run);
675
676 /* call parent */
677 ags_play_lv2_audio_run_parent_connectable_interface->connect(connectable);
678
679 if(delay_audio_run != NULL){
680 g_object_unref(delay_audio_run);
681 }
682 }
683
684 void
ags_play_lv2_audio_run_disconnect(AgsConnectable * connectable)685 ags_play_lv2_audio_run_disconnect(AgsConnectable *connectable)
686 {
687 AgsPlayLv2AudioRun *play_lv2_audio_run;
688 AgsDelayAudioRun *delay_audio_run;
689
690 if(!ags_connectable_is_connected(connectable)){
691 return;
692 }
693
694 play_lv2_audio_run = AGS_PLAY_LV2_AUDIO_RUN(connectable);
695
696 g_object_get(play_lv2_audio_run,
697 "delay-audio-run", &delay_audio_run,
698 NULL);
699
700 ags_connectable_disconnect_connection(connectable, (GObject *) delay_audio_run);
701
702 /* call parent */
703 ags_play_lv2_audio_run_parent_connectable_interface->disconnect(connectable);
704
705 if(delay_audio_run != NULL){
706 g_object_unref(delay_audio_run);
707 }
708 }
709
710 void
ags_play_lv2_audio_run_connect_connection(AgsConnectable * connectable,GObject * connection)711 ags_play_lv2_audio_run_connect_connection(AgsConnectable *connectable, GObject *connection)
712 {
713 AgsPlayLv2AudioRun *play_lv2_audio_run;
714 AgsDelayAudioRun *delay_audio_run;
715
716 if(connection == NULL){
717 return;
718 }
719
720 play_lv2_audio_run = AGS_PLAY_LV2_AUDIO_RUN(connectable);
721
722 g_object_get(play_lv2_audio_run,
723 "delay-audio-run", &delay_audio_run,
724 NULL);
725
726 if(connection == (GObject *) delay_audio_run){
727 g_signal_connect(G_OBJECT(delay_audio_run), "notation-alloc-input",
728 G_CALLBACK(ags_play_lv2_audio_run_alloc_input_callback), play_lv2_audio_run);
729 }
730
731 if(delay_audio_run != NULL){
732 g_object_unref(delay_audio_run);
733 }
734 }
735
736 void
ags_play_lv2_audio_run_disconnect_connection(AgsConnectable * connectable,GObject * connection)737 ags_play_lv2_audio_run_disconnect_connection(AgsConnectable *connectable, GObject *connection)
738 {
739 AgsPlayLv2AudioRun *play_lv2_audio_run;
740 AgsDelayAudioRun *delay_audio_run;
741
742 if(connection == NULL){
743 return;
744 }
745
746 play_lv2_audio_run = AGS_PLAY_LV2_AUDIO_RUN(connectable);
747
748 g_object_get(play_lv2_audio_run,
749 "delay-audio-run", &delay_audio_run,
750 NULL);
751
752 if(connection == (GObject *) delay_audio_run){
753 g_object_disconnect(G_OBJECT(delay_audio_run),
754 "any_signal::notation-alloc-input",
755 G_CALLBACK(ags_play_lv2_audio_run_alloc_input_callback),
756 play_lv2_audio_run,
757 NULL);
758 }
759
760 if(delay_audio_run != NULL){
761 g_object_unref(delay_audio_run);
762 }
763 }
764
765 void
ags_play_lv2_audio_run_resolve_dependency(AgsRecall * recall)766 ags_play_lv2_audio_run_resolve_dependency(AgsRecall *recall)
767 {
768 AgsRecall *template;
769 AgsRecallID *recall_id;
770 AgsRecallContainer *recall_container;
771 AgsRecallDependency *recall_dependency;
772 AgsDelayAudioRun *delay_audio_run;
773 AgsCountBeatsAudioRun *count_beats_audio_run;
774
775 GList *list_start, *list;
776
777 guint i, i_stop;
778
779 g_object_get(recall,
780 "recall-id", &recall_id,
781 "recall-container", &recall_container,
782 NULL);
783
784 g_object_get(recall_container,
785 "recall-audio-run", &list_start,
786 NULL);
787
788 template = NULL;
789 list = ags_recall_find_template(list_start);
790
791 if(list != NULL){
792 template = AGS_RECALL(list->data);
793 }
794
795 g_list_free_full(list_start,
796 g_object_unref);
797
798 g_object_get(template,
799 "recall-dependency", &list_start,
800 NULL);
801
802 list = list_start;
803
804 delay_audio_run = NULL;
805 count_beats_audio_run = NULL;
806
807 i_stop = 2;
808
809 for(i = 0; i < i_stop && list != NULL;){
810 GObject *dependency;
811
812 recall_dependency = AGS_RECALL_DEPENDENCY(list->data);
813
814 g_object_get(recall_dependency,
815 "dependency", &dependency,
816 NULL);
817
818 if(AGS_IS_DELAY_AUDIO_RUN(dependency)){
819 delay_audio_run = (AgsDelayAudioRun *) ags_recall_dependency_resolve(recall_dependency,
820 recall_id);
821
822 i++;
823 }else if(AGS_IS_COUNT_BEATS_AUDIO_RUN(dependency)){
824 count_beats_audio_run = (AgsCountBeatsAudioRun *) ags_recall_dependency_resolve(recall_dependency,
825 recall_id);
826
827 i++;
828 }
829
830 g_object_unref(dependency);
831
832 list = list->next;
833 }
834
835 g_object_set(G_OBJECT(recall),
836 "delay-audio-run", delay_audio_run,
837 "count-beats-audio-run", count_beats_audio_run,
838 NULL);
839
840 /* unref */
841 g_object_unref(recall_id);
842
843 g_object_unref(recall_container);
844
845 g_list_free_full(list_start,
846 g_object_unref);
847 }
848
849 void
ags_play_lv2_audio_run_run_init_pre(AgsRecall * recall)850 ags_play_lv2_audio_run_run_init_pre(AgsRecall *recall)
851 {
852 AgsPlayLv2Audio *play_lv2_audio;
853 AgsPlayLv2AudioRun *play_lv2_audio_run;
854
855 AgsLv2Plugin *lv2_plugin;
856
857 GObject *output_soundcard;
858
859 LV2_Handle *lv2_handle;
860
861 gchar *path;
862 float *output, *input;
863
864 guint output_lines, input_lines;
865 guint audio_channel;
866 guint samplerate;
867 guint buffer_size;
868 guint port_count;
869 uint32_t i;
870
871 GRecMutex *play_lv2_audio_mutex;
872
873 void (*parent_class_run_init_pre)(AgsRecall *recall);
874
875 void (*connect_port)(LV2_Handle instance,
876 uint32_t port,
877 void *data_location);
878 void (*activate)(LV2_Handle instance);
879
880 /* get parent class */
881 parent_class_run_init_pre = AGS_RECALL_CLASS(ags_play_lv2_audio_run_parent_class)->run_init_pre;
882
883 /* call parent */
884 parent_class_run_init_pre(recall);
885
886 play_lv2_audio_run = AGS_PLAY_LV2_AUDIO_RUN(recall);
887
888 /* get some fields */
889 g_object_get(play_lv2_audio_run,
890 "output-soundcard", &output_soundcard,
891 "recall-audio", &play_lv2_audio,
892 NULL);
893
894 /* get presets */
895 ags_soundcard_get_presets(AGS_SOUNDCARD(output_soundcard),
896 NULL,
897 &samplerate,
898 &buffer_size,
899 NULL);
900
901 /* recall mutex */
902 play_lv2_audio_mutex = AGS_RECALL_GET_OBJ_MUTEX(play_lv2_audio);
903
904 /* get some fields */
905 g_rec_mutex_lock(play_lv2_audio_mutex);
906
907 lv2_plugin = play_lv2_audio->plugin;
908
909 input_lines = play_lv2_audio->input_lines;
910 output_lines = play_lv2_audio->output_lines;
911
912 connect_port = play_lv2_audio->plugin_descriptor->connect_port;
913 activate = play_lv2_audio->plugin_descriptor->activate;
914
915 g_rec_mutex_unlock(play_lv2_audio_mutex);
916
917 /* set up buffer */
918 input = NULL;
919 output = NULL;
920
921 if(input_lines > 0){
922 input = (float *) malloc(input_lines *
923 buffer_size *
924 sizeof(float));
925 }
926
927 output = (float *) malloc(output_lines *
928 buffer_size *
929 sizeof(float));
930
931 play_lv2_audio_run->output = output;
932 play_lv2_audio_run->input = input;
933
934 /* instantiate lv2 */
935 lv2_handle = (LV2_Handle *) ags_base_plugin_instantiate((AgsBasePlugin *) lv2_plugin,
936 samplerate, buffer_size);
937
938 play_lv2_audio_run->lv2_handle = lv2_handle;
939
940 #ifdef AGS_DEBUG
941 g_message("instantiate LV2 handle");
942 #endif
943
944 ags_play_lv2_audio_run_load_ports(play_lv2_audio_run);
945
946 /* can't be done in ags_play_lv2_audio_run_run_init_inter since possebility of overlapping buffers */
947 g_rec_mutex_lock(play_lv2_audio_mutex);
948
949 /* connect audio port */
950 for(i = 0; i < input_lines; i++){
951 #ifdef AGS_DEBUG
952 g_message("connect port: %d", play_lv2_audio->input_port[i]);
953 #endif
954
955 connect_port(play_lv2_audio_run->lv2_handle[0],
956 play_lv2_audio->input_port[i],
957 play_lv2_audio_run->input);
958 }
959
960 for(i = 0; i < output_lines; i++){
961 #ifdef AGS_DEBUG
962 g_message("connect port: %d", play_lv2_audio->output_port[i]);
963 #endif
964
965 connect_port(play_lv2_audio_run->lv2_handle[0],
966 play_lv2_audio->output_port[i],
967 play_lv2_audio_run->output);
968 }
969
970 /* connect event port */
971 if(ags_play_lv2_audio_test_flags(play_lv2_audio, AGS_PLAY_LV2_AUDIO_HAS_EVENT_PORT)){
972 play_lv2_audio_run->event_port = ags_lv2_plugin_event_buffer_alloc(AGS_PLAY_LV2_AUDIO_DEFAULT_MIDI_LENGHT);
973
974 connect_port(play_lv2_audio_run->lv2_handle[0],
975 play_lv2_audio->event_port,
976 play_lv2_audio_run->event_port);
977 }
978
979 /* connect atom port */
980 if(ags_play_lv2_audio_test_flags(play_lv2_audio, AGS_PLAY_LV2_AUDIO_HAS_ATOM_PORT)){
981 play_lv2_audio_run->atom_port = ags_lv2_plugin_alloc_atom_sequence(AGS_PLAY_LV2_AUDIO_DEFAULT_MIDI_LENGHT);
982
983 connect_port(play_lv2_audio_run->lv2_handle[0],
984 play_lv2_audio->atom_port,
985 play_lv2_audio_run->atom_port);
986 }
987
988 /* activate */
989 if(activate != NULL){
990 activate(play_lv2_audio_run->lv2_handle[0]);
991 }
992
993 g_rec_mutex_unlock(play_lv2_audio_mutex);
994
995 /* set program */
996 if(ags_lv2_plugin_test_flags(lv2_plugin, AGS_LV2_PLUGIN_HAS_PROGRAM_INTERFACE)){
997 AgsPort *current_port;
998
999 GList *plugin_port_start, *plugin_port;
1000 GList *port;
1001 GList *list;
1002
1003 gchar *specifier, *current_specifier;
1004
1005 float *port_data;
1006
1007 guint bank, program;
1008 guint port_count;
1009
1010 GRecMutex *base_plugin_mutex;
1011
1012 g_rec_mutex_lock(play_lv2_audio_mutex);
1013
1014 port = g_list_copy(AGS_RECALL(play_lv2_audio)->port);
1015
1016 bank = play_lv2_audio->bank;
1017 program = play_lv2_audio->program;
1018
1019 g_rec_mutex_unlock(play_lv2_audio_mutex);
1020
1021 /* get base plugin mutex */
1022 base_plugin_mutex = AGS_BASE_PLUGIN_GET_OBJ_MUTEX(lv2_plugin);
1023
1024 /* get plugin port */
1025 g_rec_mutex_lock(base_plugin_mutex);
1026
1027 plugin_port =
1028 plugin_port_start = g_list_copy(AGS_BASE_PLUGIN(lv2_plugin)->plugin_port);
1029
1030 g_rec_mutex_unlock(base_plugin_mutex);
1031
1032 /* create port data */
1033 port_count = g_list_length(plugin_port_start);
1034
1035 port_data = (float *) malloc(port_count * sizeof(float));
1036
1037 plugin_port = plugin_port_start;
1038
1039 for(i = 0; i < port_count && plugin_port != NULL; ){
1040 AgsPluginPort *current_plugin_port;
1041
1042 GRecMutex *plugin_port_mutex;
1043
1044 current_plugin_port = AGS_PLUGIN_PORT(plugin_port->data);
1045
1046 /* get plugin port mutex */
1047 plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(current_plugin_port);
1048
1049 /* get specifier */
1050 g_rec_mutex_lock(plugin_port_mutex);
1051
1052 specifier = g_strdup(current_plugin_port->port_name);
1053
1054 g_rec_mutex_unlock(plugin_port_mutex);
1055
1056 list = ags_port_find_specifier(port, specifier);
1057 port_data[i] = 0.0;
1058
1059 if(list != NULL){
1060 GValue value = {0,};
1061
1062 current_port = list->data;
1063
1064 g_value_init(&value,
1065 G_TYPE_FLOAT);
1066
1067 ags_port_safe_read(current_port,
1068 &value);
1069 port_data[i] = g_value_get_float(&value);
1070
1071 g_value_unset(&value);
1072 }
1073
1074 g_free(specifier);
1075
1076 /* iterate plugin port */
1077 plugin_port = plugin_port->next;
1078 }
1079
1080 ags_lv2_plugin_change_program(lv2_plugin,
1081 play_lv2_audio_run->lv2_handle[0],
1082 bank,
1083 program);
1084
1085 /* reset port data */
1086 plugin_port = plugin_port_start;
1087
1088 for(i = 0; i < port_count && plugin_port != NULL;){
1089 AgsPluginPort *current_plugin_port;
1090
1091 GRecMutex *plugin_port_mutex;
1092
1093 current_plugin_port = AGS_PLUGIN_PORT(plugin_port->data);
1094
1095 /* get plugin port mutex */
1096 plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(current_plugin_port);
1097
1098 /* get specifier */
1099 g_rec_mutex_lock(plugin_port_mutex);
1100
1101 specifier = g_strdup(current_plugin_port->port_name);
1102
1103 g_rec_mutex_unlock(plugin_port_mutex);
1104
1105 list = ags_port_find_specifier(port, specifier);
1106
1107 if(list != NULL){
1108 GValue value = {0,};
1109
1110 current_port = list->data;
1111
1112 g_value_init(&value,
1113 G_TYPE_FLOAT);
1114 g_value_set_float(&value, port_data[i]);
1115
1116 ags_port_safe_write_raw(current_port,
1117 &value);
1118
1119 g_value_unset(&value);
1120 }
1121
1122 /* iterate plugin port */
1123 plugin_port = plugin_port->next;
1124 }
1125
1126 g_free(port_data);
1127
1128 g_list_free(port);
1129 g_list_free(plugin_port_start);
1130 }
1131
1132 /* unref */
1133 g_object_unref(output_soundcard);
1134
1135 g_object_unref(play_lv2_audio);
1136 }
1137
1138 void
ags_play_lv2_audio_run_run_pre(AgsRecall * recall)1139 ags_play_lv2_audio_run_run_pre(AgsRecall *recall)
1140 {
1141 AgsAudio *audio;
1142 AgsChannel *start_output, *start_input;
1143 AgsChannel *channel;
1144 AgsChannel *selected_channel;
1145 AgsRecycling *recycling;
1146 AgsAudioSignal *destination;
1147 AgsRecallID *recall_id;
1148 AgsRecyclingContext *recycling_context;
1149 AgsPlayLv2Audio *play_lv2_audio;
1150 AgsPlayLv2AudioRun *play_lv2_audio_run;
1151
1152 AgsLv2Plugin *lv2_plugin;
1153
1154 GObject *output_soundcard;
1155
1156 float *output_buffer, *input_buffer;
1157
1158 guint output_lines, input_lines;
1159 guint audio_channel;
1160 guint samplerate;
1161 guint buffer_size;
1162 guint format;
1163 guint copy_mode_in, copy_mode_out;
1164 uint32_t i;
1165
1166 void (*parent_class_run_pre)(AgsRecall *recall);
1167
1168 void (*run)(LV2_Handle instance,
1169 uint32_t sample_count);
1170 void (*deactivate)(LV2_Handle instance);
1171 void (*cleanup)(LV2_Handle instance);
1172
1173 GRecMutex *play_lv2_audio_mutex;
1174
1175 /* get parent class */
1176 parent_class_run_pre = AGS_RECALL_CLASS(ags_play_lv2_audio_run_parent_class)->run_pre;
1177
1178 /* call parent */
1179 parent_class_run_pre(recall);
1180
1181 play_lv2_audio_run = AGS_PLAY_LV2_AUDIO_RUN(recall);
1182
1183 /* get some fields */
1184 g_object_get(play_lv2_audio_run,
1185 "output-soundcard", &output_soundcard,
1186 "audio-channel", &audio_channel,
1187 "recall-id", &recall_id,
1188 "audio", &audio,
1189 "recall-audio", &play_lv2_audio,
1190 "destination", &destination,
1191 NULL);
1192
1193 /* get presets */
1194 ags_soundcard_get_presets(AGS_SOUNDCARD(output_soundcard),
1195 NULL,
1196 NULL,
1197 &buffer_size,
1198 NULL);
1199
1200 /* recall mutex */
1201 play_lv2_audio_mutex = AGS_RECALL_GET_OBJ_MUTEX(play_lv2_audio);
1202
1203 /* get some fields */
1204 g_rec_mutex_lock(play_lv2_audio_mutex);
1205
1206 lv2_plugin = play_lv2_audio->plugin;
1207
1208 input_lines = play_lv2_audio->input_lines;
1209 output_lines = play_lv2_audio->output_lines;
1210
1211 g_rec_mutex_unlock(play_lv2_audio_mutex);
1212
1213 /* get some fields */
1214 g_object_get(audio,
1215 "output", &start_output,
1216 "input", &start_input,
1217 NULL);
1218
1219 /* get channel */
1220 selected_channel = ags_channel_nth(start_output,
1221 audio_channel);
1222
1223 #if 0
1224 if(ags_audio_test_behaviour_flags(audio, AGS_SOUND_BEHAVIOUR_DEFAULTS_TO_INPUT)){
1225 selected_channel = ags_channel_nth(start_input,
1226 audio_channel);
1227 }else{
1228 selected_channel = ags_channel_nth(start_output,
1229 audio_channel);
1230 }
1231 #endif
1232
1233 /* recycling */
1234 g_object_get(selected_channel,
1235 "first-recycling", &recycling,
1236 NULL);
1237
1238 ags_recall_unset_behaviour_flags((AgsRecall *) recall, AGS_SOUND_BEHAVIOUR_PERSISTENT);
1239
1240 if(destination == NULL){
1241 gdouble delay;
1242 guint attack;
1243 guint length;
1244
1245 //TODO:JK: unclear
1246 attack = 0;
1247 delay = 0.0;
1248
1249 /* create new audio signal */
1250 destination = ags_audio_signal_new((GObject *) output_soundcard,
1251 (GObject *) recycling,
1252 (GObject *) recall_id);
1253
1254 g_object_set(play_lv2_audio_run,
1255 "destination", destination,
1256 NULL);
1257
1258 ags_recycling_create_audio_signal_with_defaults(recycling,
1259 destination,
1260 delay, attack);
1261 length = 1; // (guint) (2.0 * soundcard->delay[soundcard->tic_counter]) + 1;
1262 ags_audio_signal_stream_resize(destination,
1263 length);
1264
1265 ags_connectable_connect(AGS_CONNECTABLE(destination));
1266
1267 destination->stream_current = destination->stream;
1268
1269 ags_recycling_add_audio_signal(recycling,
1270 destination);
1271
1272 #ifdef AGS_DEBUG
1273 g_message("play %x to %x", destination, recall_id);
1274 g_message("creating destination");
1275 #endif
1276 }
1277
1278 /*
1279 * process data
1280 */
1281
1282 /* create audio data */
1283 g_object_get(destination,
1284 "buffer-size", &buffer_size,
1285 "format", &format,
1286 NULL);
1287
1288 ags_audio_buffer_util_clear_buffer(destination->stream_current->data, 1,
1289 buffer_size, ags_audio_buffer_util_format_from_soundcard(format));
1290
1291 /* get copy mode and clear buffer */
1292 copy_mode_in = ags_audio_buffer_util_get_copy_mode(AGS_AUDIO_BUFFER_UTIL_FLOAT,
1293 ags_audio_buffer_util_format_from_soundcard(format));
1294
1295 copy_mode_out = ags_audio_buffer_util_get_copy_mode(ags_audio_buffer_util_format_from_soundcard(format),
1296 AGS_AUDIO_BUFFER_UTIL_FLOAT);
1297
1298 if(play_lv2_audio_run->output != NULL){
1299 ags_audio_buffer_util_clear_float(play_lv2_audio_run->output, output_lines,
1300 buffer_size);
1301 }
1302
1303 if(play_lv2_audio_run->input != NULL){
1304 ags_audio_buffer_util_clear_float(play_lv2_audio_run->input, input_lines,
1305 buffer_size);
1306 }
1307
1308 /* copy data */
1309 if(play_lv2_audio_run->input != NULL){
1310 ags_audio_buffer_util_copy_buffer_to_buffer(play_lv2_audio_run->input, (guint) input_lines, 0,
1311 destination->stream_current->data, 1, 0,
1312 (guint) buffer_size, copy_mode_in);
1313 }
1314
1315 /* process data */
1316 g_rec_mutex_lock(play_lv2_audio_mutex);
1317
1318 run = play_lv2_audio->plugin_descriptor->run;
1319
1320 g_rec_mutex_unlock(play_lv2_audio_mutex);
1321
1322 if(play_lv2_audio_run->key_on != 0 &&
1323 play_lv2_audio_run->lv2_handle != NULL){
1324 run(play_lv2_audio_run->lv2_handle[0],
1325 (uint32_t) buffer_size);
1326 }
1327
1328 /* copy data */
1329 if(play_lv2_audio_run->output != NULL){
1330 ags_audio_buffer_util_copy_buffer_to_buffer(destination->stream_current->data, 1, 0,
1331 play_lv2_audio_run->output, (guint) output_lines, 0,
1332 (guint) buffer_size, copy_mode_out);
1333 }
1334
1335 /* unref */
1336 g_object_unref(output_soundcard);
1337
1338 g_object_unref(recall_id);
1339
1340 g_object_unref(audio);
1341
1342 g_object_unref(play_lv2_audio);
1343
1344 g_object_unref(destination);
1345
1346 if(start_output != NULL){
1347 g_object_unref(start_output);
1348 }
1349
1350 if(start_input != NULL){
1351 g_object_unref(start_input);
1352 }
1353
1354 if(selected_channel != NULL){
1355 g_object_unref(selected_channel);
1356 }
1357
1358 if(recycling != NULL){
1359 g_object_unref(recycling);
1360 }
1361 }
1362
1363 void
ags_play_lv2_audio_run_alloc_input_callback(AgsDelayAudioRun * delay_audio_run,guint nth_run,gdouble delay,guint attack,AgsPlayLv2AudioRun * play_lv2_audio_run)1364 ags_play_lv2_audio_run_alloc_input_callback(AgsDelayAudioRun *delay_audio_run,
1365 guint nth_run,
1366 gdouble delay, guint attack,
1367 AgsPlayLv2AudioRun *play_lv2_audio_run)
1368 {
1369 AgsAudio *audio;
1370 AgsNotation *notation;
1371 AgsNote *note;
1372 AgsPlayLv2Audio *play_lv2_audio;
1373 AgsDelayAudio *delay_audio;
1374
1375 GObject *output_soundcard;
1376
1377 snd_seq_event_t *seq_event;
1378 snd_seq_event_t **event_buffer;
1379 unsigned long *event_count;
1380
1381 GList *start_list, *list;
1382 GList *start_current_position, *current_position;
1383 GList *start_append_note, *append_note;
1384 GList *start_remove_note, *remove_note;
1385
1386 guint audio_start_mapping;
1387 guint midi_start_mapping, midi_end_mapping;
1388 guint notation_counter;
1389 guint note_x0, note_x1;
1390 guint note_y;
1391 guint input_pads;
1392 guint selected_key;
1393 guint audio_channel;
1394 guint i;
1395
1396 GRecMutex *audio_mutex;
1397
1398 if(delay != 0.0){
1399 return;
1400 }
1401
1402 g_object_get(play_lv2_audio_run,
1403 "audio", &audio,
1404 "audio-channel", &audio_channel,
1405 "output-soundcard", &output_soundcard,
1406 "recall-audio", &play_lv2_audio,
1407 NULL);
1408
1409 g_object_get(delay_audio_run,
1410 "recall-audio", &delay_audio,
1411 NULL);
1412
1413 /* audio mutex */
1414 audio_mutex = AGS_AUDIO_GET_OBJ_MUTEX(audio);
1415
1416 /* get audio fields */
1417 g_rec_mutex_lock(audio_mutex);
1418
1419 start_list = g_list_copy_deep(audio->notation,
1420 (GCopyFunc) g_object_ref,
1421 NULL);
1422
1423 g_rec_mutex_unlock(audio_mutex);
1424
1425 if(start_list == NULL){
1426 g_object_unref(audio);
1427
1428 g_object_unref(output_soundcard);
1429
1430 g_object_unref(play_lv2_audio);
1431
1432 g_object_unref(delay_audio);
1433
1434 return;
1435 }
1436
1437 /* get notation */
1438 notation = NULL;
1439 current_position = NULL;
1440
1441 start_append_note = NULL;
1442 start_remove_note = NULL;
1443
1444 /* get some fields */
1445 g_rec_mutex_lock(audio_mutex);
1446
1447 notation_counter = play_lv2_audio_run->count_beats_audio_run->notation_counter;
1448
1449 input_pads = audio->input_pads;
1450
1451 audio_start_mapping = audio->audio_start_mapping;
1452
1453 midi_start_mapping = audio->midi_start_mapping;
1454 midi_end_mapping = audio->midi_end_mapping;
1455
1456 g_rec_mutex_unlock(audio_mutex);
1457
1458 /* */
1459 play_lv2_audio_run->timestamp->timer.ags_offset.offset = AGS_NOTATION_DEFAULT_OFFSET * floor(notation_counter / AGS_NOTATION_DEFAULT_OFFSET);
1460
1461 list = ags_notation_find_near_timestamp(start_list, audio_channel,
1462 play_lv2_audio_run->timestamp);
1463 start_current_position = NULL;
1464
1465 if(list != NULL){
1466 notation = list->data;
1467
1468 g_object_get(notation,
1469 "note", &start_current_position,
1470 NULL);
1471
1472 current_position = start_current_position;
1473 }
1474
1475 /*
1476 * feed midi
1477 */
1478 while(current_position != NULL){
1479 gboolean do_feed;
1480 gboolean success;
1481
1482 note = AGS_NOTE(current_position->data);
1483
1484 do_feed = ags_note_test_flags(note,
1485 AGS_NOTE_FEED);
1486 g_object_get(note,
1487 "x0", ¬e_x0,
1488 "x1", ¬e_x1,
1489 "y", ¬e_y,
1490 NULL);
1491
1492 if(note_x0 == notation_counter){
1493 start_append_note = g_list_prepend(start_append_note,
1494 note);
1495 g_object_ref(note);
1496 }else if((do_feed &&
1497 (note_x1 == notation_counter ||
1498 note_x1 + 1 == notation_counter)) ||
1499 (!do_feed &&
1500 note_x0 <= notation_counter &&
1501 note_x1 > notation_counter)){
1502 //feed
1503 }else if((do_feed &&
1504 note_x1 + 1 == notation_counter) ||
1505 (!do_feed &&
1506 note_x1 == notation_counter)){
1507 start_remove_note = g_list_prepend(start_remove_note,
1508 note);
1509 g_object_ref(note);
1510 }else if(note_x0 > notation_counter){
1511 break;
1512 }
1513
1514 /* iterate */
1515 current_position = current_position->next;
1516 }
1517
1518 append_note =
1519 start_append_note = g_list_reverse(start_append_note);
1520
1521 remove_note =
1522 start_remove_note = g_list_reverse(start_remove_note);
1523
1524 /* append */
1525 while(append_note != NULL){
1526 gboolean success;
1527
1528 note = append_note->data;
1529
1530 g_object_get(note,
1531 "y", ¬e_y,
1532 NULL);
1533
1534 /* send key-on */
1535 if(ags_audio_test_behaviour_flags(audio, AGS_SOUND_BEHAVIOUR_REVERSE_MAPPING)){
1536 selected_key = input_pads - note_y - 1;
1537 }else{
1538 selected_key = note_y;
1539 }
1540
1541 /* key on */
1542 seq_event = (snd_seq_event_t *) g_malloc(sizeof(snd_seq_event_t));
1543 memset(seq_event, 0, sizeof(snd_seq_event_t));
1544
1545 seq_event->type = SND_SEQ_EVENT_NOTEON;
1546
1547 seq_event->data.note.channel = 0;
1548 seq_event->data.note.note = 0x7f & (selected_key - audio_start_mapping + midi_start_mapping);
1549 seq_event->data.note.velocity = 127;
1550
1551 /* write to port */
1552 success = FALSE;
1553
1554 if(ags_play_lv2_audio_test_flags(play_lv2_audio, AGS_PLAY_LV2_AUDIO_HAS_ATOM_PORT)){
1555 success = ags_lv2_plugin_atom_sequence_append_midi(play_lv2_audio_run->atom_port,
1556 AGS_PLAY_LV2_AUDIO_DEFAULT_MIDI_LENGHT,
1557 seq_event,
1558 1);
1559 }else if(ags_play_lv2_audio_test_flags(play_lv2_audio, AGS_PLAY_LV2_AUDIO_HAS_EVENT_PORT)){
1560 success = ags_lv2_plugin_event_buffer_append_midi(play_lv2_audio_run->event_port,
1561 AGS_PLAY_LV2_AUDIO_DEFAULT_MIDI_LENGHT,
1562 seq_event,
1563 1);
1564 }
1565
1566 if(success){
1567 play_lv2_audio_run->key_on += 1;
1568 }
1569
1570 g_free(seq_event);
1571
1572 /* iterate */
1573 g_object_unref(append_note->data);
1574
1575 append_note = append_note->next;
1576 }
1577
1578 /* remove */
1579 while(remove_note != NULL){
1580 gint match_index;
1581 gboolean success;
1582
1583 note = remove_note->data;
1584
1585 g_object_get(note,
1586 "y", ¬e_y,
1587 NULL);
1588
1589 /* send key-on */
1590 if(ags_audio_test_behaviour_flags(audio, AGS_SOUND_BEHAVIOUR_REVERSE_MAPPING)){
1591 selected_key = input_pads - note_y - 1;
1592 }else{
1593 selected_key = note_y;
1594 }
1595
1596 /* remove key-on */
1597 if(ags_audio_test_behaviour_flags(audio, AGS_SOUND_BEHAVIOUR_REVERSE_MAPPING)){
1598 selected_key = input_pads - note_y - 1;
1599 }else{
1600 selected_key = note_y;
1601 }
1602
1603 /* write to port */
1604 success = FALSE;
1605
1606 if(ags_play_lv2_audio_test_flags(play_lv2_audio, AGS_PLAY_LV2_AUDIO_HAS_ATOM_PORT)){
1607 success = ags_lv2_plugin_atom_sequence_remove_midi(play_lv2_audio_run->atom_port,
1608 AGS_PLAY_LV2_AUDIO_DEFAULT_MIDI_LENGHT,
1609 (0x7f & (selected_key - audio_start_mapping + midi_start_mapping)));
1610 }else if(ags_play_lv2_audio_test_flags(play_lv2_audio, AGS_PLAY_LV2_AUDIO_HAS_EVENT_PORT)){
1611 success = ags_lv2_plugin_event_buffer_remove_midi(play_lv2_audio_run->event_port,
1612 AGS_PLAY_LV2_AUDIO_DEFAULT_MIDI_LENGHT,
1613 (0x7f & (selected_key - audio_start_mapping + midi_start_mapping)));
1614 }
1615
1616 if(success &&
1617 play_lv2_audio_run->key_on != 0){
1618 play_lv2_audio_run->key_on -= 1;
1619 }
1620
1621 /* iterate */
1622 g_object_unref(remove_note->data);
1623
1624 remove_note = remove_note->next;
1625 }
1626
1627 g_list_free_full(start_list,
1628 g_object_unref);
1629 g_list_free_full(start_current_position,
1630 g_object_unref);
1631
1632 g_list_free(start_append_note);
1633 g_list_free(start_remove_note);
1634
1635 /* unref */
1636 g_object_unref(audio);
1637
1638 g_object_unref(output_soundcard);
1639
1640 g_object_unref(play_lv2_audio);
1641
1642 g_object_unref(delay_audio);
1643 }
1644
1645 /**
1646 * ags_play_lv2_audio_run_load_ports:
1647 * @play_lv2_audio_run: the #AgsRecallLv2Run
1648 *
1649 * Set up LV2 ports.
1650 *
1651 * Since: 3.0.0
1652 */
1653 void
ags_play_lv2_audio_run_load_ports(AgsPlayLv2AudioRun * play_lv2_audio_run)1654 ags_play_lv2_audio_run_load_ports(AgsPlayLv2AudioRun *play_lv2_audio_run)
1655 {
1656 AgsPlayLv2Audio *play_lv2_audio;
1657 AgsPort *current;
1658
1659 AgsLv2Plugin *lv2_plugin;
1660
1661 GList *start_port, *port;
1662 GList *start_list, *list;
1663
1664 gchar *plugin_name;
1665 gchar *specifier;
1666
1667 uint32_t port_count;
1668 uint32_t i, j;
1669
1670 GRecMutex *play_lv2_audio_mutex;
1671
1672 g_object_get(play_lv2_audio_run,
1673 "recall-audio", &play_lv2_audio,
1674 NULL);
1675
1676 /* recall mutex */
1677 play_lv2_audio_mutex = AGS_RECALL_GET_OBJ_MUTEX(play_lv2_audio);
1678
1679 /* get some fields */
1680 g_rec_mutex_lock(play_lv2_audio_mutex);
1681
1682 start_port = g_list_copy(AGS_RECALL(play_lv2_audio)->port);
1683
1684 lv2_plugin = play_lv2_audio->plugin;
1685
1686 g_rec_mutex_unlock(play_lv2_audio_mutex);
1687
1688 /* get some fields */
1689 port_count = g_list_length(start_port);
1690
1691 g_object_get(lv2_plugin,
1692 "plugin-port", &start_list,
1693 NULL);
1694
1695 list = start_list;
1696
1697 for(i = 0; list != NULL; i++){
1698 guint port_index;
1699
1700 GRecMutex *plugin_port_mutex;
1701
1702 g_object_get(list->data,
1703 "port-index", &port_index,
1704 NULL);
1705
1706 if(ags_plugin_port_test_flags(list->data, AGS_PLUGIN_PORT_CONTROL)){
1707 /* get plugin port mutex */
1708 plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(list->data);
1709
1710 /* get specifier */
1711 g_rec_mutex_lock(plugin_port_mutex);
1712
1713 specifier = g_strdup(AGS_PLUGIN_PORT(list->data)->port_name);
1714
1715 g_rec_mutex_unlock(plugin_port_mutex);
1716
1717 port = start_port;
1718 current = NULL;
1719
1720 while(port != NULL){
1721 gboolean success;
1722
1723 GRecMutex *port_mutex;
1724
1725 port_mutex = AGS_PORT_GET_OBJ_MUTEX(port->data);
1726
1727 /* check success */
1728 g_rec_mutex_lock(port_mutex);
1729
1730 success = (!g_strcmp0(specifier,
1731 AGS_PORT(port->data)->specifier)) ? TRUE: FALSE;
1732
1733 g_rec_mutex_unlock(port_mutex);
1734
1735 if(success){
1736 current = port->data;
1737
1738 break;
1739 }
1740
1741 /* iterate */
1742 port = port->next;
1743 }
1744
1745 #ifdef AGS_DEBUG
1746 g_message("connect port: %d", AGS_PLUGIN_PORT(list->data)->port_index);
1747 #endif
1748
1749 if(current != NULL){
1750 ags_base_plugin_connect_port(AGS_BASE_PLUGIN(lv2_plugin),
1751 play_lv2_audio_run->lv2_handle[0],
1752 port_index,
1753 (float *) &(current->port_value.ags_port_float));
1754 }
1755 }
1756
1757 list = list->next;
1758 }
1759
1760 /* unref */
1761 g_list_free_full(start_list,
1762 g_object_unref);
1763
1764 g_object_unref(play_lv2_audio);
1765 }
1766
1767 /**
1768 * ags_play_lv2_audio_run_new:
1769 * @audio: the #AgsAudio
1770 * @delay_audio_run: the #AgsDelayAudioRun dependency
1771 * @count_beats_audio_run: the #AgsCountBeatsAudioRun dependency
1772 *
1773 * Create a new instance of #AgsPlayLv2AudioRun
1774 *
1775 * Returns: the new #AgsPlayLv2AudioRun
1776 *
1777 * Since: 3.0.0
1778 */
1779 AgsPlayLv2AudioRun*
ags_play_lv2_audio_run_new(AgsAudio * audio,AgsDelayAudioRun * delay_audio_run,AgsCountBeatsAudioRun * count_beats_audio_run)1780 ags_play_lv2_audio_run_new(AgsAudio *audio,
1781 AgsDelayAudioRun *delay_audio_run,
1782 AgsCountBeatsAudioRun *count_beats_audio_run)
1783 {
1784 AgsPlayLv2AudioRun *play_lv2_audio_run;
1785
1786 play_lv2_audio_run = (AgsPlayLv2AudioRun *) g_object_new(AGS_TYPE_PLAY_LV2_AUDIO_RUN,
1787 "audio", audio,
1788 "delay-audio-run", delay_audio_run,
1789 "count-beats-audio-run", count_beats_audio_run,
1790 NULL);
1791
1792 return(play_lv2_audio_run);
1793 }
1794