fluid_dsp_float.c
上传用户:tjmskj2
上传日期:2020-08-17
资源大小:577k
文件大小:23k
源码类别:

midi

开发平台:

C/C++

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