#ifndef REVERB_H #define REVERB_H #include #include #include template class Diffusor { dsp::BufferMulti m_dly; int m_delay_spec[numCh]; int m_shuffle_spec[numCh]; public: Diffusor(uint maxDelaySize) : m_dly(maxDelaySize) { float delayRagePerWindow = (float)maxDelaySize/(float)numCh; // Delay spec for (int i=0; i < numCh; i++) { float base_delay = i*delayRagePerWindow; float z = (float)rand()/(float)RAND_MAX; int delay = (int)(base_delay + z*delayRagePerWindow); m_delay_spec[i] = -delay; } // Shuffle spec for (int i=0; i < numCh; i++) { m_shuffle_spec[i] = i; } // Shuffle values for (int i=0; i < 2*numCh; i++) { int i1 = rand() & (numCh-1); int i2 = rand() & (numCh-1); int temp = m_shuffle_spec[i1]; m_shuffle_spec[i1] = m_shuffle_spec[i2]; m_shuffle_spec[i2] = temp; } // Shuffle signs float p = 0.3; for (int i=0; i < numCh; i++) { float z = (float)rand()/(float)RAND_MAX; if (z <= p) { m_shuffle_spec[i] *= (T)-1; } } } inline T process(T in) { m_dly = in; T qbuf[numCh]; m_dly.quer(qbuf, m_delay_spec); T sbuf[numCh]; Shuffle::outOfPlace(qbuf, sbuf, m_shuffle_spec); Hadamard::inPlace(sbuf); Householder::inPlace(sbuf); ++m_dly; return sbuf[0]; } }; template class Reverb { std::array, 3> m_diffusors; public: Reverb(uint maxDelay) : m_diffusors({maxDelay, maxDelay, maxDelay}) { } void process(float *in, float *out, unsigned numPoints) { for (int i=0; i < numPoints; i++) { T temp = in[i]; for (auto diffusor: m_diffusors) { temp = diffusor.process(temp); } out[i] = temp; } } }; #endif