Skip to content

Commit d34cdd3

Browse files
committed
Inverse FFT corrections
1 parent d44d0f5 commit d34cdd3

File tree

5 files changed

+94
-8
lines changed

5 files changed

+94
-8
lines changed

src/AudioTools/AudioLibs/AudioFFT.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class FFTInverseOverlapAdder {
9191

9292
void resize(int size) {
9393
rfft_max = 0.0;
94+
len = size;
9495
data.resize(size);
9596
for (int j = 0; j < data.size(); j++) {
9697
data[j] = 0.0;
@@ -240,6 +241,7 @@ class AudioFFTBase : public AudioStream {
240241
if (cfg.rxtx_mode == RX_MODE || cfg.rxtx_mode == RXTX_MODE) {
241242
rfft_data.resize(cfg.channels * bytesPerSample() * step_size);
242243
rfft_add.resize(cfg.length);
244+
step_data.resize(cfg.stride);
243245
is_valid_rxtx = true;
244246
}
245247

@@ -462,10 +464,10 @@ class AudioFFTBase : public AudioStream {
462464

463465
// Add samples to input data p_x - and process them if full
464466
template <typename T>
465-
void processSamples(const void *data, size_t samples) {
467+
void processSamples(const void *data, size_t count) {
466468
T *dataT = (T *)data;
467469
T sample;
468-
for (int j = 0; j < samples; j += cfg.channels) {
470+
for (int j = 0; j < count; j += cfg.channels) {
469471
sample = dataT[j + cfg.channel_used];
470472
if (writeStrideBuffer((uint8_t *)&sample, sizeof(T))){
471473
// process data if buffer is full
@@ -527,10 +529,9 @@ class AudioFFTBase : public AudioStream {
527529
/// write reverse fft result to buffer to make it available for readBytes
528530
void rfftWriteData(BaseBuffer<uint8_t> &data) {
529531
// get data to result buffer
530-
step_data.resize(cfg.stride);
531-
for (int j = 0; j < cfg.stride; j++) {
532-
step_data[j] = 0.0;
533-
}
532+
// for (int j = 0; j < cfg.stride; j++) {
533+
// step_data[j] = 0.0;
534+
// }
534535
rfft_add.getStepData(step_data.data(), cfg.stride,
535536
NumberConverter::maxValue(cfg.bits_per_sample));
536537

src/AudioTools/AudioLibs/FFT/FFTWindows.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class BufferedWindow : public WindowFunction {
7575
WindowFunction::begin(samples);
7676
if (p_wf->samples() != samples) {
7777
p_wf->begin(samples);
78-
len = samples / 2;
78+
len = samples;
7979
buffer.resize(len);
8080
for (int j = 0; j < len; j++) {
8181
buffer[j] = p_wf->factor(j);
@@ -89,7 +89,8 @@ class BufferedWindow : public WindowFunction {
8989
int len;
9090

9191
float factor_internal(int idx) override {
92-
return idx < len ? buffer[idx] : buffer[i_samples - idx];
92+
if (idx < 0 || idx > len) return 0.0;
93+
return buffer[idx];
9394
}
9495
};
9596

tests-cmake/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ endif()
2323
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/resample ${CMAKE_CURRENT_BINARY_DIR}/resample)
2424
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/generator ${CMAKE_CURRENT_BINARY_DIR}/generator)
2525
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/effects ${CMAKE_CURRENT_BINARY_DIR}/effects)
26+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/fft ${CMAKE_CURRENT_BINARY_DIR}/fft)
2627
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/filter ${CMAKE_CURRENT_BINARY_DIR}/filter)
2728
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/filter-wav ${CMAKE_CURRENT_BINARY_DIR}/filter-wav)
2829
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/url-test ${CMAKE_CURRENT_BINARY_DIR}/url-test)

tests-cmake/fft/CMakeLists.txt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
cmake_minimum_required(VERSION 3.20)
2+
3+
4+
# set the project name
5+
project(fft)
6+
set (CMAKE_CXX_STANDARD 11)
7+
set (DCMAKE_CXX_FLAGS "-Werror")
8+
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ldl -lpthread -lm")
9+
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -ldl -lpthread -lm")
10+
11+
# Emulator is not necessary for -DIS_MIN_DESKTOP
12+
set(ADD_ARDUINO_EMULATOR OFF CACHE BOOL "Add Arduino Emulator Library")
13+
set(ADD_PORTAUDIO OFF CACHE BOOL "No Portaudio")
14+
15+
# Build with arduino-audio-tools
16+
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
17+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../.. ${CMAKE_CURRENT_BINARY_DIR}/arduino-audio-tools )
18+
endif()
19+
20+
# Download miniaudio.h
21+
file(DOWNLOAD https://raw.githubusercontent.com/mackron/miniaudio/master/miniaudio.h
22+
${CMAKE_CURRENT_SOURCE_DIR}/miniaudio.h)
23+
24+
25+
# build sketch as executable
26+
add_executable (fft fft.cpp)
27+
28+
# set preprocessor defines
29+
target_compile_definitions(fft PUBLIC -DIS_MIN_DESKTOP)
30+
31+
# specify libraries
32+
target_link_libraries(fft arduino-audio-tools)
33+
34+
# access to miniaudio in sketch directory
35+
target_include_directories(fft PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

tests-cmake/fft/fft.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include "AudioTools.h"
2+
#include "AudioTools/AudioLibs/AudioRealFFT.h" // using RealFFT
3+
#include "AudioTools/AudioLibs/MiniAudioStream.h"
4+
5+
AudioInfo info(44100, 2, 16);
6+
AudioRealFFT afft; // or AudioKissFFT
7+
Hann hann;
8+
BufferedWindow buffered(&hann);
9+
SineWaveGenerator<int16_t> sineWave(32000);
10+
GeneratedSoundStream<int16_t> in(sineWave);
11+
StreamCopy copier(afft, in);
12+
//CsvOutput<int16_t> out(Serial);
13+
MiniAudioStream out;
14+
StreamCopy copierIFFT(out, afft);
15+
16+
// process fft result
17+
void fftResult(AudioFFTBase &fft) {
18+
// copy ifft result to output
19+
while (copierIFFT.copy());
20+
}
21+
22+
void setup() {
23+
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
24+
25+
// set the frequency
26+
sineWave.setFrequency(N_B4);
27+
28+
// Setup sine wave
29+
auto cfg = in.defaultConfig();
30+
cfg.copyFrom(info);
31+
in.begin(cfg);
32+
33+
// Setup FFT
34+
auto tcfg = afft.defaultConfig(RXTX_MODE);
35+
tcfg.copyFrom(info);
36+
tcfg.length = 1024;
37+
tcfg.window_function = &buffered;
38+
tcfg.stride = 512;
39+
tcfg.callback = fftResult;
40+
afft.begin(tcfg);
41+
42+
// setup output
43+
auto ocfg = out.defaultConfig(TX_MODE);
44+
ocfg.copyFrom(info);
45+
out.begin(ocfg);
46+
}
47+
48+
void loop() { copier.copy(); }

0 commit comments

Comments
 (0)