1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2021 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/ags_sfz_synth_generator.h>
21
22 #include <ags/audio/ags_diatonic_scale.h>
23 #include <ags/audio/ags_audio_signal.h>
24 #include <ags/audio/ags_audio_buffer_util.h>
25 #include <ags/audio/ags_generic_pitch_util.h>
26 #include <ags/audio/ags_sfz_synth_util.h>
27
28 #include <ags/audio/file/ags_audio_container.h>
29 #include <ags/audio/file/ags_audio_container_manager.h>
30 #include <ags/audio/file/ags_sfz_sample.h>
31
32 #include <math.h>
33
34 #include <ags/i18n.h>
35
36 void ags_sfz_synth_generator_class_init(AgsSFZSynthGeneratorClass *sfz_synth_generator);
37 void ags_sfz_synth_generator_init(AgsSFZSynthGenerator *sfz_synth_generator);
38 void ags_sfz_synth_generator_set_property(GObject *gobject,
39 guint prop_id,
40 const GValue *value,
41 GParamSpec *param_spec);
42 void ags_sfz_synth_generator_get_property(GObject *gobject,
43 guint prop_id,
44 GValue *value,
45 GParamSpec *param_spec);
46 void ags_sfz_synth_generator_finalize(GObject *gobject);
47
48 /**
49 * SECTION:ags_sfz_synth_generator
50 * @short_description: generate wave-form
51 * @title: AgsSFZSynthGenerator
52 * @section_id:
53 * @include: ags/file/ags_sfz_synth_generator.h
54 *
55 * The #AgsSFZSynthGenerator generates wave-forms with oscillators.
56 */
57
58 enum{
59 PROP_0,
60 PROP_FILENAME,
61 PROP_SAMPLERATE,
62 PROP_BUFFER_SIZE,
63 PROP_FORMAT,
64 PROP_PITCH_TYPE,
65 PROP_DELAY,
66 PROP_ATTACK,
67 PROP_FRAME_COUNT,
68 PROP_LOOP_START,
69 PROP_LOOP_END,
70 PROP_VOLUME,
71 PROP_BASE_KEY,
72 PROP_TUNING,
73 PROP_TIMESTAMP,
74 };
75
76 static gpointer ags_sfz_synth_generator_parent_class = NULL;
77
78
79 GType
ags_sfz_synth_generator_get_type()80 ags_sfz_synth_generator_get_type()
81 {
82 static volatile gsize g_define_type_id__volatile = 0;
83
84 if(g_once_init_enter (&g_define_type_id__volatile)){
85 GType ags_type_sfz_synth_generator = 0;
86
87 static const GTypeInfo ags_sfz_synth_generator_info = {
88 sizeof (AgsSFZSynthGeneratorClass),
89 NULL, /* base_init */
90 NULL, /* base_finalize */
91 (GClassInitFunc) ags_sfz_synth_generator_class_init,
92 NULL, /* class_finalize */
93 NULL, /* class_data */
94 sizeof (AgsSFZSynthGenerator),
95 0, /* n_preallocs */
96 (GInstanceInitFunc) ags_sfz_synth_generator_init,
97 };
98
99 ags_type_sfz_synth_generator = g_type_register_static(AGS_TYPE_FUNCTION,
100 "AgsSFZSynthGenerator",
101 &ags_sfz_synth_generator_info,
102 0);
103
104 g_once_init_leave(&g_define_type_id__volatile, ags_type_sfz_synth_generator);
105 }
106
107 return g_define_type_id__volatile;
108 }
109
110 void
ags_sfz_synth_generator_class_init(AgsSFZSynthGeneratorClass * sfz_synth_generator)111 ags_sfz_synth_generator_class_init(AgsSFZSynthGeneratorClass *sfz_synth_generator)
112 {
113 GObjectClass *gobject;
114 GParamSpec *param_spec;
115
116 ags_sfz_synth_generator_parent_class = g_type_class_peek_parent(sfz_synth_generator);
117
118 /* GObjectClass */
119 gobject = (GObjectClass *) sfz_synth_generator;
120
121 gobject->set_property = ags_sfz_synth_generator_set_property;
122 gobject->get_property = ags_sfz_synth_generator_get_property;
123
124 gobject->finalize = ags_sfz_synth_generator_finalize;
125
126 /* properties */
127 /**
128 * AgsSFZSynthGenerator:filename:
129 *
130 * The assigned filename.
131 *
132 * Since: 3.4.0
133 */
134 param_spec = g_param_spec_string("filename",
135 i18n_pspec("filename of audio container"),
136 i18n_pspec("The filename of audio container"),
137 NULL,
138 G_PARAM_READABLE | G_PARAM_WRITABLE);
139 g_object_class_install_property(gobject,
140 PROP_FILENAME,
141 param_spec);
142
143 /**
144 * AgsSFZSynthGenerator:samplerate:
145 *
146 * The samplerate to be used.
147 *
148 * Since: 3.4.0
149 */
150 param_spec = g_param_spec_uint("samplerate",
151 i18n_pspec("using samplerate"),
152 i18n_pspec("The samplerate to be used"),
153 0,
154 G_MAXUINT32,
155 AGS_SFZ_SYNTH_GENERATOR_DEFAULT_SAMPLERATE,
156 G_PARAM_READABLE | G_PARAM_WRITABLE);
157 g_object_class_install_property(gobject,
158 PROP_SAMPLERATE,
159 param_spec);
160
161 /**
162 * AgsSFZSynthGenerator:buffer-size:
163 *
164 * The buffer size to be used.
165 *
166 * Since: 3.4.0
167 */
168 param_spec = g_param_spec_uint("buffer-size",
169 i18n_pspec("using buffer size"),
170 i18n_pspec("The buffer size to be used"),
171 0,
172 G_MAXUINT32,
173 AGS_SFZ_SYNTH_GENERATOR_DEFAULT_BUFFER_SIZE,
174 G_PARAM_READABLE | G_PARAM_WRITABLE);
175 g_object_class_install_property(gobject,
176 PROP_BUFFER_SIZE,
177 param_spec);
178
179 /**
180 * AgsSFZSynthGenerator:format:
181 *
182 * The format to be used.
183 *
184 * Since: 3.4.0
185 */
186 param_spec = g_param_spec_uint("format",
187 i18n_pspec("using format"),
188 i18n_pspec("The format to be used"),
189 0,
190 G_MAXUINT32,
191 AGS_SFZ_SYNTH_GENERATOR_DEFAULT_FORMAT,
192 G_PARAM_READABLE | G_PARAM_WRITABLE);
193 g_object_class_install_property(gobject,
194 PROP_FORMAT,
195 param_spec);
196
197 /**
198 * AgsSFZSynthGenerator:pitch-type:
199 *
200 * The pitch type to be used.
201 *
202 * Since: 3.9.0
203 */
204 param_spec = g_param_spec_uint("pitch-type",
205 i18n_pspec("using pitch type"),
206 i18n_pspec("The pitch type to be used"),
207 0,
208 G_MAXUINT32,
209 AGS_FLUID_4TH_ORDER_INTERPOLATE,
210 G_PARAM_READABLE | G_PARAM_WRITABLE);
211 g_object_class_install_property(gobject,
212 PROP_PITCH_TYPE,
213 param_spec);
214
215 /**
216 * AgsSFZSynthGenerator:frame-count:
217 *
218 * The frame count to be used.
219 *
220 * Since: 3.4.0
221 */
222 param_spec = g_param_spec_uint("frame-count",
223 i18n_pspec("apply frame count"),
224 i18n_pspec("To apply frame count"),
225 0,
226 G_MAXUINT32,
227 0,
228 G_PARAM_READABLE | G_PARAM_WRITABLE);
229 g_object_class_install_property(gobject,
230 PROP_FRAME_COUNT,
231 param_spec);
232
233 /**
234 * AgsSFZSynthGenerator:loop-start:
235 *
236 * The loop start to be used.
237 *
238 * Since: 3.4.0
239 */
240 param_spec = g_param_spec_uint("loop-start",
241 i18n_pspec("loop start"),
242 i18n_pspec("The loop start"),
243 0,
244 G_MAXUINT32,
245 0,
246 G_PARAM_READABLE | G_PARAM_WRITABLE);
247 g_object_class_install_property(gobject,
248 PROP_LOOP_START,
249 param_spec);
250
251 /**
252 * AgsSFZSynthGenerator:loop-end:
253 *
254 * The loop end to be used.
255 *
256 * Since: 3.4.0
257 */
258 param_spec = g_param_spec_uint("loop-end",
259 i18n_pspec("loop end"),
260 i18n_pspec("To loop end"),
261 0,
262 G_MAXUINT32,
263 0,
264 G_PARAM_READABLE | G_PARAM_WRITABLE);
265 g_object_class_install_property(gobject,
266 PROP_LOOP_END,
267 param_spec);
268
269
270 /**
271 * AgsSFZSynthGenerator:delay:
272 *
273 * The delay to be used.
274 *
275 * Since: 3.4.11
276 */
277 param_spec = g_param_spec_double("delay",
278 i18n_pspec("using delay"),
279 i18n_pspec("The delay to be used"),
280 0.0,
281 65535.0,
282 0.0,
283 G_PARAM_READABLE | G_PARAM_WRITABLE);
284 g_object_class_install_property(gobject,
285 PROP_DELAY,
286 param_spec);
287
288 /**
289 * AgsSFZSynthGenerator:attack:
290 *
291 * The attack to be used.
292 *
293 * Since: 3.4.11
294 */
295 param_spec = g_param_spec_uint("attack",
296 i18n_pspec("apply attack"),
297 i18n_pspec("To apply attack"),
298 0,
299 G_MAXUINT32,
300 0,
301 G_PARAM_READABLE | G_PARAM_WRITABLE);
302 g_object_class_install_property(gobject,
303 PROP_ATTACK,
304 param_spec);
305
306 /**
307 * AgsSFZSynthGenerator:volume:
308 *
309 * The volume to be used.
310 *
311 * Since: 3.4.11
312 */
313 param_spec = g_param_spec_double("volume",
314 i18n_pspec("using volume"),
315 i18n_pspec("The volume to be used"),
316 0.0,
317 2.0,
318 AGS_SFZ_SYNTH_GENERATOR_DEFAULT_VOLUME,
319 G_PARAM_READABLE | G_PARAM_WRITABLE);
320 g_object_class_install_property(gobject,
321 PROP_VOLUME,
322 param_spec);
323
324 /**
325 * AgsSFZSynthGenerator:tuning:
326 *
327 * The tuning to be used.
328 *
329 * Since: 3.4.0
330 */
331 param_spec = g_param_spec_double("tuning",
332 i18n_pspec("using tuning"),
333 i18n_pspec("The tuning to be used"),
334 0.0,
335 1200.0,
336 AGS_SFZ_SYNTH_GENERATOR_DEFAULT_TUNING,
337 G_PARAM_READABLE | G_PARAM_WRITABLE);
338 g_object_class_install_property(gobject,
339 PROP_TUNING,
340 param_spec);
341
342 /**
343 * AgsSFZSynthGenerator:base_key:
344 *
345 * The base_key to be used.
346 *
347 * Since: 3.4.0
348 */
349 param_spec = g_param_spec_double("base_key",
350 i18n_pspec("using base_key"),
351 i18n_pspec("The base_key to be used"),
352 -65535.0,
353 65535.0,
354 AGS_SFZ_SYNTH_GENERATOR_DEFAULT_BASE_KEY,
355 G_PARAM_READABLE | G_PARAM_WRITABLE);
356 g_object_class_install_property(gobject,
357 PROP_BASE_KEY,
358 param_spec);
359 }
360
361 void
ags_sfz_synth_generator_init(AgsSFZSynthGenerator * sfz_synth_generator)362 ags_sfz_synth_generator_init(AgsSFZSynthGenerator *sfz_synth_generator)
363 {
364 AgsConfig *config;
365
366 sfz_synth_generator->flags = 0;
367
368 /* sfz synth generator mutex */
369 g_rec_mutex_init(&(sfz_synth_generator->obj_mutex));
370
371 /* config */
372 config = ags_config_get_instance();
373
374 sfz_synth_generator->filename = NULL;
375
376 /* presets */
377 sfz_synth_generator->samplerate = ags_soundcard_helper_config_get_samplerate(config);
378 sfz_synth_generator->buffer_size = ags_soundcard_helper_config_get_buffer_size(config);
379 sfz_synth_generator->format = ags_soundcard_helper_config_get_format(config);
380
381 sfz_synth_generator->pitch_type = AGS_FLUID_4TH_ORDER_INTERPOLATE;
382
383 /* more base init */
384 sfz_synth_generator->frame_count = 0;
385 sfz_synth_generator->loop_start = 0;
386 sfz_synth_generator->loop_end = 0;
387
388 sfz_synth_generator->delay = 0.0;
389 sfz_synth_generator->attack = 0;
390
391 sfz_synth_generator->volume = AGS_SFZ_SYNTH_GENERATOR_DEFAULT_VOLUME;
392
393 sfz_synth_generator->base_key = AGS_SFZ_SYNTH_GENERATOR_DEFAULT_BASE_KEY;
394 sfz_synth_generator->tuning = AGS_SFZ_SYNTH_GENERATOR_DEFAULT_TUNING;
395
396 sfz_synth_generator->sfz = (AgsSFZ *) g_new0(AgsSFZ,
397 1);
398
399 sfz_synth_generator->sfz->generic_pitch = (gpointer) g_new0(AgsGenericPitch,
400 1);
401
402 /* timestamp */
403 sfz_synth_generator->timestamp = NULL;
404 }
405
406
407 void
ags_sfz_synth_generator_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)408 ags_sfz_synth_generator_set_property(GObject *gobject,
409 guint prop_id,
410 const GValue *value,
411 GParamSpec *param_spec)
412 {
413 AgsSFZSynthGenerator *sfz_synth_generator;
414
415 GRecMutex *sfz_synth_generator_mutex;
416
417 sfz_synth_generator = AGS_SFZ_SYNTH_GENERATOR(gobject);
418
419 /* get sfz synth generator mutex */
420 sfz_synth_generator_mutex = AGS_SFZ_SYNTH_GENERATOR_GET_OBJ_MUTEX(sfz_synth_generator);
421
422 switch(prop_id){
423 case PROP_FILENAME:
424 {
425 gchar *filename;
426
427 filename = (gchar *) g_value_get_string(value);
428
429 g_rec_mutex_lock(sfz_synth_generator_mutex);
430
431 if(sfz_synth_generator->filename == filename){
432 g_rec_mutex_unlock(sfz_synth_generator_mutex);
433
434 return;
435 }
436
437 if(sfz_synth_generator->filename != NULL){
438 g_free(sfz_synth_generator->filename);
439 }
440
441 sfz_synth_generator->filename = g_strdup(filename);
442
443 g_rec_mutex_unlock(sfz_synth_generator_mutex);
444 }
445 break;
446 case PROP_SAMPLERATE:
447 {
448 guint samplerate;
449
450 samplerate = g_value_get_uint(value);
451
452 ags_sfz_synth_generator_set_samplerate(sfz_synth_generator,
453 samplerate);
454 }
455 break;
456 case PROP_BUFFER_SIZE:
457 {
458 guint buffer_size;
459
460 buffer_size = g_value_get_uint(value);
461
462 ags_sfz_synth_generator_set_buffer_size(sfz_synth_generator,
463 buffer_size);
464 }
465 break;
466 case PROP_FORMAT:
467 {
468 guint format;
469
470 format = g_value_get_uint(value);
471
472 ags_sfz_synth_generator_set_format(sfz_synth_generator,
473 format);
474 }
475 break;
476 case PROP_PITCH_TYPE:
477 {
478 guint pitch_type;
479
480 pitch_type = g_value_get_uint(value);
481
482 ags_sfz_synth_generator_set_pitch_type(sfz_synth_generator,
483 pitch_type);
484 }
485 break;
486 case PROP_DELAY:
487 {
488 g_rec_mutex_lock(sfz_synth_generator_mutex);
489
490 sfz_synth_generator->delay = g_value_get_double(value);
491
492 g_rec_mutex_unlock(sfz_synth_generator_mutex);
493 }
494 break;
495 case PROP_ATTACK:
496 {
497 g_rec_mutex_lock(sfz_synth_generator_mutex);
498
499 sfz_synth_generator->attack = g_value_get_uint(value);
500
501 g_rec_mutex_unlock(sfz_synth_generator_mutex);
502 }
503 break;
504 case PROP_FRAME_COUNT:
505 {
506 g_rec_mutex_lock(sfz_synth_generator_mutex);
507
508 sfz_synth_generator->frame_count = g_value_get_uint(value);
509
510 g_rec_mutex_unlock(sfz_synth_generator_mutex);
511 }
512 break;
513 case PROP_LOOP_START:
514 {
515 g_rec_mutex_lock(sfz_synth_generator_mutex);
516
517 sfz_synth_generator->loop_start = g_value_get_uint(value);
518
519 g_rec_mutex_unlock(sfz_synth_generator_mutex);
520 }
521 break;
522 case PROP_LOOP_END:
523 {
524 g_rec_mutex_lock(sfz_synth_generator_mutex);
525
526 sfz_synth_generator->loop_end = g_value_get_uint(value);
527
528 g_rec_mutex_unlock(sfz_synth_generator_mutex);
529 }
530 break;
531 case PROP_VOLUME:
532 {
533 g_rec_mutex_lock(sfz_synth_generator_mutex);
534
535 sfz_synth_generator->volume = g_value_get_double(value);
536
537 g_rec_mutex_unlock(sfz_synth_generator_mutex);
538 }
539 break;
540 case PROP_BASE_KEY:
541 {
542 g_rec_mutex_lock(sfz_synth_generator_mutex);
543
544 sfz_synth_generator->base_key = g_value_get_double(value);
545
546 g_rec_mutex_unlock(sfz_synth_generator_mutex);
547 }
548 break;
549 case PROP_TUNING:
550 {
551 g_rec_mutex_lock(sfz_synth_generator_mutex);
552
553 sfz_synth_generator->tuning = g_value_get_double(value);
554
555 g_rec_mutex_unlock(sfz_synth_generator_mutex);
556 }
557 break;
558 case PROP_TIMESTAMP:
559 {
560 AgsTimestamp *timestamp;
561
562 timestamp = (AgsTimestamp *) g_value_get_object(value);
563
564 g_rec_mutex_lock(sfz_synth_generator_mutex);
565
566 if(sfz_synth_generator->timestamp == (GObject *) timestamp){
567 g_rec_mutex_unlock(sfz_synth_generator_mutex);
568
569 return;
570 }
571
572 if(sfz_synth_generator->timestamp != NULL){
573 g_object_unref(sfz_synth_generator->timestamp);
574 }
575
576 if(timestamp != NULL){
577 g_object_ref(timestamp);
578 }
579
580 sfz_synth_generator->timestamp = (GObject *) timestamp;
581
582 g_rec_mutex_unlock(sfz_synth_generator_mutex);
583 }
584 break;
585 default:
586 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
587 break;
588 }
589 }
590
591 void
ags_sfz_synth_generator_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)592 ags_sfz_synth_generator_get_property(GObject *gobject,
593 guint prop_id,
594 GValue *value,
595 GParamSpec *param_spec)
596 {
597 AgsSFZSynthGenerator *sfz_synth_generator;
598
599 GRecMutex *sfz_synth_generator_mutex;
600
601 sfz_synth_generator = AGS_SFZ_SYNTH_GENERATOR(gobject);
602
603 /* get sfz synth generator mutex */
604 sfz_synth_generator_mutex = AGS_SFZ_SYNTH_GENERATOR_GET_OBJ_MUTEX(sfz_synth_generator);
605
606 switch(prop_id){
607 case PROP_FILENAME:
608 {
609 g_rec_mutex_lock(sfz_synth_generator_mutex);
610
611 g_value_set_string(value, sfz_synth_generator->filename);
612
613 g_rec_mutex_unlock(sfz_synth_generator_mutex);
614 }
615 break;
616 case PROP_SAMPLERATE:
617 {
618 g_rec_mutex_lock(sfz_synth_generator_mutex);
619
620 g_value_set_uint(value, sfz_synth_generator->samplerate);
621
622 g_rec_mutex_unlock(sfz_synth_generator_mutex);
623 }
624 break;
625 case PROP_BUFFER_SIZE:
626 {
627 g_rec_mutex_lock(sfz_synth_generator_mutex);
628
629 g_value_set_uint(value, sfz_synth_generator->buffer_size);
630
631 g_rec_mutex_unlock(sfz_synth_generator_mutex);
632 }
633 break;
634 case PROP_FORMAT:
635 {
636 g_rec_mutex_lock(sfz_synth_generator_mutex);
637
638 g_value_set_uint(value, sfz_synth_generator->format);
639
640 g_rec_mutex_unlock(sfz_synth_generator_mutex);
641 }
642 break;
643 case PROP_PITCH_TYPE:
644 {
645 g_rec_mutex_lock(sfz_synth_generator_mutex);
646
647 g_value_set_uint(value, sfz_synth_generator->pitch_type);
648
649 g_rec_mutex_unlock(sfz_synth_generator_mutex);
650 }
651 break;
652 case PROP_DELAY:
653 {
654 g_rec_mutex_lock(sfz_synth_generator_mutex);
655
656 g_value_set_double(value, sfz_synth_generator->delay);
657
658 g_rec_mutex_unlock(sfz_synth_generator_mutex);
659 }
660 break;
661 case PROP_ATTACK:
662 {
663 g_rec_mutex_lock(sfz_synth_generator_mutex);
664
665 g_value_set_uint(value, sfz_synth_generator->attack);
666
667 g_rec_mutex_unlock(sfz_synth_generator_mutex);
668 }
669 break;
670 case PROP_FRAME_COUNT:
671 {
672 g_rec_mutex_lock(sfz_synth_generator_mutex);
673
674 g_value_set_uint(value, sfz_synth_generator->frame_count);
675
676 g_rec_mutex_unlock(sfz_synth_generator_mutex);
677 }
678 break;
679 case PROP_LOOP_START:
680 {
681 g_rec_mutex_lock(sfz_synth_generator_mutex);
682
683 g_value_set_uint(value, sfz_synth_generator->loop_start);
684
685 g_rec_mutex_unlock(sfz_synth_generator_mutex);
686 }
687 break;
688 case PROP_LOOP_END:
689 {
690 g_rec_mutex_lock(sfz_synth_generator_mutex);
691
692 g_value_set_uint(value, sfz_synth_generator->loop_end);
693
694 g_rec_mutex_unlock(sfz_synth_generator_mutex);
695 }
696 break;
697 case PROP_VOLUME:
698 {
699 g_rec_mutex_lock(sfz_synth_generator_mutex);
700
701 g_value_set_double(value, sfz_synth_generator->volume);
702
703 g_rec_mutex_unlock(sfz_synth_generator_mutex);
704 }
705 break;
706 case PROP_BASE_KEY:
707 {
708 g_rec_mutex_lock(sfz_synth_generator_mutex);
709
710 g_value_set_double(value, sfz_synth_generator->base_key);
711
712 g_rec_mutex_unlock(sfz_synth_generator_mutex);
713 }
714 break;
715 case PROP_TUNING:
716 {
717 g_rec_mutex_lock(sfz_synth_generator_mutex);
718
719 g_value_set_double(value, sfz_synth_generator->tuning);
720
721 g_rec_mutex_unlock(sfz_synth_generator_mutex);
722 }
723 break;
724 case PROP_TIMESTAMP:
725 {
726 g_rec_mutex_lock(sfz_synth_generator_mutex);
727
728 g_value_set_object(value, sfz_synth_generator->timestamp);
729
730 g_rec_mutex_unlock(sfz_synth_generator_mutex);
731 }
732 break;
733 default:
734 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
735 break;
736 }
737 }
738
739 void
ags_sfz_synth_generator_finalize(GObject * gobject)740 ags_sfz_synth_generator_finalize(GObject *gobject)
741 {
742 AgsSFZSynthGenerator *sfz_synth_generator;
743
744 sfz_synth_generator = AGS_SFZ_SYNTH_GENERATOR(gobject);
745
746 if(sfz_synth_generator->timestamp != NULL){
747 g_object_unref(sfz_synth_generator->timestamp);
748 }
749
750 /* finalize */
751 G_OBJECT_CLASS(ags_sfz_synth_generator_parent_class)->finalize(gobject);
752 }
753
754 /**
755 * ags_sfz_synth_generator_get_obj_mutex:
756 * @sfz_synth_generator: the #AgsSFZSynthGenerator
757 *
758 * Get object mutex.
759 *
760 * Returns: the #GRecMutex to lock @sfz_synth_generator
761 *
762 * Since: 3.4.0
763 */
764 GRecMutex*
ags_sfz_synth_generator_get_obj_mutex(AgsSFZSynthGenerator * sfz_synth_generator)765 ags_sfz_synth_generator_get_obj_mutex(AgsSFZSynthGenerator *sfz_synth_generator)
766 {
767 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
768 return(NULL);
769 }
770
771 return(AGS_SFZ_SYNTH_GENERATOR_GET_OBJ_MUTEX(sfz_synth_generator));
772 }
773
774 /**
775 * ags_sfz_synth_generator_get_filename:
776 * @sfz_synth_generator: the #AgsSFZSynthGenerator
777 *
778 * Gets filename.
779 *
780 * Returns: the filename
781 *
782 * Since: 3.4.0
783 */
784 gchar*
ags_sfz_synth_generator_get_filename(AgsSFZSynthGenerator * sfz_synth_generator)785 ags_sfz_synth_generator_get_filename(AgsSFZSynthGenerator *sfz_synth_generator)
786 {
787 gchar *filename;
788
789 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
790 return(NULL);
791 }
792
793 g_object_get(sfz_synth_generator,
794 "filename", &filename,
795 NULL);
796
797 return(filename);
798 }
799
800 /**
801 * ags_sfz_synth_generator_set_filename:
802 * @sfz_synth_generator: the #AgsSFZSynthGenerator
803 * @filename: the filename
804 *
805 * Set filename.
806 *
807 * Since: 3.4.0
808 */
809 void
ags_sfz_synth_generator_set_filename(AgsSFZSynthGenerator * sfz_synth_generator,gchar * filename)810 ags_sfz_synth_generator_set_filename(AgsSFZSynthGenerator *sfz_synth_generator, gchar *filename)
811 {
812 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
813 return;
814 }
815
816 g_object_set(sfz_synth_generator,
817 "filename", filename,
818 NULL);
819 }
820
821 /**
822 * ags_sfz_synth_generator_get_samplerate:
823 * @sfz_synth_generator: the #AgsSFZSynthGenerator
824 *
825 * Gets samplerate.
826 *
827 * Returns: the samplerate
828 *
829 * Since: 3.4.0
830 */
831 guint
ags_sfz_synth_generator_get_samplerate(AgsSFZSynthGenerator * sfz_synth_generator)832 ags_sfz_synth_generator_get_samplerate(AgsSFZSynthGenerator *sfz_synth_generator)
833 {
834 guint samplerate;
835
836 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
837 return(0);
838 }
839
840 g_object_get(sfz_synth_generator,
841 "samplerate", &samplerate,
842 NULL);
843
844 return(samplerate);
845 }
846
847 /**
848 * ags_sfz_synth_generator_set_samplerate:
849 * @sfz_synth_generator: the #AgsSFZSynthGenerator
850 * @samplerate: the samplerate
851 *
852 * Set samplerate.
853 *
854 * Since: 3.4.0
855 */
856 void
ags_sfz_synth_generator_set_samplerate(AgsSFZSynthGenerator * sfz_synth_generator,guint samplerate)857 ags_sfz_synth_generator_set_samplerate(AgsSFZSynthGenerator *sfz_synth_generator, guint samplerate)
858 {
859 guint old_samplerate;
860 guint i;
861
862 GRecMutex *sfz_synth_generator_mutex;
863
864 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
865 return;
866 }
867
868 /* get sfz synth generator mutex */
869 sfz_synth_generator_mutex = AGS_SFZ_SYNTH_GENERATOR_GET_OBJ_MUTEX(sfz_synth_generator);
870
871 g_rec_mutex_lock(sfz_synth_generator_mutex);
872
873 old_samplerate = sfz_synth_generator->samplerate;
874
875 if(old_samplerate == samplerate){
876 g_rec_mutex_unlock(sfz_synth_generator_mutex);
877
878 return;
879 }
880
881 sfz_synth_generator->samplerate = samplerate;
882
883 sfz_synth_generator->frame_count = samplerate * (sfz_synth_generator->frame_count / old_samplerate);
884
885 sfz_synth_generator->loop_start = samplerate * (sfz_synth_generator->loop_start / old_samplerate);
886 sfz_synth_generator->loop_end = samplerate * (sfz_synth_generator->loop_end / old_samplerate);
887
888 g_rec_mutex_unlock(sfz_synth_generator_mutex);
889 }
890
891 /**
892 * ags_sfz_synth_generator_get_buffer_size:
893 * @sfz_synth_generator: the #AgsSFZSynthGenerator
894 *
895 * Gets buffer size.
896 *
897 * Returns: the buffer size
898 *
899 * Since: 3.4.0
900 */
901 guint
ags_sfz_synth_generator_get_buffer_size(AgsSFZSynthGenerator * sfz_synth_generator)902 ags_sfz_synth_generator_get_buffer_size(AgsSFZSynthGenerator *sfz_synth_generator)
903 {
904 guint buffer_size;
905
906 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
907 return(0);
908 }
909
910 g_object_get(sfz_synth_generator,
911 "buffer-size", &buffer_size,
912 NULL);
913
914 return(buffer_size);
915 }
916
917 /**
918 * ags_sfz_synth_generator_set_buffer_size:
919 * @sfz_synth_generator: the #AgsSFZSynthGenerator
920 * @buffer_size: the buffer size
921 *
922 * Set buffer size.
923 *
924 * Since: 3.4.0
925 */
926 void
ags_sfz_synth_generator_set_buffer_size(AgsSFZSynthGenerator * sfz_synth_generator,guint buffer_size)927 ags_sfz_synth_generator_set_buffer_size(AgsSFZSynthGenerator *sfz_synth_generator, guint buffer_size)
928 {
929 GRecMutex *sfz_synth_generator_mutex;
930
931 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
932 return;
933 }
934
935 /* get sfz synth generator mutex */
936 sfz_synth_generator_mutex = AGS_SFZ_SYNTH_GENERATOR_GET_OBJ_MUTEX(sfz_synth_generator);
937
938 g_rec_mutex_lock(sfz_synth_generator_mutex);
939
940 sfz_synth_generator->buffer_size = buffer_size;
941
942 g_rec_mutex_unlock(sfz_synth_generator_mutex);
943 }
944
945 /**
946 * ags_sfz_synth_generator_get_format:
947 * @sfz_synth_generator: the #AgsSFZSynthGenerator
948 *
949 * Gets format.
950 *
951 * Returns: the format
952 *
953 * Since: 3.4.0
954 */
955 guint
ags_sfz_synth_generator_get_format(AgsSFZSynthGenerator * sfz_synth_generator)956 ags_sfz_synth_generator_get_format(AgsSFZSynthGenerator *sfz_synth_generator)
957 {
958 guint format;
959
960 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
961 return(0);
962 }
963
964 g_object_get(sfz_synth_generator,
965 "format", &format,
966 NULL);
967
968 return(format);
969 }
970
971 /**
972 * ags_sfz_synth_generator_set_format:
973 * @sfz_synth_generator: the #AgsSFZSynthGenerator
974 * @format: the format
975 *
976 * Set format.
977 *
978 * Since: 3.4.0
979 */
980 void
ags_sfz_synth_generator_set_format(AgsSFZSynthGenerator * sfz_synth_generator,guint format)981 ags_sfz_synth_generator_set_format(AgsSFZSynthGenerator *sfz_synth_generator, guint format)
982 {
983 GRecMutex *sfz_synth_generator_mutex;
984
985 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
986 return;
987 }
988
989 /* get sfz synth generator mutex */
990 sfz_synth_generator_mutex = AGS_SFZ_SYNTH_GENERATOR_GET_OBJ_MUTEX(sfz_synth_generator);
991
992 g_rec_mutex_lock(sfz_synth_generator_mutex);
993
994 sfz_synth_generator->format = format;
995
996 g_rec_mutex_unlock(sfz_synth_generator_mutex);
997 }
998
999 /**
1000 * ags_sfz_synth_generator_get_pitch_type:
1001 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1002 *
1003 * Gets pitch type.
1004 *
1005 * Returns: the pitch type
1006 *
1007 * Since: 3.9.0
1008 */
1009 guint
ags_sfz_synth_generator_get_pitch_type(AgsSFZSynthGenerator * sfz_synth_generator)1010 ags_sfz_synth_generator_get_pitch_type(AgsSFZSynthGenerator *sfz_synth_generator)
1011 {
1012 guint pitch_type;
1013
1014 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1015 return(0);
1016 }
1017
1018 g_object_get(sfz_synth_generator,
1019 "pitch-type", &pitch_type,
1020 NULL);
1021
1022 return(pitch_type);
1023 }
1024
1025 /**
1026 * ags_sfz_synth_generator_set_pitch_type:
1027 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1028 * @pitch_type: the pitch type
1029 *
1030 * Set pitch type.
1031 *
1032 * Since: 3.9.0
1033 */
1034 void
ags_sfz_synth_generator_set_pitch_type(AgsSFZSynthGenerator * sfz_synth_generator,guint pitch_type)1035 ags_sfz_synth_generator_set_pitch_type(AgsSFZSynthGenerator *sfz_synth_generator, guint pitch_type)
1036 {
1037 GRecMutex *sfz_synth_generator_mutex;
1038
1039 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1040 return;
1041 }
1042
1043 /* get sfz synth generator mutex */
1044 sfz_synth_generator_mutex = AGS_SFZ_SYNTH_GENERATOR_GET_OBJ_MUTEX(sfz_synth_generator);
1045
1046 g_rec_mutex_lock(sfz_synth_generator_mutex);
1047
1048 sfz_synth_generator->pitch_type = pitch_type;
1049
1050 g_rec_mutex_unlock(sfz_synth_generator_mutex);
1051 }
1052
1053 /**
1054 * ags_sfz_synth_generator_get_delay:
1055 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1056 *
1057 * Gets delay.
1058 *
1059 * Returns: the delay
1060 *
1061 * Since: 3.4.0
1062 */
1063 gdouble
ags_sfz_synth_generator_get_delay(AgsSFZSynthGenerator * sfz_synth_generator)1064 ags_sfz_synth_generator_get_delay(AgsSFZSynthGenerator *sfz_synth_generator)
1065 {
1066 gdouble delay;
1067
1068 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1069 return(0.0);
1070 }
1071
1072 g_object_get(sfz_synth_generator,
1073 "delay", &delay,
1074 NULL);
1075
1076 return(delay);
1077 }
1078
1079 /**
1080 * ags_sfz_synth_generator_set_delay:
1081 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1082 * @delay: the delay
1083 *
1084 * Sets delay.
1085 *
1086 * Since: 3.4.0
1087 */
1088 void
ags_sfz_synth_generator_set_delay(AgsSFZSynthGenerator * sfz_synth_generator,gdouble delay)1089 ags_sfz_synth_generator_set_delay(AgsSFZSynthGenerator *sfz_synth_generator, gdouble delay)
1090 {
1091 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1092 return;
1093 }
1094
1095 g_object_set(sfz_synth_generator,
1096 "delay", delay,
1097 NULL);
1098 }
1099
1100 /**
1101 * ags_sfz_synth_generator_get_frame_count:
1102 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1103 *
1104 * Gets frame count.
1105 *
1106 * Returns: the frame count
1107 *
1108 * Since: 3.4.0
1109 */
1110 guint
ags_sfz_synth_generator_get_frame_count(AgsSFZSynthGenerator * sfz_synth_generator)1111 ags_sfz_synth_generator_get_frame_count(AgsSFZSynthGenerator *sfz_synth_generator)
1112 {
1113 guint frame_count;
1114
1115 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1116 return(0);
1117 }
1118
1119 g_object_get(sfz_synth_generator,
1120 "frame-count", &frame_count,
1121 NULL);
1122
1123 return(frame_count);
1124 }
1125
1126 /**
1127 * ags_sfz_synth_generator_set_frame_count:
1128 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1129 * @frame_count: the frame count
1130 *
1131 * Sets frame count.
1132 *
1133 * Since: 3.4.0
1134 */
1135 void
ags_sfz_synth_generator_set_frame_count(AgsSFZSynthGenerator * sfz_synth_generator,guint frame_count)1136 ags_sfz_synth_generator_set_frame_count(AgsSFZSynthGenerator *sfz_synth_generator, guint frame_count)
1137 {
1138 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1139 return;
1140 }
1141
1142 g_object_set(sfz_synth_generator,
1143 "frame-count", frame_count,
1144 NULL);
1145 }
1146
1147 /**
1148 * ags_sfz_synth_generator_get_loop_start:
1149 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1150 *
1151 * Gets loop start.
1152 *
1153 * Returns: the loop start
1154 *
1155 * Since: 3.4.0
1156 */
1157 guint
ags_sfz_synth_generator_get_loop_start(AgsSFZSynthGenerator * sfz_synth_generator)1158 ags_sfz_synth_generator_get_loop_start(AgsSFZSynthGenerator *sfz_synth_generator)
1159 {
1160 guint loop_start;
1161
1162 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1163 return(0);
1164 }
1165
1166 g_object_get(sfz_synth_generator,
1167 "loop-start", &loop_start,
1168 NULL);
1169
1170 return(loop_start);
1171 }
1172
1173 /**
1174 * ags_sfz_synth_generator_set_loop_start:
1175 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1176 * @loop_start: the loop start
1177 *
1178 * Sets loop start.
1179 *
1180 * Since: 3.4.0
1181 */
1182 void
ags_sfz_synth_generator_set_loop_start(AgsSFZSynthGenerator * sfz_synth_generator,guint loop_start)1183 ags_sfz_synth_generator_set_loop_start(AgsSFZSynthGenerator *sfz_synth_generator, guint loop_start)
1184 {
1185 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1186 return;
1187 }
1188
1189 g_object_set(sfz_synth_generator,
1190 "loop-start", loop_start,
1191 NULL);
1192 }
1193
1194 /**
1195 * ags_sfz_synth_generator_get_loop_end:
1196 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1197 *
1198 * Gets loop end.
1199 *
1200 * Returns: the loop end
1201 *
1202 * Since: 3.4.0
1203 */
1204 guint
ags_sfz_synth_generator_get_loop_end(AgsSFZSynthGenerator * sfz_synth_generator)1205 ags_sfz_synth_generator_get_loop_end(AgsSFZSynthGenerator *sfz_synth_generator)
1206 {
1207 guint loop_end;
1208
1209 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1210 return(0);
1211 }
1212
1213 g_object_get(sfz_synth_generator,
1214 "loop-end", &loop_end,
1215 NULL);
1216
1217 return(loop_end);
1218 }
1219
1220 /**
1221 * ags_sfz_synth_generator_set_loop_end:
1222 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1223 * @loop_end: the loop end
1224 *
1225 * Sets loop end.
1226 *
1227 * Since: 3.4.0
1228 */
1229 void
ags_sfz_synth_generator_set_loop_end(AgsSFZSynthGenerator * sfz_synth_generator,guint loop_end)1230 ags_sfz_synth_generator_set_loop_end(AgsSFZSynthGenerator *sfz_synth_generator, guint loop_end)
1231 {
1232 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1233 return;
1234 }
1235
1236 g_object_set(sfz_synth_generator,
1237 "loop-end", loop_end,
1238 NULL);
1239 }
1240
1241 /**
1242 * ags_sfz_synth_generator_get_base_key:
1243 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1244 *
1245 * Gets base key.
1246 *
1247 * Returns: the base key
1248 *
1249 * Since: 3.4.0
1250 */
1251 gdouble
ags_sfz_synth_generator_get_base_key(AgsSFZSynthGenerator * sfz_synth_generator)1252 ags_sfz_synth_generator_get_base_key(AgsSFZSynthGenerator *sfz_synth_generator)
1253 {
1254 gdouble base_key;
1255
1256 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1257 return(0.0);
1258 }
1259
1260 g_object_get(sfz_synth_generator,
1261 "base_key", &base_key,
1262 NULL);
1263
1264 return(base_key);
1265 }
1266
1267 /**
1268 * ags_sfz_synth_generator_set_base_key:
1269 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1270 * @base_key: the base key
1271 *
1272 * Sets base key.
1273 *
1274 * Since: 3.4.0
1275 */
1276 void
ags_sfz_synth_generator_set_base_key(AgsSFZSynthGenerator * sfz_synth_generator,gdouble base_key)1277 ags_sfz_synth_generator_set_base_key(AgsSFZSynthGenerator *sfz_synth_generator, gdouble base_key)
1278 {
1279 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1280 return;
1281 }
1282
1283 g_object_set(sfz_synth_generator,
1284 "base-key", base_key,
1285 NULL);
1286 }
1287
1288 /**
1289 * ags_sfz_synth_generator_get_tuning:
1290 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1291 *
1292 * Gets tuning.
1293 *
1294 * Returns: the tuning
1295 *
1296 * Since: 3.4.0
1297 */
1298 gdouble
ags_sfz_synth_generator_get_tuning(AgsSFZSynthGenerator * sfz_synth_generator)1299 ags_sfz_synth_generator_get_tuning(AgsSFZSynthGenerator *sfz_synth_generator)
1300 {
1301 gdouble tuning;
1302
1303 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1304 return(0.0);
1305 }
1306
1307 g_object_get(sfz_synth_generator,
1308 "tuning", &tuning,
1309 NULL);
1310
1311 return(tuning);
1312 }
1313
1314 /**
1315 * ags_sfz_synth_generator_set_tuning:
1316 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1317 * @tuning: the tuning
1318 *
1319 * Sets tuning.
1320 *
1321 * Since: 3.4.0
1322 */
1323 void
ags_sfz_synth_generator_set_tuning(AgsSFZSynthGenerator * sfz_synth_generator,gdouble tuning)1324 ags_sfz_synth_generator_set_tuning(AgsSFZSynthGenerator *sfz_synth_generator, gdouble tuning)
1325 {
1326 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1327 return;
1328 }
1329
1330 g_object_set(sfz_synth_generator,
1331 "tuning", tuning,
1332 NULL);
1333 }
1334
1335 /**
1336 * ags_sfz_synth_generator_get_timestamp:
1337 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1338 *
1339 * Get timestamp.
1340 *
1341 * Returns: (transfer full): the #AgsTimestamp
1342 *
1343 * Since: 3.4.0
1344 */
1345 AgsTimestamp*
ags_sfz_synth_generator_get_timestamp(AgsSFZSynthGenerator * sfz_synth_generator)1346 ags_sfz_synth_generator_get_timestamp(AgsSFZSynthGenerator *sfz_synth_generator)
1347 {
1348 AgsTimestamp *timestamp;
1349
1350 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1351 return(NULL);
1352 }
1353
1354 g_object_get(sfz_synth_generator,
1355 "timestamp", ×tamp,
1356 NULL);
1357
1358 return(timestamp);
1359 }
1360
1361 /**
1362 * ags_sfz_synth_generator_set_timestamp:
1363 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1364 * @timestamp: the #AgsTimestamp
1365 *
1366 * Set timestamp.
1367 *
1368 * Since: 3.4.0
1369 */
1370 void
ags_sfz_synth_generator_set_timestamp(AgsSFZSynthGenerator * sfz_synth_generator,AgsTimestamp * timestamp)1371 ags_sfz_synth_generator_set_timestamp(AgsSFZSynthGenerator *sfz_synth_generator, AgsTimestamp *timestamp)
1372 {
1373 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator)){
1374 return;
1375 }
1376
1377 g_object_set(sfz_synth_generator,
1378 "timestamp", timestamp,
1379 NULL);
1380 }
1381
1382 /**
1383 * ags_sfz_synth_generator_compute:
1384 * @sfz_synth_generator: the #AgsSFZSynthGenerator
1385 * @audio_signal: the #AgsAudioSignal
1386 * @note: the note to compute
1387 *
1388 * Compute instrument for @note.
1389 *
1390 * Since: 3.4.0
1391 */
1392 void
ags_sfz_synth_generator_compute(AgsSFZSynthGenerator * sfz_synth_generator,GObject * audio_signal,gdouble note)1393 ags_sfz_synth_generator_compute(AgsSFZSynthGenerator *sfz_synth_generator,
1394 GObject *audio_signal,
1395 gdouble note)
1396 {
1397 AgsAudioContainerManager *audio_container_manager;
1398 AgsAudioContainer *audio_container;
1399 AgsSFZSample *sfz_sample;
1400
1401 GObject *output_soundcard;
1402
1403 GList *start_list, *list;
1404 GList *stream_start, *stream;
1405
1406 void *buffer;
1407
1408 gchar *filename;
1409
1410 gint midi_key;
1411 glong lower, upper;
1412 gdouble delay;
1413 guint attack;
1414 guint frame_count;
1415 guint length;
1416 guint buffer_size;
1417 guint current_frame_count, requested_frame_count;
1418 gdouble samplerate;
1419 guint format;
1420 gdouble volume;
1421 guint audio_buffer_util_format;
1422 guint loop_mode;
1423 gint loop_start, loop_end;
1424 guint copy_mode;
1425 guint i;
1426
1427 GRecMutex *sfz_synth_generator_mutex;
1428 GRecMutex *stream_mutex;
1429 GRecMutex *audio_container_manager_mutex;
1430
1431 if(!AGS_IS_SFZ_SYNTH_GENERATOR(sfz_synth_generator) ||
1432 !AGS_IS_AUDIO_SIGNAL(audio_signal)){
1433 return;
1434 }
1435
1436 /* get sfz synth generator mutex */
1437 sfz_synth_generator_mutex = AGS_SFZ_SYNTH_GENERATOR_GET_OBJ_MUTEX(sfz_synth_generator);
1438
1439 /* get stream mutex */
1440 stream_mutex = AGS_AUDIO_SIGNAL_GET_STREAM_MUTEX(audio_signal);
1441
1442 sfz_sample = NULL;
1443
1444 output_soundcard = NULL;
1445
1446 g_object_get(audio_signal,
1447 "output-soundcard", &output_soundcard,
1448 NULL);
1449
1450 filename = NULL;
1451
1452 g_object_get(sfz_synth_generator,
1453 "filename", &filename,
1454 NULL);
1455
1456 audio_container_manager = ags_audio_container_manager_get_instance();
1457
1458 /* get audio container manager mutex */
1459 audio_container_manager_mutex = AGS_AUDIO_CONTAINER_MANAGER_GET_OBJ_MUTEX(audio_container_manager);
1460
1461 g_rec_mutex_lock(audio_container_manager_mutex);
1462
1463 audio_container = ags_audio_container_manager_find_audio_container(audio_container_manager,
1464 filename);
1465
1466 if(audio_container == NULL){
1467 audio_container = ags_audio_container_new(filename,
1468 NULL,
1469 NULL,
1470 NULL,
1471 output_soundcard,
1472 -1);
1473 ags_audio_container_open(audio_container);
1474
1475 ags_audio_container_manager_add_audio_container(audio_container_manager,
1476 audio_container);
1477 }
1478
1479 g_rec_mutex_unlock(audio_container_manager_mutex);
1480
1481 list =
1482 start_list = ags_audio_container_find_sound_resource(audio_container,
1483 NULL,
1484 NULL,
1485 NULL);
1486
1487 sfz_sample = NULL;
1488
1489 if(list != NULL){
1490 sfz_sample = list->data;
1491 }
1492
1493 midi_key = (gint) floor(note) + 69;
1494
1495 // g_message("--> %d", midi_key);
1496
1497 upper = -1;
1498 lower = -1;
1499
1500 while(list != NULL){
1501 gchar *str;
1502
1503 glong hikey, lokey;
1504 glong value;
1505 glong current_diff, diff;
1506 int retval;
1507
1508 hikey = ags_sfz_sample_get_hikey(list->data);
1509 lokey = ags_sfz_sample_get_lokey(list->data);
1510
1511 if(lokey <= midi_key &&
1512 hikey >= midi_key){
1513 sfz_sample = list->data;
1514
1515 break;
1516 }
1517
1518 diff = lower - midi_key;
1519 current_diff = lokey - midi_key;
1520
1521 if(diff < 0){
1522 diff *= -1;
1523 }
1524
1525 if(current_diff < 0){
1526 current_diff *= -1;
1527 }
1528
1529 if(lower == -1 ||
1530 current_diff < diff){
1531 sfz_sample = list->data;
1532
1533 lower = lokey;
1534 upper = hikey;
1535 }
1536
1537 diff = upper - midi_key;
1538 current_diff = hikey - midi_key;
1539
1540 if(diff < 0){
1541 diff *= -1;
1542 }
1543
1544 if(current_diff < 0){
1545 current_diff *= -1;
1546 }
1547
1548 if(upper == -1 ||
1549 current_diff < diff){
1550 sfz_sample = list->data;
1551
1552 lower = lokey;
1553 upper = hikey;
1554 }
1555
1556 list = list->next;
1557 }
1558
1559 g_list_free_full(start_list,
1560 (GDestroyNotify) g_object_unref);
1561
1562 delay = 0.0;
1563 attack = 0;
1564
1565 frame_count = 0;
1566
1567 volume = 1.0;
1568
1569 g_object_get(sfz_synth_generator,
1570 "delay", &delay,
1571 "attack", &attack,
1572 "frame-count", &frame_count,
1573 "volume", &volume,
1574 NULL);
1575
1576 if(sfz_sample != NULL){
1577 guint loop_start, loop_end;
1578
1579 loop_start = 0;
1580 loop_end = 0;
1581
1582 ags_sound_resource_info(AGS_SOUND_RESOURCE(sfz_sample),
1583 NULL,
1584 &loop_start, &loop_end);
1585
1586 g_object_set(audio_signal,
1587 "loop-start", loop_start,
1588 "loop-end", loop_end,
1589 NULL);
1590 }
1591
1592 buffer_size = AGS_SFZ_SYNTH_GENERATOR_DEFAULT_BUFFER_SIZE;
1593 samplerate = AGS_SFZ_SYNTH_GENERATOR_DEFAULT_SAMPLERATE;
1594 format = AGS_SFZ_SYNTH_GENERATOR_DEFAULT_FORMAT;
1595
1596 length = 0;
1597
1598 g_object_get(audio_signal,
1599 "buffer-size", &buffer_size,
1600 "format", &format,
1601 "samplerate", &samplerate,
1602 "length", &length,
1603 NULL);
1604
1605 current_frame_count = length * buffer_size;
1606 requested_frame_count = (guint) ceil(((floor(delay) * buffer_size + attack) + frame_count) / buffer_size) * buffer_size;
1607
1608 if(current_frame_count < requested_frame_count){
1609 ags_audio_signal_stream_resize((AgsAudioSignal *) audio_signal,
1610 ceil(requested_frame_count / buffer_size));
1611 }
1612
1613 ags_audio_signal_clear(audio_signal);
1614
1615 /* */
1616 g_rec_mutex_lock(stream_mutex);
1617
1618 stream =
1619 stream_start = g_list_nth(AGS_AUDIO_SIGNAL(audio_signal)->stream,
1620 (guint) floor(delay));
1621
1622 g_rec_mutex_unlock(stream_mutex);
1623
1624 loop_mode = AGS_SFZ_SYNTH_UTIL_LOOP_NONE;
1625
1626 loop_start = 0;
1627 loop_end = 0;
1628
1629 audio_buffer_util_format = ags_audio_buffer_util_format_from_soundcard(format);
1630
1631 buffer = ags_stream_alloc(frame_count,
1632 format);
1633
1634 if(sfz_sample != NULL){
1635 ags_sound_resource_seek(AGS_SOUND_RESOURCE(sfz_sample),
1636 0, G_SEEK_SET);
1637 }
1638
1639 #if 0
1640 {
1641 gint current_midi_key;
1642
1643 current_midi_key = ags_sfz_sample_get_pitch_keycenter(sfz_sample);
1644
1645 g_message("SFZ, note %f, midi_key %d", note, current_midi_key);
1646 }
1647 #endif
1648
1649 #if 0
1650 ags_sfz_synth_util_copy(buffer,
1651 frame_count,
1652 sfz_sample,
1653 (gdouble) note,
1654 volume,
1655 samplerate, audio_buffer_util_format,
1656 0, frame_count,
1657 AGS_SFZ_SYNTH_UTIL_LOOP_NONE,
1658 0, 0);
1659 #else
1660 g_rec_mutex_lock(sfz_synth_generator_mutex);
1661
1662 sfz_synth_generator->sfz->note = note;
1663
1664 sfz_synth_generator->sfz->volume = volume;
1665
1666 sfz_synth_generator->sfz->samplerate = samplerate;
1667
1668 sfz_synth_generator->sfz->offset = 0;
1669 sfz_synth_generator->sfz->n_frames = frame_count;
1670
1671 sfz_synth_generator->sfz->loop_mode = AGS_SFZ_SYNTH_UTIL_LOOP_NONE;
1672
1673 sfz_synth_generator->sfz->loop_start = 0;
1674 sfz_synth_generator->sfz->loop_end = 0;
1675
1676 AGS_GENERIC_PITCH(sfz_synth_generator->sfz->generic_pitch)->pitch_type = sfz_synth_generator->pitch_type;
1677
1678 ags_sfz_util_copy(sfz_synth_generator->sfz,
1679 buffer,
1680 frame_count,
1681 sfz_sample,
1682 audio_buffer_util_format);
1683
1684 g_rec_mutex_unlock(sfz_synth_generator_mutex);
1685 #endif
1686
1687 copy_mode = ags_audio_buffer_util_get_copy_mode(audio_buffer_util_format,
1688 audio_buffer_util_format);
1689
1690
1691 g_rec_mutex_lock(stream_mutex);
1692
1693 for(i = 0; i < frame_count && stream != NULL;){
1694 guint copy_count;
1695
1696 copy_count = buffer_size;
1697
1698 if(i + copy_count > frame_count){
1699 copy_count = frame_count - i;
1700 }
1701
1702 ags_audio_buffer_util_copy_buffer_to_buffer(stream->data, 1, 0,
1703 buffer, 1, i,
1704 copy_count, copy_mode);
1705 i += copy_count;
1706
1707 stream = stream->next;
1708 }
1709
1710 g_rec_mutex_unlock(stream_mutex);
1711
1712 if(output_soundcard != NULL){
1713 g_object_unref(output_soundcard);
1714 }
1715
1716 g_free(filename);
1717
1718 ags_stream_free(buffer);
1719 }
1720
1721 /**
1722 * ags_sfz_synth_generator_new:
1723 *
1724 * Creates an #AgsSFZSynthGenerator
1725 *
1726 * Returns: a new #AgsSFZSynthGenerator
1727 *
1728 * Since: 3.4.0
1729 */
1730 AgsSFZSynthGenerator*
ags_sfz_synth_generator_new()1731 ags_sfz_synth_generator_new()
1732 {
1733 AgsSFZSynthGenerator *sfz_synth_generator;
1734
1735 sfz_synth_generator = (AgsSFZSynthGenerator *) g_object_new(AGS_TYPE_SFZ_SYNTH_GENERATOR,
1736 NULL);
1737
1738 return(sfz_synth_generator);
1739 }
1740