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 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. 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 * Library General Public License for more details. 14 * 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 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 * 02111-1307, USA 19 */ 20 21#include "fluidsynth_priv.h" 22#include "fluid_phase.h" 23 24/* Purpose: 25 * 26 * Interpolates audio data (obtains values between the samples of the original 27 * waveform data). 28 * 29 * Variables loaded from the voice structure (assigned in fluid_voice_write()): 30 * - dsp_data: Pointer to the original waveform data 31 * - dsp_phase: The position in the original waveform data. 32 * This has an integer and a fractional part (between samples). 33 * - dsp_phase_incr: For each output sample, the position in the original 34 * waveform advances by dsp_phase_incr. This also has an integer 35 * part and a fractional part. 36 * If a sample is played at root pitch (no pitch change), 37 * dsp_phase_incr is integer=1 and fractional=0. 38 * - dsp_amp: The current amplitude envelope value. 39 * - dsp_amp_incr: The changing rate of the amplitude envelope. 40 * 41 * A couple of variables are used internally, their results are discarded: 42 * - dsp_i: Index through the output buffer 43 * - dsp_buf: Output buffer of floating point values (FLUID_BUFSIZE in length) 44 */ 45 46#include "fluidsynth_priv.h" 47#include "fluid_synth.h" 48#include "fluid_voice.h" 49 50 51/* Interpolation (find a value between two samples of the original waveform) */ 52 53/* Linear interpolation table (2 coefficients centered on 1st) */ 54static fluid_real_t interp_coeff_linear[FLUID_INTERP_MAX][2]; 55 56/* 4th order (cubic) interpolation table (4 coefficients centered on 2nd) */ 57static fluid_real_t interp_coeff[FLUID_INTERP_MAX][4]; 58 59/* 7th order interpolation (7 coefficients centered on 3rd) */ 60static fluid_real_t sinc_table7[FLUID_INTERP_MAX][7]; 61 62 63#define SINC_INTERP_ORDER 7 /* 7th order constant */ 64 65 66/* Initializes interpolation tables */ 67void fluid_dsp_float_config (void) 68{ 69 int i, i2; 70 double x, v; 71 double i_shifted; 72 73 /* Initialize the coefficients for the interpolation. The math comes 74 * from a mail, posted by Olli Niemitalo to the music-dsp mailing 75 * list (I found it in the music-dsp archives 76 * http://www.smartelectronix.com/musicdsp/). */ 77 78 for (i = 0; i < FLUID_INTERP_MAX; i++) 79 { 80 x = (double) i / (double) FLUID_INTERP_MAX; 81 82 interp_coeff[i][0] = (fluid_real_t)(x * (-0.5 + x * (1 - 0.5 * x))); 83 interp_coeff[i][1] = (fluid_real_t)(1.0 + x * x * (1.5 * x - 2.5)); 84 interp_coeff[i][2] = (fluid_real_t)(x * (0.5 + x * (2.0 - 1.5 * x))); 85 interp_coeff[i][3] = (fluid_real_t)(0.5 * x * x * (x - 1.0)); 86 87 interp_coeff_linear[i][0] = (fluid_real_t)(1.0 - x); 88 interp_coeff_linear[i][1] = (fluid_real_t)x; 89 } 90 91 /* i: Offset in terms of whole samples */ 92 for (i = 0; i < SINC_INTERP_ORDER; i++) 93 { /* i2: Offset in terms of fractional samples ('subsamples') */ 94 for (i2 = 0; i2 < FLUID_INTERP_MAX; i2++) 95 { 96 /* center on middle of table */ 97 i_shifted = (double)i - ((double)SINC_INTERP_ORDER / 2.0) 98 + (double)i2 / (double)FLUID_INTERP_MAX; 99 100 /* sinc(0) cannot be calculated straightforward (limit needed for 0/0) */ 101 if (fabs (i_shifted) > 0.000001) 102 { 103 v = (fluid_real_t)sin (i_shifted * M_PI) / (M_PI * i_shifted); 104 /* Hamming window */ 105 v *= (fluid_real_t)0.5 * (1.0 + cos (2.0 * M_PI * i_shifted / (fluid_real_t)SINC_INTERP_ORDER)); 106 } 107 else v = 1.0; 108 109 sinc_table7[FLUID_INTERP_MAX - i2 - 1][i] = v; 110 } 111 } 112 113#if 0 114 for (i = 0; i < FLUID_INTERP_MAX; i++) 115 { 116 printf ("%d %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f\n", 117 i, sinc_table7[0][i], sinc_table7[1][i], sinc_table7[2][i], 118 sinc_table7[3][i], sinc_table7[4][i], sinc_table7[5][i], sinc_table7[6][i]); 119 } 120#endif 121 122 fluid_check_fpe("interpolation table calculation"); 123} 124 125 126/* No interpolation. Just take the sample, which is closest to 127 * the playback pointer. Questionable quality, but very 128 * efficient. */ 129int 130fluid_dsp_float_interpolate_none (fluid_voice_t *voice) 131{ 132 fluid_phase_t dsp_phase = voice->phase; 133 fluid_phase_t dsp_phase_incr, end_phase; 134 short int *dsp_data = voice->sample->data; 135 fluid_real_t *dsp_buf = voice->dsp_buf; 136 fluid_real_t dsp_amp = voice->amp; 137 fluid_real_t dsp_amp_incr = voice->amp_incr; 138 unsigned int dsp_i = 0; 139 unsigned int dsp_phase_index; 140 unsigned int end_index; 141 int looping; 142 143 /* Convert playback "speed" floating point value to phase index/fract */ 144 fluid_phase_set_float (dsp_phase_incr, voice->phase_incr); 145 146 /* voice is currently looping? */ 147 looping = _SAMPLEMODE (voice) == FLUID_LOOP_DURING_RELEASE 148 || (_SAMPLEMODE (voice) == FLUID_LOOP_UNTIL_RELEASE 149 && voice->volenv_section < FLUID_VOICE_ENVRELEASE); 150 151 end_index = looping ? voice->loopend - 1 : voice->end; 152 153 while (1) 154 { 155 dsp_phase_index = fluid_phase_index_round (dsp_phase); /* round to nearest point */ 156 157 /* interpolate sequence of sample points */ 158 for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) 159 { 160 dsp_buf[dsp_i] = dsp_amp * dsp_data[dsp_phase_index]; 161 162 /* increment phase and amplitude */ 163 fluid_phase_incr (dsp_phase, dsp_phase_incr); 164 dsp_phase_index = fluid_phase_index_round (dsp_phase); /* round to nearest point */ 165 dsp_amp += dsp_amp_incr; 166 } 167 168 /* break out if not looping (buffer may not be full) */ 169 if (!looping) break; 170 171 /* go back to loop start */ 172 if (dsp_phase_index > end_index) 173 { 174 fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart); 175 voice->has_looped = 1; 176 } 177 178 /* break out if filled buffer */ 179 if (dsp_i >= FLUID_BUFSIZE) break; 180 } 181 182 voice->phase = dsp_phase; 183 voice->amp = dsp_amp; 184 185 return (dsp_i); 186} 187 188/* Straight line interpolation. 189 * Returns number of samples processed (usually FLUID_BUFSIZE but could be 190 * smaller if end of sample occurs). 191 */ 192int 193fluid_dsp_float_interpolate_linear (fluid_voice_t *voice) 194{ 195 fluid_phase_t dsp_phase = voice->phase; 196 fluid_phase_t dsp_phase_incr, end_phase; 197 short int *dsp_data = voice->sample->data; 198 fluid_real_t *dsp_buf = voice->dsp_buf; 199 fluid_real_t dsp_amp = voice->amp; 200 fluid_real_t dsp_amp_incr = voice->amp_incr; 201 unsigned int dsp_i = 0; 202 unsigned int dsp_phase_index; 203 unsigned int end_index; 204 short int point; 205 fluid_real_t *coeffs; 206 int looping; 207 208 /* Convert playback "speed" floating point value to phase index/fract */ 209 fluid_phase_set_float (dsp_phase_incr, voice->phase_incr); 210 211 /* voice is currently looping? */ 212 looping = _SAMPLEMODE (voice) == FLUID_LOOP_DURING_RELEASE 213 || (_SAMPLEMODE (voice) == FLUID_LOOP_UNTIL_RELEASE 214 && voice->volenv_section < FLUID_VOICE_ENVRELEASE); 215 216 /* last index before 2nd interpolation point must be specially handled */ 217 end_index = (looping ? voice->loopend - 1 : voice->end) - 1; 218 219 /* 2nd interpolation point to use at end of loop or sample */ 220 if (looping) point = dsp_data[voice->loopstart]; /* loop start */ 221 else point = dsp_data[voice->end]; /* duplicate end for samples no longer looping */ 222 223 while (1) 224 { 225 dsp_phase_index = fluid_phase_index (dsp_phase); 226 227 /* interpolate the sequence of sample points */ 228 for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) 229 { 230 coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow (dsp_phase)]; 231 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index] 232 + coeffs[1] * dsp_data[dsp_phase_index+1]); 233 234 /* increment phase and amplitude */ 235 fluid_phase_incr (dsp_phase, dsp_phase_incr); 236 dsp_phase_index = fluid_phase_index (dsp_phase); 237 dsp_amp += dsp_amp_incr; 238 } 239 240 /* break out if buffer filled */ 241 if (dsp_i >= FLUID_BUFSIZE) break; 242 243 end_index++; /* we're now interpolating the last point */ 244 245 /* interpolate within last point */ 246 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) 247 { 248 coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow (dsp_phase)]; 249 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index] 250 + coeffs[1] * point); 251 252 /* increment phase and amplitude */ 253 fluid_phase_incr (dsp_phase, dsp_phase_incr); 254 dsp_phase_index = fluid_phase_index (dsp_phase); 255 dsp_amp += dsp_amp_incr; /* increment amplitude */ 256 } 257 258 if (!looping) break; /* break out if not looping (end of sample) */ 259 260 /* go back to loop start (if past */ 261 if (dsp_phase_index > end_index) 262 { 263 fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart); 264 voice->has_looped = 1; 265 } 266 267 /* break out if filled buffer */ 268 if (dsp_i >= FLUID_BUFSIZE) break; 269 270 end_index--; /* set end back to second to last sample point */ 271 } 272 273 voice->phase = dsp_phase; 274 voice->amp = dsp_amp; 275 276 return (dsp_i); 277} 278 279/* 4th order (cubic) interpolation. 280 * Returns number of samples processed (usually FLUID_BUFSIZE but could be 281 * smaller if end of sample occurs). 282 */ 283int 284fluid_dsp_float_interpolate_4th_order (fluid_voice_t *voice) 285{ 286 fluid_phase_t dsp_phase = voice->phase; 287 fluid_phase_t dsp_phase_incr, end_phase; 288 short int *dsp_data = voice->sample->data; 289 fluid_real_t *dsp_buf = voice->dsp_buf; 290 fluid_real_t dsp_amp = voice->amp; 291 fluid_real_t dsp_amp_incr = voice->amp_incr; 292 unsigned int dsp_i = 0; 293 unsigned int dsp_phase_index; 294 unsigned int start_index, end_index; 295 short int start_point, end_point1, end_point2; 296 fluid_real_t *coeffs; 297 int looping; 298 299 /* Convert playback "speed" floating point value to phase index/fract */ 300 fluid_phase_set_float (dsp_phase_incr, voice->phase_incr); 301 302 /* voice is currently looping? */ 303 looping = _SAMPLEMODE (voice) == FLUID_LOOP_DURING_RELEASE 304 || (_SAMPLEMODE (voice) == FLUID_LOOP_UNTIL_RELEASE 305 && voice->volenv_section < FLUID_VOICE_ENVRELEASE); 306 307 /* last index before 4th interpolation point must be specially handled */ 308 end_index = (looping ? voice->loopend - 1 : voice->end) - 2; 309 310 if (voice->has_looped) /* set start_index and start point if looped or not */ 311 { 312 start_index = voice->loopstart; 313 start_point = dsp_data[voice->loopend - 1]; /* last point in loop (wrap around) */ 314 } 315 else 316 { 317 start_index = voice->start; 318 start_point = dsp_data[voice->start]; /* just duplicate the point */ 319 } 320 321 /* get points off the end (loop start if looping, duplicate point if end) */ 322 if (looping) 323 { 324 end_point1 = dsp_data[voice->loopstart]; 325 end_point2 = dsp_data[voice->loopstart + 1]; 326 } 327 else 328 { 329 end_point1 = dsp_data[voice->end]; 330 end_point2 = end_point1; 331 } 332 333 while (1) 334 { 335 dsp_phase_index = fluid_phase_index (dsp_phase); 336 337 /* interpolate first sample point (start or loop start) if needed */ 338 for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++) 339 { 340 coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; 341 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * start_point 342 + coeffs[1] * dsp_data[dsp_phase_index] 343 + coeffs[2] * dsp_data[dsp_phase_index+1] 344 + coeffs[3] * dsp_data[dsp_phase_index+2]); 345 346 /* increment phase and amplitude */ 347 fluid_phase_incr (dsp_phase, dsp_phase_incr); 348 dsp_phase_index = fluid_phase_index (dsp_phase); 349 dsp_amp += dsp_amp_incr; 350 } 351 352 /* interpolate the sequence of sample points */ 353 for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) 354 { 355 coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; 356 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1] 357 + coeffs[1] * dsp_data[dsp_phase_index] 358 + coeffs[2] * dsp_data[dsp_phase_index+1] 359 + coeffs[3] * dsp_data[dsp_phase_index+2]); 360 361 /* increment phase and amplitude */ 362 fluid_phase_incr (dsp_phase, dsp_phase_incr); 363 dsp_phase_index = fluid_phase_index (dsp_phase); 364 dsp_amp += dsp_amp_incr; 365 } 366 367 /* break out if buffer filled */ 368 if (dsp_i >= FLUID_BUFSIZE) break; 369 370 end_index++; /* we're now interpolating the 2nd to last point */ 371 372 /* interpolate within 2nd to last point */ 373 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) 374 { 375 coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; 376 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1] 377 + coeffs[1] * dsp_data[dsp_phase_index] 378 + coeffs[2] * dsp_data[dsp_phase_index+1] 379 + coeffs[3] * end_point1); 380 381 /* increment phase and amplitude */ 382 fluid_phase_incr (dsp_phase, dsp_phase_incr); 383 dsp_phase_index = fluid_phase_index (dsp_phase); 384 dsp_amp += dsp_amp_incr; 385 } 386 387 end_index++; /* we're now interpolating the last point */ 388 389 /* interpolate within the last point */ 390 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) 391 { 392 coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; 393 dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1] 394 + coeffs[1] * dsp_data[dsp_phase_index] 395 + coeffs[2] * end_point1 396 + coeffs[3] * end_point2); 397 398 /* increment phase and amplitude */ 399 fluid_phase_incr (dsp_phase, dsp_phase_incr); 400 dsp_phase_index = fluid_phase_index (dsp_phase); 401 dsp_amp += dsp_amp_incr; 402 } 403 404 if (!looping) break; /* break out if not looping (end of sample) */ 405 406 /* go back to loop start */ 407 if (dsp_phase_index > end_index) 408 { 409 fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart); 410 411 if (!voice->has_looped) 412 { 413 voice->has_looped = 1; 414 start_index = voice->loopstart; 415 start_point = dsp_data[voice->loopend - 1]; 416 } 417 } 418 419 /* break out if filled buffer */ 420 if (dsp_i >= FLUID_BUFSIZE) break; 421 422 end_index -= 2; /* set end back to third to last sample point */ 423 } 424 425 voice->phase = dsp_phase; 426 voice->amp = dsp_amp; 427 428 return (dsp_i); 429} 430 431/* 7th order interpolation. 432 * Returns number of samples processed (usually FLUID_BUFSIZE but could be 433 * smaller if end of sample occurs). 434 */ 435int 436fluid_dsp_float_interpolate_7th_order (fluid_voice_t *voice) 437{ 438 fluid_phase_t dsp_phase = voice->phase; 439 fluid_phase_t dsp_phase_incr, end_phase; 440 short int *dsp_data = voice->sample->data; 441 fluid_real_t *dsp_buf = voice->dsp_buf; 442 fluid_real_t dsp_amp = voice->amp; 443 fluid_real_t dsp_amp_incr = voice->amp_incr; 444 unsigned int dsp_i = 0; 445 unsigned int dsp_phase_index; 446 unsigned int start_index, end_index; 447 short int start_points[3]; 448 short int end_points[3]; 449 fluid_real_t *coeffs; 450 int looping; 451 452 /* Convert playback "speed" floating point value to phase index/fract */ 453 fluid_phase_set_float (dsp_phase_incr, voice->phase_incr); 454 455 /* add 1/2 sample to dsp_phase since 7th order interpolation is centered on 456 * the 4th sample point */ 457 fluid_phase_incr (dsp_phase, (fluid_phase_t)0x80000000); 458 459 /* voice is currently looping? */ 460 looping = _SAMPLEMODE (voice) == FLUID_LOOP_DURING_RELEASE 461 || (_SAMPLEMODE (voice) == FLUID_LOOP_UNTIL_RELEASE 462 && voice->volenv_section < FLUID_VOICE_ENVRELEASE); 463 464 /* last index before 7th interpolation point must be specially handled */ 465 end_index = (looping ? voice->loopend - 1 : voice->end) - 3; 466 467 if (voice->has_looped) /* set start_index and start point if looped or not */ 468 { 469 start_index = voice->loopstart; 470 start_points[0] = dsp_data[voice->loopend - 1]; 471 start_points[1] = dsp_data[voice->loopend - 2]; 472 start_points[2] = dsp_data[voice->loopend - 3]; 473 } 474 else 475 { 476 start_index = voice->start; 477 start_points[0] = dsp_data[voice->start]; /* just duplicate the start point */ 478 start_points[1] = start_points[0]; 479 start_points[2] = start_points[0]; 480 } 481 482 /* get the 3 points off the end (loop start if looping, duplicate point if end) */ 483 if (looping) 484 { 485 end_points[0] = dsp_data[voice->loopstart]; 486 end_points[1] = dsp_data[voice->loopstart + 1]; 487 end_points[2] = dsp_data[voice->loopstart + 2]; 488 } 489 else 490 { 491 end_points[0] = dsp_data[voice->end]; 492 end_points[1] = end_points[0]; 493 end_points[2] = end_points[0]; 494 } 495 496 while (1) 497 { 498 dsp_phase_index = fluid_phase_index (dsp_phase); 499 500 /* interpolate first sample point (start or loop start) if needed */ 501 for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++) 502 { 503 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; 504 505 dsp_buf[dsp_i] = dsp_amp 506 * (coeffs[0] * (fluid_real_t)start_points[2] 507 + coeffs[1] * (fluid_real_t)start_points[1] 508 + coeffs[2] * (fluid_real_t)start_points[0] 509 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] 510 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] 511 + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] 512 + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); 513 514 /* increment phase and amplitude */ 515 fluid_phase_incr (dsp_phase, dsp_phase_incr); 516 dsp_phase_index = fluid_phase_index (dsp_phase); 517 dsp_amp += dsp_amp_incr; 518 } 519 520 start_index++; 521 522 /* interpolate 2nd to first sample point (start or loop start) if needed */ 523 for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++) 524 { 525 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; 526 527 dsp_buf[dsp_i] = dsp_amp 528 * (coeffs[0] * (fluid_real_t)start_points[1] 529 + coeffs[1] * (fluid_real_t)start_points[0] 530 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] 531 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] 532 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] 533 + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] 534 + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); 535 536 /* increment phase and amplitude */ 537 fluid_phase_incr (dsp_phase, dsp_phase_incr); 538 dsp_phase_index = fluid_phase_index (dsp_phase); 539 dsp_amp += dsp_amp_incr; 540 } 541 542 start_index++; 543 544 /* interpolate 3rd to first sample point (start or loop start) if needed */ 545 for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++) 546 { 547 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; 548 549 dsp_buf[dsp_i] = dsp_amp 550 * (coeffs[0] * (fluid_real_t)start_points[0] 551 + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] 552 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] 553 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] 554 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] 555 + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] 556 + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); 557 558 /* increment phase and amplitude */ 559 fluid_phase_incr (dsp_phase, dsp_phase_incr); 560 dsp_phase_index = fluid_phase_index (dsp_phase); 561 dsp_amp += dsp_amp_incr; 562 } 563 564 start_index -= 2; /* set back to original start index */ 565 566 567 /* interpolate the sequence of sample points */ 568 for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) 569 { 570 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; 571 572 dsp_buf[dsp_i] = dsp_amp 573 * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] 574 + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] 575 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] 576 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] 577 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] 578 + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] 579 + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); 580 581 /* increment phase and amplitude */ 582 fluid_phase_incr (dsp_phase, dsp_phase_incr); 583 dsp_phase_index = fluid_phase_index (dsp_phase); 584 dsp_amp += dsp_amp_incr; 585 } 586 587 /* break out if buffer filled */ 588 if (dsp_i >= FLUID_BUFSIZE) break; 589 590 end_index++; /* we're now interpolating the 3rd to last point */ 591 592 /* interpolate within 3rd to last point */ 593 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) 594 { 595 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; 596 597 dsp_buf[dsp_i] = dsp_amp 598 * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] 599 + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] 600 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] 601 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] 602 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] 603 + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] 604 + coeffs[6] * (fluid_real_t)end_points[0]); 605 606 /* increment phase and amplitude */ 607 fluid_phase_incr (dsp_phase, dsp_phase_incr); 608 dsp_phase_index = fluid_phase_index (dsp_phase); 609 dsp_amp += dsp_amp_incr; 610 } 611 612 end_index++; /* we're now interpolating the 2nd to last point */ 613 614 /* interpolate within 2nd to last point */ 615 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) 616 { 617 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; 618 619 dsp_buf[dsp_i] = dsp_amp 620 * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] 621 + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] 622 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] 623 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] 624 + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] 625 + coeffs[5] * (fluid_real_t)end_points[0] 626 + coeffs[6] * (fluid_real_t)end_points[1]); 627 628 /* increment phase and amplitude */ 629 fluid_phase_incr (dsp_phase, dsp_phase_incr); 630 dsp_phase_index = fluid_phase_index (dsp_phase); 631 dsp_amp += dsp_amp_incr; 632 } 633 634 end_index++; /* we're now interpolating the last point */ 635 636 /* interpolate within last point */ 637 for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) 638 { 639 coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; 640 641 dsp_buf[dsp_i] = dsp_amp 642 * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] 643 + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] 644 + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] 645 + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] 646 + coeffs[4] * (fluid_real_t)end_points[0] 647 + coeffs[5] * (fluid_real_t)end_points[1] 648 + coeffs[6] * (fluid_real_t)end_points[2]); 649 650 /* increment phase and amplitude */ 651 fluid_phase_incr (dsp_phase, dsp_phase_incr); 652 dsp_phase_index = fluid_phase_index (dsp_phase); 653 dsp_amp += dsp_amp_incr; 654 } 655 656 if (!looping) break; /* break out if not looping (end of sample) */ 657 658 /* go back to loop start */ 659 if (dsp_phase_index > end_index) 660 { 661 fluid_phase_sub_int (dsp_phase, voice->loopend - voice->loopstart); 662 663 if (!voice->has_looped) 664 { 665 voice->has_looped = 1; 666 start_index = voice->loopstart; 667 start_points[0] = dsp_data[voice->loopend - 1]; 668 start_points[1] = dsp_data[voice->loopend - 2]; 669 start_points[2] = dsp_data[voice->loopend - 3]; 670 } 671 } 672 673 /* break out if filled buffer */ 674 if (dsp_i >= FLUID_BUFSIZE) break; 675 676 end_index -= 3; /* set end back to 4th to last sample point */ 677 } 678 679 /* sub 1/2 sample from dsp_phase since 7th order interpolation is centered on 680 * the 4th sample point (correct back to real value) */ 681 fluid_phase_decr (dsp_phase, (fluid_phase_t)0x80000000); 682 683 voice->phase = dsp_phase; 684 voice->amp = dsp_amp; 685 686 return (dsp_i); 687} 688