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

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_voice.h"
  22. #include "fluid_mod.h"
  23. #include "fluid_chan.h"
  24. #include "fluid_conv.h"
  25. #include "fluid_synth.h"
  26. #include "fluid_sys.h"
  27. #include "fluid_sfont.h"
  28. /* used for filter turn off optimization - if filter cutoff is above the
  29.    specified value and filter q is below the other value, turn filter off */
  30. #define FLUID_MAX_AUDIBLE_FILTER_FC 19000.0f
  31. #define FLUID_MIN_AUDIBLE_FILTER_Q 1.2f
  32. /* Smallest amplitude that can be perceived (full scale is +/- 0.5)
  33.  * 16 bits => 96+4=100 dB dynamic range => 0.00001
  34.  * 0.00001 * 2 is approximately 0.00003 :)
  35.  */
  36. #define FLUID_NOISE_FLOOR 0.00003
  37. /* these should be the absolute minimum that FluidSynth can deal with */
  38. #define FLUID_MIN_LOOP_SIZE 2
  39. #define FLUID_MIN_LOOP_PAD 0
  40. /* min vol envelope release (to stop clicks) in SoundFont timecents */
  41. #define FLUID_MIN_VOLENVRELEASE -7200.0f /* ~16ms */
  42. static int fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice);
  43. static int calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base,
  44.                                         int gen_key2base, int is_decay);
  45. static inline void fluid_voice_filter (fluid_voice_t *voice);
  46. static fluid_real_t
  47. fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t* voice);
  48. static void fluid_voice_check_sample_sanity(fluid_voice_t* voice);
  49. /*
  50.  * new_fluid_voice
  51.  */
  52. fluid_voice_t*
  53. new_fluid_voice(fluid_real_t output_rate)
  54. {
  55.   fluid_voice_t* voice;
  56.   voice = FLUID_NEW(fluid_voice_t);
  57.   if (voice == NULL) {
  58.     FLUID_LOG(FLUID_ERR, "Out of memory");
  59.     return NULL;
  60.   }
  61.   voice->status = FLUID_VOICE_CLEAN;
  62.   voice->chan = NO_CHANNEL;
  63.   voice->key = 0;
  64.   voice->vel = 0;
  65.   voice->channel = NULL;
  66.   voice->sample = NULL;
  67.   voice->output_rate = output_rate;
  68.   /* The 'sustain' and 'finished' segments of the volume / modulation
  69.    * envelope are constant. They are never affected by any modulator
  70.    * or generator. Therefore it is enough to initialize them once
  71.    * during the lifetime of the synth.
  72.    */
  73.   voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].count = 0xffffffff;
  74.   voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].coeff = 1.0f;
  75.   voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].incr = 0.0f;
  76.   voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].min = -1.0f;
  77.   voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].max = 2.0f;
  78.   voice->volenv_data[FLUID_VOICE_ENVFINISHED].count = 0xffffffff;
  79.   voice->volenv_data[FLUID_VOICE_ENVFINISHED].coeff = 0.0f;
  80.   voice->volenv_data[FLUID_VOICE_ENVFINISHED].incr = 0.0f;
  81.   voice->volenv_data[FLUID_VOICE_ENVFINISHED].min = -1.0f;
  82.   voice->volenv_data[FLUID_VOICE_ENVFINISHED].max = 1.0f;
  83.   voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].count = 0xffffffff;
  84.   voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].coeff = 1.0f;
  85.   voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].incr = 0.0f;
  86.   voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].min = -1.0f;
  87.   voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].max = 2.0f;
  88.   voice->modenv_data[FLUID_VOICE_ENVFINISHED].count = 0xffffffff;
  89.   voice->modenv_data[FLUID_VOICE_ENVFINISHED].coeff = 0.0f;
  90.   voice->modenv_data[FLUID_VOICE_ENVFINISHED].incr = 0.0f;
  91.   voice->modenv_data[FLUID_VOICE_ENVFINISHED].min = -1.0f;
  92.   voice->modenv_data[FLUID_VOICE_ENVFINISHED].max = 1.0f;
  93.   return voice;
  94. }
  95. /*
  96.  * delete_fluid_voice
  97.  */
  98. int
  99. delete_fluid_voice(fluid_voice_t* voice)
  100. {
  101.   if (voice == NULL) {
  102.     return FLUID_OK;
  103.   }
  104.   FLUID_FREE(voice);
  105.   return FLUID_OK;
  106. }
  107. /* fluid_voice_init
  108.  *
  109.  * Initialize the synthesis process
  110.  */
  111. int
  112. fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
  113.  fluid_channel_t* channel, int key, int vel, unsigned int id,
  114.  unsigned int start_time, fluid_real_t gain)
  115. {
  116.   /* Note: The voice parameters will be initialized later, when the
  117.    * generators have been retrieved from the sound font. Here, only
  118.    * the 'working memory' of the voice (position in envelopes, history
  119.    * of IIR filters, position in sample etc) is initialized. */
  120.   voice->id = id;
  121.   voice->chan = fluid_channel_get_num(channel);
  122.   voice->key = (unsigned char) key;
  123.   voice->vel = (unsigned char) vel;
  124.   voice->channel = channel;
  125.   voice->mod_count = 0;
  126.   voice->sample = sample;
  127.   voice->start_time = start_time;
  128.   voice->ticks = 0;
  129.   voice->noteoff_ticks = 0;
  130.   voice->debug = 0;
  131.   voice->has_looped = 0; /* Will be set during voice_write when the 2nd loop point is reached */
  132.   voice->last_fres = -1; /* The filter coefficients have to be calculated later in the DSP loop. */
  133.   voice->filter_startup = 1; /* Set the filter immediately, don't fade between old and new settings */
  134.   voice->interp_method = fluid_channel_get_interp_method(voice->channel);
  135.   /* vol env initialization */
  136.   voice->volenv_count = 0;
  137.   voice->volenv_section = 0;
  138.   voice->volenv_val = 0.0f;
  139.   voice->amp = 0.0f; /* The last value of the volume envelope, used to
  140.                         calculate the volume increment during
  141.                         processing */
  142.   /* mod env initialization*/
  143.   voice->modenv_count = 0;
  144.   voice->modenv_section = 0;
  145.   voice->modenv_val = 0.0f;
  146.   /* mod lfo */
  147.   voice->modlfo_val = 0.0;/* Fixme: Retrieve from any other existing
  148.                              voice on this channel to keep LFOs in
  149.                              unison? */
  150.   /* vib lfo */
  151.   voice->viblfo_val = 0.0f; /* Fixme: See mod lfo */
  152.   /* Clear sample history in filter */
  153.   voice->hist1 = 0;
  154.   voice->hist2 = 0;
  155.   /* Set all the generators to their default value, according to SF
  156.    * 2.01 section 8.1.3 (page 48). The value of NRPN messages are
  157.    * copied from the channel to the voice's generators. The sound font
  158.    * loader overwrites them. The generator values are later converted
  159.    * into voice parameters in
  160.    * fluid_voice_calculate_runtime_synthesis_parameters.  */
  161.   fluid_gen_init(&voice->gen[0], channel);
  162.   voice->synth_gain = gain;
  163.   /* avoid division by zero later*/
  164.   if (voice->synth_gain < 0.0000001){
  165.     voice->synth_gain = 0.0000001;
  166.   }
  167.   /* For a looped sample, this value will be overwritten as soon as the
  168.    * loop parameters are initialized (they may depend on modulators).
  169.    * This value can be kept, it is a worst-case estimate.
  170.    */
  171.   voice->amplitude_that_reaches_noise_floor_nonloop = FLUID_NOISE_FLOOR / voice->synth_gain;
  172.   voice->amplitude_that_reaches_noise_floor_loop = FLUID_NOISE_FLOOR / voice->synth_gain;
  173.   /* Increment the reference count of the sample to prevent the
  174.      unloading of the soundfont while this voice is playing. */
  175.   fluid_sample_incr_ref(voice->sample);
  176.   return FLUID_OK;
  177. }
  178. /**
  179.  * Set the value of a generator.
  180.  * @param voice Voice instance
  181.  * @param i Generator ID (#fluid_gen_type)
  182.  * @param val Generator value
  183.  */
  184. void
  185. fluid_voice_gen_set(fluid_voice_t* voice, int i, float val)
  186. {
  187.   voice->gen[i].val = val;
  188.   voice->gen[i].flags = GEN_SET;
  189. }
  190. /**
  191.  * Offset the value of a generator.
  192.  * @param voice Voice instance
  193.  * @param i Generator ID (#fluid_gen_type)
  194.  * @param val Value to add to the existing value
  195.  */
  196. void
  197. fluid_voice_gen_incr(fluid_voice_t* voice, int i, float val)
  198. {
  199.   voice->gen[i].val += val;
  200.   voice->gen[i].flags = GEN_SET;
  201. }
  202. /**
  203.  * Get the value of a generator.
  204.  * @param voice Voice instance
  205.  * @param gen Generator ID (#fluid_gen_type)
  206.  * @return Current generator value
  207.  */
  208. float
  209. fluid_voice_gen_get(fluid_voice_t* voice, int gen)
  210. {
  211.   return voice->gen[gen].val;
  212. }
  213. fluid_real_t fluid_voice_gen_value(fluid_voice_t* voice, int num)
  214. {
  215. /* This is an extension to the SoundFont standard. More
  216.  * documentation is available at the fluid_synth_set_gen2()
  217.  * function. */
  218. if (voice->gen[num].flags == GEN_ABS_NRPN) {
  219. return (fluid_real_t) voice->gen[num].nrpn;
  220. } else {
  221. return (fluid_real_t) (voice->gen[num].val + voice->gen[num].mod + voice->gen[num].nrpn);
  222. }
  223. }
  224. /**
  225.  * Synthesize a voice to a buffer.
  226.  *
  227.  * @param voice Voice to synthesize
  228.  * @param dsp_buf Audio buffer to synthesize to (#FLUID_BUFSIZE in length)
  229.  * @return Count of samples written to dsp_buf (can be 0)
  230.  *
  231.  * Panning, reverb and chorus are processed separately. The dsp interpolation
  232.  * routine is in (fluid_dsp_float.c).
  233.  */
  234. int
  235. fluid_voice_write (fluid_voice_t* voice, fluid_real_t *dsp_buf)
  236. {
  237.   fluid_real_t fres;
  238.   fluid_real_t target_amp; /* target amplitude */
  239.   fluid_env_data_t* env_data;
  240.   fluid_real_t x;
  241.   int count = 0;
  242.   /* Other routines (such as fluid_voice_effects) use the last dsp_buf assigned */
  243.   voice->dsp_buf = dsp_buf;
  244.   voice->dsp_buf_count = 0;
  245.   /******************* sample **********************/
  246.   if (voice->sample == NULL)
  247.   {
  248.     fluid_voice_off(voice);
  249.     return 0;
  250.   }
  251.   if (voice->noteoff_ticks != 0 && voice->ticks >= voice->noteoff_ticks) 
  252.   {
  253.     fluid_voice_noteoff(voice);
  254.   }
  255.   fluid_check_fpe ("voice_write startup");
  256.   /* Range checking for sample- and loop-related parameters
  257.    * Initial phase is calculated here*/
  258.   fluid_voice_check_sample_sanity (voice);
  259.   /******************* vol env **********************/
  260.   env_data = &voice->volenv_data[voice->volenv_section];
  261.   /* skip to the next section of the envelope if necessary */
  262.   while (voice->volenv_count >= env_data->count)
  263.   {
  264.     // If we're switching envelope stages from decay to sustain, force the value to be the end value of the previous stage
  265.     if (env_data && voice->volenv_section == FLUID_VOICE_ENVDECAY)
  266.       voice->volenv_val = env_data->min * env_data->coeff;
  267.     env_data = &voice->volenv_data[++voice->volenv_section];
  268.     voice->volenv_count = 0;
  269.   }
  270.   /* calculate the envelope value and check for valid range */
  271.   x = env_data->coeff * voice->volenv_val + env_data->incr;
  272.   if (x < env_data->min)
  273.   {
  274.     x = env_data->min;
  275.     voice->volenv_section++;
  276.     voice->volenv_count = 0;
  277.   }
  278.   else if (x > env_data->max)
  279.   {
  280.     x = env_data->max;
  281.     voice->volenv_section++;
  282.     voice->volenv_count = 0;
  283.   }
  284.   voice->volenv_val = x;
  285.   voice->volenv_count++;
  286.   if (voice->volenv_section == FLUID_VOICE_ENVFINISHED)
  287.   {
  288.     fluid_profile (FLUID_PROF_VOICE_RELEASE, voice->ref);
  289.     fluid_voice_off (voice);
  290.     return 0;
  291.   }
  292.   fluid_check_fpe ("voice_write vol env");
  293.   /******************* mod env **********************/
  294.   env_data = &voice->modenv_data[voice->modenv_section];
  295.   /* skip to the next section of the envelope if necessary */
  296.   while (voice->modenv_count >= env_data->count)
  297.   {
  298.     env_data = &voice->modenv_data[++voice->modenv_section];
  299.     voice->modenv_count = 0;
  300.   }
  301.   /* calculate the envelope value and check for valid range */
  302.   x = env_data->coeff * voice->modenv_val + env_data->incr;
  303.   if (x < env_data->min)
  304.   {
  305.     x = env_data->min;
  306.     voice->modenv_section++;
  307.     voice->modenv_count = 0;
  308.   }
  309.   else if (x > env_data->max)
  310.   {
  311.     x = env_data->max;
  312.     voice->modenv_section++;
  313.     voice->modenv_count = 0;
  314.   }
  315.   voice->modenv_val = x;
  316.   voice->modenv_count++;
  317.   fluid_check_fpe ("voice_write mod env");
  318.   /******************* mod lfo **********************/
  319.   if (voice->ticks >= voice->modlfo_delay)
  320.   {
  321.     voice->modlfo_val += voice->modlfo_incr;
  322.   
  323.     if (voice->modlfo_val > 1.0)
  324.     {
  325.       voice->modlfo_incr = -voice->modlfo_incr;
  326.       voice->modlfo_val = (fluid_real_t) 2.0 - voice->modlfo_val;
  327.     }
  328.     else if (voice->modlfo_val < -1.0)
  329.     {
  330.       voice->modlfo_incr = -voice->modlfo_incr;
  331.       voice->modlfo_val = (fluid_real_t) -2.0 - voice->modlfo_val;
  332.     }
  333.   }
  334.   
  335.   fluid_check_fpe ("voice_write mod LFO");
  336.   /******************* vib lfo **********************/
  337.   if (voice->ticks >= voice->viblfo_delay)
  338.   {
  339.     voice->viblfo_val += voice->viblfo_incr;
  340.     if (voice->viblfo_val > (fluid_real_t) 1.0)
  341.     {
  342.       voice->viblfo_incr = -voice->viblfo_incr;
  343.       voice->viblfo_val = (fluid_real_t) 2.0 - voice->viblfo_val;
  344.     }
  345.     else if (voice->viblfo_val < -1.0)
  346.     {
  347.       voice->viblfo_incr = -voice->viblfo_incr;
  348.       voice->viblfo_val = (fluid_real_t) -2.0 - voice->viblfo_val;
  349.     }
  350.   }
  351.   fluid_check_fpe ("voice_write Vib LFO");
  352.   /******************* amplitude **********************/
  353.   /* calculate final amplitude
  354.    * - initial gain
  355.    * - amplitude envelope
  356.    */
  357.   if (voice->volenv_section == FLUID_VOICE_ENVDELAY)
  358.     goto post_process; /* The volume amplitude is in hold phase. No sound is produced. */
  359.   if (voice->volenv_section == FLUID_VOICE_ENVATTACK)
  360.   {
  361.     /* the envelope is in the attack section: ramp linearly to max value.
  362.      * A positive modlfo_to_vol should increase volume (negative attenuation).
  363.      */
  364.     target_amp = fluid_atten2amp (voice->attenuation)
  365.       * fluid_cb2amp (voice->modlfo_val * -voice->modlfo_to_vol)
  366.       * voice->volenv_val;
  367.   }
  368.   else
  369.   {
  370.     fluid_real_t amplitude_that_reaches_noise_floor;
  371.     fluid_real_t amp_max;
  372.     target_amp = fluid_atten2amp (voice->attenuation)
  373.       * fluid_cb2amp (960.0f * (1.0f - voice->volenv_val)
  374.       + voice->modlfo_val * -voice->modlfo_to_vol);
  375.     /* We turn off a voice, if the volume has dropped low enough. */
  376.     /* A voice can be turned off, when an estimate for the volume
  377.      * (upper bound) falls below that volume, that will drop the
  378.      * sample below the noise floor.
  379.      */
  380.     /* If the loop amplitude is known, we can use it if the voice loop is within
  381.      * the sample loop
  382.      */
  383.     /* Is the playing pointer already in the loop? */
  384.     if (voice->has_looped)
  385.       amplitude_that_reaches_noise_floor = voice->amplitude_that_reaches_noise_floor_loop;
  386.     else
  387.       amplitude_that_reaches_noise_floor = voice->amplitude_that_reaches_noise_floor_nonloop;
  388.     /* voice->attenuation_min is a lower boundary for the attenuation
  389.      * now and in the future (possibly 0 in the worst case).  Now the
  390.      * amplitude of sample and volenv cannot exceed amp_max (since
  391.      * volenv_val can only drop):
  392.      */
  393.     amp_max = fluid_atten2amp (voice->min_attenuation_cB) * voice->volenv_val;
  394.     /* And if amp_max is already smaller than the known amplitude,
  395.      * which will attenuate the sample below the noise floor, then we
  396.      * can safely turn off the voice. Duh. */
  397.     if (amp_max < amplitude_that_reaches_noise_floor)
  398.     {
  399.       fluid_profile (FLUID_PROF_VOICE_RELEASE, voice->ref);
  400.       fluid_voice_off (voice);
  401.       goto post_process;
  402.     }
  403.   }
  404.   /* Volume increment to go from voice->amp to target_amp in FLUID_BUFSIZE steps */
  405.   voice->amp_incr = (target_amp - voice->amp) / FLUID_BUFSIZE;
  406.   fluid_check_fpe ("voice_write amplitude calculation");
  407.   /* no volume and not changing? - No need to process */
  408.   if ((voice->amp == 0.0f) && (voice->amp_incr == 0.0f))
  409.     goto post_process;
  410.   /* Calculate the number of samples, that the DSP loop advances
  411.    * through the original waveform with each step in the output
  412.    * buffer. It is the ratio between the frequencies of original
  413.    * waveform and output waveform.*/
  414.   voice->phase_incr = fluid_ct2hz_real
  415.     (voice->pitch + voice->modlfo_val * voice->modlfo_to_pitch
  416.      + voice->viblfo_val * voice->viblfo_to_pitch
  417.      + voice->modenv_val * voice->modenv_to_pitch) / voice->root_pitch_hz;
  418.   fluid_check_fpe ("voice_write phase calculation");
  419.   /* if phase_incr is not advancing, set it to the minimum fraction value (prevent stuckage) */
  420.   if (voice->phase_incr == 0) voice->phase_incr = 1;
  421.   /*************** resonant filter ******************/
  422.   /* calculate the frequency of the resonant filter in Hz */
  423.   fres = fluid_ct2hz(voice->fres
  424.      + voice->modlfo_val * voice->modlfo_to_fc
  425.      + voice->modenv_val * voice->modenv_to_fc);
  426.   /* FIXME - Still potential for a click during turn on, can we interpolate
  427.      between 20khz cutoff and 0 Q? */
  428.   /* I removed the optimization of turning the filter off when the
  429.    * resonance frequence is above the maximum frequency. Instead, the
  430.    * filter frequency is set to a maximum of 0.45 times the sampling
  431.    * rate. For a 44100 kHz sampling rate, this amounts to 19845
  432.    * Hz. The reason is that there were problems with anti-aliasing when the
  433.    * synthesizer was run at lower sampling rates. Thanks to Stephan
  434.    * Tassart for pointing me to this bug. By turning the filter on and
  435.    * clipping the maximum filter frequency at 0.45*srate, the filter
  436.    * is used as an anti-aliasing filter. */
  437.   if (fres > 0.45f * voice->output_rate)
  438.     fres = 0.45f * voice->output_rate;
  439.   else if (fres < 5)
  440.     fres = 5;
  441.   /* if filter enabled and there is a significant frequency change.. */
  442.   if ((abs (fres - voice->last_fres) > 0.01))
  443.   {
  444.     /* The filter coefficients have to be recalculated (filter
  445.     * parameters have changed). Recalculation for various reasons is
  446.     * forced by setting last_fres to -1.  The flag filter_startup
  447.     * indicates, that the DSP loop runs for the first time, in this
  448.     * case, the filter is set directly, instead of smoothly fading
  449.     * between old and new settings.
  450.     *
  451.     * Those equations from Robert Bristow-Johnson's `Cookbook
  452.     * formulae for audio EQ biquad filter coefficients', obtained
  453.     * from Harmony-central.com / Computer / Programming. They are
  454.     * the result of the bilinear transform on an analogue filter
  455.     * prototype. To quote, `BLT frequency warping has been taken
  456.     * into account for both significant frequency relocation and for
  457.     * bandwidth readjustment'. */
  458.    fluid_real_t omega = (fluid_real_t) (2.0 * M_PI * (fres / ((float) voice->output_rate)));
  459.    fluid_real_t sin_coeff = (fluid_real_t) sin(omega);
  460.    fluid_real_t cos_coeff = (fluid_real_t) cos(omega);
  461.    fluid_real_t alpha_coeff = sin_coeff / (2.0f * voice->q_lin);
  462.    fluid_real_t a0_inv = 1.0f / (1.0f + alpha_coeff);
  463.    /* Calculate the filter coefficients. All coefficients are
  464.     * normalized by a0. Think of `a1' as `a1/a0'.
  465.     *
  466.     * Here a couple of multiplications are saved by reusing common expressions.
  467.     * The original equations should be:
  468.     *  voice->b0=(1.-cos_coeff)*a0_inv*0.5*voice->filter_gain;
  469.     *  voice->b1=(1.-cos_coeff)*a0_inv*voice->filter_gain;
  470.     *  voice->b2=(1.-cos_coeff)*a0_inv*0.5*voice->filter_gain; */
  471.    fluid_real_t a1_temp = -2.0f * cos_coeff * a0_inv;
  472.    fluid_real_t a2_temp = (1.0f - alpha_coeff) * a0_inv;
  473.    fluid_real_t b1_temp = (1.0f - cos_coeff) * a0_inv * voice->filter_gain;
  474.    /* both b0 -and- b2 */
  475.    fluid_real_t b02_temp = b1_temp * 0.5f;
  476.    if (voice->filter_startup)
  477.    {
  478.      /* The filter is calculated, because the voice was started up.
  479.       * In this case set the filter coefficients without delay.
  480.       */
  481.      voice->a1 = a1_temp;
  482.      voice->a2 = a2_temp;
  483.      voice->b02 = b02_temp;
  484.      voice->b1 = b1_temp;
  485.      voice->filter_coeff_incr_count = 0;
  486.      voice->filter_startup = 0;
  487. //       printf("Setting initial filter coefficients.n");
  488.    }
  489.    else
  490.    {
  491.       /* The filter frequency is changed.  Calculate an increment
  492.        * factor, so that the new setting is reached after one buffer
  493.        * length. x_incr is added to the current value FLUID_BUFSIZE
  494.        * times. The length is arbitrarily chosen. Longer than one
  495.        * buffer will sacrifice some performance, though.  Note: If
  496.        * the filter is still too 'grainy', then increase this number
  497.        * at will.
  498.        */
  499. #define FILTER_TRANSITION_SAMPLES (FLUID_BUFSIZE)
  500.       voice->a1_incr = (a1_temp - voice->a1) / FILTER_TRANSITION_SAMPLES;
  501.       voice->a2_incr = (a2_temp - voice->a2) / FILTER_TRANSITION_SAMPLES;
  502.       voice->b02_incr = (b02_temp - voice->b02) / FILTER_TRANSITION_SAMPLES;
  503.       voice->b1_incr = (b1_temp - voice->b1) / FILTER_TRANSITION_SAMPLES;
  504.       /* Have to add the increments filter_coeff_incr_count times. */
  505.       voice->filter_coeff_incr_count = FILTER_TRANSITION_SAMPLES;
  506.     }
  507.     voice->last_fres = fres;
  508.     fluid_check_fpe ("voice_write filter calculation");
  509.   }
  510.   fluid_check_fpe ("voice_write DSP coefficients");
  511.   /*********************** run the dsp chain ************************
  512.    * The sample is mixed with the output buffer.
  513.    * The buffer has to be filled from 0 to FLUID_BUFSIZE-1.
  514.    * Depending on the position in the loop and the loop size, this
  515.    * may require several runs. */
  516.   switch (voice->interp_method)
  517.   {
  518.     case FLUID_INTERP_NONE:
  519.       count = fluid_dsp_float_interpolate_none (voice);
  520.       break;
  521.     case FLUID_INTERP_LINEAR:
  522.       count = fluid_dsp_float_interpolate_linear (voice);
  523.       break;
  524.     case FLUID_INTERP_4THORDER:
  525.     default:
  526.       count = fluid_dsp_float_interpolate_4th_order (voice);
  527.       break;
  528.     case FLUID_INTERP_7THORDER:
  529.       count = fluid_dsp_float_interpolate_7th_order (voice);
  530.       break;
  531.   }
  532.   fluid_check_fpe ("voice_write interpolation");
  533.   voice->dsp_buf_count = count;
  534.   /* Apply filter */
  535.   if (count > 0) fluid_voice_filter (voice);
  536.   /* turn off voice if short count (sample ended and not looping) */
  537.   if (count < FLUID_BUFSIZE)
  538.   {
  539.       fluid_profile(FLUID_PROF_VOICE_RELEASE, voice->ref);
  540.       fluid_voice_off(voice);
  541.   }
  542.  post_process:
  543.   voice->ticks += FLUID_BUFSIZE;
  544.   fluid_check_fpe ("voice_write postprocess");
  545.   return count;
  546. }
  547. /**
  548.  * Applies a lowpass filter with variable cutoff frequency and quality factor.
  549.  * @param voice Voice to apply filter to
  550.  * @param count Count of samples in voice->dsp_buf
  551.  */
  552. /*
  553.  * Variable description:
  554.  * - dsp_buf: Pointer to the synthesized audio data
  555.  * - dsp_a1, dsp_a2, dsp_b0, dsp_b1, dsp_b2: Filter coefficients
  556.  * - voice holds the voice structure
  557.  *
  558.  * A couple of variables are used internally, their results are discarded:
  559.  * - dsp_i: Index through the output buffer
  560.  * - dsp_phase_fractional: The fractional part of dsp_phase
  561.  * - dsp_coeff: A table of four coefficients, depending on the fractional phase.
  562.  *              Used to interpolate between samples.
  563.  * - dsp_process_buffer: Holds the processed signal between stages
  564.  * - dsp_centernode: delay line for the IIR filter
  565.  * - dsp_hist1: same
  566.  * - dsp_hist2: same
  567.  */
  568. static inline void
  569. fluid_voice_filter (fluid_voice_t *voice)
  570. {
  571.   /* IIR filter sample history */
  572.   fluid_real_t dsp_hist1 = voice->hist1;
  573.   fluid_real_t dsp_hist2 = voice->hist2;
  574.   /* IIR filter coefficients */
  575.   fluid_real_t dsp_a1 = voice->a1;
  576.   fluid_real_t dsp_a2 = voice->a2;
  577.   fluid_real_t dsp_b02 = voice->b02;
  578.   fluid_real_t dsp_b1 = voice->b1;
  579.   fluid_real_t dsp_a1_incr = voice->a1_incr;
  580.   fluid_real_t dsp_a2_incr = voice->a2_incr;
  581.   fluid_real_t dsp_b02_incr = voice->b02_incr;
  582.   fluid_real_t dsp_b1_incr = voice->b1_incr;
  583.   int dsp_filter_coeff_incr_count = voice->filter_coeff_incr_count;
  584.   fluid_real_t *dsp_buf = voice->dsp_buf;
  585.   fluid_real_t dsp_centernode;
  586.   int count = voice->dsp_buf_count;
  587.   int dsp_i;
  588.   /* filter (implement the voice filter according to SoundFont standard) */
  589.   /* Check for denormal number (too close to zero). */
  590.   if (fabs (dsp_hist1) < 1e-20) dsp_hist1 = 0.0f;  /* FIXME JMG - Is this even needed? */
  591.   /* Two versions of the filter loop. One, while the filter is
  592.   * changing towards its new setting. The other, if the filter
  593.   * doesn't change.
  594.   */
  595.   if (dsp_filter_coeff_incr_count > 0)
  596.   {
  597.     /* Increment is added to each filter coefficient filter_coeff_incr_count times. */
  598.     for (dsp_i = 0; dsp_i < count; dsp_i++)
  599.     {
  600.       /* The filter is implemented in Direct-II form. */
  601.       dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
  602.       dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
  603.       dsp_hist2 = dsp_hist1;
  604.       dsp_hist1 = dsp_centernode;
  605.       if (dsp_filter_coeff_incr_count-- > 0)
  606.       {
  607. dsp_a1 += dsp_a1_incr;
  608. dsp_a2 += dsp_a2_incr;
  609. dsp_b02 += dsp_b02_incr;
  610. dsp_b1 += dsp_b1_incr;
  611.       }
  612.     } /* for dsp_i */
  613.   }
  614.   else /* The filter parameters are constant.  This is duplicated to save time. */
  615.   {
  616.     for (dsp_i = 0; dsp_i < count; dsp_i++)
  617.     { /* The filter is implemented in Direct-II form. */
  618.       dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
  619.       dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
  620.       dsp_hist2 = dsp_hist1;
  621.       dsp_hist1 = dsp_centernode;
  622.     }
  623.   }
  624.   voice->hist1 = dsp_hist1;
  625.   voice->hist2 = dsp_hist2;
  626.   voice->a1 = dsp_a1;
  627.   voice->a2 = dsp_a2;
  628.   voice->b02 = dsp_b02;
  629.   voice->b1 = dsp_b1;
  630.   voice->filter_coeff_incr_count = dsp_filter_coeff_incr_count;
  631.   fluid_check_fpe ("voice_filter");
  632. }
  633. /**
  634.  * Mix voice data to left/right (panning), reverb and chorus buffers.
  635.  * @param voice Voice to mix
  636.  * @param left_buf Left audio buffer
  637.  * @param right_buf Right audio buffer
  638.  * @param reverb_buf Reverb buffer
  639.  * @param chorus_buf Chorus buffer
  640.  *
  641.  * NOTE: Uses voice->dsp_buf and voice->dsp_buf_count which were assigned
  642.  * by fluid_voice_write().  This is therefore meant to be called only after
  643.  * that function.
  644.  */
  645. void
  646. fluid_voice_mix (fluid_voice_t *voice,
  647.  fluid_real_t* left_buf, fluid_real_t* right_buf,
  648.  fluid_real_t* reverb_buf, fluid_real_t* chorus_buf)
  649. {
  650.   fluid_real_t *dsp_buf = voice->dsp_buf;
  651.   int count = voice->dsp_buf_count;
  652.   int dsp_i;
  653.   float v;
  654.   /* pan (Copy the signal to the left and right output buffer) The voice
  655.    * panning generator has a range of -500 .. 500.  If it is centered,
  656.    * it's close to 0.  voice->amp_left and voice->amp_right are then the
  657.    * same, and we can save one multiplication per voice and sample.
  658.    */
  659.   if ((-0.5 < voice->pan) && (voice->pan < 0.5))
  660.   {
  661.     /* The voice is centered. Use voice->amp_left twice. */
  662.     for (dsp_i = 0; dsp_i < count; dsp_i++)
  663.     {
  664.       v = voice->amp_left * dsp_buf[dsp_i];
  665.       left_buf[dsp_i] += v;
  666.       right_buf[dsp_i] += v;
  667.     }
  668.   }
  669.   else /* The voice is not centered. Stereo samples have one side zero. */
  670.   {
  671.     if (voice->amp_left != 0.0)
  672.     {
  673.       for (dsp_i = 0; dsp_i < count; dsp_i++)
  674. left_buf[dsp_i] += voice->amp_left * dsp_buf[dsp_i];
  675.     }
  676.     if (voice->amp_right != 0.0)
  677.     {
  678.       for (dsp_i = 0; dsp_i < count; dsp_i++)
  679. right_buf[dsp_i] += voice->amp_right * dsp_buf[dsp_i];
  680.     }
  681.   }
  682.   /* reverb send. Buffer may be NULL. */
  683.   if ((reverb_buf != NULL) && (voice->amp_reverb != 0.0))
  684.   {
  685.     for (dsp_i = 0; dsp_i < count; dsp_i++)
  686.       reverb_buf[dsp_i] += voice->amp_reverb * dsp_buf[dsp_i];
  687.   }
  688.   /* chorus send. Buffer may be NULL. */
  689.   if ((chorus_buf != NULL) && (voice->amp_chorus != 0))
  690.   {
  691.     for (dsp_i = 0; dsp_i < count; dsp_i++)
  692.       chorus_buf[dsp_i] += voice->amp_chorus * dsp_buf[dsp_i];
  693.   }
  694.   fluid_check_fpe ("voice_mix");
  695. }
  696. /*
  697.  * fluid_voice_start
  698.  */
  699. void fluid_voice_start(fluid_voice_t* voice)
  700. {
  701.   /* The maximum volume of the loop is calculated and cached once for each
  702.    * sample with its nominal loop settings. This happens, when the sample is used
  703.    * for the first time.*/
  704.   fluid_voice_calculate_runtime_synthesis_parameters(voice);
  705.   /* Force setting of the phase at the first DSP loop run
  706.    * This cannot be done earlier, because it depends on modulators.*/
  707.   voice->check_sample_sanity_flag=FLUID_SAMPLESANITY_STARTUP;
  708.   voice->ref = fluid_profile_ref();
  709.   voice->status = FLUID_VOICE_ON;
  710.   /* Increment voice count atomically, for non-synth thread read access */
  711.   fluid_atomic_int_add (&voice->channel->synth->active_voice_count, 1);
  712. }
  713. void 
  714. fluid_voice_calculate_gen_pitch(fluid_voice_t* voice)
  715. {
  716.   fluid_tuning_t* tuning;
  717.   fluid_real_t x;
  718.   /* The GEN_PITCH is a hack to fit the pitch bend controller into the
  719.    * modulator paradigm.  Now the nominal pitch of the key is set.
  720.    * Note about SCALETUNE: SF2.01 8.1.3 says, that this generator is a
  721.    * non-realtime parameter. So we don't allow modulation (as opposed
  722.    * to _GEN(voice, GEN_SCALETUNE) When the scale tuning is varied,
  723.    * one key remains fixed. Here C3 (MIDI number 60) is used.
  724.    */
  725.   if (fluid_channel_has_tuning(voice->channel)) {
  726.     tuning = fluid_channel_get_tuning (voice->channel);
  727.     x = fluid_tuning_get_pitch (tuning, (int)(voice->root_pitch / 100.0f));
  728.     voice->gen[GEN_PITCH].val = voice->gen[GEN_SCALETUNE].val / 100.0f *
  729.       (fluid_tuning_get_pitch (tuning, voice->key) - x) + x;
  730.   } else {
  731.     voice->gen[GEN_PITCH].val = voice->gen[GEN_SCALETUNE].val
  732.       * (voice->key - voice->root_pitch / 100.0f) + voice->root_pitch;
  733.   }
  734. }
  735. /*
  736.  * fluid_voice_calculate_runtime_synthesis_parameters
  737.  *
  738.  * in this function we calculate the values of all the parameters. the
  739.  * parameters are converted to their most useful unit for the DSP
  740.  * algorithm, for example, number of samples instead of
  741.  * timecents. Some parameters keep their "perceptual" unit and
  742.  * conversion will be done in the DSP function. This is the case, for
  743.  * example, for the pitch since it is modulated by the controllers in
  744.  * cents. */
  745. static int
  746. fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice)
  747. {
  748.   int i;
  749.   int list_of_generators_to_initialize[35] = {
  750.     GEN_STARTADDROFS,                    /* SF2.01 page 48 #0   */
  751.     GEN_ENDADDROFS,                      /*                #1   */
  752.     GEN_STARTLOOPADDROFS,                /*                #2   */
  753.     GEN_ENDLOOPADDROFS,                  /*                #3   */
  754.     /* GEN_STARTADDRCOARSEOFS see comment below [1]        #4   */
  755.     GEN_MODLFOTOPITCH,                   /*                #5   */
  756.     GEN_VIBLFOTOPITCH,                   /*                #6   */
  757.     GEN_MODENVTOPITCH,                   /*                #7   */
  758.     GEN_FILTERFC,                        /*                #8   */
  759.     GEN_FILTERQ,                         /*                #9   */
  760.     GEN_MODLFOTOFILTERFC,                /*                #10  */
  761.     GEN_MODENVTOFILTERFC,                /*                #11  */
  762.     /* GEN_ENDADDRCOARSEOFS [1]                            #12  */
  763.     GEN_MODLFOTOVOL,                     /*                #13  */
  764.     /* not defined                                         #14  */
  765.     GEN_CHORUSSEND,                      /*                #15  */
  766.     GEN_REVERBSEND,                      /*                #16  */
  767.     GEN_PAN,                             /*                #17  */
  768.     /* not defined                                         #18  */
  769.     /* not defined                                         #19  */
  770.     /* not defined                                         #20  */
  771.     GEN_MODLFODELAY,                     /*                #21  */
  772.     GEN_MODLFOFREQ,                      /*                #22  */
  773.     GEN_VIBLFODELAY,                     /*                #23  */
  774.     GEN_VIBLFOFREQ,                      /*                #24  */
  775.     GEN_MODENVDELAY,                     /*                #25  */
  776.     GEN_MODENVATTACK,                    /*                #26  */
  777.     GEN_MODENVHOLD,                      /*                #27  */
  778.     GEN_MODENVDECAY,                     /*                #28  */
  779.     /* GEN_MODENVSUSTAIN [1]                               #29  */
  780.     GEN_MODENVRELEASE,                   /*                #30  */
  781.     /* GEN_KEYTOMODENVHOLD [1]                             #31  */
  782.     /* GEN_KEYTOMODENVDECAY [1]                            #32  */
  783.     GEN_VOLENVDELAY,                     /*                #33  */
  784.     GEN_VOLENVATTACK,                    /*                #34  */
  785.     GEN_VOLENVHOLD,                      /*                #35  */
  786.     GEN_VOLENVDECAY,                     /*                #36  */
  787.     /* GEN_VOLENVSUSTAIN [1]                               #37  */
  788.     GEN_VOLENVRELEASE,                   /*                #38  */
  789.     /* GEN_KEYTOVOLENVHOLD [1]                             #39  */
  790.     /* GEN_KEYTOVOLENVDECAY [1]                            #40  */
  791.     /* GEN_STARTLOOPADDRCOARSEOFS [1]                      #45  */
  792.     GEN_KEYNUM,                          /*                #46  */
  793.     GEN_VELOCITY,                        /*                #47  */
  794.     GEN_ATTENUATION,                     /*                #48  */
  795.     /* GEN_ENDLOOPADDRCOARSEOFS [1]                        #50  */
  796.     /* GEN_COARSETUNE           [1]                        #51  */
  797.     /* GEN_FINETUNE             [1]                        #52  */
  798.     GEN_OVERRIDEROOTKEY,                 /*                #58  */
  799.     GEN_PITCH,                           /*                ---  */
  800.     -1};                                 /* end-of-list marker  */
  801.   /* When the voice is made ready for the synthesis process, a lot of
  802.    * voice-internal parameters have to be calculated.
  803.    *
  804.    * At this point, the sound font has already set the -nominal- value
  805.    * for all generators (excluding GEN_PITCH). Most generators can be
  806.    * modulated - they include a nominal value and an offset (which
  807.    * changes with velocity, note number, channel parameters like
  808.    * aftertouch, mod wheel...) Now this offset will be calculated as
  809.    * follows:
  810.    *
  811.    *  - Process each modulator once.
  812.    *  - Calculate its output value.
  813.    *  - Find the target generator.
  814.    *  - Add the output value to the modulation value of the generator.
  815.    *
  816.    * Note: The generators have been initialized with
  817.    * fluid_gen_set_default_values.
  818.    */
  819.   for (i = 0; i < voice->mod_count; i++) {
  820.     fluid_mod_t* mod = &voice->mod[i];
  821.     fluid_real_t modval = fluid_mod_get_value(mod, voice->channel, voice);
  822.     int dest_gen_index = mod->dest;
  823.     fluid_gen_t* dest_gen = &voice->gen[dest_gen_index];
  824.     dest_gen->mod += modval;
  825.     /*      fluid_dump_modulator(mod); */
  826.   }
  827.   /* Now the generators are initialized, nominal and modulation value.
  828.    * The voice parameters (which depend on generators) are calculated
  829.    * with fluid_voice_update_param. Processing the list of generator
  830.    * changes will calculate each voice parameter once.
  831.    *
  832.    * Note [1]: Some voice parameters depend on several generators. For
  833.    * example, the pitch depends on GEN_COARSETUNE, GEN_FINETUNE and
  834.    * GEN_PITCH.  voice->pitch.  Unnecessary recalculation is avoided
  835.    * by removing all but one generator from the list of voice
  836.    * parameters.  Same with GEN_XXX and GEN_XXXCOARSE: the
  837.    * initialisation list contains only GEN_XXX.
  838.    */
  839.   /* Calculate the voice parameter(s) dependent on each generator. */
  840.   for (i = 0; list_of_generators_to_initialize[i] != -1; i++) {
  841.     fluid_voice_update_param(voice, list_of_generators_to_initialize[i]);
  842.   }
  843.   /* Make an estimate on how loud this voice can get at any time (attenuation). */
  844.   voice->min_attenuation_cB = fluid_voice_get_lower_boundary_for_attenuation(voice);
  845.   return FLUID_OK;
  846. }
  847. /*
  848.  * calculate_hold_decay_buffers
  849.  */
  850. static int
  851. calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base,
  852.                              int gen_key2base, int is_decay)
  853. {
  854.   /* Purpose:
  855.    *
  856.    * Returns the number of DSP loops, that correspond to the hold
  857.    * (is_decay=0) or decay (is_decay=1) time.
  858.    * gen_base=GEN_VOLENVHOLD, GEN_VOLENVDECAY, GEN_MODENVHOLD,
  859.    * GEN_MODENVDECAY gen_key2base=GEN_KEYTOVOLENVHOLD,
  860.    * GEN_KEYTOVOLENVDECAY, GEN_KEYTOMODENVHOLD, GEN_KEYTOMODENVDECAY
  861.    */
  862.   fluid_real_t timecents;
  863.   fluid_real_t seconds;
  864.   int buffers;
  865.   /* SF2.01 section 8.4.3 # 31, 32, 39, 40
  866.    * GEN_KEYTOxxxENVxxx uses key 60 as 'origin'.
  867.    * The unit of the generator is timecents per key number.
  868.    * If KEYTOxxxENVxxx is 100, a key one octave over key 60 (72)
  869.    * will cause (60-72)*100=-1200 timecents of time variation.
  870.    * The time is cut in half.
  871.    */
  872.   timecents = (_GEN(voice, gen_base) + _GEN(voice, gen_key2base) * (60.0 - voice->key));
  873.   /* Range checking */
  874.   if (is_decay){
  875.     /* SF 2.01 section 8.1.3 # 28, 36 */
  876.     if (timecents > 8000.0) {
  877.       timecents = 8000.0;
  878.     }
  879.   } else {
  880.     /* SF 2.01 section 8.1.3 # 27, 35 */
  881.     if (timecents > 5000) {
  882.       timecents = 5000.0;
  883.     }
  884.     /* SF 2.01 section 8.1.2 # 27, 35:
  885.      * The most negative number indicates no hold time
  886.      */
  887.     if (timecents <= -32768.) {
  888.       return 0;
  889.     }
  890.   }
  891.   /* SF 2.01 section 8.1.3 # 27, 28, 35, 36 */
  892.   if (timecents < -12000.0) {
  893.     timecents = -12000.0;
  894.   }
  895.   seconds = fluid_tc2sec(timecents);
  896.   /* Each DSP loop processes FLUID_BUFSIZE samples. */
  897.   /* round to next full number of buffers */
  898.   buffers = (int)(((fluid_real_t)voice->output_rate * seconds)
  899.   / (fluid_real_t)FLUID_BUFSIZE
  900.   +0.5);
  901.   return buffers;
  902. }
  903. /*
  904.  * The value of a generator (gen) has changed.  (The different
  905.  * generators are listed in fluidsynth.h, or in SF2.01 page 48-49)
  906.  * Now the dependent 'voice' parameters are calculated.
  907.  *
  908.  * fluid_voice_update_param can be called during the setup of the
  909.  * voice (to calculate the initial value for a voice parameter), or
  910.  * during its operation (a generator has been changed due to
  911.  * real-time parameter modifications like pitch-bend).
  912.  *
  913.  * Note: The generator holds three values: The base value .val, an
  914.  * offset caused by modulators .mod, and an offset caused by the
  915.  * NRPN system. _GEN(voice, generator_enumerator) returns the sum
  916.  * of all three.
  917.  */
  918. /**
  919.  * Update all the synthesis parameters, which depend on generator a gen.
  920.  * @param voice Voice instance
  921.  * @param gen Generator id (#fluid_gen_type)
  922.  *
  923.  * This is only necessary after changing a generator of an already operating voice.
  924.  * Most applications will not need this function.
  925.  */
  926. void
  927. fluid_voice_update_param(fluid_voice_t* voice, int gen)
  928. {
  929.   double q_dB;
  930.   fluid_real_t x;
  931.   fluid_real_t y;
  932.   unsigned int count;
  933.   // Alternate attenuation scale used by EMU10K1 cards when setting the attenuation at the preset or instrument level within the SoundFont bank.
  934.   static const float ALT_ATTENUATION_SCALE = 0.4;
  935.   switch (gen) {
  936.   case GEN_PAN:
  937.     /* range checking is done in the fluid_pan function */
  938.     voice->pan = _GEN(voice, GEN_PAN);
  939.     voice->amp_left = fluid_pan(voice->pan, 1) * voice->synth_gain / 32768.0f;
  940.     voice->amp_right = fluid_pan(voice->pan, 0) * voice->synth_gain / 32768.0f;
  941.     break;
  942.   case GEN_ATTENUATION:
  943.     voice->attenuation = ((fluid_real_t)(voice)->gen[GEN_ATTENUATION].val*ALT_ATTENUATION_SCALE) +
  944.     (fluid_real_t)(voice)->gen[GEN_ATTENUATION].mod + (fluid_real_t)(voice)->gen[GEN_ATTENUATION].nrpn;
  945.     /* Range: SF2.01 section 8.1.3 # 48
  946.      * Motivation for range checking:
  947.      * OHPiano.SF2 sets initial attenuation to a whooping -96 dB */
  948.     fluid_clip(voice->attenuation, 0.0, 1440.0);
  949.     break;
  950.     /* The pitch is calculated from three different generators.
  951.      * Read comment in fluidsynth.h about GEN_PITCH.
  952.      */
  953.   case GEN_PITCH:
  954.   case GEN_COARSETUNE:
  955.   case GEN_FINETUNE:
  956.     /* The testing for allowed range is done in 'fluid_ct2hz' */
  957.     voice->pitch = (_GEN(voice, GEN_PITCH)
  958.     + 100.0f * _GEN(voice, GEN_COARSETUNE)
  959.     + _GEN(voice, GEN_FINETUNE));
  960.     break;
  961.   case GEN_REVERBSEND:
  962.     /* The generator unit is 'tenths of a percent'. */
  963.     voice->reverb_send = _GEN(voice, GEN_REVERBSEND) / 1000.0f;
  964.     fluid_clip(voice->reverb_send, 0.0, 1.0);
  965.     voice->amp_reverb = voice->reverb_send * voice->synth_gain / 32768.0f;
  966.     break;
  967.   case GEN_CHORUSSEND:
  968.     /* The generator unit is 'tenths of a percent'. */
  969.     voice->chorus_send = _GEN(voice, GEN_CHORUSSEND) / 1000.0f;
  970.     fluid_clip(voice->chorus_send, 0.0, 1.0);
  971.     voice->amp_chorus = voice->chorus_send * voice->synth_gain / 32768.0f;
  972.     break;
  973.   case GEN_OVERRIDEROOTKEY:
  974.     /* This is a non-realtime parameter. Therefore the .mod part of the generator
  975.      * can be neglected.
  976.      * NOTE: origpitch sets MIDI root note while pitchadj is a fine tuning amount
  977.      * which offsets the original rate.  This means that the fine tuning is
  978.      * inverted with respect to the root note (so subtract it, not add).
  979.      */
  980.     if (voice->gen[GEN_OVERRIDEROOTKEY].val > -1) {   //FIXME: use flag instead of -1
  981.       voice->root_pitch = voice->gen[GEN_OVERRIDEROOTKEY].val * 100.0f
  982. - voice->sample->pitchadj;
  983.     } else {
  984.       voice->root_pitch = voice->sample->origpitch * 100.0f - voice->sample->pitchadj;
  985.     }
  986.     voice->root_pitch_hz = fluid_ct2hz(voice->root_pitch);
  987.     if (voice->sample != NULL) {
  988.       voice->root_pitch_hz *= (fluid_real_t) voice->output_rate / voice->sample->samplerate;
  989.     }
  990.     /* voice->pitch depends on voice->root_pitch, so calculate voice->pitch now */
  991.     fluid_voice_calculate_gen_pitch(voice);
  992.     break;
  993.   case GEN_FILTERFC:
  994.     /* The resonance frequency is converted from absolute cents to
  995.      * midicents .val and .mod are both used, this permits real-time
  996.      * modulation.  The allowed range is tested in the 'fluid_ct2hz'
  997.      * function [PH,20021214]
  998.      */
  999.     voice->fres = _GEN(voice, GEN_FILTERFC);
  1000.     /* The synthesis loop will have to recalculate the filter
  1001.      * coefficients. */
  1002.     voice->last_fres = -1.0f;
  1003.     break;
  1004.   case GEN_FILTERQ:
  1005.     /* The generator contains 'centibels' (1/10 dB) => divide by 10 to
  1006.      * obtain dB */
  1007.     q_dB = _GEN(voice, GEN_FILTERQ) / 10.0f;
  1008.     /* Range: SF2.01 section 8.1.3 # 8 (convert from cB to dB => /10) */
  1009.     fluid_clip(q_dB, 0.0f, 96.0f);
  1010.     /* Short version: Modify the Q definition in a way, that a Q of 0
  1011.      * dB leads to no resonance hump in the freq. response.
  1012.      *
  1013.      * Long version: From SF2.01, page 39, item 9 (initialFilterQ):
  1014.      * "The gain at the cutoff frequency may be less than zero when
  1015.      * zero is specified".  Assume q_dB=0 / q_lin=1: If we would leave
  1016.      * q as it is, then this results in a 3 dB hump slightly below
  1017.      * fc. At fc, the gain is exactly the DC gain (0 dB).  What is
  1018.      * (probably) meant here is that the filter does not show a
  1019.      * resonance hump for q_dB=0. In this case, the corresponding
  1020.      * q_lin is 1/sqrt(2)=0.707.  The filter should have 3 dB of
  1021.      * attenuation at fc now.  In this case Q_dB is the height of the
  1022.      * resonance peak not over the DC gain, but over the frequency
  1023.      * response of a non-resonant filter.  This idea is implemented as
  1024.      * follows: */
  1025.     q_dB -= 3.01f;
  1026.     /* The 'sound font' Q is defined in dB. The filter needs a linear
  1027.        q. Convert. */
  1028.     voice->q_lin = (fluid_real_t) (pow(10.0f, q_dB / 20.0f));
  1029.     /* SF 2.01 page 59:
  1030.      *
  1031.      *  The SoundFont specs ask for a gain reduction equal to half the
  1032.      *  height of the resonance peak (Q).  For example, for a 10 dB
  1033.      *  resonance peak, the gain is reduced by 5 dB.  This is done by
  1034.      *  multiplying the total gain with sqrt(1/Q).  `Sqrt' divides dB
  1035.      *  by 2 (100 lin = 40 dB, 10 lin = 20 dB, 3.16 lin = 10 dB etc)
  1036.      *  The gain is later factored into the 'b' coefficients
  1037.      *  (numerator of the filter equation).  This gain factor depends
  1038.      *  only on Q, so this is the right place to calculate it.
  1039.      */
  1040.     voice->filter_gain = (fluid_real_t) (1.0 / sqrt(voice->q_lin));
  1041.     /* The synthesis loop will have to recalculate the filter coefficients. */
  1042.     voice->last_fres = -1.;
  1043.     break;
  1044.   case GEN_MODLFOTOPITCH:
  1045.     voice->modlfo_to_pitch = _GEN(voice, GEN_MODLFOTOPITCH);
  1046.     fluid_clip(voice->modlfo_to_pitch, -12000.0, 12000.0);
  1047.     break;
  1048.   case GEN_MODLFOTOVOL:
  1049.     voice->modlfo_to_vol = _GEN(voice, GEN_MODLFOTOVOL);
  1050.     fluid_clip(voice->modlfo_to_vol, -960.0, 960.0);
  1051.     break;
  1052.   case GEN_MODLFOTOFILTERFC:
  1053.     voice->modlfo_to_fc = _GEN(voice, GEN_MODLFOTOFILTERFC);
  1054.     fluid_clip(voice->modlfo_to_fc, -12000, 12000);
  1055.     break;
  1056.   case GEN_MODLFODELAY:
  1057.     x = _GEN(voice, GEN_MODLFODELAY);
  1058.     fluid_clip(x, -12000.0f, 5000.0f);
  1059.     voice->modlfo_delay = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x));
  1060.     break;
  1061.   case GEN_MODLFOFREQ:
  1062.     /* - the frequency is converted into a delta value, per buffer of FLUID_BUFSIZE samples
  1063.      * - the delay into a sample delay
  1064.      */
  1065.     x = _GEN(voice, GEN_MODLFOFREQ);
  1066.     fluid_clip(x, -16000.0f, 4500.0f);
  1067.     voice->modlfo_incr = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate);
  1068.     break;
  1069.   case GEN_VIBLFOFREQ:
  1070.     /* vib lfo
  1071.      *
  1072.      * - the frequency is converted into a delta value, per buffer of FLUID_BUFSIZE samples
  1073.      * - the delay into a sample delay
  1074.      */
  1075.     x = _GEN(voice, GEN_VIBLFOFREQ);
  1076.     fluid_clip(x, -16000.0f, 4500.0f);
  1077.     voice->viblfo_incr = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate);
  1078.     break;
  1079.   case GEN_VIBLFODELAY:
  1080.     x = _GEN(voice,GEN_VIBLFODELAY);
  1081.     fluid_clip(x, -12000.0f, 5000.0f);
  1082.     voice->viblfo_delay = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x));
  1083.     break;
  1084.   case GEN_VIBLFOTOPITCH:
  1085.     voice->viblfo_to_pitch = _GEN(voice, GEN_VIBLFOTOPITCH);
  1086.     fluid_clip(voice->viblfo_to_pitch, -12000.0, 12000.0);
  1087.     break;
  1088.   case GEN_KEYNUM:
  1089.     /* GEN_KEYNUM: SF2.01 page 46, item 46
  1090.      *
  1091.      * If this generator is active, it forces the key number to its
  1092.      * value.  Non-realtime controller.
  1093.      *
  1094.      * There is a flag, which should indicate, whether a generator is
  1095.      * enabled or not.  But here we rely on the default value of -1.
  1096.      * */
  1097.     x = _GEN(voice, GEN_KEYNUM);
  1098.     if (x >= 0){
  1099.       voice->key = x;
  1100.     }
  1101.     break;
  1102.   case GEN_VELOCITY:
  1103.     /* GEN_VELOCITY: SF2.01 page 46, item 47
  1104.      *
  1105.      * If this generator is active, it forces the velocity to its
  1106.      * value. Non-realtime controller.
  1107.      *
  1108.      * There is a flag, which should indicate, whether a generator is
  1109.      * enabled or not. But here we rely on the default value of -1.  */
  1110.     x = _GEN(voice, GEN_VELOCITY);
  1111.     if (x > 0) {
  1112.       voice->vel = x;
  1113.     }
  1114.     break;
  1115.   case GEN_MODENVTOPITCH:
  1116.     voice->modenv_to_pitch = _GEN(voice, GEN_MODENVTOPITCH);
  1117.     fluid_clip(voice->modenv_to_pitch, -12000.0, 12000.0);
  1118.     break;
  1119.   case GEN_MODENVTOFILTERFC:
  1120.     voice->modenv_to_fc = _GEN(voice,GEN_MODENVTOFILTERFC);
  1121.     /* Range: SF2.01 section 8.1.3 # 1
  1122.      * Motivation for range checking:
  1123.      * Filter is reported to make funny noises now and then
  1124.      */
  1125.     fluid_clip(voice->modenv_to_fc, -12000.0, 12000.0);
  1126.     break;
  1127.     /* sample start and ends points
  1128.      *
  1129.      * Range checking is initiated via the
  1130.      * voice->check_sample_sanity flag,
  1131.      * because it is impossible to check here:
  1132.      * During the voice setup, all modulators are processed, while
  1133.      * the voice is inactive. Therefore, illegal settings may
  1134.      * occur during the setup (for example: First move the loop
  1135.      * end point ahead of the loop start point => invalid, then
  1136.      * move the loop start point forward => valid again.
  1137.      */
  1138.   case GEN_STARTADDROFS:              /* SF2.01 section 8.1.3 # 0 */
  1139.   case GEN_STARTADDRCOARSEOFS:        /* SF2.01 section 8.1.3 # 4 */
  1140.     if (voice->sample != NULL) {
  1141.       voice->start = (voice->sample->start
  1142.      + (int) _GEN(voice, GEN_STARTADDROFS)
  1143.      + 32768 * (int) _GEN(voice, GEN_STARTADDRCOARSEOFS));
  1144.       voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
  1145.     }
  1146.     break;
  1147.   case GEN_ENDADDROFS:                 /* SF2.01 section 8.1.3 # 1 */
  1148.   case GEN_ENDADDRCOARSEOFS:           /* SF2.01 section 8.1.3 # 12 */
  1149.     if (voice->sample != NULL) {
  1150.       voice->end = (voice->sample->end
  1151.    + (int) _GEN(voice, GEN_ENDADDROFS)
  1152.    + 32768 * (int) _GEN(voice, GEN_ENDADDRCOARSEOFS));
  1153.       voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
  1154.     }
  1155.     break;
  1156.   case GEN_STARTLOOPADDROFS:           /* SF2.01 section 8.1.3 # 2 */
  1157.   case GEN_STARTLOOPADDRCOARSEOFS:     /* SF2.01 section 8.1.3 # 45 */
  1158.     if (voice->sample != NULL) {
  1159.       voice->loopstart = (voice->sample->loopstart
  1160.   + (int) _GEN(voice, GEN_STARTLOOPADDROFS)
  1161.   + 32768 * (int) _GEN(voice, GEN_STARTLOOPADDRCOARSEOFS));
  1162.       voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
  1163.     }
  1164.     break;
  1165.   case GEN_ENDLOOPADDROFS:             /* SF2.01 section 8.1.3 # 3 */
  1166.   case GEN_ENDLOOPADDRCOARSEOFS:       /* SF2.01 section 8.1.3 # 50 */
  1167.     if (voice->sample != NULL) {
  1168.       voice->loopend = (voice->sample->loopend
  1169. + (int) _GEN(voice, GEN_ENDLOOPADDROFS)
  1170. + 32768 * (int) _GEN(voice, GEN_ENDLOOPADDRCOARSEOFS));
  1171.       voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
  1172.     }
  1173.     break;
  1174.     /* Conversion functions differ in range limit */
  1175. #define NUM_BUFFERS_DELAY(_v)   (unsigned int) (voice->output_rate * fluid_tc2sec_delay(_v) / FLUID_BUFSIZE)
  1176. #define NUM_BUFFERS_ATTACK(_v)  (unsigned int) (voice->output_rate * fluid_tc2sec_attack(_v) / FLUID_BUFSIZE)
  1177. #define NUM_BUFFERS_RELEASE(_v) (unsigned int) (voice->output_rate * fluid_tc2sec_release(_v) / FLUID_BUFSIZE)
  1178.     /* volume envelope
  1179.      *
  1180.      * - delay and hold times are converted to absolute number of samples
  1181.      * - sustain is converted to its absolute value
  1182.      * - attack, decay and release are converted to their increment per sample
  1183.      */
  1184.   case GEN_VOLENVDELAY:                /* SF2.01 section 8.1.3 # 33 */
  1185.     x = _GEN(voice, GEN_VOLENVDELAY);
  1186.     fluid_clip(x, -12000.0f, 5000.0f);
  1187.     count = NUM_BUFFERS_DELAY(x);
  1188.     voice->volenv_data[FLUID_VOICE_ENVDELAY].count = count;
  1189.     voice->volenv_data[FLUID_VOICE_ENVDELAY].coeff = 0.0f;
  1190.     voice->volenv_data[FLUID_VOICE_ENVDELAY].incr = 0.0f;
  1191.     voice->volenv_data[FLUID_VOICE_ENVDELAY].min = -1.0f;
  1192.     voice->volenv_data[FLUID_VOICE_ENVDELAY].max = 1.0f;
  1193.     break;
  1194.   case GEN_VOLENVATTACK:               /* SF2.01 section 8.1.3 # 34 */
  1195.     x = _GEN(voice, GEN_VOLENVATTACK);
  1196.     fluid_clip(x, -12000.0f, 8000.0f);
  1197.     count = 1 + NUM_BUFFERS_ATTACK(x);
  1198.     voice->volenv_data[FLUID_VOICE_ENVATTACK].count = count;
  1199.     voice->volenv_data[FLUID_VOICE_ENVATTACK].coeff = 1.0f;
  1200.     voice->volenv_data[FLUID_VOICE_ENVATTACK].incr = count ? 1.0f / count : 0.0f;
  1201.     voice->volenv_data[FLUID_VOICE_ENVATTACK].min = -1.0f;
  1202.     voice->volenv_data[FLUID_VOICE_ENVATTACK].max = 1.0f;
  1203.     break;
  1204.   case GEN_VOLENVHOLD:                 /* SF2.01 section 8.1.3 # 35 */
  1205.   case GEN_KEYTOVOLENVHOLD:            /* SF2.01 section 8.1.3 # 39 */
  1206.     count = calculate_hold_decay_buffers(voice, GEN_VOLENVHOLD, GEN_KEYTOVOLENVHOLD, 0); /* 0 means: hold */
  1207.     voice->volenv_data[FLUID_VOICE_ENVHOLD].count = count;
  1208.     voice->volenv_data[FLUID_VOICE_ENVHOLD].coeff = 1.0f;
  1209.     voice->volenv_data[FLUID_VOICE_ENVHOLD].incr = 0.0f;
  1210.     voice->volenv_data[FLUID_VOICE_ENVHOLD].min = -1.0f;
  1211.     voice->volenv_data[FLUID_VOICE_ENVHOLD].max = 2.0f;
  1212.     break;
  1213.   case GEN_VOLENVDECAY:               /* SF2.01 section 8.1.3 # 36 */
  1214.   case GEN_VOLENVSUSTAIN:             /* SF2.01 section 8.1.3 # 37 */
  1215.   case GEN_KEYTOVOLENVDECAY:          /* SF2.01 section 8.1.3 # 40 */
  1216.     y = 1.0f - 0.001f * _GEN(voice, GEN_VOLENVSUSTAIN);
  1217.     fluid_clip(y, 0.0f, 1.0f);
  1218.     count = calculate_hold_decay_buffers(voice, GEN_VOLENVDECAY, GEN_KEYTOVOLENVDECAY, 1); /* 1 for decay */
  1219.     voice->volenv_data[FLUID_VOICE_ENVDECAY].count = count;
  1220.     voice->volenv_data[FLUID_VOICE_ENVDECAY].coeff = 1.0f;
  1221.     voice->volenv_data[FLUID_VOICE_ENVDECAY].incr = count ? -1.0f / count : 0.0f;
  1222.     voice->volenv_data[FLUID_VOICE_ENVDECAY].min = y;
  1223.     voice->volenv_data[FLUID_VOICE_ENVDECAY].max = 2.0f;
  1224.     break;
  1225.   case GEN_VOLENVRELEASE:             /* SF2.01 section 8.1.3 # 38 */
  1226.     x = _GEN(voice, GEN_VOLENVRELEASE);
  1227.     fluid_clip(x, FLUID_MIN_VOLENVRELEASE, 8000.0f);
  1228.     count = 1 + NUM_BUFFERS_RELEASE(x);
  1229.     voice->volenv_data[FLUID_VOICE_ENVRELEASE].count = count;
  1230.     voice->volenv_data[FLUID_VOICE_ENVRELEASE].coeff = 1.0f;
  1231.     voice->volenv_data[FLUID_VOICE_ENVRELEASE].incr = count ? -1.0f / count : 0.0f;
  1232.     voice->volenv_data[FLUID_VOICE_ENVRELEASE].min = 0.0f;
  1233.     voice->volenv_data[FLUID_VOICE_ENVRELEASE].max = 1.0f;
  1234.     break;
  1235.     /* Modulation envelope */
  1236.   case GEN_MODENVDELAY:               /* SF2.01 section 8.1.3 # 25 */
  1237.     x = _GEN(voice, GEN_MODENVDELAY);
  1238.     fluid_clip(x, -12000.0f, 5000.0f);
  1239.     voice->modenv_data[FLUID_VOICE_ENVDELAY].count = NUM_BUFFERS_DELAY(x);
  1240.     voice->modenv_data[FLUID_VOICE_ENVDELAY].coeff = 0.0f;
  1241.     voice->modenv_data[FLUID_VOICE_ENVDELAY].incr = 0.0f;
  1242.     voice->modenv_data[FLUID_VOICE_ENVDELAY].min = -1.0f;
  1243.     voice->modenv_data[FLUID_VOICE_ENVDELAY].max = 1.0f;
  1244.     break;
  1245.   case GEN_MODENVATTACK:               /* SF2.01 section 8.1.3 # 26 */
  1246.     x = _GEN(voice, GEN_MODENVATTACK);
  1247.     fluid_clip(x, -12000.0f, 8000.0f);
  1248.     count = 1 + NUM_BUFFERS_ATTACK(x);
  1249.     voice->modenv_data[FLUID_VOICE_ENVATTACK].count = count;
  1250.     voice->modenv_data[FLUID_VOICE_ENVATTACK].coeff = 1.0f;
  1251.     voice->modenv_data[FLUID_VOICE_ENVATTACK].incr = count ? 1.0f / count : 0.0f;
  1252.     voice->modenv_data[FLUID_VOICE_ENVATTACK].min = -1.0f;
  1253.     voice->modenv_data[FLUID_VOICE_ENVATTACK].max = 1.0f;
  1254.     break;
  1255.   case GEN_MODENVHOLD:               /* SF2.01 section 8.1.3 # 27 */
  1256.   case GEN_KEYTOMODENVHOLD:          /* SF2.01 section 8.1.3 # 31 */
  1257.     count = calculate_hold_decay_buffers(voice, GEN_MODENVHOLD, GEN_KEYTOMODENVHOLD, 0); /* 1 means: hold */
  1258.     voice->modenv_data[FLUID_VOICE_ENVHOLD].count = count;
  1259.     voice->modenv_data[FLUID_VOICE_ENVHOLD].coeff = 1.0f;
  1260.     voice->modenv_data[FLUID_VOICE_ENVHOLD].incr = 0.0f;
  1261.     voice->modenv_data[FLUID_VOICE_ENVHOLD].min = -1.0f;
  1262.     voice->modenv_data[FLUID_VOICE_ENVHOLD].max = 2.0f;
  1263.     break;
  1264.   case GEN_MODENVDECAY:                                   /* SF 2.01 section 8.1.3 # 28 */
  1265.   case GEN_MODENVSUSTAIN:                                 /* SF 2.01 section 8.1.3 # 29 */
  1266.   case GEN_KEYTOMODENVDECAY:                              /* SF 2.01 section 8.1.3 # 32 */
  1267.     count = calculate_hold_decay_buffers(voice, GEN_MODENVDECAY, GEN_KEYTOMODENVDECAY, 1); /* 1 for decay */
  1268.     y = 1.0f - 0.001f * _GEN(voice, GEN_MODENVSUSTAIN);
  1269.     fluid_clip(y, 0.0f, 1.0f);
  1270.     voice->modenv_data[FLUID_VOICE_ENVDECAY].count = count;
  1271.     voice->modenv_data[FLUID_VOICE_ENVDECAY].coeff = 1.0f;
  1272.     voice->modenv_data[FLUID_VOICE_ENVDECAY].incr = count ? -1.0f / count : 0.0f;
  1273.     voice->modenv_data[FLUID_VOICE_ENVDECAY].min = y;
  1274.     voice->modenv_data[FLUID_VOICE_ENVDECAY].max = 2.0f;
  1275.     break;
  1276.   case GEN_MODENVRELEASE:                                  /* SF 2.01 section 8.1.3 # 30 */
  1277.     x = _GEN(voice, GEN_MODENVRELEASE);
  1278.     fluid_clip(x, -12000.0f, 8000.0f);
  1279.     count = 1 + NUM_BUFFERS_RELEASE(x);
  1280.     voice->modenv_data[FLUID_VOICE_ENVRELEASE].count = count;
  1281.     voice->modenv_data[FLUID_VOICE_ENVRELEASE].coeff = 1.0f;
  1282.     voice->modenv_data[FLUID_VOICE_ENVRELEASE].incr = count ? -1.0f / count : 0.0;
  1283.     voice->modenv_data[FLUID_VOICE_ENVRELEASE].min = 0.0f;
  1284.     voice->modenv_data[FLUID_VOICE_ENVRELEASE].max = 2.0f;
  1285.     break;
  1286.   } /* switch gen */
  1287. }
  1288. /**
  1289.  * Recalculate voice parameters for a given control.
  1290.  * @param voice the synthesis voice
  1291.  * @param cc flag to distinguish between a continous control and a channel control (pitch bend, ...)
  1292.  * @param ctrl the control number
  1293.  *
  1294.  * In this implementation, I want to make sure that all controllers
  1295.  * are event based: the parameter values of the DSP algorithm should
  1296.  * only be updates when a controller event arrived and not at every
  1297.  * iteration of the audio cycle (which would probably be feasible if
  1298.  * the synth was made in silicon).
  1299.  *
  1300.  * The update is done in three steps:
  1301.  *
  1302.  * - first, we look for all the modulators that have the changed
  1303.  * controller as a source. This will yield a list of generators that
  1304.  * will be changed because of the controller event.
  1305.  *
  1306.  * - For every changed generator, calculate its new value. This is the
  1307.  * sum of its original value plus the values of al the attached
  1308.  * modulators.
  1309.  *
  1310.  * - For every changed generator, convert its value to the correct
  1311.  * unit of the corresponding DSP parameter
  1312.  */
  1313. int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl)
  1314. {
  1315.   int i, k;
  1316.   fluid_mod_t* mod;
  1317.   int gen;
  1318.   fluid_real_t modval;
  1319. /*    printf("Chan=%d, CC=%d, Src=%d, Val=%dn", voice->channel->channum, cc, ctrl, val); */
  1320.   for (i = 0; i < voice->mod_count; i++) {
  1321.     mod = &voice->mod[i];
  1322.     /* step 1: find all the modulators that have the changed controller
  1323.      * as input source. */
  1324.     if (fluid_mod_has_source(mod, cc, ctrl)) {
  1325.       gen = fluid_mod_get_dest(mod);
  1326.       modval = 0.0;
  1327.       /* step 2: for every changed modulator, calculate the modulation
  1328.        * value of its associated generator */
  1329.       for (k = 0; k < voice->mod_count; k++) {
  1330. if (fluid_mod_has_dest(&voice->mod[k], gen)) {
  1331.   modval += fluid_mod_get_value(&voice->mod[k], voice->channel, voice);
  1332. }
  1333.       }
  1334.       fluid_gen_set_mod(&voice->gen[gen], modval);
  1335.       /* step 3: now that we have the new value of the generator,
  1336.        * recalculate the parameter values that are derived from the
  1337.        * generator */
  1338.       fluid_voice_update_param(voice, gen);
  1339.     }
  1340.   }
  1341.   return FLUID_OK;
  1342. }
  1343. /**
  1344.  * Update all the modulators. This function is called after a
  1345.  * ALL_CTRL_OFF MIDI message has been received (CC 121).
  1346.  *
  1347.  */
  1348. int fluid_voice_modulate_all(fluid_voice_t* voice)
  1349. {
  1350.   fluid_mod_t* mod;
  1351.   int i, k, gen;
  1352.   fluid_real_t modval;
  1353.   /* Loop through all the modulators.
  1354.      FIXME: we should loop through the set of generators instead of
  1355.      the set of modulators. We risk to call 'fluid_voice_update_param'
  1356.      several times for the same generator if several modulators have
  1357.      that generator as destination. It's not an error, just a wast of
  1358.      energy (think polution, global warming, unhappy musicians,
  1359.      ...) */
  1360.   for (i = 0; i < voice->mod_count; i++) {
  1361.     mod = &voice->mod[i];
  1362.     gen = fluid_mod_get_dest(mod);
  1363.     modval = 0.0;
  1364.     /* Accumulate the modulation values of all the modulators with
  1365.      * destination generator 'gen' */
  1366.     for (k = 0; k < voice->mod_count; k++) {
  1367.       if (fluid_mod_has_dest(&voice->mod[k], gen)) {
  1368. modval += fluid_mod_get_value(&voice->mod[k], voice->channel, voice);
  1369.       }
  1370.     }
  1371.     fluid_gen_set_mod(&voice->gen[gen], modval);
  1372.     /* Update the parameter values that are depend on the generator
  1373.      * 'gen' */
  1374.     fluid_voice_update_param(voice, gen);
  1375.   }
  1376.   return FLUID_OK;
  1377. }
  1378. /*
  1379.  * fluid_voice_noteoff
  1380.  */
  1381. int
  1382. fluid_voice_noteoff(fluid_voice_t* voice)
  1383. {
  1384.   unsigned int at_tick;
  1385.   fluid_profile(FLUID_PROF_VOICE_NOTE, voice->ref);
  1386.   at_tick = fluid_channel_get_min_note_length_ticks (voice->channel);
  1387.   if (at_tick > voice->ticks) {
  1388.     /* Delay noteoff */
  1389.     voice->noteoff_ticks = at_tick;
  1390.     return FLUID_OK;
  1391.   }
  1392.   voice->noteoff_ticks = 0;
  1393.   if (voice->channel && fluid_channel_sustained(voice->channel)) {
  1394.     voice->status = FLUID_VOICE_SUSTAINED;
  1395.   } else {
  1396.     if (voice->volenv_section == FLUID_VOICE_ENVATTACK) {
  1397.       /* A voice is turned off during the attack section of the volume
  1398.        * envelope.  The attack section ramps up linearly with
  1399.        * amplitude. The other sections use logarithmic scaling. Calculate new
  1400.        * volenv_val to achieve equievalent amplitude during the release phase
  1401.        * for seamless volume transition.
  1402.        */
  1403.       if (voice->volenv_val > 0){
  1404. fluid_real_t lfo = voice->modlfo_val * -voice->modlfo_to_vol;
  1405.         fluid_real_t amp = voice->volenv_val * pow (10.0, lfo / -200);
  1406.         fluid_real_t env_value = - ((-200 * log (amp) / log (10.0) - lfo) / 960.0 - 1);
  1407. fluid_clip (env_value, 0.0, 1.0);
  1408.         voice->volenv_val = env_value;
  1409.       }
  1410.     }
  1411.     voice->volenv_section = FLUID_VOICE_ENVRELEASE;
  1412.     voice->volenv_count = 0;
  1413.     voice->modenv_section = FLUID_VOICE_ENVRELEASE;
  1414.     voice->modenv_count = 0;
  1415.   }
  1416.   return FLUID_OK;
  1417. }
  1418. /*
  1419.  * fluid_voice_kill_excl
  1420.  *
  1421.  * Percussion sounds can be mutually exclusive: for example, a 'closed
  1422.  * hihat' sound will terminate an 'open hihat' sound ringing at the
  1423.  * same time. This behaviour is modeled using 'exclusive classes',
  1424.  * turning on a voice with an exclusive class other than 0 will kill
  1425.  * all other voices having that exclusive class within the same preset
  1426.  * or channel.  fluid_voice_kill_excl gets called, when 'voice' is to
  1427.  * be killed for that reason.
  1428.  */
  1429. int
  1430. fluid_voice_kill_excl(fluid_voice_t* voice){
  1431.   if (!_PLAYING(voice)) {
  1432.     return FLUID_OK;
  1433.   }
  1434.   /* Turn off the exclusive class information for this voice,
  1435.      so that it doesn't get killed twice
  1436.   */
  1437.   fluid_voice_gen_set(voice, GEN_EXCLUSIVECLASS, 0);
  1438.   /* If the voice is not yet in release state, put it into release state */
  1439.   if (voice->volenv_section != FLUID_VOICE_ENVRELEASE){
  1440.     voice->volenv_section = FLUID_VOICE_ENVRELEASE;
  1441.     voice->volenv_count = 0;
  1442.     voice->modenv_section = FLUID_VOICE_ENVRELEASE;
  1443.     voice->modenv_count = 0;
  1444.   }
  1445.   /* Speed up the volume envelope */
  1446.   /* The value was found through listening tests with hi-hat samples. */
  1447.   fluid_voice_gen_set(voice, GEN_VOLENVRELEASE, -200);
  1448.   fluid_voice_update_param(voice, GEN_VOLENVRELEASE);
  1449.   /* Speed up the modulation envelope */
  1450.   fluid_voice_gen_set(voice, GEN_MODENVRELEASE, -200);
  1451.   fluid_voice_update_param(voice, GEN_MODENVRELEASE);
  1452.   return FLUID_OK;
  1453. }
  1454. /*
  1455.  * fluid_voice_off
  1456.  *
  1457.  * Purpose:
  1458.  * Turns off a voice, meaning that it is not processed
  1459.  * anymore by the DSP loop.
  1460.  */
  1461. int
  1462. fluid_voice_off(fluid_voice_t* voice)
  1463. {
  1464.   fluid_profile(FLUID_PROF_VOICE_RELEASE, voice->ref);
  1465.   voice->chan = NO_CHANNEL;
  1466.   voice->volenv_section = FLUID_VOICE_ENVFINISHED;
  1467.   voice->volenv_count = 0;
  1468.   voice->modenv_section = FLUID_VOICE_ENVFINISHED;
  1469.   voice->modenv_count = 0;
  1470.   voice->status = FLUID_VOICE_OFF;
  1471.   /* Decrement the reference count of the sample. */
  1472.   if (voice->sample) {
  1473.     fluid_sample_decr_ref(voice->sample);
  1474.     voice->sample = NULL;
  1475.   }
  1476.   /* Decrement voice count atomically, for non-synth thread read access */
  1477.   fluid_atomic_int_add (&voice->channel->synth->active_voice_count, -1);
  1478.   return FLUID_OK;
  1479. }
  1480. /**
  1481.  * Adds a modulator to the voice.
  1482.  * @param voice Voice instance
  1483.  * @param mod Modulator info (copied)
  1484.  * @param mode Determines how to handle an existing identical modulator
  1485.  *   #FLUID_VOICE_ADD to add (offset) the modulator amounts,
  1486.  *   #FLUID_VOICE_OVERWRITE to replace the modulator,
  1487.  *   #FLUID_VOICE_DEFAULT when adding a default modulator - no duplicate should
  1488.  *   exist so don't check.
  1489.  */
  1490. void
  1491. fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode)
  1492. {
  1493.   int i;
  1494.   /*
  1495.    * Some soundfonts come with a huge number of non-standard
  1496.    * controllers, because they have been designed for one particular
  1497.    * sound card.  Discard them, maybe print a warning.
  1498.    */
  1499.   if (((mod->flags1 & FLUID_MOD_CC) == 0)
  1500.       && ((mod->src1 != 0)          /* SF2.01 section 8.2.1: Constant value */
  1501.   && (mod->src1 != 2)       /* Note-on velocity */
  1502.   && (mod->src1 != 3)       /* Note-on key number */
  1503.   && (mod->src1 != 10)      /* Poly pressure */
  1504.   && (mod->src1 != 13)      /* Channel pressure */
  1505.   && (mod->src1 != 14)      /* Pitch wheel */
  1506.   && (mod->src1 != 16))) {  /* Pitch wheel sensitivity */
  1507.     FLUID_LOG(FLUID_WARN, "Ignoring invalid controller, using non-CC source %i.", mod->src1);
  1508.     return;
  1509.   }
  1510.   if (mode == FLUID_VOICE_ADD) {
  1511.     /* if identical modulator exists, add them */
  1512.     for (i = 0; i < voice->mod_count; i++) {
  1513.       if (fluid_mod_test_identity(&voice->mod[i], mod)) {
  1514. // printf("Adding modulator...n");
  1515. voice->mod[i].amount += mod->amount;
  1516. return;
  1517.       }
  1518.     }
  1519.   } else if (mode == FLUID_VOICE_OVERWRITE) {
  1520.     /* if identical modulator exists, replace it (only the amount has to be changed) */
  1521.     for (i = 0; i < voice->mod_count; i++) {
  1522.       if (fluid_mod_test_identity(&voice->mod[i], mod)) {
  1523. // printf("Replacing modulator...amount is %fn",mod->amount);
  1524. voice->mod[i].amount = mod->amount;
  1525. return;
  1526.       }
  1527.     }
  1528.   }
  1529.   /* Add a new modulator (No existing modulator to add / overwrite).
  1530.      Also, default modulators (FLUID_VOICE_DEFAULT) are added without
  1531.      checking, if the same modulator already exists. */
  1532.   if (voice->mod_count < FLUID_NUM_MOD) {
  1533.     fluid_mod_clone(&voice->mod[voice->mod_count++], mod);
  1534.   }
  1535. }
  1536. /**
  1537.  * Get the unique ID of the noteon-event.
  1538.  * @param voice Voice instance
  1539.  * @return Note on unique ID
  1540.  *
  1541.  * A SoundFont loader may store the voice processes it has created for
  1542.  * real-time control during the operation of a voice (for example: parameter
  1543.  * changes in SoundFont editor). The synth uses a pool of voices, which are
  1544.  * 'recycled' and never deallocated.
  1545.  *
  1546.  * Before modifying an existing voice, check
  1547.  * - that its state is still 'playing'
  1548.  * - that the ID is still the same
  1549.  *
  1550.  * Otherwise the voice has finished playing.
  1551.  */
  1552. unsigned int fluid_voice_get_id(fluid_voice_t* voice)
  1553. {
  1554.   return voice->id;
  1555. }
  1556. /**
  1557.  * Check if a voice is still playing.
  1558.  * @param voice Voice instance
  1559.  * @return TRUE if playing, FALSE otherwise
  1560.  */
  1561. int fluid_voice_is_playing(fluid_voice_t* voice)
  1562. {
  1563.   return _PLAYING(voice);
  1564. }
  1565. /*
  1566.  * fluid_voice_get_lower_boundary_for_attenuation
  1567.  *
  1568.  * Purpose:
  1569.  *
  1570.  * A lower boundary for the attenuation (as in 'the minimum
  1571.  * attenuation of this voice, with volume pedals, modulators
  1572.  * etc. resulting in minimum attenuation, cannot fall below x cB) is
  1573.  * calculated.  This has to be called during fluid_voice_init, after
  1574.  * all modulators have been run on the voice once.  Also,
  1575.  * voice->attenuation has to be initialized.
  1576.  */
  1577. static fluid_real_t
  1578. fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t* voice)
  1579. {
  1580.   int i;
  1581.   fluid_mod_t* mod;
  1582.   fluid_real_t possible_att_reduction_cB=0;
  1583.   fluid_real_t lower_bound;
  1584.   for (i = 0; i < voice->mod_count; i++) {
  1585.     mod = &voice->mod[i];
  1586.     /* Modulator has attenuation as target and can change over time? */
  1587.     if ((mod->dest == GEN_ATTENUATION)
  1588. && ((mod->flags1 & FLUID_MOD_CC) || (mod->flags2 & FLUID_MOD_CC))) {
  1589.       fluid_real_t current_val = fluid_mod_get_value(mod, voice->channel, voice);
  1590.       fluid_real_t v = fabs(mod->amount);
  1591.       if ((mod->src1 == FLUID_MOD_PITCHWHEEL)
  1592.   || (mod->flags1 & FLUID_MOD_BIPOLAR)
  1593.   || (mod->flags2 & FLUID_MOD_BIPOLAR)
  1594.   || (mod->amount < 0)) {
  1595. /* Can this modulator produce a negative contribution? */
  1596. v *= -1.0;
  1597.       } else {
  1598. /* No negative value possible. But still, the minimum contribution is 0. */
  1599. v = 0;
  1600.       }
  1601.       /* For example:
  1602.        * - current_val=100
  1603.        * - min_val=-4000
  1604.        * - possible_att_reduction_cB += 4100
  1605.        */
  1606.       if (current_val > v){
  1607. possible_att_reduction_cB += (current_val - v);
  1608.       }
  1609.     }
  1610.   }
  1611.   lower_bound = voice->attenuation-possible_att_reduction_cB;
  1612.   /* SF2.01 specs do not allow negative attenuation */
  1613.   if (lower_bound < 0) {
  1614.     lower_bound = 0;
  1615.   }
  1616.   return lower_bound;
  1617. }
  1618. /* Purpose:
  1619.  *
  1620.  * Make sure, that sample start / end point and loop points are in
  1621.  * proper order. When starting up, calculate the initial phase.
  1622.  */
  1623. static void
  1624. fluid_voice_check_sample_sanity(fluid_voice_t* voice)
  1625. {
  1626.     int min_index_nonloop=(int) voice->sample->start;
  1627.     int max_index_nonloop=(int) voice->sample->end;
  1628.     /* make sure we have enough samples surrounding the loop */
  1629.     int min_index_loop=(int) voice->sample->start + FLUID_MIN_LOOP_PAD;
  1630.     int max_index_loop=(int) voice->sample->end - FLUID_MIN_LOOP_PAD + 1; /* 'end' is last valid sample, loopend can be + 1 */
  1631.     fluid_check_fpe("voice_check_sample_sanity start");
  1632.     if (!voice->check_sample_sanity_flag){
  1633. return;
  1634.     }
  1635. #if 0
  1636.     printf("Sample from %i to %in",voice->sample->start, voice->sample->end);
  1637.     printf("Sample loop from %i %in",voice->sample->loopstart, voice->sample->loopend);
  1638.     printf("Playback from %i to %in", voice->start, voice->end);
  1639.     printf("Playback loop from %i to %in",voice->loopstart, voice->loopend);
  1640. #endif
  1641.     /* Keep the start point within the sample data */
  1642.     if (voice->start < min_index_nonloop){
  1643. voice->start = min_index_nonloop;
  1644.     } else if (voice->start > max_index_nonloop){
  1645. voice->start = max_index_nonloop;
  1646.     }
  1647.     /* Keep the end point within the sample data */
  1648.     if (voice->end < min_index_nonloop){
  1649.       voice->end = min_index_nonloop;
  1650.     } else if (voice->end > max_index_nonloop){
  1651.       voice->end = max_index_nonloop;
  1652.     }
  1653.     /* Keep start and end point in the right order */
  1654.     if (voice->start > voice->end){
  1655. int temp = voice->start;
  1656. voice->start = voice->end;
  1657. voice->end = temp;
  1658. /*FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Changing order of start / end points!"); */
  1659.     }
  1660.     /* Zero length? */
  1661.     if (voice->start == voice->end){
  1662. fluid_voice_off(voice);
  1663. return;
  1664.     }
  1665.     if ((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE)
  1666. || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)) {
  1667. /* Keep the loop start point within the sample data */
  1668. if (voice->loopstart < min_index_loop){
  1669.     voice->loopstart = min_index_loop;
  1670.       } else if (voice->loopstart > max_index_loop){
  1671. voice->loopstart = max_index_loop;
  1672.       }
  1673.       /* Keep the loop end point within the sample data */
  1674.       if (voice->loopend < min_index_loop){
  1675. voice->loopend = min_index_loop;
  1676.       } else if (voice->loopend > max_index_loop){
  1677. voice->loopend = max_index_loop;
  1678.       }
  1679.       /* Keep loop start and end point in the right order */
  1680.       if (voice->loopstart > voice->loopend){
  1681. int temp = voice->loopstart;
  1682. voice->loopstart = voice->loopend;
  1683. voice->loopend = temp;
  1684. /*FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Changing order of loop points!"); */
  1685.       }
  1686.       /* Loop too short? Then don't loop. */
  1687.       if (voice->loopend < voice->loopstart + FLUID_MIN_LOOP_SIZE){
  1688.   voice->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED;
  1689.       }
  1690.       /* The loop points may have changed. Obtain a new estimate for the loop volume. */
  1691.       /* Is the voice loop within the sample loop? */
  1692.       if ((int)voice->loopstart >= (int)voice->sample->loopstart
  1693.   && (int)voice->loopend <= (int)voice->sample->loopend){
  1694. /* Is there a valid peak amplitude available for the loop? */
  1695. if (voice->sample->amplitude_that_reaches_noise_floor_is_valid){
  1696.   voice->amplitude_that_reaches_noise_floor_loop=voice->sample->amplitude_that_reaches_noise_floor / voice->synth_gain;
  1697. } else {
  1698.   /* Worst case */
  1699.   voice->amplitude_that_reaches_noise_floor_loop=voice->amplitude_that_reaches_noise_floor_nonloop;
  1700. };
  1701.       };
  1702.     } /* if sample mode is looped */
  1703.     /* Run startup specific code (only once, when the voice is started) */
  1704.     if (voice->check_sample_sanity_flag & FLUID_SAMPLESANITY_STARTUP){
  1705.       if (max_index_loop - min_index_loop < FLUID_MIN_LOOP_SIZE){
  1706.         if ((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE)
  1707.     || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)){
  1708.   voice->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED;
  1709. }
  1710.       }
  1711.       /* Set the initial phase of the voice (using the result from the
  1712.  start offset modulators). */
  1713.       fluid_phase_set_int(voice->phase, voice->start);
  1714.     } /* if startup */
  1715.     /* Is this voice run in loop mode, or does it run straight to the
  1716.        end of the waveform data? */
  1717.     if (((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE) && (voice->volenv_section < FLUID_VOICE_ENVRELEASE))
  1718. || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)) {
  1719.       /* Yes, it will loop as soon as it reaches the loop point.  In
  1720.        * this case we must prevent, that the playback pointer (phase)
  1721.        * happens to end up beyond the 2nd loop point, because the
  1722.        * point has moved.  The DSP algorithm is unable to cope with
  1723.        * that situation.  So if the phase is beyond the 2nd loop
  1724.        * point, set it to the start of the loop. No way to avoid some
  1725.        * noise here.  Note: If the sample pointer ends up -before the
  1726.        * first loop point- instead, then the DSP loop will just play
  1727.        * the sample, enter the loop and proceed as expected => no
  1728.        * actions required.
  1729.        */
  1730.       int index_in_sample = fluid_phase_index(voice->phase);
  1731.       if (index_in_sample >= voice->loopend){
  1732. /* FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Phase after 2nd loop point!"); */
  1733. fluid_phase_set_int(voice->phase, voice->loopstart);
  1734.       }
  1735.     }
  1736. /*    FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Sample from %i to %i, loop from %i to %i", voice->start, voice->end, voice->loopstart, voice->loopend); */
  1737.     /* Sample sanity has been assured. Don't check again, until some
  1738.        sample parameter is changed by modulation. */
  1739.     voice->check_sample_sanity_flag=0;
  1740. #if 0
  1741.     printf("Sane? playback loop from %i to %in", voice->loopstart, voice->loopend);
  1742. #endif
  1743.     fluid_check_fpe("voice_check_sample_sanity");
  1744. }
  1745. int fluid_voice_set_param(fluid_voice_t* voice, int gen, fluid_real_t nrpn_value, int abs)
  1746. {
  1747.   voice->gen[gen].nrpn = nrpn_value;
  1748.   voice->gen[gen].flags = (abs)? GEN_ABS_NRPN : GEN_SET;
  1749.   fluid_voice_update_param(voice, gen);
  1750.   return FLUID_OK;
  1751. }
  1752. int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain)
  1753. {
  1754.   /* avoid division by zero*/
  1755.   if (gain < 0.0000001){
  1756.     gain = 0.0000001;
  1757.   }
  1758.   voice->synth_gain = gain;
  1759.   voice->amp_left = fluid_pan(voice->pan, 1) * gain / 32768.0f;
  1760.   voice->amp_right = fluid_pan(voice->pan, 0) * gain / 32768.0f;
  1761.   voice->amp_reverb = voice->reverb_send * gain / 32768.0f;
  1762.   voice->amp_chorus = voice->chorus_send * gain / 32768.0f;
  1763.   return FLUID_OK;
  1764. }
  1765. /* - Scan the loop
  1766.  * - determine the peak level
  1767.  * - Calculate, what factor will make the loop inaudible
  1768.  * - Store in sample
  1769.  */
  1770. /**
  1771.  * Calculate the peak volume of a sample for voice off optimization.
  1772.  * @param s Sample to optimize
  1773.  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
  1774.  *
  1775.  * If the peak volume during the loop is known, then the voice can
  1776.  * be released earlier during the release phase. Otherwise, the
  1777.  * voice will operate (inaudibly), until the envelope is at the
  1778.  * nominal turnoff point.  So it's a good idea to call
  1779.  * fluid_voice_optimize_sample() on each sample once.
  1780.  */
  1781. int
  1782. fluid_voice_optimize_sample(fluid_sample_t* s)
  1783. {
  1784.   signed short peak_max = 0;
  1785.   signed short peak_min = 0;
  1786.   signed short peak;
  1787.   fluid_real_t normalized_amplitude_during_loop;
  1788.   double result;
  1789.   int i;
  1790.   /* ignore ROM and other(?) invalid samples */
  1791.   if (!s->valid) return (FLUID_OK);
  1792.   if (!s->amplitude_that_reaches_noise_floor_is_valid){ /* Only once */
  1793.     /* Scan the loop */
  1794.     for (i = (int)s->loopstart; i < (int) s->loopend; i ++){
  1795.       signed short val = s->data[i];
  1796.       if (val > peak_max) {
  1797. peak_max = val;
  1798.       } else if (val < peak_min) {
  1799. peak_min = val;
  1800.       }
  1801.     }
  1802.     /* Determine the peak level */
  1803.     if (peak_max >- peak_min){
  1804.       peak = peak_max;
  1805.     } else {
  1806.       peak =- peak_min;
  1807.     };
  1808.     if (peak == 0){
  1809.       /* Avoid division by zero */
  1810.       peak = 1;
  1811.     };
  1812.     /* Calculate what factor will make the loop inaudible
  1813.      * For example: Take a peak of 3277 (10 % of 32768).  The
  1814.      * normalized amplitude is 0.1 (10 % of 32768).  An amplitude
  1815.      * factor of 0.0001 (as opposed to the default 0.00001) will
  1816.      * drop this sample to the noise floor.
  1817.      */
  1818.     /* 16 bits => 96+4=100 dB dynamic range => 0.00001 */
  1819.     normalized_amplitude_during_loop = ((fluid_real_t)peak)/32768.;
  1820.     result = FLUID_NOISE_FLOOR / normalized_amplitude_during_loop;
  1821.     /* Store in sample */
  1822.     s->amplitude_that_reaches_noise_floor = (double)result;
  1823.     s->amplitude_that_reaches_noise_floor_is_valid = 1;
  1824. #if 0
  1825.     printf("Sample peak detection: factor %fn", (double)result);
  1826. #endif
  1827.   };
  1828.   return FLUID_OK;
  1829. }