107 if (
size > 0 &&
data.data() ==
nullptr) {
108 LOGE(
"Could not resize data");
111 for (
int j = 0; j <
data.size(); j++) {
119 float add_value = value;
120 if (window_function !=
nullptr) {
121 add_value = value * window_function->
factor(pos);
124 data[pos] += add_value;
129 for (
int j = 0; j < stride; j++) {
133 for (
int j = 0; j < stride; j++) {
136 if (result[j] > maxResult) {
137 result[j] = maxResult;
139 if (result[j] < -maxResult) {
140 result[j] = -maxResult;
144 for (
int j = 0; j <
len - stride; j++) {
148 for (
int j =
len - stride; j <
len; j++) {
189 virtual bool setBin(
int idx,
float real,
float img) {
return false; }
222 info.rxtx_mode = mode;
236 if (
cfg.window_function_fft ==
nullptr)
237 cfg.window_function_fft =
cfg.window_function;
238 if (
cfg.window_function_ifft ==
nullptr)
239 cfg.window_function_ifft =
cfg.window_function;
241 if (
cfg.stride == 0)
cfg.stride =
cfg.length;
244 LOGE(
"Len must be of the power of 2: %d",
cfg.length);
248 LOGE(
"Not enough memory");
251 if (
cfg.window_function_fft !=
nullptr) {
252 cfg.window_function_fft->begin(
cfg.length);
254 if (
cfg.window_function_ifft !=
nullptr &&
255 cfg.window_function_ifft !=
cfg.window_function_fft) {
256 cfg.window_function_ifft->begin(
cfg.length);
259 bool is_valid_rxtx =
false;
263 is_valid_rxtx =
true;
269 is_valid_rxtx =
true;
272 if (!is_valid_rxtx) {
273 LOGE(
"Invalid rxtx_mode");
286 if (
cfg.window_function_fft !=
nullptr) {
287 cfg.window_function_fft->begin(
cfg.length);
289 if (
cfg.window_function_ifft !=
nullptr) {
290 cfg.window_function_ifft->begin(
cfg.length);
294 operator bool()
override {
300 cfg.bits_per_sample =
info.bits_per_sample;
301 cfg.sample_rate =
info.sample_rate;
319 size_t write(
const uint8_t *data,
size_t len)
override {
324 size_t samples = frame_bytes > 0 ? len / frame_bytes *
cfg.channels : 0;
325 switch (
cfg.bits_per_sample) {
339 LOGE(
"Unsupported bits_per_sample: %d",
cfg.bits_per_sample);
392 for (
int j = 0; j <
size(); j++) {
407 for (
int j = 0; j < N; j++) {
408 result[j].magnitude = -1000000;
412 for (
int j = 0; j <
size(); j++) {
427 float *
toMEL(
int n_bins,
float min_freq = 0.0f,
float max_freq = 0.0f,
428 bool power =
false) {
429 if (n_bins <= 0) n_bins =
size();
434 for (
int i = 0; i < n_bins; i++) {
437 const float *m = mags + filter.
start_bin;
438 float mel_sum = 0.0f;
439 for (
int j = 0; j < filter.
count; j++) mel_sum += m[j] * weights[j];
453 bool fromMEL(
float *values,
int n_bins,
float min_freq = 0.0f,
454 float max_freq = 0.0f) {
455 if (n_bins <= 0 || values ==
nullptr)
return false;
461 for (
int i = 0; i <
bins; i++) linear_magnitudes[i] = 0.0f;
462 for (
int i = 0; i < n_bins; i++) {
465 for (
int j = 0; j < filter.
count; j++) {
466 linear_magnitudes[filter.
start_bin + j] += values[i] * weights[j];
471 for (
int i = 0; i <
bins; i++) {
474 bin.
real = linear_magnitudes[i];
487 LOGE(
"Invalid bin %d", bin);
490 return static_cast<float>(bin) *
cfg.sample_rate /
cfg.length;
495 int max_freq =
cfg.sample_rate / 2;
496 return map(freq, 0, max_freq, 0,
size());
503 LOGE(
"Invalid bin %d", bin);
511 LOGE(
"Invalid bin %d", bin);
514 return p_driver->magnitudeFast(bin);
521 return atan2(fft_bin.
img, fft_bin.
real);
531 for (
int j = 0; j <
size(); j++) {
544 for (
int j = 0; j <
size(); j++) {
551 bool setBin(
int idx,
float real,
float img) {
553 if (idx < 0 || idx >=
size())
return false;
554 bool rc_first_half =
p_driver->setBin(idx, real, img);
555 bool rc_2nd_half =
p_driver->setBin(
cfg.length - idx, real, img);
556 return rc_first_half && rc_2nd_half;
566 for (
int j = 0; j <
size(); j++) {
575 template <
typename T>
577 return *((T*)
cfg.ref);
605 static float hzToMel(
float hz) {
return 2595.0f * log10f(1.0f + hz / 700.0f); }
607 return 700.0f * (powf(10.0f, mel / 2595.0f) - 1.0f);
612 if (
bins <= 0 ||
cfg.sample_rate <= 0)
return false;
613 if (min_freq <= 0.0f) min_freq =
frequency(0);
620 float min_mel =
hzToMel(min_freq);
621 float mel_step = (
hzToMel(max_freq) - min_mel) / (n_bins + 1);
622 float bin_hz = (float)
cfg.sample_rate /
cfg.length;
627 for (
int i = 0; i < n_bins + 2; i++) edges[i] =
melToHz(min_mel + i * mel_step);
630 for (
int i = 0; i < n_bins; i++) {
633 int first = (int)(edges[i] / bin_hz) + 1;
634 int last = (int)ceilf(edges[i + 2] / bin_hz) - 1;
638 filter.
count = last - first + 1;
642 int j = (int)(edges[i + 1] / bin_hz + 0.5f);
651 for (
int i = 0; i < n_bins; i++) {
654 if (filter.
count == 0) {
659 float left = edges[i], center = edges[i + 1], right = edges[i + 2];
660 for (
int k = 0; k < filter.
count; k++) {
661 float f = (filter.
start_bin + k) * bin_hz;
662 w[k] = f <= center ? (f - left) / (center - left) : (right - f) / (right - center);
677 template <
typename T>
679 T *dataT = (T *)data;
680 if (
cfg.channels == 1) {
683 while (pos < count) {
685 size_t n = count - pos < room ? count - pos : room;
686 stride_buffer.writeArray((uint8_t *)(dataT + pos), n *
sizeof(T));
693 for (
int j = 0; j < count; j +=
cfg.channels) {
694 sample = dataT[j +
cfg.channel_used];
700 template <
typename T>
706 for (
int j = 0; j < sample_count; j++) {
708 p_driver->setValue(j, scale * windowed_sample);
721 template <
typename T>
724 if (
cfg.window_function_fft !=
nullptr) {
725 result =
cfg.window_function_fft->factor(pos) * sample;
730 template <
typename T>
736 if (
cfg.callback !=
nullptr) {
748 for (
int j = 0; j <
cfg.length; j++) {
749 float value =
p_driver->getValue(j);
765 switch (
cfg.bits_per_sample) {
779 LOGE(
"Unsupported bits: %d",
cfg.bits_per_sample);
783 template <
typename T>
785 for (
int j = 0; j < len; j++) {
787 T out_data[
cfg.channels];
788 for (
int ch = 0; ch <
cfg.channels; ch++) {
789 out_data[ch] = sample;
791 int result =
rfft_data.writeArray((uint8_t *)out_data,
sizeof(out_data));
799 return cfg.bits_per_sample == 24 ? (int)
sizeof(
int24_t) :
cfg.bits_per_sample / 8;
806 for (
int j = 0; j < N; j++) {
810 for (
int i = N - 2; i >= j; i--) {
Different Window functions that can be used by FFT.
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