-
Notifications
You must be signed in to change notification settings - Fork 87
/
sample_processor.hpp
67 lines (57 loc) · 1.96 KB
/
sample_processor.hpp
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
// nStreams specifies the number of interleaved streams in the incoming data.
// emitValue_t must have the signature:
// void(int32_t* re, int32_t* im)
// where re and im point to arrays of size nStreams.
template<class emitValue_t, int nStreams=1>
class SampleProcessor {
public:
uint32_t accumPhase;
int32_t accumRe[nStreams],accumIm[nStreams];
// integration time for each output value
int accumPeriod = 50;
// sinusoid table, must be accumPeriod*2 entries (interleaved real & imag)
const int16_t* correlationTable = nullptr;
bool clipFlag = false;
// void emitValue(int32_t valRe, int32_t valIm)
emitValue_t emitValue;
SampleProcessor(const emitValue_t& cb): emitValue(cb) {}
void init() {
accumPhase = 0;
for(int streamNum = 0; streamNum < nStreams; streamNum++)
accumRe[streamNum] = accumIm[streamNum] = 0;
clipFlag = false;
}
void setCorrelationTable(const int16_t* table, int length) {
accumPhase = 0;
correlationTable = table;
accumPeriod = length;
}
// len specifies the number of aggregates (i.e. when nStreams > 1,
// the number of words in the array must be len * nStreams).
// returns whether we completed a cycle.
bool process(uint16_t* samples, int len) {
uint16_t* end = samples+len*nStreams;
bool ret = false;
while(samples < end) {
int32_t lo_im = correlationTable[accumPhase*2];
int32_t lo_re = correlationTable[accumPhase*2 + 1];
for(int streamNum = 0; streamNum < nStreams; streamNum++) {
int16_t sample = int16_t((samples[streamNum]) - 2048);
if(sample > 2000 || sample < -2000) {clipFlag = true;} // Overflow
accumRe[streamNum] += lo_re*sample/512;
accumIm[streamNum] += lo_im*sample/512;
}
accumPhase++;
samples += nStreams;
if(int(accumPhase) >= accumPeriod) {
emitValue(accumRe, accumIm);
clipFlag = false;
for(int streamNum = 0; streamNum < nStreams; streamNum++)
accumRe[streamNum] = accumIm[streamNum] = 0;
accumPhase = 0;
ret = true;
}
}
return ret;
}
};