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
26 #include "envelope_parameters.h"
32 EnvelopeParams
* parameters_ptr
,
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
;
61 envdt
[i
] = 2.0; // any value larger than 1
64 envval
[i
] = parameters_ptr
->m_values
[i
];
69 currentpoint
= 1; // the envelope starts from 1
70 m_key_released
= false;
86 * Relase the key (note envelope)
96 m_key_released
= true;
112 if (m_finished
) // if the envelope is finished
114 envoutval
= envval
[envpoints
- 1];
118 if ((currentpoint
== envsustain
+ 1) && !m_key_released
) // if it is sustaining now
120 envoutval
= envval
[envsustain
];
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)
134 out
= envoutval
+ (envval
[tmp
] - envoutval
) * t
;
137 t
+= envdt
[tmp
] * m_stretch
;
141 currentpoint
= envsustain
+ 2;
142 m_forced_release
= false;
144 inct
= envdt
[currentpoint
];
145 if (currentpoint
>= envpoints
|| envsustain
< 0)
156 out
= envval
[currentpoint
];
160 out
= envval
[currentpoint
- 1] + (envval
[currentpoint
] - envval
[currentpoint
- 1]) * t
;
167 if (currentpoint
>= envpoints
- 1)
178 inct
= envdt
[currentpoint
];
187 * Envelope Output (dB)
190 Envelope::envout_dB()
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
;
219 envoutval
=rap2dB(out
);
228 out
= dB2rap(envout());