add some code

This commit is contained in:
2025-09-05 13:25:11 +08:00
parent 9ff0a99e7a
commit 3cf1229a85
8911 changed files with 2535396 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "unity.h"
#include "esp_dsp.h"
#include "dsp_platform.h"
#include "esp_log.h"
#include <malloc.h>
#include "dsps_view.h"
#include "dsps_fft2r.h"
#include "dsp_tests.h"
static const char *TAG = "fft2r_ae32";
__attribute__((aligned(16)))
static float data[1024 * 2];
__attribute__((aligned(16)))
static float check_data[1024 * 2];
TEST_CASE("dsps_fft2r_fc32 functionality", "[dsps]")
{
float *data_test = (float *)memalign(1024, sizeof(float) * 1024 * 2);
TEST_ASSERT_NOT_NULL(data_test);
int N = sizeof(data) / sizeof(float) / 2;
int check_bin = 32;
float check_ampl = 2;
for (int i = 0 ; i < N ; i++) {
data[i * 2 + 0] = check_ampl * sinf(M_PI / N * check_bin * 2 * i) / (N / 2);
data[i * 2 + 1] = 0;
}
for (int i = 0 ; i < N * 2 ; i++) {
check_data[i] = data[i];
data_test[i] = -1;
}
// Init FFT tables
esp_err_t ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
int N_check = N;
dsps_fft2r_fc32(data, N_check);
dsps_fft2r_fc32_ansi(check_data, N_check);
for (int i = 0 ; i < N_check ; i++) {
if (fabs(check_data[i] - data[i]) < 1e-5) {
ESP_LOGD(TAG, "Data[%i] =%8.4f, %8.4f, %8.4f", i, data[i], check_data[i], check_data[i] - data[i]);
} else {
ESP_LOGE(TAG, "Data[%i] =%f, %f, %f", i, data[i], check_data[i], check_data[i] - data[i]);
}
}
dsps_bit_rev_fc32_ansi(data, N);
float min = 10000;
float max = -10000;
int max_pos = 0;
for (int i = 0 ; i < N ; i++) {
data[i] = 10 * log10f(data[i * 2 + 0] * data[i * 2 + 0] + data[i * 2 + 1] * data[i * 2 + 1]);
if (data[i] < min) {
min = data[i];
}
if (data[i] > max) {
max = data[i];
max_pos = i;
}
ESP_LOGD(TAG, "FFT Data[%i] =%8.4f dB", i, data[i]);
}
dsps_view_spectrum(data, 256, -160, 40);
TEST_ASSERT_EQUAL( check_bin, max_pos);
float round_pow = round(max * 10);
TEST_ASSERT_EQUAL( 6 * 10, round_pow);
ESP_LOGI(TAG, "Calculation error is less then 0.1 dB");
dsps_fft2r_deinit_fc32();
free(data_test);
}
TEST_CASE("dsps_fft2r_fc32 benchmark", "[dsps]")
{
esp_err_t ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
asm("test_point1: nop;");
for (int i = 5 ; i < 10 ; i++) {
int N_check = 2 << i;
int check_bin = 32;
for (int i = 0 ; i < N_check ; i++) {
data[i * 2 + 0] = 4 * sinf(M_PI / N_check * check_bin * 2 * i) / (N_check / 2);
data[i * 2 + 1] = 0;
}
unsigned int start_b = dsp_get_cpu_cycle_count();
dsps_fft2r_fc32(data, N_check);
unsigned int end_b = dsp_get_cpu_cycle_count();
float total_b = end_b - start_b;
float cycles = total_b;
ESP_LOGI(TAG, "Benchmark dsps_fft2r_fc32 - %6i cycles for %6i points FFT.", (int)cycles, N_check);
float min_exec = 3;
float max_exec = 330000;
TEST_ASSERT_EXEC_IN_RANGE(min_exec, max_exec, cycles);
}
dsps_fft2r_deinit_fc32();
}
TEST_CASE("dsps_bit_rev2r_fc32_ae32 benchmark", "[dsps]")
{
esp_err_t ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
float *data = (float *)memalign(16, 2 * 4096 * sizeof(float));
TEST_ASSERT_NOT_NULL(data);
float *check_data = (float *)memalign(16, 2 * 4096 * sizeof(float));
TEST_ASSERT_NOT_NULL(check_data);
int N_check = 256;
for (size_t i = 4; i < 13; i++) {
N_check = 1 << i;
for (size_t i = 0; i < N_check * 2; i++) {
data[i] = i;
check_data[i] = i;
}
dsps_bit_rev_fc32_ansi(data, N_check);
unsigned int start_b = dsp_get_cpu_cycle_count();
dsps_bit_rev2r_fc32(data, N_check);
float cycles = dsp_get_cpu_cycle_count() - start_b;
for (size_t i = 0; i < N_check * 2; i++) {
TEST_ASSERT_EQUAL( data[i], check_data[i]);
}
ESP_LOGI(TAG, "Benchmark dsps_bit_rev2r_fc32_ae32 - %6i cycles for %i points.", (int)cycles, N_check);
}
dsps_fft2r_deinit_fc32();
free(data);
free(check_data);
}

View File

@@ -0,0 +1,120 @@
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "unity.h"
#include "esp_dsp.h"
#include "dsp_platform.h"
#include "esp_log.h"
#include <malloc.h>
#include "dsps_view.h"
#include "dsps_fft2r.h"
#include "dsp_tests.h"
static const char *TAG = "dsps_fft2r_ansi";
TEST_CASE("dsps_fft2r_fc32_ansi functionality", "[dsps]")
{
float *data = (float *)malloc(2 * 4096 * sizeof(float));
float *check_data = (float *)malloc(2 * 4096 * sizeof(float));
int N = 1024;
int check_bin = 32;
for (int i = 0 ; i < N ; i++) {
data[i * 2 + 0] = 2 * sinf(M_PI / N * check_bin * 2 * i) / (N / 2);
data[i * 2 + 1] = 0;
}
float *fft_table_buff = (float *)malloc((N + 2) * sizeof(float));
fft_table_buff[0] = 1234;
fft_table_buff[N + 1] = 5678;
esp_err_t ret = dsps_fft2r_init_fc32(&fft_table_buff[1], N);
TEST_ESP_OK(ret);
dsps_fft2r_fc32_ansi(data, N);
unsigned int start_b = dsp_get_cpu_cycle_count();
dsps_bit_rev_fc32_ansi(data, N);
unsigned int end_b = dsp_get_cpu_cycle_count();
float min = 10000;
float max = -10000;
int max_pos = 0;
for (int i = 0 ; i < N ; i++) {
data[i] = 10 * log10f(data[i * 2 + 0] * data[i * 2 + 0] + data[i * 2 + 1] * data[i * 2 + 1]);
if (data[i] < min) {
min = data[i];
}
if (data[i] > max) {
max = data[i];
max_pos = i;
}
ESP_LOGD(TAG, "FFT Data[%i] =%8.4f dB", i, data[i]);
}
dsps_view_spectrum(data, 256, -160, 40);
TEST_ASSERT_EQUAL( check_bin, max_pos);
float round_pow = round(max * 10);
TEST_ASSERT_EQUAL( 6 * 10, round_pow);
ESP_LOGI(TAG, "Calculation error is less then 0.1 dB");
ESP_LOGI(TAG, "cycles - %i", end_b - start_b);
ESP_LOGI(TAG, "fft_table_buff[0] = %f, fft_table_buff[N+1] = %f", fft_table_buff[0], fft_table_buff[N + 1]);
TEST_ASSERT_EQUAL( fft_table_buff[0], 1234);
TEST_ASSERT_EQUAL( fft_table_buff[N + 1], 5678);
free(fft_table_buff);
free(data);
free(check_data);
dsps_fft2r_deinit_fc32();
}
TEST_CASE("dsps_fft2r_fc32_ansi benchmark", "[dsps]")
{
esp_err_t ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
float *data = (float *)malloc(2 * 4096 * sizeof(float));
TEST_ASSERT_NOT_NULL(data);
float *check_data = (float *)malloc(2 * 4096 * sizeof(float));
TEST_ASSERT_NOT_NULL(check_data);
for (int i = 5 ; i < 10 ; i++) {
int N_check = 2 << i;
unsigned int start_b = dsp_get_cpu_cycle_count();
dsps_fft2r_fc32_ansi(data, N_check);
unsigned int end_b = dsp_get_cpu_cycle_count();
float total_b = end_b - start_b;
float cycles = total_b;
ESP_LOGI(TAG, "Benchmark dsps_fft2r_fc32_ansi - %6i cycles for %6i points FFT.", (int)cycles, N_check);
float min_exec = 3;
float max_exec = 330000 * 3;
TEST_ASSERT_EXEC_IN_RANGE(min_exec, max_exec, cycles);
}
free(data);
free(check_data);
dsps_fft2r_deinit_fc32();
}
TEST_CASE("dsps_gen_bitrev2r_table bitrev table generation.", "[dsps]")
{
for (int i = 4 ; i < 13 ; i++) {
int N_check = 1 << i;
dsps_gen_bitrev2r_table(N_check, 8, "fc32");
}
}

View File

@@ -0,0 +1,200 @@
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "unity.h"
#include "esp_dsp.h"
#include "dsp_platform.h"
#include "esp_log.h"
#include <malloc.h>
#include "dsps_view.h"
#include "dsps_fft2r.h"
#include "dsp_tests.h"
static const char *TAG = "dsps_fft2r_ae32_s16";
TEST_CASE("dsps_fft2r_sc16_aexx functionality", "[dsps]")
{
int N = 1024;
int16_t *data = (int16_t *)memalign(N, sizeof(int16_t) * N * 2);
TEST_ASSERT_NOT_NULL(data);
float *result_data = (float *)memalign(N, sizeof(float) * N * 2);
TEST_ASSERT_NOT_NULL(result_data);
int check_bin = 64;
for (int i = 0 ; i < N ; i++) {
data[i * 2 + 0] = (INT16_MAX) * sin(M_PI / N * check_bin * 2 * i) * 0.5 * (1 - cosf(i * 2 * M_PI / (float)(N - 1)));
data[i * 2 + 1] = 0;
}
esp_err_t ret = dsps_fft2r_init_sc16(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
ESP_LOGI(TAG, "data address=%8.8"PRIx32"\n", (uint32_t)data);
dsps_fft2r_sc16(data, N);
unsigned int start_b = dsp_get_cpu_cycle_count();
dsps_bit_rev_sc16_ansi(data, N);
unsigned int end_b = dsp_get_cpu_cycle_count();
for (int i = 0 ; i < N ; i++) {
ESP_LOGD(TAG, "Data[%i] %04x\n", i / 2, data[i]);
}
float min = 10000;
float max = -10000;
int max_pos = 0;
for (int i = 0 ; i < (N * 2) ; i++) {
result_data[i] = data[i];
result_data[i] = result_data[i] / INT16_MAX;
}
for (int i = 0 ; i < N ; i++) {
result_data[i] = 10 * log10f(0.0000000000001 + result_data[i * 2 + 0] * result_data[i * 2 + 0] + result_data[i * 2 + 1] * result_data[i * 2 + 1]);
if (result_data[i] < min) {
min = result_data[i];
}
if (result_data[i] > max) {
max = result_data[i];
max_pos = i;
}
ESP_LOGD(TAG, "FFT Data[%i] =%8.4f dB", i, result_data[i]);
}
dsps_view_spectrum(result_data, N, -100, 0);
float round_pow = round(max * 5);
ESP_LOGI(TAG, "max_bin=%i, check_bin=%i, round_pow=%f\n", max_pos, check_bin, round_pow);
if (max_pos < N / 2) {
TEST_ASSERT_EQUAL( check_bin, max_pos);
} else {
TEST_ASSERT_EQUAL( N - check_bin, max_pos);
}
TEST_ASSERT_EQUAL( -12 * 5, round_pow);
ESP_LOGI(TAG, "Calculation error is less then 0.2 dB");
ESP_LOGI(TAG, "cycles - %i", end_b - start_b);
dsps_fft2r_deinit_sc16();
free(data);
free(result_data);
}
TEST_CASE("dsps_fft2r_sc16_aexx overflow check", "[dsps]")
{
int N = 1024;
int16_t *data = (int16_t *)memalign(N, sizeof(int16_t) * N * 2);
TEST_ASSERT_NOT_NULL(data);
float *result_data = (float *)memalign(N, sizeof(float) * N * 2);
TEST_ASSERT_NOT_NULL(result_data);
int check_bin = 32;
int bins_count = 4;
for (int i = 0 ; i < N ; i++) {
data[i * 2 + 0] = 0;
data[i * 2 + 1] = 0;
for (int n = 1; n <= bins_count ; n++ ) {
data[i * 2 + 0] += (INT16_MAX) * cos(M_PI / N * check_bin * 2 * i * n) / bins_count;
data[i * 2 + 1] += (INT16_MAX) * sin(M_PI / N * check_bin * 2 * i * n) / bins_count;
}
}
esp_err_t ret = dsps_fft2r_init_sc16(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
dsps_fft2r_sc16(data, N);
unsigned int start_b = dsp_get_cpu_cycle_count();
dsps_bit_rev_sc16_ansi(data, N);
unsigned int end_b = dsp_get_cpu_cycle_count();
for (int i = 0 ; i < N ; i++) {
ESP_LOGD(TAG, "Data[%i] %04x\n", i / 2, data[i]);
}
float min = 10000;
float max = -10000;
int max_pos = 0;
for (int i = 0 ; i < (N * 2) ; i++) {
result_data[i] = data[i];
result_data[i] = result_data[i] / INT16_MAX;
}
for (int i = 0 ; i < N ; i++) {
result_data[i] = 10 * log10f(0.0000000000001 + result_data[i * 2 + 0] * result_data[i * 2 + 0] + result_data[i * 2 + 1] * result_data[i * 2 + 1]);
if (result_data[i] < min) {
min = result_data[i];
}
if (result_data[i] > max) {
max = result_data[i];
max_pos = i;
}
ESP_LOGD(TAG, "FFT Data[%i] =%8.4f dB", i, result_data[i]);
}
dsps_view_spectrum(result_data, N, -100, 0);
float round_pow = round(max * 5);
float noise_pow = -100;
for (int i = (bins_count * check_bin + 10) ; i < N ; i++) {
if (result_data[i] > noise_pow) {
noise_pow = result_data[i];
}
}
ESP_LOGI(TAG, "max_bin=%i, check_bin=%i, round_pow=%f, noise power=%f\n", max_pos, check_bin, round_pow, noise_pow);
if (noise_pow > (-65)) {
TEST_ASSERT_MESSAGE (false, "Noise power is more than expected!");
}
ESP_LOGI(TAG, "cycles - %i", end_b - start_b);
dsps_fft2r_deinit_sc16();
free(data);
free(result_data);
}
TEST_CASE("dsps_fft2r_sc16_ae32 benchmark", "[dsps]")
{
int16_t *data = (int16_t *)memalign(1024, sizeof(int16_t) * 1024 * 2);
TEST_ASSERT_NOT_NULL(data);
esp_err_t ret = dsps_fft2r_init_sc16(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
for (int i = 5 ; i < 10 ; i++) {
int N_check = 2 << i;
unsigned int start_b = dsp_get_cpu_cycle_count();
dsps_fft2r_sc16(data, N_check);
unsigned int end_b = dsp_get_cpu_cycle_count();
float total_b = end_b - start_b;
float cycles = total_b;
ESP_LOGI(TAG, "Benchmark dsps_fft2r_sc16_aexx - %6i cycles for %6i points FFT.", (int)cycles, N_check);
float min_exec = 3;
float max_exec = 330000 * 3;
TEST_ASSERT_EXEC_IN_RANGE(min_exec, max_exec, cycles);
}
dsps_fft2r_deinit_sc16();
free(data);
}

View File

@@ -0,0 +1,125 @@
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "unity.h"
#include "esp_dsp.h"
#include "dsp_platform.h"
#include "esp_log.h"
#include <malloc.h>
#include "dsps_view.h"
#include "dsps_fft2r.h"
#include "dsp_tests.h"
static const char *TAG = "dsps_fft2r_ansi_s16";
TEST_CASE("dsps_fft2r_sc16_ansi functionality", "[dsps]")
{
int N = 1024;
int16_t *data = (int16_t *)memalign(N, sizeof(int16_t) * N * 2);
TEST_ASSERT_NOT_NULL(data);
float *result_data = (float *)memalign(N, sizeof(float) * N * 2);
TEST_ASSERT_NOT_NULL(result_data);
int check_bin = 64;
for (int i = 0 ; i < N ; i++) {
data[i * 2 + 0] = (INT16_MAX) * sin(M_PI / N * check_bin * 2 * i) * 0.5 * (1 - cosf(i * 2 * M_PI / (float)(N - 1)));
data[i * 2 + 1] = 0;
}
int16_t *fft_table_buff = (int16_t *)malloc((N + 2) * sizeof(int16_t));
TEST_ASSERT_NOT_NULL(fft_table_buff);
fft_table_buff[0] = 1234;
fft_table_buff[N + 1] = 5678;
esp_err_t ret = dsps_fft2r_init_sc16(&fft_table_buff[1], N);
TEST_ESP_OK(ret);
dsps_fft2r_sc16_ansi(data, N);
unsigned int start_b = dsp_get_cpu_cycle_count();
dsps_bit_rev_sc16_ansi(data, N);
unsigned int end_b = dsp_get_cpu_cycle_count();
for (int i = 0 ; i < N ; i++) {
ESP_LOGD(TAG, "Data[%i] %i\n", i / 2, data[i]);
}
float min = 10000;
float max = -10000;
int max_pos = 0;
for (int i = 0 ; i < (N * 2) ; i++) {
result_data[i] = data[i];
result_data[i] = result_data[i] / INT16_MAX;
}
for (int i = 0 ; i < N ; i++) {
result_data[i] = 10 * log10f(0.0000000000001 + result_data[i * 2 + 0] * result_data[i * 2 + 0] + result_data[i * 2 + 1] * result_data[i * 2 + 1]);
if (result_data[i] < min) {
min = result_data[i];
}
if (result_data[i] > max) {
max = result_data[i];
max_pos = i;
}
ESP_LOGD(TAG, "FFT Data[%i] =%8.4f dB", i, result_data[i]);
}
dsps_view_spectrum(result_data, N, -100, 0);
float round_pow = round(max * 5);
ESP_LOGI(TAG, "max_bin=%i, check_bin=%i, round_pow=%f\n", max_pos, check_bin, round_pow);
if (max_pos < N / 2) {
TEST_ASSERT_EQUAL( check_bin, max_pos);
} else {
TEST_ASSERT_EQUAL( N - check_bin, max_pos);
}
TEST_ASSERT_EQUAL( -12 * 5, round_pow);
ESP_LOGI(TAG, "Calculation error is less then 0.2 dB");
ESP_LOGI(TAG, "cycles - %i", end_b - start_b);
// Check if we not out of range
ESP_LOGI(TAG, "fft_table_buff[0] = %i, fft_table_buff[N+1] = %i", fft_table_buff[0], fft_table_buff[N + 1]);
TEST_ASSERT_EQUAL( fft_table_buff[0], 1234);
TEST_ASSERT_EQUAL( fft_table_buff[N + 1], 5678);
free(fft_table_buff);
dsps_fft2r_deinit_sc16();
free(data);
free(result_data);
}
TEST_CASE("dsps_fft2r_sc16_ansi benchmark", "[dsps]")
{
int16_t *data = (int16_t *)memalign(1024, sizeof(int16_t) * 1024 * 2);
TEST_ASSERT_NOT_NULL(data);
esp_err_t ret = dsps_fft2r_init_sc16(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
for (int i = 5 ; i < 10 ; i++) {
int N_check = 2 << i;
unsigned int start_b = dsp_get_cpu_cycle_count();
dsps_fft2r_sc16_ansi(data, N_check);
unsigned int end_b = dsp_get_cpu_cycle_count();
float total_b = end_b - start_b;
float cycles = total_b;
ESP_LOGI(TAG, "Benchmark dsps_fft2r_sc16_ansi - %6i cycles for %6i points FFT.", (int)cycles, N_check);
float min_exec = 3;
float max_exec = 330000 * 3;
TEST_ASSERT_EXEC_IN_RANGE(min_exec, max_exec, cycles);
}
dsps_fft2r_deinit_sc16();
free(data);
}

View File

@@ -0,0 +1,181 @@
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "unity.h"
#include "esp_dsp.h"
#include "dsp_platform.h"
#include "esp_log.h"
#include <malloc.h>
#include "dsps_view.h"
#include "dsps_fft2r.h"
#include "dsps_fft4r.h"
#include "dsp_tests.h"
#define FFTR4_TEST_SIZE 1024
static const char *TAG = "dsps_fft4r_ae32";
TEST_CASE("dsps_fft4r_fc32 functionality", "[dsps]")
{
float *data = (float *)memalign(16, sizeof(float) * FFTR4_TEST_SIZE * 2);
TEST_ASSERT_NOT_NULL(data);
float *check_data_fft = (float *)memalign(16, sizeof(float) * FFTR4_TEST_SIZE * 2);
TEST_ASSERT_NOT_NULL(check_data_fft);
esp_err_t ret = dsps_fft4r_init_fc32(NULL, FFTR4_TEST_SIZE);
TEST_ESP_OK(ret);
int N_check = 256;
for (size_t pow = 2; pow < 7; pow++) {
N_check = 1 << (pow * 2);
if (N_check > FFTR4_TEST_SIZE) {
break;
}
for (size_t i = 0; i < N_check; i++) {
data[i * 2] = cosf(2 * M_PI * 4 / 256 * i);
data[i * 2 + 1] = sinf(2 * M_PI * 18 / 256 * i);
check_data_fft[i * 2] = data[i * 2];
check_data_fft[i * 2 + 1] = data[i * 2 + 1];
}
dsps_fft4r_fc32_ansi(data, N_check);
dsps_bit_rev4r_fc32(data, N_check);
dsps_fft4r_fc32(check_data_fft, N_check);
dsps_bit_rev4r_fc32(check_data_fft, N_check);
float diff = 0;
for (size_t i = 0; i < N_check * 2; i++) {
diff += fabs(data[i] - check_data_fft[i]);
}
diff = diff / N_check;
if (diff > 0.00001) {
TEST_ASSERT_MESSAGE (false, "Result out of range!\n");
}
ESP_LOGI(TAG, "diff[%i] = %f\n", N_check, diff);
}
if (N_check > FFTR4_TEST_SIZE) {
N_check = FFTR4_TEST_SIZE;
}
dsps_view(data, N_check * 2, 64, 16, -256, 256, '.');
dsps_view(check_data_fft, N_check * 2, 64, 16, -256, 256, '.');
dsps_fft2r_deinit_fc32();
dsps_fft4r_deinit_fc32();
free(data);
free(check_data_fft);
}
static portMUX_TYPE testnlock = portMUX_INITIALIZER_UNLOCKED;
TEST_CASE("dsps_fft4r_fc32 benchmark", "[dsps]")
{
float *check_data_fft = (float *)memalign(16, sizeof(float) * 4096 * 2);
TEST_ASSERT_NOT_NULL(check_data_fft);
unsigned int start_b;
float cycles;
esp_err_t ret = dsps_fft4r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
int N_check = 256;
for (size_t pow = 2; pow < 7; pow++) {
N_check = 1 << (pow * 2);
for (size_t i = 0; i < N_check; i++) {
check_data_fft[i * 2] = cosf(2 * M_PI * 4 / 256 * i);
check_data_fft[i * 2 + 1] = sinf(2 * M_PI * 18 / 256 * i);
}
portENTER_CRITICAL(&testnlock);
start_b = dsp_get_cpu_cycle_count();
dsps_fft4r_fc32(check_data_fft, N_check);
dsps_bit_rev4r_fc32(check_data_fft, N_check);
cycles = dsp_get_cpu_cycle_count() - start_b;
portEXIT_CRITICAL(&testnlock);
ESP_LOGI(TAG, "Benchmark dsps_fft4r_fc32 - %6i cycles for %6i points FFT.", (int)cycles, N_check);
}
dsps_fft4r_deinit_fc32();
free(check_data_fft);
}
TEST_CASE("dsps_cplx2real_fc32 benchmark", "[dsps]")
{
float *check_data_fft = (float *)memalign(16, sizeof(float) * 4096 * 2);
TEST_ASSERT_NOT_NULL(check_data_fft);
unsigned int start_b;
float cycles;
esp_err_t ret = dsps_fft4r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
int N_check = 256;
for (size_t pow = 4; pow < 13; pow++) {
N_check = 1 << (pow);
for (size_t i = 0; i < N_check; i++) {
check_data_fft[i * 2] = cosf(2 * M_PI * 4 / 256 * i);
check_data_fft[i * 2 + 1] = sinf(2 * M_PI * 18 / 256 * i);
}
portENTER_CRITICAL(&testnlock);
start_b = dsp_get_cpu_cycle_count();
dsps_cplx2real_fc32(check_data_fft, N_check);
cycles = dsp_get_cpu_cycle_count() - start_b;
portEXIT_CRITICAL(&testnlock);
ESP_LOGI(TAG, "Benchmark dsps_cplx2real_fc32 - %6i cycles for %6i points FFT.", (int)cycles, N_check);
}
dsps_fft4r_deinit_fc32();
free(check_data_fft);
}
TEST_CASE("dsps_bit_rev4r_fc32_ansi benchmark", "[dsps]")
{
float *check_data_fft = (float *)memalign(16, sizeof(float) * 4096 * 2);
TEST_ASSERT_NOT_NULL(check_data_fft);
unsigned int start_b;
float cycles;
esp_err_t ret = dsps_fft4r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
int N_check = 256;
for (size_t pow = 3; pow < 7; pow++) {
N_check = 1 << (2 * pow);
for (size_t i = 0; i < N_check; i++) {
check_data_fft[i * 2] = cosf(2 * M_PI * 4 / 256 * i);
check_data_fft[i * 2 + 1] = sinf(2 * M_PI * 18 / 256 * i);
}
portENTER_CRITICAL(&testnlock);
start_b = dsp_get_cpu_cycle_count();
dsps_bit_rev4r_fc32(check_data_fft, N_check);
cycles = dsp_get_cpu_cycle_count() - start_b;
portEXIT_CRITICAL(&testnlock);
ESP_LOGI(TAG, "Benchmark dsps_bit_rev4r_fc32_ansi - %6i cycles for %6i points FFT.", (int)cycles, N_check);
}
dsps_fft4r_deinit_fc32();
free(check_data_fft);
}

View File

@@ -0,0 +1,214 @@
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "unity.h"
#include "esp_dsp.h"
#include "dsp_platform.h"
#include "esp_log.h"
#include <malloc.h>
#include "dsps_view.h"
#include "dsps_fft2r.h"
#include "dsps_fft4r.h"
#include "dsp_tests.h"
static const char *TAG = "dsps_fft4r_ansi";
TEST_CASE("dsps_fft4r_fc32_ansi functionality", "[dsps]")
{
float *data = (float *)memalign(16, sizeof(float) * 1024 * 2);
TEST_ASSERT_NOT_NULL(data);
float *check_data_fft = (float *)memalign(16, sizeof(float) * 1024 * 2);
TEST_ASSERT_NOT_NULL(check_data_fft);
esp_err_t ret;
ret = dsps_fft2r_init_fc32(NULL, 1024);
TEST_ESP_OK(ret);
ret = dsps_fft4r_init_fc32(NULL, 1024);
TEST_ESP_OK(ret);
int N_check = 256;
for (size_t pow = 2; pow < 6; pow++) {
N_check = 1 << (pow * 2);
for (size_t i = 0; i < N_check; i++) {
data[i * 2] = cosf(2 * M_PI * 4 / 256 * i);
data[i * 2 + 1] = sinf(2 * M_PI * 18 / 256 * i);
check_data_fft[i * 2] = data[i * 2];
check_data_fft[i * 2 + 1] = data[i * 2 + 1];
}
dsps_fft2r_fc32_ansi(data, N_check);
dsps_bit_rev_fc32_ansi(data, N_check);
dsps_fft4r_fc32_ansi(check_data_fft, N_check);
dsps_bit_rev4r_fc32(check_data_fft, N_check);
float diff = 0;
for (size_t i = 0; i < N_check * 2; i++) {
diff += fabs(data[i] - check_data_fft[i]);
}
diff = diff / N_check;
ESP_LOGI(TAG, "diff[%i] = %f\n", N_check, diff);
if (diff > 0.00001) {
dsps_view(data, N_check * 2, 64, 16, -N_check, N_check, '.');
dsps_view(check_data_fft, N_check * 2, 64, 16, -N_check, N_check, '.');
TEST_ASSERT_MESSAGE (false, "Result out of range!\n");
}
}
dsps_view(data, N_check * 2, 64, 16, -N_check, N_check, '.');
dsps_view(check_data_fft, N_check * 2, 64, 16, -N_check, N_check, '.');
dsps_fft2r_deinit_fc32();
dsps_fft4r_deinit_fc32();
free(data);
free(check_data_fft);
}
TEST_CASE("dsps_fft4r_fc32_ansi benchmark", "[dsps]")
{
float *check_data_fft = (float *)malloc(sizeof(float) * 4096 * 2);
TEST_ASSERT_NOT_NULL(check_data_fft);
unsigned int start_b;
float cycles;
esp_err_t ret = dsps_fft4r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
int N_check = 256;
for (size_t pow = 2; pow < 7; pow++) {
N_check = 1 << (pow * 2);
for (size_t i = 0; i < N_check; i++) {
check_data_fft[i * 2] = cosf(2 * M_PI * 4 / 256 * i);
check_data_fft[i * 2 + 1] = sinf(2 * M_PI * 18 / 256 * i);
}
start_b = dsp_get_cpu_cycle_count();
dsps_fft4r_fc32_ansi(check_data_fft, N_check);
dsps_bit_rev4r_fc32(check_data_fft, N_check);
cycles = dsp_get_cpu_cycle_count() - start_b;
ESP_LOGI(TAG, "Benchmark dsps_fft4r_fc32_ansi - %6i cycles for %6i points FFT.", (int)cycles, N_check);
}
dsps_fft4r_deinit_fc32();
free(check_data_fft);
}
TEST_CASE("dsps_cplx2real_fc32 functionality", "[dsps]")
{
float *data = (float *)malloc(sizeof(float) * 1024 * 2);
TEST_ASSERT_NOT_NULL(data);
float *check_data_fft = (float *)malloc(sizeof(float) * 1024 * 2);
TEST_ASSERT_NOT_NULL(check_data_fft);
esp_err_t ret = dsps_fft4r_init_fc32(NULL, 1024);
TEST_ESP_OK(ret);
ret = dsps_fft2r_init_fc32(NULL, 1024);
TEST_ESP_OK(ret);
int N_check = 256;
for (size_t pow = 4; pow < 11; pow++) {
N_check = 1 << (pow);
for (size_t i = 0; i < N_check * 2; i++) {
data[i] = 0;
check_data_fft[i] = data[i];
}
data[1] = N_check;
check_data_fft[1] = data[1];
dsps_fft2r_fc32_ansi(data, N_check);
dsps_bit_rev_fc32_ansi(data, N_check);
dsps_cplx2real_fc32_ansi(data, N_check);
dsps_fft2r_fc32_ansi(check_data_fft, N_check);
dsps_bit_rev_fc32_ansi(check_data_fft, N_check);
dsps_cplx2real_fc32(check_data_fft, N_check);
float diff = 0;
for (size_t i = 0; i < N_check * 2; i++) {
diff += fabs(data[i] - check_data_fft[i]);
}
diff = diff / N_check;
if (diff > 0.00001) {
for (int i = 0; i < N_check * 2; i++) {
ESP_LOGD(TAG, "data[%i]= %f, %f = check_data_fft[%i], diff=%f\n", i, data[i], check_data_fft[i], i, data[i] - check_data_fft[i]);
}
dsps_view(data, N_check * 2, 128, 16, -N_check, N_check, '.');
dsps_view(check_data_fft, N_check * 2, 128, 16, -N_check, N_check, '.');
ESP_LOGE(TAG, "Error diff[%i] = %f\n", N_check, diff);
TEST_ASSERT_MESSAGE (false, "Result out of range!\n");
}
ESP_LOGI(TAG, "diff[%i] = %f\n", N_check, diff);
}
free(data);
free(check_data_fft);
dsps_fft4r_deinit_fc32();
dsps_fft2r_deinit_fc32();
}
static portMUX_TYPE testnlock = portMUX_INITIALIZER_UNLOCKED;
TEST_CASE("dsps_cplx2real_fc32_ansi benchmark", "[dsps]")
{
float *check_data_fft = (float *)malloc(sizeof(float) * 4096 * 2);
TEST_ASSERT_NOT_NULL(check_data_fft);
unsigned int start_b;
float cycles;
esp_err_t ret = dsps_fft4r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
TEST_ESP_OK(ret);
int N_check = 256;
for (size_t pow = 4; pow < 13; pow++) {
N_check = 1 << (pow);
for (size_t i = 0; i < N_check; i++) {
check_data_fft[i * 2] = cosf(2 * M_PI * 4 / 256 * i);
check_data_fft[i * 2 + 1] = sinf(2 * M_PI * 18 / 256 * i);
}
portENTER_CRITICAL(&testnlock);
start_b = dsp_get_cpu_cycle_count();
dsps_cplx2real_fc32_ansi(check_data_fft, N_check);
cycles = dsp_get_cpu_cycle_count() - start_b;
portEXIT_CRITICAL(&testnlock);
ESP_LOGI(TAG, "Benchmark dsps_cplx2real_fc32_ansi - %6i cycles for %6i points FFT.", (int)cycles, N_check);
}
dsps_fft4r_deinit_fc32();
free(check_data_fft);
}
TEST_CASE("dsps_gen_bitrev4r_table bitrev table generation.", "[dsps]")
{
for (int i = 2 ; i < 7 ; i++) {
int N_check = 1 << (i * 2);
dsps_gen_bitrev4r_table(N_check, 8, "fc32");
}
}