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 Library General Public License
7 * as published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * 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 {
33 fluid_real_t increment;
38 /* Indices for envelope tables */
39 enum fluid_voice_envelope_index_t{
41 FLUID_VOICE_ENVATTACK,
44 FLUID_VOICE_ENVSUSTAIN,
45 FLUID_VOICE_ENVRELEASE,
46 FLUID_VOICE_ENVFINISHED,
50 typedef enum fluid_voice_envelope_index_t fluid_adsr_env_section_t;
52 typedef struct _fluid_adsr_env_t fluid_adsr_env_t;
54 struct _fluid_adsr_env_t {
55 fluid_env_data_t data[FLUID_VOICE_ENVLAST];
58 fluid_real_t val; /* the current value of the envelope */
61 /* For performance, all functions are inlined */
63 static FLUID_INLINE void
64 fluid_adsr_env_calc(fluid_adsr_env_t* env, int is_volenv)
66 fluid_env_data_t* env_data;
69 env_data = &env->data[env->section];
71 /* skip to the next section of the envelope if necessary */
72 while (env->count >= env_data->count)
74 // If we're switching envelope stages from decay to sustain, force the value to be the end value of the previous stage
75 // Hmm, should this only apply to volenv? It was so before refactoring, so keep it for now. [DH]
76 if (env->section == FLUID_VOICE_ENVDECAY && is_volenv)
77 env->val = env_data->min * env_data->coeff;
79 env_data = &env->data[++env->section];
83 /* calculate the envelope value and check for valid range */
84 x = env_data->coeff * env->val + env_data->increment;
86 if (x < env_data->min)
92 else if (x > env_data->max)
103 /* This one cannot be inlined since it is referenced in
106 fluid_adsr_env_set_data(fluid_adsr_env_t* env,
107 fluid_adsr_env_section_t section,
110 fluid_real_t increment,
115 fluid_adsr_env_reset(fluid_adsr_env_t* env)
122 static inline fluid_real_t
123 fluid_adsr_env_get_val(fluid_adsr_env_t* env)
129 fluid_adsr_env_set_val(fluid_adsr_env_t* env, fluid_real_t val)
134 static inline fluid_adsr_env_section_t
135 fluid_adsr_env_get_section(fluid_adsr_env_t* env)
141 fluid_adsr_env_set_section(fluid_adsr_env_t* env,
142 fluid_adsr_env_section_t section)
144 env->section = section;
148 /* Used for determining which voice to kill.
149 Returns max amplitude from now, and forward in time.
151 static inline fluid_real_t
152 fluid_adsr_env_get_max_val(fluid_adsr_env_t* env)
154 if (env->section > FLUID_VOICE_ENVATTACK){
155 return env->val * 1000;
157 return env->data[FLUID_VOICE_ENVATTACK].max;