-
Notifications
You must be signed in to change notification settings - Fork 32
/
AudioEffectFreqShiftFD_OA_F32.h
134 lines (114 loc) · 4.56 KB
/
AudioEffectFreqShiftFD_OA_F32.h
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
/*
* AudioEffectFreqShiftFD_F32
*
* Created: Chip Audette, Aug 2019
* Purpose: Shift the frequency content of the audio up or down. Performed in the frequency domain
*
* This processes a single stream of audio data (ie, it is mono)
*
* MIT License. use at your own risk.
*/
#ifndef _AudioEffectFreqShiftFD_OA_F32_h
#define _AudioEffectFreqShiftFD_OA_F32_h
#include "AudioStream_F32.h"
#include <arm_math.h>
#include "FFT_Overlapped_OA_F32.h"
#include <Arduino.h>
class AudioEffectFreqShiftFD_OA_F32 : public AudioStream_F32
{
//GUI: inputs:1, outputs:1 //this line used for automatic generation of GUI node
//GUI: shortName:freq_shift
public:
//constructors...a few different options. The usual one should be: AudioEffectFreqShiftFD_F32(const AudioSettings_F32 &settings, const int _N_FFT)
AudioEffectFreqShiftFD_OA_F32(void) : AudioStream_F32(1, inputQueueArray_f32) {};
AudioEffectFreqShiftFD_OA_F32(const AudioSettings_F32 &settings) :
AudioStream_F32(1, inputQueueArray_f32) {
sample_rate_Hz = settings.sample_rate_Hz;
}
AudioEffectFreqShiftFD_OA_F32(const AudioSettings_F32 &settings, const int _N_FFT) :
AudioStream_F32(1, inputQueueArray_f32) {
setup(settings, _N_FFT);
}
//destructor...release all of the memory that has been allocated
~AudioEffectFreqShiftFD_OA_F32(void) {
if (complex_2N_buffer != NULL) delete complex_2N_buffer;
}
int setup(const AudioSettings_F32 &settings, const int _N_FFT) {
sample_rate_Hz = settings.sample_rate_Hz;
//setup the FFT and IFFT. If they return a negative FFT, it wasn't an allowed FFT size.
N_FFT = myFFT.setup(settings, _N_FFT); //hopefully, we got the same N_FFT that we asked for
if (N_FFT < 1) return N_FFT;
N_FFT = myIFFT.setup(settings, _N_FFT); //hopefully, we got the same N_FFT that we asked for
if (N_FFT < 1) return N_FFT;
//decide windowing
//Serial.println("AudioEffectFreqShiftFD_F32: setting myFFT to use hanning...");
(myFFT.getFFTObject())->useHanningWindow(); //applied prior to FFT
#if 1
if (myIFFT.getNBuffBlocks() > 3) {
Serial.println("AudioEffectFormantShiftFD_F32: setting myIFFT to use hanning...");
(myIFFT.getIFFTObject())->useHanningWindow(); //window again after IFFT
}
#endif
//decide how much overlap is happening
switch (myIFFT.getNBuffBlocks()) {
case 0:
//should never happen
break;
case 1:
overlap_amount = NONE;
break;
case 2:
overlap_amount = HALF;
break;
case 3:
//to do...need to add phase shifting logic to the update() function to support this case
break;
case 4:
overlap_amount = THREE_QUARTERS;
//to do...need to add phase shifting logic to the update() function to support this case
break;
}
#if 0
//print info about setup
Serial.println("AudioEffectFreqShiftFD_F32: FFT parameters...");
Serial.print(" : N_FFT = "); Serial.println(N_FFT);
Serial.print(" : audio_block_samples = "); Serial.println(settings.audio_block_samples);
Serial.print(" : FFT N_BUFF_BLOCKS = "); Serial.println(myFFT.getNBuffBlocks());
Serial.print(" : IFFT N_BUFF_BLOCKS = "); Serial.println(myIFFT.getNBuffBlocks());
Serial.print(" : FFT use window = "); Serial.println(myFFT.getFFTObject()->get_flagUseWindow());
Serial.print(" : IFFT use window = "); Serial.println((myIFFT.getIFFTObject())->get_flagUseWindow());
#endif
//allocate memory to hold frequency domain data
complex_2N_buffer = new float32_t[2 * N_FFT];
//we're done. return!
enabled = 1;
return N_FFT;
}
int setShift_bins(int _shift_bins) {
return shift_bins = _shift_bins;
}
int getShift_bins(void) {
return shift_bins;
}
float getShift_Hz(void) {
return getFrequencyOfBin(shift_bins);
}
float getFrequencyOfBin(int bin) { //"bin" should be zero to (N_FFT-1)
return sample_rate_Hz * ((float)bin) / ((float) N_FFT);
}
virtual void update(void);
bool enable(bool state = true) { enabled = state; return enabled;}
private:
int enabled = 0;
float32_t *complex_2N_buffer;
audio_block_f32_t *inputQueueArray_f32[1];
FFT_Overlapped_OA_F32 myFFT;
IFFT_Overlapped_OA_F32 myIFFT;
float sample_rate_Hz = AUDIO_SAMPLE_RATE;
int N_FFT = -1;
enum OVERLAP_OPTIONS {NONE, HALF, THREE_QUARTERS}; //evenutally extend to THREE_QUARTERS
int overlap_amount = NONE;
int overlap_block_counter = 0;
int shift_bins = 0; //how much to shift the frequency
};
#endif