Last active
February 18, 2023 08:53
-
-
Save ayavilevich/8f44c89620612284ebe3f055eba13c6d to your computer and use it in GitHub Desktop.
dsps_view_s16_s3 vs ansi bug demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Hello World Example | |
This example code is in the Public Domain (or CC0 licensed, at your option.) | |
Unless required by applicable law or agreed to in writing, this | |
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
CONDITIONS OF ANY KIND, either express or implied. | |
*/ | |
#include <stdio.h> | |
#include <math.h> | |
#include "sdkconfig.h" | |
#include "freertos/FreeRTOS.h" | |
#include "freertos/task.h" | |
#include "esp_system.h" | |
#include "esp_spi_flash.h" | |
#include "esp_dsp.h" // for dsp lib | |
static const char *TAG = "DSP_TEST"; | |
#define N_TESTS (1024) | |
__attribute__((aligned(16))) float input[N_TESTS]; | |
__attribute__((aligned(16))) int16_t x1_sc16[N_TESTS]; | |
__attribute__((aligned(16))) int16_t x2_sc16[N_TESTS]; | |
__attribute__((aligned(16))) int16_t diff_sc16[N_TESTS]; | |
__attribute__((aligned(16))) int16_t dsps_fft2r_init_sc16_static_buf[CONFIG_DSP_MAX_FFT_SIZE]; | |
void view_vector_s16(int16_t *v, unsigned int s, unsigned int nPrint) | |
{ | |
ESP_LOGI(TAG, "view_vector"); | |
if (s == 0 || s < nPrint) | |
{ | |
ESP_LOGI(TAG, "view_vector, zero len buffer or invalid arg"); | |
return; | |
} | |
// calc stats | |
int16_t minValue = v[0]; | |
int16_t maxValue = v[0]; | |
int sum = v[0]; | |
for (unsigned int i = 1; i < s; i++) | |
{ | |
sum += v[i]; | |
if (v[i] < minValue) | |
{ | |
minValue = v[i]; | |
} | |
if (v[i] > maxValue) | |
{ | |
maxValue = v[i]; | |
} | |
} | |
ESP_LOGI(TAG, "view_vector, s=%u, min=%d, max=%d", s, minValue, maxValue); | |
for (unsigned int i = 0; i < nPrint; i++) | |
{ | |
ESP_LOGI(TAG, "%u: %d", i, v[i]); | |
} | |
ESP_LOGI(TAG, "..."); | |
for (unsigned int i = s - nPrint; i < s; i++) | |
{ | |
ESP_LOGI(TAG, "%u: %d", i, v[i]); | |
} | |
} | |
void test_esp_dsp() | |
{ | |
// init | |
esp_err_t ret; | |
ESP_LOGI(TAG, "Start fft init"); | |
ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE); | |
if (ret != ESP_OK) | |
{ | |
ESP_LOGE(TAG, "Not possible to initialize FFT. Error = %i", ret); | |
return; | |
} | |
// ret = dsps_fft2r_init_sc16(NULL, CONFIG_DSP_MAX_FFT_SIZE); | |
ret = dsps_fft2r_init_sc16(dsps_fft2r_init_sc16_static_buf, CONFIG_DSP_MAX_FFT_SIZE); | |
if (ret != ESP_OK) | |
{ | |
ESP_LOGE(TAG, "Not possible to initialize FFT sc16. Error = %i", ret); | |
return; | |
} | |
// generate input | |
ESP_ERROR_CHECK(dsps_tone_gen_f32(input, N_TESTS, 0.9, 0.05, 0)); | |
ESP_LOGW(TAG, "Signal x1, tone"); | |
dsps_view(input, N_TESTS, 64, 10, -1, 1, '|'); | |
// fake a reals only complex input | |
// not critical to see the issue but provides another way to see it as a real input is expected to have a "mirrored" output and that is not the case with an optimized function | |
// for (int i = 1; i < N_TESTS; i+=2) | |
// { | |
// input[i] = 0; | |
// } | |
// make x1_sc16, x2_sc16 from input | |
for (int i = 0; i < N_TESTS; i++) | |
{ | |
x1_sc16[i] = input[i] * INT16_MAX; | |
x2_sc16[i] = x1_sc16[i]; | |
} | |
ESP_LOGW(TAG, "Signal x1_s16, input"); | |
dsps_view_s16(x1_sc16, N_TESTS, 64, 10, -1, 1, '|'); | |
view_vector_s16(x1_sc16, N_TESTS, 10); | |
ESP_LOGW(TAG, "Signal x2_s16, input"); | |
dsps_view_s16(x2_sc16, N_TESTS, 64, 10, -1, 1, '|'); | |
view_vector_s16(x2_sc16, N_TESTS, 10); | |
// FFT radix-2 sc16 | |
// ESP_ERROR_CHECK(dsps_fft2r_sc16(x1_sc16, N_TESTS >> 1)); | |
ESP_ERROR_CHECK(dsps_fft2r_sc16_aes3(x1_sc16, N_TESTS >> 1)); | |
// ESP_ERROR_CHECK(dsps_fft2r_sc16_ae32(x1_sc16, N_TESTS >> 1)); | |
ESP_ERROR_CHECK(dsps_fft2r_sc16_ansi(x2_sc16, N_TESTS >> 1)); | |
ESP_ERROR_CHECK(dsps_bit_rev_sc16_ansi(x1_sc16, N_TESTS >> 1)); | |
ESP_ERROR_CHECK(dsps_bit_rev_sc16_ansi(x2_sc16, N_TESTS >> 1)); | |
// print result | |
ESP_LOGW(TAG, "Signal x1_s16 (s3), result"); | |
dsps_view_s16(x1_sc16, N_TESTS, 64, 10, -1, 1, '|'); | |
view_vector_s16(x1_sc16, N_TESTS, 10); | |
ESP_LOGW(TAG, "Signal x2_s16 (ansi), result"); | |
dsps_view_s16(x2_sc16, N_TESTS, 64, 10, -1, 1, '|'); | |
view_vector_s16(x2_sc16, N_TESTS, 10); | |
// diff | |
for (int i = 0; i < N_TESTS; i++) | |
{ | |
diff_sc16[i] = fabs(x1_sc16[i] - x2_sc16[i]); | |
} | |
// compare | |
ESP_LOGW(TAG, "Difference between signals x1 and x2 on one plot"); | |
dsps_view_s16(diff_sc16, N_TESTS, 64, 10, 0, 10.0f/INT16_MAX, '-'); | |
view_vector_s16(diff_sc16, N_TESTS, 10); | |
} | |
void app_main(void) | |
{ | |
/* Print chip information */ | |
esp_chip_info_t chip_info; | |
esp_chip_info(&chip_info); | |
printf("This is %s chip with %d CPU core(s), WiFi%s%s, ", | |
CONFIG_IDF_TARGET, | |
chip_info.cores, | |
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", | |
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); | |
printf("silicon revision %d, ", chip_info.revision); | |
printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024), | |
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); | |
printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size()); | |
test_esp_dsp(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment