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_filter_util.h>
21
22 #include <ags/audio/ags_audio_signal.h>
23 #include <ags/audio/ags_audio_buffer_util.h>
24 #include <ags/audio/ags_fourier_transform_util.h>
25
26 #include <math.h>
27 #include <complex.h>
28
29 gpointer ags_filter_util_copy(gpointer ptr);
30 void ags_filter_util_free(gpointer ptr);
31
32 /**
33 * SECTION:ags_filter_util
34 * @short_description: filter util
35 * @title: AgsFilterUtil
36 * @section_id:
37 * @include: ags/audio/ags_filter_util.h
38 *
39 * Utility functions to compute filters.
40 */
41
42 GType
ags_filter_util_get_type(void)43 ags_filter_util_get_type(void)
44 {
45 static volatile gsize g_define_type_id__volatile = 0;
46
47 if(g_once_init_enter (&g_define_type_id__volatile)){
48 GType ags_type_filter_util = 0;
49
50 ags_type_filter_util =
51 g_boxed_type_register_static("AgsFilterUtil",
52 (GBoxedCopyFunc) ags_filter_util_copy,
53 (GBoxedFreeFunc) ags_filter_util_free);
54
55 g_once_init_leave(&g_define_type_id__volatile, ags_type_filter_util);
56 }
57
58 return g_define_type_id__volatile;
59 }
60
61 gpointer
ags_filter_util_copy(gpointer ptr)62 ags_filter_util_copy(gpointer ptr)
63 {
64 gpointer retval;
65
66 retval = g_memdup(ptr, sizeof(AgsFilterUtil));
67
68 return(retval);
69 }
70
71 void
ags_filter_util_free(gpointer ptr)72 ags_filter_util_free(gpointer ptr)
73 {
74 g_free(ptr);
75 }
76
77 /**
78 * ags_filter_util_pitch_s8:
79 * @buffer: the audio buffer
80 * @buffer_length: the buffer's length
81 * @samplerate: the samplerate
82 * @base_key: the base key
83 * @tuning: the tuning
84 *
85 * Apply pitch filter.
86 *
87 * Since: 3.0.0
88 */
89 void
ags_filter_util_pitch_s8(gint8 * buffer,guint buffer_length,guint samplerate,gdouble base_key,gdouble tuning)90 ags_filter_util_pitch_s8(gint8 *buffer,
91 guint buffer_length,
92 guint samplerate,
93 gdouble base_key,
94 gdouble tuning)
95 {
96 AgsComplex *ptr_mix_buffer, *ptr_im_mix_buffer, *ptr_low_mix_buffer, *ptr_new_mix_buffer;
97 AgsComplex *mix_buffer, *im_mix_buffer, *low_mix_buffer, *new_mix_buffer;
98 gint8 *ptr_buffer;
99
100 gdouble volume;
101 gdouble im_key, low_key;
102 gdouble base_freq, im_freq, low_freq, new_freq;
103 gdouble offset_factor, im_offset_factor, low_offset_factor, new_offset_factor;
104 gdouble freq_period, im_freq_period, low_freq_period, new_freq_period;
105 gdouble t;
106 guint i;
107
108 if(buffer == NULL){
109 return;
110 }
111
112 /* frequency */
113 base_freq = exp2((base_key) / 12.0) * 440.0;
114
115 im_key = (gdouble) ((gint) floor(tuning / 100.0) % 12);
116
117 if(im_key < 0.0){
118 im_key += 12.0;
119 }
120
121 if(im_key == 0.0){
122 im_key = 1.0;
123 }
124
125 im_freq = exp2((base_key + im_key) / 12.0) * 440.0;
126
127 low_key = base_key - 12.0;
128
129 low_freq = exp2((low_key) / 12.0) * 440.0;
130
131 new_freq = exp2((base_key + (tuning / 100.0)) / 12.0) * 440.0;
132
133 if(base_freq <= 0.0){
134 g_warning("rejecting pitch base freq %f <= 0.0", base_freq);
135
136 return;
137 }
138
139 if(im_freq <= 0.0){
140 g_warning("rejecting pitch intermediate freq %f <= 0.0", im_freq);
141
142 return;
143 }
144
145 if(new_freq <= 0.0){
146 g_warning("rejecting pitch new freq %f <= 0.0", new_freq);
147
148 return;
149 }
150
151 volume = 1.0 / base_freq * new_freq;
152
153 /* get frequency period */
154 freq_period = samplerate / base_freq;
155
156 im_freq_period = samplerate / im_freq;
157 low_freq_period = samplerate / low_freq;
158 new_freq_period = samplerate / new_freq;
159
160 /* get offset factor */
161 offset_factor = 1.0;
162
163 im_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / im_freq);
164 low_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / low_freq);
165 new_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / new_freq);
166
167 /* allocate buffer */
168 mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
169 AGS_SOUNDCARD_COMPLEX);
170
171 im_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
172 AGS_SOUNDCARD_COMPLEX);
173
174 low_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
175 AGS_SOUNDCARD_COMPLEX);
176
177 new_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
178 AGS_SOUNDCARD_COMPLEX);
179
180 /* mix buffer */
181 for(i = 0; i < buffer_length; i++){
182 ptr_mix_buffer = mix_buffer + i;
183
184 /* write mix buffer */
185 AGS_AUDIO_BUFFER_UTIL_S8_TO_COMPLEX(buffer[i], &ptr_mix_buffer);
186 }
187
188 /* im mix buffer */
189 for(i = 0; i < buffer_length; i++){
190 double _Complex z, mix_z, im_z;
191 gdouble phase, im_phase;
192 guint start_x;
193
194 if(floor(freq_period) != 0.0){
195 start_x = freq_period * floor((double) i / freq_period);
196 }else{
197 start_x = 0;
198 }
199
200 im_phase = fmod(i, im_freq_period);
201
202 phase = fmod(i, freq_period);
203
204 if(start_x + (guint) floor(phase) < buffer_length){
205 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
206 }else{
207 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
208 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
209 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
210 }else{
211 if(floor(phase) < buffer_length){
212 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
213 }else{
214 ptr_mix_buffer = mix_buffer + buffer_length - 1;
215 }
216 }
217 }
218
219 ptr_im_mix_buffer = im_mix_buffer + i;
220
221 /* write im mix buffer */
222 z = ags_complex_get(mix_buffer + i);
223 mix_z = ags_complex_get(ptr_mix_buffer);
224
225 t = (im_freq_period / freq_period);
226
227 im_z = (1.0 - t) * z + (t * mix_z);
228
229 ags_complex_set(ptr_im_mix_buffer, im_z);
230 }
231
232 /* low mix buffer */
233 for(i = 0; i < buffer_length; i++){
234 double _Complex z, mix_z, low_z;
235 gdouble phase, low_phase;
236 guint start_x;
237
238 if(floor(freq_period) != 0.0){
239 start_x = freq_period * floor((double) i / freq_period);
240 }else{
241 start_x = 0;
242 }
243
244 low_phase = fmod(i, low_freq_period);
245
246 phase = fmod(i, freq_period);
247
248 if(start_x + (guint) floor(phase) < buffer_length){
249 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
250 }else{
251 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
252 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
253 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
254 }else{
255 if(floor(phase) < buffer_length){
256 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
257 }else{
258 ptr_mix_buffer = mix_buffer + buffer_length - 1;
259 }
260 }
261 }
262
263 ptr_low_mix_buffer = low_mix_buffer + i;
264
265 /* write low mix buffer */
266 z = ags_complex_get(mix_buffer + i);
267 mix_z = ags_complex_get(ptr_mix_buffer);
268
269 t = (low_freq_period / freq_period);
270
271 low_z = (1.0 - t) * z + (t * mix_z);
272
273 ags_complex_set(ptr_low_mix_buffer, low_z);
274 }
275
276 /* new mix buffer */
277 for(i = 0; i < buffer_length; i++){
278 double _Complex new_z;
279 gdouble phase, im_phase, low_phase, new_phase;
280 guint start_x, im_start_x, low_start_x;
281
282 if(floor(freq_period) != 0.0){
283 start_x = freq_period * floor((double) i / freq_period);
284 }else{
285 start_x = 0;
286 }
287
288 if(floor(im_freq_period) != 0.0){
289 im_start_x = im_freq_period * floor((double) i / im_freq_period);
290 }else{
291 im_start_x = 0;
292 }
293
294 if(floor(low_freq_period) != 0.0){
295 low_start_x = low_freq_period * floor((double) i / low_freq_period);
296 }else{
297 low_start_x = 0;
298 }
299
300 phase = fmod(i, freq_period);
301
302 im_phase = fmod(i, im_freq_period);
303
304 low_phase = fmod(i, low_freq_period);
305
306 new_phase = fmod(i, new_freq_period);
307
308 if(start_x + (guint) floor(new_phase) < buffer_length){
309 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase));
310 }else{
311 if((start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) < buffer_length &&
312 (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) > 0){
313 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period);
314 }else{
315 if(floor(new_phase) < buffer_length){
316 ptr_mix_buffer = mix_buffer + (guint) floor(new_phase);
317 }else{
318 ptr_mix_buffer = mix_buffer + buffer_length - 1;
319 }
320 }
321 }
322
323 if(im_start_x + (guint) floor(new_phase) < buffer_length){
324 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase));
325 }else{
326 if((im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) < buffer_length &&
327 (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) > 0){
328 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period);
329 }else{
330 if(floor(new_phase) < buffer_length){
331 ptr_im_mix_buffer = im_mix_buffer + (guint) floor(new_phase);
332 }else{
333 ptr_im_mix_buffer = im_mix_buffer + buffer_length - 1;
334 }
335 }
336 }
337
338 if(low_start_x + (guint) floor(new_phase) < buffer_length){
339 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase));
340 }else{
341 if((low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) < buffer_length &&
342 (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) > 0){
343 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period);
344 }else{
345 if(floor(new_phase) < buffer_length){
346 ptr_low_mix_buffer = low_mix_buffer + (guint) floor(new_phase);
347 }else{
348 ptr_low_mix_buffer = low_mix_buffer + buffer_length - 1;
349 }
350 }
351 }
352
353 ptr_new_mix_buffer = new_mix_buffer + i;
354
355 /* write new mix buffer */
356 if(ptr_mix_buffer->real != 0.0){
357 new_z = volume * ((1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_im_mix_buffer) / im_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)) + (1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_low_mix_buffer) / low_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)));
358 }else{
359 new_z = 0.0 + I * 0.0;
360 }
361
362 ags_complex_set(ptr_new_mix_buffer,
363 new_z);
364 }
365
366 /* rewrite buffer */
367 for(i = 0; i < buffer_length; i++){
368 ptr_new_mix_buffer = new_mix_buffer + i;
369 ptr_buffer = buffer + i;
370
371 AGS_AUDIO_BUFFER_UTIL_COMPLEX_TO_S8(ptr_new_mix_buffer, ptr_buffer);
372 }
373
374 ags_stream_free(mix_buffer);
375
376 ags_stream_free(im_mix_buffer);
377
378 ags_stream_free(low_mix_buffer);
379
380 ags_stream_free(new_mix_buffer);
381 }
382
383 /**
384 * ags_filter_util_pitch_s16:
385 * @buffer: the audio buffer
386 * @buffer_length: the buffer's length
387 * @samplerate: the samplerate
388 * @base_key: the base key
389 * @tuning: the tuning
390 *
391 * Apply pitch filter.
392 *
393 * Since: 3.0.0
394 */
395 void
ags_filter_util_pitch_s16(gint16 * buffer,guint buffer_length,guint samplerate,gdouble base_key,gdouble tuning)396 ags_filter_util_pitch_s16(gint16 *buffer,
397 guint buffer_length,
398 guint samplerate,
399 gdouble base_key,
400 gdouble tuning)
401 {
402 AgsComplex *ptr_mix_buffer, *ptr_im_mix_buffer, *ptr_low_mix_buffer, *ptr_new_mix_buffer;
403 AgsComplex *mix_buffer, *im_mix_buffer, *low_mix_buffer, *new_mix_buffer;
404 gint16 *ptr_buffer;
405
406 gdouble volume;
407 gdouble im_key, low_key;
408 gdouble base_freq, im_freq, low_freq, new_freq;
409 gdouble offset_factor, im_offset_factor, low_offset_factor, new_offset_factor;
410 gdouble freq_period, im_freq_period, low_freq_period, new_freq_period;
411 gdouble t;
412 guint i;
413
414 if(buffer == NULL){
415 return;
416 }
417
418 /* frequency */
419 base_freq = exp2((base_key) / 12.0) * 440.0;
420
421 im_key = (gdouble) ((gint) floor(tuning / 100.0) % 12);
422
423 if(im_key < 0.0){
424 im_key += 12.0;
425 }
426
427 if(im_key == 0.0){
428 im_key = 1.0;
429 }
430
431 im_freq = exp2((base_key + im_key) / 12.0) * 440.0;
432
433 low_key = base_key - 12.0;
434
435 low_freq = exp2((low_key) / 12.0) * 440.0;
436
437 new_freq = exp2((base_key + (tuning / 100.0)) / 12.0) * 440.0;
438
439 if(base_freq <= 0.0){
440 g_warning("rejecting pitch base freq %f <= 0.0", base_freq);
441
442 return;
443 }
444
445 if(im_freq <= 0.0){
446 g_warning("rejecting pitch intermediate freq %f <= 0.0", im_freq);
447
448 return;
449 }
450
451 if(new_freq <= 0.0){
452 g_warning("rejecting pitch new freq %f <= 0.0", new_freq);
453
454 return;
455 }
456
457 volume = 1.0 / base_freq * new_freq;
458
459 /* get frequency period */
460 freq_period = samplerate / base_freq;
461
462 im_freq_period = samplerate / im_freq;
463 low_freq_period = samplerate / low_freq;
464 new_freq_period = samplerate / new_freq;
465
466 /* get offset factor */
467 offset_factor = 1.0;
468
469 im_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / im_freq);
470 low_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / low_freq);
471 new_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / new_freq);
472
473 /* allocate buffer */
474 mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
475 AGS_SOUNDCARD_COMPLEX);
476
477 im_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
478 AGS_SOUNDCARD_COMPLEX);
479
480 low_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
481 AGS_SOUNDCARD_COMPLEX);
482
483 new_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
484 AGS_SOUNDCARD_COMPLEX);
485
486 /* mix buffer */
487 for(i = 0; i < buffer_length; i++){
488 ptr_mix_buffer = mix_buffer + i;
489
490 /* write mix buffer */
491 AGS_AUDIO_BUFFER_UTIL_S16_TO_COMPLEX(buffer[i], &ptr_mix_buffer);
492 }
493
494 /* im mix buffer */
495 for(i = 0; i < buffer_length; i++){
496 double _Complex z, mix_z, im_z;
497 gdouble phase, im_phase;
498 guint start_x;
499
500 if(floor(freq_period) != 0.0){
501 start_x = freq_period * floor((double) i / freq_period);
502 }else{
503 start_x = 0;
504 }
505
506 im_phase = fmod(i, im_freq_period);
507
508 phase = fmod(i, freq_period);
509
510 if(start_x + (guint) floor(phase) < buffer_length){
511 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
512 }else{
513 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
514 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
515 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
516 }else{
517 if(floor(phase) < buffer_length){
518 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
519 }else{
520 ptr_mix_buffer = mix_buffer + buffer_length - 1;
521 }
522 }
523 }
524
525 ptr_im_mix_buffer = im_mix_buffer + i;
526
527 /* write im mix buffer */
528 z = ags_complex_get(mix_buffer + i);
529 mix_z = ags_complex_get(ptr_mix_buffer);
530
531 t = (im_freq_period / freq_period);
532
533 im_z = (1.0 - t) * z + (t * mix_z);
534
535 ags_complex_set(ptr_im_mix_buffer, im_z);
536 }
537
538 /* low mix buffer */
539 for(i = 0; i < buffer_length; i++){
540 double _Complex z, mix_z, low_z;
541 gdouble phase, low_phase;
542 guint start_x;
543
544 if(floor(freq_period) != 0.0){
545 start_x = freq_period * floor((double) i / freq_period);
546 }else{
547 start_x = 0;
548 }
549
550 low_phase = fmod(i, low_freq_period);
551
552 phase = fmod(i, freq_period);
553
554 if(start_x + (guint) floor(phase) < buffer_length){
555 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
556 }else{
557 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
558 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
559 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
560 }else{
561 if(floor(phase) < buffer_length){
562 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
563 }else{
564 ptr_mix_buffer = mix_buffer + buffer_length - 1;
565 }
566 }
567 }
568
569 ptr_low_mix_buffer = low_mix_buffer + i;
570
571 /* write low mix buffer */
572 z = ags_complex_get(mix_buffer + i);
573 mix_z = ags_complex_get(ptr_mix_buffer);
574
575 t = (low_freq_period / freq_period);
576
577 low_z = (1.0 - t) * z + (t * mix_z);
578
579 ags_complex_set(ptr_low_mix_buffer, low_z);
580 }
581
582 /* new mix buffer */
583 for(i = 0; i < buffer_length; i++){
584 double _Complex new_z;
585 gdouble phase, im_phase, low_phase, new_phase;
586 guint start_x, im_start_x, low_start_x;
587
588 if(floor(freq_period) != 0.0){
589 start_x = freq_period * floor((double) i / freq_period);
590 }else{
591 start_x = 0;
592 }
593
594 if(floor(im_freq_period) != 0.0){
595 im_start_x = im_freq_period * floor((double) i / im_freq_period);
596 }else{
597 im_start_x = 0;
598 }
599
600 if(floor(low_freq_period) != 0.0){
601 low_start_x = low_freq_period * floor((double) i / low_freq_period);
602 }else{
603 low_start_x = 0;
604 }
605
606 phase = fmod(i, freq_period);
607
608 im_phase = fmod(i, im_freq_period);
609
610 low_phase = fmod(i, low_freq_period);
611
612 new_phase = fmod(i, new_freq_period);
613
614 if(start_x + (guint) floor(new_phase) < buffer_length){
615 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase));
616 }else{
617 if((start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) < buffer_length &&
618 (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) > 0){
619 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period);
620 }else{
621 if(floor(new_phase) < buffer_length){
622 ptr_mix_buffer = mix_buffer + (guint) floor(new_phase);
623 }else{
624 ptr_mix_buffer = mix_buffer + buffer_length - 1;
625 }
626 }
627 }
628
629 if(im_start_x + (guint) floor(new_phase) < buffer_length){
630 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase));
631 }else{
632 if((im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) < buffer_length &&
633 (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) > 0){
634 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period);
635 }else{
636 if(floor(new_phase) < buffer_length){
637 ptr_im_mix_buffer = im_mix_buffer + (guint) floor(new_phase);
638 }else{
639 ptr_im_mix_buffer = im_mix_buffer + buffer_length - 1;
640 }
641 }
642 }
643
644 if(low_start_x + (guint) floor(new_phase) < buffer_length){
645 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase));
646 }else{
647 if((low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) < buffer_length &&
648 (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) > 0){
649 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period);
650 }else{
651 if(floor(new_phase) < buffer_length){
652 ptr_low_mix_buffer = low_mix_buffer + (guint) floor(new_phase);
653 }else{
654 ptr_low_mix_buffer = low_mix_buffer + buffer_length - 1;
655 }
656 }
657 }
658
659 ptr_new_mix_buffer = new_mix_buffer + i;
660
661 /* write new mix buffer */
662 if(ptr_mix_buffer->real != 0.0){
663 new_z = volume * ((1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_im_mix_buffer) / im_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)) + (1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_low_mix_buffer) / low_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)));
664 }else{
665 new_z = 0.0 + I * 0.0;
666 }
667
668 ags_complex_set(ptr_new_mix_buffer,
669 new_z);
670 }
671
672 /* rewrite buffer */
673 for(i = 0; i < buffer_length; i++){
674 ptr_new_mix_buffer = new_mix_buffer + i;
675 ptr_buffer = buffer + i;
676
677 AGS_AUDIO_BUFFER_UTIL_COMPLEX_TO_S16(ptr_new_mix_buffer, ptr_buffer);
678 }
679
680 ags_stream_free(mix_buffer);
681
682 ags_stream_free(im_mix_buffer);
683
684 ags_stream_free(low_mix_buffer);
685
686 ags_stream_free(new_mix_buffer);
687 }
688
689 /**
690 * ags_filter_util_pitch_s24:
691 * @buffer: the audio buffer
692 * @buffer_length: the buffer's length
693 * @samplerate: the samplerate
694 * @base_key: the base key
695 * @tuning: the tuning
696 *
697 * Apply pitch filter.
698 *
699 * Since: 3.0.0
700 */
701 void
ags_filter_util_pitch_s24(gint32 * buffer,guint buffer_length,guint samplerate,gdouble base_key,gdouble tuning)702 ags_filter_util_pitch_s24(gint32 *buffer,
703 guint buffer_length,
704 guint samplerate,
705 gdouble base_key,
706 gdouble tuning)
707 {
708 AgsComplex *ptr_mix_buffer, *ptr_im_mix_buffer, *ptr_low_mix_buffer, *ptr_new_mix_buffer;
709 AgsComplex *mix_buffer, *im_mix_buffer, *low_mix_buffer, *new_mix_buffer;
710 gint32 *ptr_buffer;
711
712 gdouble volume;
713 gdouble im_key, low_key;
714 gdouble base_freq, im_freq, low_freq, new_freq;
715 gdouble offset_factor, im_offset_factor, low_offset_factor, new_offset_factor;
716 gdouble freq_period, im_freq_period, low_freq_period, new_freq_period;
717 gdouble t;
718 guint i;
719
720 if(buffer == NULL){
721 return;
722 }
723
724 /* frequency */
725 base_freq = exp2((base_key) / 12.0) * 440.0;
726
727 im_key = (gdouble) ((gint) floor(tuning / 100.0) % 12);
728
729 if(im_key < 0.0){
730 im_key += 12.0;
731 }
732
733 if(im_key == 0.0){
734 im_key = 1.0;
735 }
736
737 im_freq = exp2((base_key + im_key) / 12.0) * 440.0;
738
739 low_key = base_key - 12.0;
740
741 low_freq = exp2((low_key) / 12.0) * 440.0;
742
743 new_freq = exp2((base_key + (tuning / 100.0)) / 12.0) * 440.0;
744
745 if(base_freq <= 0.0){
746 g_warning("rejecting pitch base freq %f <= 0.0", base_freq);
747
748 return;
749 }
750
751 if(im_freq <= 0.0){
752 g_warning("rejecting pitch intermediate freq %f <= 0.0", im_freq);
753
754 return;
755 }
756
757 if(new_freq <= 0.0){
758 g_warning("rejecting pitch new freq %f <= 0.0", new_freq);
759
760 return;
761 }
762
763 volume = 1.0 / base_freq * new_freq;
764
765 /* get frequency period */
766 freq_period = samplerate / base_freq;
767
768 im_freq_period = samplerate / im_freq;
769 low_freq_period = samplerate / low_freq;
770 new_freq_period = samplerate / new_freq;
771
772 /* get offset factor */
773 offset_factor = 1.0;
774
775 im_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / im_freq);
776 low_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / low_freq);
777 new_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / new_freq);
778
779 /* allocate buffer */
780 mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
781 AGS_SOUNDCARD_COMPLEX);
782
783 im_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
784 AGS_SOUNDCARD_COMPLEX);
785
786 low_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
787 AGS_SOUNDCARD_COMPLEX);
788
789 new_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
790 AGS_SOUNDCARD_COMPLEX);
791
792 /* mix buffer */
793 for(i = 0; i < buffer_length; i++){
794 ptr_mix_buffer = mix_buffer + i;
795
796 /* write mix buffer */
797 AGS_AUDIO_BUFFER_UTIL_S24_TO_COMPLEX(buffer[i], &ptr_mix_buffer);
798 }
799
800 /* im mix buffer */
801 for(i = 0; i < buffer_length; i++){
802 double _Complex z, mix_z, im_z;
803 gdouble phase, im_phase;
804 guint start_x;
805
806 if(floor(freq_period) != 0.0){
807 start_x = freq_period * floor((double) i / freq_period);
808 }else{
809 start_x = 0;
810 }
811
812 im_phase = fmod(i, im_freq_period);
813
814 phase = fmod(i, freq_period);
815
816 if(start_x + (guint) floor(phase) < buffer_length){
817 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
818 }else{
819 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
820 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
821 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
822 }else{
823 if(floor(phase) < buffer_length){
824 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
825 }else{
826 ptr_mix_buffer = mix_buffer + buffer_length - 1;
827 }
828 }
829 }
830
831 ptr_im_mix_buffer = im_mix_buffer + i;
832
833 /* write im mix buffer */
834 z = ags_complex_get(mix_buffer + i);
835 mix_z = ags_complex_get(ptr_mix_buffer);
836
837 t = (im_freq_period / freq_period);
838
839 im_z = (1.0 - t) * z + (t * mix_z);
840
841 ags_complex_set(ptr_im_mix_buffer, im_z);
842 }
843
844 /* low mix buffer */
845 for(i = 0; i < buffer_length; i++){
846 double _Complex z, mix_z, low_z;
847 gdouble phase, low_phase;
848 guint start_x;
849
850 if(floor(freq_period) != 0.0){
851 start_x = freq_period * floor((double) i / freq_period);
852 }else{
853 start_x = 0;
854 }
855
856 low_phase = fmod(i, low_freq_period);
857
858 phase = fmod(i, freq_period);
859
860 if(start_x + (guint) floor(phase) < buffer_length){
861 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
862 }else{
863 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
864 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
865 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
866 }else{
867 if(floor(phase) < buffer_length){
868 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
869 }else{
870 ptr_mix_buffer = mix_buffer + buffer_length - 1;
871 }
872 }
873 }
874
875 ptr_low_mix_buffer = low_mix_buffer + i;
876
877 /* write low mix buffer */
878 z = ags_complex_get(mix_buffer + i);
879 mix_z = ags_complex_get(ptr_mix_buffer);
880
881 t = (low_freq_period / freq_period);
882
883 low_z = (1.0 - t) * z + (t * mix_z);
884
885 ags_complex_set(ptr_low_mix_buffer, low_z);
886 }
887
888 /* new mix buffer */
889 for(i = 0; i < buffer_length; i++){
890 double _Complex new_z;
891 gdouble phase, im_phase, low_phase, new_phase;
892 guint start_x, im_start_x, low_start_x;
893
894 if(floor(freq_period) != 0.0){
895 start_x = freq_period * floor((double) i / freq_period);
896 }else{
897 start_x = 0;
898 }
899
900 if(floor(im_freq_period) != 0.0){
901 im_start_x = im_freq_period * floor((double) i / im_freq_period);
902 }else{
903 im_start_x = 0;
904 }
905
906 if(floor(low_freq_period) != 0.0){
907 low_start_x = low_freq_period * floor((double) i / low_freq_period);
908 }else{
909 low_start_x = 0;
910 }
911
912 phase = fmod(i, freq_period);
913
914 im_phase = fmod(i, im_freq_period);
915
916 low_phase = fmod(i, low_freq_period);
917
918 new_phase = fmod(i, new_freq_period);
919
920 if(start_x + (guint) floor(new_phase) < buffer_length){
921 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase));
922 }else{
923 if((start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) < buffer_length &&
924 (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) > 0){
925 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period);
926 }else{
927 if(floor(new_phase) < buffer_length){
928 ptr_mix_buffer = mix_buffer + (guint) floor(new_phase);
929 }else{
930 ptr_mix_buffer = mix_buffer + buffer_length - 1;
931 }
932 }
933 }
934
935 if(im_start_x + (guint) floor(new_phase) < buffer_length){
936 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase));
937 }else{
938 if((im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) < buffer_length &&
939 (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) > 0){
940 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period);
941 }else{
942 if(floor(new_phase) < buffer_length){
943 ptr_im_mix_buffer = im_mix_buffer + (guint) floor(new_phase);
944 }else{
945 ptr_im_mix_buffer = im_mix_buffer + buffer_length - 1;
946 }
947 }
948 }
949
950 if(low_start_x + (guint) floor(new_phase) < buffer_length){
951 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase));
952 }else{
953 if((low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) < buffer_length &&
954 (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) > 0){
955 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period);
956 }else{
957 if(floor(new_phase) < buffer_length){
958 ptr_low_mix_buffer = low_mix_buffer + (guint) floor(new_phase);
959 }else{
960 ptr_low_mix_buffer = low_mix_buffer + buffer_length - 1;
961 }
962 }
963 }
964
965 ptr_new_mix_buffer = new_mix_buffer + i;
966
967 /* write new mix buffer */
968 if(ptr_mix_buffer->real != 0.0){
969 new_z = volume * ((1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_im_mix_buffer) / im_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)) + (1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_low_mix_buffer) / low_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)));
970 }else{
971 new_z = 0.0 + I * 0.0;
972 }
973
974 ags_complex_set(ptr_new_mix_buffer,
975 new_z);
976 }
977
978 /* rewrite buffer */
979 for(i = 0; i < buffer_length; i++){
980 ptr_new_mix_buffer = new_mix_buffer + i;
981 ptr_buffer = buffer + i;
982
983 AGS_AUDIO_BUFFER_UTIL_COMPLEX_TO_S24(ptr_new_mix_buffer, ptr_buffer);
984 }
985
986 ags_stream_free(mix_buffer);
987
988 ags_stream_free(im_mix_buffer);
989
990 ags_stream_free(low_mix_buffer);
991
992 ags_stream_free(new_mix_buffer);
993 }
994
995 /**
996 * ags_filter_util_pitch_s32:
997 * @buffer: the audio buffer
998 * @buffer_length: the buffer's length
999 * @samplerate: the samplerate
1000 * @base_key: the base key
1001 * @tuning: the tuning
1002 *
1003 * Apply pitch filter.
1004 *
1005 * Since: 3.0.0
1006 */
1007 void
ags_filter_util_pitch_s32(gint32 * buffer,guint buffer_length,guint samplerate,gdouble base_key,gdouble tuning)1008 ags_filter_util_pitch_s32(gint32 *buffer,
1009 guint buffer_length,
1010 guint samplerate,
1011 gdouble base_key,
1012 gdouble tuning)
1013 {
1014 AgsComplex *ptr_mix_buffer, *ptr_im_mix_buffer, *ptr_low_mix_buffer, *ptr_new_mix_buffer;
1015 AgsComplex *mix_buffer, *im_mix_buffer, *low_mix_buffer, *new_mix_buffer;
1016 gint32 *ptr_buffer;
1017
1018 gdouble volume;
1019 gdouble im_key, low_key;
1020 gdouble base_freq, im_freq, low_freq, new_freq;
1021 gdouble offset_factor, im_offset_factor, low_offset_factor, new_offset_factor;
1022 gdouble freq_period, im_freq_period, low_freq_period, new_freq_period;
1023 gdouble t;
1024 guint i;
1025
1026 if(buffer == NULL){
1027 return;
1028 }
1029
1030 /* frequency */
1031 base_freq = exp2((base_key) / 12.0) * 440.0;
1032
1033 im_key = (gdouble) ((gint) floor(tuning / 100.0) % 12);
1034
1035 if(im_key < 0.0){
1036 im_key += 12.0;
1037 }
1038
1039 if(im_key == 0.0){
1040 im_key = 1.0;
1041 }
1042
1043 im_freq = exp2((base_key + im_key) / 12.0) * 440.0;
1044
1045 low_key = base_key - 12.0;
1046
1047 low_freq = exp2((low_key) / 12.0) * 440.0;
1048
1049 new_freq = exp2((base_key + (tuning / 100.0)) / 12.0) * 440.0;
1050
1051 if(base_freq <= 0.0){
1052 g_warning("rejecting pitch base freq %f <= 0.0", base_freq);
1053
1054 return;
1055 }
1056
1057 if(im_freq <= 0.0){
1058 g_warning("rejecting pitch intermediate freq %f <= 0.0", im_freq);
1059
1060 return;
1061 }
1062
1063 if(new_freq <= 0.0){
1064 g_warning("rejecting pitch new freq %f <= 0.0", new_freq);
1065
1066 return;
1067 }
1068
1069 volume = 1.0 / base_freq * new_freq;
1070
1071 /* get frequency period */
1072 freq_period = samplerate / base_freq;
1073
1074 im_freq_period = samplerate / im_freq;
1075 low_freq_period = samplerate / low_freq;
1076 new_freq_period = samplerate / new_freq;
1077
1078 /* get offset factor */
1079 offset_factor = 1.0;
1080
1081 im_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / im_freq);
1082 low_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / low_freq);
1083 new_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / new_freq);
1084
1085 /* allocate buffer */
1086 mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1087 AGS_SOUNDCARD_COMPLEX);
1088
1089 im_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1090 AGS_SOUNDCARD_COMPLEX);
1091
1092 low_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1093 AGS_SOUNDCARD_COMPLEX);
1094
1095 new_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1096 AGS_SOUNDCARD_COMPLEX);
1097
1098 /* mix buffer */
1099 for(i = 0; i < buffer_length; i++){
1100 ptr_mix_buffer = mix_buffer + i;
1101
1102 /* write mix buffer */
1103 AGS_AUDIO_BUFFER_UTIL_S32_TO_COMPLEX(buffer[i], &ptr_mix_buffer);
1104 }
1105
1106 /* im mix buffer */
1107 for(i = 0; i < buffer_length; i++){
1108 double _Complex z, mix_z, im_z;
1109 gdouble phase, im_phase;
1110 guint start_x;
1111
1112 if(floor(freq_period) != 0.0){
1113 start_x = freq_period * floor((double) i / freq_period);
1114 }else{
1115 start_x = 0;
1116 }
1117
1118 im_phase = fmod(i, im_freq_period);
1119
1120 phase = fmod(i, freq_period);
1121
1122 if(start_x + (guint) floor(phase) < buffer_length){
1123 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
1124 }else{
1125 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
1126 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
1127 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
1128 }else{
1129 if(floor(phase) < buffer_length){
1130 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
1131 }else{
1132 ptr_mix_buffer = mix_buffer + buffer_length - 1;
1133 }
1134 }
1135 }
1136
1137 ptr_im_mix_buffer = im_mix_buffer + i;
1138
1139 /* write im mix buffer */
1140 z = ags_complex_get(mix_buffer + i);
1141 mix_z = ags_complex_get(ptr_mix_buffer);
1142
1143 t = (im_freq_period / freq_period);
1144
1145 im_z = (1.0 - t) * z + (t * mix_z);
1146
1147 ags_complex_set(ptr_im_mix_buffer, im_z);
1148 }
1149
1150 /* low mix buffer */
1151 for(i = 0; i < buffer_length; i++){
1152 double _Complex z, mix_z, low_z;
1153 gdouble phase, low_phase;
1154 guint start_x;
1155
1156 if(floor(freq_period) != 0.0){
1157 start_x = freq_period * floor((double) i / freq_period);
1158 }else{
1159 start_x = 0;
1160 }
1161
1162 low_phase = fmod(i, low_freq_period);
1163
1164 phase = fmod(i, freq_period);
1165
1166 if(start_x + (guint) floor(phase) < buffer_length){
1167 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
1168 }else{
1169 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
1170 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
1171 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
1172 }else{
1173 if(floor(phase) < buffer_length){
1174 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
1175 }else{
1176 ptr_mix_buffer = mix_buffer + buffer_length - 1;
1177 }
1178 }
1179 }
1180
1181 ptr_low_mix_buffer = low_mix_buffer + i;
1182
1183 /* write low mix buffer */
1184 z = ags_complex_get(mix_buffer + i);
1185 mix_z = ags_complex_get(ptr_mix_buffer);
1186
1187 t = (low_freq_period / freq_period);
1188
1189 low_z = (1.0 - t) * z + (t * mix_z);
1190
1191 ags_complex_set(ptr_low_mix_buffer, low_z);
1192 }
1193
1194 /* new mix buffer */
1195 for(i = 0; i < buffer_length; i++){
1196 double _Complex new_z;
1197 gdouble phase, im_phase, low_phase, new_phase;
1198 guint start_x, im_start_x, low_start_x;
1199
1200 if(floor(freq_period) != 0.0){
1201 start_x = freq_period * floor((double) i / freq_period);
1202 }else{
1203 start_x = 0;
1204 }
1205
1206 if(floor(im_freq_period) != 0.0){
1207 im_start_x = im_freq_period * floor((double) i / im_freq_period);
1208 }else{
1209 im_start_x = 0;
1210 }
1211
1212 if(floor(low_freq_period) != 0.0){
1213 low_start_x = low_freq_period * floor((double) i / low_freq_period);
1214 }else{
1215 low_start_x = 0;
1216 }
1217
1218 phase = fmod(i, freq_period);
1219
1220 im_phase = fmod(i, im_freq_period);
1221
1222 low_phase = fmod(i, low_freq_period);
1223
1224 new_phase = fmod(i, new_freq_period);
1225
1226 if(start_x + (guint) floor(new_phase) < buffer_length){
1227 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase));
1228 }else{
1229 if((start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) < buffer_length &&
1230 (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) > 0){
1231 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period);
1232 }else{
1233 if(floor(new_phase) < buffer_length){
1234 ptr_mix_buffer = mix_buffer + (guint) floor(new_phase);
1235 }else{
1236 ptr_mix_buffer = mix_buffer + buffer_length - 1;
1237 }
1238 }
1239 }
1240
1241 if(im_start_x + (guint) floor(new_phase) < buffer_length){
1242 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase));
1243 }else{
1244 if((im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) < buffer_length &&
1245 (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) > 0){
1246 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period);
1247 }else{
1248 if(floor(new_phase) < buffer_length){
1249 ptr_im_mix_buffer = im_mix_buffer + (guint) floor(new_phase);
1250 }else{
1251 ptr_im_mix_buffer = im_mix_buffer + buffer_length - 1;
1252 }
1253 }
1254 }
1255
1256 if(low_start_x + (guint) floor(new_phase) < buffer_length){
1257 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase));
1258 }else{
1259 if((low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) < buffer_length &&
1260 (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) > 0){
1261 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period);
1262 }else{
1263 if(floor(new_phase) < buffer_length){
1264 ptr_low_mix_buffer = low_mix_buffer + (guint) floor(new_phase);
1265 }else{
1266 ptr_low_mix_buffer = low_mix_buffer + buffer_length - 1;
1267 }
1268 }
1269 }
1270
1271 ptr_new_mix_buffer = new_mix_buffer + i;
1272
1273 /* write new mix buffer */
1274 if(ptr_mix_buffer->real != 0.0){
1275 new_z = volume * ((1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_im_mix_buffer) / im_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)) + (1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_low_mix_buffer) / low_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)));
1276 }else{
1277 new_z = 0.0 + I * 0.0;
1278 }
1279
1280 ags_complex_set(ptr_new_mix_buffer,
1281 new_z);
1282 }
1283
1284 /* rewrite buffer */
1285 for(i = 0; i < buffer_length; i++){
1286 ptr_new_mix_buffer = new_mix_buffer + i;
1287 ptr_buffer = buffer + i;
1288
1289 AGS_AUDIO_BUFFER_UTIL_COMPLEX_TO_S32(ptr_new_mix_buffer, ptr_buffer);
1290 }
1291
1292 ags_stream_free(mix_buffer);
1293
1294 ags_stream_free(im_mix_buffer);
1295
1296 ags_stream_free(low_mix_buffer);
1297
1298 ags_stream_free(new_mix_buffer);
1299 }
1300
1301 /**
1302 * ags_filter_util_pitch_s64:
1303 * @buffer: the audio buffer
1304 * @buffer_length: the buffer's length
1305 * @samplerate: the samplerate
1306 * @base_key: the base key
1307 * @tuning: the tuning
1308 *
1309 * Apply pitch filter.
1310 *
1311 * Since: 3.0.0
1312 */
1313 void
ags_filter_util_pitch_s64(gint64 * buffer,guint buffer_length,guint samplerate,gdouble base_key,gdouble tuning)1314 ags_filter_util_pitch_s64(gint64 *buffer,
1315 guint buffer_length,
1316 guint samplerate,
1317 gdouble base_key,
1318 gdouble tuning)
1319 {
1320 AgsComplex *ptr_mix_buffer, *ptr_im_mix_buffer, *ptr_low_mix_buffer, *ptr_new_mix_buffer;
1321 AgsComplex *mix_buffer, *im_mix_buffer, *low_mix_buffer, *new_mix_buffer;
1322 gint64 *ptr_buffer;
1323
1324 gdouble volume;
1325 gdouble im_key, low_key;
1326 gdouble base_freq, im_freq, low_freq, new_freq;
1327 gdouble offset_factor, im_offset_factor, low_offset_factor, new_offset_factor;
1328 gdouble freq_period, im_freq_period, low_freq_period, new_freq_period;
1329 gdouble t;
1330 guint i;
1331
1332 if(buffer == NULL){
1333 return;
1334 }
1335
1336 /* frequency */
1337 base_freq = exp2((base_key) / 12.0) * 440.0;
1338
1339 im_key = (gdouble) ((gint) floor(tuning / 100.0) % 12);
1340
1341 if(im_key < 0.0){
1342 im_key += 12.0;
1343 }
1344
1345 if(im_key == 0.0){
1346 im_key = 1.0;
1347 }
1348
1349 im_freq = exp2((base_key + im_key) / 12.0) * 440.0;
1350
1351 low_key = base_key - 12.0;
1352
1353 low_freq = exp2((low_key) / 12.0) * 440.0;
1354
1355 new_freq = exp2((base_key + (tuning / 100.0)) / 12.0) * 440.0;
1356
1357 if(base_freq <= 0.0){
1358 g_warning("rejecting pitch base freq %f <= 0.0", base_freq);
1359
1360 return;
1361 }
1362
1363 if(im_freq <= 0.0){
1364 g_warning("rejecting pitch intermediate freq %f <= 0.0", im_freq);
1365
1366 return;
1367 }
1368
1369 if(new_freq <= 0.0){
1370 g_warning("rejecting pitch new freq %f <= 0.0", new_freq);
1371
1372 return;
1373 }
1374
1375 volume = 1.0 / base_freq * new_freq;
1376
1377 /* get frequency period */
1378 freq_period = samplerate / base_freq;
1379
1380 im_freq_period = samplerate / im_freq;
1381 low_freq_period = samplerate / low_freq;
1382 new_freq_period = samplerate / new_freq;
1383
1384 /* get offset factor */
1385 offset_factor = 1.0;
1386
1387 im_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / im_freq);
1388 low_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / low_freq);
1389 new_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / new_freq);
1390
1391 /* allocate buffer */
1392 mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1393 AGS_SOUNDCARD_COMPLEX);
1394
1395 im_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1396 AGS_SOUNDCARD_COMPLEX);
1397
1398 low_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1399 AGS_SOUNDCARD_COMPLEX);
1400
1401 new_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1402 AGS_SOUNDCARD_COMPLEX);
1403
1404 /* mix buffer */
1405 for(i = 0; i < buffer_length; i++){
1406 ptr_mix_buffer = mix_buffer + i;
1407
1408 /* write mix buffer */
1409 AGS_AUDIO_BUFFER_UTIL_S64_TO_COMPLEX(buffer[i], &ptr_mix_buffer);
1410 }
1411
1412 /* im mix buffer */
1413 for(i = 0; i < buffer_length; i++){
1414 double _Complex z, mix_z, im_z;
1415 gdouble phase, im_phase;
1416 guint start_x;
1417
1418 if(floor(freq_period) != 0.0){
1419 start_x = freq_period * floor((double) i / freq_period);
1420 }else{
1421 start_x = 0;
1422 }
1423
1424 im_phase = fmod(i, im_freq_period);
1425
1426 phase = fmod(i, freq_period);
1427
1428 if(start_x + (guint) floor(phase) < buffer_length){
1429 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
1430 }else{
1431 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
1432 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
1433 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
1434 }else{
1435 if(floor(phase) < buffer_length){
1436 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
1437 }else{
1438 ptr_mix_buffer = mix_buffer + buffer_length - 1;
1439 }
1440 }
1441 }
1442
1443 ptr_im_mix_buffer = im_mix_buffer + i;
1444
1445 /* write im mix buffer */
1446 z = ags_complex_get(mix_buffer + i);
1447 mix_z = ags_complex_get(ptr_mix_buffer);
1448
1449 t = (im_freq_period / freq_period);
1450
1451 im_z = (1.0 - t) * z + (t * mix_z);
1452
1453 ags_complex_set(ptr_im_mix_buffer, im_z);
1454 }
1455
1456 /* low mix buffer */
1457 for(i = 0; i < buffer_length; i++){
1458 double _Complex z, mix_z, low_z;
1459 gdouble phase, low_phase;
1460 guint start_x;
1461
1462 if(floor(freq_period) != 0.0){
1463 start_x = freq_period * floor((double) i / freq_period);
1464 }else{
1465 start_x = 0;
1466 }
1467
1468 low_phase = fmod(i, low_freq_period);
1469
1470 phase = fmod(i, freq_period);
1471
1472 if(start_x + (guint) floor(phase) < buffer_length){
1473 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
1474 }else{
1475 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
1476 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
1477 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
1478 }else{
1479 if(floor(phase) < buffer_length){
1480 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
1481 }else{
1482 ptr_mix_buffer = mix_buffer + buffer_length - 1;
1483 }
1484 }
1485 }
1486
1487 ptr_low_mix_buffer = low_mix_buffer + i;
1488
1489 /* write low mix buffer */
1490 z = ags_complex_get(mix_buffer + i);
1491 mix_z = ags_complex_get(ptr_mix_buffer);
1492
1493 t = (low_freq_period / freq_period);
1494
1495 low_z = (1.0 - t) * z + (t * mix_z);
1496
1497 ags_complex_set(ptr_low_mix_buffer, low_z);
1498 }
1499
1500 /* new mix buffer */
1501 for(i = 0; i < buffer_length; i++){
1502 double _Complex new_z;
1503 gdouble phase, im_phase, low_phase, new_phase;
1504 guint start_x, im_start_x, low_start_x;
1505
1506 if(floor(freq_period) != 0.0){
1507 start_x = freq_period * floor((double) i / freq_period);
1508 }else{
1509 start_x = 0;
1510 }
1511
1512 if(floor(im_freq_period) != 0.0){
1513 im_start_x = im_freq_period * floor((double) i / im_freq_period);
1514 }else{
1515 im_start_x = 0;
1516 }
1517
1518 if(floor(low_freq_period) != 0.0){
1519 low_start_x = low_freq_period * floor((double) i / low_freq_period);
1520 }else{
1521 low_start_x = 0;
1522 }
1523
1524 phase = fmod(i, freq_period);
1525
1526 im_phase = fmod(i, im_freq_period);
1527
1528 low_phase = fmod(i, low_freq_period);
1529
1530 new_phase = fmod(i, new_freq_period);
1531
1532 if(start_x + (guint) floor(new_phase) < buffer_length){
1533 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase));
1534 }else{
1535 if((start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) < buffer_length &&
1536 (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) > 0){
1537 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period);
1538 }else{
1539 if(floor(new_phase) < buffer_length){
1540 ptr_mix_buffer = mix_buffer + (guint) floor(new_phase);
1541 }else{
1542 ptr_mix_buffer = mix_buffer + buffer_length - 1;
1543 }
1544 }
1545 }
1546
1547 if(im_start_x + (guint) floor(new_phase) < buffer_length){
1548 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase));
1549 }else{
1550 if((im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) < buffer_length &&
1551 (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) > 0){
1552 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period);
1553 }else{
1554 if(floor(new_phase) < buffer_length){
1555 ptr_im_mix_buffer = im_mix_buffer + (guint) floor(new_phase);
1556 }else{
1557 ptr_im_mix_buffer = im_mix_buffer + buffer_length - 1;
1558 }
1559 }
1560 }
1561
1562 if(low_start_x + (guint) floor(new_phase) < buffer_length){
1563 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase));
1564 }else{
1565 if((low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) < buffer_length &&
1566 (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) > 0){
1567 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period);
1568 }else{
1569 if(floor(new_phase) < buffer_length){
1570 ptr_low_mix_buffer = low_mix_buffer + (guint) floor(new_phase);
1571 }else{
1572 ptr_low_mix_buffer = low_mix_buffer + buffer_length - 1;
1573 }
1574 }
1575 }
1576
1577 ptr_new_mix_buffer = new_mix_buffer + i;
1578
1579 /* write new mix buffer */
1580 if(ptr_mix_buffer->real != 0.0){
1581 new_z = volume * ((1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_im_mix_buffer) / im_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)) + (1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_low_mix_buffer) / low_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)));
1582 }else{
1583 new_z = 0.0 + I * 0.0;
1584 }
1585
1586 ags_complex_set(ptr_new_mix_buffer,
1587 new_z);
1588 }
1589
1590 /* rewrite buffer */
1591 for(i = 0; i < buffer_length; i++){
1592 ptr_new_mix_buffer = new_mix_buffer + i;
1593 ptr_buffer = buffer + i;
1594
1595 AGS_AUDIO_BUFFER_UTIL_COMPLEX_TO_S64(ptr_new_mix_buffer, ptr_buffer);
1596 }
1597
1598 ags_stream_free(mix_buffer);
1599
1600 ags_stream_free(im_mix_buffer);
1601
1602 ags_stream_free(low_mix_buffer);
1603
1604 ags_stream_free(new_mix_buffer);
1605 }
1606
1607 /**
1608 * ags_filter_util_pitch_float:
1609 * @buffer: the audio buffer
1610 * @buffer_length: the buffer's length
1611 * @samplerate: the samplerate
1612 * @base_key: the base key
1613 * @tuning: the tuning
1614 *
1615 * Apply pitch filter.
1616 *
1617 * Since: 3.0.0
1618 */
1619 void
ags_filter_util_pitch_float(gfloat * buffer,guint buffer_length,guint samplerate,gdouble base_key,gdouble tuning)1620 ags_filter_util_pitch_float(gfloat *buffer,
1621 guint buffer_length,
1622 guint samplerate,
1623 gdouble base_key,
1624 gdouble tuning)
1625 {
1626 AgsComplex *ptr_mix_buffer, *ptr_im_mix_buffer, *ptr_low_mix_buffer, *ptr_new_mix_buffer;
1627 AgsComplex *mix_buffer, *im_mix_buffer, *low_mix_buffer, *new_mix_buffer;
1628 gfloat *ptr_buffer;
1629
1630 gdouble volume;
1631 gdouble im_key, low_key;
1632 gdouble base_freq, im_freq, low_freq, new_freq;
1633 gdouble offset_factor, im_offset_factor, low_offset_factor, new_offset_factor;
1634 gdouble freq_period, im_freq_period, low_freq_period, new_freq_period;
1635 gdouble t;
1636 guint i;
1637
1638 if(buffer == NULL){
1639 return;
1640 }
1641
1642 /* frequency */
1643 base_freq = exp2((base_key) / 12.0) * 440.0;
1644
1645 im_key = (gdouble) ((gint) floor(tuning / 100.0) % 12);
1646
1647 if(im_key < 0.0){
1648 im_key += 12.0;
1649 }
1650
1651 if(im_key == 0.0){
1652 im_key = 1.0;
1653 }
1654
1655 im_freq = exp2((base_key + im_key) / 12.0) * 440.0;
1656
1657 low_key = base_key - 12.0;
1658
1659 low_freq = exp2((low_key) / 12.0) * 440.0;
1660
1661 new_freq = exp2((base_key + (tuning / 100.0)) / 12.0) * 440.0;
1662
1663 if(base_freq <= 0.0){
1664 g_warning("rejecting pitch base freq %f <= 0.0", base_freq);
1665
1666 return;
1667 }
1668
1669 if(im_freq <= 0.0){
1670 g_warning("rejecting pitch intermediate freq %f <= 0.0", im_freq);
1671
1672 return;
1673 }
1674
1675 if(new_freq <= 0.0){
1676 g_warning("rejecting pitch new freq %f <= 0.0", new_freq);
1677
1678 return;
1679 }
1680
1681 volume = 1.0 / base_freq * new_freq;
1682
1683 /* get frequency period */
1684 freq_period = samplerate / base_freq;
1685
1686 im_freq_period = samplerate / im_freq;
1687 low_freq_period = samplerate / low_freq;
1688 new_freq_period = samplerate / new_freq;
1689
1690 /* get offset factor */
1691 offset_factor = 1.0;
1692
1693 im_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / im_freq);
1694 low_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / low_freq);
1695 new_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / new_freq);
1696
1697 /* allocate buffer */
1698 mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1699 AGS_SOUNDCARD_COMPLEX);
1700
1701 im_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1702 AGS_SOUNDCARD_COMPLEX);
1703
1704 low_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1705 AGS_SOUNDCARD_COMPLEX);
1706
1707 new_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
1708 AGS_SOUNDCARD_COMPLEX);
1709
1710 /* mix buffer */
1711 for(i = 0; i < buffer_length; i++){
1712 ptr_mix_buffer = mix_buffer + i;
1713
1714 /* write mix buffer */
1715 AGS_AUDIO_BUFFER_UTIL_FLOAT_TO_COMPLEX(buffer[i], &ptr_mix_buffer);
1716 }
1717
1718 /* im mix buffer */
1719 for(i = 0; i < buffer_length; i++){
1720 double _Complex z, mix_z, im_z;
1721 gdouble phase, im_phase;
1722 guint start_x;
1723
1724 if(floor(freq_period) != 0.0){
1725 start_x = freq_period * floor((double) i / freq_period);
1726 }else{
1727 start_x = 0;
1728 }
1729
1730 im_phase = fmod(i, im_freq_period);
1731
1732 phase = fmod(i, freq_period);
1733
1734 if(start_x + (guint) floor(phase) < buffer_length){
1735 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
1736 }else{
1737 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
1738 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
1739 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
1740 }else{
1741 if(floor(phase) < buffer_length){
1742 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
1743 }else{
1744 ptr_mix_buffer = mix_buffer + buffer_length - 1;
1745 }
1746 }
1747 }
1748
1749 ptr_im_mix_buffer = im_mix_buffer + i;
1750
1751 /* write im mix buffer */
1752 z = ags_complex_get(mix_buffer + i);
1753 mix_z = ags_complex_get(ptr_mix_buffer);
1754
1755 t = (im_freq_period / freq_period);
1756
1757 im_z = (1.0 - t) * z + (t * mix_z);
1758
1759 ags_complex_set(ptr_im_mix_buffer, im_z);
1760 }
1761
1762 /* low mix buffer */
1763 for(i = 0; i < buffer_length; i++){
1764 double _Complex z, mix_z, low_z;
1765 gdouble phase, low_phase;
1766 guint start_x;
1767
1768 if(floor(freq_period) != 0.0){
1769 start_x = freq_period * floor((double) i / freq_period);
1770 }else{
1771 start_x = 0;
1772 }
1773
1774 low_phase = fmod(i, low_freq_period);
1775
1776 phase = fmod(i, freq_period);
1777
1778 if(start_x + (guint) floor(phase) < buffer_length){
1779 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
1780 }else{
1781 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
1782 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
1783 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
1784 }else{
1785 if(floor(phase) < buffer_length){
1786 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
1787 }else{
1788 ptr_mix_buffer = mix_buffer + buffer_length - 1;
1789 }
1790 }
1791 }
1792
1793 ptr_low_mix_buffer = low_mix_buffer + i;
1794
1795 /* write low mix buffer */
1796 z = ags_complex_get(mix_buffer + i);
1797 mix_z = ags_complex_get(ptr_mix_buffer);
1798
1799 t = (low_freq_period / freq_period);
1800
1801 low_z = (1.0 - t) * z + (t * mix_z);
1802
1803 ags_complex_set(ptr_low_mix_buffer, low_z);
1804 }
1805
1806 /* new mix buffer */
1807 for(i = 0; i < buffer_length; i++){
1808 double _Complex new_z;
1809 gdouble phase, im_phase, low_phase, new_phase;
1810 guint start_x, im_start_x, low_start_x;
1811
1812 if(floor(freq_period) != 0.0){
1813 start_x = freq_period * floor((double) i / freq_period);
1814 }else{
1815 start_x = 0;
1816 }
1817
1818 if(floor(im_freq_period) != 0.0){
1819 im_start_x = im_freq_period * floor((double) i / im_freq_period);
1820 }else{
1821 im_start_x = 0;
1822 }
1823
1824 if(floor(low_freq_period) != 0.0){
1825 low_start_x = low_freq_period * floor((double) i / low_freq_period);
1826 }else{
1827 low_start_x = 0;
1828 }
1829
1830 phase = fmod(i, freq_period);
1831
1832 im_phase = fmod(i, im_freq_period);
1833
1834 low_phase = fmod(i, low_freq_period);
1835
1836 new_phase = fmod(i, new_freq_period);
1837
1838 if(start_x + (guint) floor(new_phase) < buffer_length){
1839 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase));
1840 }else{
1841 if((start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) < buffer_length &&
1842 (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) > 0){
1843 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period);
1844 }else{
1845 if(floor(new_phase) < buffer_length){
1846 ptr_mix_buffer = mix_buffer + (guint) floor(new_phase);
1847 }else{
1848 ptr_mix_buffer = mix_buffer + buffer_length - 1;
1849 }
1850 }
1851 }
1852
1853 if(im_start_x + (guint) floor(new_phase) < buffer_length){
1854 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase));
1855 }else{
1856 if((im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) < buffer_length &&
1857 (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) > 0){
1858 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period);
1859 }else{
1860 if(floor(new_phase) < buffer_length){
1861 ptr_im_mix_buffer = im_mix_buffer + (guint) floor(new_phase);
1862 }else{
1863 ptr_im_mix_buffer = im_mix_buffer + buffer_length - 1;
1864 }
1865 }
1866 }
1867
1868 if(low_start_x + (guint) floor(new_phase) < buffer_length){
1869 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase));
1870 }else{
1871 if((low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) < buffer_length &&
1872 (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) > 0){
1873 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period);
1874 }else{
1875 if(floor(new_phase) < buffer_length){
1876 ptr_low_mix_buffer = low_mix_buffer + (guint) floor(new_phase);
1877 }else{
1878 ptr_low_mix_buffer = low_mix_buffer + buffer_length - 1;
1879 }
1880 }
1881 }
1882
1883 ptr_new_mix_buffer = new_mix_buffer + i;
1884
1885 /* write new mix buffer */
1886 if(ptr_mix_buffer->real != 0.0){
1887 new_z = volume * ((1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_im_mix_buffer) / im_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)) + (1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_low_mix_buffer) / low_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)));
1888 }else{
1889 new_z = 0.0 + I * 0.0;
1890 }
1891
1892 ags_complex_set(ptr_new_mix_buffer,
1893 new_z);
1894 }
1895
1896 /* rewrite buffer */
1897 for(i = 0; i < buffer_length; i++){
1898 ptr_new_mix_buffer = new_mix_buffer + i;
1899 ptr_buffer = buffer + i;
1900
1901 AGS_AUDIO_BUFFER_UTIL_COMPLEX_TO_FLOAT(ptr_new_mix_buffer, ptr_buffer);
1902 }
1903
1904 ags_stream_free(mix_buffer);
1905
1906 ags_stream_free(im_mix_buffer);
1907
1908 ags_stream_free(low_mix_buffer);
1909
1910 ags_stream_free(new_mix_buffer);
1911 }
1912
1913 /**
1914 * ags_filter_util_pitch_double:
1915 * @buffer: the audio buffer
1916 * @buffer_length: the buffer's length
1917 * @samplerate: the samplerate
1918 * @base_key: the base key
1919 * @tuning: the tuning
1920 *
1921 * Apply pitch filter.
1922 *
1923 * Since: 3.0.0
1924 */
1925 void
ags_filter_util_pitch_double(gdouble * buffer,guint buffer_length,guint samplerate,gdouble base_key,gdouble tuning)1926 ags_filter_util_pitch_double(gdouble *buffer,
1927 guint buffer_length,
1928 guint samplerate,
1929 gdouble base_key,
1930 gdouble tuning)
1931 {
1932 AgsComplex *ptr_mix_buffer, *ptr_im_mix_buffer, *ptr_low_mix_buffer, *ptr_new_mix_buffer;
1933 AgsComplex *mix_buffer, *im_mix_buffer, *low_mix_buffer, *new_mix_buffer;
1934 gdouble *ptr_buffer;
1935
1936 gdouble volume;
1937 gdouble im_key, low_key;
1938 gdouble base_freq, im_freq, low_freq, new_freq;
1939 gdouble offset_factor, im_offset_factor, low_offset_factor, new_offset_factor;
1940 gdouble freq_period, im_freq_period, low_freq_period, new_freq_period;
1941 gdouble t;
1942 guint i;
1943
1944 if(buffer == NULL){
1945 return;
1946 }
1947
1948 /* frequency */
1949 base_freq = exp2((base_key) / 12.0) * 440.0;
1950
1951 im_key = (gdouble) ((gint) floor(tuning / 100.0) % 12);
1952
1953 if(im_key < 0.0){
1954 im_key += 12.0;
1955 }
1956
1957 if(im_key == 0.0){
1958 im_key = 1.0;
1959 }
1960
1961 im_freq = exp2((base_key + im_key) / 12.0) * 440.0;
1962
1963 low_key = base_key - 12.0;
1964
1965 low_freq = exp2((low_key) / 12.0) * 440.0;
1966
1967 new_freq = exp2((base_key + (tuning / 100.0)) / 12.0) * 440.0;
1968
1969 if(base_freq <= 0.0){
1970 g_warning("rejecting pitch base freq %f <= 0.0", base_freq);
1971
1972 return;
1973 }
1974
1975 if(im_freq <= 0.0){
1976 g_warning("rejecting pitch intermediate freq %f <= 0.0", im_freq);
1977
1978 return;
1979 }
1980
1981 if(new_freq <= 0.0){
1982 g_warning("rejecting pitch new freq %f <= 0.0", new_freq);
1983
1984 return;
1985 }
1986
1987 volume = 1.0 / base_freq * new_freq;
1988
1989 /* get frequency period */
1990 freq_period = samplerate / base_freq;
1991
1992 im_freq_period = samplerate / im_freq;
1993 low_freq_period = samplerate / low_freq;
1994 new_freq_period = samplerate / new_freq;
1995
1996 /* get offset factor */
1997 offset_factor = 1.0;
1998
1999 im_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / im_freq);
2000 low_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / low_freq);
2001 new_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / new_freq);
2002
2003 /* allocate buffer */
2004 mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
2005 AGS_SOUNDCARD_COMPLEX);
2006
2007 im_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
2008 AGS_SOUNDCARD_COMPLEX);
2009
2010 low_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
2011 AGS_SOUNDCARD_COMPLEX);
2012
2013 new_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
2014 AGS_SOUNDCARD_COMPLEX);
2015
2016 /* mix buffer */
2017 for(i = 0; i < buffer_length; i++){
2018 ptr_mix_buffer = mix_buffer + i;
2019
2020 /* write mix buffer */
2021 AGS_AUDIO_BUFFER_UTIL_DOUBLE_TO_COMPLEX(buffer[i], &ptr_mix_buffer);
2022 }
2023
2024 /* im mix buffer */
2025 for(i = 0; i < buffer_length; i++){
2026 double _Complex z, mix_z, im_z;
2027 gdouble phase, im_phase;
2028 guint start_x;
2029
2030 if(floor(freq_period) != 0.0){
2031 start_x = freq_period * floor((double) i / freq_period);
2032 }else{
2033 start_x = 0;
2034 }
2035
2036 im_phase = fmod(i, im_freq_period);
2037
2038 phase = fmod(i, freq_period);
2039
2040 if(start_x + (guint) floor(phase) < buffer_length){
2041 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
2042 }else{
2043 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
2044 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
2045 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
2046 }else{
2047 if(floor(phase) < buffer_length){
2048 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
2049 }else{
2050 ptr_mix_buffer = mix_buffer + buffer_length - 1;
2051 }
2052 }
2053 }
2054
2055 ptr_im_mix_buffer = im_mix_buffer + i;
2056
2057 /* write im mix buffer */
2058 z = ags_complex_get(mix_buffer + i);
2059 mix_z = ags_complex_get(ptr_mix_buffer);
2060
2061 t = (im_freq_period / freq_period);
2062
2063 im_z = (1.0 - t) * z + (t * mix_z);
2064
2065 ags_complex_set(ptr_im_mix_buffer, im_z);
2066 }
2067
2068 /* low mix buffer */
2069 for(i = 0; i < buffer_length; i++){
2070 double _Complex z, mix_z, low_z;
2071 gdouble phase, low_phase;
2072 guint start_x;
2073
2074 if(floor(freq_period) != 0.0){
2075 start_x = freq_period * floor((double) i / freq_period);
2076 }else{
2077 start_x = 0;
2078 }
2079
2080 low_phase = fmod(i, low_freq_period);
2081
2082 phase = fmod(i, freq_period);
2083
2084 if(start_x + (guint) floor(phase) < buffer_length){
2085 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
2086 }else{
2087 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
2088 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
2089 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
2090 }else{
2091 if(floor(phase) < buffer_length){
2092 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
2093 }else{
2094 ptr_mix_buffer = mix_buffer + buffer_length - 1;
2095 }
2096 }
2097 }
2098
2099 ptr_low_mix_buffer = low_mix_buffer + i;
2100
2101 /* write low mix buffer */
2102 z = ags_complex_get(mix_buffer + i);
2103 mix_z = ags_complex_get(ptr_mix_buffer);
2104
2105 t = (low_freq_period / freq_period);
2106
2107 low_z = (1.0 - t) * z + (t * mix_z);
2108
2109 ags_complex_set(ptr_low_mix_buffer, low_z);
2110 }
2111
2112 /* new mix buffer */
2113 for(i = 0; i < buffer_length; i++){
2114 double _Complex new_z;
2115 gdouble phase, im_phase, low_phase, new_phase;
2116 guint start_x, im_start_x, low_start_x;
2117
2118 if(floor(freq_period) != 0.0){
2119 start_x = freq_period * floor((double) i / freq_period);
2120 }else{
2121 start_x = 0;
2122 }
2123
2124 if(floor(im_freq_period) != 0.0){
2125 im_start_x = im_freq_period * floor((double) i / im_freq_period);
2126 }else{
2127 im_start_x = 0;
2128 }
2129
2130 if(floor(low_freq_period) != 0.0){
2131 low_start_x = low_freq_period * floor((double) i / low_freq_period);
2132 }else{
2133 low_start_x = 0;
2134 }
2135
2136 phase = fmod(i, freq_period);
2137
2138 im_phase = fmod(i, im_freq_period);
2139
2140 low_phase = fmod(i, low_freq_period);
2141
2142 new_phase = fmod(i, new_freq_period);
2143
2144 if(start_x + (guint) floor(new_phase) < buffer_length){
2145 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase));
2146 }else{
2147 if((start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) < buffer_length &&
2148 (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) > 0){
2149 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period);
2150 }else{
2151 if(floor(new_phase) < buffer_length){
2152 ptr_mix_buffer = mix_buffer + (guint) floor(new_phase);
2153 }else{
2154 ptr_mix_buffer = mix_buffer + buffer_length - 1;
2155 }
2156 }
2157 }
2158
2159 if(im_start_x + (guint) floor(new_phase) < buffer_length){
2160 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase));
2161 }else{
2162 if((im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) < buffer_length &&
2163 (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) > 0){
2164 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period);
2165 }else{
2166 if(floor(new_phase) < buffer_length){
2167 ptr_im_mix_buffer = im_mix_buffer + (guint) floor(new_phase);
2168 }else{
2169 ptr_im_mix_buffer = im_mix_buffer + buffer_length - 1;
2170 }
2171 }
2172 }
2173
2174 if(low_start_x + (guint) floor(new_phase) < buffer_length){
2175 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase));
2176 }else{
2177 if((low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) < buffer_length &&
2178 (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) > 0){
2179 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period);
2180 }else{
2181 if(floor(new_phase) < buffer_length){
2182 ptr_low_mix_buffer = low_mix_buffer + (guint) floor(new_phase);
2183 }else{
2184 ptr_low_mix_buffer = low_mix_buffer + buffer_length - 1;
2185 }
2186 }
2187 }
2188
2189 ptr_new_mix_buffer = new_mix_buffer + i;
2190
2191 /* write new mix buffer */
2192 if(ptr_mix_buffer->real != 0.0){
2193 new_z = volume * ((1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_im_mix_buffer) / im_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)) + (1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_low_mix_buffer) / low_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)));
2194 }else{
2195 new_z = 0.0 + I * 0.0;
2196 }
2197
2198 ags_complex_set(ptr_new_mix_buffer,
2199 new_z);
2200 }
2201
2202 /* rewrite buffer */
2203 for(i = 0; i < buffer_length; i++){
2204 ptr_new_mix_buffer = new_mix_buffer + i;
2205 ptr_buffer = buffer + i;
2206
2207 AGS_AUDIO_BUFFER_UTIL_COMPLEX_TO_DOUBLE(ptr_new_mix_buffer, ptr_buffer);
2208 }
2209
2210 ags_stream_free(mix_buffer);
2211
2212 ags_stream_free(im_mix_buffer);
2213
2214 ags_stream_free(low_mix_buffer);
2215
2216 ags_stream_free(new_mix_buffer);
2217 }
2218
2219 /**
2220 * ags_filter_util_pitch_complex:
2221 * @buffer: the audio buffer
2222 * @buffer_length: the buffer's length
2223 * @samplerate: the samplerate
2224 * @base_key: the base key
2225 * @tuning: the tuning
2226 *
2227 * Apply pitch filter.
2228 *
2229 * Since: 3.0.0
2230 */
2231 void
ags_filter_util_pitch_complex(AgsComplex * buffer,guint buffer_length,guint samplerate,gdouble base_key,gdouble tuning)2232 ags_filter_util_pitch_complex(AgsComplex *buffer,
2233 guint buffer_length,
2234 guint samplerate,
2235 gdouble base_key,
2236 gdouble tuning)
2237 {
2238 AgsComplex *ptr_mix_buffer, *ptr_im_mix_buffer, *ptr_low_mix_buffer, *ptr_new_mix_buffer;
2239 AgsComplex *mix_buffer, *im_mix_buffer, *low_mix_buffer, *new_mix_buffer;
2240 AgsComplex *ptr_buffer;
2241
2242 gdouble volume;
2243 gdouble im_key, low_key;
2244 gdouble base_freq, im_freq, low_freq, new_freq;
2245 gdouble offset_factor, im_offset_factor, low_offset_factor, new_offset_factor;
2246 gdouble freq_period, im_freq_period, low_freq_period, new_freq_period;
2247 gdouble t;
2248 guint i;
2249
2250 if(buffer == NULL){
2251 return;
2252 }
2253
2254 /* frequency */
2255 base_freq = exp2((base_key) / 12.0) * 440.0;
2256
2257 im_key = (gdouble) ((gint) floor(tuning / 100.0) % 12);
2258
2259 if(im_key < 0.0){
2260 im_key += 12.0;
2261 }
2262
2263 if(im_key == 0.0){
2264 im_key = 1.0;
2265 }
2266
2267 im_freq = exp2((base_key + im_key) / 12.0) * 440.0;
2268
2269 low_key = base_key - 12.0;
2270
2271 low_freq = exp2((low_key) / 12.0) * 440.0;
2272
2273 new_freq = exp2((base_key + (tuning / 100.0)) / 12.0) * 440.0;
2274
2275 if(base_freq <= 0.0){
2276 g_warning("rejecting pitch base freq %f <= 0.0", base_freq);
2277
2278 return;
2279 }
2280
2281 if(im_freq <= 0.0){
2282 g_warning("rejecting pitch intermediate freq %f <= 0.0", im_freq);
2283
2284 return;
2285 }
2286
2287 if(new_freq <= 0.0){
2288 g_warning("rejecting pitch new freq %f <= 0.0", new_freq);
2289
2290 return;
2291 }
2292
2293 volume = 1.0 / base_freq * new_freq;
2294
2295 /* get frequency period */
2296 freq_period = samplerate / base_freq;
2297
2298 im_freq_period = samplerate / im_freq;
2299 low_freq_period = samplerate / low_freq;
2300 new_freq_period = samplerate / new_freq;
2301
2302 /* get offset factor */
2303 offset_factor = 1.0;
2304
2305 im_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / im_freq);
2306 low_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / low_freq);
2307 new_offset_factor = 1.0 / (samplerate / base_freq) * (samplerate / new_freq);
2308
2309 /* allocate buffer */
2310 mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
2311 AGS_SOUNDCARD_COMPLEX);
2312
2313 im_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
2314 AGS_SOUNDCARD_COMPLEX);
2315
2316 low_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
2317 AGS_SOUNDCARD_COMPLEX);
2318
2319 new_mix_buffer = (AgsComplex *) ags_stream_alloc(buffer_length,
2320 AGS_SOUNDCARD_COMPLEX);
2321
2322 /* mix buffer */
2323 for(i = 0; i < buffer_length; i++){
2324 ptr_mix_buffer = mix_buffer + i;
2325
2326 /* write mix buffer */
2327 ags_complex_set(ptr_mix_buffer, ags_complex_get(buffer + i));
2328 }
2329
2330 /* im mix buffer */
2331 for(i = 0; i < buffer_length; i++){
2332 double _Complex z, mix_z, im_z;
2333 gdouble phase, im_phase;
2334 guint start_x;
2335
2336 if(floor(freq_period) != 0.0){
2337 start_x = freq_period * floor((double) i / freq_period);
2338 }else{
2339 start_x = 0;
2340 }
2341
2342 im_phase = fmod(i, im_freq_period);
2343
2344 phase = fmod(i, freq_period);
2345
2346 if(start_x + (guint) floor(phase) < buffer_length){
2347 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
2348 }else{
2349 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
2350 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
2351 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
2352 }else{
2353 if(floor(phase) < buffer_length){
2354 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
2355 }else{
2356 ptr_mix_buffer = mix_buffer + buffer_length - 1;
2357 }
2358 }
2359 }
2360
2361 ptr_im_mix_buffer = im_mix_buffer + i;
2362
2363 /* write im mix buffer */
2364 z = ags_complex_get(mix_buffer + i);
2365 mix_z = ags_complex_get(ptr_mix_buffer);
2366
2367 t = (im_freq_period / freq_period);
2368
2369 im_z = (1.0 - t) * z + (t * mix_z);
2370
2371 ags_complex_set(ptr_im_mix_buffer, im_z);
2372 }
2373
2374 /* low mix buffer */
2375 for(i = 0; i < buffer_length; i++){
2376 double _Complex z, mix_z, low_z;
2377 gdouble phase, low_phase;
2378 guint start_x;
2379
2380 if(floor(freq_period) != 0.0){
2381 start_x = freq_period * floor((double) i / freq_period);
2382 }else{
2383 start_x = 0;
2384 }
2385
2386 low_phase = fmod(i, low_freq_period);
2387
2388 phase = fmod(i, freq_period);
2389
2390 if(start_x + (guint) floor(phase) < buffer_length){
2391 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase));
2392 }else{
2393 if((start_x + (guint) floor(phase)) - (guint) floor(freq_period) < buffer_length &&
2394 (start_x + (guint) floor(phase)) - (guint) floor(freq_period) > 0){
2395 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(phase)) - (guint) floor(freq_period);
2396 }else{
2397 if(floor(phase) < buffer_length){
2398 ptr_mix_buffer = mix_buffer + (guint) floor(phase);
2399 }else{
2400 ptr_mix_buffer = mix_buffer + buffer_length - 1;
2401 }
2402 }
2403 }
2404
2405 ptr_low_mix_buffer = low_mix_buffer + i;
2406
2407 /* write low mix buffer */
2408 z = ags_complex_get(mix_buffer + i);
2409 mix_z = ags_complex_get(ptr_mix_buffer);
2410
2411 t = (low_freq_period / freq_period);
2412
2413 low_z = (1.0 - t) * z + (t * mix_z);
2414
2415 ags_complex_set(ptr_low_mix_buffer, low_z);
2416 }
2417
2418 /* new mix buffer */
2419 for(i = 0; i < buffer_length; i++){
2420 double _Complex new_z;
2421 gdouble phase, im_phase, low_phase, new_phase;
2422 guint start_x, im_start_x, low_start_x;
2423
2424 if(floor(freq_period) != 0.0){
2425 start_x = freq_period * floor((double) i / freq_period);
2426 }else{
2427 start_x = 0;
2428 }
2429
2430 if(floor(im_freq_period) != 0.0){
2431 im_start_x = im_freq_period * floor((double) i / im_freq_period);
2432 }else{
2433 im_start_x = 0;
2434 }
2435
2436 if(floor(low_freq_period) != 0.0){
2437 low_start_x = low_freq_period * floor((double) i / low_freq_period);
2438 }else{
2439 low_start_x = 0;
2440 }
2441
2442 phase = fmod(i, freq_period);
2443
2444 im_phase = fmod(i, im_freq_period);
2445
2446 low_phase = fmod(i, low_freq_period);
2447
2448 new_phase = fmod(i, new_freq_period);
2449
2450 if(start_x + (guint) floor(new_phase) < buffer_length){
2451 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase));
2452 }else{
2453 if((start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) < buffer_length &&
2454 (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period) > 0){
2455 ptr_mix_buffer = mix_buffer + (start_x + (guint) floor(new_phase)) - (guint) floor(freq_period);
2456 }else{
2457 if(floor(new_phase) < buffer_length){
2458 ptr_mix_buffer = mix_buffer + (guint) floor(new_phase);
2459 }else{
2460 ptr_mix_buffer = mix_buffer + buffer_length - 1;
2461 }
2462 }
2463 }
2464
2465 if(im_start_x + (guint) floor(new_phase) < buffer_length){
2466 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase));
2467 }else{
2468 if((im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) < buffer_length &&
2469 (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period) > 0){
2470 ptr_im_mix_buffer = im_mix_buffer + (im_start_x + (guint) floor(new_phase)) - (guint) floor(im_freq_period);
2471 }else{
2472 if(floor(new_phase) < buffer_length){
2473 ptr_im_mix_buffer = im_mix_buffer + (guint) floor(new_phase);
2474 }else{
2475 ptr_im_mix_buffer = im_mix_buffer + buffer_length - 1;
2476 }
2477 }
2478 }
2479
2480 if(low_start_x + (guint) floor(new_phase) < buffer_length){
2481 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase));
2482 }else{
2483 if((low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) < buffer_length &&
2484 (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period) > 0){
2485 ptr_low_mix_buffer = low_mix_buffer + (low_start_x + (guint) floor(new_phase)) - (guint) floor(low_freq_period);
2486 }else{
2487 if(floor(new_phase) < buffer_length){
2488 ptr_low_mix_buffer = low_mix_buffer + (guint) floor(new_phase);
2489 }else{
2490 ptr_low_mix_buffer = low_mix_buffer + buffer_length - 1;
2491 }
2492 }
2493 }
2494
2495 ptr_new_mix_buffer = new_mix_buffer + i;
2496
2497 /* write new mix buffer */
2498 if(ptr_mix_buffer->real != 0.0){
2499 new_z = volume * ((1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_im_mix_buffer) / im_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)) + (1.0 / 2.0) * (new_freq_period * (ags_complex_get(ptr_mix_buffer) / freq_period) * (ags_complex_get(ptr_low_mix_buffer) / low_freq_period) / (ags_complex_get(ptr_mix_buffer) / freq_period)));
2500 }else{
2501 new_z = 0.0 + I * 0.0;
2502 }
2503
2504 ags_complex_set(ptr_new_mix_buffer,
2505 new_z);
2506 }
2507
2508 /* rewrite buffer */
2509 for(i = 0; i < buffer_length; i++){
2510 ptr_new_mix_buffer = new_mix_buffer + i;
2511 ptr_buffer = buffer + i;
2512
2513 ags_complex_set(ptr_buffer, ags_complex_get(ptr_new_mix_buffer));
2514 }
2515
2516 ags_stream_free(mix_buffer);
2517
2518 ags_stream_free(im_mix_buffer);
2519
2520 ags_stream_free(low_mix_buffer);
2521
2522 ags_stream_free(new_mix_buffer);
2523 }
2524