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_capture_wave_channel_run.h>
21 
22 #include <ags/audio/ags_recycling.h>
23 #include <ags/audio/ags_recall_id.h>
24 #include <ags/audio/ags_recall_container.h>
25 #include <ags/audio/ags_audio_buffer_util.h>
26 
27 #include <ags/audio/recall/ags_capture_wave_audio.h>
28 #include <ags/audio/recall/ags_capture_wave_audio_run.h>
29 #include <ags/audio/recall/ags_capture_wave_channel.h>
30 
31 #include <ags/i18n.h>
32 
33 void ags_capture_wave_channel_run_class_init(AgsCaptureWaveChannelRunClass *capture_wave_channel_run);
34 void ags_capture_wave_channel_run_seekable_interface_init(AgsSeekableInterface *seekable);
35 void ags_capture_wave_channel_run_init(AgsCaptureWaveChannelRun *capture_wave_channel_run);
36 void ags_capture_wave_channel_run_set_property(GObject *gobject,
37 					       guint prop_id,
38 					       const GValue *value,
39 					       GParamSpec *param_spec);
40 void ags_capture_wave_channel_run_get_property(GObject *gobject,
41 					       guint prop_id,
42 					       GValue *value,
43 					       GParamSpec *param_spec);
44 void ags_capture_wave_channel_run_dispose(GObject *gobject);
45 void ags_capture_wave_channel_run_finalize(GObject *gobject);
46 
47 void ags_capture_wave_channel_run_seek(AgsSeekable *seekable,
48 				       gint64 offset,
49 				       guint whence);
50 
51 void ags_capture_wave_channel_run_run_pre(AgsRecall *recall);
52 
53 /**
54  * SECTION:ags_capture_wave_channel_run
55  * @short_description: capture wave
56  * @title: AgsCaptureWaveChannelRun
57  * @section_id:
58  * @include: ags/channel/recall/ags_capture_wave_channel_run.h
59  *
60  * The #AgsCaptureWaveChannelRun class capture wave.
61  */
62 
63 enum{
64   PROP_0,
65   PROP_X_OFFSET,
66 };
67 
68 static gpointer ags_capture_wave_channel_run_parent_class = NULL;
69 
70 GType
ags_capture_wave_channel_run_get_type()71 ags_capture_wave_channel_run_get_type()
72 {
73   static volatile gsize g_define_type_id__volatile = 0;
74 
75   if(g_once_init_enter (&g_define_type_id__volatile)){
76     GType ags_type_capture_wave_channel_run = 0;
77 
78     static const GTypeInfo ags_capture_wave_channel_run_info = {
79       sizeof (AgsCaptureWaveChannelRunClass),
80       NULL, /* base_init */
81       NULL, /* base_finalize */
82       (GClassInitFunc) ags_capture_wave_channel_run_class_init,
83       NULL, /* class_finalize */
84       NULL, /* class_data */
85       sizeof (AgsCaptureWaveChannelRun),
86       0,    /* n_preallocs */
87       (GInstanceInitFunc) ags_capture_wave_channel_run_init,
88     };
89 
90     static const GInterfaceInfo ags_seekable_interface_info = {
91       (GInterfaceInitFunc) ags_capture_wave_channel_run_seekable_interface_init,
92       NULL, /* interface_finalize */
93       NULL, /* interface_data */
94     };
95 
96     ags_type_capture_wave_channel_run = g_type_register_static(AGS_TYPE_RECALL_CHANNEL_RUN,
97 							       "AgsCaptureWaveChannelRun",
98 							       &ags_capture_wave_channel_run_info,
99 							       0);
100 
101     g_type_add_interface_static(ags_type_capture_wave_channel_run,
102 				AGS_TYPE_SEEKABLE,
103 				&ags_seekable_interface_info);
104 
105     g_once_init_leave(&g_define_type_id__volatile, ags_type_capture_wave_channel_run);
106   }
107 
108   return g_define_type_id__volatile;
109 }
110 
111 void
ags_capture_wave_channel_run_class_init(AgsCaptureWaveChannelRunClass * capture_wave_channel_run)112 ags_capture_wave_channel_run_class_init(AgsCaptureWaveChannelRunClass *capture_wave_channel_run)
113 {
114   GObjectClass *gobject;
115   AgsRecallClass *recall;
116 
117   GParamSpec *param_spec;
118 
119   ags_capture_wave_channel_run_parent_class = g_type_class_peek_parent(capture_wave_channel_run);
120 
121   /* GObjectClass */
122   gobject = (GObjectClass *) capture_wave_channel_run;
123 
124   gobject->set_property = ags_capture_wave_channel_run_set_property;
125   gobject->get_property = ags_capture_wave_channel_run_get_property;
126 
127   gobject->dispose = ags_capture_wave_channel_run_dispose;
128   gobject->finalize = ags_capture_wave_channel_run_finalize;
129 
130   /* properties */
131   /**
132    * AgsCaptureWaveChannelRun:x-offset:
133    *
134    * The x offset.
135    *
136    * Since: 3.0.0
137    */
138   param_spec = g_param_spec_uint64("x-offset",
139 				   i18n_pspec("x offset"),
140 				   i18n_pspec("The x offset in the wave"),
141 				   0,
142 				   G_MAXUINT64,
143 				   0,
144 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
145   g_object_class_install_property(gobject,
146 				  PROP_X_OFFSET,
147 				  param_spec);
148 
149   /* AgsRecallClass */
150   recall = (AgsRecallClass *) capture_wave_channel_run;
151 
152   recall->run_pre = ags_capture_wave_channel_run_run_pre;
153 }
154 
155 void
ags_capture_wave_channel_run_seekable_interface_init(AgsSeekableInterface * seekable)156 ags_capture_wave_channel_run_seekable_interface_init(AgsSeekableInterface *seekable)
157 {
158   seekable->seek = ags_capture_wave_channel_run_seek;
159 }
160 
161 void
ags_capture_wave_channel_run_init(AgsCaptureWaveChannelRun * capture_wave_channel_run)162 ags_capture_wave_channel_run_init(AgsCaptureWaveChannelRun *capture_wave_channel_run)
163 {
164   ags_recall_set_ability_flags((AgsRecall *) capture_wave_channel_run, (AGS_SOUND_ABILITY_WAVE));
165 
166   AGS_RECALL(capture_wave_channel_run)->name = "ags-capture-wave";
167   AGS_RECALL(capture_wave_channel_run)->version = AGS_RECALL_DEFAULT_VERSION;
168   AGS_RECALL(capture_wave_channel_run)->build_id = AGS_RECALL_DEFAULT_BUILD_ID;
169   AGS_RECALL(capture_wave_channel_run)->xml_type = "ags-capture-wave-channel-run";
170   AGS_RECALL(capture_wave_channel_run)->port = NULL;
171 
172   capture_wave_channel_run->timestamp = ags_timestamp_new();
173   g_object_ref(capture_wave_channel_run->timestamp);
174 
175   capture_wave_channel_run->timestamp->flags &= (~AGS_TIMESTAMP_UNIX);
176   capture_wave_channel_run->timestamp->flags |= AGS_TIMESTAMP_OFFSET;
177 
178   capture_wave_channel_run->timestamp->timer.ags_offset.offset = 0;
179 
180   capture_wave_channel_run->audio_signal = NULL;
181 
182   capture_wave_channel_run->x_offset = 0;
183 }
184 
185 void
ags_capture_wave_channel_run_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)186 ags_capture_wave_channel_run_set_property(GObject *gobject,
187 					  guint prop_id,
188 					  const GValue *value,
189 					  GParamSpec *param_spec)
190 {
191   AgsCaptureWaveChannelRun *capture_wave_channel_run;
192 
193   GRecMutex *recall_mutex;
194 
195   capture_wave_channel_run = AGS_CAPTURE_WAVE_CHANNEL_RUN(gobject);
196 
197   /* get recall mutex */
198   recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(capture_wave_channel_run);
199 
200   switch(prop_id){
201   case PROP_X_OFFSET:
202     {
203       guint64 x_offset;
204 
205       x_offset = g_value_get_uint64(value);
206 
207       g_rec_mutex_lock(recall_mutex);
208 
209       capture_wave_channel_run->x_offset = x_offset;
210 
211       g_rec_mutex_unlock(recall_mutex);
212     }
213     break;
214   default:
215     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
216     break;
217   };
218 }
219 
220 void
ags_capture_wave_channel_run_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)221 ags_capture_wave_channel_run_get_property(GObject *gobject,
222 					  guint prop_id,
223 					  GValue *value,
224 					  GParamSpec *param_spec)
225 {
226   AgsCaptureWaveChannelRun *capture_wave_channel_run;
227 
228   GRecMutex *recall_mutex;
229 
230   capture_wave_channel_run = AGS_CAPTURE_WAVE_CHANNEL_RUN(gobject);
231 
232   /* get recall mutex */
233   recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(capture_wave_channel_run);
234 
235   switch(prop_id){
236   case PROP_X_OFFSET:
237     {
238       g_rec_mutex_lock(recall_mutex);
239 
240       g_value_set_uint64(value, capture_wave_channel_run->x_offset);
241 
242       g_rec_mutex_unlock(recall_mutex);
243     }
244     break;
245   default:
246     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
247     break;
248   };
249 }
250 
251 void
ags_capture_wave_channel_run_dispose(GObject * gobject)252 ags_capture_wave_channel_run_dispose(GObject *gobject)
253 {
254   AgsCaptureWaveChannelRun *capture_wave_channel_run;
255 
256   capture_wave_channel_run = AGS_CAPTURE_WAVE_CHANNEL_RUN(gobject);
257 
258   /* call parent */
259   G_OBJECT_CLASS(ags_capture_wave_channel_run_parent_class)->dispose(gobject);
260 }
261 
262 void
ags_capture_wave_channel_run_finalize(GObject * gobject)263 ags_capture_wave_channel_run_finalize(GObject *gobject)
264 {
265   AgsCaptureWaveChannelRun *capture_wave_channel_run;
266 
267   capture_wave_channel_run = AGS_CAPTURE_WAVE_CHANNEL_RUN(gobject);
268 
269   /* timestamp */
270   if(capture_wave_channel_run->timestamp != NULL){
271     g_object_unref(G_OBJECT(capture_wave_channel_run->timestamp));
272   }
273 
274   /* call parent */
275   G_OBJECT_CLASS(ags_capture_wave_channel_run_parent_class)->finalize(gobject);
276 }
277 
278 void
ags_capture_wave_channel_run_seek(AgsSeekable * seekable,gint64 offset,guint whence)279 ags_capture_wave_channel_run_seek(AgsSeekable *seekable,
280 				  gint64 offset,
281 				  guint whence)
282 {
283   AgsCaptureWaveChannelRun *capture_wave_channel_run;
284 
285   GObject *soundcard;
286 
287   gdouble absolute_delay;
288   guint buffer_size;
289   guint64 x_offset;
290 
291   capture_wave_channel_run = AGS_CAPTURE_WAVE_CHANNEL_RUN(seekable);
292 
293   g_object_get(capture_wave_channel_run,
294 	       "output-soundcard", &soundcard,
295 	       "buffer-size", &buffer_size,
296 	       NULL);
297 
298   absolute_delay = ags_soundcard_get_absolute_delay(AGS_SOUNDCARD(soundcard));
299 
300   switch(whence){
301   case AGS_SEEK_CUR:
302     {
303       g_object_get(capture_wave_channel_run,
304 		   "x-offset", &x_offset,
305 		   NULL);
306 
307       if(x_offset + (offset * absolute_delay * buffer_size) < 0){
308 	x_offset = 0;
309       }else{
310 	x_offset = x_offset + (offset * absolute_delay * buffer_size);
311       }
312 
313       g_object_set(capture_wave_channel_run,
314 		   "x-offset", x_offset,
315 		   NULL);
316     }
317     break;
318   case AGS_SEEK_END:
319     {
320       g_warning("seek from end not implemented");
321     }
322     break;
323   case AGS_SEEK_SET:
324     {
325       x_offset = offset * absolute_delay * buffer_size;
326 
327       g_object_set(capture_wave_channel_run,
328 		   "x-offset", x_offset,
329 		   NULL);
330     }
331     break;
332   }
333 
334   g_object_unref(soundcard);
335 }
336 
337 void
ags_capture_wave_channel_run_run_pre(AgsRecall * recall)338 ags_capture_wave_channel_run_run_pre(AgsRecall *recall)
339 {
340   AgsAudio *audio;
341   AgsChannel *channel;
342   AgsChannel *start_input;
343   AgsChannel *input;
344   AgsPort *port;
345   AgsWave *wave;
346   AgsBuffer *buffer;
347 
348   AgsCaptureWaveAudio *capture_wave_audio;
349   AgsCaptureWaveAudioRun *capture_wave_audio_run;
350   AgsCaptureWaveChannel *capture_wave_channel;
351   AgsCaptureWaveChannelRun *capture_wave_channel_run;
352 
353   AgsTimestamp *timestamp;
354 
355   GObject *output_soundcard, *input_soundcard;
356 
357   GList *list_start, *list;
358 
359   void *data, *file_data;
360 
361   gint input_soundcard_channel;
362   guint line;
363   guint64 relative_offset;
364   guint note_offset;
365   gdouble delay;
366   guint delay_counter;
367   gboolean do_loop;
368   guint64 x_offset;
369   guint64 x_point_offset;
370   guint target_copy_mode, file_copy_mode;
371   guint audio_channels, target_audio_channels, file_audio_channels;
372   guint samplerate, target_samplerate, file_samplerate;
373   guint format, target_format, file_format;
374   guint buffer_size, target_buffer_size, file_buffer_size;
375   guint frame_count;
376   guint attack;
377   gboolean do_playback, do_replace, is_new_buffer;
378   gboolean do_record;
379   gboolean resample_target, resample_file;
380   gboolean create_wave;
381 
382   GValue value = {0,};
383   GValue do_loop_value = {0,};
384   GValue x_offset_value = {0,};
385 
386   void (*parent_class_run_pre)(AgsRecall *recall);
387 
388   GRecMutex *audio_mutex;
389   GRecMutex *buffer_mutex;
390   GRecMutex *recall_mutex;
391 
392   capture_wave_channel_run = AGS_CAPTURE_WAVE_CHANNEL_RUN(recall);
393 
394   /* get parent class */
395   parent_class_run_pre = AGS_RECALL_CLASS(ags_capture_wave_channel_run_parent_class)->run_pre;
396 
397   /* get mutex */
398   recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(recall);
399 
400   /* get some fields */
401   g_object_get(capture_wave_channel_run,
402 	       "recall-audio", &capture_wave_audio,
403 	       "recall-audio-run", &capture_wave_audio_run,
404 	       "recall-channel", &capture_wave_channel,
405 	       NULL);
406 
407   timestamp = capture_wave_channel_run->timestamp;
408 
409   g_object_get(capture_wave_channel_run,
410 	       "source", &channel,
411 	       NULL);
412 
413   g_object_get(channel,
414 	       "line", &line,
415 	       "input-soundcard-channel", &input_soundcard_channel,
416 	       NULL);
417 
418   if(input_soundcard_channel == -1){
419     input_soundcard_channel = line;
420   }
421 
422   /* get audio and mutex */
423   g_object_get(capture_wave_audio,
424 	       "audio", &audio,
425 	       NULL);
426 
427   audio_mutex = AGS_AUDIO_GET_OBJ_MUTEX(audio);
428 
429   g_object_get(audio,
430 	       "input", &start_input,
431 	       "buffer-size", &target_buffer_size,
432 	       NULL);
433 
434   /* get soundcard */
435   input = ags_channel_nth(start_input,
436 			  line);
437 
438   g_object_get(input,
439 	       "output-soundcard", &output_soundcard,
440 	       "input-soundcard", &input_soundcard,
441 	       NULL);
442 
443   if(input_soundcard == NULL){
444     /* call parent */
445     parent_class_run_pre(recall);
446 
447     /* unref */
448     g_object_unref(capture_wave_audio);
449 
450     g_object_unref(capture_wave_audio_run);
451 
452     g_object_unref(capture_wave_channel);
453 
454     g_object_unref(channel);
455 
456     g_object_unref(audio);
457 
458     if(start_input != NULL){
459       g_object_unref(start_input);
460     }
461 
462     if(input != NULL){
463       g_object_unref(input);
464     }
465 
466     return;
467   }
468 
469   data = ags_soundcard_get_prev_buffer(AGS_SOUNDCARD(input_soundcard));
470   ags_soundcard_get_presets(AGS_SOUNDCARD(input_soundcard),
471 			    &audio_channels,
472 			    &samplerate,
473 			    &buffer_size,
474 			    &format);
475 
476   frame_count = buffer_size;
477 
478   note_offset = ags_soundcard_get_note_offset(AGS_SOUNDCARD(output_soundcard));
479   delay = ags_soundcard_get_delay(AGS_SOUNDCARD(output_soundcard));
480 
481   delay_counter = ags_soundcard_get_delay_counter(AGS_SOUNDCARD(output_soundcard));
482 
483   x_offset = capture_wave_channel_run->x_offset;
484 
485   relative_offset = AGS_WAVE_DEFAULT_BUFFER_LENGTH * samplerate;
486 
487   /* read playback */
488   g_object_get(capture_wave_audio,
489 	       "playback", &port,
490 	       NULL);
491 
492   g_value_init(&value,
493 	       G_TYPE_BOOLEAN);
494   ags_port_safe_read(port,
495 		     &value);
496 
497   do_playback = g_value_get_boolean(&value);
498   g_value_unset(&value);
499 
500   g_object_unref(port);
501 
502   if(do_playback){
503     /* read replace */
504     g_object_get(capture_wave_audio,
505 		 "replace", &port,
506 		 NULL);
507 
508     g_value_init(&value,
509 		 G_TYPE_BOOLEAN);
510     ags_port_safe_read(port,
511 		       &value);
512 
513     do_replace = g_value_get_boolean(&value);
514     g_value_unset(&value);
515 
516     g_object_unref(port);
517 
518     /* get target presets */
519     g_rec_mutex_lock(audio_mutex);
520 
521     target_audio_channels = audio->audio_channels;
522     target_samplerate = audio->samplerate;
523     target_buffer_size = audio->buffer_size;
524     target_format = audio->format;
525 
526     list_start = g_list_copy(audio->wave);
527 
528     g_rec_mutex_unlock(audio_mutex);
529 
530     relative_offset = AGS_WAVE_DEFAULT_BUFFER_LENGTH * target_samplerate;
531 
532     attack = (x_offset % relative_offset) % target_buffer_size;
533 
534     frame_count = target_buffer_size - attack;
535 
536     create_wave = FALSE;
537 
538     if(x_offset + frame_count > relative_offset * floor(x_offset / relative_offset) + relative_offset){
539       frame_count = relative_offset * floor((x_offset + frame_count) / relative_offset) - x_offset;
540       create_wave = TRUE;
541     }else if(x_offset + frame_count == relative_offset * floor(x_offset / relative_offset) + relative_offset){
542       create_wave = TRUE;
543     }
544 
545     /* check resample */
546     resample_target = FALSE;
547 
548     if(target_samplerate != samplerate){
549       void *tmp_data;
550 
551       tmp_data = ags_stream_alloc(target_buffer_size,
552 				  format);
553 
554       ags_audio_buffer_util_resample_with_buffer(data, audio_channels,
555 						 ags_audio_buffer_util_format_from_soundcard(format), samplerate,
556 						 buffer_size,
557 						 target_samplerate,
558 						 target_buffer_size,
559 						 tmp_data);
560 
561       data = tmp_data;
562 
563       resample_target = TRUE;
564     }
565 
566     target_copy_mode = ags_audio_buffer_util_get_copy_mode(ags_audio_buffer_util_format_from_soundcard(target_format),
567 							   ags_audio_buffer_util_format_from_soundcard(format));
568 
569     ags_timestamp_set_ags_offset(timestamp,
570 				 relative_offset * floor(x_offset / relative_offset));
571 
572     /* play */
573     list = ags_wave_find_near_timestamp(list_start, line,
574 					timestamp);
575 
576     if(list != NULL){
577       wave = list->data;
578     }else{
579       AgsTimestamp *current_timestamp;
580 
581       wave = ags_wave_new((GObject *) audio,
582 			  line);
583 
584       g_object_get(wave,
585 		   "timestamp", &current_timestamp,
586 		   NULL);
587       ags_timestamp_set_ags_offset(current_timestamp,
588 				   relative_offset * floor(x_offset / relative_offset));
589 
590       ags_audio_add_wave(audio,
591 			 (GObject *) wave);
592 
593       g_object_unref(current_timestamp);
594     }
595 
596     x_point_offset = x_offset - attack;
597 
598     buffer = ags_wave_find_point(wave,
599 				 x_point_offset,
600 				 FALSE);
601 
602     is_new_buffer = FALSE;
603 
604     if(buffer == NULL){
605       buffer = ags_buffer_new();
606       buffer->x = x_point_offset;
607 
608       ags_wave_add_buffer(wave,
609 			  buffer,
610 			  FALSE);
611 
612       is_new_buffer = TRUE;
613     }
614 
615     /* get buffer mutex */
616     buffer_mutex = AGS_BUFFER_GET_OBJ_MUTEX(buffer);
617 
618     if(!is_new_buffer &&
619        do_replace){
620       void *data;
621 
622       data = NULL;
623 
624       switch(target_format){
625       case AGS_SOUNDCARD_SIGNED_8_BIT:
626 	{
627 	  data = ((gint8 *) buffer->data) + attack;
628 	}
629 	break;
630       case AGS_SOUNDCARD_SIGNED_16_BIT:
631 	{
632 	  data = ((gint16 *) buffer->data) + attack;
633 	}
634 	break;
635       case AGS_SOUNDCARD_SIGNED_24_BIT:
636 	{
637 	  data = ((gint32 *) buffer->data) + attack;
638 	}
639 	break;
640       case AGS_SOUNDCARD_SIGNED_32_BIT:
641 	{
642 	  data = ((gint32 *) buffer->data) + attack;
643 	}
644 	break;
645       case AGS_SOUNDCARD_SIGNED_64_BIT:
646 	{
647 	  data = ((gint64 *) buffer->data) + attack;
648 	}
649 	break;
650       }
651 
652       g_rec_mutex_lock(buffer_mutex);
653 
654       ags_audio_buffer_util_clear_buffer(data, 1,
655 					 target_buffer_size - attack, ags_audio_buffer_util_format_from_soundcard(target_format));
656 
657       g_rec_mutex_unlock(buffer_mutex);
658     }
659 
660     /* copy to buffer */
661     g_rec_mutex_lock(buffer_mutex);
662     ags_soundcard_lock_buffer(AGS_SOUNDCARD(input_soundcard), data);
663 
664     ags_audio_buffer_util_copy_buffer_to_buffer(buffer->data, 1, attack,
665 						data, audio_channels, input_soundcard_channel,
666 						frame_count, target_copy_mode);
667 
668     ags_soundcard_unlock_buffer(AGS_SOUNDCARD(input_soundcard), data);
669     g_rec_mutex_unlock(buffer_mutex);
670 
671     g_list_free(list_start);
672 
673     /* 2nd attempt */
674     g_rec_mutex_lock(audio_mutex);
675 
676     list_start = g_list_copy(audio->wave);
677 
678     g_rec_mutex_unlock(audio_mutex);
679 
680     if(create_wave){
681       ags_timestamp_set_ags_offset(timestamp,
682 				   relative_offset * floor((x_offset + frame_count) / relative_offset));
683 
684       /* play */
685       list = ags_wave_find_near_timestamp(list_start, line,
686 					  timestamp);
687 
688       if(list != NULL){
689 	wave = list->data;
690       }else{
691 	AgsTimestamp *current_timestamp;
692 
693 	wave = ags_wave_new((GObject *) audio,
694 			    line);
695 
696 	g_object_get(wave,
697 		     "timestamp", &current_timestamp,
698 		     NULL);
699 	ags_timestamp_set_ags_offset(current_timestamp,
700 				     relative_offset * floor((x_offset + frame_count) / relative_offset));
701 
702 	ags_audio_add_wave(audio,
703 			   (GObject *) wave);
704 
705 	g_object_unref(current_timestamp);
706       }
707     }
708 
709     g_list_free(list_start);
710 
711     if(attack != 0 ||
712        target_buffer_size != frame_count){
713       x_point_offset = x_offset + frame_count;
714       buffer = ags_wave_find_point(wave,
715 				   x_point_offset,
716 				   FALSE);
717 
718       is_new_buffer = FALSE;
719 
720       if(buffer == NULL){
721 	buffer = ags_buffer_new();
722 	buffer->x = x_point_offset;
723 
724 	ags_wave_add_buffer(wave,
725 			    buffer,
726 			    FALSE);
727 
728 	is_new_buffer = TRUE;
729       }
730 
731       /* get buffer mutex */
732       buffer_mutex = AGS_BUFFER_GET_OBJ_MUTEX(buffer);
733 
734       if(!is_new_buffer &&
735 	 do_replace){
736 	g_rec_mutex_lock(buffer_mutex);
737 
738 	ags_audio_buffer_util_clear_buffer(buffer->data, 1,
739 					   target_buffer_size - frame_count, ags_audio_buffer_util_format_from_soundcard(target_format));
740 
741 	g_rec_mutex_unlock(buffer_mutex);
742       }
743 
744       /* copy to buffer */
745       g_rec_mutex_lock(buffer_mutex);
746       ags_soundcard_lock_buffer(AGS_SOUNDCARD(input_soundcard), data);
747 
748       ags_audio_buffer_util_copy_buffer_to_buffer(buffer->data, 1, 0,
749 						  data, audio_channels, (frame_count * audio_channels) + input_soundcard_channel,
750 						  target_buffer_size - frame_count, target_copy_mode);
751 
752       ags_soundcard_unlock_buffer(AGS_SOUNDCARD(input_soundcard), data);
753       g_rec_mutex_unlock(buffer_mutex);
754     }
755 
756     if(resample_target){
757       g_free(data);
758     }
759   }
760 
761   /* read record */
762   g_object_get(capture_wave_audio,
763 	       "record", &port,
764 	       NULL);
765 
766   g_value_init(&value,
767 	       G_TYPE_BOOLEAN);
768   ags_port_safe_read(port,
769 		     &value);
770 
771   do_record = g_value_get_boolean(&value);
772   g_value_unset(&value);
773 
774   g_object_unref(port);
775 
776   if(do_record){
777     AgsAudioFile *audio_file;
778 
779     g_rec_mutex_lock(&(capture_wave_audio->audio_file_mutex));
780 
781     audio_file = capture_wave_audio->audio_file;
782 
783     g_rec_mutex_unlock(&(capture_wave_audio->audio_file_mutex));
784 
785     /* get presets */
786     g_object_get(audio_file,
787 		 "file-audio-channels", &file_audio_channels,
788 		 "samplerate", &file_samplerate,
789 		 "buffer-size", &file_buffer_size,
790 		 "format", &file_format,
791 		 NULL);
792 
793     ags_audio_buffer_util_clear_buffer(capture_wave_audio_run->file_buffer, 1,
794 				       file_audio_channels * file_buffer_size, file_format);
795 
796     if(file_samplerate != samplerate){
797       void *tmp_data;
798 
799       tmp_data = ags_stream_alloc(file_buffer_size,
800 				  format);
801 
802       ags_audio_buffer_util_resample_with_buffer(data, audio_channels,
803 						 ags_audio_buffer_util_format_from_soundcard(format), samplerate,
804 						 buffer_size,
805 						 file_samplerate,
806 						 file_buffer_size,
807 						 tmp_data);
808 
809       data = tmp_data;
810 
811       resample_file = TRUE;
812     }
813 
814     file_copy_mode = ags_audio_buffer_util_get_copy_mode(ags_audio_buffer_util_format_from_soundcard(file_format),
815 							 ags_audio_buffer_util_format_from_soundcard(format));
816 
817     //TODO:JK: implement me
818 #if 0
819     ags_soundcard_lock_buffer(AGS_SOUNDCARD(input_soundcard), data);
820 
821     ags_audio_buffer_util_copy_buffer_to_buffer(file_data, file_audio_channels, line,
822 						data, audio_channels, input_soundcard_channel,
823 						file_buffer_size, file_copy_mode);
824 
825     ags_soundcard_unlock_buffer(AGS_SOUNDCARD(input_soundcard), data);
826 
827     if(resample_file){
828       g_free(data);
829     }
830 
831     /* file */
832     g_rec_mutex_lock(&(capture_wave_audio->audio_file_mutex));
833 
834     ags_audio_file_write(audio_file,
835 			 capture_wave_audio_run->file_buffer, file_buffer_size,
836 			 file_format);
837 
838     g_rec_mutex_unlock(&(capture_wave_audio->audio_file_mutex));
839 #endif
840   }
841 
842   /* check loop */
843   x_offset += target_buffer_size;
844 
845   g_object_get(capture_wave_audio,
846 	       "wave-loop", &port,
847 	       NULL);
848 
849   g_value_init(&do_loop_value,
850 	       G_TYPE_BOOLEAN);
851 
852   ags_port_safe_read(port,
853 		     &do_loop_value);
854 
855   do_loop = g_value_get_boolean(&do_loop_value);
856 
857   g_value_unset(&do_loop_value);
858   g_object_unref(port);
859 
860   if(do_loop){
861     guint64 loop_start, loop_end;
862 
863     GValue loop_start_value = {0,};
864     GValue loop_end_value = {0,};
865 
866     g_object_get(capture_wave_audio,
867 		 "wave-loop-end", &port,
868 		 NULL);
869 
870     g_value_init(&loop_end_value,
871 		 G_TYPE_UINT64);
872 
873     ags_port_safe_read(port,
874 		       &loop_end_value);
875 
876     loop_end = g_value_get_uint64(&loop_end_value);
877 
878     g_value_unset(&loop_end_value);
879     g_object_unref(port);
880 
881     if(x_offset / buffer_size / delay >= loop_end){
882       g_object_get(capture_wave_audio,
883 		   "wave-loop-start", &port,
884 		   NULL);
885 
886       g_value_init(&loop_start_value,
887 		   G_TYPE_UINT64);
888 
889       ags_port_safe_read(port,
890 			 &loop_start_value);
891 
892       loop_start = g_value_get_uint64(&loop_start_value);
893       g_value_unset(&loop_start_value);
894 
895       g_object_unref(port);
896 
897       x_offset = (relative_offset * floor((delay * buffer_size * loop_start) / relative_offset)) + ((guint64) (delay * buffer_size * loop_start) % relative_offset);
898     }
899   }
900 
901   /* new x offset */
902   capture_wave_channel_run->x_offset = x_offset;
903 
904   g_object_get(capture_wave_channel,
905 	       "x-offset", &port,
906 	       NULL);
907 
908   g_value_init(&x_offset_value,
909 	       G_TYPE_UINT64);
910 
911   g_value_set_uint64(&x_offset_value,
912 		     x_offset);
913 
914   ags_port_safe_write(port,
915 		      &x_offset_value);
916 
917   g_value_unset(&x_offset_value);
918   g_object_unref(port);
919 
920   /* call parent */
921   parent_class_run_pre(recall);
922 
923   /* unref */
924   g_object_unref(capture_wave_audio);
925 
926   g_object_unref(capture_wave_audio_run);
927 
928   g_object_unref(capture_wave_channel);
929 
930   g_object_unref(channel);
931 
932   g_object_unref(audio);
933 
934   g_object_unref(output_soundcard);
935   g_object_unref(input_soundcard);
936 
937   if(start_input != NULL){
938     g_object_unref(start_input);
939   }
940 
941   if(input != NULL){
942     g_object_unref(input);
943   }
944 }
945 
946 /**
947  * ags_capture_wave_channel_run_new:
948  * @source: the #AgsChannel
949  *
950  * Create a new instance of #AgsCaptureWaveChannelRun
951  *
952  * Returns: the new #AgsCaptureWaveChannelRun
953  *
954  * Since: 3.0.0
955  */
956 AgsCaptureWaveChannelRun*
ags_capture_wave_channel_run_new(AgsChannel * source)957 ags_capture_wave_channel_run_new(AgsChannel *source)
958 {
959   AgsCaptureWaveChannelRun *capture_wave_channel_run;
960 
961   capture_wave_channel_run = (AgsCaptureWaveChannelRun *) g_object_new(AGS_TYPE_CAPTURE_WAVE_CHANNEL_RUN,
962 								       "source", source,
963 								       NULL);
964 
965   return(capture_wave_channel_run);
966 }
967