107 lines
1.8 KiB
C++
107 lines
1.8 KiB
C++
#ifndef REVERB_H
|
|
#define REVERB_H
|
|
|
|
#include <cstdlib>
|
|
#include <delay/buffer_multi.hpp>
|
|
#include <common/mix.hpp>
|
|
|
|
template<typename T, size_t numCh>
|
|
class Diffusor
|
|
{
|
|
dsp::BufferMulti<T, numCh> 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<T, numCh>::outOfPlace(qbuf, sbuf, m_shuffle_spec);
|
|
|
|
Hadamard<T, numCh>::inPlace(sbuf);
|
|
Householder<T, numCh>::inPlace(sbuf);
|
|
++m_dly;
|
|
|
|
return sbuf[0];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
template<typename T, uint numCh>
|
|
class Reverb
|
|
{
|
|
std::array<Diffusor<T, numCh>, 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
|