ProtoTracer  1.0
Real-time 3D rendering and animation engine
Loading...
Searching...
No Matches
MicrophoneFourier_DMA.cpp
Go to the documentation of this file.
2
3ADC* adc = new ADC();
4
5DMAMEM static volatile uint16_t __attribute__((aligned(32))) adc_buffer1[256];
6DMAMEM static volatile uint16_t __attribute__((aligned(32))) adc_buffer2[256];
7
8AnalogBufferDMA adc_dma_instance(adc_buffer1, 256, adc_buffer2, 256);
9bool MicrophoneFourier::microphoneGain_50db = false;
10uint8_t MicrophoneFourier::gain_pin = 0;
11
12// Hanning Window LUT from the Teensy audio library
13const int16_t MicrophoneFourier::Hanning256[] __attribute__((aligned(4))) = {
14 0,
15 5,
16 20,
17 45,
18 80,
19 124,
20 179,
21 243,
22 317,
23 401,
24 495,
25 598,
26 711,
27 833,
28 965,
29 1106,
30 1257,
31 1416,
32 1585,
33 1763,
34 1949,
35 2145,
36 2349,
37 2561,
38 2782,
39 3011,
40 3249,
41 3494,
42 3747,
43 4008,
44 4276,
45 4552,
46 4834,
47 5124,
48 5421,
49 5724,
50 6034,
51 6350,
52 6672,
53 7000,
54 7334,
55 7673,
56 8018,
57 8367,
58 8722,
59 9081,
60 9445,
61 9812,
62 10184,
63 10560,
64 10939,
65 11321,
66 11707,
67 12095,
68 12486,
69 12879,
70 13274,
71 13672,
72 14070,
73 14471,
74 14872,
75 15275,
76 15678,
77 16081,
78 16485,
79 16889,
80 17292,
81 17695,
82 18097,
83 18498,
84 18897,
85 19295,
86 19692,
87 20086,
88 20478,
89 20868,
90 21255,
91 21639,
92 22019,
93 22397,
94 22770,
95 23140,
96 23506,
97 23867,
98 24224,
99 24576,
100 24923,
101 25265,
102 25602,
103 25932,
104 26258,
105 26577,
106 26890,
107 27196,
108 27496,
109 27789,
110 28076,
111 28355,
112 28627,
113 28892,
114 29148,
115 29398,
116 29639,
117 29872,
118 30097,
119 30314,
120 30522,
121 30722,
122 30913,
123 31095,
124 31268,
125 31432,
126 31588,
127 31733,
128 31870,
129 31997,
130 32115,
131 32223,
132 32321,
133 32410,
134 32489,
135 32558,
136 32618,
137 32667,
138 32707,
139 32737,
140 32757,
141 32767,
142 32767,
143 32757,
144 32737,
145 32707,
146 32667,
147 32618,
148 32558,
149 32489,
150 32410,
151 32321,
152 32223,
153 32115,
154 31997,
155 31870,
156 31733,
157 31588,
158 31432,
159 31268,
160 31095,
161 30913,
162 30722,
163 30522,
164 30314,
165 30097,
166 29872,
167 29639,
168 29398,
169 29148,
170 28892,
171 28627,
172 28355,
173 28076,
174 27789,
175 27496,
176 27196,
177 26890,
178 26577,
179 26258,
180 25932,
181 25602,
182 25265,
183 24923,
184 24576,
185 24224,
186 23867,
187 23506,
188 23140,
189 22770,
190 22397,
191 22019,
192 21639,
193 21255,
194 20868,
195 20478,
196 20086,
197 19692,
198 19295,
199 18897,
200 18498,
201 18097,
202 17695,
203 17292,
204 16889,
205 16485,
206 16081,
207 15678,
208 15275,
209 14872,
210 14471,
211 14070,
212 13672,
213 13274,
214 12879,
215 12486,
216 12095,
217 11707,
218 11321,
219 10939,
220 10560,
221 10184,
222 9812,
223 9445,
224 9081,
225 8722,
226 8367,
227 8018,
228 7673,
229 7334,
230 7000,
231 6672,
232 6350,
233 6034,
234 5724,
235 5421,
236 5124,
237 4834,
238 4552,
239 4276,
240 4008,
241 3747,
242 3494,
243 3249,
244 3011,
245 2782,
246 2561,
247 2349,
248 2145,
249 1949,
250 1763,
251 1585,
252 1416,
253 1257,
254 1106,
255 965,
256 833,
257 711,
258 598,
259 495,
260 401,
261 317,
262 243,
263 179,
264 124,
265 80,
266 45,
267 20,
268 5,
269 0,
270};
271
272void MicrophoneFourier::window_raw_fft_data(void* buffer, const void* window) {
273 int16_t* buf = (int16_t*)buffer;
274 const int16_t* win = (int16_t*)window;
275
276 for (int i = 0; i < 256; i++) {
277 int32_t val = *buf * *win++;
278 *buf = val >> 15;
279 buf += 2;
280 }
281}
282
283
284void MicrophoneFourier::SamplerCallback(AnalogBufferDMA* dma_buffer_instance, int8_t adc_num) {
285 uint16_t samplePos = 0;
286 uint16_t samplesStoragePos = 0;
287 volatile uint16_t* data = dma_buffer_instance->bufferLastISRFilled();
288 volatile uint16_t* data_end = data + dma_buffer_instance->bufferCountLastISRFilled();
289
290 // Clear the Data cache so we know we're getting the most up-to-date data
291 if ((uint32_t)data >= 0x20200000u)
292 arm_dcache_delete((void*)data, sizeof(adc_buffer1));
293
294 // Copy DMA Buffer into the storage buffer
295 while (data < data_end) {
296 inputStorage[samplesStoragePos++] = (float)*data;
297 data++;
298 }
299
300 // Clear the QuadTimer Interrupt
301 dma_buffer_instance->clearInterrupt();
302
303 // Window the raw data
305
306 // Interleave Real and Imaginary Numbers into a separate buffer for the FFT DSP
307 samplePos = 0;
308 for (int i = 0; i < 256; i++) {
309 inputSamp[samplePos++] = inputStorage[i];
310 inputSamp[samplePos++] = 0.0f;
311 }
312}
313
314void MicrophoneFourier::Initialize(uint8_t pin, uint32_t sampleRate, float minDB, float maxDB) {
319
320 pinMode(pin, INPUT);
321
322 adc->adc1->setAveraging(32);
323 adc->adc1->setResolution(16);
324 adc->adc1->calibrate();
325 adc->adc1->wait_for_cal();
326
327 adc_dma_instance.init(adc, ADC_1);
328
329 adc->adc1->startSingleRead(pin);
330 adc->adc1->startTimer(sampleRate);
331
332 isInitialized = true;
333}
334
335void MicrophoneFourier::Initialize(uint8_t pin, uint8_t gain_pin, uint32_t sampleRate, float minDB, float maxDB, bool microphoneGain_50db) {
342
343 pinMode(pin, INPUT);
344 pinMode(gain_pin, OUTPUT);
345
346 (!MicrophoneFourier::microphoneGain_50db) ? digitalWrite(gain_pin, 0) : digitalWrite(gain_pin, 1);
347
348 adc->adc1->setAveraging(32);
349 adc->adc1->setResolution(16);
350 adc->adc1->calibrate();
351 adc->adc1->wait_for_cal();
352
353 adc_dma_instance.init(adc, ADC_1);
354
355 adc->adc1->startSingleRead(pin);
356 adc->adc1->startTimer(sampleRate);
357
358 isInitialized = true;
359}
360
361void MicrophoneFourier::setSamplingRate(uint32_t sampleRate) {
362 adc->adc1->stopTimer();
364 adc->adc1->startTimer(sampleRate);
365}
366
369 (!MicrophoneFourier::microphoneGain_50db) ? digitalWrite(gain_pin, 0) : digitalWrite(gain_pin, 1);
370}
371
372
374 if (adc_dma_instance.interrupted()) {
376
379
380 float averageMagnitude = 0.0f;
381
382 for (uint16_t i = 0; i < OutputBins - 1; i++) {
383 float intensity = 20.0f * log10f(AverageMagnitude(i, i + 1));
384
385 intensity = map(intensity, minDB, maxDB, 0.0f, 1.0f);
386
387 outputData[i] = intensity;
388 outputDataFilt[i] = fftFilters[i].Filter(intensity);
389 if (i % 12 == 0)
390 averageMagnitude = peakFilterRate.Filter(inputStorage[i] / 4096.0f);
391 }
392
393 averageMagnitude *= 10.0f;
394 threshold = powf(averageMagnitude, 2.0f);
395 threshold = threshold > 0.2f ? (threshold * 5.0f > 1.0f ? 1.0f : threshold * 5.0f) : 0.0f;
396 }
397}
AnalogBufferDMA adc_dma_instance(adc_buffer1, 256, adc_buffer2, 256)
static DMAMEM volatile uint16_t __attribute__((aligned(32))) adc_buffer1[256]
ADC * adc
Declares the MicrophoneFourier class for performing FFT on microphone input.
float Filter(float value)
Filters the derivative of the input value and normalizes the output.
float Filter(float value)
Filters and normalizes the input value for FFT data processing.
Definition FFTFilter.cpp:9
static void Radix2FFT(float *data)
Performs a Radix-2 FFT on the provided data.
static void ComplexMagnitude(float *complexData, float *magnitude)
Computes the magnitude of complex numbers from interleaved real and imaginary components.
static bool isInitialized
Flag indicating if the system is initialized.
static float inputSamp[FFTSize *2]
Raw input samples for FFT.
static FFT< FFTSize > fft
FFT processor instance.
static FFTFilter fftFilters[OutputBins]
Array of FFT filters for post-processing.
static float threshold
Threshold value for processing.
static float outputData[OutputBins]
Processed FFT data for output bins.
static const uint16_t OutputBins
Number of output bins from FFT processing.
static DerivativeFilter peakFilterRate
Filter for peak rate detection.
static float outputMagn[FFTSize]
Magnitude output from FFT.
static float maxDB
Maximum decibel value for normalization.
static float inputStorage[FFTSize]
Storage for processed input samples.
static uint8_t pin
Pin number for microphone input.
static float outputDataFilt[OutputBins]
Filtered FFT data for output bins.
static float AverageMagnitude(uint16_t binL, uint16_t binH)
Calculates the average magnitude of the specified FFT bins.
static uint16_t sampleRate
Sampling rate in Hz.
static float minDB
Minimum decibel value for normalization.
Provides real-time FFT analysis of microphone signals.
static uint8_t gain_pin
Pin number for gain control (if applicable).
static void setMicGain(bool is50db)
Sets the microphone gain.
static void setSamplingRate(uint32_t sampleRate)
Sets the sampling rate for the microphone.
static void UpdateDMA()
Updates the DMA system to process new samples.
static const int16_t Hanning256[]
Hanning window coefficients for FFT.
static void Initialize(uint8_t pin, uint32_t sampleRate, float minDB, float maxDB)
Initializes the microphone and FFT system with basic parameters.
static void SamplerCallback()
Callback function for the sampling timer.
static void window_raw_fft_data(void *buffer, const void *window)
Applies a Hanning window to raw FFT data.
static bool microphoneGain_50db
Flag to enable or disable 50dB microphone gain.