// An envelope follower implementation I found on the internets: http://www.musicdsp.org/showone.php?id=97 class EnvelopeFollower extends UGen { // attack and release time in seconds float m_attack; float m_release; // coefficients for our envelope following algorithm float m_ga, m_gr; // for collecting a buffer to calculate the envelope value float[] m_buffer; // to keep track of how full our buffer is. // when it fills all the way up, we calculate a value // and then go back to filling. int m_bufferCount; // the current value of the envelope float m_envelope; UGenInput audio; EnvelopeFollower( float attack, float release, int bufferSize ) { m_attack = attack; m_release = release; m_buffer = new float[bufferSize]; m_bufferCount = 0; m_envelope = 0.f; audio = new UGenInput( InputType.AUDIO ); } void sampleRateChanged() { m_ga = exp( -1 / (sampleRate() * m_attack) ); m_gr = exp( -1 / (sampleRate() * m_release) ); } void uGenerate( float[] out ) { if ( audio.isPatched() ) { m_buffer[m_bufferCount++] = audio.getLastValues()[0]; } // full buffer, find the envelope value if ( m_bufferCount == m_buffer.length ) { m_envelope = 0.f; for(int i = 0; i < m_buffer.length; ++i ) { float envIn = abs( m_buffer[i] ); if ( m_envelope < envIn ) { m_envelope *= m_ga; m_envelope += (1-m_ga)*envIn; } else { m_envelope *= m_gr; m_envelope += (1-m_gr)*envIn; } } m_bufferCount = 0; } for (int i = 0; i < out.length; i++) { out[i] = m_envelope; } } }