Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/fluidsynth/src/rvoice/fluid_rvoice_dsp.cpp
12346 views
1
/* FluidSynth - A Software Synthesizer
2
*
3
* Copyright (C) 2003 Peter Hanappe and others.
4
*
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public License
7
* as published by the Free Software Foundation; either version 2.1 of
8
* the License, or (at your option) any later version.
9
*
10
* This library is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
14
*
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free
17
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
* 02110-1301, USA
19
*/
20
21
#include "fluid_sys.h"
22
#include "fluid_phase.h"
23
#include "fluid_rvoice.h"
24
#include "fluid_rvoice_dsp_tables.inc.h"
25
26
/* Purpose:
27
*
28
* Interpolates audio data (obtains values between the samples of the original
29
* waveform data).
30
*
31
* Variables loaded from the voice structure (assigned in fluid_rvoice_write()):
32
* - dsp_data: Pointer to the original waveform data
33
* - dsp_phase: The position in the original waveform data.
34
* This has an integer and a fractional part (between samples).
35
* - dsp_phase_incr: For each output sample, the position in the original
36
* waveform advances by dsp_phase_incr. This also has an integer
37
* part and a fractional part.
38
* If a sample is played at root pitch (no pitch change),
39
* dsp_phase_incr is integer=1 and fractional=0.
40
* - dsp_amp: The current amplitude envelope value.
41
* - dsp_amp_incr: The changing rate of the amplitude envelope.
42
*
43
* A couple of variables are used internally, their results are discarded:
44
* - dsp_i: Index through the output buffer
45
* - dsp_buf: Output buffer of floating point values (FLUID_BUFSIZE in length)
46
*/
47
48
/* Interpolation (find a value between two samples of the original waveform) */
49
50
template<bool IS_24BIT>
51
static FLUID_INLINE fluid_real_t
52
fluid_rvoice_get_float_sample(const short int *FLUID_RESTRICT dsp_msb, const char *FLUID_RESTRICT dsp_lsb, unsigned int idx)
53
{
54
int32_t sample;
55
if (IS_24BIT)
56
{
57
sample = fluid_rvoice_get_sample24(dsp_msb, dsp_lsb, idx);
58
}
59
else
60
{
61
sample = fluid_rvoice_get_sample16(dsp_msb, idx);
62
}
63
64
return (fluid_real_t)sample;
65
}
66
67
/* Special case of interpolate_none for rendering silent voices, i.e. in delay phase or zero volume */
68
template<bool LOOPING>
69
static int fluid_rvoice_dsp_silence_local(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf)
70
{
71
fluid_rvoice_dsp_t *voice = &rvoice->dsp;
72
fluid_phase_t dsp_phase = voice->phase;
73
fluid_phase_t dsp_phase_incr;
74
unsigned short dsp_i = 0;
75
unsigned int dsp_phase_index;
76
unsigned int end_index;
77
78
/* Convert playback "speed" floating point value to phase index/fract */
79
fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
80
81
end_index = LOOPING ? voice->loopend - 1 : voice->end;
82
83
while (1)
84
{
85
dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */
86
87
/* interpolate sequence of sample points */
88
for (; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
89
{
90
fluid_real_t sample = 0;
91
dsp_buf[dsp_i] = sample;
92
93
/* increment phase and amplitude */
94
fluid_phase_incr(dsp_phase, dsp_phase_incr);
95
}
96
97
/* break out if not looping (buffer may not be full) */
98
if (!LOOPING)
99
{
100
break;
101
}
102
103
dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */
104
/* go back to loop start */
105
if (dsp_phase_index > end_index)
106
{
107
fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
108
voice->has_looped = 1;
109
}
110
111
/* break out if filled buffer */
112
if (dsp_i >= FLUID_BUFSIZE)
113
{
114
break;
115
}
116
}
117
118
voice->phase = dsp_phase;
119
// Note, there is no need to update the amplitude here. When the voice becomes audible again, the amp will be updated anyway in fluid_rvoice_calc_amp().
120
// voice->amp = dsp_amp;
121
122
return (dsp_i);
123
}
124
125
/* No interpolation. Just take the sample, which is closest to
126
* the playback pointer. Questionable quality, but very
127
* efficient. */
128
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
129
static int
130
fluid_rvoice_dsp_interpolate_none_local(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf)
131
{
132
fluid_rvoice_dsp_t *voice = &rvoice->dsp;
133
fluid_phase_t dsp_phase = voice->phase;
134
fluid_phase_t dsp_phase_incr;
135
const short int *FLUID_RESTRICT dsp_data = voice->sample->data;
136
const char *FLUID_RESTRICT dsp_data24 = voice->sample->data24;
137
fluid_real_t dsp_amp = voice->amp;
138
fluid_real_t dsp_amp_incr = voice->amp_incr;
139
unsigned short dsp_i = 0;
140
unsigned int dsp_phase_index;
141
unsigned int end_index;
142
143
/* Convert playback "speed" floating point value to phase index/fract */
144
fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
145
146
end_index = LOOPING ? voice->loopend - 1 : voice->end;
147
148
while(1)
149
{
150
dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */
151
152
/* interpolate sequence of sample points */
153
for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
154
{
155
fluid_real_t sample = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index);
156
157
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
158
if (ENABLE_CUSTOM_FILTER)
159
{
160
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
161
}
162
163
dsp_buf[dsp_i] = dsp_amp * sample;
164
165
/* increment phase and amplitude */
166
fluid_phase_incr(dsp_phase, dsp_phase_incr);
167
dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */
168
dsp_amp += dsp_amp_incr;
169
}
170
171
/* break out if not looping (buffer may not be full) */
172
if(!LOOPING)
173
{
174
break;
175
}
176
177
/* go back to loop start */
178
if(dsp_phase_index > end_index)
179
{
180
fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
181
voice->has_looped = 1;
182
}
183
184
/* break out if filled buffer */
185
if(dsp_i >= FLUID_BUFSIZE)
186
{
187
break;
188
}
189
}
190
191
voice->phase = dsp_phase;
192
voice->amp = dsp_amp;
193
194
return (dsp_i);
195
}
196
197
/* Straight line interpolation.
198
* Returns number of samples processed (usually FLUID_BUFSIZE but could be
199
* smaller if end of sample occurs).
200
*/
201
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
202
static int
203
fluid_rvoice_dsp_interpolate_linear_local(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf)
204
{
205
fluid_rvoice_dsp_t *voice = &rvoice->dsp;
206
fluid_phase_t dsp_phase = voice->phase;
207
fluid_phase_t dsp_phase_incr;
208
const short int *FLUID_RESTRICT dsp_data = voice->sample->data;
209
const char *FLUID_RESTRICT dsp_data24 = voice->sample->data24;
210
fluid_real_t dsp_amp = voice->amp;
211
fluid_real_t dsp_amp_incr = voice->amp_incr;
212
unsigned short dsp_i = 0;
213
unsigned int dsp_phase_index;
214
unsigned int end_index;
215
fluid_real_t point;
216
const fluid_real_t *FLUID_RESTRICT coeffs;
217
218
/* Convert playback "speed" floating point value to phase index/fract */
219
fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
220
221
/* last index before 2nd interpolation point must be specially handled */
222
end_index = (LOOPING ? voice->loopend - 1 : voice->end) - 1;
223
224
/* 2nd interpolation point to use at end of loop or sample */
225
if(LOOPING)
226
{
227
point = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopstart); /* loop start */
228
}
229
else
230
{
231
point = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->end); /* duplicate end for samples no longer looping */
232
}
233
234
while(1)
235
{
236
dsp_phase_index = fluid_phase_index(dsp_phase);
237
238
/* interpolate the sequence of sample points */
239
for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
240
{
241
fluid_real_t sample;
242
coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow(dsp_phase)];
243
244
sample = (coeffs[0] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
245
+ coeffs[1] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 1));
246
247
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
248
if (ENABLE_CUSTOM_FILTER)
249
{
250
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
251
}
252
253
dsp_buf[dsp_i] = dsp_amp * sample;
254
255
/* increment phase and amplitude */
256
fluid_phase_incr(dsp_phase, dsp_phase_incr);
257
dsp_phase_index = fluid_phase_index(dsp_phase);
258
dsp_amp += dsp_amp_incr;
259
}
260
261
/* break out if buffer filled */
262
if(dsp_i >= FLUID_BUFSIZE)
263
{
264
break;
265
}
266
267
end_index++; /* we're now interpolating the last point */
268
269
/* interpolate within last point */
270
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
271
{
272
fluid_real_t sample;
273
coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow(dsp_phase)];
274
275
sample = (coeffs[0] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
276
+ coeffs[1] * point);
277
278
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
279
if (ENABLE_CUSTOM_FILTER)
280
{
281
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
282
}
283
284
dsp_buf[dsp_i] = dsp_amp * sample;
285
286
/* increment phase and amplitude */
287
fluid_phase_incr(dsp_phase, dsp_phase_incr);
288
dsp_phase_index = fluid_phase_index(dsp_phase);
289
dsp_amp += dsp_amp_incr; /* increment amplitude */
290
}
291
292
if(!LOOPING)
293
{
294
break; /* break out if not looping (end of sample) */
295
}
296
297
/* go back to loop start (if past */
298
if(dsp_phase_index > end_index)
299
{
300
fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
301
voice->has_looped = 1;
302
}
303
304
/* break out if filled buffer */
305
if(dsp_i >= FLUID_BUFSIZE)
306
{
307
break;
308
}
309
310
end_index--; /* set end back to second to last sample point */
311
}
312
313
voice->phase = dsp_phase;
314
voice->amp = dsp_amp;
315
316
return (dsp_i);
317
}
318
319
/* 4th order (cubic) interpolation.
320
* Returns number of samples processed (usually FLUID_BUFSIZE but could be
321
* smaller if end of sample occurs).
322
*/
323
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
324
static int
325
fluid_rvoice_dsp_interpolate_4th_order_local(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf)
326
{
327
fluid_rvoice_dsp_t *voice = &rvoice->dsp;
328
fluid_phase_t dsp_phase = voice->phase;
329
fluid_phase_t dsp_phase_incr;
330
const short int *FLUID_RESTRICT dsp_data = voice->sample->data;
331
const char *FLUID_RESTRICT dsp_data24 = voice->sample->data24;
332
fluid_real_t dsp_amp = voice->amp;
333
fluid_real_t dsp_amp_incr = voice->amp_incr;
334
unsigned short dsp_i = 0;
335
unsigned int dsp_phase_index;
336
unsigned int start_index, end_index;
337
fluid_real_t start_point, end_point1, end_point2;
338
const fluid_real_t *FLUID_RESTRICT coeffs;
339
340
/* Convert playback "speed" floating point value to phase index/fract */
341
fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
342
343
/* last index before 4th interpolation point must be specially handled */
344
end_index = (LOOPING ? voice->loopend - 1 : voice->end) - 2;
345
346
if(voice->has_looped) /* set start_index and start point if looped or not */
347
{
348
start_index = voice->loopstart;
349
start_point = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopend - 1); /* last point in loop (wrap around) */
350
}
351
else
352
{
353
start_index = voice->start;
354
start_point = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->start); /* just duplicate the point */
355
}
356
357
/* get points off the end (loop start if looping, duplicate point if end) */
358
if(LOOPING)
359
{
360
end_point1 = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopstart);
361
end_point2 = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopstart + 1);
362
}
363
else
364
{
365
end_point1 = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->end);
366
end_point2 = end_point1;
367
}
368
369
while(1)
370
{
371
dsp_phase_index = fluid_phase_index(dsp_phase);
372
373
/* interpolate first sample point (start or loop start) if needed */
374
for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
375
{
376
fluid_real_t sample;
377
coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
378
379
sample = (coeffs[0] * start_point
380
+ coeffs[1] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
381
+ coeffs[2] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 1)
382
+ coeffs[3] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 2));
383
384
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
385
if (ENABLE_CUSTOM_FILTER)
386
{
387
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
388
}
389
390
dsp_buf[dsp_i] = dsp_amp * sample;
391
392
/* increment phase and amplitude */
393
fluid_phase_incr(dsp_phase, dsp_phase_incr);
394
dsp_phase_index = fluid_phase_index(dsp_phase);
395
dsp_amp += dsp_amp_incr;
396
}
397
398
/* interpolate the sequence of sample points */
399
for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
400
{
401
fluid_real_t sample;
402
coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
403
404
sample = (coeffs[0] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 1)
405
+ coeffs[1] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
406
+ coeffs[2] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 1)
407
+ coeffs[3] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 2));
408
409
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
410
if (ENABLE_CUSTOM_FILTER)
411
{
412
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
413
}
414
415
dsp_buf[dsp_i] = dsp_amp * sample;
416
417
/* increment phase and amplitude */
418
fluid_phase_incr(dsp_phase, dsp_phase_incr);
419
dsp_phase_index = fluid_phase_index(dsp_phase);
420
dsp_amp += dsp_amp_incr;
421
}
422
423
/* break out if buffer filled */
424
if(dsp_i >= FLUID_BUFSIZE)
425
{
426
break;
427
}
428
429
end_index++; /* we're now interpolating the 2nd to last point */
430
431
/* interpolate within 2nd to last point */
432
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
433
{
434
fluid_real_t sample;
435
coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
436
437
sample = (coeffs[0] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 1)
438
+ coeffs[1] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
439
+ coeffs[2] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 1)
440
+ coeffs[3] * end_point1);
441
442
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
443
if (ENABLE_CUSTOM_FILTER)
444
{
445
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
446
}
447
448
dsp_buf[dsp_i] = dsp_amp * sample;
449
450
/* increment phase and amplitude */
451
fluid_phase_incr(dsp_phase, dsp_phase_incr);
452
dsp_phase_index = fluid_phase_index(dsp_phase);
453
dsp_amp += dsp_amp_incr;
454
}
455
456
end_index++; /* we're now interpolating the last point */
457
458
/* interpolate within the last point */
459
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
460
{
461
fluid_real_t sample;
462
coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
463
464
465
sample = (coeffs[0] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 1)
466
+ coeffs[1] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
467
+ coeffs[2] * end_point1
468
+ coeffs[3] * end_point2);
469
470
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
471
if (ENABLE_CUSTOM_FILTER)
472
{
473
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
474
}
475
476
dsp_buf[dsp_i] = dsp_amp * sample;
477
478
/* increment phase and amplitude */
479
fluid_phase_incr(dsp_phase, dsp_phase_incr);
480
dsp_phase_index = fluid_phase_index(dsp_phase);
481
dsp_amp += dsp_amp_incr;
482
}
483
484
if(!LOOPING)
485
{
486
break; /* break out if not looping (end of sample) */
487
}
488
489
/* go back to loop start */
490
if(dsp_phase_index > end_index)
491
{
492
fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
493
494
if(!voice->has_looped)
495
{
496
voice->has_looped = 1;
497
start_index = voice->loopstart;
498
start_point = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopend - 1);
499
}
500
}
501
502
/* break out if filled buffer */
503
if(dsp_i >= FLUID_BUFSIZE)
504
{
505
break;
506
}
507
508
end_index -= 2; /* set end back to third to last sample point */
509
}
510
511
voice->phase = dsp_phase;
512
voice->amp = dsp_amp;
513
514
return (dsp_i);
515
}
516
517
/* 7th order interpolation.
518
* Returns number of samples processed (usually FLUID_BUFSIZE but could be
519
* smaller if end of sample occurs).
520
*/
521
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
522
static int
523
fluid_rvoice_dsp_interpolate_7th_order_local(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf)
524
{
525
fluid_rvoice_dsp_t *voice = &rvoice->dsp;
526
fluid_phase_t dsp_phase = voice->phase;
527
fluid_phase_t dsp_phase_incr;
528
const short int *FLUID_RESTRICT dsp_data = voice->sample->data;
529
const char *FLUID_RESTRICT dsp_data24 = voice->sample->data24;
530
fluid_real_t dsp_amp = voice->amp;
531
fluid_real_t dsp_amp_incr = voice->amp_incr;
532
unsigned short dsp_i = 0;
533
unsigned int dsp_phase_index;
534
unsigned int start_index, end_index;
535
fluid_real_t start_points[3], end_points[3];
536
const fluid_real_t *FLUID_RESTRICT coeffs;
537
538
/* Convert playback "speed" floating point value to phase index/fract */
539
fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
540
541
/* add 1/2 sample to dsp_phase since 7th order interpolation is centered on
542
* the 4th sample point */
543
fluid_phase_incr(dsp_phase, (fluid_phase_t)0x80000000);
544
545
/* last index before 7th interpolation point must be specially handled */
546
end_index = (LOOPING ? voice->loopend - 1 : voice->end) - 3;
547
548
if(voice->has_looped) /* set start_index and start point if looped or not */
549
{
550
start_index = voice->loopstart;
551
start_points[0] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopend - 1);
552
start_points[1] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopend - 2);
553
start_points[2] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopend - 3);
554
}
555
else
556
{
557
start_index = voice->start;
558
start_points[0] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->start); /* just duplicate the start point */
559
start_points[1] = start_points[0];
560
start_points[2] = start_points[0];
561
}
562
563
/* get the 3 points off the end (loop start if looping, duplicate point if end) */
564
if(LOOPING)
565
{
566
end_points[0] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopstart);
567
end_points[1] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopstart + 1);
568
end_points[2] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopstart + 2);
569
}
570
else
571
{
572
end_points[0] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->end);
573
end_points[1] = end_points[0];
574
end_points[2] = end_points[0];
575
}
576
577
while(1)
578
{
579
dsp_phase_index = fluid_phase_index(dsp_phase);
580
581
/* interpolate first sample point (start or loop start) if needed */
582
for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
583
{
584
fluid_real_t sample;
585
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
586
587
sample = (coeffs[0] * start_points[2]
588
+ coeffs[1] * start_points[1]
589
+ coeffs[2] * start_points[0]
590
+ coeffs[3] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
591
+ coeffs[4] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 1)
592
+ coeffs[5] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 2)
593
+ coeffs[6] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 3));
594
595
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
596
if (ENABLE_CUSTOM_FILTER)
597
{
598
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
599
}
600
dsp_buf[dsp_i] = dsp_amp * sample;
601
602
/* increment phase and amplitude */
603
fluid_phase_incr(dsp_phase, dsp_phase_incr);
604
dsp_phase_index = fluid_phase_index(dsp_phase);
605
dsp_amp += dsp_amp_incr;
606
}
607
608
start_index++;
609
610
/* interpolate 2nd to first sample point (start or loop start) if needed */
611
for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
612
{
613
fluid_real_t sample;
614
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
615
616
sample = (coeffs[0] * start_points[1]
617
+ coeffs[1] * start_points[0]
618
+ coeffs[2] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 1)
619
+ coeffs[3] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
620
+ coeffs[4] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 1)
621
+ coeffs[5] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 2)
622
+ coeffs[6] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 3));
623
624
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
625
if (ENABLE_CUSTOM_FILTER)
626
{
627
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
628
}
629
dsp_buf[dsp_i] = dsp_amp * sample;
630
631
/* increment phase and amplitude */
632
fluid_phase_incr(dsp_phase, dsp_phase_incr);
633
dsp_phase_index = fluid_phase_index(dsp_phase);
634
dsp_amp += dsp_amp_incr;
635
}
636
637
start_index++;
638
639
/* interpolate 3rd to first sample point (start or loop start) if needed */
640
for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
641
{
642
fluid_real_t sample;
643
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
644
645
sample = (coeffs[0] * start_points[0]
646
+ coeffs[1] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 2)
647
+ coeffs[2] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 1)
648
+ coeffs[3] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
649
+ coeffs[4] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 1)
650
+ coeffs[5] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 2)
651
+ coeffs[6] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 3));
652
653
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
654
if (ENABLE_CUSTOM_FILTER)
655
{
656
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
657
}
658
dsp_buf[dsp_i] = dsp_amp * sample;
659
660
/* increment phase and amplitude */
661
fluid_phase_incr(dsp_phase, dsp_phase_incr);
662
dsp_phase_index = fluid_phase_index(dsp_phase);
663
dsp_amp += dsp_amp_incr;
664
}
665
666
start_index -= 2; /* set back to original start index */
667
668
669
/* interpolate the sequence of sample points */
670
for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
671
{
672
fluid_real_t sample;
673
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
674
675
sample = (coeffs[0] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 3)
676
+ coeffs[1] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 2)
677
+ coeffs[2] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 1)
678
+ coeffs[3] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
679
+ coeffs[4] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 1)
680
+ coeffs[5] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 2)
681
+ coeffs[6] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 3));
682
683
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
684
if (ENABLE_CUSTOM_FILTER)
685
{
686
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
687
}
688
dsp_buf[dsp_i] = dsp_amp * sample;
689
690
/* increment phase and amplitude */
691
fluid_phase_incr(dsp_phase, dsp_phase_incr);
692
dsp_phase_index = fluid_phase_index(dsp_phase);
693
dsp_amp += dsp_amp_incr;
694
}
695
696
/* break out if buffer filled */
697
if(dsp_i >= FLUID_BUFSIZE)
698
{
699
break;
700
}
701
702
end_index++; /* we're now interpolating the 3rd to last point */
703
704
/* interpolate within 3rd to last point */
705
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
706
{
707
fluid_real_t sample;
708
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
709
710
sample = (coeffs[0] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 3)
711
+ coeffs[1] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 2)
712
+ coeffs[2] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 1)
713
+ coeffs[3] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
714
+ coeffs[4] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 1)
715
+ coeffs[5] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 2)
716
+ coeffs[6] * end_points[0]);
717
718
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
719
if (ENABLE_CUSTOM_FILTER)
720
{
721
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
722
}
723
dsp_buf[dsp_i] = dsp_amp * sample;
724
725
/* increment phase and amplitude */
726
fluid_phase_incr(dsp_phase, dsp_phase_incr);
727
dsp_phase_index = fluid_phase_index(dsp_phase);
728
dsp_amp += dsp_amp_incr;
729
}
730
731
end_index++; /* we're now interpolating the 2nd to last point */
732
733
/* interpolate within 2nd to last point */
734
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
735
{
736
fluid_real_t sample;
737
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
738
739
sample = (coeffs[0] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 3)
740
+ coeffs[1] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 2)
741
+ coeffs[2] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 1)
742
+ coeffs[3] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
743
+ coeffs[4] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index + 1)
744
+ coeffs[5] * end_points[0]
745
+ coeffs[6] * end_points[1]);
746
747
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
748
if (ENABLE_CUSTOM_FILTER)
749
{
750
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
751
}
752
dsp_buf[dsp_i] = dsp_amp * sample;
753
754
/* increment phase and amplitude */
755
fluid_phase_incr(dsp_phase, dsp_phase_incr);
756
dsp_phase_index = fluid_phase_index(dsp_phase);
757
dsp_amp += dsp_amp_incr;
758
}
759
760
end_index++; /* we're now interpolating the last point */
761
762
/* interpolate within last point */
763
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
764
{
765
fluid_real_t sample;
766
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
767
768
sample = (coeffs[0] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 3)
769
+ coeffs[1] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 2)
770
+ coeffs[2] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index - 1)
771
+ coeffs[3] * fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, dsp_phase_index)
772
+ coeffs[4] * end_points[0]
773
+ coeffs[5] * end_points[1]
774
+ coeffs[6] * end_points[2]);
775
776
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
777
if (ENABLE_CUSTOM_FILTER)
778
{
779
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
780
}
781
dsp_buf[dsp_i] = dsp_amp * sample;
782
783
/* increment phase and amplitude */
784
fluid_phase_incr(dsp_phase, dsp_phase_incr);
785
dsp_phase_index = fluid_phase_index(dsp_phase);
786
dsp_amp += dsp_amp_incr;
787
}
788
789
if(!LOOPING)
790
{
791
break; /* break out if not looping (end of sample) */
792
}
793
794
/* go back to loop start */
795
if(dsp_phase_index > end_index)
796
{
797
fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
798
799
if(!voice->has_looped)
800
{
801
voice->has_looped = 1;
802
start_index = voice->loopstart;
803
start_points[0] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopend - 1);
804
start_points[1] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopend - 2);
805
start_points[2] = fluid_rvoice_get_float_sample<IS_24BIT>(dsp_data, dsp_data24, voice->loopend - 3);
806
}
807
}
808
809
/* break out if filled buffer */
810
if(dsp_i >= FLUID_BUFSIZE)
811
{
812
break;
813
}
814
815
end_index -= 3; /* set end back to 4th to last sample point */
816
}
817
818
/* sub 1/2 sample from dsp_phase since 7th order interpolation is centered on
819
* the 4th sample point (correct back to real value) */
820
fluid_phase_decr(dsp_phase, (fluid_phase_t)0x80000000);
821
822
voice->phase = dsp_phase;
823
voice->amp = dsp_amp;
824
825
return (dsp_i);
826
}
827
828
struct ProcessSilence
829
{
830
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
831
int operator()(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf) const
832
{
833
return fluid_rvoice_dsp_silence_local<LOOPING>(rvoice, dsp_buf);
834
}
835
};
836
837
struct InterpolateNone
838
{
839
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
840
int operator()(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf) const
841
{
842
return fluid_rvoice_dsp_interpolate_none_local<ENABLE_CUSTOM_FILTER, IS_24BIT, LOOPING>(rvoice, dsp_buf);
843
}
844
};
845
846
struct InterpolateLinear
847
{
848
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
849
int operator()(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf) const
850
{
851
return fluid_rvoice_dsp_interpolate_linear_local<ENABLE_CUSTOM_FILTER, IS_24BIT, LOOPING>(rvoice, dsp_buf);
852
}
853
};
854
855
struct Interpolate4thOrder
856
{
857
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
858
int operator()(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf) const
859
{
860
return fluid_rvoice_dsp_interpolate_4th_order_local<ENABLE_CUSTOM_FILTER, IS_24BIT, LOOPING>(rvoice, dsp_buf);
861
}
862
};
863
864
struct Interpolate7thOrder
865
{
866
template<bool ENABLE_CUSTOM_FILTER, bool IS_24BIT, bool LOOPING>
867
int operator()(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf) const
868
{
869
return fluid_rvoice_dsp_interpolate_7th_order_local<ENABLE_CUSTOM_FILTER, IS_24BIT, LOOPING>(rvoice, dsp_buf);
870
}
871
};
872
873
template<typename T>
874
int dsp_invoker(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
875
{
876
T func;
877
bool is_24bit = rvoice->dsp.sample->data24 != NULL;
878
879
if (rvoice->resonant_custom_filter.flags & FLUID_IIR_DISABLED)
880
{
881
if (is_24bit)
882
{
883
if(looping)
884
{
885
return func.template operator()<false, true, true>(rvoice, dsp_buf);
886
}
887
else
888
{
889
return func.template operator()<false, true, false>(rvoice, dsp_buf);
890
}
891
}
892
else
893
{
894
// This case is most common, thanks to templating it will also become the fastest one
895
if (looping)
896
{
897
return func.template operator()<false, false, true>(rvoice, dsp_buf);
898
}
899
else
900
{
901
return func.template operator()<false, false, false>(rvoice, dsp_buf);
902
}
903
}
904
}
905
else
906
{
907
if (is_24bit)
908
{
909
if (looping)
910
{
911
return func.template operator()<true, true, true>(rvoice, dsp_buf);
912
}
913
else
914
{
915
return func.template operator()<true, true, false>(rvoice, dsp_buf);
916
}
917
}
918
else
919
{
920
if (looping)
921
{
922
return func.template operator()<true, false, true>(rvoice, dsp_buf);
923
}
924
else
925
{
926
return func.template operator()<true, false, false>(rvoice, dsp_buf);
927
}
928
}
929
}
930
}
931
932
extern "C" int
933
fluid_rvoice_dsp_silence(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
934
{
935
return dsp_invoker<ProcessSilence>(rvoice, dsp_buf, looping);
936
}
937
938
extern "C" int
939
fluid_rvoice_dsp_interpolate_none(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
940
{
941
return dsp_invoker<InterpolateNone>(rvoice, dsp_buf, looping);
942
}
943
944
extern "C" int
945
fluid_rvoice_dsp_interpolate_linear(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
946
{
947
return dsp_invoker<InterpolateLinear>(rvoice, dsp_buf, looping);
948
}
949
950
extern "C" int
951
fluid_rvoice_dsp_interpolate_4th_order(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
952
{
953
return dsp_invoker<Interpolate4thOrder>(rvoice, dsp_buf, looping);
954
}
955
956
extern "C" int fluid_rvoice_dsp_interpolate_7th_order(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
957
{
958
return dsp_invoker<Interpolate7thOrder>(rvoice, dsp_buf, looping);
959
}
960
961