Merging with trunk up to r38631.
[blender.git] / intern / audaspace / FX / AUD_EnvelopeFactory.cpp
index 1c625067f1c59ff88520f063536cecb71bd2d8b9..80df7e9f8748e249c5fce9610c5bb32a97103b62 100644 (file)
@@ -1,32 +1,62 @@
 /*
  * $Id$
  *
- * ***** BEGIN LGPL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
- * Copyright 2009 Jörg Hermann Müller
+ * Copyright 2009-2011 Jörg Hermann Müller
  *
  * This file is part of AudaSpace.
  *
- * AudaSpace is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * Audaspace is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
  * AudaSpace is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
+ * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * ***** END LGPL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file audaspace/FX/AUD_EnvelopeFactory.cpp
+ *  \ingroup audfx
+ */
+
+
 #include "AUD_EnvelopeFactory.h"
-#include "AUD_EnvelopeReader.h"
+#include "AUD_CallbackIIRFilterReader.h"
+
+#include <cmath>
+
+struct EnvelopeParameters
+{
+       float attack;
+       float release;
+       float threshold;
+       float arthreshold;
+};
+
+sample_t AUD_EnvelopeFactory::envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param)
+{
+       float in = fabs(reader->x(0));
+       float out = reader->y(-1);
+       if(in < param->threshold)
+               in = 0.0f;
+       return (in > out ? param->attack : param->release) * (out - in) + in;
+}
 
-AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
+void AUD_EnvelopeFactory::endEnvelopeFilter(EnvelopeParameters* param)
+{
+       delete param;
+}
+
+AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_Reference<AUD_IFactory> factory, float attack,
                                                                                 float release, float threshold,
                                                                                 float arthreshold) :
                AUD_EffectFactory(factory),
@@ -37,8 +67,18 @@ AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
 {
 }
 
-AUD_IReader* AUD_EnvelopeFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_EnvelopeFactory::createReader()
 {
-       return new AUD_EnvelopeReader(getReader(), m_attack, m_release, m_threshold,
-                                                                 m_arthreshold);
+       AUD_Reference<AUD_IReader> reader = getReader();
+
+       EnvelopeParameters* param = new EnvelopeParameters();
+       param->arthreshold = m_arthreshold;
+       param->attack = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_attack));
+       param->release = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_release));
+       param->threshold = m_threshold;
+
+       return new AUD_CallbackIIRFilterReader(reader, 1, 2,
+                                                                                  (doFilterIIR) envelopeFilter,
+                                                                                  (endFilterIIR) endEnvelopeFilter,
+                                                                                  param);
 }