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.c
8882 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
static FLUID_INLINE fluid_real_t
51
fluid_rvoice_get_float_sample(const short int *dsp_msb, const char *dsp_lsb, unsigned int idx)
52
{
53
int32_t sample = fluid_rvoice_get_sample(dsp_msb, dsp_lsb, idx);
54
return (fluid_real_t)sample;
55
}
56
57
/* No interpolation. Just take the sample, which is closest to
58
* the playback pointer. Questionable quality, but very
59
* efficient. */
60
int
61
fluid_rvoice_dsp_interpolate_none(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
62
{
63
fluid_rvoice_dsp_t *voice = &rvoice->dsp;
64
fluid_phase_t dsp_phase = voice->phase;
65
fluid_phase_t dsp_phase_incr;
66
short int *dsp_data = voice->sample->data;
67
char *dsp_data24 = voice->sample->data24;
68
fluid_real_t dsp_amp = voice->amp;
69
fluid_real_t dsp_amp_incr = voice->amp_incr;
70
unsigned int dsp_i = 0;
71
unsigned int dsp_phase_index;
72
unsigned int end_index;
73
74
/* Convert playback "speed" floating point value to phase index/fract */
75
fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
76
77
end_index = looping ? voice->loopend - 1 : voice->end;
78
79
while(1)
80
{
81
dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */
82
83
/* interpolate sequence of sample points */
84
for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
85
{
86
fluid_real_t sample = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index);
87
88
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
89
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
90
91
dsp_buf[dsp_i] = dsp_amp * sample;
92
93
/* increment phase and amplitude */
94
fluid_phase_incr(dsp_phase, dsp_phase_incr);
95
dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */
96
dsp_amp += dsp_amp_incr;
97
}
98
99
/* break out if not looping (buffer may not be full) */
100
if(!looping)
101
{
102
break;
103
}
104
105
/* go back to loop start */
106
if(dsp_phase_index > end_index)
107
{
108
fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
109
voice->has_looped = 1;
110
}
111
112
/* break out if filled buffer */
113
if(dsp_i >= FLUID_BUFSIZE)
114
{
115
break;
116
}
117
}
118
119
voice->phase = dsp_phase;
120
voice->amp = dsp_amp;
121
122
return (dsp_i);
123
}
124
125
/* Straight line interpolation.
126
* Returns number of samples processed (usually FLUID_BUFSIZE but could be
127
* smaller if end of sample occurs).
128
*/
129
int
130
fluid_rvoice_dsp_interpolate_linear(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
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
short int *dsp_data = voice->sample->data;
136
char *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 int dsp_i = 0;
140
unsigned int dsp_phase_index;
141
unsigned int end_index;
142
fluid_real_t point;
143
const fluid_real_t *FLUID_RESTRICT coeffs;
144
145
/* Convert playback "speed" floating point value to phase index/fract */
146
fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
147
148
/* last index before 2nd interpolation point must be specially handled */
149
end_index = (looping ? voice->loopend - 1 : voice->end) - 1;
150
151
/* 2nd interpolation point to use at end of loop or sample */
152
if(looping)
153
{
154
point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart); /* loop start */
155
}
156
else
157
{
158
point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end); /* duplicate end for samples no longer looping */
159
}
160
161
while(1)
162
{
163
dsp_phase_index = fluid_phase_index(dsp_phase);
164
165
/* interpolate the sequence of sample points */
166
for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
167
{
168
fluid_real_t sample;
169
coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow(dsp_phase)];
170
171
sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
172
+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1));
173
174
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
175
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
176
177
dsp_buf[dsp_i] = dsp_amp * sample;
178
179
/* increment phase and amplitude */
180
fluid_phase_incr(dsp_phase, dsp_phase_incr);
181
dsp_phase_index = fluid_phase_index(dsp_phase);
182
dsp_amp += dsp_amp_incr;
183
}
184
185
/* break out if buffer filled */
186
if(dsp_i >= FLUID_BUFSIZE)
187
{
188
break;
189
}
190
191
end_index++; /* we're now interpolating the last point */
192
193
/* interpolate within last point */
194
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
195
{
196
fluid_real_t sample;
197
coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow(dsp_phase)];
198
199
sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
200
+ coeffs[1] * point);
201
202
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
203
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
204
205
dsp_buf[dsp_i] = dsp_amp * sample;
206
207
/* increment phase and amplitude */
208
fluid_phase_incr(dsp_phase, dsp_phase_incr);
209
dsp_phase_index = fluid_phase_index(dsp_phase);
210
dsp_amp += dsp_amp_incr; /* increment amplitude */
211
}
212
213
if(!looping)
214
{
215
break; /* break out if not looping (end of sample) */
216
}
217
218
/* go back to loop start (if past */
219
if(dsp_phase_index > end_index)
220
{
221
fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
222
voice->has_looped = 1;
223
}
224
225
/* break out if filled buffer */
226
if(dsp_i >= FLUID_BUFSIZE)
227
{
228
break;
229
}
230
231
end_index--; /* set end back to second to last sample point */
232
}
233
234
voice->phase = dsp_phase;
235
voice->amp = dsp_amp;
236
237
return (dsp_i);
238
}
239
240
/* 4th order (cubic) interpolation.
241
* Returns number of samples processed (usually FLUID_BUFSIZE but could be
242
* smaller if end of sample occurs).
243
*/
244
int
245
fluid_rvoice_dsp_interpolate_4th_order(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
246
{
247
fluid_rvoice_dsp_t *voice = &rvoice->dsp;
248
fluid_phase_t dsp_phase = voice->phase;
249
fluid_phase_t dsp_phase_incr;
250
short int *dsp_data = voice->sample->data;
251
char *dsp_data24 = voice->sample->data24;
252
fluid_real_t dsp_amp = voice->amp;
253
fluid_real_t dsp_amp_incr = voice->amp_incr;
254
unsigned int dsp_i = 0;
255
unsigned int dsp_phase_index;
256
unsigned int start_index, end_index;
257
fluid_real_t start_point, end_point1, end_point2;
258
const fluid_real_t *FLUID_RESTRICT coeffs;
259
260
/* Convert playback "speed" floating point value to phase index/fract */
261
fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
262
263
/* last index before 4th interpolation point must be specially handled */
264
end_index = (looping ? voice->loopend - 1 : voice->end) - 2;
265
266
if(voice->has_looped) /* set start_index and start point if looped or not */
267
{
268
start_index = voice->loopstart;
269
start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1); /* last point in loop (wrap around) */
270
}
271
else
272
{
273
start_index = voice->start;
274
start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the point */
275
}
276
277
/* get points off the end (loop start if looping, duplicate point if end) */
278
if(looping)
279
{
280
end_point1 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart);
281
end_point2 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 1);
282
}
283
else
284
{
285
end_point1 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end);
286
end_point2 = end_point1;
287
}
288
289
while(1)
290
{
291
dsp_phase_index = fluid_phase_index(dsp_phase);
292
293
/* interpolate first sample point (start or loop start) if needed */
294
for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
295
{
296
fluid_real_t sample;
297
coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
298
299
sample = (coeffs[0] * start_point
300
+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
301
+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
302
+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2));
303
304
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
305
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
306
307
dsp_buf[dsp_i] = dsp_amp * sample;
308
309
/* increment phase and amplitude */
310
fluid_phase_incr(dsp_phase, dsp_phase_incr);
311
dsp_phase_index = fluid_phase_index(dsp_phase);
312
dsp_amp += dsp_amp_incr;
313
}
314
315
/* interpolate the sequence of sample points */
316
for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
317
{
318
fluid_real_t sample;
319
coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
320
321
sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
322
+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
323
+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
324
+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2));
325
326
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
327
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
328
329
dsp_buf[dsp_i] = dsp_amp * sample;
330
331
/* increment phase and amplitude */
332
fluid_phase_incr(dsp_phase, dsp_phase_incr);
333
dsp_phase_index = fluid_phase_index(dsp_phase);
334
dsp_amp += dsp_amp_incr;
335
}
336
337
/* break out if buffer filled */
338
if(dsp_i >= FLUID_BUFSIZE)
339
{
340
break;
341
}
342
343
end_index++; /* we're now interpolating the 2nd to last point */
344
345
/* interpolate within 2nd to last point */
346
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
347
{
348
fluid_real_t sample;
349
coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
350
351
sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
352
+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
353
+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
354
+ coeffs[3] * end_point1);
355
356
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
357
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
358
359
dsp_buf[dsp_i] = dsp_amp * sample;
360
361
/* increment phase and amplitude */
362
fluid_phase_incr(dsp_phase, dsp_phase_incr);
363
dsp_phase_index = fluid_phase_index(dsp_phase);
364
dsp_amp += dsp_amp_incr;
365
}
366
367
end_index++; /* we're now interpolating the last point */
368
369
/* interpolate within the last point */
370
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
371
{
372
fluid_real_t sample;
373
coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
374
375
376
sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
377
+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
378
+ coeffs[2] * end_point1
379
+ coeffs[3] * end_point2);
380
381
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
382
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
383
384
dsp_buf[dsp_i] = dsp_amp * sample;
385
386
/* increment phase and amplitude */
387
fluid_phase_incr(dsp_phase, dsp_phase_incr);
388
dsp_phase_index = fluid_phase_index(dsp_phase);
389
dsp_amp += dsp_amp_incr;
390
}
391
392
if(!looping)
393
{
394
break; /* break out if not looping (end of sample) */
395
}
396
397
/* go back to loop start */
398
if(dsp_phase_index > end_index)
399
{
400
fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
401
402
if(!voice->has_looped)
403
{
404
voice->has_looped = 1;
405
start_index = voice->loopstart;
406
start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1);
407
}
408
}
409
410
/* break out if filled buffer */
411
if(dsp_i >= FLUID_BUFSIZE)
412
{
413
break;
414
}
415
416
end_index -= 2; /* set end back to third to last sample point */
417
}
418
419
voice->phase = dsp_phase;
420
voice->amp = dsp_amp;
421
422
return (dsp_i);
423
}
424
425
/* 7th order interpolation.
426
* Returns number of samples processed (usually FLUID_BUFSIZE but could be
427
* smaller if end of sample occurs).
428
*/
429
int
430
fluid_rvoice_dsp_interpolate_7th_order(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
431
{
432
fluid_rvoice_dsp_t *voice = &rvoice->dsp;
433
fluid_phase_t dsp_phase = voice->phase;
434
fluid_phase_t dsp_phase_incr;
435
short int *dsp_data = voice->sample->data;
436
char *dsp_data24 = voice->sample->data24;
437
fluid_real_t dsp_amp = voice->amp;
438
fluid_real_t dsp_amp_incr = voice->amp_incr;
439
unsigned int dsp_i = 0;
440
unsigned int dsp_phase_index;
441
unsigned int start_index, end_index;
442
fluid_real_t start_points[3], end_points[3];
443
const fluid_real_t *FLUID_RESTRICT coeffs;
444
445
/* Convert playback "speed" floating point value to phase index/fract */
446
fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
447
448
/* add 1/2 sample to dsp_phase since 7th order interpolation is centered on
449
* the 4th sample point */
450
fluid_phase_incr(dsp_phase, (fluid_phase_t)0x80000000);
451
452
/* last index before 7th interpolation point must be specially handled */
453
end_index = (looping ? voice->loopend - 1 : voice->end) - 3;
454
455
if(voice->has_looped) /* set start_index and start point if looped or not */
456
{
457
start_index = voice->loopstart;
458
start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1);
459
start_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 2);
460
start_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 3);
461
}
462
else
463
{
464
start_index = voice->start;
465
start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the start point */
466
start_points[1] = start_points[0];
467
start_points[2] = start_points[0];
468
}
469
470
/* get the 3 points off the end (loop start if looping, duplicate point if end) */
471
if(looping)
472
{
473
end_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart);
474
end_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 1);
475
end_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 2);
476
}
477
else
478
{
479
end_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end);
480
end_points[1] = end_points[0];
481
end_points[2] = end_points[0];
482
}
483
484
while(1)
485
{
486
dsp_phase_index = fluid_phase_index(dsp_phase);
487
488
/* interpolate first sample point (start or loop start) if needed */
489
for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
490
{
491
fluid_real_t sample;
492
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
493
494
sample = (coeffs[0] * start_points[2]
495
+ coeffs[1] * start_points[1]
496
+ coeffs[2] * start_points[0]
497
+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
498
+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
499
+ coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)
500
+ coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));
501
502
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
503
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
504
505
dsp_buf[dsp_i] = dsp_amp * sample;
506
507
/* increment phase and amplitude */
508
fluid_phase_incr(dsp_phase, dsp_phase_incr);
509
dsp_phase_index = fluid_phase_index(dsp_phase);
510
dsp_amp += dsp_amp_incr;
511
}
512
513
start_index++;
514
515
/* interpolate 2nd to first sample point (start or loop start) if needed */
516
for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
517
{
518
fluid_real_t sample;
519
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
520
521
sample = (coeffs[0] * start_points[1]
522
+ coeffs[1] * start_points[0]
523
+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
524
+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
525
+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
526
+ coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)
527
+ coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));
528
529
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
530
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
531
532
dsp_buf[dsp_i] = dsp_amp * sample;
533
534
/* increment phase and amplitude */
535
fluid_phase_incr(dsp_phase, dsp_phase_incr);
536
dsp_phase_index = fluid_phase_index(dsp_phase);
537
dsp_amp += dsp_amp_incr;
538
}
539
540
start_index++;
541
542
/* interpolate 3rd to first sample point (start or loop start) if needed */
543
for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
544
{
545
fluid_real_t sample;
546
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
547
548
sample = (coeffs[0] * start_points[0]
549
+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)
550
+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
551
+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
552
+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
553
+ coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)
554
+ coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));
555
556
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
557
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
558
559
dsp_buf[dsp_i] = dsp_amp * sample;
560
561
/* increment phase and amplitude */
562
fluid_phase_incr(dsp_phase, dsp_phase_incr);
563
dsp_phase_index = fluid_phase_index(dsp_phase);
564
dsp_amp += dsp_amp_incr;
565
}
566
567
start_index -= 2; /* set back to original start index */
568
569
570
/* interpolate the sequence of sample points */
571
for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
572
{
573
fluid_real_t sample;
574
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
575
576
sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)
577
+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)
578
+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
579
+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
580
+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
581
+ coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)
582
+ coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));
583
584
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
585
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
586
587
dsp_buf[dsp_i] = dsp_amp * sample;
588
589
/* increment phase and amplitude */
590
fluid_phase_incr(dsp_phase, dsp_phase_incr);
591
dsp_phase_index = fluid_phase_index(dsp_phase);
592
dsp_amp += dsp_amp_incr;
593
}
594
595
/* break out if buffer filled */
596
if(dsp_i >= FLUID_BUFSIZE)
597
{
598
break;
599
}
600
601
end_index++; /* we're now interpolating the 3rd to last point */
602
603
/* interpolate within 3rd to last point */
604
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
605
{
606
fluid_real_t sample;
607
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
608
609
sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)
610
+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)
611
+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
612
+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
613
+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
614
+ coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)
615
+ coeffs[6] * end_points[0]);
616
617
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
618
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
619
620
dsp_buf[dsp_i] = dsp_amp * sample;
621
622
/* increment phase and amplitude */
623
fluid_phase_incr(dsp_phase, dsp_phase_incr);
624
dsp_phase_index = fluid_phase_index(dsp_phase);
625
dsp_amp += dsp_amp_incr;
626
}
627
628
end_index++; /* we're now interpolating the 2nd to last point */
629
630
/* interpolate within 2nd to last point */
631
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
632
{
633
fluid_real_t sample;
634
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
635
636
sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)
637
+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)
638
+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
639
+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
640
+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
641
+ coeffs[5] * end_points[0]
642
+ coeffs[6] * end_points[1]);
643
644
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
645
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
646
647
dsp_buf[dsp_i] = dsp_amp * sample;
648
649
/* increment phase and amplitude */
650
fluid_phase_incr(dsp_phase, dsp_phase_incr);
651
dsp_phase_index = fluid_phase_index(dsp_phase);
652
dsp_amp += dsp_amp_incr;
653
}
654
655
end_index++; /* we're now interpolating the last point */
656
657
/* interpolate within last point */
658
for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
659
{
660
fluid_real_t sample;
661
coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
662
663
sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)
664
+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)
665
+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
666
+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
667
+ coeffs[4] * end_points[0]
668
+ coeffs[5] * end_points[1]
669
+ coeffs[6] * end_points[2]);
670
671
fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);
672
fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);
673
674
dsp_buf[dsp_i] = dsp_amp * sample;
675
676
/* increment phase and amplitude */
677
fluid_phase_incr(dsp_phase, dsp_phase_incr);
678
dsp_phase_index = fluid_phase_index(dsp_phase);
679
dsp_amp += dsp_amp_incr;
680
}
681
682
if(!looping)
683
{
684
break; /* break out if not looping (end of sample) */
685
}
686
687
/* go back to loop start */
688
if(dsp_phase_index > end_index)
689
{
690
fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
691
692
if(!voice->has_looped)
693
{
694
voice->has_looped = 1;
695
start_index = voice->loopstart;
696
start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1);
697
start_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 2);
698
start_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 3);
699
}
700
}
701
702
/* break out if filled buffer */
703
if(dsp_i >= FLUID_BUFSIZE)
704
{
705
break;
706
}
707
708
end_index -= 3; /* set end back to 4th to last sample point */
709
}
710
711
/* sub 1/2 sample from dsp_phase since 7th order interpolation is centered on
712
* the 4th sample point (correct back to real value) */
713
fluid_phase_decr(dsp_phase, (fluid_phase_t)0x80000000);
714
715
voice->phase = dsp_phase;
716
voice->amp = dsp_amp;
717
718
return (dsp_i);
719
}
720
721