ESP-IDF Firmware
Firmware architecture and call graph
Loading...
Searching...
No Matches
dsps_snr_f32.cpp
Go to the documentation of this file.
1// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "dsps_snr.h"
16#include "dsps_fft2r.h"
17#include "dsp_common.h"
18#include <math.h>
19#include <limits>
20#include "esp_log.h"
21
22static const char *TAG = "snr";
23
24float dsps_snr_f32(const float *input, int32_t len, uint8_t use_dc)
25{
26 if (!dsp_is_power_of_two(len)) {
27 return 0;
28 }
29
30 float *temp_array = new float[len * 2];
31 for (int i = 0 ; i < len ; i++) {
32 float wind = 0.5 * (1 - cosf(i * 2 * M_PI / (float)len));
33 temp_array[i * 2 + 0] = input[i] * wind;
34 temp_array[i * 2 + 1] = 0;
35 }
37
38 dsps_fft2r_fc32_ansi(temp_array, len);
39 dsps_bit_rev_fc32_ansi(temp_array, len);
40
41 float min = std::numeric_limits<float>::max();
42 float max = std::numeric_limits<float>::min();
43 int max_pos = 0;
44 for (int i = 0 ; i < len / 2 ; i++) {
45 temp_array[i] = temp_array[i * 2 + 0] * temp_array[i * 2 + 0] + temp_array[i * 2 + 1] * temp_array[i * 2 + 1];
46 if (temp_array[i] < min) {
47 min = temp_array[i];
48 }
49 if (temp_array[i] > max) {
50 max = temp_array[i];
51 max_pos = i;
52 }
53 ESP_LOGD(TAG, "FFT Data[%i] =%8.4f dB", i, temp_array[i]);
54 }
55 int start_pos = 0;
56 int wind_width = 7;
57
58 if (use_dc == 0) {
59 start_pos = wind_width;
60 }
61 float noise_power = 0;
62 for (int i = start_pos ; i < len / 2 ; i++) {
63 if ((i < (max_pos - wind_width)) || (i > (max_pos + wind_width))) {
64 noise_power += temp_array[i];
65 ESP_LOGD(TAG, "FFT Data[%i] =%8.4f dB, maX=%f, max_pos=%i, noise_power=%f", i, temp_array[i], max, max_pos, noise_power);
66 }
67 }
68
69 delete[] temp_array;
70 noise_power += std::numeric_limits<float>::min();
71 if (noise_power < max * 0.00000000001) {
72 return 192;
73 }
74 float snr = max / noise_power;
75 float result = 10 * log10(max / noise_power) - 2; // 2 - window correction
76 ESP_LOGI(TAG, "SNR = %f, result=%f dB", snr, result);
77 return result;
78}
bool dsp_is_power_of_two(int x)
check power of two The function check if the argument is power of 2. The implementation use ANSI C an...
#define dsps_fft2r_fc32_ansi(data, N)
Definition dsps_fft2r.h:114
#define CONFIG_DSP_MAX_FFT_SIZE
Definition dsps_fft2r.h:24
esp_err_t dsps_fft2r_init_fc32(float *fft_table_buff, int table_size)
init fft tables
esp_err_t dsps_bit_rev_fc32_ansi(float *data, int N)
bit reverse operation for the complex input array
float dsps_snr_f32(const float *input, int32_t len, uint8_t use_dc)
SNR.
#define M_PI
Definition esp_err.h:26
#define ESP_LOGD
Definition esp_log.h:22
static const char * TAG
Definition main/main.c:31