-
Notifications
You must be signed in to change notification settings - Fork 1
/
peakmeter.cpp
59 lines (48 loc) · 1.08 KB
/
peakmeter.cpp
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
#include "peakmeter.h"
void AudioPeakHold::update(void)
{
audio_block_t *block;
const int16_t *p, *end;
block = receiveReadOnly();
if (!block) {
return;
}
// shift the old blockPeak
for(int i = PEAK_HOLD_BLOCKS - 1; i > 0; i--){
blockPeak[i] = blockPeak[i-1];
blockSqAccum[i] = blockSqAccum[i-1];
}
uint16_t thisBlockPeak = 0;
// calculate peak
p = block->data;
end = p + AUDIO_BLOCK_SAMPLES;
do {
int32_t d=*p++;
d = abs(d);
// TODO: can we speed this up with SSUB16 and SEL
// http://www.m4-unleashed.com/parallel-comparison/
if(d > thisBlockPeak){
thisBlockPeak = d;
}
} while (p < end);
// calculate sum of squared samples
p = block->data;
end = p + AUDIO_BLOCK_SAMPLES;
int64_t sum = 0;
do {
int32_t n = *p++;
sum += n * n;
} while (p < end);
blockSqAccum[0] = sum;
blockPeak[0] = thisBlockPeak;
peak = 0;
meanSq = 0;
for(int i = 0; i < PEAK_HOLD_BLOCKS; i++){
if(blockPeak[i] > peak){
peak = blockPeak[i];
}
meanSq += blockSqAccum[i];
}
meanSq /= AUDIO_BLOCK_SAMPLES * PEAK_HOLD_BLOCKS;
release(block);
}