blob: 0e72d7a8341e054f6e141c96f401539d93e41f6b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
/**
* FilterPan Single :
* + This delay will be applied on left channel following the
* leftDelayFrames parameter and on the right one by minus leftDelayFrames.
* + This delay is applied sample by sample and not on the full buffer.
*/
#ifndef ENGINEFILTERPANSINGLE_H
#define ENGINEFILTERPANSINGLE_H
#include <string.h>
#include "engine/engineobject.h"
#include "util/assert.h"
static const int numChannels = 2;
template<unsigned int SIZE>
class EngineFilterPanSingle {
public:
EngineFilterPanSingle()
: m_delayFrame(0),
m_doStart(false) {
// Set the current buffers to 0
memset(m_buf, 0, sizeof(m_buf));
}
virtual ~EngineFilterPanSingle() {};
void pauseFilter() {
// Set the current buffers to 0
if (!m_doStart) {
memset(m_buf, 0, sizeof(m_buf));
m_doStart = true;
}
}
virtual void process(const CSAMPLE* pIn, CSAMPLE* pOutput, double leftDelayFrames) {
double delayLeftSourceFrame;
double delayRightSourceFrame;
if (leftDelayFrames > 0) {
delayLeftSourceFrame = m_delayFrame + SIZE - leftDelayFrames;
delayRightSourceFrame = m_delayFrame + SIZE;
} else {
delayLeftSourceFrame = m_delayFrame + SIZE;
delayRightSourceFrame = m_delayFrame + SIZE + leftDelayFrames;
}
// put in samples into delay buffer
m_buf[m_delayFrame * 2] = pIn[0];
m_buf[m_delayFrame * 2 + 1] = pIn[1];
// move the delay cursor forward
m_delayFrame = (m_delayFrame + 1) % SIZE;
// prepare coefficients for linear interpolation using a linear stretching
double timeBetweenFullSamplesLeft = fmod(delayLeftSourceFrame, 1);
double timeBetweenFullSamplesRight = fmod(delayRightSourceFrame, 1);
// applying the delay on left channel with linear interpolation between each sample
pOutput[0] = m_buf[(static_cast<int>(floor(delayLeftSourceFrame)) % SIZE) * 2] * (1 - timeBetweenFullSamplesLeft);
pOutput[0] += m_buf[(static_cast<int>(ceil(delayLeftSourceFrame)) % SIZE) * 2] * timeBetweenFullSamplesLeft;
// then on right channel
pOutput[1] = m_buf[(static_cast<int>(floor(delayRightSourceFrame)) % SIZE) * 2 + 1] * (1 - timeBetweenFullSamplesRight);
pOutput[1] += m_buf[(static_cast<int>(ceil(delayRightSourceFrame)) % SIZE) * 2 + 1] * timeBetweenFullSamplesRight;
m_doStart = false;
}
protected:
int m_delayFrame;
CSAMPLE m_buf[SIZE * numChannels];
bool m_doStart;
};
#endif // ENGINEFILTERPAN_H
|