forked from audacity/audacity
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSpecPowerMeter.cpp
More file actions
83 lines (59 loc) · 1.77 KB
/
Copy pathSpecPowerMeter.cpp
File metadata and controls
83 lines (59 loc) · 1.77 KB
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
77
78
79
80
81
82
/**********************************************************************
Audacity: A Digital Audio Editor
SpecPowerCalculation.cpp
Philipp Sibler
******************************************************************//**
\class SpecPowerCalculation
\brief SpecPowerCalculation is a simple spectral power level meter.
SpecPowerCalculation operates in the Fourier domain and allows power level
measurements in subbands or in the entire signal band.
*//*******************************************************************/
#include "SpecPowerMeter.h"
#include <cmath>
#include <cstdlib>
#include <wx/defs.h>
#include "../FFT.h"
SpecPowerCalculation::SpecPowerCalculation(size_t sigLen)
: mSigLen(sigLen)
, mSigI{ sigLen, true }
, mSigFR{ sigLen }
, mSigFI{ sigLen }
{
}
SpecPowerCalculation::~SpecPowerCalculation()
{
}
float SpecPowerCalculation::CalcPower(float* sig, float fc, float bw)
{
float pwr;
int loBin, hiBin;
// Given the bandwidth bw, get the boundary bin numbers
loBin = Freq2Bin(fc - (bw / 2.0f));
hiBin = Freq2Bin(fc + (bw / 2.0f));
if (loBin == hiBin)
{
hiBin = loBin + 1;
}
// Calc the FFT
FFT(mSigLen, 0, sig, mSigI.get(), mSigFR.get(), mSigFI.get());
// Calc the in-band power
pwr = CalcBinPower(mSigFR.get(), mSigFI.get(), loBin, hiBin);
return pwr;
}
float SpecPowerCalculation::CalcBinPower(float* sig_f_r, float* sig_f_i, int loBin, int hiBin)
{
float pwr = 0.0f;
for (int n = loBin; n < hiBin; n++)
{
pwr += ((sig_f_r[n]*sig_f_r[n])+(sig_f_i[n]*sig_f_i[n]));
}
return pwr;
}
int SpecPowerCalculation::Freq2Bin(float fc)
{
int bin;
// There is no round() in (older) MSVSs ...
bin = floor((double)fc * mSigLen);
bin %= (int)mSigLen;
return bin;
}