first commit

This commit is contained in:
2026-05-22 22:05:03 +03:00
commit 43393d2692
33463 changed files with 9249702 additions and 0 deletions
@@ -0,0 +1,90 @@
// Copyright 2018-2022 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.
#ifndef _dsp_common_H_
#define _dsp_common_H_
#include <stdint.h>
#include <stdbool.h>
#include "dsp_err.h"
#include "esp_idf_version.h"
#if defined(__XTENSA__) || defined(__riscv)
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
#include "esp_cpu.h"
#else
#include "soc/cpu.h"
#endif
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief check power of two
* The function check if the argument is power of 2.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @return
* - true if x is power of two
* - false if no
*/
bool dsp_is_power_of_two(int x);
/**
* @brief Power of two
* The function return power of 2 for values 2^N.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @return
* - power of two
*/
int dsp_power_of_two(int x);
/**
* @brief Logginng for esp32s3 TIE core
* Registers covered q0 to q7, ACCX and SAR_BYTE
*
* @param n_regs: number of registers to be logged at once
* @param ...: register codes 0, 1, 2, 3, 4, 5, 6, 7, 'a', 's'
*
* @return ESP_OK
*
*/
esp_err_t tie_log(int n_regs, ...);
#ifdef __cplusplus
}
#endif
// esp_cpu_get_ccount function is implemented in IDF 4.1 and later
#if defined(__XTENSA__) || defined(__riscv)
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#define dsp_get_cpu_cycle_count esp_cpu_get_cycle_count
#else
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)
#define dsp_get_cpu_cycle_count esp_cpu_get_ccount
#else
#define dsp_get_cpu_cycle_count xthal_get_ccount
#endif
#endif // ESP_IDF_VERSION
#else
// Linux Target
#include <x86intrin.h>
#define dsp_get_cpu_cycle_count __rdtsc
#endif
#endif // _dsp_common_H_
@@ -0,0 +1,23 @@
// 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.
#ifndef _DSP_ERR_H_
#define _DSP_ERR_H_
#include "stdint.h"
#include "esp_err.h"
#include "dsp_err_codes.h"
#endif // _DSP_ERR_H_
@@ -0,0 +1,28 @@
// Copyright 2018-2022 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.
#ifndef _dsp_error_codes_H_
#define _dsp_error_codes_H_
#define DSP_OK 0 // For internal use only. Please use ESP_OK instead
#define ESP_ERR_DSP_BASE 0x70000
#define ESP_ERR_DSP_INVALID_LENGTH (ESP_ERR_DSP_BASE + 1)
#define ESP_ERR_DSP_INVALID_PARAM (ESP_ERR_DSP_BASE + 2)
#define ESP_ERR_DSP_PARAM_OUTOFRANGE (ESP_ERR_DSP_BASE + 3)
#define ESP_ERR_DSP_UNINITIALIZED (ESP_ERR_DSP_BASE + 4)
#define ESP_ERR_DSP_REINITIALIZED (ESP_ERR_DSP_BASE + 5)
#define ESP_ERR_DSP_ARRAY_NOT_ALIGNED (ESP_ERR_DSP_BASE + 6)
#endif // _dsp_error_codes_H_
@@ -0,0 +1,33 @@
// 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.
#ifndef dsp_platform_h_
#define dsp_platform_h_
#include "esp_idf_version.h"
#if defined(__XTENSA__) || defined(__riscv)
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
#include "esp_cpu.h"
#else
#include "soc/cpu.h"
#endif
#endif
#include "freertos/FreeRTOS.h"
#include "freertos/portable.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#endif // dsp_platform_h_
@@ -0,0 +1,38 @@
// 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.
#ifndef _DSP_TESTS_H_
#define _DSP_TESTS_H_
#include <stdlib.h>
#include "esp_idf_version.h"
#include "esp_dsp.h"
#define TEST_ASSERT_EXEC_IN_RANGE(min_exec, max_exec, actual) \
if (actual >= max_exec) { \
ESP_LOGE("", "Time error. Expected max: %i, reached: %i", (int)max_exec, (int)actual);\
TEST_ASSERT_MESSAGE (false, "Exec time takes more than expected! ");\
}\
if (actual < min_exec) {\
ESP_LOGE("", "Time error. Expected min: %i, reached: %i", (int)min_exec, (int)actual);\
TEST_ASSERT_MESSAGE (false, "Exec time takes less then expected!");\
}
// memalign function is implemented in IDF 4.3 and later
#if ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(4, 3, 0)
#define memalign(align_, size_) malloc(size_)
#endif
#endif // _DSP_TESTS_H_
@@ -0,0 +1,36 @@
#ifndef _dsp_types_H_
#define _dsp_types_H_
#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
// union to simplify access to the 16 bit data
typedef union sc16_u {
struct {
int16_t re;
int16_t im;
};
uint32_t data;
} sc16_t;
typedef union fc32_u {
struct {
float re;
float im;
};
uint64_t data;
} fc32_t;
typedef struct image2d_s {
void *data; // could be int8_t, unt8_t, int16_t, unt16_t, float
int step_x; // step of elements by X
int step_y; // step of elements by Y, usually is 1
int stride_x; // stride width: size of the elements in X axis * by step_x + padding
int stride_y; // stride height: size of the elements in Y axis * by step_y + padding
// Point[x,y] = data[width*y*step_y + x*step_x];
// Full data size = width*height
int size_x; // image width
int size_y; // image height
} image2d_t;
#endif // _dsp_types_H_
@@ -0,0 +1,66 @@
// Copyright 2018-2023 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.
#ifndef _esp_dsp_H_
#define _esp_dsp_H_
#ifdef __cplusplus
extern "C"
{
#endif
// Common includes
#include "dsp_common.h"
#include "dsp_types.h"
// Signal processing
#include "dsps_dotprod.h"
#include "dsps_math.h"
#include "dsps_fir.h"
#include "dsps_resampler.h"
#include "dsps_biquad.h"
#include "dsps_biquad_gen.h"
#include "dsps_wind.h"
#include "dsps_conv.h"
#include "dsps_corr.h"
#include "dsps_d_gen.h"
#include "dsps_h_gen.h"
#include "dsps_tone_gen.h"
#include "dsps_snr.h"
#include "dsps_sfdr.h"
#include "dsps_fft2r.h"
#include "dsps_fft4r.h"
#include "dsps_dct.h"
// Matrix operations
#include "dspm_matrix.h"
// Support functions
#include "dsps_view.h"
// Image processing functions:
#include "dspi_dotprod.h"
#include "dspi_conv.h"
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
#include "mat.h"
#endif
#endif // _esp_dsp_H_
@@ -0,0 +1,55 @@
// Copyright 2024 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.
#ifndef _dspi_conv_H_
#define _dspi_conv_H_
#include "dsp_err.h"
#include "dsps_conv_platform.h"
#include "dsp_types.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief 2D Convolution
*
* The function convolve Signal image with Kernel (filter) image.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] in_image: input image
* @param[in] filter: input array with convolution kernel
* @param[out] out_image: output image. The stride and step parameters must be set.
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspi_conv_f32_ansi(const image2d_t *in_image, const image2d_t *filter, image2d_t *out_image);
/**@}*/
#ifdef __cplusplus
}
#endif
#ifdef CONFIG_DSP_OPTIMIZED
#define dspi_conv_f32 dspi_conv_f32_ansi
#else
#define dspi_conv_f32 dspi_conv_f32_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dspi_conv_H_
@@ -0,0 +1,63 @@
// Copyright 2018-2020 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.
#ifndef _dsps_ccorr_H_
#define _dsps_ccorr_H_
#include "dsp_err.h"
#include "dsps_conv_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief Cross correlation
*
* The function make cross correlate between two ignals.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] Signal1: input array with input 1 signal values
* @param[in] siglen1: length of the input 1 signal array
* @param[in] Signal2: input array with input 2 signal values
* @param[in] siglen2: length of the input signal array
* @param corrout: output array with result of cross correlation. The size of dest array must be (siglen1 + siglen2 - 1) !!!
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library (one of the input array are NULL, or if (siglen < patlen))
*/
esp_err_t dsps_ccorr_f32_ansi(const float *Signal, const int siglen, const float *Pattern, const int patlen, float *corrout);
esp_err_t dsps_ccorr_f32_ae32(const float *Signal, const int siglen, const float *Pattern, const int patlen, float *corrout);
/**}@*/
#ifdef __cplusplus
}
#endif
#ifdef CONFIG_DSP_OPTIMIZED
#if (dsps_ccorr_f32_ae32_enabled == 1)
#define dsps_ccorr_f32 dsps_ccorr_f32_ae32
#else
#define dsps_ccorr_f32 dsps_ccorr_f32_ansi
#endif // dsps_ccorr_f32_ae32_enabled
#else
#define dsps_ccorr_f32 dsps_ccorr_f32_ansi
#endif
#endif // _dsps_conv_H_
@@ -0,0 +1,65 @@
// Copyright 2018-2020 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.
#ifndef _dsps_conv_H_
#define _dsps_conv_H_
#include "dsp_err.h"
#include "dsps_conv_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief Convolution
*
* The function convolve Signal array with Kernel array.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] Signal: input array with signal
* @param[in] siglen: length of the input signal
* @param[in] Kernel: input array with convolution kernel
* @param[in] kernlen: length of the Kernel array
* @param convout: output array with convolution result length of (siglen + Kernel -1)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_conv_f32_ae32(const float *Signal, const int siglen, const float *Kernel, const int kernlen, float *convout);
esp_err_t dsps_conv_f32_ansi(const float *Signal, const int siglen, const float *Kernel, const int kernlen, float *convout);
/**@}*/
#ifdef __cplusplus
}
#endif
#ifdef CONFIG_DSP_OPTIMIZED
#if (dsps_conv_f32_ae32_enabled == 1)
#define dsps_conv_f32 dsps_conv_f32_ae32
#else
#define dsps_conv_f32 dsps_conv_f32_ansi
#endif // dsps_conv_f32_ae32_enabled
#else
#define dsps_conv_f32 dsps_conv_f32_ansi
#endif
#endif // _dsps_conv_H_
@@ -0,0 +1,20 @@
#ifndef _dsps_conv_platform_H_
#define _dsps_conv_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dsps_conv_f32_ae32_enabled 1
#define dsps_ccorr_f32_ae32_enabled 1
#define dsps_corr_f32_ae32_enabled 1
#endif
#endif // __XTENSA__
#endif // _dsps_conv_platform_H_
@@ -0,0 +1,63 @@
// Copyright 2018-2020 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.
#ifndef _dsps_corr_H_
#define _dsps_corr_H_
#include "dsp_err.h"
#include "dsps_conv_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief Correlation with pattern
*
* The function correlate input sigla array with pattern array.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] Signal: input array with signal values
* @param[in] siglen: length of the signal array
* @param[in] Pattern: input array with pattern values
* @param[in] patlen: length of the pattern array. The siglen must be bigger then patlen!
* @param dest: output array with result of correlation
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library (one of the input array are NULL, or if (siglen < patlen))
*/
esp_err_t dsps_corr_f32_ansi(const float *Signal, const int siglen, const float *Pattern, const int patlen, float *dest);
esp_err_t dsps_corr_f32_ae32(const float *Signal, const int siglen, const float *Pattern, const int patlen, float *dest);
/**@}*/
#ifdef __cplusplus
}
#endif
#ifdef CONFIG_DSP_OPTIMIZED
#if (dsps_corr_f32_ae32_enabled == 1)
#define dsps_corr_f32 dsps_corr_f32_ae32
#else
#define dsps_corr_f32 dsps_corr_f32_ansi
#endif // dsps_corr_f32_ae32_enabled
#else
#define dsps_corr_f32 dsps_corr_f32_ansi
#endif
#endif // _dsps_corr_H_
@@ -0,0 +1,137 @@
// Copyright 2018-2020 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.
#ifndef _dsps_dct_H_
#define _dsps_dct_H_
#include "dsp_err.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief DCT of radix 2, unscaled
*
* Discrete Cosine Transform type II of radix 2, unscaled
* Function is FFT based
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[inout] data: input/output array with size of N*2. An elements located: Re[0],Re[1], , ... Re[N-1], any data... up to N*2
* result of DCT will be stored to this array from 0...N-1.
* Size of data array must be N*2!!!
* @param[in] N: Size of DCT transform. Size of data array must be N*2!!!
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_dct_f32(float *data, int N);
/**@}*/
/**@{*/
/**
* @brief DCT of radix 2, type IV, unscaled
*
* Discrete Cosine Transform type IV of radix 2, unscaled
* Function is FFT based
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[inout] data: input/output array with size of N. An elements located: Re[0],Re[1], , ... Re[N-1]
* result of DST will be stored to this array from 0...N-1.
* Size of data array must be N
* @param[in] N: Size of DCT transform. Size of data array must be N
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_dctiv_f32(float *data, int N);
/**@}*/
/**@{*/
/**
* @brief DST of radix 2, type IV, unscaled
*
* Discrete Sine Transform type IV of radix 2, unscaled
* Function is FFT based
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[inout] data: input/output array with size of N*2. An elements located: Re[0],Re[1], , ... Re[N-1]
* result of DST will be stored to this array from 0...N-1.
* Size of data array must be N
* @param[in] N: Size of DST transform. Size of data array must be N
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_dstiv_f32(float *data, int N);
/**@}*/
/**@{*/
/**
* @brief Inverce DCT of radix 2
*
* Inverce Discrete Cosine Transform type II of radix 2, unscaled
* Function is FFT based
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[inout] data: input/output array with size of N*2. An elements located: Re[0],Re[1], , ... Re[N-1], any data... up to N*2
* result of DCT will be stored to this array from 0...N-1.
* Size of data array must be N*2!!!
* @param[in] N: Size of DCT transform. Size of data array must be N*2!!!
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_dct_inv_f32(float *data, int N);
/**@}*/
/**@{*/
/**
* @brief DCTs
*
* Direct DCT type II and Inverce DCT type III, unscaled
* These functions used as a reference for general purpose. These functions are not optimyzed!
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] data: input/output array with size of N. An elements located: Re[0],Re[1], , ... Re[N-1]
* @param[in] N: Size of DCT transform. Size of data array must be N*2!!!
* @param[out] result: output result array with size of N.
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_dct_f32_ref(float *data, int N, float *result);
esp_err_t dsps_dct_inverce_f32_ref(float *data, int N, float *result);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif // _dsps_dct_H_
@@ -0,0 +1,191 @@
// 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.
#ifndef _dspi_dotprod_H_
#define _dspi_dotprod_H_
#include "esp_log.h"
#include "dsp_err.h"
#include "dsp_types.h"
#include "dspi_dotprod_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief dot product of two images
* Dot product calculation for two floating point images: *out_value += image[i*...] * src2[i*...]); i= [0..count_x*count_y)
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] in_image descriptor of the image
* @param[in] filter descriptor of the filter
* @param[out] out_value pointer to the output value
* @param[in] count_x amount of samples by X axis (count_x*step_X <= widdth)
* @param[in] count_y amount of samples by Y axis (count_y*step_Y <= height)
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspi_dotprod_f32_ansi(image2d_t *in_image, image2d_t *filter, float *out_value, int count_x, int count_y);
/**@}*/
/**@{*/
/**
* @brief dot product of two images
* Dot product calculation for two floating point images: *out_value += image[i*...] * src2[i*...]); i= [0..count_x*count_y)
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] in_image descriptor of the image
* @param[in] filter descriptor of the filter
* @param[out] out_value pointer to the output value
* @param[in] count_x amount of samples by X axis (count_x*step_X <= widdth)
* @param[in] count_y amount of samples by Y axis (count_y*step_Y <= height)
* @param[in] shift - result shift to right, by default must be 15 for int16_t or 7 for int8_t
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspi_dotprod_s16_ansi(image2d_t *in_image, image2d_t *filter, int16_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_u16_ansi(image2d_t *in_image, image2d_t *filter, uint16_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_s8_ansi(image2d_t *in_image, image2d_t *filter, int8_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_u8_ansi(image2d_t *in_image, image2d_t *filter, uint8_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_s16_aes3(image2d_t *in_image, image2d_t *filter, int16_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_u16_aes3(image2d_t *in_image, image2d_t *filter, uint16_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_s8_aes3(image2d_t *in_image, image2d_t *filter, int8_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_u8_aes3(image2d_t *in_image, image2d_t *filter, uint8_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_s16_arp4(image2d_t *in_image, image2d_t *filter, int16_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_s8_arp4(image2d_t *in_image, image2d_t *filter, int8_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_u16_arp4(image2d_t *in_image, image2d_t *filter, uint16_t *out_value, int count_x, int count_y, int shift);
esp_err_t dspi_dotprod_u8_arp4(image2d_t *in_image, image2d_t *filter, uint8_t *out_value, int count_x, int count_y, int shift);
/**@}*/
/**@{*/
/**
* @brief dot product of two images with input offset
* Dot product calculation for two floating point images: *out_value += (image[i*...] + offset) * src2[i*...]); i= [0..count_x*count_y)
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] in_image descriptor of the image
* @param[in] filter descriptor of the filter
* @param[out] out_value pointer to the output value
* @param[in] count_x amount of samples by X axis (count_x*step_X <= widdth)
* @param[in] count_y amount of samples by Y axis (count_y*step_Y <= height)
* @param[in] offset - input offset value.
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspi_dotprod_off_f32_ansi(image2d_t *in_image, image2d_t *filter, float *out_value, int count_x, int count_y, float offset);
/**@}*/
/**@{*/
/**
* @brief dot product of two images with input offset
* Dot product calculation for two floating point images: *out_value += (image[i*...] + offset) * src2[i*...]); i= [0..count_x*count_y)
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] in_image descriptor of the image
* @param[in] filter descriptor of the filter
* @param[out] out_value pointer to the output value
* @param[in] count_x amount of samples by X axis (count_x*step_X <= widdth)
* @param[in] count_y amount of samples by Y axis (count_y*step_Y <= height)
* @param[in] shift - result shift to right, by default must be 15 for int16_t or 7 for int8_t
* @param[in] offset - input offset value.
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspi_dotprod_off_s16_ansi(image2d_t *in_image, image2d_t *filter, int16_t *out_value, int count_x, int count_y, int shift, int16_t offset);
esp_err_t dspi_dotprod_off_u16_ansi(image2d_t *in_image, image2d_t *filter, uint16_t *out_value, int count_x, int count_y, int shift, uint16_t offset);
esp_err_t dspi_dotprod_off_s8_ansi(image2d_t *in_image, image2d_t *filter, int8_t *out_value, int count_x, int count_y, int shift, int8_t offset);
esp_err_t dspi_dotprod_off_u8_ansi(image2d_t *in_image, image2d_t *filter, uint8_t *out_value, int count_x, int count_y, int shift, uint8_t offset);
esp_err_t dspi_dotprod_off_s16_aes3(image2d_t *in_image, image2d_t *filter, int16_t *out_value, int count_x, int count_y, int shift, int16_t offset);
esp_err_t dspi_dotprod_off_u16_aes3(image2d_t *in_image, image2d_t *filter, uint16_t *out_value, int count_x, int count_y, int shift, uint16_t offset);
esp_err_t dspi_dotprod_off_s8_aes3(image2d_t *in_image, image2d_t *filter, int8_t *out_value, int count_x, int count_y, int shift, int8_t offset);
esp_err_t dspi_dotprod_off_u8_aes3(image2d_t *in_image, image2d_t *filter, uint8_t *out_value, int count_x, int count_y, int shift, uint8_t offset);
esp_err_t dspi_dotprod_off_s16_arp4(image2d_t *in_image, image2d_t *filter, int16_t *out_value, int count_x, int count_y, int shift, int16_t offset);
esp_err_t dspi_dotprod_off_u16_arp4(image2d_t *in_image, image2d_t *filter, uint16_t *out_value, int count_x, int count_y, int shift, uint16_t offset);
esp_err_t dspi_dotprod_off_s8_arp4(image2d_t *in_image, image2d_t *filter, int8_t *out_value, int count_x, int count_y, int shift, int8_t offset);
esp_err_t dspi_dotprod_off_u8_arp4(image2d_t *in_image, image2d_t *filter, uint8_t *out_value, int count_x, int count_y, int shift, uint8_t offset);
/**@}*/
#ifdef __cplusplus
}
#endif
#ifdef CONFIG_DSP_OPTIMIZED
#define dspi_dotprod_f32 dspi_dotprod_f32_ansi
#define dspi_dotprod_off_f32 dspi_dotprod_off_f32_ansi
#if (dspi_dotprod_aes3_enabled == 1)
#define dspi_dotprod_s16 dspi_dotprod_s16_aes3
#define dspi_dotprod_u16 dspi_dotprod_u16_aes3
#define dspi_dotprod_s8 dspi_dotprod_s8_aes3
#define dspi_dotprod_u8 dspi_dotprod_u8_aes3
#define dspi_dotprod_off_s16 dspi_dotprod_off_s16_aes3
#define dspi_dotprod_off_s8 dspi_dotprod_off_s8_aes3
#define dspi_dotprod_off_u16 dspi_dotprod_off_u16_aes3
#define dspi_dotprod_off_u8 dspi_dotprod_off_u8_aes3
#elif (dspi_dotprod_arp4_enabled == 1)
#define dspi_dotprod_s16 dspi_dotprod_s16_arp4
#define dspi_dotprod_s8 dspi_dotprod_s8_arp4
#define dspi_dotprod_u16 dspi_dotprod_u16_arp4
#define dspi_dotprod_u8 dspi_dotprod_u8_arp4
#define dspi_dotprod_off_s16 dspi_dotprod_off_s16_arp4
#define dspi_dotprod_off_s8 dspi_dotprod_off_s8_arp4
#define dspi_dotprod_off_u16 dspi_dotprod_off_u16_arp4
#define dspi_dotprod_off_u8 dspi_dotprod_off_u8_arp4
#else
#define dspi_dotprod_s16 dspi_dotprod_s16_ansi
#define dspi_dotprod_s8 dspi_dotprod_s8_ansi
#define dspi_dotprod_u16 dspi_dotprod_u16_ansi
#define dspi_dotprod_u8 dspi_dotprod_u8_ansi
#define dspi_dotprod_off_s16 dspi_dotprod_off_s16_ansi
#define dspi_dotprod_off_s8 dspi_dotprod_off_s8_ansi
#define dspi_dotprod_off_u16 dspi_dotprod_off_u16_ansi
#define dspi_dotprod_off_u8 dspi_dotprod_off_u8_ansi
#endif
#endif
#ifdef CONFIG_DSP_ANSI
#define dspi_dotprod_f32 dspi_dotprod_f32_ansi
#define dspi_dotprod_off_f32 dspi_dotprod_off_f32_ansi
#define dspi_dotprod_s16 dspi_dotprod_s16_ansi
#define dspi_dotprod_s8 dspi_dotprod_s8_ansi
#define dspi_dotprod_off_s16 dspi_dotprod_off_s16_ansi
#define dspi_dotprod_off_s8 dspi_dotprod_off_s8_ansi
#define dspi_dotprod_u16 dspi_dotprod_u16_ansi
#define dspi_dotprod_u8 dspi_dotprod_u8_ansi
#define dspi_dotprod_off_u16 dspi_dotprod_off_u16_ansi
#define dspi_dotprod_off_u8 dspi_dotprod_off_u8_ansi
#endif
#endif // _dspi_dotprod_H_
@@ -0,0 +1,24 @@
#ifndef _dspi_dotprod_platform_H_
#define _dspi_dotprod_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if CONFIG_IDF_TARGET_ESP32S3
#define dspi_dotprod_aes3_enabled 1
#endif
#endif // __XTENSA__
#if CONFIG_IDF_TARGET_ESP32P4
#ifdef CONFIG_DSP_OPTIMIZED
#define dspi_dotprod_arp4_enabled 1
#else
#define dspi_dotprod_arp4_enabled 0
#endif
#endif
#endif // _dspi_dotprod_platform_H_
@@ -0,0 +1,128 @@
// 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.
#ifndef _DSPI_DOTPROD_H_
#define _DSPI_DOTPROD_H_
#include "esp_log.h"
#include "dsp_err.h"
#include "dsps_dotprod_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
// These functions calculates dotproduct of two vectors.
/**@{*/
/**
* @brief dot product of two 16 bit vectors
* Dot product calculation for two signed 16 bit arrays: *dest += (src1[i] * src2[i]) >> (15-shift); i= [0..N)
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] src1 source array 1
* @param[in] src2 source array 2
* @param dest destination pointer
* @param[in] len length of input arrays
* @param[in] shift shift of the result.
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_dotprod_s16_ansi(const int16_t *src1, const int16_t *src2, int16_t *dest, int len, int8_t shift);
esp_err_t dsps_dotprod_s16_ae32(const int16_t *src1, const int16_t *src2, int16_t *dest, int len, int8_t shift);
esp_err_t dsps_dotprod_s16_arp4(const int16_t *src1, const int16_t *src2, int16_t *dest, int len, int8_t shift);
/**@}*/
/**@{*/
/**
* @brief dot product of two float vectors
* Dot product calculation for two floating point arrays: *dest += (src1[i] * src2[i]); i= [0..N)
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] src1 source array 1
* @param[in] src2 source array 2
* @param dest destination pointer
* @param[in] len length of input arrays
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_dotprod_f32_ansi(const float *src1, const float *src2, float *dest, int len);
esp_err_t dsps_dotprod_f32_ae32(const float *src1, const float *src2, float *dest, int len);
esp_err_t dsps_dotprod_f32_aes3(const float *src1, const float *src2, float *dest, int len);
esp_err_t dsps_dotprod_f32_arp4(const float *src1, const float *src2, float *dest, int len);
/**@}*/
/**@{*/
/**
* @brief dot product of two float vectors with step
* Dot product calculation for two floating point arrays: *dest += (src1[i*step1] * src2[i*step2]); i= [0..N)
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] src1 source array 1
* @param[in] src2 source array 2
* @param dest destination pointer
* @param[in] len length of input arrays
* @param[in] step1 step over elements in first array
* @param[in] step2 step over elements in second array
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_dotprode_f32_ansi(const float *src1, const float *src2, float *dest, int len, int step1, int step2);
esp_err_t dsps_dotprode_f32_ae32(const float *src1, const float *src2, float *dest, int len, int step1, int step2);
esp_err_t dsps_dotprode_f32_arp4(const float *src1, const float *src2, float *dest, int len, int step1, int step2);
/**@}*/
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dsps_dotprod_s16_ae32_enabled == 1)
#define dsps_dotprod_s16 dsps_dotprod_s16_ae32
#elif (dsps_dotprod_s16_arp4_enabled == 1)
#define dsps_dotprod_s16 dsps_dotprod_s16_arp4
#else
#define dsps_dotprod_s16 dsps_dotprod_s16_ansi
#endif // dsps_dotprod_s16_ae32_enabled
#if (dsps_dotprod_f32_aes3_enabled == 1)
#define dsps_dotprod_f32 dsps_dotprod_f32_aes3
#define dsps_dotprode_f32 dsps_dotprode_f32_ae32
#elif (dsps_dotprod_f32_arp4_enabled == 1)
#define dsps_dotprod_f32 dsps_dotprod_f32_arp4
#define dsps_dotprode_f32 dsps_dotprode_f32_arp4
#elif (dotprod_f32_ae32_enabled == 1)
#define dsps_dotprod_f32 dsps_dotprod_f32_ae32
#define dsps_dotprode_f32 dsps_dotprode_f32_ae32
#else
#define dsps_dotprod_f32 dsps_dotprod_f32_ansi
#define dsps_dotprode_f32 dsps_dotprode_f32_ansi
#endif // dsps_dotprod_f32_ae32_enabled
#else // CONFIG_DSP_OPTIMIZED
#define dsps_dotprod_s16 dsps_dotprod_s16_ansi
#define dsps_dotprod_f32 dsps_dotprod_f32_ansi
#define dsps_dotprode_f32 dsps_dotprode_f32_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _DSPI_DOTPROD_H_
@@ -0,0 +1,42 @@
#ifndef _dsps_dotprod_platform_H_
#define _dsps_dotprod_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dotprod_f32_ae32_enabled 1
#define dotprode_f32_ae32_enabled 1
#endif //
#if ((XCHAL_HAVE_LOOPS == 1) && (XCHAL_HAVE_MAC16 == 1))
#define dsps_dotprod_s16_ae32_enabled 1
#endif //
#endif // __XTENSA__
#if CONFIG_IDF_TARGET_ESP32S3
#define dsps_dotprod_s16_aes3_enabled 1
#define dsps_dotprod_f32_aes3_enabled 1
#endif
#if CONFIG_IDF_TARGET_ESP32P4
#ifdef CONFIG_DSP_OPTIMIZED
#define dsps_dotprod_s16_arp4_enabled 1
#define dsps_dotprod_f32_arp4_enabled 1
#else
#define dsps_dotprod_s16_arp4_enabled 0
#define dsps_dotprod_f32_arp4_enabled 0
#endif // CONFIG_DSP_OPTIMIZED
#endif
#endif // _dsps_dotprod_platform_H_
@@ -0,0 +1,257 @@
// 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.
#ifndef _dsps_fft2r_H_
#define _dsps_fft2r_H_
#include "dsp_err.h"
#include "sdkconfig.h"
#include "dsps_fft_tables.h"
#include "dsps_fft2r_platform.h"
#ifndef CONFIG_DSP_MAX_FFT_SIZE
#define CONFIG_DSP_MAX_FFT_SIZE 4096
#endif // CONFIG_DSP_MAX_FFT_SIZE
#ifdef __cplusplus
extern "C"
{
#endif
extern float *dsps_fft_w_table_fc32;
extern int dsps_fft_w_table_size;
extern uint8_t dsps_fft2r_initialized;
extern int16_t *dsps_fft_w_table_sc16;
extern int dsps_fft_w_table_sc16_size;
extern uint8_t dsps_fft2r_sc16_initialized;
/**@{*/
/**
* @brief init fft tables
*
* Initialization of Complex FFT. This function initialize coefficients table.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[inout] fft_table_buff: pointer to floating point buffer where sin/cos table will be stored
* if this parameter set to NULL, and table_size value is more then 0, then
* dsps_fft2r_init_fc32 will allocate buffer internally
* @param[in] table_size: size of the buffer in float words
* if fft_table_buff is NULL and table_size is not 0, buffer will be allocated internally.
* If table_size is 0, buffer will not be allocated.
*
* @return
* - ESP_OK on success
* - ESP_ERR_DSP_PARAM_OUTOFRANGE if table_size > CONFIG_DSP_MAX_FFT_SIZE
* - ESP_ERR_DSP_REINITIALIZED if buffer already allocated internally by other function
* - One of the error codes from DSP library
*/
esp_err_t dsps_fft2r_init_fc32(float *fft_table_buff, int table_size);
esp_err_t dsps_fft2r_init_sc16(int16_t *fft_table_buff, int table_size);
/**@}*/
/**@{*/
/**
* @brief deinit fft tables
*
* Free resources of Complex FFT. This function delete coefficients table if it was allocated by dsps_fft2r_init_fc32.
* The implementation use ANSI C and could be compiled and run on any platform
*
*/
void dsps_fft2r_deinit_fc32(void);
void dsps_fft2r_deinit_sc16(void);
/**@}*/
/**@{*/
/**
* @brief complex FFT of radix 2
*
* Complex FFT of radix 2
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[inout] data: input/output complex array. An elements located: Re[0], Im[0], ... Re[N-1], Im[N-1]
* result of FFT will be stored to this array.
* @param[in] N: Number of complex elements in input array
* @param[in] w: pointer to the sin/cos table
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_fft2r_fc32_ansi_(float *data, int N, float *w);
esp_err_t dsps_fft2r_fc32_ae32_(float *data, int N, float *w);
esp_err_t dsps_fft2r_fc32_aes3_(float *data, int N, float *w);
esp_err_t dsps_fft2r_fc32_arp4_(float *data, int N, float *w);
esp_err_t dsps_fft2r_sc16_ansi_(int16_t *data, int N, int16_t *w);
esp_err_t dsps_fft2r_sc16_ae32_(int16_t *data, int N, int16_t *w);
esp_err_t dsps_fft2r_sc16_aes3_(int16_t *data, int N, int16_t *w);
esp_err_t dsps_fft2r_sc16_arp4_(int16_t *data, int N, int16_t *w);
/**@}*/
// This is workaround because linker generates permanent error when assembler uses
// direct access to the table pointer
#define dsps_fft2r_fc32_ae32(data, N) dsps_fft2r_fc32_ae32_(data, N, dsps_fft_w_table_fc32)
#define dsps_fft2r_fc32_aes3(data, N) dsps_fft2r_fc32_aes3_(data, N, dsps_fft_w_table_fc32)
#define dsps_fft2r_fc32_arp4(data, N) dsps_fft2r_fc32_arp4_(data, N, dsps_fft_w_table_fc32)
#define dsps_fft2r_sc16_ae32(data, N) dsps_fft2r_sc16_ae32_(data, N, dsps_fft_w_table_sc16)
#define dsps_fft2r_sc16_aes3(data, N) dsps_fft2r_sc16_aes3_(data, N, dsps_fft_w_table_sc16)
#define dsps_fft2r_sc16_arp4(data, N) dsps_fft2r_sc16_arp4_(data, N, dsps_fft_w_table_sc16)
#define dsps_fft2r_fc32_ansi(data, N) dsps_fft2r_fc32_ansi_(data, N, dsps_fft_w_table_fc32)
#define dsps_fft2r_sc16_ansi(data, N) dsps_fft2r_sc16_ansi_(data, N, dsps_fft_w_table_sc16)
/**@{*/
/**
* @brief bit reverse operation for the complex input array
*
* Bit reverse operation for the complex input array
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[inout] data: input/ complex array. An elements located: Re[0], Im[0], ... Re[N-1], Im[N-1]
* result of FFT will be stored to this array.
* @param[in] N: Number of complex elements in input array
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_bit_rev_fc32_ansi(float *data, int N);
esp_err_t dsps_bit_rev_sc16_ansi(int16_t *data, int N);
esp_err_t dsps_bit_rev2r_fc32(float *data, int N);
/**@}*/
esp_err_t dsps_bit_rev_lookup_fc32_ansi(float *data, int reverse_size, uint16_t *reverse_tab);
esp_err_t dsps_bit_rev_lookup_fc32_ae32(float *data, int reverse_size, uint16_t *reverse_tab);
esp_err_t dsps_bit_rev_lookup_fc32_aes3(float *data, int reverse_size, uint16_t *reverse_tab);
/**@{*/
/**
* @brief Generate coefficients table for the FFT radix 2
*
* Generate coefficients table for the FFT radix 2. This function called inside init.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[inout] w: memory location to store coefficients.
* By default coefficients will be stored to the dsps_fft_w_table_fc32.
* Maximum size of the FFT must be setup in menuconfig
* @param[in] N: maximum size of the FFT that will be used
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_gen_w_r2_fc32(float *w, int N);
esp_err_t dsps_gen_w_r2_sc16(int16_t *w, int N);
/**@}*/
/**@{*/
/**
* @brief Convert complex array to two real arrays
*
* Convert complex array to two real arrays in case if input was two real arrays.
* This function have to be used if FFT used to process real data.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[inout] data: Input complex array and result of FFT2R.
* input has size of 2*N, because contains real and imaginary part.
* result will be stored to the same array.
* Input1: input[0..N-1], Input2: input[N..2*N-1]
* @param[in] N: Number of complex elements in input array
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_cplx2reC_fc32_ansi(float *data, int N);
esp_err_t dsps_cplx2reC_sc16(int16_t *data, int N);
/**@}*/
/**@{*/
/**
* @brief Convert complex FFT result to real array
*
* Convert FFT result of complex FFT for resl input to real array.
* This function have to be used if FFT used to process real data.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[inout] data: Input complex array and result of FFT2R.
* input has size of 2*N, because contains real and imaginary part.
* result will be stored to the same array.
* Input1: input[0..N-1], Input2: input[N..2*N-1]
* @param[in] N: Number of complex elements in input array
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_cplx2real_sc16_ansi(int16_t *data, int N);
/**@}*/
esp_err_t dsps_cplx2real256_fc32_ansi(float *data);
esp_err_t dsps_gen_bitrev2r_table(int N, int step, char *name_ext);
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#define dsps_bit_rev_fc32 dsps_bit_rev_fc32_ansi
#define dsps_cplx2reC_fc32 dsps_cplx2reC_fc32_ansi
#if (dsps_fft2r_fc32_aes3_enabled == 1)
#define dsps_fft2r_fc32 dsps_fft2r_fc32_aes3
#elif (dsps_fft2r_fc32_ae32_enabled == 1)
#define dsps_fft2r_fc32 dsps_fft2r_fc32_ae32
#elif (dsps_fft2r_fc32_arp4_enabled == 1)
#define dsps_fft2r_fc32 dsps_fft2r_fc32_arp4
#else
#define dsps_fft2r_fc32 dsps_fft2r_fc32_ansi
#endif
#if (dsps_fft2r_sc16_aes3_enabled == 1)
#define dsps_fft2r_sc16 dsps_fft2r_sc16_aes3
#elif (dsps_fft2r_sc16_ae32_enabled == 1)
#define dsps_fft2r_sc16 dsps_fft2r_sc16_ae32
#elif (dsps_fft2r_sc16_arp4_enabled == 1)
#define dsps_fft2r_sc16 dsps_fft2r_sc16_arp4
#else
#define dsps_fft2r_sc16 dsps_fft2r_sc16_ansi
#endif
#if (dsps_bit_rev_lookup_fc32_ae32_enabled == 1)
#if (dsps_fft2r_fc32_aes3_enabled)
#define dsps_bit_rev_lookup_fc32 dsps_bit_rev_lookup_fc32_aes3
#else
#define dsps_bit_rev_lookup_fc32 dsps_bit_rev_lookup_fc32_ae32
#endif // dsps_fft2r_fc32_aes3_enabled
#else
#define dsps_bit_rev_lookup_fc32 dsps_bit_rev_lookup_fc32_ansi
#endif
#else // CONFIG_DSP_OPTIMIZED
#define dsps_fft2r_fc32 dsps_fft2r_fc32_ansi
#define dsps_bit_rev_fc32 dsps_bit_rev_fc32_ansi
#define dsps_cplx2reC_fc32 dsps_cplx2reC_fc32_ansi
#define dsps_bit_rev_sc16 dsps_bit_rev_sc16_ansi
#define dsps_bit_rev_lookup_fc32 dsps_bit_rev_lookup_fc32_ansi
#define dsps_fft2r_sc16 dsps_fft2r_sc16_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dsps_fft2r_H_
@@ -0,0 +1,44 @@
#ifndef _dsps_fft2r_platform_H_
#define _dsps_fft2r_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dsps_fft2r_fc32_ae32_enabled 1
#endif //
#if ((XCHAL_HAVE_LOOPS == 1) && (XCHAL_HAVE_MAC16 == 1))
#define dsps_fft2r_sc16_ae32_enabled 1
#endif //
#if (XCHAL_HAVE_LOOPS == 1)
#define dsps_bit_rev_lookup_fc32_ae32_enabled 1
#endif //
#endif // __XTENSA__
#if CONFIG_IDF_TARGET_ESP32S3
#define dsps_fft2r_fc32_aes3_enabled 1
#define dsps_fft2r_sc16_aes3_enabled 1
#endif
#if CONFIG_IDF_TARGET_ESP32P4
#ifdef CONFIG_DSP_OPTIMIZED
#define dsps_fft2r_fc32_arp4_enabled 1
#define dsps_fft2r_sc16_arp4_enabled 1
#else
#define dsps_fft2r_fc32_arp4_enabled 0
#define dsps_fft2r_sc16_arp4_enabled 0
#endif // CONFIG_DSP_OPTIMIZED
#endif
#endif // _dsps_fft2r_platform_H_
@@ -0,0 +1,188 @@
// 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.
#ifndef _dsps_fft4r_H_
#define _dsps_fft4r_H_
#include "dsp_err.h"
#include "sdkconfig.h"
#include "dsps_fft_tables.h"
#include "dsps_fft4r_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
extern float *dsps_fft4r_w_table_fc32;
extern int dsps_fft4r_w_table_size;
extern uint8_t dsps_fft4r_initialized;
extern int16_t *dsps_fft4r_w_table_sc16;
extern int dsps_fft4r_w_table_sc16_size;
extern uint8_t dsps_fft4r_sc16_initialized;
/**@{*/
/**
* @brief init fft tables
*
* Initialization of Complex FFT Radix-4. This function initialize coefficients table.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[inout] fft_table_buff: pointer to floating point buffer where sin/cos table will be stored
* if this parameter set to NULL, and table_size value is more then 0, then
* dsps_fft4r_init_fc32 will allocate buffer internally
* @param[in] max_fft_size: maximum fft size. The buffer for sin/cos table that will be used for radix-4 it's
* four times maximum length of FFT.
* if fft_table_buff is NULL and table_size is not 0, buffer will be allocated internally.
* If table_size is 0, buffer will not be allocated.
*
* @return
* - ESP_OK on success
* - ESP_ERR_DSP_PARAM_OUTOFRANGE if table_size > CONFIG_DSP_MAX_FFT_SIZE
* - ESP_ERR_DSP_REINITIALIZED if buffer already allocated internally by other function
* - One of the error codes from DSP library
*/
esp_err_t dsps_fft4r_init_fc32(float *fft_table_buff, int max_fft_size);
/**@}*/
/**@{*/
/**
* @brief deinit fft tables
*
* Free resources of Complex FFT Radix-4. This function delete coefficients table if it was allocated by dsps_fft4r_init_fc32.
* The implementation use ANSI C and could be compiled and run on any platform
*
*
*/
void dsps_fft4r_deinit_fc32(void);
/**@}*/
/**@{*/
/**
* @brief complex FFT of radix 4
*
* Complex FFT of radix 4
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[inout] data: input/output complex array. An elements located: Re[0], Im[0], ... Re[N-1], Im[N-1]
* result of FFT will be stored to this array.
* @param[in] N: Number of complex elements in input array
* @param[in] table: pointer to sin/cos table
* @param[in] table_size: size of the sin/cos table
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_fft4r_fc32_ansi_(float *data, int N, float *table, int table_size);
esp_err_t dsps_fft4r_fc32_ae32_(float *data, int N, float *table, int table_size);
esp_err_t dsps_fft4r_fc32_aes3_(float *data, int N, float *table, int table_size);
esp_err_t dsps_fft4r_fc32_arp4_(float *data, int N, float *table, int table_size);
/**@}*/
// This is workaround because linker generates permanent error when assembler uses
// direct access to the table pointer
#define dsps_fft4r_fc32_ansi(data, N) dsps_fft4r_fc32_ansi_(data, N, dsps_fft4r_w_table_fc32, dsps_fft4r_w_table_size)
#define dsps_fft4r_fc32_ae32(data, N) dsps_fft4r_fc32_ae32_(data, N, dsps_fft4r_w_table_fc32, dsps_fft4r_w_table_size)
#define dsps_fft4r_fc32_aes3(data, N) dsps_fft4r_fc32_aes3_(data, N, dsps_fft4r_w_table_fc32, dsps_fft4r_w_table_size)
#define dsps_fft4r_fc32_arp4(data, N) dsps_fft4r_fc32_arp4_(data, N, dsps_fft4r_w_table_fc32, dsps_fft4r_w_table_size/(N))
/**@{*/
/**
* @brief bit reverse operation for the complex input array radix-4
*
* Bit reverse operation for the complex input array
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[inout] data: input/ complex array. An elements located: Re[0], Im[0], ... Re[N-1], Im[N-1]
* result of FFT will be stored to this array.
* @param[in] N: Number of complex elements in input array
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_bit_rev4r_fc32(float *data, int N);
esp_err_t dsps_bit_rev4r_fc32_ae32(float *data, int N);
esp_err_t dsps_bit_rev4r_direct_fc32_ansi(float *data, int N);
esp_err_t dsps_bit_rev4r_sc16_ansi(int16_t *data, int N);
/**@}*/
/**@{*/
/**
* @brief Convert FFT result to complex array for real input data
*
* Convert FFT result of complex FFT for real input to complex output.
* This function have to be used if FFT used to process real data.
* This function use tabels inside and can be used only it dsps_fft4r_init_fc32(...) was
* called and FFT4 was initialized.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[inout] data: Input complex array and result of FFT2R/FFT4R.
* input has size of 2*N, because contains real and imaginary part.
* result will be stored to the same array.
* Input1: input[0..N-1] if the result is complex Re[0], Im[0]....Re[N-1], Im[N-1],
* and input[0...2*n-1] if result is real re[0], re[1],...,re[2*N-1].
* @param[in] N: Number of complex elements in input array
* @param[in] table: pointer to sin/cos table
* @param[in] table_size: size of the sin/cos table
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_cplx2real_fc32_ansi_(float *data, int N, float *table, int table_size);
esp_err_t dsps_cplx2real_fc32_ae32_(float *data, int N, float *table, int table_size);
/**@}*/
#define dsps_cplx2real_fc32_ansi(data, N) dsps_cplx2real_fc32_ansi_(data, N, dsps_fft4r_w_table_fc32, dsps_fft4r_w_table_size)
#define dsps_cplx2real_fc32_ae32(data, N) dsps_cplx2real_fc32_ae32_(data, N, dsps_fft4r_w_table_fc32, dsps_fft4r_w_table_size)
esp_err_t dsps_gen_bitrev4r_table(int N, int step, char *name_ext);
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dsps_fft4r_fc32_ae32_enabled == 1)
#define dsps_fft4r_fc32 dsps_fft4r_fc32_ae32
#elif (dsps_fft4r_fc32_aes3_enabled == 1)
#define dsps_fft4r_fc32 dsps_fft4r_fc32_aes3
#elif (dsps_fft4r_fc32_arp4_enabled == 1)
#define dsps_fft4r_fc32 dsps_fft4r_fc32_arp4
#else
#define dsps_fft4r_fc32 dsps_fft4r_fc32_ansi
#endif // dsps_fft4r_fc32_ae32_enabled
#define dsps_fft4r_sc16 dsps_fft4r_sc16_ae32
#define dsps_bit_rev4r_fc32 dsps_bit_rev4r_fc32_ae32
#if (dsps_cplx2real_fc32_ae32_enabled == 1)
#define dsps_cplx2real_fc32 dsps_cplx2real_fc32_ae32
#else
#define dsps_cplx2real_fc32 dsps_cplx2real_fc32_ansi
#endif // dsps_cplx2real_fc32_ae32_enabled
#else
#define dsps_fft4r_fc32 dsps_fft4r_fc32_ansi
#define dsps_fft4r_sc16 dsps_fft4r_sc16_ansi
#define dsps_bit_rev4r_fc32 dsps_bit_rev4r_fc32
#define dsps_cplx2real_fc32 dsps_cplx2real_fc32_ansi
#endif
#endif // _dsps_fft4r_H_
@@ -0,0 +1,55 @@
#ifndef _dsps_fft4r_platform_H_
#define _dsps_fft4r_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dsps_cplx2real_fc32_ae32_enabled 1
#endif //
#if ((XCHAL_HAVE_LOOPS == 1) && (XCHAL_HAVE_MAC16 == 1))
#define dsps_fft2r_sc16_ae32_enabled 1
#endif //
#if (XCHAL_HAVE_LOOPS == 1)
#define dsps_bit_rev_lookup_fc32_ae32_enabled 1
#endif //
#endif // __XTENSA__
#if CONFIG_IDF_TARGET_ESP32P4
#ifdef CONFIG_DSP_OPTIMIZED
#define dsps_fft4r_fc32_arp4_enabled 1
#else // CONFIG_DSP_OPTIMIZED
#define dsps_fft4r_fc32_arp4_enabled 0
#endif // CONFIG_DSP_OPTIMIZED
#endif
#if CONFIG_IDF_TARGET_ESP32
#ifdef CONFIG_DSP_OPTIMIZED
#define dsps_fft4r_fc32_ae32_enabled 1
#else // CONFIG_DSP_OPTIMIZED
#define dsps_fft4r_fc32_ae32_enabled 0
#endif // CONFIG_DSP_OPTIMIZED
#endif
#if CONFIG_IDF_TARGET_ESP32S3
#ifdef CONFIG_DSP_OPTIMIZED
#define dsps_fft4r_fc32_aes3_enabled 1
#else // CONFIG_DSP_OPTIMIZED
#define dsps_fft4r_fc32_aes3_enabled 0
#endif // CONFIG_DSP_OPTIMIZED
#endif
#endif // _dsps_fft4r_platform_H_
@@ -0,0 +1,89 @@
// 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.
#ifndef _dsps_fft_tables_H_
#define _dsps_fft_tables_H_
#ifdef __cplusplus
extern "C"
{
#endif
extern const uint16_t bitrev2r_table_16_fc32[];
extern const uint16_t bitrev2r_table_16_fc32_size;
extern const uint16_t bitrev2r_table_32_fc32[];
extern const uint16_t bitrev2r_table_32_fc32_size;
extern const uint16_t bitrev2r_table_64_fc32[];
extern const uint16_t bitrev2r_table_64_fc32_size;
extern const uint16_t bitrev2r_table_128_fc32[];
extern const uint16_t bitrev2r_table_128_fc32_size;
extern const uint16_t bitrev2r_table_256_fc32[];
extern const uint16_t bitrev2r_table_256_fc32_size;
extern const uint16_t bitrev2r_table_512_fc32[];
extern const uint16_t bitrev2r_table_512_fc32_size;
extern const uint16_t bitrev2r_table_1024_fc32[];
extern const uint16_t bitrev2r_table_1024_fc32_size;
extern const uint16_t bitrev2r_table_2048_fc32[];
extern const uint16_t bitrev2r_table_2048_fc32_size;
extern const uint16_t bitrev2r_table_4096_fc32[];
extern const uint16_t bitrev2r_table_4096_fc32_size;
void dsps_fft2r_rev_tables_init_fc32(void);
extern uint16_t *dsps_fft2r_rev_tables_fc32[];
extern const uint16_t dsps_fft2r_rev_tables_fc32_size[];
extern const uint16_t bitrev4r_table_16_fc32[];
extern const uint16_t bitrev4r_table_16_fc32_size;
extern const uint16_t bitrev4r_table_32_fc32[];
extern const uint16_t bitrev4r_table_32_fc32_size;
extern const uint16_t bitrev4r_table_64_fc32[];
extern const uint16_t bitrev4r_table_64_fc32_size;
extern const uint16_t bitrev4r_table_128_fc32[];
extern const uint16_t bitrev4r_table_128_fc32_size;
extern const uint16_t bitrev4r_table_256_fc32[];
extern const uint16_t bitrev4r_table_256_fc32_size;
extern const uint16_t bitrev4r_table_512_fc32[];
extern const uint16_t bitrev4r_table_512_fc32_size;
extern const uint16_t bitrev4r_table_1024_fc32[];
extern const uint16_t bitrev4r_table_1024_fc32_size;
extern const uint16_t bitrev4r_table_2048_fc32[];
extern const uint16_t bitrev4r_table_2048_fc32_size;
extern const uint16_t bitrev4r_table_4096_fc32[];
extern const uint16_t bitrev4r_table_4096_fc32_size;
void dsps_fft4r_rev_tables_init_fc32(void);
extern uint16_t *dsps_fft4r_rev_tables_fc32[];
extern const uint16_t dsps_fft4r_rev_tables_fc32_size[];
#ifdef __cplusplus
}
#endif
#endif // _dsps_fft_tables_H_
@@ -0,0 +1,386 @@
/*
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _dsps_fir_H_
#define _dsps_fir_H_
#include "dsp_err.h"
#include "dsps_fir_platform.h"
#include "dsp_common.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Data struct of f32 fir filter
*
* This structure is used by a filter internally. A user should access this structure only in case of
* extensions for the DSP Library.
* All fields of this structure are initialized by the dsps_fir_init_f32(...) function.
*/
typedef struct fir_f32_s {
float *coeffs; /*!< Pointer to the coefficient buffer.*/
float *delay; /*!< Pointer to the delay line buffer.*/
int N; /*!< FIR filter coefficients amount.*/
int pos; /*!< Position in delay line.*/
int decim; /*!< Decimation factor.*/
int16_t use_delay; /*!< The delay line was allocated by init function.*/
/**
* @brief Interpolation parameters
*
* @note This is used for multi-rate FIR filter
*/
int delay_size; /*!< Size of the delay line.*/
int interp; /*!< Interpolation factor.*/
int interp_pos; /*!< Interpolation position.*/
int start_pos; /*!< Start position for decimation counter.*/
} fir_f32_t;
/**
* @brief Data struct of s16 fir filter
*
* This structure is used by a filter internally. A user should access this structure only in case of
* extensions for the DSP Library.
* All fields of this structure are initialized by the dsps_fir_init_s16(...) function.
*/
typedef struct fir_s16_s {
int16_t *coeffs; /*!< Pointer to the coefficient buffer.*/
int16_t *delay; /*!< Pointer to the delay line buffer.*/
int16_t coeffs_len; /*!< FIR filter coefficients amount.*/
int16_t pos; /*!< Position in delay line.*/
int16_t decim; /*!< Decimation factor.*/
int16_t d_pos; /*!< Actual decimation counter.*/
int16_t shift; /*!< Shift value of the result.*/
int32_t *rounding_buff; /*!< Rounding buffer for the purposes of esp32s3 ee.ld.accx.ip assembly instruction */
int32_t rounding_val; /*!< Rounding value*/
int16_t free_status; /*!< Indicator for dsps_fird_s16_aes3_free() function*/
/**
* @brief Interpolation parameters
*
* @note This is used for multi-rate FIR filter
*/
int16_t delay_size; /*!< Size of the delay line.*/
int16_t interp; /*!< Interpolation factor.*/
int16_t interp_pos; /*!< Interpolation position.*/
int16_t start_pos; /*!< Start position for decimation counter.*/
} fir_s16_t;
/**
* @brief initialize structure for 32 bit FIR filter
*
* Function initialize structure for 32 bit floating point FIR filter
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param fir: pointer to fir filter structure, that must be preallocated
* @param coeffs: array with FIR filter coefficients. Must be length N
* @param delay: array for FIR filter delay line. Must have a length = coeffs_len + 4
* @param coeffs_len: FIR filter length. Length of coeffs array. For esp32s3 length should be divided by 4 and aligned to 16.
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_fir_init_f32(fir_f32_t *fir, float *coeffs, float *delay, int coeffs_len);
/**
* @brief initialize structure for 32 bit Decimation FIR filter
* Function initialize structure for 32 bit floating point FIR filter with decimation
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param fir: pointer to fir filter structure, that must be preallocated
* @param coeffs: array with FIR filter coefficients. Must be length N
* @param delay: array for FIR filter delay line. Must be length N
* @param N: FIR filter length. Length of coeffs and delay arrays.
* @param decim: decimation factor.
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_fird_init_f32(fir_f32_t *fir, float *coeffs, float *delay, int N, int decim);
/**
* @brief initialize structure for 16 bit Decimation FIR filter
* Function initialize structure for 16 bit signed fixed point FIR filter with decimation
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param fir: pointer to fir filter structure, that must be preallocated
* @param coeffs: array with FIR filter coefficients. Must be length N
* @param delay: array for FIR filter delay line. Must be length N
* @param coeffs_len: FIR filter length. Length of coeffs and delay arrays.
* @param decim: decimation factor.
* @param start_pos: initial value of decimation counter. Must be [0..d)
* @param shift: shift position of the result
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_fird_init_s16(fir_s16_t *fir, int16_t *coeffs, int16_t *delay, int16_t coeffs_len, int16_t decim, int16_t start_pos, int16_t shift);
/**@{*/
/**
* @brief 32 bit floating point FIR filter
*
* Function implements FIR filter
* The extension (_ansi) uses ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param fir: pointer to fir filter structure, that must be initialized before
* @param[in] input: input array
* @param[out] output: array with the result of FIR filter
* @param[in] len: length of input and result arrays
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_fir_f32_ansi(fir_f32_t *fir, const float *input, float *output, int len);
esp_err_t dsps_fir_f32_ae32(fir_f32_t *fir, const float *input, float *output, int len);
esp_err_t dsps_fir_f32_aes3(fir_f32_t *fir, const float *input, float *output, int len);
/**@}*/
/**@{*/
/**
* @brief 32 bit floating point Decimation FIR filter
*
* Function implements FIR filter with decimation
* The extension (_ansi) uses ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param fir: pointer to fir filter structure, that must be initialized before
* @param input: input array
* @param output: array with the result of FIR filter
* @param len: length of result array
*
* @return: function returns the number of samples stored in the output array
* depends on the previous state value could be [0..len/decimation]
*/
int dsps_fird_f32_ansi(fir_f32_t *fir, const float *input, float *output, int len);
int dsps_fird_f32_ae32(fir_f32_t *fir, const float *input, float *output, int len);
int dsps_fird_f32_aes3(fir_f32_t *fir, const float *input, float *output, int len);
int dsps_fird_f32_arp4(fir_f32_t *fir, const float *input, float *output, int len);
/**@}*/
/**@{*/
/**
* @brief 16 bit signed fixed point Decimation FIR filter
*
* Function implements FIR filter with decimation
* The extension (_ansi) uses ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param fir: pointer to fir filter structure, that must be initialized before
* @param input: input array
* @param output: array with the result of the FIR filter
* @param len: length of the result array
*
* @return: function returns the number of samples stored in the output array
* depends on the previous state value could be [0..len/decimation]
*/
int32_t dsps_fird_s16_ansi(fir_s16_t *fir, const int16_t *input, int16_t *output, int32_t len);
int32_t dsps_fird_s16_ae32(fir_s16_t *fir, const int16_t *input, int16_t *output, int32_t len);
int32_t dsps_fird_s16_aes3(fir_s16_t *fir, const int16_t *input, int16_t *output, int32_t len);
int32_t dsps_fird_s16_arp4(fir_s16_t *fir, const int16_t *input, int16_t *output, int32_t len);
/**@}*/
/**@{*/
/**
* @brief initialize structure for multi-rate FIR filter
* Function initialize structure for 32 bit floating point multi-rate FIR filter
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param fir: pointer to fir filter structure, that must be preallocated
* @param coeffs: array with FIR filter coefficients. Must be length N
* @param delay: array for FIR filter delay line. Must be length N
* @param length: FIR filter length. Length of coeffs and delay arrays.
* @param interp: interpolation factor.
* @param decim: decimation factor.
* @param start_pos: initial value of decimation counter. Must be [0..decim)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_firmr_init_f32(fir_f32_t *fir, float *coeffs, float *delay, int length, int interp, int decim, int start_pos );
/**@}*/
/**@{*/
/**
* @brief initialize structure for multi-rate FIR filter
* Function initialize structure for 16 bit signed fixed point multi-rate FIR filter
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param fir: pointer to fir filter structure, that must be preallocated
* @param coeffs: array with FIR filter coefficients. Must be length N
* @param delay: array for FIR filter delay line. Must be length N
* @param length: FIR filter length. Length of coeffs and delay arrays.
* @param interp: interpolation factor.
* @param decim: decimation factor.
* @param start_pos: initial value of decimation counter. Must be [0..decim)
* @param shift: shift of accumulator value to store in the output array.
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_firmr_init_s16(fir_s16_t *fir, int16_t *coeffs, int16_t *delay, int16_t length, int16_t interp, int16_t decim, int16_t start_pos, int16_t shift);
/**@}*/
/**@{*/
/**
* @brief 32 bit floating point multi-rate FIR filter
*
* Function implements FIR filter with decimation
* The extension (_ansi) uses ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param fir: pointer to fir filter structure, that must be initialized before
* @param input: input array
* @param output: array with the result of the FIR filter
* @param input_len: length of the input array
*
* @return
* - amount of samples stored in the output array
* - depends on the previous state value
* - could be [0..len*intepr/decimation]
*
*/
int dsps_firmr_f32_ansi(fir_f32_t *fir, const float *input, float *output, int input_len);
/**@}*/
/**@{*/
/**
* @brief 16 bit signed fixed point multi-rate FIR filter
*
* Function implements FIR filter with decimation
* The extension (_ansi) uses ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param fir: pointer to fir filter structure, that must be initialized before
* @param input: input array
* @param output: array with the result of the FIR filter
* @param input_len: length of the intput array
*
* @return: function returns the number of samples stored in the output array
* depends on the previous state value could be [0..len*intepr/decimation]
*/
int32_t dsps_firmr_s16_ansi(fir_s16_t *fir, const int16_t *input, int16_t *output, int32_t input_len);
/**@}*/
/**@{*/
/**
* @brief support arrays freeing function
*
* Function frees all the arrays, which were created during the initialization of the fir_s16_t structure
* 1. frees allocated memory for rounding buffer, for the purposes of esp32s3 ee.ld.accx.ip assembly instruction
* 2. frees allocated memory in case the delay line is NULL
* 3. frees allocated memory in case the length of the filter (and the delay line) is not divisible by 8
* and new delay line and filter coefficients arrays are created for the purpose of the esp32s3 assembly
*
* @param fir: pointer to fir filter structure, that must be initialized before
*
* @return
* - ESP_OK on success
*/
esp_err_t dsps_fird_s16_aexx_free(fir_s16_t *fir);
/**@}*/
/**@{*/
/**
* @brief support arrays freeing function
*
* Function frees the delay line arrays, if it was allocated by the init functions.
*
* @param fir: pointer to fir filter structure, that must be initialized before
*
* @return
* - ESP_OK on success
*/
esp_err_t dsps_fir_f32_free(fir_f32_t *fir);
/**@}*/
/**@{*/
/**
* @brief Array reversal
*
* Function reverses 16-bit long array members for the purpose of the dsps_fird_s16_aes3 implementation
* The function has to be called either during the fir struct initialization or every time the coefficients change
*
* @param arr: pointer to the array to be reversed
* @param len: length of the array to be reversed
*
* @return
* - ESP_OK on success
*/
esp_err_t dsps_16_array_rev(int16_t *arr, int16_t len);
/**@}*/
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dsps_fir_f32_ae32_enabled == 1)
#define dsps_fir_f32 dsps_fir_f32_ae32
#elif (dsps_fir_f32_aes3_enabled == 1)
#define dsps_fir_f32 dsps_fir_f32_aes3
#else
#define dsps_fir_f32 dsps_fir_f32_ansi
#endif
#if (dsps_fird_f32_aes3_enabled == 1)
#define dsps_fird_f32 dsps_fird_f32_aes3
#define dsps_firmr_f32 dsps_firmr_f32_ansi
#elif (dsps_fird_f32_ae32_enabled == 1)
#define dsps_fird_f32 dsps_fird_f32_ae32
#define dsps_firmr_f32 dsps_firmr_f32_ansi
#elif (dsps_fird_f32_arp4_enabled == 1)
#define dsps_fird_f32 dsps_fird_f32_arp4
#define dsps_firmr_f32 dsps_firmr_f32_ansi
#else
#define dsps_fird_f32 dsps_fird_f32_ansi
#define dsps_firmr_f32 dsps_firmr_f32_ansi
#endif
#if (dsps_fird_s16_ae32_enabled == 1)
#define dsps_fird_s16 dsps_fird_s16_ae32
#define dsps_firmr_s16 dsps_firmr_s16_ansi
#elif (dsps_fird_s16_aes3_enabled == 1)
#define dsps_fird_s16 dsps_fird_s16_aes3
#define dsps_firmr_s16 dsps_firmr_s16_ansi
#elif (dsps_fird_s16_arp4_enabled == 1)
#define dsps_fird_s16 dsps_fird_s16_arp4
#define dsps_firmr_s16 dsps_firmr_s16_ansi
#else
#define dsps_fird_s16 dsps_fird_s16_ansi
#define dsps_firmr_s16 dsps_firmr_s16_ansi
#endif
#else // CONFIG_DSP_OPTIMIZED
#define dsps_fir_f32 dsps_fir_f32_ansi
#define dsps_fird_f32 dsps_fird_f32_ansi
#define dsps_firmr_f32 dsps_firmr_f32_ansi
#define dsps_fird_s16 dsps_fird_s16_ansi
#define dsps_firmr_s16 dsps_firmr_s16_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dsps_fir_H_
@@ -0,0 +1,40 @@
#ifndef _dsps_fir_platform_H_
#define _dsps_fir_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#if CONFIG_IDF_TARGET_ESP32S3
#define dsps_fird_f32_aes3_enabled 1
#define dsps_fird_f32_ae32_enabled 1
#define dsps_fird_s16_aes3_enabled 1
#define dsps_fird_s16_ae32_enabled 0
#define dsps_fir_f32_aes3_enabled 1
#define dsps_fir_f32_ae32_enabled 0
#else
#define dsps_fird_f32_ae32_enabled 1
#define dsps_fird_s16_aes3_enabled 0
#define dsps_fird_s16_ae32_enabled 1
#define dsps_fir_f32_aes3_enabled 0
#define dsps_fir_f32_ae32_enabled 1
#endif
#endif //
#endif // __XTENSA__
#ifdef CONFIG_IDF_TARGET_ESP32P4
#ifdef CONFIG_DSP_OPTIMIZED
#define dsps_fird_f32_arp4_enabled 1
#define dsps_fird_s16_arp4_enabled 1
#else
#define dsps_fird_f32_arp4_enabled 0
#define dsps_fird_s16_arp4_enabled 0
#endif // CONFIG_DSP_OPTIMIZED
#endif
#endif // _dsps_fir_platform_H_
@@ -0,0 +1,133 @@
/*
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _dsps_resampl_H_
#define _dsps_resampl_H_
#include "dsp_err.h"
#include "dsps_fir.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Data struct of f32 multi-rate resampler
*
* This structure is used by a resampler internally. A user should access this structure only in case of
* extensions for the DSP Library.
* To initialize the resampler, use the dsps_resampler_mr_init() function.
* To execute the resampler, use the dsps_resampler_mr_exec() function.
* To free the resampler, use the dsps_resampler_mr_free() function.
*/
typedef struct dsps_resample_mr_s {
void *filter; /*!< FIR filter structure*/
float samplerate_factor; /*!< Sample rate factor */
int16_t decim_c; /*!< Decimation factor for ceil */
int16_t decim_f; /*!< Decimation factor for floor */
int16_t active_decim; /*!< Active decimation factor */
float decim_avg_in; /*!< Average decimation factor for input */
float decim_avg_out; /*!< Average decimation factor for output */
int32_t (*dsps_firmr)(void *fir, void *input, void *output, int32_t length); /*!< Pointer to FIR filter function */
int32_t fixed_point; /*!< Fixed point flag */
} dsps_resample_mr_t;
/**
* @brief Data struct of f32 poly-phase resampler
*
* This structure is used by a poly-phase resampler internally. A user should access this structure only in case of
* extensions for the DSP Library.
* To initialize the resampler, use the dsps_resampler_ph_init() function.
* To execute the resampler, use the dsps_resampler_ph_exec() function.
*
* It is possible to correct the sample rate by adjust the phase parameter "on the fly".
*/
typedef struct dsps_resample_ph_s {
float phase;
float step;
float delay[4];
int delay_pos;
} dsps_resample_ph_t;
/**
* @brief Initialize the multi-rate resampler
*
* @param resampler Pointer to the resampler structure
* @param coeffs Pointer to the filter coefficients (float or int16_t for fixed point)
* @param length Length of the filter coefficients
* @param interp Interpolation factor for the filter
* @param samplerate_factor Sample rate factor
* @param fixed_point Fixed point flag, 0 for float, 1 for fixed point
* @param shift Shift value for fixed point
*
* @return ESP_OK on success, ESP_ERR_INVALID_ARG if the parameters are invalid
*/
esp_err_t dsps_resampler_mr_init(dsps_resample_mr_t *resampler, void *coeffs, int16_t length, int16_t interp, float samplerate_factor, int32_t fixed_point, int16_t shift);
/**
* @brief Execute the multi-rate resampler
*
* This function executes the multi-rate resampler. The input and output buffers can be the same.
* The function based on multi-rate FIR filter.
* The decimation factor is updated for each execution. The current decimation factor calculated
* as division of average input and average output sample rate.
* To correct the output sample rate, the length_correction parameter is used. To increase
* the output sample rate, the length_correction parameter should be positive. To decrease
* the output sample rate, the length_correction parameter should be negative. This parameter
* is used when the input and output sample rates are comes from different sources.
*
* @param resampler: Pointer to the resampler structure
* @param input: Pointer to the input buffer
* @param output: Pointer to the output buffer
* @param length: Length of the input buffers
* @param length_correction: Length correction for the current execution. Positive value
* increases the output sample rate, negative value decreases
* the output sample rate.
*
* @return Length of the output buffer
*/
int32_t dsps_resampler_mr_exec(dsps_resample_mr_t *resampler, void *input, void *output, int32_t length, int32_t length_correction);
/**
* @brief Free the multi-rate resampler
*
* @param resampler Pointer to the resampler structure
*/
void dsps_resampler_mr_free(dsps_resample_mr_t *resampler);
/**
* @brief Initialize the poly-phase resampler
*
* The poly-phase resampler is a implementation of the poly-phase Farrow filter
* that use cubic interpolation with 4 coefficients.
*
* @param resampler Pointer to the resampler structure
* @param samplerate_factor Sample rate factor
*
* @return ESP_OK on success, ESP_ERR_INVALID_ARG if the parameters are invalid
*/
esp_err_t dsps_resampler_ph_init(dsps_resample_ph_t *resampler, float samplerate_factor);
/**
* @brief Execute the poly-phase resampler
*
* @param resampler Pointer to the resampler structure
* @param input Pointer to the input buffer
* @param output Pointer to the output buffer
* @param length Length of the input buffer
*
* @return Length of the output buffer
*/
int32_t dsps_resampler_ph_exec(dsps_resample_ph_t *resampler, float *input, float *output, int32_t length);
#ifdef __cplusplus
}
#endif
#endif //_dsps_resampl_H_
@@ -0,0 +1,105 @@
// Copyright 2018-2025 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.
#ifndef _dsps_biquad_H_
#define _dsps_biquad_H_
#include "dsp_err.h"
#include "dsps_biquad_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief IIR filter
*
* IIR filter 2nd order direct form II (bi quad)
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] input: input array
* @param output: output array
* @param len: length of input and output vectors
* @param coef: array of coefficients. b0,b1,b2,a1,a2
* expected that a0 = 1. b0..b2 - numerator, a0..a2 - denominator
* @param w: delay line w0,w1. Length of 2.
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_f32_ansi(const float *input, float *output, int len, float *coef, float *w);
esp_err_t dsps_biquad_f32_ae32(const float *input, float *output, int len, float *coef, float *w);
esp_err_t dsps_biquad_f32_aes3(const float *input, float *output, int len, float *coef, float *w);
esp_err_t dsps_biquad_f32_arp4(const float *input, float *output, int len, float *coef, float *w);
/**@}*/
/**@{*/
/**
* @brief IIR filter for stereo data
*
* IIR filter 2nd order direct form II (bi quad)
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] input: input array of two channels: L/R/L/R/L/R
* @param output: output array of two channels: L/R/L/R/L/R
* @param len: number of samples in one channel
* @param coef: array of coefficients. b0,b1,b2,a1,a2
* expected that a0 = 1. b0..b2 - numerator, a0..a2 - denominator
* @param w: delay line w0,w1,w2,w3. Length of 4. w0,w1 - channel0, w2,w3 - channel1
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_sf32_ansi(const float *input, float *output, int len, float *coef, float *w);
esp_err_t dsps_biquad_sf32_ae32(const float *input, float *output, int len, float *coef, float *w);
esp_err_t dsps_biquad_sf32_aes3(const float *input, float *output, int len, float *coef, float *w);
esp_err_t dsps_biquad_sf32_arp4(const float *input, float *output, int len, float *coef, float *w);
/**@}*/
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dsps_biquad_f32_ae32_enabled == 1)
#define dsps_biquad_f32 dsps_biquad_f32_ae32
#define dsps_biquad_sf32 dsps_biquad_sf32_ae32
#elif (dsps_biquad_f32_aes3_enabled == 1)
#define dsps_biquad_f32 dsps_biquad_f32_aes3
#define dsps_biquad_sf32 dsps_biquad_sf32_ae32
#elif (dsps_biquad_f32_arp4_enabled == 1)
#define dsps_biquad_f32 dsps_biquad_f32_arp4
#define dsps_biquad_sf32 dsps_biquad_sf32_arp4
#else
#define dsps_biquad_f32 dsps_biquad_f32_ansi
#define dsps_biquad_sf32 dsps_biquad_sf32_ansi
#endif
#else // CONFIG_DSP_OPTIMIZED
#define dsps_biquad_f32 dsps_biquad_f32_ansi
#define dsps_biquad_sf32 dsps_biquad_sf32_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dsps_biquad_H_
@@ -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.
#ifndef _dsps_biquad_gen_H_
#define _dsps_biquad_gen_H_
#include "dsp_err.h"
#ifdef __cplusplus
extern "C"
{
#endif
// Common rules for all generated coefficients.
// The coefficients placed to the array as follows:
// coeffs[0] = b0;
// coeffs[1] = b1;
// coeffs[2] = b2;
// coeffs[3] = a1;
// coeffs[4] = a2;
// a0 - are not placed and expected always as == 1
/**
* @brief LPF IIR filter coefficients
* Coefficients for low pass 2nd order IIR filter (bi-quad)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param coeffs: result coefficients. b0,b1,b2,a1,a2, a0 are not placed to the array and expected by IIR as 1
* @param f: filter cut off frequency in range of 0..0.5 (normalized to sample frequency)
* @param qFactor: Q factor of filter
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_gen_lpf_f32(float *coeffs, float f, float qFactor);
/**
* @brief HPF IIR filter coefficients
*
* Coefficients for high pass 2nd order IIR filter (bi-quad)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param coeffs: result coefficients. b0,b1,b2,a1,a2, a0 are not placed to the array and expected by IIR as 1
* @param f: filter cut off frequency in range of 0..0.5 (normalized to sample frequency)
* @param qFactor: Q factor of filter
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_gen_hpf_f32(float *coeffs, float f, float qFactor);
/**
* @brief BPF IIR filter coefficients
*
* Coefficients for band pass 2nd order IIR filter (bi-quad)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param coeffs: result coefficients. b0,b1,b2,a1,a2, a0 are not placed to the array and expected by IIR as 1
* @param f: filter center frequency in range of 0..0.5 (normalized to sample frequency)
* @param qFactor: Q factor of filter
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_gen_bpf_f32(float *coeffs, float f, float qFactor);
/**
* @brief 0 dB BPF IIR filter coefficients
*
* Coefficients for band pass 2nd order IIR filter (bi-quad) with 0 dB gain in passband
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param coeffs: result coefficients. b0,b1,b2,a1,a2, a0 are not placed to the array and expected by IIR as 1
* @param f: filter center frequency in range of 0..0.5 (normalized to sample frequency)
* @param qFactor: Q factor of filter
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_gen_bpf0db_f32(float *coeffs, float f, float qFactor);
/**
* @brief Notch IIR filter coefficients
*
* Coefficients for notch 2nd order IIR filter (bi-quad)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param coeffs: result coefficients. b0,b1,b2,a1,a2, a0 are not placed to the array and expected by IIR as 1
* @param f: filter notch frequency in range of 0..0.5 (normalized to sample frequency)
* @param gain: gain in stopband in dB
* @param qFactor: Q factor of filter
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_gen_notch_f32(float *coeffs, float f, float gain, float qFactor);
/**
* @brief Allpass 360 degree IIR filter coefficients
*
* Coefficients for all pass 2nd order IIR filter (bi-quad) with 360 degree phase shift
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param coeffs: result coefficients. b0,b1,b2,a1,a2, a0 are not placed to the array and expected by IIR as 1
* @param f: filter notch frequency in range of 0..0.5 (normalized to sample frequency)
* @param qFactor: Q factor of filter
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_gen_allpass360_f32(float *coeffs, float f, float qFactor);
/**
* @brief Allpass 180 degree IIR filter coefficients
*
* Coefficients for all pass 2nd order IIR filter (bi-quad) with 180 degree phase shift
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param coeffs: result coefficients. b0,b1,b2,a1,a2, a0 are not placed to the array and expected by IIR as 1
* @param f: filter notch frequency in range of 0..0.5 (normalized to sample frequency)
* @param qFactor: Q factor of filter
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_gen_allpass180_f32(float *coeffs, float f, float qFactor);
/**
* @brief peak IIR filter coefficients
*
* Coefficients for peak 2nd order IIR filter (bi-quad)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param coeffs: result coefficients. b0,b1,b2,a1,a2, a0 are not placed to the array and expected by IIR as 1
* @param f: filter notch frequency in range of 0..0.5 (normalized to sample frequency)
* @param qFactor: Q factor of filter
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_gen_peakingEQ_f32(float *coeffs, float f, float qFactor);
/**
* @brief low shelf IIR filter coefficients
*
* Coefficients for low pass Shelf 2nd order IIR filter (bi-quad)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param coeffs: result coefficients. b0,b1,b2,a1,a2, a0 are not placed to the array and expected by IIR as 1
* @param f: filter notch frequency in range of 0..0.5 (normalized to sample frequency)
* @param gain: gain in stopband in dB
* @param qFactor: Q factor of filter
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_gen_lowShelf_f32(float *coeffs, float f, float gain, float qFactor);
/**
* @brief high shelf IIR filter coefficients
*
* Coefficients for high pass Shelf 2nd order IIR filter (bi-quad)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param coeffs: result coefficients. b0,b1,b2,a1,a2, a0 are not placed to the array and expected by IIR as 1
* @param f: filter notch frequency in range of 0..0.5 (normalized to sample frequency)
* @param gain: gain in stopband in dB
* @param qFactor: Q factor of filter
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_biquad_gen_highShelf_f32(float *coeffs, float f, float gain, float qFactor);
#ifdef __cplusplus
}
#endif
#endif // _dsps_biquad_gen_H_
@@ -0,0 +1,34 @@
#ifndef _dsps_biquad_platform_H_
#define _dsps_biquad_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dsps_biquad_f32_ae32_enabled 1
#endif
#if CONFIG_IDF_TARGET_ESP32S3
#define dsps_biquad_f32_aes3_enabled 1
#else
#define dsps_biquad_f32_aes3_enabled 0
#endif
#endif // __XTENSA__
#ifdef CONFIG_IDF_TARGET_ESP32P4
#ifdef CONFIG_DSP_OPTIMIZED
#define dsps_biquad_f32_arp4_enabled 1
#else
#define dsps_biquad_f32_arp4_enabled 0
#endif // CONFIG_DSP_OPTIMIZED
#else
#define dsps_biquad_f32_arp4_enabled 0
#endif
#endif // _dsps_biquad_platform_H_
@@ -0,0 +1,255 @@
// Copyright 2020-2021 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.
#ifndef _ekf_h_
#define _ekf_h_
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#include <stdint.h>
#include <mat.h>
/**
* The ekf is a base class for Extended Kalman Filter.
* It contains main matrix operations and define the processing flow.
*/
class ekf {
public:
/**
* Constructor of EKF.
* THe constructor allocate main memory for the matrixes.
* @param[in] x: - amount of states in EKF. x[n] = F*x[n-1] + G*u + W. Size of matrix F
* @param[in] w: - amount of control measurements and noise inputs. Size of matrix G
*/
ekf(int x, int w);
/**
* Distructor of EKF
*/
virtual ~ekf();
/**
* Main processing method of the EKF.
*
* @param[in] u: - input measurements
* @param[in] dt: - time difference from the last call in seconds
*/
virtual void Process(float *u, float dt);
/**
* Initialization of EKF.
* The method should be called befare the first use of the filter.
*/
virtual void Init() = 0;
/**
* xDot[n] = F*x[n] + G*u + W
* Number of states, X is the state vector (size of F matrix)
*/
int NUMX;
/**
* xDot[n] = F*x[n] + G*u + W
* The size of G matrix
*/
int NUMW;
/**
* System state vector
*/
dspm::Mat &X;
/**
* Linearized system matrices F, where xDot[n] = F*x[n] + G*u + W
*/
dspm::Mat &F;
/**
* Linearized system matrices G, where xDot[n] = F*x[n] + G*u + W
*/
dspm::Mat &G;
/**
* Covariance matrix and state vector
*/
dspm::Mat &P;
/**
* Input noise and measurement noise variances
*/
dspm::Mat &Q;
/**
* Runge-Kutta state update method.
* The method calculates derivatives of input vector x and control measurements u
*
* @param[in] x: state vector
* @param[in] u: control measurement
* @param[in] dt: time interval from last update in seconds
*/
void RungeKutta(dspm::Mat &x, float *u, float dt);
// System Dependent methods:
/**
* Derivative of state vector X
* The default calculation: xDot = F*x + G*u
* It's possible to implement optimized version
* @param[in] x: state vector
* @param[in] u: control measurement
* @return
* xDot - derivative of input vector x and u
*/
virtual dspm::Mat StateXdot(dspm::Mat &x, float *u);
/**
* Calculation of system state matrices F and G
* @param[in] x: state vector
* @param[in] u: control measurement
*/
virtual void LinearizeFG(dspm::Mat &x, float *u) = 0;
//
// System independent methods
/**
* Calculates covariance prediction matrux P.
* Update matrix P
* @param[in] dt: time interval from last update
*/
virtual void CovariancePrediction(float dt);
/**
* Update of current state by measured values.
* Optimized method for non correlated values
* Calculate Kalman gain and update matrix P and vector X.
* @param[in] H: derivative matrix
* @param[in] measured: array of measured values
* @param[in] expected: array of expected values
* @param[in] R: measurement noise covariance values
*/
virtual void Update(dspm::Mat &H, float *measured, float *expected, float *R);
/**
* Update of current state by measured values.
* This method just as a reference for research purpose.
* Not used in real calculations.
* @param[in] H: derivative matrix
* @param[in] measured: array of measured values
* @param[in] expected: array of expected values
* @param[in] R: measurement noise covariance values
*/
virtual void UpdateRef(dspm::Mat &H, float *measured, float *expected, float *R);
/**
* Matrix for intermidieve calculations
*/
float *HP;
/**
* Matrix for intermidieve calculations
*/
float *Km;
public:
// Additional universal helper methods
/**
* Convert quaternion to rotation matrix.
* @param[in] q: quaternion
*
* @return
* - rotation matrix 3x3
*/
static dspm::Mat quat2rotm(float q[4]);
/**
* Convert rotation matrix to quaternion.
* @param[in] R: rotation matrix
*
* @return
* - quaternion 4x1
*/
static dspm::Mat rotm2quat(dspm::Mat &R);
/**
* Convert quaternion to Euler angels.
* @param[in] q: quaternion
*
* @return
* - Euler angels 3x1
*/
static dspm::Mat quat2eul(const float q[4]);
/**
* Convert Euler angels to rotation matrix.
* @param[in] xyz: Euler angels
*
* @return
* - rotation matrix 3x3
*/
static dspm::Mat eul2rotm(float xyz[3]);
/**
* Convert rotation matrix to Euler angels.
* @param[in] rotm: rotation matrix
*
* @return
* - Euler angels 3x1
*/
static dspm::Mat rotm2eul(dspm::Mat &rotm);
/**
* Df/dq: Derivative of vector by quaternion.
* @param[in] vector: input vector
* @param[in] quat: quaternion
*
* @return
* - Derivative matrix 3x4
*/
static dspm::Mat dFdq(dspm::Mat &vector, dspm::Mat &quat);
/**
* Df/dq: Derivative of vector by inverted quaternion.
* @param[in] vector: input vector
* @param[in] quat: quaternion
*
* @return
* - Derivative matrix 3x4
*/
static dspm::Mat dFdq_inv(dspm::Mat &vector, dspm::Mat &quat);
/**
* Make skew-symmetric matrix of vector.
* @param[in] w: source vector
*
* @return
* - skew-symmetric matrix 4x4
*/
static dspm::Mat SkewSym4x4(float *w);
// q product
// Rl = [q(1) - q(2) - q(3) - q(4); ...
// q(2) q(1) - q(4) q(3); ...
// q(3) q(4) q(1) - q(2); ...
// q(4) - q(3) q(2) q(1); ...
/**
* Make right quaternion-product matrices.
* @param[in] q: source quaternion
*
* @return
* - right quaternion-product matrix 4x4
*/
static dspm::Mat qProduct(float *q);
};
#endif // _ekf_h_
@@ -0,0 +1,98 @@
// Copyright 2020-2021 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.
#ifndef _ekf_imu13states_H_
#define _ekf_imu13states_H_
#include "ekf.h"
/**
* @brief This class is used to process and calculate attitude from imu sensors.
*
* The class use state vector with 13 follows values
* X[0..3] - attitude quaternion
* X[4..6] - gyroscope bias error, rad/sec
* X[7..9] - magnetometer vector value - magn_ampl
* X[10..12] - magnetometer offset value - magn_offset
*
* where, reference magnetometer value = magn_ampl*rotation_matrix' + magn_offset
*/
class ekf_imu13states: public ekf {
public:
ekf_imu13states();
virtual ~ekf_imu13states();
virtual void Init();
// Method calculates Xdot values depends on U
// U - gyroscope values in radian per seconds (rad/sec)
virtual dspm::Mat StateXdot(dspm::Mat &x, float *u);
virtual void LinearizeFG(dspm::Mat &x, float *u);
/**
* Method for development and tests only.
*/
void Test();
/**
* Method for development and tests only.
*
* @param[in] enable_att - enable attitude as input reference value
*/
void TestFull(bool enable_att);
/**
* Initial reference valie for magnetometer.
*/
dspm::Mat mag0;
/**
* Initial reference valie for accelerometer.
*/
dspm::Mat accel0;
/**
* number of control measurements
*/
int NUMU;
/**
* Update part of system state by reference measurements accelerometer and magnetometer.
* Only attitude and gyro bias will be updated.
* This method should be used as main method after calibration.
*
* @param[in] accel_data: accelerometer measurement vector XYZ in g, where 1 g ~ 9.81 m/s^2
* @param[in] magn_data: magnetometer measurement vector XYZ
* @param[in] R: measurement noise covariance values for diagonal covariance matrix. Then smaller value, then more you trust them.
*/
void UpdateRefMeasurement(float *accel_data, float *magn_data, float R[6]);
/**
* Update full system state by reference measurements accelerometer and magnetometer.
* This method should be used at calibration phase.
*
* @param[in] accel_data: accelerometer measurement vector XYZ in g, where 1 g ~ 9.81 m/s^2
* @param[in] magn_data: magnetometer measurement vector XYZ
* @param[in] R: measurement noise covariance values for diagonal covariance matrix. Then smaller value, then more you trust them.
*/
void UpdateRefMeasurementMagn(float *accel_data, float *magn_data, float R[6]);
/**
* Update system state by reference measurements accelerometer, magnetometer and attitude quaternion.
* This method could be used when system on constant state or in initialization phase.
* @param[in] accel_data: accelerometer measurement vector XYZ in g, where 1 g ~ 9.81 m/s^2
* @param[in] magn_data: magnetometer measurement vector XYZ
* @param[in] attitude: attitude quaternion
* @param[in] R: measurement noise covariance values for diagonal covariance matrix. Then smaller value, then more you trust them.
*/
void UpdateRefMeasurement(float *accel_data, float *magn_data, float *attitude, float R[10]);
};
#endif // _ekf_imu13states_H_
@@ -0,0 +1,89 @@
// 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.
#ifndef _dsps_add_H_
#define _dsps_add_H_
#include "dsp_err.h"
#include "dsps_add_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief add two arrays
*
* The function add one input array to another
* out[i*step_out] = input1[i*step1] + input2[i*step2]; i=[0..len)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] input1: input array 1
* @param[in] input2: input array 2
* @param output: output array
* @param len: amount of operations for arrays
* @param step1: step over input array 1 (by default should be 1)
* @param step2: step over input array 2 (by default should be 1)
* @param step_out: step over output array (by default should be 1)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_add_f32_ansi(const float *input1, const float *input2, float *output, int len, int step1, int step2, int step_out);
esp_err_t dsps_add_f32_ae32(const float *input1, const float *input2, float *output, int len, int step1, int step2, int step_out);
esp_err_t dsps_add_s16_ansi(const int16_t *input1, const int16_t *input2, int16_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_add_s16_ae32(const int16_t *input1, const int16_t *input2, int16_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_add_s16_aes3(const int16_t *input1, const int16_t *input2, int16_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_add_s8_ansi(const int8_t *input1, const int8_t *input2, int8_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_add_s8_aes3(const int8_t *input1, const int8_t *input2, int8_t *output, int len, int step1, int step2, int step_out, int shift);
/**@}*/
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dsps_add_f32_ae32_enabled == 1)
#define dsps_add_f32 dsps_add_f32_ae32
#else
#define dsps_add_f32 dsps_add_f32_ansi
#endif
#if (dsps_add_s16_aes3_enabled == 1)
#define dsps_add_s16 dsps_add_s16_aes3
#define dsps_add_s8 dsps_add_s8_aes3
#elif (dsps_add_s16_ae32_enabled == 1)
#define dsps_add_s16 dsps_add_s16_ae32
#define dsps_add_s8 dsps_add_s8_ansi
#else
#define dsps_add_s16 dsps_add_s16_ansi
#define dsps_add_s8 dsps_add_s8_ansi
#endif
#else // CONFIG_DSP_OPTIMIZED
#define dsps_add_f32 dsps_add_f32_ansi
#define dsps_add_s16 dsps_add_s16_ansi
#define dsps_add_s8 dsps_add_s8_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dsps_add_H_
@@ -0,0 +1,32 @@
#ifndef _dsps_add_platform_H_
#define _dsps_add_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if (CONFIG_IDF_TARGET_ESP32S3 == 1)
#define dsps_add_f32_ae32_enabled 1
#define dsps_add_s16_aes3_enabled 1
#else
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dsps_add_f32_ae32_enabled 1
#define dsps_add_s16_ae32_enabled 1
#endif
#if (XCHAL_HAVE_LOOPS == 1)
#define dsps_add_f32_ae32_enabled 1
#define dsps_add_s16_ae32_enabled 1
#endif
#endif // CONFIG_IDF_TARGET_ESP32S3
#endif // __XTENSA__
#endif // _dsps_add_platform_H_
@@ -0,0 +1,65 @@
// 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.
#ifndef _dsps_addc_H_
#define _dsps_addc_H_
#include "dsp_err.h"
#include "dsps_addc_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief add constant
*
* The function adds constant to the input array
* x[i*step_out] = y[i*step_in] + C; i=[0..len)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] input: input array
* @param output: output array
* @param len: amount of operations for arrays
* @param C: constant value
* @param step_in: step over input array (by default should be 1)
* @param step_out: step over output array (by default should be 1)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_addc_f32_ansi(const float *input, float *output, int len, float C, int step_in, int step_out);
esp_err_t dsps_addc_f32_ae32(const float *input, float *output, int len, float C, int step_in, int step_out);
/**@}*/
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dsps_addc_f32_ae32_enabled == 1)
#define dsps_addc_f32 dsps_addc_f32_ae32
#else
#define dsps_addc_f32 dsps_addc_f32_ansi
#endif
#else
#define dsps_addc_f32 dsps_addc_f32_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dsps_addc_H_
@@ -0,0 +1,19 @@
#ifndef _dsps_addc_platform_H_
#define _dsps_addc_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dsps_addc_f32_ae32_enabled 1
#endif
#endif // __XTENSA__
#endif // _dsps_addc_platform_H_
@@ -0,0 +1,25 @@
// 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.
#ifndef _dsps_math_H_
#define _dsps_math_H_
#include "dsps_add.h"
#include "dsps_sub.h"
#include "dsps_mul.h"
#include "dsps_addc.h"
#include "dsps_mulc.h"
#include "dsps_sqrt.h"
#endif // _dsps_math_H_
@@ -0,0 +1,111 @@
// 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.
#ifndef _dsps_mul_H_
#define _dsps_mul_H_
#include "dsp_err.h"
#include "dsps_mul_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief Multiply two arrays
*
* The function multiply one input array to another and store result to other array
* out[i*step_out] = input1[i*step1] * input2[i*step2]; i=[0..len)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] input1: input array 1
* @param[in] input2: input array 2
* @param output: output array
* @param len: amount of operations for arrays
* @param step1: step over input array 1 (by default should be 1)
* @param step2: step over input array 2 (by default should be 1)
* @param step_out: step over output array (by default should be 1)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_mul_f32_ansi(const float *input1, const float *input2, float *output, int len, int step1, int step2, int step_out);
esp_err_t dsps_mul_f32_ae32(const float *input1, const float *input2, float *output, int len, int step1, int step2, int step_out);
/**@}*/
/**@{*/
/**
* @brief Multiply two arrays
*
* The function multiply one input array to another and store result to other array
* out[i*step_out] = input1[i*step1] * input2[i*step2]; i=[0..len)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] input1: input array 1
* @param[in] input2: input array 2
* @param output: output array
* @param len: amount of operations for arrays
* @param step1: step over input array 1 (by default should be 1)
* @param step2: step over input array 2 (by default should be 1)
* @param step_out: step over output array (by default should be 1)
* @param shift: output shift after multiplication (by default should be 15)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_mul_s16_ansi(const int16_t *input1, const int16_t *input2, int16_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_mul_s16_ae32(const int16_t *input1, const int16_t *input2, int16_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_mul_s16_aes3(const int16_t *input1, const int16_t *input2, int16_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_mul_s8_ansi(const int8_t *input1, const int8_t *input2, int8_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_mul_s8_aes3(const int8_t *input1, const int8_t *input2, int8_t *output, int len, int step1, int step2, int step_out, int shift);
/**@}*/
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dsps_mul_f32_ae32_enabled == 1)
#define dsps_mul_f32 dsps_mul_f32_ae32
#else
#define dsps_mul_f32 dsps_mul_f32_ansi
#endif
#if (dsps_mul_s16_aes3_enabled == 1)
#define dsps_mul_s16 dsps_mul_s16_aes3
#define dsps_mul_s8 dsps_mul_s8_aes3
#elif (dsps_mul_s16_ae32_enabled == 1)
#define dsps_mul_s16 dsps_mul_s16_ae32
#define dsps_mul_s8 dsps_mul_s8_ansi
#else
#define dsps_mul_s16 dsps_mul_s16_ansi
#define dsps_mul_s8 dsps_mul_s8_ansi
#endif
#else // CONFIG_DSP_OPTIMIZED
#define dsps_mul_f32 dsps_mul_f32_ansi
#define dsps_mul_s16 dsps_mul_s16_ansi
#define dsps_mul_s8 dsps_mul_s8_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dsps_mul_H_
@@ -0,0 +1,30 @@
#ifndef _dsps_mul_platform_H_
#define _dsps_mul_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dsps_mul_f32_ae32_enabled 1
#define dsps_mul_s16_ae32_enabled 1
#endif
#if (XCHAL_HAVE_LOOPS == 1)
#define dsps_mul_f32_ae32_enabled 1
#define dsps_mul_s16_ae32_enabled 1
#endif
#if (CONFIG_IDF_TARGET_ESP32S3 == 1)
#define dsps_mul_f32_ae32_enabled 1
#define dsps_mul_s16_aes3_enabled 1
#endif
#endif // __XTENSA__
#endif // _dsps_mul_platform_H_
@@ -0,0 +1,74 @@
// 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.
#ifndef _dsps_mulc_H_
#define _dsps_mulc_H_
#include "dsp_err.h"
#include "dsps_mulc_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief multiply constant
*
* The function multiplies input array to the constant value
* x[i*step_out] = y[i*step_in]*C; i=[0..len)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] input: input array
* @param output: output array
* @param len: amount of operations for arrays
* @param C: constant value
* @param step_in: step over input array (by default should be 1)
* @param step_out: step over output array (by default should be 1)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_mulc_f32_ansi(const float *input, float *output, int len, float C, int step_in, int step_out);
esp_err_t dsps_mulc_f32_ae32(const float *input, float *output, int len, float C, int step_in, int step_out);
esp_err_t dsps_mulc_s16_ae32(const int16_t *input, int16_t *output, int len, int16_t C, int step_in, int step_out);
esp_err_t dsps_mulc_s16_ansi(const int16_t *input, int16_t *output, int len, int16_t C, int step_in, int step_out);
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dsps_mulc_f32_ae32_enabled == 1)
#define dsps_mulc_f32 dsps_mulc_f32_ae32
#else //
#define dsps_mulc_f32 dsps_mulc_f32_ansi
#endif
#if (dsps_mulc_s16_ae32_enabled == 1)
#define dsps_mulc_s16 dsps_mulc_s16_ae32
#else
#define dsps_mulc_s16 dsps_mulc_s16_ansi
#endif // dsps_mulc_s16_ae32_enabled
#else
#define dsps_mulc_f32 dsps_mulc_f32_ansi
#define dsps_mulc_s16 dsps_mulc_s16_ansi
#endif
#endif // _dsps_mulc_H_
@@ -0,0 +1,25 @@
#ifndef _dsps_mulc_platform_H_
#define _dsps_mulc_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dsps_mulc_f32_ae32_enabled 1
#endif
#if ((XCHAL_HAVE_LOOPS == 1) && (XCHAL_HAVE_MAC16 == 1))
#define dsps_mulc_s16_ae32_enabled 1
#endif //
#endif // __XTENSA__
#endif // _dsps_mulc_platform_H_
@@ -0,0 +1,91 @@
// 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.
#ifndef _dsps_sqrt_H_
#define _dsps_sqrt_H_
#include "dsp_err.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief square root approximation
*
* The function takes square root approximation
* x[i] ~ sqrt(y[i]); i=[0..len)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] input: input array
* @param output: output array
* @param len: amount of operations for arrays
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_sqrt_f32_ansi(const float *input, float *output, int len);
//esp_err_t dsps_sqrt_s32_ansi(const int32_t *input, int16_t *output, int len);
/**@{*/
/**
* @brief square root approximation
*
* The function takes square root approximation
* x ~ sqrt(y);
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] data: input value
*
* @return
* - square root value
*/
float dsps_sqrtf_f32_ansi(const float data);
/**@{*/
/**
* @brief inverted square root approximation
*
* The function takes inverted square root approximation
* x ~ 1/sqrt(y);
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] data: input value
*
* @return
* - inverted square root value
*/
float dsps_inverted_sqrtf_f32_ansi(float data );
/**@}*/
#ifdef __cplusplus
}
#endif
#ifdef CONFIG_DSP_OPTIMIZED
#define dsps_sqrt_f32 dsps_sqrt_f32_ansi
#define dsps_sqrtf_f32 dsps_sqrtf_f32_ansi
#define dsps_inverted_sqrtf_f32 dsps_inverted_sqrtf_f32_ansi
#else
#define dsps_sqrt_f32 dsps_sqrt_f32_ansi
#define dsps_sqrtf_f32 dsps_sqrtf_f32_ansi
#define dsps_inverted_sqrtf_f32 dsps_inverted_sqrtf_f32_ansi
#endif
#endif // _dsps_sqrt_H_
@@ -0,0 +1,87 @@
// 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.
#ifndef _dsps_sub_H_
#define _dsps_sub_H_
#include "dsp_err.h"
#include "dsps_sub_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief sub arrays
*
* The function subtract one array from another
* out[i*step_out] = input1[i*step1] - input2[i*step2]; i=[0..len)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] input1: input array 1
* @param[in] input2: input array 2
* @param output: output array
* @param len: amount of operations for arrays
* @param step1: step over input array 1 (by default should be 1)
* @param step2: step over input array 2 (by default should be 1)
* @param step_out: step over output array (by default should be 1)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_sub_f32_ansi(const float *input1, const float *input2, float *output, int len, int step1, int step2, int step_out);
esp_err_t dsps_sub_f32_ae32(const float *input1, const float *input2, float *output, int len, int step1, int step2, int step_out);
esp_err_t dsps_sub_s16_ansi(const int16_t *input1, const int16_t *input2, int16_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_sub_s16_ae32(const int16_t *input1, const int16_t *input2, int16_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_sub_s16_aes3(const int16_t *input1, const int16_t *input2, int16_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_sub_s8_ansi(const int8_t *input1, const int8_t *input2, int8_t *output, int len, int step1, int step2, int step_out, int shift);
esp_err_t dsps_sub_s8_aes3(const int8_t *input1, const int8_t *input2, int8_t *output, int len, int step1, int step2, int step_out, int shift);
/**@}*/
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dsps_sub_f32_ae32_enabled == 1)
#define dsps_sub_f32 dsps_sub_f32_ae32
#else
#define dsps_sub_f32 dsps_sub_f32_ansi
#endif
#if (dsps_sub_s16_aes3_enabled == 1)
#define dsps_sub_s16 dsps_sub_s16_aes3
#define dsps_sub_s8 dsps_sub_s8_aes3
#elif (dsps_sub_s16_ae32_enabled == 1)
#define dsps_sub_s16 dsps_sub_s16_ae32
#define dsps_sub_s8 dsps_sub_s8_ansi
#else
#define dsps_sub_s16 dsps_sub_s16_ansi
#define dsps_sub_s8 dsps_sub_s8_ansi
#endif
#else // CONFIG_DSP_OPTIMIZED
#define dsps_sub_f32 dsps_sub_f32_ansi
#define dsps_sub_s16 dsps_sub_s16_ansi
#define dsps_sub_s8 dsps_sub_s8_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dsps_sub_H_
@@ -0,0 +1,30 @@
#ifndef _dsps_sub_platform_H_
#define _dsps_sub_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dsps_sub_f32_ae32_enabled 1
#define dsps_sub_s16_ae32_enabled 1
#endif
#if (XCHAL_HAVE_LOOPS == 1)
#define dsps_sub_f32_ae32_enabled 1
#define dsps_sub_s16_ae32_enabled 1
#endif
#if (CONFIG_IDF_TARGET_ESP32S3 == 1)
#define dsps_sub_f32_ae32_enabled 1
#define dsps_sub_s16_aes3_enabled 1
#endif
#endif // __XTENSA__
#endif // _dsps_sub_platform_H_
@@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _dspm_add_H_
#define _dspm_add_H_
#include "dsp_err.h"
#include "dspm_add_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief add two arrays with paddings (add two sub-matrices)
*
* The function adds two arrays defined as sub-matrices with paddings
* out[row * ptr_step_out + col * step_out] = in1[row * ptr_step_in1 + col * step1] + in2[row * ptr_step_in2 + col * step2];
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] input1: input array 1
* @param[in] input2: input array 2
* @param[out] output: output array
* @param[in] rows: matrix rows
* @param[in] cols: matrix cols
* @param[in] padd1: input array 1 padding
* @param[in] padd2: input array 2 padding
* @param[in] padd_out: output array padding
* @param[in] step1: step over input array 1 (by default should be 1)
* @param[in] step2: step over input array 2 (by default should be 1)
* @param[in] step_out: step over output array (by default should be 1)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_add_f32_ansi(const float *input1, const float *input2, float *output, int rows, int cols, int padd1, int padd2, int padd_out, int step1, int step2, int step_out);
esp_err_t dspm_add_f32_ae32(const float *input1, const float *input2, float *output, int rows, int cols, int padd1, int padd2, int padd_out, int step1, int step2, int step_out);
/**@}*/
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dspm_add_f32_ae32_enabled == 1)
#define dspm_add_f32 dspm_add_f32_ae32
#else
#define dspm_add_f32 dspm_add_f32_ansi
#endif
#else // CONFIG_DSP_OPTIMIZED
#define dspm_add_f32 dspm_add_f32_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dspm_add_H_
@@ -0,0 +1,20 @@
#ifndef _dspm_add_platform_H_
#define _dspm_add_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dspm_add_f32_ae32_enabled 1
#endif
#endif // __XTENSA__
#endif // _dspm_add_platform_H_
@@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _dspm_addc_H_
#define _dspm_addc_H_
#include "dsp_err.h"
#include "dspm_addc_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief add a constant and an array with padding (add a constant and a sub-matrix)
*
* The function adds a constant and an array defined as a sub-matrix with padding
* out[row * ptr_step_out + col * step_out] = input[row * ptr_step_in + col * step_in] + C;
* The implementation uses ANSI C and could be compiled and run on any platform
*
* @param[in] input: input array
* @param[out] output: output array
* @param[in] C: constant value
* @param[in] rows: matrix rows
* @param[in] cols: matrix cols
* @param[in] padd_in: input array padding
* @param[in] padd_out: output array padding
* @param[in] step_in: step over input array (by default should be 1)
* @param[in] step_out: step over output array (by default should be 1)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_addc_f32_ansi(const float *input, float *output, float C, int rows, int cols, int padd_in, int padd_out, int step_in, int step_out);
esp_err_t dspm_addc_f32_ae32(const float *input, float *output, float C, int rows, int cols, int padd_in, int padd_out, int step_in, int step_out);
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dspm_addc_f32_ae32_enabled == 1)
#define dspm_addc_f32 dspm_addc_f32_ae32
#else
#define dspm_addc_f32 dspm_addc_f32_ansi
#endif
#else
#define dspm_addc_f32 dspm_addc_f32_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dspm_addc_H_
@@ -0,0 +1,19 @@
#ifndef _dspm_addc_platform_H_
#define _dspm_addc_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dspm_addc_f32_ae32_enabled 1
#endif
#endif // __XTENSA__
#endif // _dspm_addc_platform_H_
@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _dspm_matrix_H_
#define _dspm_matrix_H_
#include "dspm_add.h"
#include "dspm_addc.h"
#include "dspm_mult.h"
#include "dspm_mulc.h"
#include "dspm_sub.h"
#endif // _dspm_matrix_H_
@@ -0,0 +1,671 @@
// Copyright 2018-2023 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.
#ifndef _dspm_mat_h_
#define _dspm_mat_h_
#include <iostream>
/**
* @brief DSP matrix namespace
*
* DSP library matrix namespace.
*/
namespace dspm {
/**
* @brief Matrix
*
* The Mat class provides basic matrix operations on single-precision floating point values.
*/
class Mat {
public:
int rows; /*!< Amount of rows*/
int cols; /*!< Amount of columns*/
int stride; /*!< Stride = (number of elements in a row) + padding*/
int padding; /*!< Padding between 2 rows*/
float *data; /*!< Buffer with matrix data*/
int length; /*!< Total amount of data in data array*/
static float abs_tol; /*!< Max acceptable absolute tolerance*/
bool ext_buff; /*!< Flag indicates that matrix use external buffer*/
bool sub_matrix; /*!< Flag indicates that matrix is a subset of another matrix*/
/**
* @brief Rectangular area
*
* The Rect is used for creating regions of interest ROI(s). The ROI is then used as a sub-matrix
*/
struct Rect {
int x; /*!< x starting position (start col) of the rectangular area*/
int y; /*!< y starting position (start row) of the rectangular area*/
int width; /*!< width (number of cols) of the rectangular area*/
int height; /*!< height (number of rows) of the rectangular area*/
/**
* @brief Constructor with initialization to 0
*
* @param[in] x: x starting position (start col) of the rectangular area
* @param[in] y: y starting position (start row) of the rectangular area
* @param[in] width: width (number of cols) of the rectangular area
* @param[in] height: height (number of rows) of the rectangular area
*/
Rect(int x = 0, int y = 0, int width = 0, int height = 0);
/**
* @brief Resize rect area
*
* @param[in] x: x starting position (start col) of the new rectangular area
* @param[in] y: y starting position (start row) of the new rectangular area
* @param[in] width: width (number of cols) of the new rectangular area
* @param[in] height: height (number of rows) of the new rectangular area
*/
void resizeRect(int x, int y, int width, int height);
/**
* @brief Get amount of elements in the rect area
*/
int areaRect(void);
};
/**
* Constructor allocate internal buffer.
* @param[in] rows: amount of matrix rows
* @param[in] cols: amount of matrix columns
*/
Mat(int rows, int cols);
/**
* Constructor use external buffer.
* @param[in] data: external buffer with row-major matrix data
* @param[in] rows: amount of matrix rows
* @param[in] cols: amount of matrix columns
*/
Mat(float *data, int rows, int cols);
/**
* Constructor
* @param[in] data: external buffer with row-major matrix data
* @param[in] rows: amount of matrix rows
* @param[in] cols: amount of matrix columns
* @param[in] stride: col stride
*/
Mat(float *data, int rows, int cols, int stride);
/**
* Allocate matrix with undefined size.
*/
Mat();
virtual ~Mat();
/**
* @brief Make copy of matrix.
*
* if src matrix is sub matrix, only the header is copied
* if src matrix is matrix, header and data are copied
*
* @param[in] src: source matrix
*/
Mat(const Mat &src);
/**
* @brief Create a subset of matrix as ROI (Region of Interest)
*
* @param[in] startRow: start row position of source matrix to get the subset matrix from
* @param[in] startCol: start col position of source matrix to get the subset matrix from
* @param[in] roiRows: size of row elements of source matrix to get the subset matrix from
* @param[in] roiCols: size of col elements of source matrix to get the subset matrix from
*
* @return
* - result matrix size roiRows x roiCols
*/
Mat getROI(int startRow, int startCol, int roiRows, int roiCols);
/**
* @brief Create a subset of matrix as ROI (Region of Interest)
*
* @param[in] startRow: start row position of source matrix to get the subset matrix from
* @param[in] startCol: start col position of source matrix to get the subset matrix from
* @param[in] roiRows: size of row elements of source matrix to get the subset matrix from
* @param[in] roiCols: size of col elements of source matrix to get the subset matrix from
* @param[in] stride: number of cols + padding between 2 rows
*
* @return
* - result matrix size roiRows x roiCols
*/
Mat getROI(int startRow, int startCol, int roiRows, int roiCols, int stride);
/**
* @brief Create a subset of matrix as ROI (Region of Interest)
*
* @param[in] rect: rectangular area of interest
*
* @return
* - result matrix size rect.rectRows x rect.rectCols
*/
Mat getROI(const Mat::Rect &rect);
/**
* Make copy of matrix.
* @param[in] src: source matrix
* @param[in] row_pos: start row position of destination matrix
* @param[in] col_pos: start col position of destination matrix
*/
void Copy(const Mat &src, int row_pos, int col_pos);
/**
* @brief copy header of matrix
*
* Make a shallow copy of matrix (no data copy)
* @param[in] src: source matrix
*/
void CopyHead(const Mat &src);
/**
* @brief print matrix header
*
* Print all information about matrix to the terminal
* @param[in] src: source matrix
*/
void PrintHead(void);
/**
* Make copy of matrix.
* @param[in] row_start: start row position of source matrix to copy
* @param[in] row_size: size of wor elements of source matrix to copy
* @param[in] col_start: start col position of source matrix to copy
* @param[in] col_size: size of wor elements of source matrix to copy
*
* @return
* - result matrix size row_size x col_size
*/
Mat Get(int row_start, int row_size, int col_start, int col_size);
/**
* Make copy of matrix.
* @param[in] rect: rectangular area of interest
* @return
* - result matrix size row_size x col_size
*/
Mat Get(const Mat::Rect &rect);
/**
* Copy operator
*
* @param[in] src: source matrix
*
* @return
* - matrix copy
*/
Mat &operator=(const Mat &src);
/**
* Access to the matrix elements.
* @param[in] row: row position
* @param[in] col: column position
*
* @return
* - element of matrix M[row][col]
*/
inline float &operator()(int row, int col)
{
return data[row * this->stride + col];
}
/**
* Access to the matrix elements.
* @param[in] row: row position
* @param[in] col: column position
*
* @return
* - element of matrix M[row][col]
*/
inline const float &operator()(int row, int col) const
{
return data[row * this->stride + col];
}
/**
* += operator
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] A: source matrix
*
* @return
* - result matrix: result += A
*/
Mat &operator+=(const Mat &A);
/**
* += operator
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] C: constant
*
* @return
* - result matrix: result += C
*/
Mat &operator+=(float C);
/**
* -= operator
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] A: source matrix
*
* @return
* - result matrix: result -= A
*/
Mat &operator-=(const Mat &A);
/**
* -= operator
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] C: constant
*
* @return
* - result matrix: result -= C
*/
Mat &operator-=(float C);
/**
* *= operator
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] A: source matrix
*
* @return
* - result matrix: result -= A
*/
Mat &operator*=(const Mat &A);
/**
* += with constant operator
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] C: constant value
*
* @return
* - result matrix: result *= C
*/
Mat &operator*=(float C);
/**
* /= with constant operator
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] C: constant value
*
* @return
* - result matrix: result /= C
*/
Mat &operator/=(float C);
/**
* /= operator
*
* @param[in] B: source matrix
*
* @return
* - result matrix: result[i,j] = result[i,j]/B[i,j]
*/
Mat &operator/=(const Mat &B);
/**
* ^= xor with constant operator
* The operator use DSP optimized implementation of multiplication.
* @param[in] C: constant value
*
* @return
* - result matrix: result ^= C
*/
Mat operator^(int C);
/**
* Swap two rows between each other.
* @param[in] row1: position of first row
* @param[in] row2: position of second row
*/
void swapRows(int row1, int row2);
/**
* Matrix transpose.
* Change rows and columns between each other.
*
* @return
* - transposed matrix
*/
Mat t();
/**
* Create identity matrix.
* Create a square matrix and fill diagonal with 1.
*
* @param[in] size: matrix size
*
* @return
* - matrix [N]x[N] with 1 in diagonal
*/
static Mat eye(int size);
/**
* Create matrix with all elements 1.
* Create a square matrix and fill all elements with 1.
*
* @param[in] size: matrix size
*
* @return
* - matrix [N]x[N] with 1 in all elements
*/
static Mat ones(int size);
/**
* Create matrix with all elements 1.
* Create a matrix and fill all elements with 1.
*
* @param[in] rows: matrix rows
* @param[in] cols: matrix cols
*
* @return
* - matrix [N]x[N] with 1 in all elements
*/
static Mat ones(int rows, int cols);
/**
* Return part of matrix from defined position (startRow, startCol) as a matrix[blockRows x blockCols].
*
* @param[in] startRow: start row position
* @param[in] startCol: start column position
* @param[in] blockRows: amount of rows in result matrix
* @param[in] blockCols: amount of columns in the result matrix
*
* @return
* - matrix [blockRows]x[blockCols]
*/
Mat block(int startRow, int startCol, int blockRows, int blockCols);
/**
* Normalizes the vector, i.e. divides it by its own norm.
* If it's matrix, calculate matrix norm
*
*/
void normalize(void);
/**
* Return norm of the vector.
* If it's matrix, calculate matrix norm
*
* @return
* - matrix norm
*/
float norm(void);
/**
* The method fill 0 to the matrix structure.
*
*/
void clear(void);
/**
* @brief Solve the matrix
*
* Solve matrix. Find roots for the matrix A*x = b
*
* @param[in] A: matrix [N]x[N] with input coefficients
* @param[in] b: vector [N]x[1] with result values
*
* @return
* - matrix [N]x[1] with roots
*/
static Mat solve(Mat A, Mat b);
/**
* @brief Band solve the matrix
*
* Solve band matrix. Find roots for the matrix A*x = b with bandwidth k.
*
* @param[in] A: matrix [N]x[N] with input coefficients
* @param[in] b: vector [N]x[1] with result values
* @param[in] k: upper bandwidth value
*
* @return
* - matrix [N]x[1] with roots
*/
static Mat bandSolve(Mat A, Mat b, int k);
/**
* @brief Solve the matrix
*
* Different way to solve the matrix. Find roots for the matrix A*x = y
*
* @param[in] A: matrix [N]x[N] with input coefficients
* @param[in] y: vector [N]x[1] with result values
*
* @return
* - matrix [N]x[1] with roots
*/
static Mat roots(Mat A, Mat y);
/**
* @brief Dotproduct of two vectors
*
* The method returns dotproduct of two vectors
*
* @param[in] A: Input vector A Nx1
* @param[in] B: Input vector B Nx1
*
* @return
* - dotproduct value
*/
static float dotProduct(Mat A, Mat B);
/**
* @brief Augmented matrices
*
* Augmented matrices
*
* @param[in] A: Input vector A MxN
* @param[in] B: Input vector B MxK
*
* @return
* - Augmented matrix Mx(N+K)
*/
static Mat augment(Mat A, Mat B);
/**
* @brief Gaussian Elimination
*
* Gaussian Elimination of matrix
*
* @return
* - result matrix
*/
Mat gaussianEliminate();
/**
* Row reduction for Gaussian elimination
*
* @return
* - result matrix
*/
Mat rowReduceFromGaussian();
/**
* Find the inverse matrix
*
* @return
* - inverse matrix
*/
Mat inverse();
/**
* Find pseudo inverse matrix
*
* @return
* - inverse matrix
*/
Mat pinv();
/**
* Find determinant
* @param[in] n: element number in first row
*
* @return
* - determinant value
*/
float det(int n);
private:
Mat cofactor(int row, int col, int n);
Mat adjoint();
void allocate(); // Allocate buffer
Mat expHelper(const Mat &m, int num);
};
/**
* Print matrix to the standard iostream.
* @param[in] os: output stream
* @param[in] m: matrix to print
*
* @return
* - output stream
*/
std::ostream &operator<<(std::ostream &os, const Mat &m);
/**
* Print rectangular ROI to the standard iostream.
* @param[in] os: output stream
* @param[in] rect: ROI
*
* @return
* - output stream
*/
std::ostream &operator<<(std::ostream &os, const Mat::Rect &rect);
/**
* Fill the matrix from iostream.
* @param[in] is: input stream
* @param[in] m: matrix to fill
*
* @return
* - input stream
*/
std::istream &operator>>(std::istream &is, Mat &m);
/**
* + operator, sum of two matrices
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] A: Input matrix A
* @param[in] B: Input matrix B
*
* @return
* - result matrix A+B
*/
Mat operator+(const Mat &A, const Mat &B);
/**
* + operator, sum of matrix with constant
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] A: Input matrix A
* @param[in] C: Input constant
*
* @return
* - result matrix A+C
*/
Mat operator+(const Mat &A, float C);
/**
* - operator, subtraction of two matrices
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] A: Input matrix A
* @param[in] B: Input matrix B
*
* @return
* - result matrix A-B
*/
Mat operator-(const Mat &A, const Mat &B);
/**
* - operator, sum of matrix with constant
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] A: Input matrix A
* @param[in] C: Input constant
*
* @return
* - result matrix A+C
*/
Mat operator-(const Mat &A, float C);
/**
* * operator, multiplication of two matrices.
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] A: Input matrix A
* @param[in] B: Input matrix B
*
* @return
* - result matrix A*B
*/
Mat operator*(const Mat &A, const Mat &B);
/**
* * operator, multiplication of matrix with constant
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] A: Input matrix A
* @param[in] C: floating point value
*
* @return
* - result matrix A*B
*/
Mat operator*(const Mat &A, float C);
/**
* * operator, multiplication of matrix with constant
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] C: floating point value
* @param[in] A: Input matrix A
*
* @return
* - result matrix A*B
*/
Mat operator*(float C, const Mat &A);
/**
* / operator, divide of matrix by constant
* The operator use DSP optimized implementation of multiplication.
*
* @param[in] A: Input matrix A
* @param[in] C: floating point value
*
* @return
* - result matrix A*B
*/
Mat operator/(const Mat &A, float C);
/**
* / operator, divide matrix A by matrix B
*
* @param[in] A: Input matrix A
* @param[in] B: Input matrix B
*
* @return
* - result matrix C, where C[i,j] = A[i,j]/B[i,j]
*/
Mat operator/(const Mat &A, const Mat &B);
/**
* == operator, compare two matrices
*
* @param[in] A: Input matrix A
* @param[in] B: Input matrix B
*
* @return
* - true if matrices are the same
* - false if matrices are different
*/
bool operator==(const Mat &A, const Mat &B);
}
#endif //_dspm_mat_h_
@@ -0,0 +1,232 @@
// Copyright 2018-2023 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.
#ifndef _dspm_mult_H_
#define _dspm_mult_H_
#include "dsp_err.h"
#include "dspm_mult_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief Matrix multiplication
*
* Matrix multiplication for two floating point matrices: C[m][k] = A[m][n] * B[n][k]
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] A input matrix A[m][n]
* @param[in] B input matrix B[n][k]
* @param C result matrix C[m][k]
* @param[in] m matrix dimension
* @param[in] n matrix dimension
* @param[in] k matrix dimension
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_mult_f32_ansi(const float *A, const float *B, float *C, int m, int n, int k);
esp_err_t dspm_mult_f32_ae32(const float *A, const float *B, float *C, int m, int n, int k);
esp_err_t dspm_mult_f32_aes3(const float *A, const float *B, float *C, int m, int n, int k);
esp_err_t dspm_mult_f32_arp4(const float *A, const float *B, float *C, int m, int n, int k);
/**@}*/
/**
* @brief Matrix multiplication A[3x3]xB[3x1]
*
* Matrix multiplication for two floating point matrices 3x3 and 3x1: C[1][3] = A[3][3] * B[3][1]
* The implementation is optimized for ESP32 chip.
*
* @param[in] A input matrix A[3][3]
* @param[in] B input matrix/vector B[3][1]
* @param C result matrix/vector C[3][3]
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_mult_3x3x1_f32_ae32(const float *A, const float *B, float *C);
/**
* @brief Matrix multiplication A[3x3]xB[3x3]
*
* Matrix multiplication for two square 3x3 floating point matrices: C[3][3] = A[3][3] * B[3][3]
* The implementation is optimized for ESP32 chip.
*
* @param[in] A input matrix A[3][3]
* @param[in] B input matrix B[3][3]
* @param C result matrix C[3][3]
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_mult_3x3x3_f32_ae32(const float *A, const float *B, float *C);
/**
* @brief Matrix multiplication A[4x4]xB[4x1]
*
* Matrix multiplication for two floating point matrices 4x4 and 4x1: C[1][4] = A[4][4] * B[4][1]
* The implementation is optimized for ESP32 chip.
*
* @param[in] A input matrix A[4][4]
* @param[in] B input matrix/vector B[4][1]
* @param C result matrix/vector C[4][4]
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_mult_4x4x1_f32_ae32(const float *A, const float *B, float *C);
/**
* @brief Matrix multiplication A[4x4]xB[4x4]
*
* Matrix multiplication for two square 3x3 floating point matrices: C[4][4] = A[4][4] * B[4][4]
* The implementation is optimized for ESP32 chip.
*
* @param[in] A input matrix A[4][4]
* @param[in] B input matrix B[4][4]
* @param C result matrix C[4][4]
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_mult_4x4x4_f32_ae32(const float *A, const float *B, float *C);
/**@{*/
/**
* @brief Matrix multiplication 16 bit signeg int
*
* Matrix multiplication for two signed 16 bit fixed point matrices: C[m][k] = (A[m][n] * B[n][k]) >> (15- shift)
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] A input matrix A[m][n]
* @param[in] B input matrix B[n][k]
* @param C result matrix C[m][k]
* @param[in] m matrix dimension
* @param[in] n matrix dimension
* @param[in] k matrix dimension
* @param[in] shift every result will be shifted and stored as 16 bit signed value.
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_mult_s16_ansi(const int16_t *A, const int16_t *B, int16_t *C, int m, int n, int k, int shift);
esp_err_t dspm_mult_s16_ae32(const int16_t *A, const int16_t *B, int16_t *C, int m, int n, int k, int shift);
esp_err_t dspm_mult_s16_aes3(const int16_t *A, const int16_t *B, int16_t *C, int m, int n, int k, int shift);
esp_err_t dspm_mult_s16_arp4(const int16_t *A, const int16_t *B, int16_t *C, int m, int n, int k, int shift);
/**@}*/
/**@{*/
/**
* @brief Matrix subset multiplication
*
* One or all of the matrices are matrix subsets, described with pointers and strides
* Matrix multiplication for two floating point matrices: C[m][k] = A[m][n] * B[n][k]
* The extension (_ansi) use ANSI C and could be compiled and run on any platform.
* The extension (_ae32) is optimized for ESP32 chip.
*
* @param[in] A input matrix A[m][n]
* @param[in] B input matrix B[n][k]
* @param[out] C result matrix C[m][k]
* @param[in] m matrix dimension
* @param[in] n matrix dimension
* @param[in] k matrix dimension
* @param[in] A_padd input matrix A padding
* @param[in] B_padd input matrix B padding
* @param[in] C_padd result matrix C padding
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_mult_ex_f32_ansi(const float *A, const float *B, float *C, int m, int n, int k, int A_padd, int B_padd, int C_padd);
esp_err_t dspm_mult_ex_f32_ae32(const float *A, const float *B, float *C, int m, int n, int k, int A_padd, int B_padd, int C_padd);
esp_err_t dspm_mult_ex_f32_aes3(const float *A, const float *B, float *C, int m, int n, int k, int A_padd, int B_padd, int C_padd);
esp_err_t dspm_mult_ex_f32_arp4(const float *A, const float *B, float *C, int m, int n, int k, int A_padd, int B_padd, int C_padd);
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dspm_mult_s16_aes3_enabled == 1)
#define dspm_mult_s16 dspm_mult_s16_aes3
#elif (dspm_mult_s16_ae32_enabled == 1)
#define dspm_mult_s16 dspm_mult_s16_ae32
#elif (dspm_mult_s16_arp4_enabled == 1)
#define dspm_mult_s16 dspm_mult_s16_arp4
#else
#define dspm_mult_s16 dspm_mult_s16_ansi
#endif
#if (dspm_mult_f32_aes3_enabled == 1)
#define dspm_mult_f32 dspm_mult_f32_aes3
#define dspm_mult_ex_f32 dspm_mult_ex_f32_aes3
#elif (dspm_mult_f32_ae32_enabled == 1)
#define dspm_mult_f32 dspm_mult_f32_ae32
#define dspm_mult_ex_f32 dspm_mult_ex_f32_ae32
#elif (dspm_mult_f32_arp4_enabled == 1)
#define dspm_mult_f32 dspm_mult_f32_arp4
#define dspm_mult_ex_f32 dspm_mult_ex_f32_arp4
#else
#define dspm_mult_f32 dspm_mult_f32_ansi
#define dspm_mult_ex_f32 dspm_mult_ex_f32_ansi
#endif
#if (dspm_mult_3x3x1_f32_ae32_enabled == 1)
#define dspm_mult_3x3x1_f32 dspm_mult_3x3x1_f32_ae32
#else
#define dspm_mult_3x3x1_f32(A,B,C) dspm_mult_f32(A,B,C, 3, 3, 1)
#endif
#if (dspm_mult_3x3x3_f32_ae32_enabled == 1)
#define dspm_mult_3x3x3_f32(A,B,C) dspm_mult_3x3x3_f32_ae32(A,B,C)
#else
#define dspm_mult_3x3x3_f32(A,B,C) dspm_mult_f32(A,B,C,3,3,3);
#endif
#if (dspm_mult_4x4x1_f32_ae32_enabled == 1)
#define dspm_mult_4x4x1_f32(A,B,C) dspm_mult_4x4x1_f32_ae32(A,B,C)
#else
#define dspm_mult_4x4x1_f32(A,B,C) dspm_mult_f32(A,B,C, 4, 4, 1)
#endif
#if (dspm_mult_f32_aes3_enabled == 1)
#define dspm_mult_4x4x4_f32(A,B,C) dspm_mult_f32_aes3(A,B,C, 4, 4, 4)
#elif (dspm_mult_4x4x4_f32_ae32_enabled == 1)
#define dspm_mult_4x4x4_f32 dspm_mult_4x4x4_f32_ae32
#else
#define dspm_mult_4x4x4_f32(A,B,C) dspm_mult_f32(A,B,C, 4, 4, 4)
#endif
#else
#define dspm_mult_s16 dspm_mult_s16_ansi
#define dspm_mult_f32 dspm_mult_f32_ansi
#define dspm_mult_3x3x1_f32(A,B,C) dspm_mult_f32(A,B,C, 3, 3, 1)
#define dsps_sub_f32 dsps_sub_f32_ansi
#define dsps_add_f32 dsps_add_f32_ansi
#define dspm_mult_4x4x4_f32(A,B,C) dspm_mult_f32(A,B,C, 4, 4, 4)
#define dspm_mult_ex_f32 dspm_mult_ex_f32_ansi
#define dspm_mult_3x3x3_f32(A,B,C) dspm_mult_f32(A,B,C,3,3,3);
#define dspm_mult_4x4x1_f32(A,B,C) dspm_mult_f32(A,B,C, 4, 4, 1)
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dspm_mult_H_
@@ -0,0 +1,44 @@
#ifndef _dspm_mult_platform_H_
#define _dspm_mult_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dspm_mult_f32_ae32_enabled 1
#define dspm_mult_3x3x1_f32_ae32_enabled 1
#define dspm_mult_3x3x3_f32_ae32_enabled 1
#define dspm_mult_4x4x1_f32_ae32_enabled 1
#define dspm_mult_4x4x4_f32_ae32_enabled 1
#endif
#if ((XCHAL_HAVE_LOOPS == 1) && (XCHAL_HAVE_MAC16 == 1))
#define dspm_mult_s16_ae32_enabled 1
#endif
#endif // __XTENSA__
#if CONFIG_IDF_TARGET_ESP32S3
#define dspm_mult_f32_aes3_enabled 1
#define dspm_mult_s16_aes3_enabled 1
#endif
#if CONFIG_IDF_TARGET_ESP32P4
#ifdef CONFIG_DSP_OPTIMIZED
#define dspm_mult_f32_arp4_enabled 1
#define dspm_mult_s16_arp4_enabled 1
#else
#define dspm_mult_f32_arp4_enabled 0
#define dspm_mult_s16_arp4_enabled 0
#endif // CONFIG_DSP_OPTIMIZED
#endif
#endif // _dspm_mult_platform_H_
@@ -0,0 +1,84 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _test_mat_common_H_
#define _test_mat_common_H_
#include "dspm_mult.h"
#include "dsp_err.h"
#include "dspm_mult_platform.h"
#include "esp_dsp.h"
#include "dsp_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief data type for testing operations with sub-matrices
*
* test evaluation in the test app for matrices check
* compare 2 matrices
*/
typedef struct m_test_data_s {
int var;
int A_start_row;
int A_start_col;
int B_start_row;
int B_start_col;
int C_start_row;
int C_start_col;
int m;
int n;
int k;
} m_test_data_t;
/**
* @brief check whether 2 matrices are equal
*
* test evaluation in the test app for matrices check
* compare 2 matrices
*
* @param[in] m_expected: reference matrix
* @param[in] m_actual: matrix to be evaluated
* @param[in] message: message for test app, in case the test fails
*
*/
void test_assert_equal_mat_mat(dspm::Mat &m_expected, dspm::Mat &m_actual, const char *message);
/**
* @brief check whether a matrix is set to a constant
*
* test evaluation in the test app for matrices check
* compare matrix with constant
*
* @param[in] m_actual: matrix to be evaluated
* @param[in] num: reference constant
* @param[in] message: message for test app, if a test fails
*
*/
void test_assert_equal_mat_const(dspm::Mat &m_actual, float num, const char *message);
/**
* @brief check if an area around a sub-matrix is unaffected
*
* test evaluation in the test app for matrices check
*
* @param[in] m_origin: original matrix
* @param[in] m_modified: sub-matrix, which is created from m_orign
* @param[in] start_row: sub-matrix start row
* @param[in] start_col: sub-matrix start col
* @param[in] message: message for test app, in case the test fails
*
*/
void test_assert_check_area_mat_mat(dspm::Mat &m_origin, dspm::Mat &m_modified, int start_row, int start_col, const char *message);
#ifdef __cplusplus
}
#endif
#endif // _test_mat_common_H_
@@ -0,0 +1,61 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _dspm_mulc_H_
#define _dspm_mulc_H_
#include "dsp_err.h"
#include "dspm_mulc_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief multiply a constant and an array with padding
*
* The function multiplies a constant and an array defined as s sub-matrix with padding
* out[row * ptr_step_out + col * step_out] = input[row * ptr_step_in + col * step_in] * C;
* The implementation uses ANSI C and could be compiled and run on any platform
*
* @param[in] input: input array
* @param[out] output: output array
* @param[in] C: constant value
* @param[in] rows: input matrix rows
* @param[in] cols: input matrix cols
* @param[in] padd_in: input array padding
* @param[in] padd_out: output array padding
* @param[in] step_in: step over input array (by default should be 1)
* @param[in] step_out: step over output array (by default should be 1)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_mulc_f32_ansi(const float *input, float *output, float C, int rows, int cols, int padd_in, int padd_out, int step_in, int step_out);
esp_err_t dspm_mulc_f32_ae32(const float *input, float *output, float C, int rows, int cols, int padd_in, int padd_out, int step_in, int step_out);
/**@}*/
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dspm_mulc_f32_ae32_enabled == 1)
#define dspm_mulc_f32 dspm_mulc_f32_ae32
#else //
#define dspm_mulc_f32 dspm_mulc_f32_ansi
#endif
#else
#define dspm_mulc_f32 dspm_mulc_f32_ansi
#endif
#endif // _dspm_mulc_H_
@@ -0,0 +1,20 @@
#ifndef _dspm_mulc_platform_H_
#define _dspm_mulc_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dspm_mulc_f32_ae32_enabled 1
#endif
#endif // __XTENSA__
#endif // _dspm_mulc_platform_H_
@@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _dspm_sub_H_
#define _dspm_sub_H_
#include "dsp_err.h"
#include "dspm_sub_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief subtracts two arrays with paddings (subtracts two sub-matrices)
*
* The function subtracts two arrays defined as sub-matrices with paddings
* out[row * ptr_step_out + col * step_out] = in1[row * ptr_step_in1 + col * step1] - in2[row * ptr_step_in2 + col * step2];
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] input1: input array 1
* @param[in] input2: input array 2
* @param[out] output: output array
* @param[in] rows: matrix rows
* @param[in] cols: matrix cols
* @param[in] padd1: input array 1 padding
* @param[in] padd2: input array 2 padding
* @param[in] padd_out: output array padding
* @param[in] step1: step over input array 1 (by default should be 1)
* @param[in] step2: step over input array 2 (by default should be 1)
* @param[in] step_out: step over output array (by default should be 1)
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dspm_sub_f32_ansi(const float *input1, const float *input2, float *output, int rows, int cols, int padd1, int padd2, int padd_out, int step1, int step2, int step_out);
esp_err_t dspm_sub_f32_ae32(const float *input1, const float *input2, float *output, int rows, int cols, int padd1, int padd2, int padd_out, int step1, int step2, int step_out);
/**@}*/
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if (dspm_sub_f32_ae32_enabled == 1)
#define dspm_sub_f32 dspm_sub_f32_ae32
#else
#define dspm_sub_f32 dspm_sub_f32_ansi
#endif
#else
#define dspm_sub_f32 dspm_sub_f32_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dspm_sub_H_
@@ -0,0 +1,18 @@
#ifndef _dspm_sub_platform_H_
#define _dspm_sub_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#define dspm_sub_f32_ae32_enabled 1
#endif
#endif // __XTENSA__
#endif // _dspm_sub_platform_H_
@@ -0,0 +1,187 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _dsps_cplx_gen_H_
#define _dsps_cplx_gen_H_
#include "dsp_err.h"
#include "dsps_cplx_gen_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Ennum defining output data type of the complex generator
*
*/
typedef enum output_data_type {
S16_FIXED = 0, /*!< Q15 fixed point - int16_t*/
F32_FLOAT = 1, /*!< Single precision floating point - float*/
} out_d_type;
/**
* @brief Data struct of the complex signal generator
*
* This structure is used by a complex generator internally. A user should access this structure only in case of
* extensions for the DSP Library.
* All the fields of this structure are initialized by the dsps_cplx_gen_init(...) function.
*/
typedef struct cplx_sig_s {
void *lut; /*!< Pointer to the lookup table.*/
int32_t lut_len; /*!< Length of the lookup table.*/
float freq; /*!< Frequency of the output signal. Nyquist frequency -1 ... 1*/
float phase; /*!< Phase (initial_phase during init)*/
out_d_type d_type; /*!< Output data type*/
int16_t free_status; /*!< Indicator for cplx_gen_free(...) function*/
} cplx_sig_t;
/**
* @brief Initialize strucure for complex generator
*
* Function initializes a structure for either 16-bit fixed point, or 32-bit floating point complex generator using LUT table.
* cplx_gen_free(...) must be called, once the generator is not needed anymore to free dynamically allocated memory
*
* A user can specify his own LUT table and pass a pointer to the table (void *lut) during the initialization. If the LUT table
* pointer passed to the init function is a NULL, the LUT table is initialized internally.
*
* @param cplx_gen: pointer to the floating point generator structure
* @param d_type: output data type - out_d_type enum
* @param lut: pointer to a user-defined LUT, the data type is void so both (S16_FIXED, F32_FLOAT) types could be used
* @param lut_len: length of the LUT
* @param freq: Frequency of the output signal in a range of [-1...1], where 1 is a Nyquist frequency
* @param initial_phase: initial phase of the complex signal in range of [-1..1] where 1 is related to 2Pi and -1 is related to -2Pi
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_cplx_gen_init(cplx_sig_t *cplx_gen, out_d_type d_type, void *lut, int32_t lut_len, float freq, float initial_phase);
/**
* @brief function sets the output frequency of the complex generator
*
* set function can be used after the cplx_gen structure was initialized by the dsps_cplx_gen_init(...) function
*
* @param cplx_gen: pointer to the complex signal generator structure
* @param freq: new frequency to be set in a range of [-1..1] where 1 is a Nyquist frequency
*
* @return
* - ESP_OK on success
* - ESP_ERR_DSP_INVALID_PARAM if the frequency is out of the Nyquist frequency range
*/
esp_err_t dsps_cplx_gen_freq_set(cplx_sig_t *cplx_gen, float freq);
/**
* @brief function gets the output frequency of the complex generator
*
* get function can be used after the cplx_gen structure was initialized by the dsps_cplx_gen_init(...) function
*
* @param cplx_gen: pointer to the complex signal generator structure
*
* @return function returns frequency of the signal generator
*/
float dsps_cplx_gen_freq_get(cplx_sig_t *cplx_gen);
/**
* @brief function sets the phase of the complex generator
*
* set function can be used after the cplx_gen structure was initialized by the dsps_cplx_gen_init(...) function
*
* @param cplx_gen: pointer to the complex signal generator structure
* @param phase: new phase to be set in the range of [-1..1] where 1 is related to 2Pi and -1 is related to -2Pi
*
* @return
* - ESP_OK on success
* - ESP_ERR_DSP_INVALID_PARAM if the phase is out of -1 ... 1 range
*/
esp_err_t dsps_cplx_gen_phase_set(cplx_sig_t *cplx_gen, float phase);
/**
* @brief function gets the phase of the complex generator
*
* get function can be used after the cplx_gen structure was initialized by the dsps_cplx_gen_init(...) function
*
* @param cplx_gen: pointer to the complex signal generator structure
*
* @return function returns phase of the signal generator
*/
float dsps_cplx_gen_phase_get(cplx_sig_t *cplx_gen);
/**
* @brief function sets the output frequency and the phase of the complex generator
*
* set function can be used after the cplx_gen structure was initialized by the dsps_cplx_gen_init(...) function
*
* @param cplx_gen: pointer to the complex signal generator structure
* @param freq: new frequency to be set in the range of [-1..1] where 1 is a Nyquist frequency
* @param phase: new phase to be set in the range of [-1..1] where 1 is related to 2Pi and -1 is related to -2Pi
*
* @return
* - ESP_OK on success
* - ESP_ERR_DSP_INVALID_PARAM if the frequency is out of the Nyquist frequency range
* if the phase is out of -1 ... 1 range
*/
esp_err_t dsps_cplx_gen_set(cplx_sig_t *cplx_gen, float freq, float phase);
/**
* @brief function frees dynamically allocated memory, which was allocated in the init function
*
* free function must be called after the dsps_cplx_gen_init(...) is called, once the complex generator is not
* needed anymore
*
* @param cplx_gen: pointer to the complex signal generator structure
*/
void cplx_gen_free(cplx_sig_t *cplx_gen);
/**
* @brief The function generates a complex signal
*
* the generated complex signal is in the form of two harmonics signals in either 16-bit signed fixed point
* or 32-bit floating point
*
* x[i]= A*sin(step*i + ph/180*Pi)
* x[i+1]= B*cos(step*i + ph/180*Pi)
* where step = 2*Pi*frequency
*
* dsps_cplx_gen_ansi() - The implementation uses ANSI C and could be compiled and run on any platform
* dsps_cplx_gen_ae32() - Is targetted for Xtensa cores
*
* @param cplx_gen: pointer to the generator structure
* @param output: output array (length of len*2), data type is void so both (S16_FIXED, F32_FLOAT) types could be used
* @param len: length of the output signal
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_cplx_gen_ansi(cplx_sig_t *cplx_gen, void *output, int32_t len);
esp_err_t dsps_cplx_gen_ae32(cplx_sig_t *cplx_gen, void *output, int32_t len);
#ifdef __cplusplus
}
#endif
#if (dsps_cplx_gen_ae32_enbled || dsps_cplx_gen_aes3_enbled)
#define dsps_cplx_gen dsps_cplx_gen_ae32
#else // CONFIG_DSP_OPTIMIZED
#define dsps_cplx_gen dsps_cplx_gen_ansi
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dsps_cplx_gen_H_
@@ -0,0 +1,30 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _dsps_cplx_gen_platform_H_
#define _dsps_cplx_gen_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#if CONFIG_IDF_TARGET_ESP32S3
#define dsps_cplx_gen_aes3_enbled 1
#define dsps_cplx_gen_ae32_enbled 0
#elif CONFIG_IDF_TARGET_ESP32
#define dsps_cplx_gen_ae32_enbled 1
#define dsps_cplx_gen_aes3_enbled 0
#endif // CONFIG_IDF_TARGET_ESP32S3 CONFIG_IDF_TARGET_ESP32
#endif //
#endif // __XTENSA__
#endif // _dsps_cplx_gen_platform_H_
@@ -0,0 +1,47 @@
// 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.
#ifndef _dsps_d_gen_H_
#define _dsps_d_gen_H_
#include "dsp_err.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief delta function
*
* The function generate delta function.
* output[i]=0, if i=[0..N)
* output[i]=1, if i=pos, pos: [0..N-1)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param output: output array.
* @param len: length of the input signal
* @param pos: delta function position
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_d_gen_f32(float *output, int len, int pos);
#ifdef __cplusplus
}
#endif
#endif // _dsps_d_gen_H_
@@ -0,0 +1,48 @@
// 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.
#ifndef _dsps_h_gen_H_
#define _dsps_h_gen_H_
#include "dsp_err.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Heviside function
*
* The Heviside function.
* output[i]=0, if i=[0..pos)
* output[i]=1, if i=[pos..N)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param output: output array.
* @param len: length of the input signal
* @param pos: heviside function position
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_h_gen_f32(float *output, int len, int pos);
#ifdef __cplusplus
}
#endif
#endif // _dsps_h_gen_H_
@@ -0,0 +1,51 @@
// 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.
#ifndef _dsps_sfdr_H_
#define _dsps_sfdr_H_
#include "dsp_err.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief SFDR
*
* The function calculates Spurious-Free Dynamic Range.
* The function makes FFT of the input, then search a spectrum maximum, and then compare
* maximum value with all others. Result calculated as minimum value.
* This function have to be used for debug and unit tests only. It's not optimized for real-time processing.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param[in] input: input array.
* @param len: length of the input signal
* @param use_dc: this parameter define will be DC value used for calculation or not.
* 0 - SNR will not include DC power
* 1 - SNR will include DC power
*
* @return
* - SFDR in DB
*/
float dsps_sfdr_f32(const float *input, int32_t len, int8_t use_dc);
float dsps_sfdr_fc32(const float *input, int32_t len);
#ifdef __cplusplus
}
#endif
#endif // _dsps_sfdr_H_
@@ -0,0 +1,51 @@
// 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.
#ifndef _DSP_SNR_H_
#define _DSP_SNR_H_
#include "dsp_err.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief SNR
*
* The function calculates signal to noise ration in case if signal is sine tone.
* The function makes FFT of the input, then search a spectrum maximum, and then calculated
* SNR as sum of all harmonics to the maximum value.
* This function have to be used for debug and unit tests only. It's not optimized for real-time processing.
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param input: input array.
* @param len: length of the input signal
* @param use_dc: this parameter define will be DC value used for calculation or not.
* 0 - SNR will not include DC power
* 1 - SNR will include DC power
*
* @return
* - SNR in dB
*/
float dsps_snr_f32(const float *input, int32_t len, uint8_t use_dc);
float dsps_snr_fc32(const float *input, int32_t len);
#ifdef __cplusplus
}
#endif
#endif // _DSP_SNR_H_
@@ -0,0 +1,48 @@
// 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.
#ifndef _dsps_tone_gen_H_
#define _dsps_tone_gen_H_
#include "dsp_err.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief tone
*
* The function generate a tone signal.
* x[i]=A*sin(2*PI*i + ph/180*PI)
* The implementation use ANSI C and could be compiled and run on any platform
*
* @param output: output array.
* @param len: length of the input signal
* @param Ampl: amplitude
* @param freq: Naiquist frequency -1..1
* @param phase: phase in degree
*
* @return
* - ESP_OK on success
* - One of the error codes from DSP library
*/
esp_err_t dsps_tone_gen_f32(float *output, int len, float Ampl, float freq, float phase);
#ifdef __cplusplus
}
#endif
#endif // _dsps_tone_gen_H_
@@ -0,0 +1,64 @@
// 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.
#ifndef _dsps_view_H_
#define _dsps_view_H_
#include "dsp_err.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief plot view
*
* Generic view function.
* This function takes input samples and show then in console view as a plot.
* The main purpose to give and draft debug information to the DSP developer.
*
* @param[in] data: array with input samples.
* @param len: length of the input array
* @param width: plot width in symbols
* @param height: plot height in lines
* @param min: minimum value that will be limited by Axis Y.
* @param max: maximum value that will be limited by Axis Y.
* @param view_char: character to draw the plot calues ('.' or '|' etc)
*
*/
void dsps_view(const float *data, int32_t len, int width, int height, float min, float max, char view_char);
void dsps_view_s16(const int16_t *data, int32_t len, int width, int height, float min, float max, char view_char);
/**@}*/
/**
* @brief spectrum view
*
* The view function to show spectrum values in 64x10 screen.
* The function based on dsps_view.
*
* @param[in] data: array with input samples.
* @param len: length of the input array
* @param min: minimum value that will be limited by Axis Y.
* @param max: maximum value that will be limited by Axis Y.
*
*/
void dsps_view_spectrum(const float *data, int32_t len, float min, float max);
#ifdef __cplusplus
}
#endif
#endif // _dsps_view_H_
@@ -0,0 +1,67 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _dsps_mem_H_
#define _dsps_mem_H_
#include "dsp_err.h"
#include "dsp_common.h"
#include "dsps_mem_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**@{*/
/**
* @brief memory copy function using esp32s3 TIE
*
* The extension (_aes3) is optimized for esp32S3 chip.
*
* @param arr_dest: pointer to the destination array
* @param arr_src: pointer to the source array
* @param arr_len: count of bytes to be copied from arr_src to arr_dest
*
* @return: pointer to dest array
*/
void *dsps_memcpy_aes3(void *arr_dest, const void *arr_src, size_t arr_len);
/**@{*/
/**
* @brief memory set function using esp32s3 TIE
*
* The extension (_aes3) is optimized for esp32S3 chip.
*
* @param arr_dest: pointer to the destination array
* @param set_val: byte value, the dest array will be set with
* @param set_size: count of bytes, the dest array will be set with
*
* @return: pointer to dest array
*/
void *dsps_memset_aes3(void *arr_dest, uint8_t set_val, size_t set_size);
#ifdef __cplusplus
}
#endif
#if CONFIG_DSP_OPTIMIZED
#if dsps_mem_aes3_enbled
#define dsps_memcpy dsps_memcpy_aes3
#define dsps_memset dsps_memset_aes3
#else
#define dsps_memcpy memcpy
#define dsps_memset memset
#endif
#else // CONFIG_DSP_OPTIMIZED
#define dsps_memcpy memcpy
#define dsps_memset memset
#endif // CONFIG_DSP_OPTIMIZED
#endif // _dsps_mem_H_
@@ -0,0 +1,21 @@
#ifndef _dsps_mem_platform_H_
#define _dsps_mem_platform_H_
#include "sdkconfig.h"
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#include <xtensa/config/core-matmap.h>
#if ((XCHAL_HAVE_FP == 1) && (XCHAL_HAVE_LOOPS == 1))
#if CONFIG_IDF_TARGET_ESP32S3
#define dsps_mem_aes3_enbled 1
#else
#define dsps_mem_aes3_enbled 0
#endif // CONFIG_IDF_TARGET_ESP32S3
#endif //
#endif // __XTENSA__
#endif // _dsps_mem_platform_H_
@@ -0,0 +1,38 @@
// 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.
#ifndef _dsps_wind_blackman_H_
#define _dsps_wind_blackman_H_
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Blackman window
*
* The function generates Blackman window for plpha = 0.16.
*
* @param window: buffer to store window array.
* @param len: length of the window array
*
*/
void dsps_wind_blackman_f32(float *window, int len);
#ifdef __cplusplus
}
#endif
#endif // _dsps_wind_blackman_H_
@@ -0,0 +1,38 @@
// 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.
#ifndef _dsps_wind_blackman_harris_H_
#define _dsps_wind_blackman_harris_H_
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Blackman-Harris window
*
* The function generates Blackman-Harris window.
*
* @param window: buffer to store window array.
* @param len: length of the window array
*
*/
void dsps_wind_blackman_harris_f32(float *window, int len);
#ifdef __cplusplus
}
#endif
#endif // _dsps_wind_blackman_harris_H_
@@ -0,0 +1,38 @@
// 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.
#ifndef _dsps_wind_blackman_nuttall_H_
#define _dsps_wind_blackman_nuttall_H_
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Blackman-Nuttall window
*
* The function generates Blackman-Nuttall window.
*
* @param window: buffer to store window array.
* @param len: length of the window array
*
*/
void dsps_wind_blackman_nuttall_f32(float *window, int len);
#ifdef __cplusplus
}
#endif
#endif // _dsps_wind_blackman_nuttall_H_
@@ -0,0 +1,38 @@
// 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.
#ifndef _dsps_wind_flat_top_H_
#define _dsps_wind_flat_top_H_
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Flat-Top window
*
* The function generates Flat-Top window.
*
* @param window: buffer to store window array.
* @param len: length of the window array
*
*/
void dsps_wind_flat_top_f32(float *window, int len);
#ifdef __cplusplus
}
#endif
#endif // _dsps_wind_flat_top_H_
@@ -0,0 +1,38 @@
// 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.
#ifndef _dsps_wind_hann_H_
#define _dsps_wind_hann_H_
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Hann window
*
* The function generates Hann window.
*
* @param window: buffer to store window array.
* @param len: length of the window array
*
*/
void dsps_wind_hann_f32(float *window, int len);
#ifdef __cplusplus
}
#endif
#endif // _dsps_wind_hann_H_
@@ -0,0 +1,26 @@
// 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.
#ifndef _dsps_wind_H_
#define _dsps_wind_H_
#include "dsps_wind_hann.h"
#include "dsps_wind_blackman.h"
#include "dsps_wind_blackman_harris.h"
#include "dsps_wind_blackman_nuttall.h"
#include "dsps_wind_nuttall.h"
#include "dsps_wind_flat_top.h"
#endif // _dsps_wind_H_
@@ -0,0 +1,38 @@
// 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.
#ifndef _dsps_wind_nuttall_H_
#define _dsps_wind_nuttall_H_
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Nuttall window
*
* The function generates Nuttall window.
*
* @param window: buffer to store window array.
* @param len: length of the window array
*
*/
void dsps_wind_nuttall_f32(float *window, int len);
#ifdef __cplusplus
}
#endif
#endif // _dsps_wind_nuttall_H_