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", &note_x0,
1488 		 "x1", &note_x1,
1489 		 "y", &note_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", &note_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", &note_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