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 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.
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.
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
21 #include "fluidsynth_priv.h"
22 #include "fluid_phase.h"
23 #include "fluid_rvoice.h"
24 #include "fluid_sys.h"
25 #include "fluid_rvoice_dsp_tables.c"
29 * Interpolates audio data (obtains values between the samples of the original
32 * Variables loaded from the voice structure (assigned in fluid_rvoice_write()):
33 * - dsp_data: Pointer to the original waveform data
34 * - dsp_phase: The position in the original waveform data.
35 * This has an integer and a fractional part (between samples).
36 * - dsp_phase_incr: For each output sample, the position in the original
37 * waveform advances by dsp_phase_incr. This also has an integer
38 * part and a fractional part.
39 * If a sample is played at root pitch (no pitch change),
40 * dsp_phase_incr is integer=1 and fractional=0.
41 * - dsp_amp: The current amplitude envelope value.
42 * - dsp_amp_incr: The changing rate of the amplitude envelope.
44 * A couple of variables are used internally, their results are discarded:
45 * - dsp_i: Index through the output buffer
46 * - dsp_buf: Output buffer of floating point values (FLUID_BUFSIZE in length)
49 /* Interpolation (find a value between two samples of the original waveform) */
51 static FLUID_INLINE fluid_real_t
52 fluid_rvoice_get_float_sample(const short int *dsp_msb, const char *dsp_lsb, unsigned int idx)
54 int32_t sample = fluid_rvoice_get_sample(dsp_msb, dsp_lsb, idx);
55 return (fluid_real_t)sample;
58 /* No interpolation. Just take the sample, which is closest to
59 * the playback pointer. Questionable quality, but very
62 fluid_rvoice_dsp_interpolate_none(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
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;
74 /* Convert playback "speed" floating point value to phase index/fract */
75 fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
77 end_index = looping ? voice->loopend - 1 : voice->end;
81 dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */
83 /* interpolate sequence of sample points */
84 for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
86 dsp_buf[dsp_i] = dsp_amp * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index);
88 /* increment phase and amplitude */
89 fluid_phase_incr(dsp_phase, dsp_phase_incr);
90 dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */
91 dsp_amp += dsp_amp_incr;
94 /* break out if not looping (buffer may not be full) */
100 /* go back to loop start */
101 if(dsp_phase_index > end_index)
103 fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
104 voice->has_looped = 1;
107 /* break out if filled buffer */
108 if(dsp_i >= FLUID_BUFSIZE)
114 voice->phase = dsp_phase;
115 voice->amp = dsp_amp;
120 /* Straight line interpolation.
121 * Returns number of samples processed (usually FLUID_BUFSIZE but could be
122 * smaller if end of sample occurs).
125 fluid_rvoice_dsp_interpolate_linear(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
127 fluid_phase_t dsp_phase = voice->phase;
128 fluid_phase_t dsp_phase_incr;
129 short int *dsp_data = voice->sample->data;
130 char *dsp_data24 = voice->sample->data24;
131 fluid_real_t dsp_amp = voice->amp;
132 fluid_real_t dsp_amp_incr = voice->amp_incr;
133 unsigned int dsp_i = 0;
134 unsigned int dsp_phase_index;
135 unsigned int end_index;
137 const fluid_real_t *FLUID_RESTRICT coeffs;
139 /* Convert playback "speed" floating point value to phase index/fract */
140 fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
142 /* last index before 2nd interpolation point must be specially handled */
143 end_index = (looping ? voice->loopend - 1 : voice->end) - 1;
145 /* 2nd interpolation point to use at end of loop or sample */
148 point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart); /* loop start */
152 point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end); /* duplicate end for samples no longer looping */
157 dsp_phase_index = fluid_phase_index(dsp_phase);
159 /* interpolate the sequence of sample points */
160 for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
162 coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow(dsp_phase)];
163 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
164 + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1));
166 /* increment phase and amplitude */
167 fluid_phase_incr(dsp_phase, dsp_phase_incr);
168 dsp_phase_index = fluid_phase_index(dsp_phase);
169 dsp_amp += dsp_amp_incr;
172 /* break out if buffer filled */
173 if(dsp_i >= FLUID_BUFSIZE)
178 end_index++; /* we're now interpolating the last point */
180 /* interpolate within last point */
181 for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
183 coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow(dsp_phase)];
184 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
185 + coeffs[1] * point);
187 /* increment phase and amplitude */
188 fluid_phase_incr(dsp_phase, dsp_phase_incr);
189 dsp_phase_index = fluid_phase_index(dsp_phase);
190 dsp_amp += dsp_amp_incr; /* increment amplitude */
195 break; /* break out if not looping (end of sample) */
198 /* go back to loop start (if past */
199 if(dsp_phase_index > end_index)
201 fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
202 voice->has_looped = 1;
205 /* break out if filled buffer */
206 if(dsp_i >= FLUID_BUFSIZE)
211 end_index--; /* set end back to second to last sample point */
214 voice->phase = dsp_phase;
215 voice->amp = dsp_amp;
220 /* 4th order (cubic) interpolation.
221 * Returns number of samples processed (usually FLUID_BUFSIZE but could be
222 * smaller if end of sample occurs).
225 fluid_rvoice_dsp_interpolate_4th_order(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
227 fluid_phase_t dsp_phase = voice->phase;
228 fluid_phase_t dsp_phase_incr;
229 short int *dsp_data = voice->sample->data;
230 char *dsp_data24 = voice->sample->data24;
231 fluid_real_t dsp_amp = voice->amp;
232 fluid_real_t dsp_amp_incr = voice->amp_incr;
233 unsigned int dsp_i = 0;
234 unsigned int dsp_phase_index;
235 unsigned int start_index, end_index;
236 fluid_real_t start_point, end_point1, end_point2;
237 const fluid_real_t *FLUID_RESTRICT coeffs;
239 /* Convert playback "speed" floating point value to phase index/fract */
240 fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
242 /* last index before 4th interpolation point must be specially handled */
243 end_index = (looping ? voice->loopend - 1 : voice->end) - 2;
245 if(voice->has_looped) /* set start_index and start point if looped or not */
247 start_index = voice->loopstart;
248 start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1); /* last point in loop (wrap around) */
252 start_index = voice->start;
253 start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the point */
256 /* get points off the end (loop start if looping, duplicate point if end) */
259 end_point1 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart);
260 end_point2 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 1);
264 end_point1 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end);
265 end_point2 = end_point1;
270 dsp_phase_index = fluid_phase_index(dsp_phase);
272 /* interpolate first sample point (start or loop start) if needed */
273 for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
275 coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
276 dsp_buf[dsp_i] = dsp_amp *
277 (coeffs[0] * start_point
278 + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
279 + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
280 + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2));
282 /* increment phase and amplitude */
283 fluid_phase_incr(dsp_phase, dsp_phase_incr);
284 dsp_phase_index = fluid_phase_index(dsp_phase);
285 dsp_amp += dsp_amp_incr;
288 /* interpolate the sequence of sample points */
289 for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
291 coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
292 dsp_buf[dsp_i] = dsp_amp *
293 (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
294 + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
295 + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
296 + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2));
298 /* increment phase and amplitude */
299 fluid_phase_incr(dsp_phase, dsp_phase_incr);
300 dsp_phase_index = fluid_phase_index(dsp_phase);
301 dsp_amp += dsp_amp_incr;
304 /* break out if buffer filled */
305 if(dsp_i >= FLUID_BUFSIZE)
310 end_index++; /* we're now interpolating the 2nd to last point */
312 /* interpolate within 2nd to last point */
313 for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
315 coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
316 dsp_buf[dsp_i] = dsp_amp *
317 (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
318 + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
319 + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
320 + coeffs[3] * end_point1);
322 /* increment phase and amplitude */
323 fluid_phase_incr(dsp_phase, dsp_phase_incr);
324 dsp_phase_index = fluid_phase_index(dsp_phase);
325 dsp_amp += dsp_amp_incr;
328 end_index++; /* we're now interpolating the last point */
330 /* interpolate within the last point */
331 for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
333 coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];
334 dsp_buf[dsp_i] = dsp_amp *
335 (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
336 + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
337 + coeffs[2] * end_point1
338 + coeffs[3] * end_point2);
340 /* increment phase and amplitude */
341 fluid_phase_incr(dsp_phase, dsp_phase_incr);
342 dsp_phase_index = fluid_phase_index(dsp_phase);
343 dsp_amp += dsp_amp_incr;
348 break; /* break out if not looping (end of sample) */
351 /* go back to loop start */
352 if(dsp_phase_index > end_index)
354 fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
356 if(!voice->has_looped)
358 voice->has_looped = 1;
359 start_index = voice->loopstart;
360 start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1);
364 /* break out if filled buffer */
365 if(dsp_i >= FLUID_BUFSIZE)
370 end_index -= 2; /* set end back to third to last sample point */
373 voice->phase = dsp_phase;
374 voice->amp = dsp_amp;
379 /* 7th order interpolation.
380 * Returns number of samples processed (usually FLUID_BUFSIZE but could be
381 * smaller if end of sample occurs).
384 fluid_rvoice_dsp_interpolate_7th_order(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)
386 fluid_phase_t dsp_phase = voice->phase;
387 fluid_phase_t dsp_phase_incr;
388 short int *dsp_data = voice->sample->data;
389 char *dsp_data24 = voice->sample->data24;
390 fluid_real_t dsp_amp = voice->amp;
391 fluid_real_t dsp_amp_incr = voice->amp_incr;
392 unsigned int dsp_i = 0;
393 unsigned int dsp_phase_index;
394 unsigned int start_index, end_index;
395 fluid_real_t start_points[3], end_points[3];
396 const fluid_real_t *FLUID_RESTRICT coeffs;
398 /* Convert playback "speed" floating point value to phase index/fract */
399 fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);
401 /* add 1/2 sample to dsp_phase since 7th order interpolation is centered on
402 * the 4th sample point */
403 fluid_phase_incr(dsp_phase, (fluid_phase_t)0x80000000);
405 /* last index before 7th interpolation point must be specially handled */
406 end_index = (looping ? voice->loopend - 1 : voice->end) - 3;
408 if(voice->has_looped) /* set start_index and start point if looped or not */
410 start_index = voice->loopstart;
411 start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1);
412 start_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 2);
413 start_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 3);
417 start_index = voice->start;
418 start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the start point */
419 start_points[1] = start_points[0];
420 start_points[2] = start_points[0];
423 /* get the 3 points off the end (loop start if looping, duplicate point if end) */
426 end_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart);
427 end_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 1);
428 end_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 2);
432 end_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end);
433 end_points[1] = end_points[0];
434 end_points[2] = end_points[0];
439 dsp_phase_index = fluid_phase_index(dsp_phase);
441 /* interpolate first sample point (start or loop start) if needed */
442 for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
444 coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
446 dsp_buf[dsp_i] = dsp_amp
447 * (coeffs[0] * start_points[2]
448 + coeffs[1] * start_points[1]
449 + coeffs[2] * start_points[0]
450 + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
451 + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
452 + coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)
453 + coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));
455 /* increment phase and amplitude */
456 fluid_phase_incr(dsp_phase, dsp_phase_incr);
457 dsp_phase_index = fluid_phase_index(dsp_phase);
458 dsp_amp += dsp_amp_incr;
463 /* interpolate 2nd to first sample point (start or loop start) if needed */
464 for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
466 coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
468 dsp_buf[dsp_i] = dsp_amp
469 * (coeffs[0] * start_points[1]
470 + coeffs[1] * start_points[0]
471 + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
472 + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
473 + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
474 + coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)
475 + coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));
477 /* increment phase and amplitude */
478 fluid_phase_incr(dsp_phase, dsp_phase_incr);
479 dsp_phase_index = fluid_phase_index(dsp_phase);
480 dsp_amp += dsp_amp_incr;
485 /* interpolate 3rd to first sample point (start or loop start) if needed */
486 for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
488 coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
490 dsp_buf[dsp_i] = dsp_amp
491 * (coeffs[0] * start_points[0]
492 + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)
493 + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
494 + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
495 + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
496 + coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)
497 + coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));
499 /* increment phase and amplitude */
500 fluid_phase_incr(dsp_phase, dsp_phase_incr);
501 dsp_phase_index = fluid_phase_index(dsp_phase);
502 dsp_amp += dsp_amp_incr;
505 start_index -= 2; /* set back to original start index */
508 /* interpolate the sequence of sample points */
509 for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)
511 coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
513 dsp_buf[dsp_i] = dsp_amp
514 * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)
515 + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)
516 + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
517 + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
518 + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
519 + coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)
520 + coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));
522 /* increment phase and amplitude */
523 fluid_phase_incr(dsp_phase, dsp_phase_incr);
524 dsp_phase_index = fluid_phase_index(dsp_phase);
525 dsp_amp += dsp_amp_incr;
528 /* break out if buffer filled */
529 if(dsp_i >= FLUID_BUFSIZE)
534 end_index++; /* we're now interpolating the 3rd to last point */
536 /* interpolate within 3rd to last point */
537 for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
539 coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
541 dsp_buf[dsp_i] = dsp_amp
542 * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)
543 + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)
544 + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
545 + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
546 + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
547 + coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)
548 + coeffs[6] * end_points[0]);
550 /* increment phase and amplitude */
551 fluid_phase_incr(dsp_phase, dsp_phase_incr);
552 dsp_phase_index = fluid_phase_index(dsp_phase);
553 dsp_amp += dsp_amp_incr;
556 end_index++; /* we're now interpolating the 2nd to last point */
558 /* interpolate within 2nd to last point */
559 for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)
561 coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];
563 dsp_buf[dsp_i] = dsp_amp
564 * (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)
565 + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)
566 + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
567 + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
568 + coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)
569 + coeffs[5] * end_points[0]
570 + coeffs[6] * end_points[1]);
572 /* increment phase and amplitude */
573 fluid_phase_incr(dsp_phase, dsp_phase_incr);
574 dsp_phase_index = fluid_phase_index(dsp_phase);
575 dsp_amp += dsp_amp_incr;
578 end_index++; /* we're now interpolating the last point */
580 /* interpolate within 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_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)
587 + coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)
588 + coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)
589 + coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)
590 + coeffs[4] * end_points[0]
591 + coeffs[5] * end_points[1]
592 + coeffs[6] * end_points[2]);
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;
602 break; /* break out if not looping (end of sample) */
605 /* go back to loop start */
606 if(dsp_phase_index > end_index)
608 fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);
610 if(!voice->has_looped)
612 voice->has_looped = 1;
613 start_index = voice->loopstart;
614 start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1);
615 start_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 2);
616 start_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 3);
620 /* break out if filled buffer */
621 if(dsp_i >= FLUID_BUFSIZE)
626 end_index -= 3; /* set end back to 4th to last sample point */
629 /* sub 1/2 sample from dsp_phase since 7th order interpolation is centered on
630 * the 4th sample point (correct back to real value) */
631 fluid_phase_decr(dsp_phase, (fluid_phase_t)0x80000000);
633 voice->phase = dsp_phase;
634 voice->amp = dsp_amp;