arduino-audio-tools
Loading...
Searching...
No Matches
AudioFFT.h
Go to the documentation of this file.
1#pragma once
2
6
13namespace audio_tools {
14
15// forward declaration
16class AudioFFTBase;
18
24 int bin = 0;
25 float magnitude = 0.0f;
26 float frequency = 0.0f;
27
28 int frequencyAsInt() { return round(frequency); }
29 const char *frequencyAsNote() { return AudioFFTNotes.note(frequency); }
30 const char *frequencyAsNote(float &diff) {
32 }
33};
34
63
65struct FFTBin {
66 float real;
67 float img;
68
69 FFTBin() = default;
70
71 FFTBin(float r, float i) {
72 real = r;
73 img = i;
74 }
75
76 void multiply(float f) {
77 real *= f;
78 img *= f;
79 }
80
81 void conjugate() { img = -img; }
82
83 void clear() { real = img = 0.0f; }
84};
85
88 public:
90 if (size > 0) resize(size);
91 }
92
94 bool resize(size_t size) {
95 // reset max for new scaling
96 rfft_max = 0.0;
97 // define new size
98 len = size;
99 if (!data.resize(size)) {
100 LOGE("Could not resize data");
101 return false;
102 }
103 for (int j = 0; j < data.size(); j++) {
104 data[j] = 0.0;
105 }
106 return true;
107 }
108
109 // adds the values to the array (by applying the window function)
110 void add(float value, int pos, WindowFunction *window_function) {
111 float add_value = value;
112 if (window_function != nullptr) {
113 add_value = value * window_function->factor(pos);
114 }
115 assert(pos < len);
116 data[pos] += add_value;
117 }
118
119 // gets the scaled audio data as result
120 void getStepData(float *result, int stride, float maxResult) {
121 for (int j = 0; j < stride; j++) {
122 // determine max value to scale
123 if (data[j] > rfft_max) rfft_max = data[j];
124 }
125 for (int j = 0; j < stride; j++) {
126 result[j] = data[j] / rfft_max * maxResult;
127 // clip
128 if (result[j] > maxResult) {
129 result[j] = maxResult;
130 }
131 if (result[j] < -maxResult) {
132 result[j] = -maxResult;
133 }
134 }
135 // copy data to head
136 for (int j = 0; j < len - stride; j++) {
137 data[j] = data[j + stride];
138 }
139 // clear tail
140 for (int j = len - stride; j < len; j++) {
141 data[j] = 0.0;
142 }
143 }
144
146 int size() { return data.size(); }
147
148 protected:
150 int len = 0;
151 float rfft_max = 0;
152};
153
161 public:
162 virtual bool begin(int len) = 0;
163 virtual void end() = 0;
165 virtual void setValue(int pos, float value) = 0;
167 virtual void fft() = 0;
169 virtual float magnitude(int idx) = 0;
171 virtual float magnitudeFast(int idx) = 0;
172 virtual bool isValid() = 0;
174 virtual bool isReverseFFT() { return false; }
176 virtual void rfft() { LOGE("Not implemented"); }
178 virtual float getValue(int pos) = 0;
180 virtual bool setBin(int idx, float real, float img) { return false; }
182 bool setBin(int pos, FFTBin &bin) { return setBin(pos, bin.real, bin.img); }
184 virtual bool getBin(int pos, FFTBin &bin) { return false; }
185};
186
195class AudioFFTBase : public AudioStream {
196 public:
200
202
206 info.rxtx_mode = mode;
207 return info;
208 }
209
212 cfg = info;
213 return begin();
214 }
215
217 bool begin() override {
218 bins = cfg.length / 2;
219 // define window functions
220 if (cfg.window_function_fft == nullptr)
222 if (cfg.window_function_ifft == nullptr)
224 // define default stride value if not defined
225 if (cfg.stride == 0) cfg.stride = cfg.length;
226
227 if (!isPowerOfTwo(cfg.length)) {
228 LOGE("Len must be of the power of 2: %d", cfg.length);
229 return false;
230 }
231 if (!p_driver->begin(cfg.length)) {
232 LOGE("Not enough memory");
233 }
234
235 if (cfg.window_function_fft != nullptr) {
237 }
238 if (cfg.window_function_ifft != nullptr &&
241 }
242
243 bool is_valid_rxtx = false;
245 // holds last N bytes that need to be reprocessed
247 is_valid_rxtx = true;
248 }
253 is_valid_rxtx = true;
254 }
255
256 if (!is_valid_rxtx) {
257 LOGE("Invalid rxtx_mode");
258 return false;
259 }
260
261 current_pos = 0;
262 return p_driver->isValid();
263 }
264
266 void reset() {
267 current_pos = 0;
268 if (cfg.window_function_fft != nullptr) {
270 }
271 if (cfg.window_function_ifft != nullptr) {
273 }
274 }
275
276 operator bool() override {
277 return p_driver != nullptr && p_driver->isValid();
278 }
279
287
289 void end() override {
290 p_driver->end();
292 rfft_data.resize(0);
293 rfft_add.resize(0);
294 step_data.resize(0);
295 }
296
298 size_t write(const uint8_t *data, size_t len) override {
299 size_t result = 0;
300 if (p_driver->isValid()) {
301 result = len;
302 switch (cfg.bits_per_sample) {
303 case 8:
304 processSamples<int8_t>(data, len);
305 break;
306 case 16:
307 processSamples<int16_t>(data, len / 2);
308 break;
309 case 24:
310 processSamples<int24_t>(data, len / 3);
311 break;
312 case 32:
313 processSamples<int32_t>(data, len / 4);
314 break;
315 default:
316 LOGE("Unsupported bits_per_sample: %d", cfg.bits_per_sample);
317 break;
318 }
319 }
320 return result;
321 }
322
324 size_t readBytes(uint8_t *data, size_t len) override {
325 TRACED();
326 if (rfft_data.size() == 0) return 0;
327
328 // get data via callback if there is no more data
329 if (cfg.rxtx_mode == RX_MODE && cfg.callback != nullptr &&
330 rfft_data.available() == 0) {
331 cfg.callback(*this);
332 }
333
334 // execute rfft when we consumed all data
335 if (has_rfft_data && rfft_data.available() == 0) {
336 rfft();
337 }
338 return rfft_data.readArray(data, len);
339 }
340
342 int availableForWrite() override {
343 return cfg.length * cfg.channels * bytesPerSample();
344 }
345
347 int available() override {
348 assert(cfg.stride != 0);
349 return cfg.stride * cfg.channels * bytesPerSample();
350 }
351
353 int size() { return bins; }
354
356 int length() { return cfg.length; }
357
360 unsigned long resultTime() { return timestamp; }
362 unsigned long resultTimeBegin() { return timestamp_begin; }
363
367 ret_value.magnitude = 0.0f;
368 ret_value.bin = 0;
369 // find max value and index
370 for (int j = 0; j < size(); j++) {
371 float m = magnitude(j);
372 if (m > ret_value.magnitude) {
373 ret_value.magnitude = m;
374 ret_value.bin = j;
375 }
376 }
377 ret_value.frequency = frequency(ret_value.bin);
378 return ret_value;
379 }
380
382 template <int N>
384 // initialize to negative value
385 for (int j = 0; j < N; j++) {
386 result[j].magnitude = -1000000;
387 }
388 // find top n values
390 for (int j = 0; j < size(); j++) {
392 act.bin = j;
393 act.frequency = frequency(j);
395 }
396 }
397
399 float *toMEL(int n_bins, float min_freq = 0.0f, float max_freq = 0.0f) {
400 // calculate mel bins
401 if (n_bins <= 0) n_bins = size();
402 if (min_freq <= 0.0f) min_freq = frequency(0);
403 if (max_freq <= 0.0f) max_freq = frequency(size() - 1);
405
406 // Convert min and max frequencies to MEL scale
407 float min_mel = 2595.0f * log10(1.0f + (min_freq / 700.0f));
408 float max_mel = 2595.0f * log10(1.0f + (max_freq / 700.0f));
409
410 // Create equally spaced points in the MEL scale
412 mel_points.resize(n_bins + 2); // +2 for the endpoints
413
414 float mel_step = (max_mel - min_mel) / (n_bins + 1);
415 for (int i = 0; i < n_bins + 2; i++) {
416 mel_points[i] = min_mel + i * mel_step;
417 }
418
419 // Convert MEL points back to frequency
422 for (int i = 0; i < n_bins + 2; i++) {
423 freq_points[i] = 700.0f * (pow(10.0f, mel_points[i] / 2595.0f) - 1.0f);
424 }
425
426 // Convert frequency points to FFT bin indices
429 for (int i = 0; i < n_bins + 2; i++) {
431 // Ensure bin index is within valid range
432 if (bin_indices[i] >= bins) bin_indices[i] = bins - 1;
433 if (bin_indices[i] < 0) bin_indices[i] = 0;
434 }
435
436 // Create and apply triangular filters
437 for (int i = 0; i < n_bins; i++) {
438 float mel_sum = 0.0f;
439
440 int start_bin = bin_indices[i];
441 int mid_bin = bin_indices[i + 1];
442 int end_bin = bin_indices[i + 2];
443
444 // Apply first half of triangle filter (ascending)
445 for (int j = start_bin; j < mid_bin; j++) {
446 if (j >= bins) break;
447 float weight = (j - start_bin) / float(mid_bin - start_bin);
448 mel_sum += magnitude(j) * weight;
449 }
450
451 // Apply second half of triangle filter (descending)
452 for (int j = mid_bin; j < end_bin; j++) {
453 if (j >= bins) break;
454 float weight = (end_bin - j) / float(end_bin - mid_bin);
455 mel_sum += magnitude(j) * weight;
456 }
457
458 mel_bins[i] = mel_sum;
459 }
460
461 return mel_bins.data();
462 }
463
471 bool fromMEL(float *values, int n_bins, float min_freq = 0.0f,
472 float max_freq = 0.0f) {
473 if (n_bins <= 0 || values == nullptr) return false;
474
475 // Use default frequency range if not specified
476 if (min_freq <= 0.0f) min_freq = frequency(0);
477 if (max_freq <= 0.0f) max_freq = frequency(size() - 1);
478
479 // Clear the current magnitude array
480 for (int i = 0; i < bins; i++) {
481 FFTBin bin;
482 bin.clear();
483 setBin(i, bin);
484 }
485
486 // Convert min and max frequencies to MEL scale
487 float min_mel = 2595.0f * log10(1.0f + (min_freq / 700.0f));
488 float max_mel = 2595.0f * log10(1.0f + (max_freq / 700.0f));
489
490 // Create equally spaced points in the MEL scale
492 mel_points.resize(n_bins + 2); // +2 for the endpoints
493
494 float mel_step = (max_mel - min_mel) / (n_bins + 1);
495 for (int i = 0; i < n_bins + 2; i++) {
496 mel_points[i] = min_mel + i * mel_step;
497 }
498
499 // Convert MEL points back to frequency
502 for (int i = 0; i < n_bins + 2; i++) {
503 freq_points[i] = 700.0f * (pow(10.0f, mel_points[i] / 2595.0f) - 1.0f);
504 }
505
506 // Convert frequency points to FFT bin indices
509 for (int i = 0; i < n_bins + 2; i++) {
511 // Ensure bin index is within valid range
512 if (bin_indices[i] >= bins) bin_indices[i] = bins - 1;
513 if (bin_indices[i] < 0) bin_indices[i] = 0;
514 }
515
516 // Distribute MEL energy back to linear frequency bins
519
520 for (int i = 0; i < n_bins; i++) {
521 int start_bin = bin_indices[i];
522 int mid_bin = bin_indices[i + 1];
523 int end_bin = bin_indices[i + 2];
524
525 // Apply first half of triangle (ascending)
526 for (int j = start_bin; j < mid_bin; j++) {
527 if (j >= bins) break;
528 float weight = (j - start_bin) / float(mid_bin - start_bin);
529 linear_magnitudes[j] += values[i] * weight;
530 }
531
532 // Apply second half of triangle (descending)
533 for (int j = mid_bin; j < end_bin; j++) {
534 if (j >= bins) break;
535 float weight = (end_bin - j) / float(end_bin - mid_bin);
536 linear_magnitudes[j] += values[i] * weight;
537 }
538 }
539
540 // Set magnitude values and create simple phase (all zeros)
541 for (int i = 0; i < bins; i++) {
542 if (linear_magnitudes[i] > 0) {
543 FFTBin bin;
544 bin.real = linear_magnitudes[i];
545 bin.img = 0.0f;
546 setBin(i, bin);
547 }
548 }
549
550 return true;
551 }
552
555 FFTDriver *driver() { return p_driver; }
556
558 float frequency(int bin) {
559 if (bin >= bins) {
560 LOGE("Invalid bin %d", bin);
561 return 0;
562 }
563 return static_cast<float>(bin) * cfg.sample_rate / cfg.length;
564 }
565
567 int frequencyToBin(int freq) {
568 int max_freq = cfg.sample_rate / 2;
569 return map(freq, 0, max_freq, 0, size());
570 }
571
574 float magnitude(int bin) {
575 if (bin >= bins) {
576 LOGE("Invalid bin %d", bin);
577 return 0;
578 }
579 return p_driver->magnitude(bin);
580 }
581
582 float magnitudeFast(int bin) {
583 if (bin >= bins) {
584 LOGE("Invalid bin %d", bin);
585 return 0;
586 }
587 return p_driver->magnitudeFast(bin);
588 }
589
591 float phase(int bin) {
593 getBin(bin, fft_bin);
594 return atan2(fft_bin.img, fft_bin.real);
595 }
596
599 float *magnitudes() {
600 if (l_magnitudes.size() == 0) {
602 }
603 for (int j = 0; j < size(); j++) {
605 }
606 return l_magnitudes.data();
607 }
608
611 float *magnitudesFast() {
612 if (l_magnitudes.size() == 0) {
614 }
615 for (int j = 0; j < size(); j++) {
617 }
618 return l_magnitudes.data();
619 }
620
622 bool setBin(int idx, float real, float img) {
623 has_rfft_data = true;
624 if (idx < 0 || idx >= size()) return false;
625 bool rc_first_half = p_driver->setBin(idx, real, img);
626 bool rc_2nd_half = p_driver->setBin(cfg.length - idx, real, img);
627 return rc_first_half && rc_2nd_half;
628 }
630 bool setBin(int pos, FFTBin &bin) { return setBin(pos, bin.real, bin.img); }
632 bool getBin(int pos, FFTBin &bin) { return p_driver->getBin(pos, bin); }
633
635 void clearBins() {
636 FFTBin empty{0, 0};
637 for (int j = 0; j < size(); j++) {
638 setBin(j, empty);
639 }
640 }
641
643 AudioFFTConfig &config() { return cfg; }
644
646 template <typename T>
648 return *((T*)cfg.ref);
649 }
650
651 protected:
652 FFTDriver *p_driver = nullptr;
653 int current_pos = 0;
654 int bins = 0;
655 unsigned long timestamp_begin = 0l;
656 unsigned long timestamp = 0l;
664 bool has_rfft_data = false;
665
666 // Add samples to input data p_x - and process them if full
667 template <typename T>
668 void processSamples(const void *data, size_t count) {
669 T *dataT = (T *)data;
670 T sample;
671 for (int j = 0; j < count; j += cfg.channels) {
672 sample = dataT[j + cfg.channel_used];
673 if (writeStrideBuffer((uint8_t *)&sample, sizeof(T))) {
674 // process data if buffer is full
675 T *samples = (T *)stride_buffer.data();
676 int sample_count = stride_buffer.size() / sizeof(T);
677 assert(sample_count == cfg.length);
678 for (int j = 0; j < sample_count; j++) {
679 T out_sample = samples[j];
681 float scaled_sample =
682 1.0f / NumberConverter::maxValueT<T>() * windowed_sample;
684 }
685
686 fft<T>();
687
688 // remove stride samples
690
691 // validate available data in stride buffer
693 }
694 }
695 }
696
697 template <typename T>
698 T windowedSample(T sample, int pos) {
699 T result = sample;
700 if (cfg.window_function_fft != nullptr) {
701 result = cfg.window_function_fft->factor(pos) * sample;
702 }
703 return result;
704 }
705
706 template <typename T>
707 void fft() {
709 p_driver->fft();
710 has_rfft_data = true;
711 timestamp = millis();
712 if (cfg.callback != nullptr) {
713 cfg.callback(*this);
714 }
715 }
716
718 void rfft() {
719 TRACED();
720 // execute reverse fft
721 p_driver->rfft();
722 has_rfft_data = false;
723 // add data to sum buffer
724 for (int j = 0; j < cfg.length; j++) {
725 float value = p_driver->getValue(j);
727 }
728 // get result data from sum buffer
730 }
731
734 // get data to result buffer
735 // for (int j = 0; j < cfg.stride; j++) {
736 // step_data[j] = 0.0;
737 // }
740
741 switch (cfg.bits_per_sample) {
742 case 8:
744 break;
745 case 16:
747 break;
748 case 24:
750 break;
751 case 32:
753 break;
754 default:
755 LOGE("Unsupported bits: %d", cfg.bits_per_sample);
756 }
757 }
758
759 template <typename T>
760 void writeIFFT(float *data, int len) {
761 for (int j = 0; j < len; j++) {
762 T sample = data[j];
764 for (int ch = 0; ch < cfg.channels; ch++) {
765 out_data[ch] = sample;
766 }
768 assert(result == sizeof(out_data));
769 }
770 }
771
772 inline int bytesPerSample() { return cfg.bits_per_sample / 8; }
773
775 template <int N>
777 // find place where we need to insert new record
778 for (int j = 0; j < N; j++) {
779 // insert when biggen then current record
780 if (tmp.magnitude > result[j].magnitude) {
781 // shift existing values right
782 for (int i = N - 2; i >= j; i--) {
783 result[i + 1] = result[i];
784 }
785 // insert new value
786 result[j] = tmp;
787 // stop after we found the correct index
788 break;
789 }
790 }
791 }
792
793 // adds samples to stride buffer, returns true if the buffer is full
794 bool writeStrideBuffer(uint8_t *buffer, size_t len) {
796 stride_buffer.writeArray(buffer, len);
797 return stride_buffer.isFull();
798 }
799
800 bool isPowerOfTwo(uint16_t x) { return (x & (x - 1)) == 0; }
801};
802
803} // namespace audio_tools
long map(long x, long in_min, long in_max, long out_min, long out_max)
Maps input to output values.
Definition Arduino.h:182
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Different Window functions that can be used by FFT.
#define assert(T)
Definition avr.h:10
Executes FFT using audio data privded by write() and/or an inverse FFT where the samples are made ava...
Definition AudioFFT.h:195
unsigned long resultTimeBegin()
time before the fft
Definition AudioFFT.h:362
unsigned long timestamp_begin
Definition AudioFFT.h:655
void clearBins()
clears the fft data
Definition AudioFFT.h:635
float magnitude(int bin)
Definition AudioFFT.h:574
T windowedSample(T sample, int pos)
Definition AudioFFT.h:698
float * magnitudesFast()
Definition AudioFFT.h:611
unsigned long resultTime()
Definition AudioFFT.h:360
bool writeStrideBuffer(uint8_t *buffer, size_t len)
Definition AudioFFT.h:794
int length()
The number of samples.
Definition AudioFFT.h:356
void fft()
Definition AudioFFT.h:707
FFTDriver * p_driver
Definition AudioFFT.h:652
size_t readBytes(uint8_t *data, size_t len) override
Provides the result of a reverse FFT.
Definition AudioFFT.h:324
RingBuffer< uint8_t > rfft_data
Definition AudioFFT.h:663
void writeIFFT(float *data, int len)
Definition AudioFFT.h:760
void end() override
Release the allocated memory.
Definition AudioFFT.h:289
bool has_rfft_data
Definition AudioFFT.h:664
int available() override
Data available for reverse fft.
Definition AudioFFT.h:347
AudioFFTBase(FFTDriver *driver)
Definition AudioFFT.h:199
AudioFFTConfig & config()
Provides the actual configuration.
Definition AudioFFT.h:643
size_t write(const uint8_t *data, size_t len) override
Provide the audio data as FFT input.
Definition AudioFFT.h:298
bool isPowerOfTwo(uint16_t x)
Definition AudioFFT.h:800
FFTDriver * driver()
Definition AudioFFT.h:555
~AudioFFTBase()
Definition AudioFFT.h:201
int frequencyToBin(int freq)
Determine the bin number from the frequency.
Definition AudioFFT.h:567
bool setBin(int idx, float real, float img)
sets the value of a bin
Definition AudioFFT.h:622
int bytesPerSample()
Definition AudioFFT.h:772
int availableForWrite() override
We try to fill the buffer at once.
Definition AudioFFT.h:342
float phase(int bin)
calculates the phase
Definition AudioFFT.h:591
Vector< float > step_data
Definition AudioFFT.h:660
AudioFFTConfig defaultConfig(RxTxMode mode=TX_MODE)
Provides the default configuration.
Definition AudioFFT.h:204
SingleBuffer< uint8_t > stride_buffer
Definition AudioFFT.h:662
T & reference()
Provides the reference pointer.
Definition AudioFFT.h:647
bool fromMEL(float *values, int n_bins, float min_freq=0.0f, float max_freq=0.0f)
Convert MEL spectrum back to linear frequency spectrum.
Definition AudioFFT.h:471
bool begin(AudioFFTConfig info)
starts the processing
Definition AudioFFT.h:211
float * magnitudes()
Definition AudioFFT.h:599
bool getBin(int pos, FFTBin &bin)
gets the value of a bin
Definition AudioFFT.h:632
FFTInverseOverlapAdder rfft_add
Definition AudioFFT.h:658
AudioFFTResult result()
Determines the result values in the max magnitude bin.
Definition AudioFFT.h:365
float frequency(int bin)
Determines the frequency of the indicated bin.
Definition AudioFFT.h:558
int current_pos
Definition AudioFFT.h:653
void rfft()
reverse fft
Definition AudioFFT.h:718
bool setBin(int pos, FFTBin &bin)
sets the value of a bin
Definition AudioFFT.h:630
AudioFFTConfig cfg
Definition AudioFFT.h:657
void insertSorted(AudioFFTResult(&result)[N], AudioFFTResult tmp)
make sure that we do not reuse already found results
Definition AudioFFT.h:776
bool begin() override
starts the processing
Definition AudioFFT.h:217
unsigned long timestamp
Definition AudioFFT.h:656
void setAudioInfo(AudioInfo info) override
Notify change of audio information.
Definition AudioFFT.h:281
void reset()
Just resets the current_pos e.g. to start a new cycle.
Definition AudioFFT.h:266
void processSamples(const void *data, size_t count)
Definition AudioFFT.h:668
float magnitudeFast(int bin)
Definition AudioFFT.h:582
Vector< float > mel_bins
Definition AudioFFT.h:661
void resultArray(AudioFFTResult(&result)[N])
Determines the N biggest result values.
Definition AudioFFT.h:383
float * toMEL(int n_bins, float min_freq=0.0f, float max_freq=0.0f)
Convert the FFT result to MEL spectrum.
Definition AudioFFT.h:399
int size()
The number of bins used by the FFT which are relevant for the result.
Definition AudioFFT.h:353
int bins
Definition AudioFFT.h:654
Vector< float > l_magnitudes
Definition AudioFFT.h:659
void rfftWriteData(BaseBuffer< uint8_t > &data)
write reverse fft result to buffer to make it available for readBytes
Definition AudioFFT.h:733
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:120
AudioInfo info
Definition BaseStream.h:171
Shared functionality of all buffers.
Definition Buffers.h:23
virtual int readArray(T data[], int len)
reads multiple values
Definition Buffers.h:34
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition Buffers.h:56
Abstract Class which defines the basic FFT functionality.
Definition AudioFFT.h:160
virtual float magnitude(int idx)=0
Calculate the magnitude (fft result) at index (sqr(i² + r²))
virtual bool isValid()=0
virtual bool setBin(int idx, float real, float img)
sets the value of a bin
Definition AudioFFT.h:180
virtual void fft()=0
Perform FFT.
virtual float magnitudeFast(int idx)=0
Calculate the magnitude w/o sqare root.
virtual bool isReverseFFT()
Returns true if reverse FFT is supported.
Definition AudioFFT.h:174
virtual void end()=0
virtual void rfft()
Calculate reverse FFT.
Definition AudioFFT.h:176
bool setBin(int pos, FFTBin &bin)
sets the value of a bin
Definition AudioFFT.h:182
virtual void setValue(int pos, float value)=0
Sets the real value.
virtual bool getBin(int pos, FFTBin &bin)
gets the value of a bin
Definition AudioFFT.h:184
virtual float getValue(int pos)=0
Get result value from Reverse FFT.
virtual bool begin(int len)=0
Inverse FFT Overlapp Add.
Definition AudioFFT.h:87
void getStepData(float *result, int stride, float maxResult)
Definition AudioFFT.h:120
Vector< float > data
Definition AudioFFT.h:149
float rfft_max
Definition AudioFFT.h:151
FFTInverseOverlapAdder(int size=0)
Definition AudioFFT.h:89
void add(float value, int pos, WindowFunction *window_function)
Definition AudioFFT.h:110
bool resize(size_t size)
Initilze data by defining new size.
Definition AudioFFT.h:94
int size()
provides the actual size
Definition AudioFFT.h:146
int len
Definition AudioFFT.h:150
Determination of the frequency of a music note.
Definition MusicalNotes.h:125
const char * note(float frequency, float &diff) const
Determines the closes note for a frequency. We also return the frequency difference.
Definition MusicalNotes.h:169
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition AudioTypes.h:297
Implements a typed Ringbuffer.
Definition Buffers.h:353
virtual size_t size() override
Returns the maximum capacity of the buffer.
Definition Buffers.h:440
virtual bool resize(size_t len)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:430
virtual int available() override
provides the number of entries that are available to read
Definition Buffers.h:422
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition Buffers.h:184
size_t size() override
Definition Buffers.h:315
int available() override
provides the number of entries that are available to read
Definition Buffers.h:245
int availableForWrite() override
provides the number of entries that are available to write
Definition Buffers.h:250
bool isFull() override
checks if the buffer is full
Definition Buffers.h:252
int writeArray(const T data[], int len) override
Fills the buffer data.
Definition Buffers.h:213
T * data()
Provides address of actual data.
Definition Buffers.h:296
bool resize(size_t size)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:317
int clearArray(int len) override
consumes len bytes and moves current data to the beginning
Definition Buffers.h:264
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
bool resize(size_t newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
int size()
Definition Vector.h:178
FFT Window Function.
Definition FFTWindows.h:24
virtual void begin(int samples)
Setup the window function providing the fft length.
Definition FFTWindows.h:29
float factor(int idx)
Definition FFTWindows.h:37
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:26
@ RXTX_MODE
Definition AudioTypes.h:26
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
static MusicalNotes AudioFFTNotes
Definition AudioFFT.h:17
uint32_t millis()
Returns the milliseconds since the start.
Definition Arduino.h:256
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
Configuration for AudioFFT. If there are more then 1 channel the channel_used is defining which chann...
Definition AudioFFT.h:40
int stride
Definition AudioFFT.h:51
void * ref
caller
Definition AudioFFT.h:61
WindowFunction * window_function_ifft
Optional window function for ifft only.
Definition AudioFFT.h:57
uint8_t channel_used
Channel which is used as input.
Definition AudioFFT.h:49
WindowFunction * window_function_fft
Optional window function for fft only.
Definition AudioFFT.h:55
WindowFunction * window_function
Optional window function for both fft and ifft.
Definition AudioFFT.h:53
int length
Definition AudioFFT.h:50
void(* callback)(AudioFFTBase &fft)
Callback method which is called after we got a new result.
Definition AudioFFT.h:47
AudioFFTConfig()
Definition AudioFFT.h:41
RxTxMode rxtx_mode
TX_MODE = FFT, RX_MODE = IFFT.
Definition AudioFFT.h:59
Result of the FFT.
Definition AudioFFT.h:23
const char * frequencyAsNote(float &diff)
Definition AudioFFT.h:30
const char * frequencyAsNote()
Definition AudioFFT.h:29
int frequencyAsInt()
Definition AudioFFT.h:28
float magnitude
Definition AudioFFT.h:25
int bin
Definition AudioFFT.h:24
float frequency
Definition AudioFFT.h:26
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
And individual FFT Bin.
Definition AudioFFT.h:65
float real
Definition AudioFFT.h:66
float img
Definition AudioFFT.h:67
void conjugate()
Definition AudioFFT.h:81
FFTBin(float r, float i)
Definition AudioFFT.h:71
void clear()
Definition AudioFFT.h:83
void multiply(float f)
Definition AudioFFT.h:76