Skip to content

Instantly share code, notes, and snippets.

@ayavilevich
Last active February 18, 2023 08:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ayavilevich/8f44c89620612284ebe3f055eba13c6d to your computer and use it in GitHub Desktop.
Save ayavilevich/8f44c89620612284ebe3f055eba13c6d to your computer and use it in GitHub Desktop.
dsps_view_s16_s3 vs ansi bug demo
/* 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];
}
}
// print
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