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