src/fluid_voice.c

00001 /* FluidSynth - A Software Synthesizer
00002  *
00003  * Copyright (C) 2003  Peter Hanappe and others.
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public License
00007  * as published by the Free Software Foundation; either version 2 of
00008  * the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public
00016  * License along with this library; if not, write to the Free
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018  * 02111-1307, USA
00019  */
00020 
00021 #include "fluidsynth_priv.h"
00022 #include "fluid_voice.h"
00023 #include "fluid_mod.h"
00024 #include "fluid_chan.h"
00025 #include "fluid_conv.h"
00026 #include "fluid_synth.h"
00027 #include "fluid_sys.h"
00028 #include "fluid_sfont.h"
00029 
00030 /* used for filter turn off optimization - if filter cutoff is above the
00031    specified value and filter q is below the other value, turn filter off */
00032 #define FLUID_MAX_AUDIBLE_FILTER_FC 19000.0f
00033 #define FLUID_MIN_AUDIBLE_FILTER_Q 1.2f
00034 
00035 /* Smallest amplitude that can be perceived (full scale is +/- 0.5)
00036  * 16 bits => 96+4=100 dB dynamic range => 0.00001
00037  * 0.00001 * 2 is approximately 0.00003 :)
00038  */
00039 #define FLUID_NOISE_FLOOR 0.00003
00040 
00041 /* these should be the absolute minimum that FluidSynth can deal with */
00042 #define FLUID_MIN_LOOP_SIZE 2
00043 #define FLUID_MIN_LOOP_PAD 0
00044 
00045 /* min vol envelope release (to stop clicks) in SoundFont timecents */
00046 #define FLUID_MIN_VOLENVRELEASE -7200.0f /* ~16ms */
00047 
00048 
00049 static inline void fluid_voice_effects (fluid_voice_t *voice, int count,
00050                                         fluid_real_t* dsp_left_buf,
00051                                         fluid_real_t* dsp_right_buf,
00052                                         fluid_real_t* dsp_reverb_buf,
00053                                         fluid_real_t* dsp_chorus_buf);
00054 /*
00055  * new_fluid_voice
00056  */
00057 fluid_voice_t*
00058 new_fluid_voice(fluid_real_t output_rate)
00059 {
00060   fluid_voice_t* voice;
00061   voice = FLUID_NEW(fluid_voice_t);
00062   if (voice == NULL) {
00063     FLUID_LOG(FLUID_ERR, "Out of memory");
00064     return NULL;
00065   }
00066   voice->status = FLUID_VOICE_CLEAN;
00067   voice->chan = NO_CHANNEL;
00068   voice->key = 0;
00069   voice->vel = 0;
00070   voice->channel = NULL;
00071   voice->sample = NULL;
00072   voice->output_rate = output_rate;
00073 
00074   /* The 'sustain' and 'finished' segments of the volume / modulation
00075    * envelope are constant. They are never affected by any modulator
00076    * or generator. Therefore it is enough to initialize them once
00077    * during the lifetime of the synth.
00078    */
00079   voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].count = 0xffffffff;
00080   voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].coeff = 1.0f;
00081   voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].incr = 0.0f;
00082   voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].min = -1.0f;
00083   voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].max = 2.0f;
00084 
00085   voice->volenv_data[FLUID_VOICE_ENVFINISHED].count = 0xffffffff;
00086   voice->volenv_data[FLUID_VOICE_ENVFINISHED].coeff = 0.0f;
00087   voice->volenv_data[FLUID_VOICE_ENVFINISHED].incr = 0.0f;
00088   voice->volenv_data[FLUID_VOICE_ENVFINISHED].min = -1.0f;
00089   voice->volenv_data[FLUID_VOICE_ENVFINISHED].max = 1.0f;
00090 
00091   voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].count = 0xffffffff;
00092   voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].coeff = 1.0f;
00093   voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].incr = 0.0f;
00094   voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].min = -1.0f;
00095   voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].max = 2.0f;
00096 
00097   voice->modenv_data[FLUID_VOICE_ENVFINISHED].count = 0xffffffff;
00098   voice->modenv_data[FLUID_VOICE_ENVFINISHED].coeff = 0.0f;
00099   voice->modenv_data[FLUID_VOICE_ENVFINISHED].incr = 0.0f;
00100   voice->modenv_data[FLUID_VOICE_ENVFINISHED].min = -1.0f;
00101   voice->modenv_data[FLUID_VOICE_ENVFINISHED].max = 1.0f;
00102 
00103   return voice;
00104 }
00105 
00106 /*
00107  * delete_fluid_voice
00108  */
00109 int
00110 delete_fluid_voice(fluid_voice_t* voice)
00111 {
00112   if (voice == NULL) {
00113     return FLUID_OK;
00114   }
00115   FLUID_FREE(voice);
00116   return FLUID_OK;
00117 }
00118 
00119 /* fluid_voice_init
00120  *
00121  * Initialize the synthesis process
00122  */
00123 int
00124 fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
00125                  fluid_channel_t* channel, int key, int vel, unsigned int id,
00126                  unsigned int start_time, fluid_real_t gain)
00127 {
00128   /* Note: The voice parameters will be initialized later, when the
00129    * generators have been retrieved from the sound font. Here, only
00130    * the 'working memory' of the voice (position in envelopes, history
00131    * of IIR filters, position in sample etc) is initialized. */
00132 
00133 
00134   voice->id = id;
00135   voice->chan = fluid_channel_get_num(channel);
00136   voice->key = (unsigned char) key;
00137   voice->vel = (unsigned char) vel;
00138   voice->channel = channel;
00139   voice->mod_count = 0;
00140   voice->sample = sample;
00141   voice->start_time = start_time;
00142   voice->ticks = 0;
00143   voice->debug = 0;
00144   voice->has_looped = 0; /* Will be set during voice_write when the 2nd loop point is reached */
00145   voice->last_fres = -1; /* The filter coefficients have to be calculated later in the DSP loop. */
00146   voice->filter_startup = 1; /* Set the filter immediately, don't fade between old and new settings */
00147   voice->interp_method = fluid_channel_get_interp_method(voice->channel);
00148 
00149   /* vol env initialization */
00150   voice->volenv_count = 0;
00151   voice->volenv_section = 0;
00152   voice->volenv_val = 0.0f;
00153   voice->amp = 0.0f; /* The last value of the volume envelope, used to
00154                         calculate the volume increment during
00155                         processing */
00156 
00157   /* mod env initialization*/
00158   voice->modenv_count = 0;
00159   voice->modenv_section = 0;
00160   voice->modenv_val = 0.0f;
00161 
00162   /* mod lfo */
00163   voice->modlfo_val = 0.0;/* Fixme: Retrieve from any other existing
00164                              voice on this channel to keep LFOs in
00165                              unison? */
00166 
00167   /* vib lfo */
00168   voice->viblfo_val = 0.0f; /* Fixme: See mod lfo */
00169 
00170   /* Clear sample history in filter */
00171   voice->hist1 = 0;
00172   voice->hist2 = 0;
00173 
00174   /* Set all the generators to their default value, according to SF
00175    * 2.01 section 8.1.3 (page 48). The value of NRPN messages are
00176    * copied from the channel to the voice's generators. The sound font
00177    * loader overwrites them. The generator values are later converted
00178    * into voice parameters in
00179    * fluid_voice_calculate_runtime_synthesis_parameters.  */
00180   fluid_gen_init(&voice->gen[0], channel);
00181 
00182   voice->synth_gain = gain;
00183   /* avoid division by zero later*/
00184   if (voice->synth_gain < 0.0000001){
00185     voice->synth_gain = 0.0000001;
00186   }
00187 
00188   /* For a looped sample, this value will be overwritten as soon as the
00189    * loop parameters are initialized (they may depend on modulators).
00190    * This value can be kept, it is a worst-case estimate.
00191    */
00192 
00193   voice->amplitude_that_reaches_noise_floor_nonloop = FLUID_NOISE_FLOOR / voice->synth_gain;
00194   voice->amplitude_that_reaches_noise_floor_loop = FLUID_NOISE_FLOOR / voice->synth_gain;
00195 
00196   /* Increment the reference count of the sample to prevent the
00197      unloading of the soundfont while this voice is playing. */
00198   fluid_sample_incr_ref(voice->sample);
00199 
00200   return FLUID_OK;
00201 }
00202 
00203 void fluid_voice_gen_set(fluid_voice_t* voice, int i, float val)
00204 {
00205   voice->gen[i].val = val;
00206   voice->gen[i].flags = GEN_SET;
00207 }
00208 
00209 void fluid_voice_gen_incr(fluid_voice_t* voice, int i, float val)
00210 {
00211   voice->gen[i].val += val;
00212   voice->gen[i].flags = GEN_SET;
00213 }
00214 
00215 float fluid_voice_gen_get(fluid_voice_t* voice, int gen)
00216 {
00217   return voice->gen[gen].val;
00218 }
00219 
00220 fluid_real_t fluid_voice_gen_value(fluid_voice_t* voice, int num)
00221 {
00222         /* This is an extension to the SoundFont standard. More
00223          * documentation is available at the fluid_synth_set_gen2()
00224          * function. */
00225         if (voice->gen[num].flags == GEN_ABS_NRPN) {
00226                 return (fluid_real_t) voice->gen[num].nrpn;
00227         } else {
00228                 return (fluid_real_t) (voice->gen[num].val + voice->gen[num].mod + voice->gen[num].nrpn);
00229         }
00230 }
00231 
00232 
00233 /*
00234  * fluid_voice_write
00235  *
00236  * This is where it all happens. This function is called by the
00237  * synthesizer to generate the sound samples. The synthesizer passes
00238  * four audio buffers: left, right, reverb out, and chorus out.
00239  *
00240  * The biggest part of this function sets the correct values for all
00241  * the dsp parameters (all the control data boil down to only a few
00242  * dsp parameters). The dsp routine is #included in several places (fluid_dsp_core.c).
00243  */
00244 int
00245 fluid_voice_write(fluid_voice_t* voice,
00246                  fluid_real_t* dsp_left_buf, fluid_real_t* dsp_right_buf,
00247                  fluid_real_t* dsp_reverb_buf, fluid_real_t* dsp_chorus_buf)
00248 {
00249   unsigned int i;
00250   fluid_real_t incr;
00251   fluid_real_t fres;
00252   fluid_real_t target_amp;      /* target amplitude */
00253   int count;
00254 
00255   int dsp_interp_method = voice->interp_method;
00256 
00257   fluid_real_t dsp_buf[FLUID_BUFSIZE];
00258   fluid_env_data_t* env_data;
00259   fluid_real_t x;
00260 
00261 
00262   /* make sure we're playing and that we have sample data */
00263   if (!_PLAYING(voice)) return FLUID_OK;
00264 
00265   /******************* sample **********************/
00266 
00267   if (voice->sample == NULL)
00268   {
00269     fluid_voice_off(voice);
00270     return FLUID_OK;
00271   }
00272 
00273   fluid_check_fpe ("voice_write startup");
00274 
00275   /* Range checking for sample- and loop-related parameters
00276    * Initial phase is calculated here*/
00277   fluid_voice_check_sample_sanity (voice);
00278 
00279   /******************* vol env **********************/
00280 
00281   env_data = &voice->volenv_data[voice->volenv_section];
00282 
00283   /* skip to the next section of the envelope if necessary */
00284   while (voice->volenv_count >= env_data->count)
00285   {
00286     env_data = &voice->volenv_data[++voice->volenv_section];
00287     voice->volenv_count = 0;
00288   }
00289 
00290   /* calculate the envelope value and check for valid range */
00291   x = env_data->coeff * voice->volenv_val + env_data->incr;
00292   if (x < env_data->min)
00293   {
00294     x = env_data->min;
00295     voice->volenv_section++;
00296     voice->volenv_count = 0;
00297   }
00298   else if (x > env_data->max)
00299   {
00300     x = env_data->max;
00301     voice->volenv_section++;
00302     voice->volenv_count = 0;
00303   }
00304 
00305   voice->volenv_val = x;
00306   voice->volenv_count++;
00307 
00308   if (voice->volenv_section == FLUID_VOICE_ENVFINISHED)
00309   {
00310     fluid_profile (FLUID_PROF_VOICE_RELEASE, voice->ref);
00311     fluid_voice_off (voice);
00312     return FLUID_OK;
00313   }
00314 
00315   fluid_check_fpe ("voice_write vol env");
00316 
00317   /******************* mod env **********************/
00318 
00319   env_data = &voice->modenv_data[voice->modenv_section];
00320 
00321   /* skip to the next section of the envelope if necessary */
00322   while (voice->modenv_count >= env_data->count)
00323   {
00324     env_data = &voice->modenv_data[++voice->modenv_section];
00325     voice->modenv_count = 0;
00326   }
00327 
00328   /* calculate the envelope value and check for valid range */
00329   x = env_data->coeff * voice->modenv_val + env_data->incr;
00330 
00331   if (x < env_data->min)
00332   {
00333     x = env_data->min;
00334     voice->modenv_section++;
00335     voice->modenv_count = 0;
00336   }
00337   else if (x > env_data->max)
00338   {
00339     x = env_data->max;
00340     voice->modenv_section++;
00341     voice->modenv_count = 0;
00342   }
00343 
00344   voice->modenv_val = x;
00345   voice->modenv_count++;
00346   fluid_check_fpe ("voice_write mod env");
00347 
00348   /******************* mod lfo **********************/
00349 
00350   if (voice->ticks >= voice->modlfo_delay)
00351   {
00352     voice->modlfo_val += voice->modlfo_incr;
00353   
00354     if (voice->modlfo_val > 1.0)
00355     {
00356       voice->modlfo_incr = -voice->modlfo_incr;
00357       voice->modlfo_val = (fluid_real_t) 2.0 - voice->modlfo_val;
00358     }
00359     else if (voice->modlfo_val < -1.0)
00360     {
00361       voice->modlfo_incr = -voice->modlfo_incr;
00362       voice->modlfo_val = (fluid_real_t) -2.0 - voice->modlfo_val;
00363     }
00364   }
00365   
00366   fluid_check_fpe ("voice_write mod LFO");
00367 
00368   /******************* vib lfo **********************/
00369 
00370   if (voice->ticks >= voice->viblfo_delay)
00371   {
00372     voice->viblfo_val += voice->viblfo_incr;
00373 
00374     if (voice->viblfo_val > (fluid_real_t) 1.0)
00375     {
00376       voice->viblfo_incr = -voice->viblfo_incr;
00377       voice->viblfo_val = (fluid_real_t) 2.0 - voice->viblfo_val;
00378     }
00379     else if (voice->viblfo_val < -1.0)
00380     {
00381       voice->viblfo_incr = -voice->viblfo_incr;
00382       voice->viblfo_val = (fluid_real_t) -2.0 - voice->viblfo_val;
00383     }
00384   }
00385 
00386   fluid_check_fpe ("voice_write Vib LFO");
00387 
00388   /******************* amplitude **********************/
00389 
00390   /* calculate final amplitude
00391    * - initial gain
00392    * - amplitude envelope
00393    */
00394 
00395   if (voice->volenv_section == FLUID_VOICE_ENVDELAY)
00396     goto post_process;  /* The volume amplitude is in hold phase. No sound is produced. */
00397 
00398   if (voice->volenv_section == FLUID_VOICE_ENVATTACK)
00399   {
00400     /* the envelope is in the attack section: ramp linearly to max value.
00401      * A positive modlfo_to_vol should increase volume (negative attenuation).
00402      */
00403     target_amp = fluid_atten2amp (voice->attenuation)
00404       * fluid_cb2amp (voice->modlfo_val * -voice->modlfo_to_vol)
00405       * voice->volenv_val;
00406   }
00407   else
00408   {
00409     fluid_real_t amplitude_that_reaches_noise_floor;
00410     fluid_real_t amp_max;
00411 
00412     target_amp = fluid_atten2amp (voice->attenuation)
00413       * fluid_cb2amp (960.0f * (1.0f - voice->volenv_val)
00414                       + voice->modlfo_val * -voice->modlfo_to_vol);
00415 
00416     /* We turn off a voice, if the volume has dropped low enough. */
00417 
00418     /* A voice can be turned off, when an estimate for the volume
00419      * (upper bound) falls below that volume, that will drop the
00420      * sample below the noise floor.
00421      */
00422 
00423     /* If the loop amplitude is known, we can use it if the voice loop is within
00424      * the sample loop
00425      */
00426 
00427     /* Is the playing pointer already in the loop? */
00428     if (voice->has_looped)
00429       amplitude_that_reaches_noise_floor = voice->amplitude_that_reaches_noise_floor_loop;
00430     else
00431       amplitude_that_reaches_noise_floor = voice->amplitude_that_reaches_noise_floor_nonloop;
00432 
00433     /* voice->attenuation_min is a lower boundary for the attenuation
00434      * now and in the future (possibly 0 in the worst case).  Now the
00435      * amplitude of sample and volenv cannot exceed amp_max (since
00436      * volenv_val can only drop):
00437      */
00438 
00439     amp_max = fluid_atten2amp (voice->min_attenuation_cB) * voice->volenv_val;
00440 
00441     /* And if amp_max is already smaller than the known amplitude,
00442      * which will attenuate the sample below the noise floor, then we
00443      * can safely turn off the voice. Duh. */
00444     if (amp_max < amplitude_that_reaches_noise_floor)
00445     {
00446       fluid_profile (FLUID_PROF_VOICE_RELEASE, voice->ref);
00447       fluid_voice_off (voice);
00448       goto post_process;
00449     }
00450   }
00451 
00452   /* Volume increment to go from voice->amp to target_amp in FLUID_BUFSIZE steps */
00453   voice->amp_incr = (target_amp - voice->amp) / FLUID_BUFSIZE;
00454 
00455   fluid_check_fpe ("voice_write amplitude calculation");
00456 
00457   /* no volume and not changing? - No need to process */
00458   if ((voice->amp == 0.0f) && (voice->amp_incr == 0.0f))
00459     goto post_process;
00460 
00461   /* Calculate the number of samples, that the DSP loop advances
00462    * through the original waveform with each step in the output
00463    * buffer. It is the ratio between the frequencies of original
00464    * waveform and output waveform.*/
00465   voice->phase_incr = fluid_ct2hz_real
00466     (voice->pitch + voice->modlfo_val * voice->modlfo_to_pitch
00467      + voice->viblfo_val * voice->viblfo_to_pitch
00468      + voice->modenv_val * voice->modenv_to_pitch) / voice->root_pitch;
00469 
00470   fluid_check_fpe ("voice_write phase calculation");
00471 
00472   /* if phase_incr is not advancing, set it to the minimum fraction value (prevent stuckage) */
00473   if (voice->phase_incr == 0) voice->phase_incr = 1;
00474 
00475   /*************** resonant filter ******************/
00476 
00477   /* calculate the frequency of the resonant filter in Hz */
00478   fres = fluid_ct2hz(voice->fres
00479                      + voice->modlfo_val * voice->modlfo_to_fc
00480                      + voice->modenv_val * voice->modenv_to_fc);
00481 
00482   /* FIXME - Still potential for a click during turn on, can we interpolate
00483      between 20khz cutoff and 0 Q? */
00484 
00485   /* I removed the optimization of turning the filter off when the
00486    * resonance frequence is above the maximum frequency. Instead, the
00487    * filter frequency is set to a maximum of 0.45 times the sampling
00488    * rate. For a 44100 kHz sampling rate, this amounts to 19845
00489    * Hz. The reason is that there were problems with anti-aliasing when the
00490    * synthesizer was run at lower sampling rates. Thanks to Stephan
00491    * Tassart for pointing me to this bug. By turning the filter on and
00492    * clipping the maximum filter frequency at 0.45*srate, the filter
00493    * is used as an anti-aliasing filter. */
00494 
00495   if (fres > 0.45f * voice->output_rate)
00496     fres = 0.45f * voice->output_rate;
00497   else if (fres < 5)
00498     fres = 5;
00499 
00500   /* if filter enabled and there is a significant frequency change.. */
00501   if ((abs (fres - voice->last_fres) > 0.01))
00502   {
00503     /* The filter coefficients have to be recalculated (filter
00504     * parameters have changed). Recalculation for various reasons is
00505     * forced by setting last_fres to -1.  The flag filter_startup
00506     * indicates, that the DSP loop runs for the first time, in this
00507     * case, the filter is set directly, instead of smoothly fading
00508     * between old and new settings.
00509     *
00510     * Those equations from Robert Bristow-Johnson's `Cookbook
00511     * formulae for audio EQ biquad filter coefficients', obtained
00512     * from Harmony-central.com / Computer / Programming. They are
00513     * the result of the bilinear transform on an analogue filter
00514     * prototype. To quote, `BLT frequency warping has been taken
00515     * into account for both significant frequency relocation and for
00516     * bandwidth readjustment'. */
00517 
00518    fluid_real_t omega = (fluid_real_t) (2.0 * M_PI * (fres / 44100.0f));
00519    fluid_real_t sin_coeff = (fluid_real_t) sin(omega);
00520    fluid_real_t cos_coeff = (fluid_real_t) cos(omega);
00521    fluid_real_t alpha_coeff = sin_coeff / (2.0f * voice->q_lin);
00522    fluid_real_t a0_inv = 1.0f / (1.0f + alpha_coeff);
00523 
00524    /* Calculate the filter coefficients. All coefficients are
00525     * normalized by a0. Think of `a1' as `a1/a0'.
00526     *
00527     * Here a couple of multiplications are saved by reusing common expressions.
00528     * The original equations should be:
00529     *  voice->b0=(1.-cos_coeff)*a0_inv*0.5*voice->filter_gain;
00530     *  voice->b1=(1.-cos_coeff)*a0_inv*voice->filter_gain;
00531     *  voice->b2=(1.-cos_coeff)*a0_inv*0.5*voice->filter_gain; */
00532 
00533    fluid_real_t a1_temp = -2.0f * cos_coeff * a0_inv;
00534    fluid_real_t a2_temp = (1.0f - alpha_coeff) * a0_inv;
00535    fluid_real_t b1_temp = (1.0f - cos_coeff) * a0_inv * voice->filter_gain;
00536    /* both b0 -and- b2 */
00537    fluid_real_t b02_temp = b1_temp * 0.5f;
00538 
00539    if (voice->filter_startup)
00540    {
00541      /* The filter is calculated, because the voice was started up.
00542       * In this case set the filter coefficients without delay.
00543       */
00544      voice->a1 = a1_temp;
00545      voice->a2 = a2_temp;
00546      voice->b02 = b02_temp;
00547      voice->b1 = b1_temp;
00548      voice->filter_coeff_incr_count = 0;
00549      voice->filter_startup = 0;
00550 //       printf("Setting initial filter coefficients.\n");
00551    }
00552    else
00553    {
00554 
00555       /* The filter frequency is changed.  Calculate an increment
00556        * factor, so that the new setting is reached after one buffer
00557        * length. x_incr is added to the current value FLUID_BUFSIZE
00558        * times. The length is arbitrarily chosen. Longer than one
00559        * buffer will sacrifice some performance, though.  Note: If
00560        * the filter is still too 'grainy', then increase this number
00561        * at will.
00562        */
00563 
00564 #define FILTER_TRANSITION_SAMPLES (FLUID_BUFSIZE)
00565 
00566       voice->a1_incr = (a1_temp - voice->a1) / FILTER_TRANSITION_SAMPLES;
00567       voice->a2_incr = (a2_temp - voice->a2) / FILTER_TRANSITION_SAMPLES;
00568       voice->b02_incr = (b02_temp - voice->b02) / FILTER_TRANSITION_SAMPLES;
00569       voice->b1_incr = (b1_temp - voice->b1) / FILTER_TRANSITION_SAMPLES;
00570       /* Have to add the increments filter_coeff_incr_count times. */
00571       voice->filter_coeff_incr_count = FILTER_TRANSITION_SAMPLES;
00572     }
00573     voice->last_fres = fres;
00574     fluid_check_fpe ("voice_write filter calculation");
00575   }
00576 
00577 
00578   fluid_check_fpe ("voice_write DSP coefficients");
00579 
00580   /*********************** run the dsp chain ************************
00581    * The sample is mixed with the output buffer.
00582    * The buffer has to be filled from 0 to FLUID_BUFSIZE-1.
00583    * Depending on the position in the loop and the loop size, this
00584    * may require several runs. */
00585 
00586   voice->dsp_buf = dsp_buf;
00587 
00588   switch (voice->interp_method)
00589   {
00590     case FLUID_INTERP_NONE:
00591       count = fluid_dsp_float_interpolate_none (voice);
00592       break;
00593     case FLUID_INTERP_LINEAR:
00594       count = fluid_dsp_float_interpolate_linear (voice);
00595       break;
00596     case FLUID_INTERP_4THORDER:
00597     default:
00598       count = fluid_dsp_float_interpolate_4th_order (voice);
00599       break;
00600     case FLUID_INTERP_7THORDER:
00601       count = fluid_dsp_float_interpolate_7th_order (voice);
00602       break;
00603   }
00604 
00605   fluid_check_fpe ("voice_write interpolation");
00606 
00607   if (count > 0)
00608     fluid_voice_effects (voice, count, dsp_left_buf, dsp_right_buf,
00609                          dsp_reverb_buf, dsp_chorus_buf);
00610 
00611   /* turn off voice if short count (sample ended and not looping) */
00612   if (count < FLUID_BUFSIZE)
00613   {
00614       fluid_profile(FLUID_PROF_VOICE_RELEASE, voice->ref);
00615       fluid_voice_off(voice);
00616   }
00617 
00618  post_process:
00619   voice->ticks += FLUID_BUFSIZE;
00620   fluid_check_fpe ("voice_write postprocess");
00621   return FLUID_OK;
00622 }
00623 
00624 
00625 /* Purpose:
00626  *
00627  * - filters (applies a lowpass filter with variable cutoff frequency and quality factor)
00628  * - mixes the processed sample to left and right output using the pan setting
00629  * - sends the processed sample to chorus and reverb
00630  *
00631  * Variable description:
00632  * - dsp_data: Pointer to the original waveform data
00633  * - dsp_left_buf: The generated signal goes here, left channel
00634  * - dsp_right_buf: right channel
00635  * - dsp_reverb_buf: Send to reverb unit
00636  * - dsp_chorus_buf: Send to chorus unit
00637  * - dsp_a1: Coefficient for the filter
00638  * - dsp_a2: same
00639  * - dsp_b0: same
00640  * - dsp_b1: same
00641  * - dsp_b2: same
00642  * - voice holds the voice structure
00643  *
00644  * A couple of variables are used internally, their results are discarded:
00645  * - dsp_i: Index through the output buffer
00646  * - dsp_phase_fractional: The fractional part of dsp_phase
00647  * - dsp_coeff: A table of four coefficients, depending on the fractional phase.
00648  *              Used to interpolate between samples.
00649  * - dsp_process_buffer: Holds the processed signal between stages
00650  * - dsp_centernode: delay line for the IIR filter
00651  * - dsp_hist1: same
00652  * - dsp_hist2: same
00653  *
00654  */
00655 static inline void
00656 fluid_voice_effects (fluid_voice_t *voice, int count,
00657                      fluid_real_t* dsp_left_buf, fluid_real_t* dsp_right_buf,
00658                      fluid_real_t* dsp_reverb_buf, fluid_real_t* dsp_chorus_buf)
00659 {
00660   /* IIR filter sample history */
00661   fluid_real_t dsp_hist1 = voice->hist1;
00662   fluid_real_t dsp_hist2 = voice->hist2;
00663 
00664   /* IIR filter coefficients */
00665   fluid_real_t dsp_a1 = voice->a1;
00666   fluid_real_t dsp_a2 = voice->a2;
00667   fluid_real_t dsp_b02 = voice->b02;
00668   fluid_real_t dsp_b1 = voice->b1;
00669   fluid_real_t dsp_a1_incr = voice->a1_incr;
00670   fluid_real_t dsp_a2_incr = voice->a2_incr;
00671   fluid_real_t dsp_b02_incr = voice->b02_incr;
00672   fluid_real_t dsp_b1_incr = voice->b1_incr;
00673   int dsp_filter_coeff_incr_count = voice->filter_coeff_incr_count;
00674 
00675   fluid_real_t *dsp_buf = voice->dsp_buf;
00676 
00677   fluid_real_t dsp_centernode;
00678   int dsp_i;
00679   float v;
00680 
00681   /* filter (implement the voice filter according to SoundFont standard) */
00682 
00683   /* Check for denormal number (too close to zero). */
00684   if (fabs (dsp_hist1) < 1e-20) dsp_hist1 = 0.0f;  /* FIXME JMG - Is this even needed? */
00685 
00686   /* Two versions of the filter loop. One, while the filter is
00687   * changing towards its new setting. The other, if the filter
00688   * doesn't change.
00689   */
00690 
00691   if (dsp_filter_coeff_incr_count > 0)
00692   {
00693     /* Increment is added to each filter coefficient filter_coeff_incr_count times. */
00694     for (dsp_i = 0; dsp_i < count; dsp_i++)
00695     {
00696       /* The filter is implemented in Direct-II form. */
00697       dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
00698       dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
00699       dsp_hist2 = dsp_hist1;
00700       dsp_hist1 = dsp_centernode;
00701 
00702       if (dsp_filter_coeff_incr_count-- > 0)
00703       {
00704         dsp_a1 += dsp_a1_incr;
00705         dsp_a2 += dsp_a2_incr;
00706         dsp_b02 += dsp_b02_incr;
00707         dsp_b1 += dsp_b1_incr;
00708       }
00709     } /* for dsp_i */
00710   }
00711   else /* The filter parameters are constant.  This is duplicated to save time. */
00712   {
00713     for (dsp_i = 0; dsp_i < count; dsp_i++)
00714     { /* The filter is implemented in Direct-II form. */
00715       dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
00716       dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
00717       dsp_hist2 = dsp_hist1;
00718       dsp_hist1 = dsp_centernode;
00719     }
00720   }
00721 
00722   /* pan (Copy the signal to the left and right output buffer) The voice
00723   * panning generator has a range of -500 .. 500.  If it is centered,
00724   * it's close to 0.  voice->amp_left and voice->amp_right are then the
00725   * same, and we can save one multiplication per voice and sample.
00726   */
00727   if ((-0.5 < voice->pan) && (voice->pan < 0.5))
00728   {
00729     /* The voice is centered. Use voice->amp_left twice. */
00730     for (dsp_i = 0; dsp_i < count; dsp_i++)
00731     {
00732       v = voice->amp_left * dsp_buf[dsp_i];
00733       dsp_left_buf[dsp_i] += v;
00734       dsp_right_buf[dsp_i] += v;
00735     }
00736   }
00737   else  /* The voice is not centered. Stereo samples have one side zero. */
00738   {
00739     if (voice->amp_left != 0.0)
00740     {
00741       for (dsp_i = 0; dsp_i < count; dsp_i++)
00742         dsp_left_buf[dsp_i] += voice->amp_left * dsp_buf[dsp_i];
00743     }
00744 
00745     if (voice->amp_right != 0.0)
00746     {
00747       for (dsp_i = 0; dsp_i < count; dsp_i++)
00748         dsp_right_buf[dsp_i] += voice->amp_right * dsp_buf[dsp_i];
00749     }
00750   }
00751 
00752   /* reverb send. Buffer may be NULL. */
00753   if ((dsp_reverb_buf != NULL) && (voice->amp_reverb != 0.0))
00754   {
00755     for (dsp_i = 0; dsp_i < count; dsp_i++)
00756       dsp_reverb_buf[dsp_i] += voice->amp_reverb * dsp_buf[dsp_i];
00757   }
00758 
00759   /* chorus send. Buffer may be NULL. */
00760   if ((dsp_chorus_buf != NULL) && (voice->amp_chorus != 0))
00761   {
00762     for (dsp_i = 0; dsp_i < count; dsp_i++)
00763       dsp_chorus_buf[dsp_i] += voice->amp_chorus * dsp_buf[dsp_i];
00764   }
00765 
00766   voice->hist1 = dsp_hist1;
00767   voice->hist2 = dsp_hist2;
00768   voice->a1 = dsp_a1;
00769   voice->a2 = dsp_a2;
00770   voice->b02 = dsp_b02;
00771   voice->b1 = dsp_b1;
00772   voice->filter_coeff_incr_count = dsp_filter_coeff_incr_count;
00773 
00774   fluid_check_fpe ("voice_effects");
00775 }
00776 
00777 /*
00778  * fluid_voice_get_channel
00779  */
00780 fluid_channel_t*
00781 fluid_voice_get_channel(fluid_voice_t* voice)
00782 {
00783   return voice->channel;
00784 }
00785 
00786 /*
00787  * fluid_voice_start
00788  */
00789 void fluid_voice_start(fluid_voice_t* voice)
00790 {
00791   /* The maximum volume of the loop is calculated and cached once for each
00792    * sample with its nominal loop settings. This happens, when the sample is used
00793    * for the first time.*/
00794 
00795   fluid_voice_calculate_runtime_synthesis_parameters(voice);
00796 
00797   /* Force setting of the phase at the first DSP loop run
00798    * This cannot be done earlier, because it depends on modulators.*/
00799   voice->check_sample_sanity_flag=FLUID_SAMPLESANITY_STARTUP;
00800 
00801   voice->ref = fluid_profile_ref();
00802 
00803   voice->status = FLUID_VOICE_ON;
00804 }
00805 
00806 /*
00807  * fluid_voice_calculate_runtime_synthesis_parameters
00808  *
00809  * in this function we calculate the values of all the parameters. the
00810  * parameters are converted to their most useful unit for the DSP
00811  * algorithm, for example, number of samples instead of
00812  * timecents. Some parameters keep their "perceptual" unit and
00813  * conversion will be done in the DSP function. This is the case, for
00814  * example, for the pitch since it is modulated by the controllers in
00815  * cents. */
00816 int
00817 fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice)
00818 {
00819   fluid_real_t x;
00820   fluid_real_t q_db;
00821   int i;
00822 
00823   int list_of_generators_to_initialize[35] = {
00824     GEN_STARTADDROFS,                    /* SF2.01 page 48 #0   */
00825     GEN_ENDADDROFS,                      /*                #1   */
00826     GEN_STARTLOOPADDROFS,                /*                #2   */
00827     GEN_ENDLOOPADDROFS,                  /*                #3   */
00828     /* GEN_STARTADDRCOARSEOFS see comment below [1]        #4   */
00829     GEN_MODLFOTOPITCH,                   /*                #5   */
00830     GEN_VIBLFOTOPITCH,                   /*                #6   */
00831     GEN_MODENVTOPITCH,                   /*                #7   */
00832     GEN_FILTERFC,                        /*                #8   */
00833     GEN_FILTERQ,                         /*                #9   */
00834     GEN_MODLFOTOFILTERFC,                /*                #10  */
00835     GEN_MODENVTOFILTERFC,                /*                #11  */
00836     /* GEN_ENDADDRCOARSEOFS [1]                            #12  */
00837     GEN_MODLFOTOVOL,                     /*                #13  */
00838     /* not defined                                         #14  */
00839     GEN_CHORUSSEND,                      /*                #15  */
00840     GEN_REVERBSEND,                      /*                #16  */
00841     GEN_PAN,                             /*                #17  */
00842     /* not defined                                         #18  */
00843     /* not defined                                         #19  */
00844     /* not defined                                         #20  */
00845     GEN_MODLFODELAY,                     /*                #21  */
00846     GEN_MODLFOFREQ,                      /*                #22  */
00847     GEN_VIBLFODELAY,                     /*                #23  */
00848     GEN_VIBLFOFREQ,                      /*                #24  */
00849     GEN_MODENVDELAY,                     /*                #25  */
00850     GEN_MODENVATTACK,                    /*                #26  */
00851     GEN_MODENVHOLD,                      /*                #27  */
00852     GEN_MODENVDECAY,                     /*                #28  */
00853     /* GEN_MODENVSUSTAIN [1]                               #29  */
00854     GEN_MODENVRELEASE,                   /*                #30  */
00855     /* GEN_KEYTOMODENVHOLD [1]                             #31  */
00856     /* GEN_KEYTOMODENVDECAY [1]                            #32  */
00857     GEN_VOLENVDELAY,                     /*                #33  */
00858     GEN_VOLENVATTACK,                    /*                #34  */
00859     GEN_VOLENVHOLD,                      /*                #35  */
00860     GEN_VOLENVDECAY,                     /*                #36  */
00861     /* GEN_VOLENVSUSTAIN [1]                               #37  */
00862     GEN_VOLENVRELEASE,                   /*                #38  */
00863     /* GEN_KEYTOVOLENVHOLD [1]                             #39  */
00864     /* GEN_KEYTOVOLENVDECAY [1]                            #40  */
00865     /* GEN_STARTLOOPADDRCOARSEOFS [1]                      #45  */
00866     GEN_KEYNUM,                          /*                #46  */
00867     GEN_VELOCITY,                        /*                #47  */
00868     GEN_ATTENUATION,                     /*                #48  */
00869     /* GEN_ENDLOOPADDRCOARSEOFS [1]                        #50  */
00870     /* GEN_COARSETUNE           [1]                        #51  */
00871     /* GEN_FINETUNE             [1]                        #52  */
00872     GEN_OVERRIDEROOTKEY,                 /*                #58  */
00873     GEN_PITCH,                           /*                ---  */
00874     -1};                                 /* end-of-list marker  */
00875 
00876   /* When the voice is made ready for the synthesis process, a lot of
00877    * voice-internal parameters have to be calculated.
00878    *
00879    * At this point, the sound font has already set the -nominal- value
00880    * for all generators (excluding GEN_PITCH). Most generators can be
00881    * modulated - they include a nominal value and an offset (which
00882    * changes with velocity, note number, channel parameters like
00883    * aftertouch, mod wheel...) Now this offset will be calculated as
00884    * follows:
00885    *
00886    *  - Process each modulator once.
00887    *  - Calculate its output value.
00888    *  - Find the target generator.
00889    *  - Add the output value to the modulation value of the generator.
00890    *
00891    * Note: The generators have been initialized with
00892    * fluid_gen_set_default_values.
00893    */
00894 
00895   for (i = 0; i < voice->mod_count; i++) {
00896     fluid_mod_t* mod = &voice->mod[i];
00897     fluid_real_t modval = fluid_mod_get_value(mod, voice->channel, voice);
00898     int dest_gen_index = mod->dest;
00899     fluid_gen_t* dest_gen = &voice->gen[dest_gen_index];
00900     dest_gen->mod += modval;
00901     /*      fluid_dump_modulator(mod); */
00902   }
00903 
00904   /* The GEN_PITCH is a hack to fit the pitch bend controller into the
00905    * modulator paradigm.  Now the nominal pitch of the key is set.
00906    * Note about SCALETUNE: SF2.01 8.1.3 says, that this generator is a
00907    * non-realtime parameter. So we don't allow modulation (as opposed
00908    * to _GEN(voice, GEN_SCALETUNE) When the scale tuning is varied,
00909    * one key remains fixed. Here C3 (MIDI number 60) is used.
00910    */
00911   if (fluid_channel_has_tuning(voice->channel)) {
00912     /* pitch(60) + scale * (pitch(key) - pitch(60)) */
00913     #define __pitch(_k) fluid_tuning_get_pitch(tuning, _k)
00914     fluid_tuning_t* tuning = fluid_channel_get_tuning(voice->channel);
00915     voice->gen[GEN_PITCH].val = (__pitch(60) + (voice->gen[GEN_SCALETUNE].val / 100.0f *
00916                                            (__pitch(voice->key) - __pitch(60))));
00917   } else {
00918     voice->gen[GEN_PITCH].val = (voice->gen[GEN_SCALETUNE].val * (voice->key - 60.0f)
00919                                  + 100.0f * 60.0f);
00920   }
00921 
00922   /* Now the generators are initialized, nominal and modulation value.
00923    * The voice parameters (which depend on generators) are calculated
00924    * with fluid_voice_update_param. Processing the list of generator
00925    * changes will calculate each voice parameter once.
00926    *
00927    * Note [1]: Some voice parameters depend on several generators. For
00928    * example, the pitch depends on GEN_COARSETUNE, GEN_FINETUNE and
00929    * GEN_PITCH.  voice->pitch.  Unnecessary recalculation is avoided
00930    * by removing all but one generator from the list of voice
00931    * parameters.  Same with GEN_XXX and GEN_XXXCOARSE: the
00932    * initialisation list contains only GEN_XXX.
00933    */
00934 
00935   /* Calculate the voice parameter(s) dependent on each generator. */
00936   for (i = 0; list_of_generators_to_initialize[i] != -1; i++) {
00937     fluid_voice_update_param(voice, list_of_generators_to_initialize[i]);
00938   }
00939 
00940   /* Make an estimate on how loud this voice can get at any time (attenuation). */
00941   voice->min_attenuation_cB = fluid_voice_get_lower_boundary_for_attenuation(voice);
00942 
00943   return FLUID_OK;
00944 }
00945 
00946 /*
00947  * calculate_hold_decay_buffers
00948  */
00949 int calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base,
00950                                  int gen_key2base, int is_decay)
00951 {
00952   /* Purpose:
00953    *
00954    * Returns the number of DSP loops, that correspond to the hold
00955    * (is_decay=0) or decay (is_decay=1) time.
00956    * gen_base=GEN_VOLENVHOLD, GEN_VOLENVDECAY, GEN_MODENVHOLD,
00957    * GEN_MODENVDECAY gen_key2base=GEN_KEYTOVOLENVHOLD,
00958    * GEN_KEYTOVOLENVDECAY, GEN_KEYTOMODENVHOLD, GEN_KEYTOMODENVDECAY
00959    */
00960 
00961   fluid_real_t timecents;
00962   fluid_real_t seconds;
00963   int buffers;
00964 
00965   /* SF2.01 section 8.4.3 # 31, 32, 39, 40
00966    * GEN_KEYTOxxxENVxxx uses key 60 as 'origin'.
00967    * The unit of the generator is timecents per key number.
00968    * If KEYTOxxxENVxxx is 100, a key one octave over key 60 (72)
00969    * will cause (60-72)*100=-1200 timecents of time variation.
00970    * The time is cut in half.
00971    */
00972   timecents = (_GEN(voice, gen_base) + _GEN(voice, gen_key2base) * (60.0 - voice->key));
00973 
00974   /* Range checking */
00975   if (is_decay){
00976     /* SF 2.01 section 8.1.3 # 28, 36 */
00977     if (timecents > 8000.0) {
00978       timecents = 8000.0;
00979     }
00980   } else {
00981     /* SF 2.01 section 8.1.3 # 27, 35 */
00982     if (timecents > 5000) {
00983       timecents = 5000.0;
00984     }
00985     /* SF 2.01 section 8.1.2 # 27, 35:
00986      * The most negative number indicates no hold time
00987      */
00988     if (timecents <= -32768.) {
00989       return 0;
00990     }
00991   }
00992   /* SF 2.01 section 8.1.3 # 27, 28, 35, 36 */
00993   if (timecents < -12000.0) {
00994     timecents = -12000.0;
00995   }
00996 
00997   seconds = fluid_tc2sec(timecents);
00998   /* Each DSP loop processes FLUID_BUFSIZE samples. */
00999 
01000   /* round to next full number of buffers */
01001   buffers = (int)(((fluid_real_t)voice->output_rate * seconds)
01002                   / (fluid_real_t)FLUID_BUFSIZE
01003                   +0.5);
01004 
01005   return buffers;
01006 }
01007 
01008 /*
01009  * fluid_voice_update_param
01010  *
01011  * Purpose:
01012  *
01013  * The value of a generator (gen) has changed.  (The different
01014  * generators are listed in fluidsynth.h, or in SF2.01 page 48-49)
01015  * Now the dependent 'voice' parameters are calculated.
01016  *
01017  * fluid_voice_update_param can be called during the setup of the
01018  * voice (to calculate the initial value for a voice parameter), or
01019  * during its operation (a generator has been changed due to
01020  * real-time parameter modifications like pitch-bend).
01021  *
01022  * Note: The generator holds three values: The base value .val, an
01023  * offset caused by modulators .mod, and an offset caused by the
01024  * NRPN system. _GEN(voice, generator_enumerator) returns the sum
01025  * of all three.
01026  */
01027 void
01028 fluid_voice_update_param(fluid_voice_t* voice, int gen)
01029 {
01030   double q_dB;
01031   fluid_real_t x;
01032   fluid_real_t y;
01033   unsigned int count;
01034 
01035   switch (gen) {
01036 
01037   case GEN_PAN:
01038     /* range checking is done in the fluid_pan function */
01039     voice->pan = _GEN(voice, GEN_PAN);
01040     voice->amp_left = fluid_pan(voice->pan, 1) * voice->synth_gain / 32768.0f;
01041     voice->amp_right = fluid_pan(voice->pan, 0) * voice->synth_gain / 32768.0f;
01042     break;
01043 
01044   case GEN_ATTENUATION:
01045     voice->attenuation = _GEN(voice, GEN_ATTENUATION);
01046 
01047     /* Range: SF2.01 section 8.1.3 # 48
01048      * Motivation for range checking:
01049      * OHPiano.SF2 sets initial attenuation to a whooping -96 dB */
01050     fluid_clip(voice->attenuation, 0.0, 1440.0);
01051     break;
01052 
01053     /* The pitch is calculated from three different generators.
01054      * Read comment in fluidsynth.h about GEN_PITCH.
01055      */
01056   case GEN_PITCH:
01057   case GEN_COARSETUNE:
01058   case GEN_FINETUNE:
01059     /* The testing for allowed range is done in 'fluid_ct2hz' */
01060     voice->pitch = (_GEN(voice, GEN_PITCH)
01061                     + 100.0f * _GEN(voice, GEN_COARSETUNE)
01062                     + _GEN(voice, GEN_FINETUNE));
01063     break;
01064 
01065   case GEN_REVERBSEND:
01066     /* The generator unit is 'tenths of a percent'. */
01067     voice->reverb_send = _GEN(voice, GEN_REVERBSEND) / 1000.0f;
01068     fluid_clip(voice->reverb_send, 0.0, 1.0);
01069     voice->amp_reverb = voice->reverb_send * voice->synth_gain / 32768.0f;
01070     break;
01071 
01072   case GEN_CHORUSSEND:
01073     /* The generator unit is 'tenths of a percent'. */
01074     voice->chorus_send = _GEN(voice, GEN_CHORUSSEND) / 1000.0f;
01075     fluid_clip(voice->chorus_send, 0.0, 1.0);
01076     voice->amp_chorus = voice->chorus_send * voice->synth_gain / 32768.0f;
01077     break;
01078 
01079   case GEN_OVERRIDEROOTKEY:
01080     /* This is a non-realtime parameter. Therefore the .mod part of the generator
01081      * can be neglected.
01082      * NOTE: origpitch sets MIDI root note while pitchadj is a fine tuning amount
01083      * which offsets the original rate.  This means that the fine tuning is
01084      * inverted with respect to the root note (so subtract it, not add).
01085      */
01086     if (voice->gen[GEN_OVERRIDEROOTKEY].val > -1) {   //FIXME: use flag instead of -1
01087       voice->root_pitch = voice->gen[GEN_OVERRIDEROOTKEY].val * 100.0f
01088         - voice->sample->pitchadj;
01089     } else {
01090       voice->root_pitch = voice->sample->origpitch * 100.0f - voice->sample->pitchadj;
01091     }
01092     voice->root_pitch = fluid_ct2hz(voice->root_pitch);
01093     if (voice->sample != NULL) {
01094       voice->root_pitch *= (fluid_real_t) voice->output_rate / voice->sample->samplerate;
01095     }
01096     break;
01097 
01098   case GEN_FILTERFC:
01099     /* The resonance frequency is converted from absolute cents to
01100      * midicents .val and .mod are both used, this permits real-time
01101      * modulation.  The allowed range is tested in the 'fluid_ct2hz'
01102      * function [PH,20021214]
01103      */
01104     voice->fres = _GEN(voice, GEN_FILTERFC);
01105 
01106     /* The synthesis loop will have to recalculate the filter
01107      * coefficients. */
01108     voice->last_fres = -1.0f;
01109     break;
01110 
01111   case GEN_FILTERQ:
01112     /* The generator contains 'centibels' (1/10 dB) => divide by 10 to
01113      * obtain dB */
01114     q_dB = _GEN(voice, GEN_FILTERQ) / 10.0f;
01115 
01116     /* Range: SF2.01 section 8.1.3 # 8 (convert from cB to dB => /10) */
01117     fluid_clip(q_dB, 0.0f, 96.0f);
01118 
01119     /* Short version: Modify the Q definition in a way, that a Q of 0
01120      * dB leads to no resonance hump in the freq. response.
01121      *
01122      * Long version: From SF2.01, page 39, item 9 (initialFilterQ):
01123      * "The gain at the cutoff frequency may be less than zero when
01124      * zero is specified".  Assume q_dB=0 / q_lin=1: If we would leave
01125      * q as it is, then this results in a 3 dB hump slightly below
01126      * fc. At fc, the gain is exactly the DC gain (0 dB).  What is
01127      * (probably) meant here is that the filter does not show a
01128      * resonance hump for q_dB=0. In this case, the corresponding
01129      * q_lin is 1/sqrt(2)=0.707.  The filter should have 3 dB of
01130      * attenuation at fc now.  In this case Q_dB is the height of the
01131      * resonance peak not over the DC gain, but over the frequency
01132      * response of a non-resonant filter.  This idea is implemented as
01133      * follows: */
01134     q_dB -= 3.01f;
01135 
01136     /* The 'sound font' Q is defined in dB. The filter needs a linear
01137        q. Convert. */
01138     voice->q_lin = (fluid_real_t) (pow(10.0f, q_dB / 20.0f));
01139 
01140     /* SF 2.01 page 59:
01141      *
01142      *  The SoundFont specs ask for a gain reduction equal to half the
01143      *  height of the resonance peak (Q).  For example, for a 10 dB
01144      *  resonance peak, the gain is reduced by 5 dB.  This is done by
01145      *  multiplying the total gain with sqrt(1/Q).  `Sqrt' divides dB
01146      *  by 2 (100 lin = 40 dB, 10 lin = 20 dB, 3.16 lin = 10 dB etc)
01147      *  The gain is later factored into the 'b' coefficients
01148      *  (numerator of the filter equation).  This gain factor depends
01149      *  only on Q, so this is the right place to calculate it.
01150      */
01151     voice->filter_gain = (fluid_real_t) (1.0 / sqrt(voice->q_lin));
01152 
01153     /* The synthesis loop will have to recalculate the filter coefficients. */
01154     voice->last_fres = -1.;
01155     break;
01156 
01157   case GEN_MODLFOTOPITCH:
01158     voice->modlfo_to_pitch = _GEN(voice, GEN_MODLFOTOPITCH);
01159     fluid_clip(voice->modlfo_to_pitch, -12000.0, 12000.0);
01160     break;
01161 
01162   case GEN_MODLFOTOVOL:
01163     voice->modlfo_to_vol = _GEN(voice, GEN_MODLFOTOVOL);
01164     fluid_clip(voice->modlfo_to_vol, -960.0, 960.0);
01165     break;
01166 
01167   case GEN_MODLFOTOFILTERFC:
01168     voice->modlfo_to_fc = _GEN(voice, GEN_MODLFOTOFILTERFC);
01169     fluid_clip(voice->modlfo_to_fc, -12000, 12000);
01170     break;
01171 
01172   case GEN_MODLFODELAY:
01173     x = _GEN(voice, GEN_MODLFODELAY);
01174     fluid_clip(x, -12000.0f, 5000.0f);
01175     voice->modlfo_delay = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x));
01176     break;
01177 
01178   case GEN_MODLFOFREQ:
01179     /* - the frequency is converted into a delta value, per buffer of FLUID_BUFSIZE samples
01180      * - the delay into a sample delay
01181      */
01182     x = _GEN(voice, GEN_MODLFOFREQ);
01183     fluid_clip(x, -16000.0f, 4500.0f);
01184     voice->modlfo_incr = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate);
01185     break;
01186 
01187   case GEN_VIBLFOFREQ:
01188     /* vib lfo
01189      *
01190      * - the frequency is converted into a delta value, per buffer of FLUID_BUFSIZE samples
01191      * - the delay into a sample delay
01192      */
01193     x = _GEN(voice, GEN_VIBLFOFREQ);
01194     fluid_clip(x, -16000.0f, 4500.0f);
01195     voice->viblfo_incr = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate);
01196     break;
01197 
01198   case GEN_VIBLFODELAY:
01199     x = _GEN(voice,GEN_VIBLFODELAY);
01200     fluid_clip(x, -12000.0f, 5000.0f);
01201     voice->viblfo_delay = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x));
01202     break;
01203 
01204   case GEN_VIBLFOTOPITCH:
01205     voice->viblfo_to_pitch = _GEN(voice, GEN_VIBLFOTOPITCH);
01206     fluid_clip(voice->viblfo_to_pitch, -12000.0, 12000.0);
01207     break;
01208 
01209   case GEN_KEYNUM:
01210     /* GEN_KEYNUM: SF2.01 page 46, item 46
01211      *
01212      * If this generator is active, it forces the key number to its
01213      * value.  Non-realtime controller.
01214      *
01215      * There is a flag, which should indicate, whether a generator is
01216      * enabled or not.  But here we rely on the default value of -1.
01217      * */
01218     x = _GEN(voice, GEN_KEYNUM);
01219     if (x >= 0){
01220       voice->key = x;
01221     }
01222     break;
01223 
01224   case GEN_VELOCITY:
01225     /* GEN_VELOCITY: SF2.01 page 46, item 47
01226      *
01227      * If this generator is active, it forces the velocity to its
01228      * value. Non-realtime controller.
01229      *
01230      * There is a flag, which should indicate, whether a generator is
01231      * enabled or not. But here we rely on the default value of -1.  */
01232     x = _GEN(voice, GEN_VELOCITY);
01233     if (x > 0) {
01234       voice->vel = x;
01235     }
01236     break;
01237 
01238   case GEN_MODENVTOPITCH:
01239     voice->modenv_to_pitch = _GEN(voice, GEN_MODENVTOPITCH);
01240     fluid_clip(voice->modenv_to_pitch, -12000.0, 12000.0);
01241     break;
01242 
01243   case GEN_MODENVTOFILTERFC:
01244     voice->modenv_to_fc = _GEN(voice,GEN_MODENVTOFILTERFC);
01245 
01246     /* Range: SF2.01 section 8.1.3 # 1
01247      * Motivation for range checking:
01248      * Filter is reported to make funny noises now and then
01249      */
01250     fluid_clip(voice->modenv_to_fc, -12000.0, 12000.0);
01251     break;
01252 
01253 
01254     /* sample start and ends points
01255      *
01256      * Range checking is initiated via the
01257      * voice->check_sample_sanity flag,
01258      * because it is impossible to check here:
01259      * During the voice setup, all modulators are processed, while
01260      * the voice is inactive. Therefore, illegal settings may
01261      * occur during the setup (for example: First move the loop
01262      * end point ahead of the loop start point => invalid, then
01263      * move the loop start point forward => valid again.
01264      */
01265   case GEN_STARTADDROFS:              /* SF2.01 section 8.1.3 # 0 */
01266   case GEN_STARTADDRCOARSEOFS:        /* SF2.01 section 8.1.3 # 4 */
01267     if (voice->sample != NULL) {
01268       voice->start = (voice->sample->start
01269                              + (int) _GEN(voice, GEN_STARTADDROFS)
01270                              + 32768 * (int) _GEN(voice, GEN_STARTADDRCOARSEOFS));
01271       voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
01272     }
01273     break;
01274   case GEN_ENDADDROFS:                 /* SF2.01 section 8.1.3 # 1 */
01275   case GEN_ENDADDRCOARSEOFS:           /* SF2.01 section 8.1.3 # 12 */
01276     if (voice->sample != NULL) {
01277       voice->end = (voice->sample->end
01278                            + (int) _GEN(voice, GEN_ENDADDROFS)
01279                            + 32768 * (int) _GEN(voice, GEN_ENDADDRCOARSEOFS));
01280       voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
01281     }
01282     break;
01283   case GEN_STARTLOOPADDROFS:           /* SF2.01 section 8.1.3 # 2 */
01284   case GEN_STARTLOOPADDRCOARSEOFS:     /* SF2.01 section 8.1.3 # 45 */
01285     if (voice->sample != NULL) {
01286       voice->loopstart = (voice->sample->loopstart
01287                                   + (int) _GEN(voice, GEN_STARTLOOPADDROFS)
01288                                   + 32768 * (int) _GEN(voice, GEN_STARTLOOPADDRCOARSEOFS));
01289       voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
01290     }
01291     break;
01292 
01293   case GEN_ENDLOOPADDROFS:             /* SF2.01 section 8.1.3 # 3 */
01294   case GEN_ENDLOOPADDRCOARSEOFS:       /* SF2.01 section 8.1.3 # 50 */
01295     if (voice->sample != NULL) {
01296       voice->loopend = (voice->sample->loopend
01297                                 + (int) _GEN(voice, GEN_ENDLOOPADDROFS)
01298                                 + 32768 * (int) _GEN(voice, GEN_ENDLOOPADDRCOARSEOFS));
01299       voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
01300     }
01301     break;
01302 
01303     /* Conversion functions differ in range limit */
01304 #define NUM_BUFFERS_DELAY(_v)   (unsigned int) (voice->output_rate * fluid_tc2sec_delay(_v) / FLUID_BUFSIZE)
01305 #define NUM_BUFFERS_ATTACK(_v)  (unsigned int) (voice->output_rate * fluid_tc2sec_attack(_v) / FLUID_BUFSIZE)
01306 #define NUM_BUFFERS_RELEASE(_v) (unsigned int) (voice->output_rate * fluid_tc2sec_release(_v) / FLUID_BUFSIZE)
01307 
01308     /* volume envelope
01309      *
01310      * - delay and hold times are converted to absolute number of samples
01311      * - sustain is converted to its absolute value
01312      * - attack, decay and release are converted to their increment per sample
01313      */
01314   case GEN_VOLENVDELAY:                /* SF2.01 section 8.1.3 # 33 */
01315     x = _GEN(voice, GEN_VOLENVDELAY);
01316     fluid_clip(x, -12000.0f, 5000.0f);
01317     count = NUM_BUFFERS_DELAY(x);
01318     voice->volenv_data[FLUID_VOICE_ENVDELAY].count = count;
01319     voice->volenv_data[FLUID_VOICE_ENVDELAY].coeff = 0.0f;
01320     voice->volenv_data[FLUID_VOICE_ENVDELAY].incr = 0.0f;
01321     voice->volenv_data[FLUID_VOICE_ENVDELAY].min = -1.0f;
01322     voice->volenv_data[FLUID_VOICE_ENVDELAY].max = 1.0f;
01323     break;
01324 
01325   case GEN_VOLENVATTACK:               /* SF2.01 section 8.1.3 # 34 */
01326     x = _GEN(voice, GEN_VOLENVATTACK);
01327     fluid_clip(x, -12000.0f, 8000.0f);
01328     count = 1 + NUM_BUFFERS_ATTACK(x);
01329     voice->volenv_data[FLUID_VOICE_ENVATTACK].count = count;
01330     voice->volenv_data[FLUID_VOICE_ENVATTACK].coeff = 1.0f;
01331     voice->volenv_data[FLUID_VOICE_ENVATTACK].incr = count ? 1.0f / count : 0.0f;
01332     voice->volenv_data[FLUID_VOICE_ENVATTACK].min = -1.0f;
01333     voice->volenv_data[FLUID_VOICE_ENVATTACK].max = 1.0f;
01334     break;
01335 
01336   case GEN_VOLENVHOLD:                 /* SF2.01 section 8.1.3 # 35 */
01337   case GEN_KEYTOVOLENVHOLD:            /* SF2.01 section 8.1.3 # 39 */
01338     count = calculate_hold_decay_buffers(voice, GEN_VOLENVHOLD, GEN_KEYTOVOLENVHOLD, 0); /* 0 means: hold */
01339     voice->volenv_data[FLUID_VOICE_ENVHOLD].count = count;
01340     voice->volenv_data[FLUID_VOICE_ENVHOLD].coeff = 1.0f;
01341     voice->volenv_data[FLUID_VOICE_ENVHOLD].incr = 0.0f;
01342     voice->volenv_data[FLUID_VOICE_ENVHOLD].min = -1.0f;
01343     voice->volenv_data[FLUID_VOICE_ENVHOLD].max = 2.0f;
01344     break;
01345 
01346   case GEN_VOLENVDECAY:               /* SF2.01 section 8.1.3 # 36 */
01347   case GEN_VOLENVSUSTAIN:             /* SF2.01 section 8.1.3 # 37 */
01348   case GEN_KEYTOVOLENVDECAY:          /* SF2.01 section 8.1.3 # 40 */
01349     y = 1.0f - 0.001f * _GEN(voice, GEN_VOLENVSUSTAIN);
01350     fluid_clip(y, 0.0f, 1.0f);
01351     count = calculate_hold_decay_buffers(voice, GEN_VOLENVDECAY, GEN_KEYTOVOLENVDECAY, 1); /* 1 for decay */
01352     voice->volenv_data[FLUID_VOICE_ENVDECAY].count = count;
01353     voice->volenv_data[FLUID_VOICE_ENVDECAY].coeff = 1.0f;
01354     voice->volenv_data[FLUID_VOICE_ENVDECAY].incr = count ? -1.0f / count : 0.0f;
01355     voice->volenv_data[FLUID_VOICE_ENVDECAY].min = y;
01356     voice->volenv_data[FLUID_VOICE_ENVDECAY].max = 2.0f;
01357     break;
01358 
01359   case GEN_VOLENVRELEASE:             /* SF2.01 section 8.1.3 # 38 */
01360     x = _GEN(voice, GEN_VOLENVRELEASE);
01361     fluid_clip(x, FLUID_MIN_VOLENVRELEASE, 8000.0f);
01362     count = 1 + NUM_BUFFERS_RELEASE(x);
01363     voice->volenv_data[FLUID_VOICE_ENVRELEASE].count = count;
01364     voice->volenv_data[FLUID_VOICE_ENVRELEASE].coeff = 1.0f;
01365     voice->volenv_data[FLUID_VOICE_ENVRELEASE].incr = count ? -1.0f / count : 0.0f;
01366     voice->volenv_data[FLUID_VOICE_ENVRELEASE].min = 0.0f;
01367     voice->volenv_data[FLUID_VOICE_ENVRELEASE].max = 1.0f;
01368     break;
01369 
01370     /* Modulation envelope */
01371   case GEN_MODENVDELAY:               /* SF2.01 section 8.1.3 # 25 */
01372     x = _GEN(voice, GEN_MODENVDELAY);
01373     fluid_clip(x, -12000.0f, 5000.0f);
01374     voice->modenv_data[FLUID_VOICE_ENVDELAY].count = NUM_BUFFERS_DELAY(x);
01375     voice->modenv_data[FLUID_VOICE_ENVDELAY].coeff = 0.0f;
01376     voice->modenv_data[FLUID_VOICE_ENVDELAY].incr = 0.0f;
01377     voice->modenv_data[FLUID_VOICE_ENVDELAY].min = -1.0f;
01378     voice->modenv_data[FLUID_VOICE_ENVDELAY].max = 1.0f;
01379     break;
01380 
01381   case GEN_MODENVATTACK:               /* SF2.01 section 8.1.3 # 26 */
01382     x = _GEN(voice, GEN_MODENVATTACK);
01383     fluid_clip(x, -12000.0f, 8000.0f);
01384     count = 1 + NUM_BUFFERS_ATTACK(x);
01385     voice->modenv_data[FLUID_VOICE_ENVATTACK].count = count;
01386     voice->modenv_data[FLUID_VOICE_ENVATTACK].coeff = 1.0f;
01387     voice->modenv_data[FLUID_VOICE_ENVATTACK].incr = count ? 1.0f / count : 0.0f;
01388     voice->modenv_data[FLUID_VOICE_ENVATTACK].min = -1.0f;
01389     voice->modenv_data[FLUID_VOICE_ENVATTACK].max = 1.0f;
01390     break;
01391 
01392   case GEN_MODENVHOLD:               /* SF2.01 section 8.1.3 # 27 */
01393   case GEN_KEYTOMODENVHOLD:          /* SF2.01 section 8.1.3 # 31 */
01394     count = calculate_hold_decay_buffers(voice, GEN_MODENVHOLD, GEN_KEYTOMODENVHOLD, 0); /* 1 means: hold */
01395     voice->modenv_data[FLUID_VOICE_ENVHOLD].count = count;
01396     voice->modenv_data[FLUID_VOICE_ENVHOLD].coeff = 1.0f;
01397     voice->modenv_data[FLUID_VOICE_ENVHOLD].incr = 0.0f;
01398     voice->modenv_data[FLUID_VOICE_ENVHOLD].min = -1.0f;
01399     voice->modenv_data[FLUID_VOICE_ENVHOLD].max = 2.0f;
01400     break;
01401 
01402   case GEN_MODENVDECAY:                                   /* SF 2.01 section 8.1.3 # 28 */
01403   case GEN_MODENVSUSTAIN:                                 /* SF 2.01 section 8.1.3 # 29 */
01404   case GEN_KEYTOMODENVDECAY:                              /* SF 2.01 section 8.1.3 # 32 */
01405     count = calculate_hold_decay_buffers(voice, GEN_MODENVDECAY, GEN_KEYTOMODENVDECAY, 1); /* 1 for decay */
01406     y = 1.0f - 0.001f * _GEN(voice, GEN_MODENVSUSTAIN);
01407     fluid_clip(y, 0.0f, 1.0f);
01408     voice->modenv_data[FLUID_VOICE_ENVDECAY].count = count;
01409     voice->modenv_data[FLUID_VOICE_ENVDECAY].coeff = 1.0f;
01410     voice->modenv_data[FLUID_VOICE_ENVDECAY].incr = count ? -1.0f / count : 0.0f;
01411     voice->modenv_data[FLUID_VOICE_ENVDECAY].min = y;
01412     voice->modenv_data[FLUID_VOICE_ENVDECAY].max = 2.0f;
01413     break;
01414 
01415   case GEN_MODENVRELEASE:                                  /* SF 2.01 section 8.1.3 # 30 */
01416     x = _GEN(voice, GEN_MODENVRELEASE);
01417     fluid_clip(x, -12000.0f, 8000.0f);
01418     count = 1 + NUM_BUFFERS_RELEASE(x);
01419     voice->modenv_data[FLUID_VOICE_ENVRELEASE].count = count;
01420     voice->modenv_data[FLUID_VOICE_ENVRELEASE].coeff = 1.0f;
01421     voice->modenv_data[FLUID_VOICE_ENVRELEASE].incr = count ? -1.0f / count : 0.0;
01422     voice->modenv_data[FLUID_VOICE_ENVRELEASE].min = 0.0f;
01423     voice->modenv_data[FLUID_VOICE_ENVRELEASE].max = 2.0f;
01424     break;
01425 
01426   } /* switch gen */
01427 }
01428 
01456 int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl)
01457 {
01458   int i, k;
01459   fluid_mod_t* mod;
01460   int gen;
01461   fluid_real_t modval;
01462 
01463 /*    printf("Chan=%d, CC=%d, Src=%d, Val=%d\n", voice->channel->channum, cc, ctrl, val); */
01464 
01465   for (i = 0; i < voice->mod_count; i++) {
01466 
01467     mod = &voice->mod[i];
01468 
01469     /* step 1: find all the modulators that have the changed controller
01470      * as input source. */
01471     if (fluid_mod_has_source(mod, cc, ctrl)) {
01472 
01473       gen = fluid_mod_get_dest(mod);
01474       modval = 0.0;
01475 
01476       /* step 2: for every changed modulator, calculate the modulation
01477        * value of its associated generator */
01478       for (k = 0; k < voice->mod_count; k++) {
01479         if (fluid_mod_has_dest(&voice->mod[k], gen)) {
01480           modval += fluid_mod_get_value(&voice->mod[k], voice->channel, voice);
01481         }
01482       }
01483 
01484       fluid_gen_set_mod(&voice->gen[gen], modval);
01485 
01486       /* step 3: now that we have the new value of the generator,
01487        * recalculate the parameter values that are derived from the
01488        * generator */
01489       fluid_voice_update_param(voice, gen);
01490     }
01491   }
01492   return FLUID_OK;
01493 }
01494 
01502 int fluid_voice_modulate_all(fluid_voice_t* voice)
01503 {
01504   fluid_mod_t* mod;
01505   int i, k, gen;
01506   fluid_real_t modval;
01507 
01508   /* Loop through all the modulators.
01509 
01510      FIXME: we should loop through the set of generators instead of
01511      the set of modulators. We risk to call 'fluid_voice_update_param'
01512      several times for the same generator if several modulators have
01513      that generator as destination. It's not an error, just a wast of
01514      energy (think polution, global warming, unhappy musicians,
01515      ...) */
01516 
01517   for (i = 0; i < voice->mod_count; i++) {
01518 
01519     mod = &voice->mod[i];
01520     gen = fluid_mod_get_dest(mod);
01521     modval = 0.0;
01522 
01523     /* Accumulate the modulation values of all the modulators with
01524      * destination generator 'gen' */
01525     for (k = 0; k < voice->mod_count; k++) {
01526       if (fluid_mod_has_dest(&voice->mod[k], gen)) {
01527         modval += fluid_mod_get_value(&voice->mod[k], voice->channel, voice);
01528       }
01529     }
01530 
01531     fluid_gen_set_mod(&voice->gen[gen], modval);
01532 
01533     /* Update the parameter values that are depend on the generator
01534      * 'gen' */
01535     fluid_voice_update_param(voice, gen);
01536   }
01537 
01538   return FLUID_OK;
01539 }
01540 
01541 /*
01542  * fluid_voice_noteoff
01543  */
01544 int
01545 fluid_voice_noteoff(fluid_voice_t* voice)
01546 {
01547   fluid_profile(FLUID_PROF_VOICE_NOTE, voice->ref);
01548 
01549   if (voice->channel && fluid_channel_sustained(voice->channel)) {
01550     voice->status = FLUID_VOICE_SUSTAINED;
01551   } else {
01552     if (voice->volenv_section == FLUID_VOICE_ENVATTACK) {
01553       /* A voice is turned off during the attack section of the volume
01554        * envelope.  The attack section ramps up linearly with
01555        * amplitude. The other sections use logarithmic scaling. Calculate new
01556        * volenv_val to achieve equievalent amplitude during the release phase
01557        * for seamless volume transition.
01558        */
01559       if (voice->volenv_val > 0){
01560         fluid_real_t lfo = voice->modlfo_val * -voice->modlfo_to_vol;
01561         fluid_real_t amp = voice->volenv_val * pow (10.0, lfo / -200);
01562         fluid_real_t env_value = - ((-200 * log (amp) / log (10.0) - lfo) / 960.0 - 1);
01563         fluid_clip (env_value, 0.0, 1.0);
01564         voice->volenv_val = env_value;
01565       }
01566     }
01567     voice->volenv_section = FLUID_VOICE_ENVRELEASE;
01568     voice->volenv_count = 0;
01569     voice->modenv_section = FLUID_VOICE_ENVRELEASE;
01570     voice->modenv_count = 0;
01571   }
01572 
01573   return FLUID_OK;
01574 }
01575 
01576 /*
01577  * fluid_voice_kill_excl
01578  *
01579  * Percussion sounds can be mutually exclusive: for example, a 'closed
01580  * hihat' sound will terminate an 'open hihat' sound ringing at the
01581  * same time. This behaviour is modeled using 'exclusive classes',
01582  * turning on a voice with an exclusive class other than 0 will kill
01583  * all other voices having that exclusive class within the same preset
01584  * or channel.  fluid_voice_kill_excl gets called, when 'voice' is to
01585  * be killed for that reason.
01586  */
01587 int
01588 fluid_voice_kill_excl(fluid_voice_t* voice){
01589 
01590   if (!_PLAYING(voice)) {
01591     return FLUID_OK;
01592   }
01593 
01594   /* Turn off the exclusive class information for this voice,
01595      so that it doesn't get killed twice
01596   */
01597   fluid_voice_gen_set(voice, GEN_EXCLUSIVECLASS, 0);
01598 
01599   /* If the voice is not yet in release state, put it into release state */
01600   if (voice->volenv_section != FLUID_VOICE_ENVRELEASE){
01601     voice->volenv_section = FLUID_VOICE_ENVRELEASE;
01602     voice->volenv_count = 0;
01603     voice->modenv_section = FLUID_VOICE_ENVRELEASE;
01604     voice->modenv_count = 0;
01605   }
01606 
01607   /* Speed up the volume envelope */
01608   /* The value was found through listening tests with hi-hat samples. */
01609   fluid_voice_gen_set(voice, GEN_VOLENVRELEASE, -200);
01610   fluid_voice_update_param(voice, GEN_VOLENVRELEASE);
01611 
01612   /* Speed up the modulation envelope */
01613   fluid_voice_gen_set(voice, GEN_MODENVRELEASE, -200);
01614   fluid_voice_update_param(voice, GEN_MODENVRELEASE);
01615 
01616   return FLUID_OK;
01617 }
01618 
01619 /*
01620  * fluid_voice_off
01621  *
01622  * Purpose:
01623  * Turns off a voice, meaning that it is not processed
01624  * anymore by the DSP loop.
01625  */
01626 int
01627 fluid_voice_off(fluid_voice_t* voice)
01628 {
01629   fluid_profile(FLUID_PROF_VOICE_RELEASE, voice->ref);
01630 
01631   voice->chan = NO_CHANNEL;
01632   voice->volenv_section = FLUID_VOICE_ENVFINISHED;
01633   voice->volenv_count = 0;
01634   voice->modenv_section = FLUID_VOICE_ENVFINISHED;
01635   voice->modenv_count = 0;
01636   voice->status = FLUID_VOICE_OFF;
01637 
01638   /* Decrement the reference count of the sample. */
01639   if (voice->sample) {
01640     fluid_sample_decr_ref(voice->sample);
01641     voice->sample = NULL;
01642   }
01643 
01644   return FLUID_OK;
01645 }
01646 
01647 /*
01648  * fluid_voice_add_mod
01649  *
01650  * Adds a modulator to the voice.  "mode" indicates, what to do, if
01651  * an identical modulator exists already.
01652  *
01653  * mode == FLUID_VOICE_ADD: Identical modulators on preset level are added
01654  * mode == FLUID_VOICE_OVERWRITE: Identical modulators on instrument level are overwritten
01655  * mode == FLUID_VOICE_DEFAULT: This is a default modulator, there can be no identical modulator.
01656  *                             Don't check.
01657  */
01658 void
01659 fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode)
01660 {
01661   int i;
01662 
01663   /*
01664    * Some soundfonts come with a huge number of non-standard
01665    * controllers, because they have been designed for one particular
01666    * sound card.  Discard them, maybe print a warning.
01667    */
01668 
01669   if (((mod->flags1 & FLUID_MOD_CC) == 0)
01670       && ((mod->src1 != 0)          /* SF2.01 section 8.2.1: Constant value */
01671           && (mod->src1 != 2)       /* Note-on velocity */
01672           && (mod->src1 != 3)       /* Note-on key number */
01673           && (mod->src1 != 10)      /* Poly pressure */
01674           && (mod->src1 != 13)      /* Channel pressure */
01675           && (mod->src1 != 14)      /* Pitch wheel */
01676           && (mod->src1 != 16))) {  /* Pitch wheel sensitivity */
01677     FLUID_LOG(FLUID_WARN, "Ignoring invalid controller, using non-CC source %i.", mod->src1);
01678     return;
01679   }
01680 
01681   if (mode == FLUID_VOICE_ADD) {
01682 
01683     /* if identical modulator exists, add them */
01684     for (i = 0; i < voice->mod_count; i++) {
01685       if (fluid_mod_test_identity(&voice->mod[i], mod)) {
01686         //              printf("Adding modulator...\n");
01687         voice->mod[i].amount += mod->amount;
01688         return;
01689       }
01690     }
01691 
01692   } else if (mode == FLUID_VOICE_OVERWRITE) {
01693 
01694     /* if identical modulator exists, replace it (only the amount has to be changed) */
01695     for (i = 0; i < voice->mod_count; i++) {
01696       if (fluid_mod_test_identity(&voice->mod[i], mod)) {
01697         //              printf("Replacing modulator...amount is %f\n",mod->amount);
01698         voice->mod[i].amount = mod->amount;
01699         return;
01700       }
01701     }
01702   }
01703 
01704   /* Add a new modulator (No existing modulator to add / overwrite).
01705      Also, default modulators (FLUID_VOICE_DEFAULT) are added without
01706      checking, if the same modulator already exists. */
01707   if (voice->mod_count < FLUID_NUM_MOD) {
01708     fluid_mod_clone(&voice->mod[voice->mod_count++], mod);
01709   }
01710 }
01711 
01712 unsigned int fluid_voice_get_id(fluid_voice_t* voice)
01713 {
01714   return voice->id;
01715 }
01716 
01717 int fluid_voice_is_playing(fluid_voice_t* voice)
01718 {
01719   return _PLAYING(voice);
01720 }
01721 
01722 /*
01723  * fluid_voice_get_lower_boundary_for_attenuation
01724  *
01725  * Purpose:
01726  *
01727  * A lower boundary for the attenuation (as in 'the minimum
01728  * attenuation of this voice, with volume pedals, modulators
01729  * etc. resulting in minimum attenuation, cannot fall below x cB) is
01730  * calculated.  This has to be called during fluid_voice_init, after
01731  * all modulators have been run on the voice once.  Also,
01732  * voice->attenuation has to be initialized.
01733  */
01734 fluid_real_t fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t* voice)
01735 {
01736   int i;
01737   fluid_mod_t* mod;
01738   fluid_real_t possible_att_reduction_cB=0;
01739   fluid_real_t lower_bound;
01740 
01741   for (i = 0; i < voice->mod_count; i++) {
01742     mod = &voice->mod[i];
01743 
01744     /* Modulator has attenuation as target and can change over time? */
01745     if ((mod->dest == GEN_ATTENUATION)
01746         && ((mod->flags1 & FLUID_MOD_CC) || (mod->flags2 & FLUID_MOD_CC))) {
01747 
01748       fluid_real_t current_val = fluid_mod_get_value(mod, voice->channel, voice);
01749       fluid_real_t v = fabs(mod->amount);
01750 
01751       if ((mod->src1 == FLUID_MOD_PITCHWHEEL)
01752           || (mod->flags1 & FLUID_MOD_BIPOLAR)
01753           || (mod->flags2 & FLUID_MOD_BIPOLAR)
01754           || (mod->amount < 0)) {
01755         /* Can this modulator produce a negative contribution? */
01756         v *= -1.0;
01757       } else {
01758         /* No negative value possible. But still, the minimum contribution is 0. */
01759         v = 0;
01760       }
01761 
01762       /* For example:
01763        * - current_val=100
01764        * - min_val=-4000
01765        * - possible_att_reduction_cB += 4100
01766        */
01767       if (current_val > v){
01768         possible_att_reduction_cB += (current_val - v);
01769       }
01770     }
01771   }
01772 
01773   lower_bound = voice->attenuation-possible_att_reduction_cB;
01774 
01775   /* SF2.01 specs do not allow negative attenuation */
01776   if (lower_bound < 0) {
01777     lower_bound = 0;
01778   }
01779   return lower_bound;
01780 }
01781 
01782 
01783 /* Purpose:
01784  *
01785  * Make sure, that sample start / end point and loop points are in
01786  * proper order. When starting up, calculate the initial phase.
01787  */
01788 void fluid_voice_check_sample_sanity(fluid_voice_t* voice)
01789 {
01790     int min_index_nonloop=(int) voice->sample->start;
01791     int max_index_nonloop=(int) voice->sample->end;
01792 
01793     /* make sure we have enough samples surrounding the loop */
01794     int min_index_loop=(int) voice->sample->start + FLUID_MIN_LOOP_PAD;
01795     int max_index_loop=(int) voice->sample->end - FLUID_MIN_LOOP_PAD + 1;       /* 'end' is last valid sample, loopend can be + 1 */
01796     fluid_check_fpe("voice_check_sample_sanity start");
01797 
01798     if (!voice->check_sample_sanity_flag){
01799         return;
01800     }
01801 
01802 #if 0
01803     printf("Sample from %i to %i\n",voice->sample->start, voice->sample->end);
01804     printf("Sample loop from %i %i\n",voice->sample->loopstart, voice->sample->loopend);
01805     printf("Playback from %i to %i\n", voice->start, voice->end);
01806     printf("Playback loop from %i to %i\n",voice->loopstart, voice->loopend);
01807 #endif
01808 
01809     /* Keep the start point within the sample data */
01810     if (voice->start < min_index_nonloop){
01811         voice->start = min_index_nonloop;
01812     } else if (voice->start > max_index_nonloop){
01813         voice->start = max_index_nonloop;
01814     }
01815 
01816     /* Keep the end point within the sample data */
01817     if (voice->end < min_index_nonloop){
01818       voice->end = min_index_nonloop;
01819     } else if (voice->end > max_index_nonloop){
01820       voice->end = max_index_nonloop;
01821     }
01822 
01823     /* Keep start and end point in the right order */
01824     if (voice->start > voice->end){
01825         int temp = voice->start;
01826         voice->start = voice->end;
01827         voice->end = temp;
01828         /*FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Changing order of start / end points!"); */
01829     }
01830 
01831     /* Zero length? */
01832     if (voice->start == voice->end){
01833         fluid_voice_off(voice);
01834         return;
01835     }
01836 
01837     if ((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE)
01838         || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)) {
01839         /* Keep the loop start point within the sample data */
01840         if (voice->loopstart < min_index_loop){
01841             voice->loopstart = min_index_loop;
01842       } else if (voice->loopstart > max_index_loop){
01843         voice->loopstart = max_index_loop;
01844       }
01845 
01846       /* Keep the loop end point within the sample data */
01847       if (voice->loopend < min_index_loop){
01848         voice->loopend = min_index_loop;
01849       } else if (voice->loopend > max_index_loop){
01850         voice->loopend = max_index_loop;
01851       }
01852 
01853       /* Keep loop start and end point in the right order */
01854       if (voice->loopstart > voice->loopend){
01855         int temp = voice->loopstart;
01856         voice->loopstart = voice->loopend;
01857         voice->loopend = temp;
01858         /*FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Changing order of loop points!"); */
01859       }
01860 
01861       /* Loop too short? Then don't loop. */
01862       if (voice->loopend < voice->loopstart + FLUID_MIN_LOOP_SIZE){
01863           voice->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED;
01864       }
01865 
01866       /* The loop points may have changed. Obtain a new estimate for the loop volume. */
01867       /* Is the voice loop within the sample loop? */
01868       if ((int)voice->loopstart >= (int)voice->sample->loopstart
01869           && (int)voice->loopend <= (int)voice->sample->loopend){
01870         /* Is there a valid peak amplitude available for the loop? */
01871         if (voice->sample->amplitude_that_reaches_noise_floor_is_valid){
01872           voice->amplitude_that_reaches_noise_floor_loop=voice->sample->amplitude_that_reaches_noise_floor / voice->synth_gain;
01873         } else {
01874           /* Worst case */
01875           voice->amplitude_that_reaches_noise_floor_loop=voice->amplitude_that_reaches_noise_floor_nonloop;
01876         };
01877       };
01878 
01879     } /* if sample mode is looped */
01880 
01881     /* Run startup specific code (only once, when the voice is started) */
01882     if (voice->check_sample_sanity_flag & FLUID_SAMPLESANITY_STARTUP){
01883       if (max_index_loop - min_index_loop < FLUID_MIN_LOOP_SIZE){
01884         if ((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE)
01885             || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)){
01886           voice->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED;
01887         }
01888       }
01889 
01890       /* Set the initial phase of the voice (using the result from the
01891          start offset modulators). */
01892       fluid_phase_set_int(voice->phase, voice->start);
01893     } /* if startup */
01894 
01895     /* Is this voice run in loop mode, or does it run straight to the
01896        end of the waveform data? */
01897     if (((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE) && (voice->volenv_section < FLUID_VOICE_ENVRELEASE))
01898         || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)) {
01899       /* Yes, it will loop as soon as it reaches the loop point.  In
01900        * this case we must prevent, that the playback pointer (phase)
01901        * happens to end up beyond the 2nd loop point, because the
01902        * point has moved.  The DSP algorithm is unable to cope with
01903        * that situation.  So if the phase is beyond the 2nd loop
01904        * point, set it to the start of the loop. No way to avoid some
01905        * noise here.  Note: If the sample pointer ends up -before the
01906        * first loop point- instead, then the DSP loop will just play
01907        * the sample, enter the loop and proceed as expected => no
01908        * actions required.
01909        */
01910       int index_in_sample = fluid_phase_index(voice->phase);
01911       if (index_in_sample >= voice->loopend){
01912         /* FLUID_LOG(FLUID_DBG, "Loop / sample sanity check: Phase after 2nd loop point!"); */
01913         fluid_phase_set_int(voice->phase, voice->loopstart);
01914       }
01915     }
01916 /*    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); */
01917 
01918     /* Sample sanity has been assured. Don't check again, until some
01919        sample parameter is changed by modulation. */
01920     voice->check_sample_sanity_flag=0;
01921 #if 0
01922     printf("Sane? playback loop from %i to %i\n", voice->loopstart, voice->loopend);
01923 #endif
01924     fluid_check_fpe("voice_check_sample_sanity");
01925 }
01926 
01927 
01928 int fluid_voice_set_param(fluid_voice_t* voice, int gen, fluid_real_t nrpn_value, int abs)
01929 {
01930   voice->gen[gen].nrpn = nrpn_value;
01931   voice->gen[gen].flags = (abs)? GEN_ABS_NRPN : GEN_SET;
01932   fluid_voice_update_param(voice, gen);
01933   return FLUID_OK;
01934 }
01935 
01936 int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain)
01937 {
01938   /* avoid division by zero*/
01939   if (gain < 0.0000001){
01940     gain = 0.0000001;
01941   }
01942 
01943   voice->synth_gain = gain;
01944   voice->amp_left = fluid_pan(voice->pan, 1) * gain / 32768.0f;
01945   voice->amp_right = fluid_pan(voice->pan, 0) * gain / 32768.0f;
01946   voice->amp_reverb = voice->reverb_send * gain / 32768.0f;
01947   voice->amp_chorus = voice->chorus_send * gain / 32768.0f;
01948 
01949   return FLUID_OK;
01950 }
01951 
01952 /* - Scan the loop
01953  * - determine the peak level
01954  * - Calculate, what factor will make the loop inaudible
01955  * - Store in sample
01956  */
01957 int fluid_voice_optimize_sample(fluid_sample_t* s)
01958 {
01959   signed short peak_max = 0;
01960   signed short peak_min = 0;
01961   signed short peak;
01962   fluid_real_t normalized_amplitude_during_loop;
01963   double result;
01964   int i;
01965 
01966   /* ignore ROM and other(?) invalid samples */
01967   if (!s->valid) return (FLUID_OK);
01968 
01969   if (!s->amplitude_that_reaches_noise_floor_is_valid){ /* Only once */
01970     /* Scan the loop */
01971     for (i = (int)s->loopstart; i < (int) s->loopend; i ++){
01972       signed short val = s->data[i];
01973       if (val > peak_max) {
01974         peak_max = val;
01975       } else if (val < peak_min) {
01976         peak_min = val;
01977       }
01978     }
01979 
01980     /* Determine the peak level */
01981     if (peak_max >- peak_min){
01982       peak = peak_max;
01983     } else {
01984       peak =- peak_min;
01985     };
01986     if (peak == 0){
01987       /* Avoid division by zero */
01988       peak = 1;
01989     };
01990 
01991     /* Calculate what factor will make the loop inaudible
01992      * For example: Take a peak of 3277 (10 % of 32768).  The
01993      * normalized amplitude is 0.1 (10 % of 32768).  An amplitude
01994      * factor of 0.0001 (as opposed to the default 0.00001) will
01995      * drop this sample to the noise floor.
01996      */
01997 
01998     /* 16 bits => 96+4=100 dB dynamic range => 0.00001 */
01999     normalized_amplitude_during_loop = ((fluid_real_t)peak)/32768.;
02000     result = FLUID_NOISE_FLOOR / normalized_amplitude_during_loop;
02001 
02002     /* Store in sample */
02003     s->amplitude_that_reaches_noise_floor = (double)result;
02004     s->amplitude_that_reaches_noise_floor_is_valid = 1;
02005 #if 0
02006     printf("Sample peak detection: factor %f\n", (double)result);
02007 #endif
02008   };
02009   return FLUID_OK;
02010 }

Generated on Sat Nov 17 13:40:24 2007 for libfluidsynth by  doxygen 1.5.3