void fluid_rvoice_noteoff(fluid_rvoice_t* voice, unsigned int min_ticks) { if (min_ticks > voice->envlfo.ticks) { /* Delay noteoff */ voice->envlfo.noteoff_ticks = min_ticks; return; } voice->envlfo.noteoff_ticks = 0; if (fluid_adsr_env_get_section(&voice->envlfo.volenv) == FLUID_VOICE_ENVATTACK) { /* A voice is turned off during the attack section of the volume * envelope. The attack section ramps up linearly with * amplitude. The other sections use logarithmic scaling. Calculate new * volenv_val to achieve equievalent amplitude during the release phase * for seamless volume transition. */ if (fluid_adsr_env_get_val(&voice->envlfo.volenv) > 0){ fluid_real_t lfo = fluid_lfo_get_val(&voice->envlfo.modlfo) * -voice->envlfo.modlfo_to_vol; fluid_real_t amp = fluid_adsr_env_get_val(&voice->envlfo.volenv) * pow (10.0, lfo / -200); fluid_real_t env_value = - ((-200 * log (amp) / log (10.0) - lfo) / 960.0 - 1); fluid_clip (env_value, 0.0, 1.0); fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value); } } fluid_adsr_env_set_section(&voice->envlfo.volenv, FLUID_VOICE_ENVRELEASE); fluid_adsr_env_set_section(&voice->envlfo.modenv, FLUID_VOICE_ENVRELEASE); }
static fluid_real_t fluid_iir_filter_q_from_dB(fluid_real_t q_dB) { /* The generator contains 'centibels' (1/10 dB) => divide by 10 to * obtain dB */ q_dB /= 10.0f; /* Range: SF2.01 section 8.1.3 # 8 (convert from cB to dB => /10) */ fluid_clip(q_dB, 0.0f, 96.0f); /* Short version: Modify the Q definition in a way, that a Q of 0 * dB leads to no resonance hump in the freq. response. * * Long version: From SF2.01, page 39, item 9 (initialFilterQ): * "The gain at the cutoff frequency may be less than zero when * zero is specified". Assume q_dB=0 / q_lin=1: If we would leave * q as it is, then this results in a 3 dB hump slightly below * fc. At fc, the gain is exactly the DC gain (0 dB). What is * (probably) meant here is that the filter does not show a * resonance hump for q_dB=0. In this case, the corresponding * q_lin is 1/sqrt(2)=0.707. The filter should have 3 dB of * attenuation at fc now. In this case Q_dB is the height of the * resonance peak not over the DC gain, but over the frequency * response of a non-resonant filter. This idea is implemented as * follows: */ q_dB -= 3.01f; /* The 'sound font' Q is defined in dB. The filter needs a linear q. Convert. */ return pow(10.0f, q_dB / 20.0f); }
/* * fluid_sndmgr_callback * */ void pascal fluid_sndmgr_callback(SndChannelPtr chan, SndDoubleBufferPtr doubleBuffer) { fluid_sndmgr_audio_driver_t* dev; signed short* buf; float* left; float* right; float v; int i, k, buffer_size; dev = (fluid_sndmgr_audio_driver_t*) doubleBuffer->dbUserInfo[0]; buf = (signed short*)doubleBuffer->dbSoundData; buffer_size = dev->bufferFrameSize; if (dev->callback_is_audio_func) { /* float API : conversion to signed short */ left = dev->convbuffers[0]; right = dev->convbuffers[1]; (*dev->callback)(dev->data, buffer_size, 0, NULL, 2, dev->convbuffers); for (i = 0, k = 0; i < buffer_size; i++) { v = 32767.0f * left[i]; fluid_clip(v, -32768.0f, 32767.0f); buf[k++] = (signed short) v; v = 32767.0f * right[i]; fluid_clip(v, -32768.0f, 32767.0f); buf[k++] = (signed short) v; } } else { /* let the synth do the convertion */ fluid_synth_write_s16((fluid_synth_t*)dev->data, buffer_size, buf, 0, 2, buf, 1, 2); } doubleBuffer->dbFlags = doubleBuffer->dbFlags | dbBufferReady; doubleBuffer->dbNumFrames = buffer_size; }
/** * Set one or more reverb parameters. * @param rev Reverb instance * @param set One or more flags from #fluid_revmodel_set_t indicating what * parameters to set (#FLUID_REVMODEL_SET_ALL to set all parameters) * @param roomsize Reverb room size * @param damping Reverb damping * @param width Reverb width * @param level Reverb level */ void fluid_revmodel_set(fluid_revmodel_t* rev, int set, float roomsize, float damping, float width, float level) { if (set & FLUID_REVMODEL_SET_ROOMSIZE) rev->roomsize = (roomsize * scaleroom) + offsetroom; if (set & FLUID_REVMODEL_SET_DAMPING) rev->damp = damping * scaledamp; if (set & FLUID_REVMODEL_SET_WIDTH) rev->width = width; if (set & FLUID_REVMODEL_SET_LEVEL) { fluid_clip(level, 0.0f, 1.0f); rev->wet = level * scalewet; } fluid_revmodel_update (rev); }