1 /* FluidSynth - A Software Synthesizer
3 * Copyright (C) 2003 Peter Hanappe and others.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public License
7 * as published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
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 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library 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
21 #include "fluidsynth_priv.h"
22 #include "fluid_phase.h"
23 #include "fluid_rvoice.h"
24 #include "fluid_sys.h"
28 * Interpolates audio data (obtains values between the samples of the original
31 * Variables loaded from the voice structure (assigned in fluid_voice_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.
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)
48 /* Interpolation (find a value between two samples of the original waveform) */
50 /* Linear interpolation table (2 coefficients centered on 1st) */
51 static fluid_real_t interp_coeff_linear[FLUID_INTERP_MAX][2];
53 /* 4th order (cubic) interpolation table (4 coefficients centered on 2nd) */
54 static fluid_real_t interp_coeff[FLUID_INTERP_MAX][4];
56 /* 7th order interpolation (7 coefficients centered on 3rd) */
57 static fluid_real_t sinc_table7[FLUID_INTERP_MAX][7];
60 #define SINC_INTERP_ORDER 7 /* 7th order constant */
63 /* Initializes interpolation tables */
64 void fluid_rvoice_dsp_config (void)
70 /* Initialize the coefficients for the interpolation. The math comes
71 * from a mail, posted by Olli Niemitalo to the music-dsp mailing
72 * list (I found it in the music-dsp archives
73 * http://www.smartelectronix.com/musicdsp/). */
75 for (i = 0; i < FLUID_INTERP_MAX; i++)
77 x = (double) i / (double) FLUID_INTERP_MAX;
79 interp_coeff[i][0] = (fluid_real_t)(x * (-0.5 + x * (1 - 0.5 * x)));
80 interp_coeff[i][1] = (fluid_real_t)(1.0 + x * x * (1.5 * x - 2.5));
81 interp_coeff[i][2] = (fluid_real_t)(x * (0.5 + x * (2.0 - 1.5 * x)));
82 interp_coeff[i][3] = (fluid_real_t)(0.5 * x * x * (x - 1.0));
84 interp_coeff_linear[i][0] = (fluid_real_t)(1.0 - x);
85 interp_coeff_linear[i][1] = (fluid_real_t)x;
88 /* i: Offset in terms of whole samples */
89 for (i = 0; i < SINC_INTERP_ORDER; i++)
90 { /* i2: Offset in terms of fractional samples ('subsamples') */
91 for (i2 = 0; i2 < FLUID_INTERP_MAX; i2++)
93 /* center on middle of table */
94 i_shifted = (double)i - ((double)SINC_INTERP_ORDER / 2.0)
95 + (double)i2 / (double)FLUID_INTERP_MAX;
97 /* sinc(0) cannot be calculated straightforward (limit needed for 0/0) */
98 if (fabs (i_shifted) > 0.000001)
100 v = (fluid_real_t)sin (i_shifted * M_PI) / (M_PI * i_shifted);
102 v *= (fluid_real_t)0.5 * (1.0 + cos (2.0 * M_PI * i_shifted / (fluid_real_t)SINC_INTERP_ORDER));
106 sinc_table7[FLUID_INTERP_MAX - i2 - 1][i] = v;
111 for (i = 0; i < FLUID_INTERP_MAX; i++)
113 printf ("%d %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f\n",
114 i, sinc_table7[0][i], sinc_table7[1][i], sinc_table7[2][i],
115 sinc_table7[3][i], sinc_table7[4][i], sinc_table7[5][i], sinc_table7[6][i]);
119 fluid_check_fpe("interpolation table calculation");
122 /* No interpolation. Just take the sample, which is closest to
123 * the playback pointer. Questionable quality, but very
126 fluid_rvoice_dsp_interpolate_none (fluid_rvoice_dsp_t *voice)
128 fluid_phase_t dsp_phase = voice->phase;
129 fluid_phase_t dsp_phase_incr;
130 short int *dsp_data = voice->sample->data;
131 fluid_real_t *dsp_buf = voice->dsp_buf;
132 fluid_real_t dsp_amp = voice->amp;
133 fluid_real_t dsp_amp_incr = voice->amp_incr;
134 unsigned int dsp_i = 0;
135 unsigned int dsp_phase_index;
136 unsigned int end_index;
139 /* Convert playback "speed" floating point value to phase index/fract */
140 fluid_phase_set_float (dsp_phase_incr, voice->phase_incr);
142 /* voice is currently looping? */
143 looping = voice->is_looping;
145 end_index = looping ? voice->loopend - 1 : voice->end;
149 dsp_phase_index = fluid_phase_index_round (dsp_phase); /* round to nearest point */
151 /* interpolate sequence of sample points */
152 for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
154 dsp_buf[dsp_i] = dsp_amp * dsp_data[dsp_phase_index];
156 /* increment phase and amplitude */
157 fluid_phase_incr (dsp_phase, dsp_phase_incr);
158 dsp_phase_index = fluid_phase_index_round (dsp_phase); /* round to nearest point */
159 dsp_amp += dsp_amp_incr;
162 /* break out if not looping (buffer may not be full) */
165 /* go back to loop start */
166 if (dsp_phase_index > end_index)
168 fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart);
169 voice->has_looped = 1;
172 /* break out if filled buffer */
173 if (dsp_i >= FLUID_BUFSIZE) break;
176 voice->phase = dsp_phase;
177 voice->amp = dsp_amp;
182 /* Straight line interpolation.
183 * Returns number of samples processed (usually FLUID_BUFSIZE but could be
184 * smaller if end of sample occurs).
187 fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice)
189 fluid_phase_t dsp_phase = voice->phase;
190 fluid_phase_t dsp_phase_incr;
191 short int *dsp_data = voice->sample->data;
192 fluid_real_t *dsp_buf = voice->dsp_buf;
193 fluid_real_t dsp_amp = voice->amp;
194 fluid_real_t dsp_amp_incr = voice->amp_incr;
195 unsigned int dsp_i = 0;
196 unsigned int dsp_phase_index;
197 unsigned int end_index;
199 fluid_real_t *coeffs;
202 /* Convert playback "speed" floating point value to phase index/fract */
203 fluid_phase_set_float (dsp_phase_incr, voice->phase_incr);
205 /* voice is currently looping? */
206 looping = voice->is_looping;
208 /* last index before 2nd interpolation point must be specially handled */
209 end_index = (looping ? voice->loopend - 1 : voice->end) - 1;
211 /* 2nd interpolation point to use at end of loop or sample */
212 if (looping) point = dsp_data[voice->loopstart]; /* loop start */
213 else point = dsp_data[voice->end]; /* duplicate end for samples no longer looping */
217 dsp_phase_index = fluid_phase_index (dsp_phase);
219 /* interpolate the sequence of sample points */
220 for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
222 coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow (dsp_phase)];
223 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index]
224 + coeffs[1] * dsp_data[dsp_phase_index+1]);
226 /* increment phase and amplitude */
227 fluid_phase_incr (dsp_phase, dsp_phase_incr);
228 dsp_phase_index = fluid_phase_index (dsp_phase);
229 dsp_amp += dsp_amp_incr;
232 /* break out if buffer filled */
233 if (dsp_i >= FLUID_BUFSIZE) break;
235 end_index++; /* we're now interpolating the last point */
237 /* interpolate within last point */
238 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
240 coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow (dsp_phase)];
241 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index]
242 + coeffs[1] * point);
244 /* increment phase and amplitude */
245 fluid_phase_incr (dsp_phase, dsp_phase_incr);
246 dsp_phase_index = fluid_phase_index (dsp_phase);
247 dsp_amp += dsp_amp_incr; /* increment amplitude */
250 if (!looping) break; /* break out if not looping (end of sample) */
252 /* go back to loop start (if past */
253 if (dsp_phase_index > end_index)
255 fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart);
256 voice->has_looped = 1;
259 /* break out if filled buffer */
260 if (dsp_i >= FLUID_BUFSIZE) break;
262 end_index--; /* set end back to second to last sample point */
265 voice->phase = dsp_phase;
266 voice->amp = dsp_amp;
271 /* 4th order (cubic) interpolation.
272 * Returns number of samples processed (usually FLUID_BUFSIZE but could be
273 * smaller if end of sample occurs).
276 fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice)
278 fluid_phase_t dsp_phase = voice->phase;
279 fluid_phase_t dsp_phase_incr;
280 short int *dsp_data = voice->sample->data;
281 fluid_real_t *dsp_buf = voice->dsp_buf;
282 fluid_real_t dsp_amp = voice->amp;
283 fluid_real_t dsp_amp_incr = voice->amp_incr;
284 unsigned int dsp_i = 0;
285 unsigned int dsp_phase_index;
286 unsigned int start_index, end_index;
287 short int start_point, end_point1, end_point2;
288 fluid_real_t *coeffs;
291 /* Convert playback "speed" floating point value to phase index/fract */
292 fluid_phase_set_float (dsp_phase_incr, voice->phase_incr);
294 /* voice is currently looping? */
295 looping = voice->is_looping;
297 /* last index before 4th interpolation point must be specially handled */
298 end_index = (looping ? voice->loopend - 1 : voice->end) - 2;
300 if (voice->has_looped) /* set start_index and start point if looped or not */
302 start_index = voice->loopstart;
303 start_point = dsp_data[voice->loopend - 1]; /* last point in loop (wrap around) */
307 start_index = voice->start;
308 start_point = dsp_data[voice->start]; /* just duplicate the point */
311 /* get points off the end (loop start if looping, duplicate point if end) */
314 end_point1 = dsp_data[voice->loopstart];
315 end_point2 = dsp_data[voice->loopstart + 1];
319 end_point1 = dsp_data[voice->end];
320 end_point2 = end_point1;
325 dsp_phase_index = fluid_phase_index (dsp_phase);
327 /* interpolate first sample point (start or loop start) if needed */
328 for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
330 coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)];
331 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * start_point
332 + coeffs[1] * dsp_data[dsp_phase_index]
333 + coeffs[2] * dsp_data[dsp_phase_index+1]
334 + coeffs[3] * dsp_data[dsp_phase_index+2]);
336 /* increment phase and amplitude */
337 fluid_phase_incr (dsp_phase, dsp_phase_incr);
338 dsp_phase_index = fluid_phase_index (dsp_phase);
339 dsp_amp += dsp_amp_incr;
342 /* interpolate the sequence of sample points */
343 for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
345 coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)];
346 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1]
347 + coeffs[1] * dsp_data[dsp_phase_index]
348 + coeffs[2] * dsp_data[dsp_phase_index+1]
349 + coeffs[3] * dsp_data[dsp_phase_index+2]);
351 /* increment phase and amplitude */
352 fluid_phase_incr (dsp_phase, dsp_phase_incr);
353 dsp_phase_index = fluid_phase_index (dsp_phase);
354 dsp_amp += dsp_amp_incr;
357 /* break out if buffer filled */
358 if (dsp_i >= FLUID_BUFSIZE) break;
360 end_index++; /* we're now interpolating the 2nd to last point */
362 /* interpolate within 2nd to last point */
363 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
365 coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)];
366 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1]
367 + coeffs[1] * dsp_data[dsp_phase_index]
368 + coeffs[2] * dsp_data[dsp_phase_index+1]
369 + coeffs[3] * end_point1);
371 /* increment phase and amplitude */
372 fluid_phase_incr (dsp_phase, dsp_phase_incr);
373 dsp_phase_index = fluid_phase_index (dsp_phase);
374 dsp_amp += dsp_amp_incr;
377 end_index++; /* we're now interpolating the last point */
379 /* interpolate within the last point */
380 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
382 coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)];
383 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1]
384 + coeffs[1] * dsp_data[dsp_phase_index]
385 + coeffs[2] * end_point1
386 + coeffs[3] * end_point2);
388 /* increment phase and amplitude */
389 fluid_phase_incr (dsp_phase, dsp_phase_incr);
390 dsp_phase_index = fluid_phase_index (dsp_phase);
391 dsp_amp += dsp_amp_incr;
394 if (!looping) break; /* break out if not looping (end of sample) */
396 /* go back to loop start */
397 if (dsp_phase_index > end_index)
399 fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart);
401 if (!voice->has_looped)
403 voice->has_looped = 1;
404 start_index = voice->loopstart;
405 start_point = dsp_data[voice->loopend - 1];
409 /* break out if filled buffer */
410 if (dsp_i >= FLUID_BUFSIZE) break;
412 end_index -= 2; /* set end back to third to last sample point */
415 voice->phase = dsp_phase;
416 voice->amp = dsp_amp;
421 /* 7th order interpolation.
422 * Returns number of samples processed (usually FLUID_BUFSIZE but could be
423 * smaller if end of sample occurs).
426 fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice)
428 fluid_phase_t dsp_phase = voice->phase;
429 fluid_phase_t dsp_phase_incr;
430 short int *dsp_data = voice->sample->data;
431 fluid_real_t *dsp_buf = voice->dsp_buf;
432 fluid_real_t dsp_amp = voice->amp;
433 fluid_real_t dsp_amp_incr = voice->amp_incr;
434 unsigned int dsp_i = 0;
435 unsigned int dsp_phase_index;
436 unsigned int start_index, end_index;
437 short int start_points[3];
438 short int end_points[3];
439 fluid_real_t *coeffs;
442 /* Convert playback "speed" floating point value to phase index/fract */
443 fluid_phase_set_float (dsp_phase_incr, voice->phase_incr);
445 /* add 1/2 sample to dsp_phase since 7th order interpolation is centered on
446 * the 4th sample point */
447 fluid_phase_incr (dsp_phase, (fluid_phase_t)0x80000000);
449 /* voice is currently looping? */
450 looping = voice->is_looping;
452 /* last index before 7th interpolation point must be specially handled */
453 end_index = (looping ? voice->loopend - 1 : voice->end) - 3;
455 if (voice->has_looped) /* set start_index and start point if looped or not */
457 start_index = voice->loopstart;
458 start_points[0] = dsp_data[voice->loopend - 1];
459 start_points[1] = dsp_data[voice->loopend - 2];
460 start_points[2] = dsp_data[voice->loopend - 3];
464 start_index = voice->start;
465 start_points[0] = dsp_data[voice->start]; /* just duplicate the start point */
466 start_points[1] = start_points[0];
467 start_points[2] = start_points[0];
470 /* get the 3 points off the end (loop start if looping, duplicate point if end) */
473 end_points[0] = dsp_data[voice->loopstart];
474 end_points[1] = dsp_data[voice->loopstart + 1];
475 end_points[2] = dsp_data[voice->loopstart + 2];
479 end_points[0] = dsp_data[voice->end];
480 end_points[1] = end_points[0];
481 end_points[2] = end_points[0];
486 dsp_phase_index = fluid_phase_index (dsp_phase);
488 /* interpolate first sample point (start or loop start) if needed */
489 for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
491 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)];
493 dsp_buf[dsp_i] = dsp_amp
494 * (coeffs[0] * (fluid_real_t)start_points[2]
495 + coeffs[1] * (fluid_real_t)start_points[1]
496 + coeffs[2] * (fluid_real_t)start_points[0]
497 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
498 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
499 + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2]
500 + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]);
502 /* increment phase and amplitude */
503 fluid_phase_incr (dsp_phase, dsp_phase_incr);
504 dsp_phase_index = fluid_phase_index (dsp_phase);
505 dsp_amp += dsp_amp_incr;
510 /* interpolate 2nd to first sample point (start or loop start) if needed */
511 for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
513 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)];
515 dsp_buf[dsp_i] = dsp_amp
516 * (coeffs[0] * (fluid_real_t)start_points[1]
517 + coeffs[1] * (fluid_real_t)start_points[0]
518 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
519 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
520 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
521 + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2]
522 + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]);
524 /* increment phase and amplitude */
525 fluid_phase_incr (dsp_phase, dsp_phase_incr);
526 dsp_phase_index = fluid_phase_index (dsp_phase);
527 dsp_amp += dsp_amp_incr;
532 /* interpolate 3rd to first sample point (start or loop start) if needed */
533 for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
535 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)];
537 dsp_buf[dsp_i] = dsp_amp
538 * (coeffs[0] * (fluid_real_t)start_points[0]
539 + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2]
540 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
541 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
542 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
543 + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2]
544 + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]);
546 /* increment phase and amplitude */
547 fluid_phase_incr (dsp_phase, dsp_phase_incr);
548 dsp_phase_index = fluid_phase_index (dsp_phase);
549 dsp_amp += dsp_amp_incr;
552 start_index -= 2; /* set back to original start index */
555 /* interpolate the sequence of sample points */
556 for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
558 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)];
560 dsp_buf[dsp_i] = dsp_amp
561 * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3]
562 + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2]
563 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
564 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
565 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
566 + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2]
567 + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]);
569 /* increment phase and amplitude */
570 fluid_phase_incr (dsp_phase, dsp_phase_incr);
571 dsp_phase_index = fluid_phase_index (dsp_phase);
572 dsp_amp += dsp_amp_incr;
575 /* break out if buffer filled */
576 if (dsp_i >= FLUID_BUFSIZE) break;
578 end_index++; /* we're now interpolating the 3rd to last point */
580 /* interpolate within 3rd to last point */
581 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
583 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)];
585 dsp_buf[dsp_i] = dsp_amp
586 * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3]
587 + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2]
588 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
589 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
590 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
591 + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2]
592 + coeffs[6] * (fluid_real_t)end_points[0]);
594 /* increment phase and amplitude */
595 fluid_phase_incr (dsp_phase, dsp_phase_incr);
596 dsp_phase_index = fluid_phase_index (dsp_phase);
597 dsp_amp += dsp_amp_incr;
600 end_index++; /* we're now interpolating the 2nd to last point */
602 /* interpolate within 2nd to last point */
603 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
605 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)];
607 dsp_buf[dsp_i] = dsp_amp
608 * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3]
609 + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2]
610 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
611 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
612 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1]
613 + coeffs[5] * (fluid_real_t)end_points[0]
614 + coeffs[6] * (fluid_real_t)end_points[1]);
616 /* increment phase and amplitude */
617 fluid_phase_incr (dsp_phase, dsp_phase_incr);
618 dsp_phase_index = fluid_phase_index (dsp_phase);
619 dsp_amp += dsp_amp_incr;
622 end_index++; /* we're now interpolating the last point */
624 /* interpolate within last point */
625 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
627 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)];
629 dsp_buf[dsp_i] = dsp_amp
630 * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3]
631 + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2]
632 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1]
633 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index]
634 + coeffs[4] * (fluid_real_t)end_points[0]
635 + coeffs[5] * (fluid_real_t)end_points[1]
636 + coeffs[6] * (fluid_real_t)end_points[2]);
638 /* increment phase and amplitude */
639 fluid_phase_incr (dsp_phase, dsp_phase_incr);
640 dsp_phase_index = fluid_phase_index (dsp_phase);
641 dsp_amp += dsp_amp_incr;
644 if (!looping) break; /* break out if not looping (end of sample) */
646 /* go back to loop start */
647 if (dsp_phase_index > end_index)
649 fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart);
651 if (!voice->has_looped)
653 voice->has_looped = 1;
654 start_index = voice->loopstart;
655 start_points[0] = dsp_data[voice->loopend - 1];
656 start_points[1] = dsp_data[voice->loopend - 2];
657 start_points[2] = dsp_data[voice->loopend - 3];
661 /* break out if filled buffer */
662 if (dsp_i >= FLUID_BUFSIZE) break;
664 end_index -= 3; /* set end back to 4th to last sample point */
667 /* sub 1/2 sample from dsp_phase since 7th order interpolation is centered on
668 * the 4th sample point (correct back to real value) */
669 fluid_phase_decr (dsp_phase, (fluid_phase_t)0x80000000);
671 voice->phase = dsp_phase;
672 voice->amp = dsp_amp;