-
Notifications
You must be signed in to change notification settings - Fork 0
/
audioAnalyzer.cpp
135 lines (105 loc) · 3.46 KB
/
audioAnalyzer.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
FFT libray
Copyright (C) 2021 Phil Malone
Copyright (C) 2010 Didier Longueville
Copyright (C) 2014 Enrique Condes
Copyright (C) 2021 Philip Malone
*/
#include <Arduino.h>
#include <AudioStream.h>
#include "audioAnalyzer.h"
#include "bufferManager.h"
AudioAnalyzeFFT::AudioAnalyzeFFT(void) : AudioStream(1, inputQueueArray)
{
LO_FFT = arduinoFFT_float(LO_vReal, LO_vImag, LO_weights, LO_FFT_SAMPLES, LO_SAMPLING_FREQ, FFT_WIN_TYP_HAMMING);
LO_Buffer = BufferManager(LO_vReal, LO_weights, LO_short, LO_FFT_SAMPLES, LO_SAMPLE_SKIP);
MD_FFT = arduinoFFT_float(MD_vReal, MD_vImag, MD_weights, MD_FFT_SAMPLES, MD_SAMPLING_FREQ, FFT_WIN_TYP_HAMMING);
MD_Buffer = BufferManager(MD_vReal, MD_weights, MD_short, MD_FFT_SAMPLES, MD_SAMPLE_SKIP);
HI_FFT = arduinoFFT_float(HI_vReal, HI_vImag, HI_weights, HI_FFT_SAMPLES, HI_SAMPLING_FREQ, FFT_WIN_TYP_HAMMING);
HI_Buffer = BufferManager(HI_vReal, HI_weights, HI_short, HI_FFT_SAMPLES, HI_SAMPLE_SKIP);
state = 0;
outputflag = false;
memset(LO_short, 0, sizeof(LO_short));
memset(MD_short, 0, sizeof(MD_short));
memset(HI_short, 0, sizeof(HI_short));
}
// Return and then clear the "available" flag.
bool AudioAnalyzeFFT::available() {
bool temp = outputflag;
outputflag = false;
return temp;
}
// Return and then clear the "missedBlock" flag.
bool AudioAnalyzeFFT::missingBlocks(){
bool temp = missedBlock;
missedBlock = false;
return temp;
}
// Return the current Scale ratio
void AudioAnalyzeFFT::setInputScale(float scale){
inputScale = scale;
}
float AudioAnalyzeFFT::read(int range, unsigned short binNumber, float noiseThreshold) {
float tempVal;
if ((range==0) && (binNumber < LO_FREQ_BINS)) {
tempVal = LO_vReal[binNumber];
} else if ((range==1) && (binNumber < MD_FREQ_BINS)) {
tempVal = MD_vReal[binNumber];
} else if ((range==2) && (binNumber < HI_FREQ_BINS)) {
tempVal = HI_vReal[binNumber];
} else {
tempVal = 0;
}
if (tempVal < noiseThreshold)
tempVal = 0;
return (tempVal);
}
float AudioAnalyzeFFT::read(int range, unsigned short binNumber) {
return (read(range, binNumber, 0.0));
}
float AudioAnalyzeFFT::read(int range, unsigned short binFirst, unsigned short binLast, float noiseThreshold) {
float sum = 0.0;
do {
sum += read(range, binFirst++, noiseThreshold);
} while (binFirst <= binLast);
return sum;
}
void AudioAnalyzeFFT::update(void)
{
audio_block_t *block;
short *src ;
// unsigned long startUpdate = micros();
block = receiveReadOnly();
if (!block) {
missedBlock = true;
return;
}
// Save a pointer to the latest audio block
src = block->data;
// add the latest block to the hi and low buffers
for (short sample = 0; sample < BURST_SAMPLES; sample++) {
LO_Buffer.addSample(*src);
MD_Buffer.addSample(*src);
HI_Buffer.addSample(*src);
src++;
}
// Release audio block back into the pool
release(block);
state++;
// Do we have a full audio buffer?
if (state == BURSTS_PER_FFT_UPDATE) {
// transfer the accumulated buffers to the FFT. Remove bias and apply weights along the way
LO_Buffer.transfer(inputScale);
MD_Buffer.transfer(inputScale);
HI_Buffer.transfer(inputScale);
// Process the FFT
LO_FFT.RunFFT();
MD_FFT.RunFFT();
HI_FFT.RunFFT();
outputflag = true;
state = 0;
// Serial.print("Update= ");
// Serial.print((float)(micros() - startUpdate) / 1000.0);
// Serial.println(" mSec");
}
}