Path: blob/master/libs/fluidsynth/src/rvoice/fluid_adsr_env.h
4396 views
/* FluidSynth - A Software Synthesizer1*2* Copyright (C) 2003 Peter Hanappe and others.3*4* This library is free software; you can redistribute it and/or5* modify it under the terms of the GNU Lesser General Public License6* as published by the Free Software Foundation; either version 2.1 of7* the License, or (at your option) any later version.8*9* This library is distributed in the hope that it will be useful, but10* WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12* Lesser General Public License for more details.13*14* You should have received a copy of the GNU Lesser General Public15* License along with this library; if not, write to the Free16* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA17* 02110-1301, USA18*/1920#ifndef _FLUID_ADSR_ENVELOPE_H21#define _FLUID_ADSR_ENVELOPE_H2223#include "fluidsynth_priv.h"24#include "fluid_sys.h"2526/*27* envelope data28*/29struct _fluid_env_data_t30{31unsigned int count;32fluid_real_t coeff;33fluid_real_t increment;34fluid_real_t min;35fluid_real_t max;36};3738/* Indices for envelope tables */39enum fluid_voice_envelope_index40{41FLUID_VOICE_ENVDELAY,42FLUID_VOICE_ENVATTACK,43FLUID_VOICE_ENVHOLD,44FLUID_VOICE_ENVDECAY,45FLUID_VOICE_ENVSUSTAIN,46FLUID_VOICE_ENVRELEASE,47FLUID_VOICE_ENVFINISHED,48FLUID_VOICE_ENVLAST49};5051typedef enum fluid_voice_envelope_index fluid_adsr_env_section_t;5253typedef struct _fluid_adsr_env_t fluid_adsr_env_t;5455struct _fluid_adsr_env_t56{57fluid_env_data_t data[FLUID_VOICE_ENVLAST];58unsigned int count;59fluid_real_t val; /* the current value of the envelope */60fluid_adsr_env_section_t section;61};6263/* For performance, all functions are inlined */6465static FLUID_INLINE void66fluid_adsr_env_calc(fluid_adsr_env_t *env)67{68fluid_env_data_t *env_data;69fluid_real_t x;7071env_data = &env->data[env->section];7273/* skip to the next section of the envelope if necessary */74while(env->count >= env_data->count)75{76// If we're switching envelope stages from decay to sustain, force the value to be the end value of the previous stage77// Hmm, should this only apply to volenv? It was so before refactoring, so keep it for now. [DH]78// No, must apply to both, otherwise some voices may sound detuned. [TM] (https://github.com/FluidSynth/fluidsynth/issues/1059)79if(env->section == FLUID_VOICE_ENVDECAY)80{81env->val = env_data->min * env_data->coeff;82}8384env_data = &env->data[++env->section];85env->count = 0;86}8788/* calculate the envelope value and check for valid range */89x = env_data->coeff * env->val + env_data->increment;9091if(x < env_data->min)92{93x = env_data->min;94env->section++;95env->count = 0;96}97else if(x > env_data->max)98{99x = env_data->max;100env->section++;101env->count = 0;102}103else104{105env->count++;106}107108env->val = x;109}110111/* This one cannot be inlined since it is referenced in112the event queue */113DECLARE_FLUID_RVOICE_FUNCTION(fluid_adsr_env_set_data);114115static FLUID_INLINE void116fluid_adsr_env_reset(fluid_adsr_env_t *env)117{118env->count = 0;119env->section = FLUID_VOICE_ENVDELAY;120env->val = 0.0f;121}122123static FLUID_INLINE fluid_real_t124fluid_adsr_env_get_val(fluid_adsr_env_t *env)125{126return env->val;127}128129static FLUID_INLINE void130fluid_adsr_env_set_val(fluid_adsr_env_t *env, fluid_real_t val)131{132env->val = val;133}134135static FLUID_INLINE fluid_adsr_env_section_t136fluid_adsr_env_get_section(fluid_adsr_env_t *env)137{138return env->section;139}140141static FLUID_INLINE void142fluid_adsr_env_set_section(fluid_adsr_env_t *env,143fluid_adsr_env_section_t section)144{145env->section = section;146env->count = 0;147}148149/* Used for determining which voice to kill.150Returns max amplitude from now, and forward in time.151*/152static FLUID_INLINE fluid_real_t153fluid_adsr_env_get_max_val(fluid_adsr_env_t *env)154{155if(env->section > FLUID_VOICE_ENVATTACK)156{157return env->val * 1000;158}159else160{161return env->data[FLUID_VOICE_ENVATTACK].max;162}163}164165#endif166167168