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
fluid_rvoice_get_float_sample(const short int * dsp_msb,const char * dsp_lsb,unsigned int idx)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
fluid_rvoice_dsp_interpolate_none(fluid_rvoice_dsp_t * voice,fluid_real_t * FLUID_RESTRICT dsp_buf,int looping)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
fluid_rvoice_dsp_interpolate_linear(fluid_rvoice_dsp_t * voice,fluid_real_t * FLUID_RESTRICT dsp_buf,int looping)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
fluid_rvoice_dsp_interpolate_4th_order(fluid_rvoice_dsp_t * voice,fluid_real_t * FLUID_RESTRICT dsp_buf,int looping)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
fluid_rvoice_dsp_interpolate_7th_order(fluid_rvoice_dsp_t * voice,fluid_real_t * FLUID_RESTRICT dsp_buf,int looping)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