Skip to content

Commit db51fa3

Browse files
committed
AudioEspressifFFT
1 parent 2809bc2 commit db51fa3

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include "AudioTools.h"
2+
#include "AudioLibs/AudioEspressifFFT.h" // Using Espressif DSP Library
3+
4+
AudioEspressifFFT fftc;
5+
SineWaveGenerator<int16_t> sineWave(32000);
6+
GeneratedSoundStream<int16_t> in(sineWave);
7+
StreamCopy copier(fftc, in);
8+
uint16_t sample_rate = 44100;
9+
int bits_per_sample = 16;
10+
int channels = 1;
11+
float value = 0;
12+
13+
// display fftc result
14+
void fftcResult(AudioFFTBase &fftc) {
15+
int diff;
16+
auto result = fftc.result();
17+
if (result.magnitude > 100) {
18+
Serial.print(result.frequency);
19+
Serial.print(" ");
20+
Serial.print(result.magnitude);
21+
Serial.print(" => ");
22+
Serial.print(result.frequencyAsNote(diff));
23+
Serial.print(" diff: ");
24+
Serial.print(diff);
25+
Serial.print(" - time ms ");
26+
Serial.print(fftc.resultTime() - fftc.resultTimeBegin());
27+
Serial.println();
28+
29+
}
30+
}
31+
32+
void setup() {
33+
Serial.begin(115200);
34+
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
35+
36+
// set the frequency
37+
sineWave.setFrequency(N_B4);
38+
39+
// Setup sine wave
40+
auto cfg = in.defaultConfig();
41+
cfg.channels = channels;
42+
cfg.sample_rate = sample_rate;
43+
in.begin(cfg);
44+
45+
// Setup FFT
46+
auto tcfg = fftc.defaultConfig();
47+
tcfg.copyFrom(cfg);
48+
tcfg.length = 4096;
49+
tcfg.callback = &fftcResult;
50+
fftc.begin(tcfg);
51+
}
52+
53+
void loop() { copier.copy(); }

src/AudioLibs/AudioEspressifFFT.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#pragma once
2+
3+
#include "AudioFFT.h"
4+
#include "esp_dsp.h"
5+
6+
namespace audio_tools {
7+
8+
/**
9+
* @brief fft Driver for espressif dsp library: https://espressif-docs.readthedocs-hosted.com/projects/esp-dsp/en/latest/esp-dsp-apis.html
10+
* @author Phil Schatzmann
11+
* @copyright GPLv3
12+
*/
13+
class FFTDriverEspressifFFT : public FFTDriver {
14+
public:
15+
void begin(int len) override {
16+
N = len;
17+
if (p_data==nullptr){
18+
p_data = new float[len*2];
19+
if (p_data==nullptr){
20+
LOGE("not enough memory");
21+
}
22+
}
23+
ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
24+
if (ret != ESP_OK){
25+
LOGE("dsps_fft2r_init_fc32 %d", ret);
26+
}
27+
}
28+
29+
void end() override {
30+
dsps_fft2r_deinit_fc32();
31+
if (p_data==nullptr){
32+
delete p_data;
33+
p_data = nullptr;
34+
}
35+
}
36+
37+
void setValue(int idx, int value) override {
38+
if (idx<N){
39+
p_data[idx*2 + 0] = value;
40+
p_data[idx*2 + 1] = 0.0f;
41+
}
42+
}
43+
44+
void fft() override {
45+
ret = dsps_fft2r_fc32(p_data, N);
46+
if (ret != ESP_OK){
47+
LOGE("dsps_fft2r_fc32 %d", ret);
48+
}
49+
// Bit reverse
50+
ret = dsps_bit_rev_fc32(p_data, N);
51+
if (ret != ESP_OK){
52+
LOGE("dsps_bit_rev_fc32 %d", ret);
53+
}
54+
// Convert one complex vector to two complex vectors
55+
ret = dsps_cplx2reC_fc32(p_data, N);
56+
if (ret != ESP_OK){
57+
LOGE("dsps_cplx2reC_fc32 %d", ret);
58+
}
59+
};
60+
61+
float magnitude(int idx) override {
62+
if (idx<N){
63+
return sqrt(p_data[idx*2] * p_data[idx*2] + p_data[idx*2+1] * p_data[idx*2+1]);
64+
}
65+
return 0.0f;
66+
}
67+
68+
virtual bool isValid() override{ return p_data!=nullptr && ret==ESP_OK; }
69+
70+
esp_err_t ret;
71+
float *p_data = nullptr;
72+
int N=0;
73+
74+
};
75+
/**
76+
* @brief AudioFFT using FFTReal. The only specific functionality is the access to the dataArray
77+
* @author Phil Schatzmann
78+
* @copyright GPLv3
79+
*/
80+
class AudioEspressifFFT : public AudioFFTBase {
81+
public:
82+
AudioEspressifFFT():AudioFFTBase(new FFTDriverEspressifFFT()) {}
83+
84+
/// Provides the complex array returned by the FFT
85+
float *dataArray() {
86+
return driverEx()->p_data;
87+
}
88+
89+
FFTDriverEspressifFFT* driverEx() {
90+
return (FFTDriverEspressifFFT*)driver();
91+
}
92+
};
93+
94+
95+
}

0 commit comments

Comments
 (0)