1 /* FluidSynth - A Software Synthesizer
3 * Copyright (C) 2003 Peter Hanappe and others.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1 of
8 * the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #ifndef _FLUID_ADSR_ENVELOPE_H
22 #define _FLUID_ADSR_ENVELOPE_H
24 #include "fluidsynth_priv.h"
25 #include "fluid_sys.h"
30 struct _fluid_env_data_t
34 fluid_real_t increment;
39 /* Indices for envelope tables */
40 enum fluid_voice_envelope_index_t
43 FLUID_VOICE_ENVATTACK,
46 FLUID_VOICE_ENVSUSTAIN,
47 FLUID_VOICE_ENVRELEASE,
48 FLUID_VOICE_ENVFINISHED,
52 typedef enum fluid_voice_envelope_index_t fluid_adsr_env_section_t;
54 typedef struct _fluid_adsr_env_t fluid_adsr_env_t;
56 struct _fluid_adsr_env_t
58 fluid_env_data_t data[FLUID_VOICE_ENVLAST];
61 fluid_real_t val; /* the current value of the envelope */
64 /* For performance, all functions are inlined */
66 static FLUID_INLINE void
67 fluid_adsr_env_calc(fluid_adsr_env_t *env, int is_volenv)
69 fluid_env_data_t *env_data;
72 env_data = &env->data[env->section];
74 /* skip to the next section of the envelope if necessary */
75 while(env->count >= env_data->count)
77 // If we're switching envelope stages from decay to sustain, force the value to be the end value of the previous stage
78 // Hmm, should this only apply to volenv? It was so before refactoring, so keep it for now. [DH]
79 if(env->section == FLUID_VOICE_ENVDECAY && is_volenv)
81 env->val = env_data->min * env_data->coeff;
84 env_data = &env->data[++env->section];
88 /* calculate the envelope value and check for valid range */
89 x = env_data->coeff * env->val + env_data->increment;
97 else if(x > env_data->max)
113 /* This one cannot be inlined since it is referenced in
115 DECLARE_FLUID_RVOICE_FUNCTION(fluid_adsr_env_set_data);
117 static FLUID_INLINE void
118 fluid_adsr_env_reset(fluid_adsr_env_t *env)
125 static FLUID_INLINE fluid_real_t
126 fluid_adsr_env_get_val(fluid_adsr_env_t *env)
131 static FLUID_INLINE void
132 fluid_adsr_env_set_val(fluid_adsr_env_t *env, fluid_real_t val)
137 static FLUID_INLINE fluid_adsr_env_section_t
138 fluid_adsr_env_get_section(fluid_adsr_env_t *env)
143 static FLUID_INLINE void
144 fluid_adsr_env_set_section(fluid_adsr_env_t *env,
145 fluid_adsr_env_section_t section)
147 env->section = section;
151 /* Used for determining which voice to kill.
152 Returns max amplitude from now, and forward in time.
154 static FLUID_INLINE fluid_real_t
155 fluid_adsr_env_get_max_val(fluid_adsr_env_t *env)
157 if(env->section > FLUID_VOICE_ENVATTACK)
159 return env->val * 1000;
163 return env->data[FLUID_VOICE_ENVATTACK].max;