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_phase_shift_util.h>
21
22 #include <ags/audio/ags_audio_signal.h>
23 #include <ags/audio/ags_audio_buffer_util.h>
24
25 gpointer ags_phase_shift_util_strct_copy(gpointer ptr);
26 void ags_phase_shift_util_strct_free(gpointer ptr);
27
28 /**
29 * SECTION:ags_phase_shift_util
30 * @short_description: phase shift util
31 * @title: AgsPhaseShiftUtil
32 * @section_id:
33 * @include: ags/audio/ags_phase_shift_util.h
34 *
35 * Utility functions to compute phase shift.
36 */
37
38
39 GType
ags_phase_shift_util_get_type(void)40 ags_phase_shift_util_get_type(void)
41 {
42 static volatile gsize g_define_type_id__volatile = 0;
43
44 if(g_once_init_enter (&g_define_type_id__volatile)){
45 GType ags_type_phase_shift_util = 0;
46
47 ags_type_phase_shift_util =
48 g_boxed_type_register_static("AgsPhaseShiftUtil",
49 (GBoxedCopyFunc) ags_phase_shift_util_strct_copy,
50 (GBoxedFreeFunc) ags_phase_shift_util_strct_free);
51
52 g_once_init_leave(&g_define_type_id__volatile, ags_type_phase_shift_util);
53 }
54
55 return g_define_type_id__volatile;
56 }
57
58 gpointer
ags_phase_shift_util_strct_copy(gpointer ptr)59 ags_phase_shift_util_strct_copy(gpointer ptr)
60 {
61 gpointer retval;
62
63 retval = g_memdup(ptr, sizeof(AgsPhaseShiftUtil));
64
65 return(retval);
66 }
67
68 void
ags_phase_shift_util_strct_free(gpointer ptr)69 ags_phase_shift_util_strct_free(gpointer ptr)
70 {
71 g_free(ptr);
72 }
73
74 /**
75 * ags_phase_shift_util_compute_s8:
76 * @destination: the destination audio buffer
77 * @source: the source audio buffer
78 * @buffer_length: the audio buffer's length
79 * @samplerate: the samplerate
80 * @frequency: the frequency
81 * @amount: the amount
82 * @phase: the phase
83 *
84 * Compute phase shift of audio buffer at @frequency with @amount with
85 * max radian 2 * M_PI.
86 *
87 * Since: 3.8.0
88 */
89 void
ags_phase_shift_util_compute_s8(gint8 * destination,gint8 * source,guint buffer_length,guint samplerate,gdouble frequency,gdouble amount,gdouble phase)90 ags_phase_shift_util_compute_s8(gint8 *destination,
91 gint8 *source,
92 guint buffer_length,
93 guint samplerate,
94 gdouble frequency,
95 gdouble amount,
96 gdouble phase)
97 {
98 gdouble freq_period, amount_period;
99 gdouble phase_period;
100 gdouble phase_shift;
101 guint i;
102
103 if(destination == NULL ||
104 source == NULL ||
105 buffer_length == 0){
106 return;
107 }
108
109 freq_period = samplerate / frequency;
110
111 amount_period = (amount / (2.0 * M_PI)) * freq_period;
112
113 phase_period = (phase / (2.0 * M_PI)) * freq_period;
114
115 for(i = 0; i < buffer_length; i++){
116 phase_shift = ((amount / (2.0 * M_PI)) * (G_MAXINT8 / 2.0)) * ((((int) ceil(i + phase_period) % (int) ceil(freq_period)) * 2.0 * frequency / samplerate) - 1.0);
117
118 destination[i] = 0.5 * (phase_shift + source[i]);
119 }
120 }
121
122 /**
123 * ags_phase_shift_util_compute_s16:
124 * @destination: the destination audio buffer
125 * @source: the source audio buffer
126 * @buffer_length: the audio buffer's length
127 * @samplerate: the samplerate
128 * @frequency: the frequency
129 * @amount: the amount
130 * @phase: the phase
131 *
132 * Compute phase shift of audio buffer at @frequency with @amount with
133 * max radian 2 * M_PI.
134 *
135 * Since: 3.8.0
136 */
137 void
ags_phase_shift_util_compute_s16(gint16 * destination,gint16 * source,guint buffer_length,guint samplerate,gdouble frequency,gdouble amount,gdouble phase)138 ags_phase_shift_util_compute_s16(gint16 *destination,
139 gint16 *source,
140 guint buffer_length,
141 guint samplerate,
142 gdouble frequency,
143 gdouble amount,
144 gdouble phase)
145 {
146 gdouble freq_period, amount_period;
147 gdouble phase_period;
148 gdouble phase_shift;
149 guint i;
150
151 if(destination == NULL ||
152 source == NULL ||
153 buffer_length == 0){
154 return;
155 }
156
157 freq_period = samplerate / frequency;
158
159 amount_period = (amount / (2.0 * M_PI)) * freq_period;
160
161 phase_period = (phase / (2.0 * M_PI)) * freq_period;
162
163 for(i = 0; i < buffer_length; i++){
164 phase_shift = ((amount / (2.0 * M_PI)) * (G_MAXINT16 / 2.0)) * ((((int) ceil(i + phase_period) % (int) ceil(freq_period)) * 2.0 * frequency / samplerate) - 1.0);
165
166 destination[i] = 0.5 * (phase_shift + source[i]);
167 }
168 }
169
170 /**
171 * ags_phase_shift_util_compute_s24:
172 * @destination: the destination audio buffer
173 * @source: the source audio buffer
174 * @buffer_length: the audio buffer's length
175 * @samplerate: the samplerate
176 * @frequency: the frequency
177 * @amount: the amount
178 * @phase: the phase
179 *
180 * Compute phase shift of audio buffer at @frequency with @amount with
181 * max radian 2 * M_PI.
182 *
183 * Since: 3.8.0
184 */
185 void
ags_phase_shift_util_compute_s24(gint32 * destination,gint32 * source,guint buffer_length,guint samplerate,gdouble frequency,gdouble amount,gdouble phase)186 ags_phase_shift_util_compute_s24(gint32 *destination,
187 gint32 *source,
188 guint buffer_length,
189 guint samplerate,
190 gdouble frequency,
191 gdouble amount,
192 gdouble phase)
193 {
194 gdouble freq_period, amount_period;
195 gdouble phase_period;
196 gdouble phase_shift;
197 guint i;
198
199 if(destination == NULL ||
200 source == NULL ||
201 buffer_length == 0){
202 return;
203 }
204
205 freq_period = samplerate / frequency;
206
207 amount_period = (amount / (2.0 * M_PI)) * freq_period;
208
209 phase_period = (phase / (2.0 * M_PI)) * freq_period;
210
211 for(i = 0; i < buffer_length; i++){
212 phase_shift = ((amount / (2.0 * M_PI)) * (0x7fffff / 2.0)) * ((((int) ceil(i + phase_period) % (int) ceil(freq_period)) * 2.0 * frequency / samplerate) - 1.0);
213
214 destination[i] = 0.5 * (phase_shift + source[i]);
215 }
216 }
217
218 /**
219 * ags_phase_shift_util_compute_s32:
220 * @destination: the destination audio buffer
221 * @source: the source audio buffer
222 * @buffer_length: the audio buffer's length
223 * @samplerate: the samplerate
224 * @frequency: the frequency
225 * @amount: the amount
226 * @phase: the phase
227 *
228 * Compute phase shift of audio buffer at @frequency with @amount with
229 * max radian 2 * M_PI.
230 *
231 * Since: 3.8.0
232 */
233 void
ags_phase_shift_util_compute_s32(gint32 * destination,gint32 * source,guint buffer_length,guint samplerate,gdouble frequency,gdouble amount,gdouble phase)234 ags_phase_shift_util_compute_s32(gint32 *destination,
235 gint32 *source,
236 guint buffer_length,
237 guint samplerate,
238 gdouble frequency,
239 gdouble amount,
240 gdouble phase)
241 {
242 gdouble freq_period, amount_period;
243 gdouble phase_period;
244 gdouble phase_shift;
245 guint i;
246
247 if(destination == NULL ||
248 source == NULL ||
249 buffer_length == 0){
250 return;
251 }
252
253 freq_period = samplerate / frequency;
254
255 amount_period = (amount / (2.0 * M_PI)) * freq_period;
256
257 phase_period = (phase / (2.0 * M_PI)) * freq_period;
258
259 for(i = 0; i < buffer_length; i++){
260 phase_shift = ((amount / (2.0 * M_PI)) * (G_MAXINT32 / 2.0)) * ((((int) ceil(i + phase_period) % (int) ceil(freq_period)) * 2.0 * frequency / samplerate) - 1.0);
261
262 destination[i] = 0.5 * (phase_shift + source[i]);
263 }
264 }
265
266 /**
267 * ags_phase_shift_util_compute_s64:
268 * @destination: the destination audio buffer
269 * @source: the source audio buffer
270 * @buffer_length: the audio buffer's length
271 * @samplerate: the samplerate
272 * @frequency: the frequency
273 * @amount: the amount
274 * @phase: the phase
275 *
276 * Compute phase shift of audio buffer at @frequency with @amount with
277 * max radian 2 * M_PI.
278 *
279 * Since: 3.8.0
280 */
281 void
ags_phase_shift_util_compute_s64(gint64 * destination,gint64 * source,guint buffer_length,guint samplerate,gdouble frequency,gdouble amount,gdouble phase)282 ags_phase_shift_util_compute_s64(gint64 *destination,
283 gint64 *source,
284 guint buffer_length,
285 guint samplerate,
286 gdouble frequency,
287 gdouble amount,
288 gdouble phase)
289 {
290 gdouble freq_period, amount_period;
291 gdouble phase_period;
292 gdouble phase_shift;
293 guint i;
294
295 if(destination == NULL ||
296 source == NULL ||
297 buffer_length == 0){
298 return;
299 }
300
301 freq_period = samplerate / frequency;
302
303 amount_period = (amount / (2.0 * M_PI)) * freq_period;
304
305 phase_period = (phase / (2.0 * M_PI)) * freq_period;
306
307 for(i = 0; i < buffer_length; i++){
308 phase_shift = ((amount / (2.0 * M_PI)) * (G_MAXINT64 / 2.0)) * ((((int) ceil(i + phase_period) % (int) ceil(freq_period)) * 2.0 * frequency / samplerate) - 1.0);
309
310 destination[i] = 0.5 * (phase_shift + source[i]);
311 }
312 }
313
314 /**
315 * ags_phase_shift_util_compute_float:
316 * @destination: the destination audio buffer
317 * @source: the source audio buffer
318 * @buffer_length: the audio buffer's length
319 * @samplerate: the samplerate
320 * @frequency: the frequency
321 * @amount: the amount
322 * @phase: the phase
323 *
324 * Compute phase shift of audio buffer at @frequency with @amount with
325 * max radian 2 * M_PI.
326 *
327 * Since: 3.8.0
328 */
329 void
ags_phase_shift_util_compute_float(gfloat * destination,gfloat * source,guint buffer_length,guint samplerate,gdouble frequency,gdouble amount,gdouble phase)330 ags_phase_shift_util_compute_float(gfloat *destination,
331 gfloat *source,
332 guint buffer_length,
333 guint samplerate,
334 gdouble frequency,
335 gdouble amount,
336 gdouble phase)
337 {
338 gdouble freq_period, amount_period;
339 gdouble phase_period;
340 gdouble phase_shift;
341 guint i;
342
343 if(destination == NULL ||
344 source == NULL ||
345 buffer_length == 0){
346 return;
347 }
348
349 freq_period = samplerate / frequency;
350
351 amount_period = (amount / (2.0 * M_PI)) * freq_period;
352
353 phase_period = (phase / (2.0 * M_PI)) * freq_period;
354
355 for(i = 0; i < buffer_length; i++){
356 phase_shift = (amount / (2.0 * M_PI)) * ((((int) ceil(i + phase_period) % (int) ceil(freq_period)) * 2.0 * frequency / samplerate) - 1.0);
357
358 destination[i] = 0.5 * (phase_shift + source[i]);
359 }
360 }
361
362 /**
363 * ags_phase_shift_util_compute_double:
364 * @destination: the destination audio buffer
365 * @source: the source audio buffer
366 * @buffer_length: the audio buffer's length
367 * @samplerate: the samplerate
368 * @frequency: the frequency
369 * @amount: the amount
370 * @phase: the phase
371 *
372 * Compute phase shift of audio buffer at @frequency with @amount with
373 * max radian 2 * M_PI.
374 *
375 * Since: 3.8.0
376 */
377 void
ags_phase_shift_util_compute_double(gdouble * destination,gdouble * source,guint buffer_length,guint samplerate,gdouble frequency,gdouble amount,gdouble phase)378 ags_phase_shift_util_compute_double(gdouble *destination,
379 gdouble *source,
380 guint buffer_length,
381 guint samplerate,
382 gdouble frequency,
383 gdouble amount,
384 gdouble phase)
385 {
386 gdouble y_translate;
387 gdouble freq_period, amount_period;
388 gdouble phase_period;
389 gdouble phase_shift;
390 guint i;
391
392 if(destination == NULL ||
393 source == NULL ||
394 buffer_length == 0){
395 return;
396 }
397
398 y_translate = -0.75;
399
400 freq_period = samplerate / frequency;
401
402 amount_period = (amount / (2.0 * M_PI)) * freq_period;
403
404 phase_period = (phase / (2.0 * M_PI)) * freq_period;
405
406 for(i = 0; i < buffer_length - (guint) floor(amount_period); i++){
407 phase_shift = (amount / (2.0 * M_PI)) * ((((int) ceil(i + phase_period) % (int) ceil(freq_period)) * 2.0 * frequency / samplerate) - 1.0);
408
409 destination[i] = 0.5 * (phase_shift + source[i]);
410 }
411 }
412
413 /**
414 * ags_phase_shift_util_compute_complex:
415 * @destination: the destination audio buffer
416 * @source: the source audio buffer
417 * @buffer_length: the audio buffer's length
418 * @samplerate: the samplerate
419 * @frequency: the frequency
420 * @amount: the amount
421 * @phase: the phase
422 *
423 * Compute phase shift of audio buffer at @frequency with @amount with
424 * max radian 2 * M_PI.
425 *
426 * Since: 3.8.0
427 */
428 void
ags_phase_shift_util_compute_complex(AgsComplex * destination,AgsComplex * source,guint buffer_length,guint samplerate,gdouble frequency,gdouble amount,gdouble phase)429 ags_phase_shift_util_compute_complex(AgsComplex *destination,
430 AgsComplex *source,
431 guint buffer_length,
432 guint samplerate,
433 gdouble frequency,
434 gdouble amount,
435 gdouble phase)
436 {
437 gdouble freq_period, amount_period;
438 gdouble phase_period;
439 gdouble phase_shift;
440 guint i;
441
442 if(destination == NULL ||
443 source == NULL ||
444 buffer_length == 0){
445 return;
446 }
447
448 freq_period = samplerate / frequency;
449
450 amount_period = (amount / (2.0 * M_PI)) * freq_period;
451
452 phase_period = (phase / (2.0 * M_PI)) * freq_period;
453
454 for(i = 0; i < buffer_length; i++){
455 phase_shift = (amount / (2.0 * M_PI)) * ((((int) ceil(i + phase_period) % (int) ceil(freq_period)) * 2.0 * frequency / samplerate) - 1.0);
456
457 ags_complex_set(destination + i,
458 0.5 * (phase_shift + ags_complex_get(source + i)));
459 }
460 }
461