1 /*******************************************************************************
2  * Copyright 2009-2016 Jörg Müller
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 
17 #include "fx/Envelope.h"
18 #include "fx/CallbackIIRFilterReader.h"
19 
20 #include <cmath>
21 
22 AUD_NAMESPACE_BEGIN
23 
24 struct EnvelopeParameters
25 {
26 	float attack;
27 	float release;
28 	float threshold;
29 	float arthreshold;
30 };
31 
envelopeFilter(CallbackIIRFilterReader * reader,EnvelopeParameters * param)32 sample_t Envelope::envelopeFilter(CallbackIIRFilterReader* reader, EnvelopeParameters* param)
33 {
34 	float in = std::fabs(reader->x(0));
35 	float out = reader->y(-1);
36 	if(in < param->threshold)
37 		in = 0.0f;
38 	return (in > out ? param->attack : param->release) * (out - in) + in;
39 }
40 
endEnvelopeFilter(EnvelopeParameters * param)41 void Envelope::endEnvelopeFilter(EnvelopeParameters* param)
42 {
43 	delete param;
44 }
45 
Envelope(std::shared_ptr<ISound> sound,float attack,float release,float threshold,float arthreshold)46 Envelope::Envelope(std::shared_ptr<ISound> sound, float attack, float release, float threshold, float arthreshold) :
47 		Effect(sound),
48 		m_attack(attack),
49 		m_release(release),
50 		m_threshold(threshold),
51 		m_arthreshold(arthreshold)
52 {
53 }
54 
createReader()55 std::shared_ptr<IReader> Envelope::createReader()
56 {
57 	std::shared_ptr<IReader> reader = getReader();
58 
59 	EnvelopeParameters* param = new EnvelopeParameters();
60 	param->arthreshold = m_arthreshold;
61 	param->attack = std::pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_attack));
62 	param->release = std::pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_release));
63 	param->threshold = m_threshold;
64 
65 	return std::shared_ptr<IReader>(new CallbackIIRFilterReader(reader, 1, 2,
66 										   (doFilterIIR) envelopeFilter,
67 										   (endFilterIIR) endEnvelopeFilter,
68 										   param));
69 }
70 
71 AUD_NAMESPACE_END
72