Expose voice detune parameter of the lv2 plugin
[zyn.git] / envelope.cpp
blobcac73601848f09492222fba17350b19968df5eca
1 /*
2 ZynAddSubFX - a software synthesizer
4 Envelope.C - Envelope implementation
5 Copyright (C) 2002-2005 Nasca Octavian Paul
6 Author: Nasca Octavian Paul
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of version 2 of the GNU General Public License
10 as published by the Free Software Foundation.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License (version 2) for more details.
17 You should have received a copy of the GNU General Public License (version 2)
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <math.h>
25 #include "globals.h"
26 #include "envelope_parameters.h"
27 #include "envelope.h"
29 void
30 Envelope::init(
31 float sample_rate,
32 EnvelopeParams * parameters_ptr,
33 float basefreq)
35 int i;
36 float buffer_duration;
38 envpoints = parameters_ptr->Penvpoints;
40 if (envpoints > MAX_ENVELOPE_POINTS)
42 envpoints = MAX_ENVELOPE_POINTS;
45 envsustain = (parameters_ptr->Penvsustain == 0) ? -1 : parameters_ptr->Penvsustain;
46 m_forced_release = parameters_ptr->m_forced_release;
47 m_stretch = pow(440.0 / basefreq, parameters_ptr->m_stretch / 64.0);
48 m_linear = parameters_ptr->m_linear;
50 buffer_duration = SOUND_BUFFER_SIZE / sample_rate;
52 for (i = 0 ; i < MAX_ENVELOPE_POINTS ; i++)
54 float tmp = parameters_ptr->getdt(i) / 1000.0 * m_stretch;
55 if (tmp > buffer_duration)
57 envdt[i] = buffer_duration / tmp;
59 else
61 envdt[i] = 2.0; // any value larger than 1
64 envval[i] = parameters_ptr->m_values[i];
67 envdt[0] = 1.0;
69 currentpoint = 1; // the envelope starts from 1
70 m_key_released = false;
71 t = 0.0;
72 m_finished = false;
73 inct = envdt[1];
74 envoutval = 0.0;
77 Envelope::Envelope()
81 Envelope::~Envelope()
86 * Relase the key (note envelope)
88 void
89 Envelope::relasekey()
91 if (m_key_released)
93 return;
96 m_key_released = true;
98 if (m_forced_release)
100 t = 0.0;
105 * Envelope Output
107 float
108 Envelope::envout()
110 float out;
112 if (m_finished) // if the envelope is finished
114 envoutval = envval[envpoints - 1];
115 return envoutval;
118 if ((currentpoint == envsustain + 1) && !m_key_released) // if it is sustaining now
120 envoutval = envval[envsustain];
121 return envoutval;
124 if (m_key_released && m_forced_release) // do the forced release
126 int tmp = (envsustain < 0) ? (envpoints - 1) : (envsustain + 1); // if there is no sustain point, use the last point for release
128 if (envdt[tmp] < 0.00000001)
130 out = envval[tmp];
132 else
134 out = envoutval + (envval[tmp] - envoutval) * t;
137 t += envdt[tmp] * m_stretch;
139 if (t >= 1.0)
141 currentpoint = envsustain + 2;
142 m_forced_release = false;
143 t = 0.0;
144 inct = envdt[currentpoint];
145 if (currentpoint >= envpoints || envsustain < 0)
147 m_finished = true;
151 return out;
154 if (inct >= 1.0)
156 out = envval[currentpoint];
158 else
160 out = envval[currentpoint - 1] + (envval[currentpoint] - envval[currentpoint - 1]) * t;
163 t += inct;
165 if (t >= 1.0)
167 if (currentpoint >= envpoints - 1)
169 m_finished = true;
171 else
173 currentpoint++;
176 t = 0.0;
178 inct = envdt[currentpoint];
181 envoutval = out;
183 return out;
187 * Envelope Output (dB)
189 float
190 Envelope::envout_dB()
192 float out;
194 if (m_linear)
196 return envout();
199 // first point is always lineary interpolated
200 if (currentpoint == 1 &&
201 (!m_key_released || !m_forced_release))
203 float v1 = dB2rap(envval[0]);
204 float v2 = dB2rap(envval[1]);
205 out = v1 + (v2 - v1) * t;
207 t += inct;
209 if (t >= 1.0)
211 t = 0.0;
212 inct = envdt[2];
213 currentpoint++;
214 out = v2;
217 if (out > 0.001)
219 envoutval=rap2dB(out);
221 else
223 envoutval=-40.0;
226 else
228 out = dB2rap(envout());
231 return out;
234 bool
235 Envelope::finished()
237 return m_finished;