ESP-IDF Firmware
Firmware architecture and call graph
Loading...
Searching...
No Matches
dsps_fird_init_s16.c File Reference
#include "dsps_fir.h"
#include "malloc.h"
#include <string.h>
#include "dsp_tests.h"
Include dependency graph for dsps_fird_init_s16.c:

Go to the source code of this file.

Macros

#define ROUNDING_VALUE   0x7fff

Functions

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)
 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
esp_err_t dsps_fird_s16_aexx_free (fir_s16_t *fir)
 support arrays freeing function
esp_err_t dsps_16_array_rev (int16_t *arr, int16_t len)
 Array reversal.

Macro Definition Documentation

◆ ROUNDING_VALUE

#define ROUNDING_VALUE   0x7fff

Definition at line 12 of file dsps_fird_init_s16.c.

Referenced by dsps_fird_init_s16(), and dsps_firmr_init_s16().

Function Documentation

◆ dsps_16_array_rev()

esp_err_t dsps_16_array_rev ( int16_t * arr,
int16_t len )

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

Parameters
arrpointer to the array to be reversed
lenlength of the array to be reversed
Returns
  • ESP_OK on success

Definition at line 146 of file dsps_fird_init_s16.c.

147{
148
149 int16_t temp;
150
151 for (int i = 0; i < (int)(len / 2); i++) {
152 temp = arr[i];
153 arr[i] = arr[len - 1 - i];
154 arr[len - 1 - i] = temp;
155 }
156 return ESP_OK;
157}
#define ESP_OK
Definition esp_err.h:23

References ESP_OK.

◆ dsps_fird_init_s16()

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 )

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

Parameters
firpointer to fir filter structure, that must be preallocated
coeffsarray with FIR filter coefficients. Must be length N
delayarray for FIR filter delay line. Must be length N
coeffs_lenFIR filter length. Length of coeffs and delay arrays.
decimdecimation factor.
start_posinitial value of decimation counter. Must be [0..d)
shiftshift position of the result
Returns
  • ESP_OK on success
  • One of the error codes from DSP library

Definition at line 14 of file dsps_fird_init_s16.c.

15{
16 fir->coeffs = coeffs;
17 fir->delay = delay;
18 fir->coeffs_len = coeffs_len;
19 fir->pos = 0;
20 fir->decim = decim;
21 fir->d_pos = start_pos;
22 fir->shift = shift;
23 fir->rounding_val = (int16_t)(ROUNDING_VALUE);
24 fir->free_status = 0;
25
26 if (fir->coeffs_len < 2) { // number of coeffcients must be higer than 1
28 }
29
30 if ((fir->shift > 40) || (fir->shift < -40)) { // shift amount must be within a range from -40 to 40
32 }
33
34 if (fir->d_pos >= fir->decim) { // start position must be lower than decimation
36 }
37
38#if CONFIG_DSP_OPTIMIZED
39
40 // Rounding value buffer primary for a purpose of ee.ld.accx.ip, but used for both the esp32 and esp32s3
41 // dsps_fird_s16_aexx_free() must be called to free the memory after the FIR function is finished
42 int32_t *aexx_rounding_buff = (int32_t *)memalign(16, 2 * sizeof(int32_t));
43
44 long long rounding = (long long)(fir->rounding_val);
45
46 if (fir->shift >= 0) {
47 rounding = (rounding >> fir->shift);
48 } else {
49 rounding = (rounding << (-fir->shift));
50 }
51#if dsps_fird_s16_arp4_enabled
52 fir->pos = start_pos;
53
54 int16_t *new_delay_buff = (int16_t *)memalign(16, (coeffs_len + 8 * 2) * sizeof(int16_t));
55 for (int i = 0 ; i < (coeffs_len + 8 * 2) ; i++) {
56 new_delay_buff[i] = 0;
57 }
58 fir->delay = &new_delay_buff[8];
59 fir->free_status |= 0x0001;
60
61#endif // dsps_fird_s16_arp4_enabled
62
63
64 aexx_rounding_buff[0] = (int32_t)(rounding); // 32 lower bits (acclo) type reassignment to 32-bit
65 aexx_rounding_buff[1] = (int32_t)((rounding >> 32) & 0xFF); // 8 higher bits (acchi) shift by 32 and apply the mask
66 fir->rounding_buff = aexx_rounding_buff;
67 fir->free_status |= 0x0004;
68
69#if dsps_fird_s16_aes3_enabled
70
71 if (fir->delay == NULL) { // New delay buffer is allocated if the current delay line is NULL
72 int16_t *new_delay_buff = (int16_t *)memalign(16, coeffs_len * sizeof(int16_t));
73 fir->delay = new_delay_buff;
74 fir->free_status |= 0x0001;
75 } else {
76 if ((int)fir->delay & 0xf) { // Delay line array must be aligned
78 }
79 }
80
81 if ((int)fir->coeffs & 0xf) { // Coefficients array must be aligned
83 }
84
85 // If the number of coefficients is not divisible by 8, a new delay line a new coefficients arrays are allocated
86 // the newly allocated arrays are divisible by 8. Coefficients are copied from the original fir structure to
87 // the new coeffs array and the remaining space is filled with zeroes
88 // dsps_fird_s16_free_coeffs_delay must be called to free the memory after the FIR function is finished
89 if (fir->coeffs_len % 8) { // Number of coefficients must be devisible by 8
90 int16_t zero_coeffs = (8 - (fir->coeffs_len % 8));
91 int16_t new_coeffs_len = fir->coeffs_len + zero_coeffs;
92 int16_t *aes3_delay_buff = (int16_t *)memalign(16, new_coeffs_len * sizeof(int16_t));
93 int16_t *aes3_coeffs_buff = (int16_t *)memalign(16, new_coeffs_len * sizeof(int16_t));
94
95 for (int i = 0; i < fir->coeffs_len; i++) { // copy fir->coeffs to aes3_coeffs_buff
96 aes3_coeffs_buff[i] = fir->coeffs[i];
97 }
98
99 for (int i = fir->coeffs_len; i < new_coeffs_len; i++) { // add zeroes to the end
100 aes3_coeffs_buff[i] = 0;
101 }
102
103 fir->delay = aes3_delay_buff;
104 fir->coeffs = aes3_coeffs_buff;
105 fir->coeffs_len = new_coeffs_len;
106 fir->free_status |= 0x0002;
107 }
108
109#endif // dsps_fird_s16_aes3_enabled
110#endif // CONFIG_DSP_OPTIMIZED
111
112 for (int i = 0; i < fir->coeffs_len; i++) { // Initialize the delay line to zero
113 fir->delay[i] = 0;
114 }
115
116 return ESP_OK;
117}
#define ESP_ERR_DSP_PARAM_OUTOFRANGE
#define ESP_ERR_DSP_INVALID_LENGTH
#define ESP_ERR_DSP_ARRAY_NOT_ALIGNED
#define memalign(align_, size_)
Definition dsp_tests.h:35
#define ROUNDING_VALUE
int16_t shift
Definition dsps_fir.h:61
int16_t * coeffs
Definition dsps_fir.h:55
int32_t rounding_val
Definition dsps_fir.h:63
int16_t * delay
Definition dsps_fir.h:56
int16_t decim
Definition dsps_fir.h:59
int16_t pos
Definition dsps_fir.h:58
int32_t * rounding_buff
Definition dsps_fir.h:62
int16_t d_pos
Definition dsps_fir.h:60
int16_t coeffs_len
Definition dsps_fir.h:57
int16_t free_status
Definition dsps_fir.h:64
float delay[256]
Definition test_fir.c:15
float coeffs[256]
Definition test_fir.c:14

References coeffs, fir_s16_s::coeffs, fir_s16_s::coeffs_len, fir_s16_s::d_pos, fir_s16_s::decim, delay, fir_s16_s::delay, ESP_ERR_DSP_ARRAY_NOT_ALIGNED, ESP_ERR_DSP_INVALID_LENGTH, ESP_ERR_DSP_PARAM_OUTOFRANGE, ESP_OK, fir_s16_s::free_status, memalign, fir_s16_s::pos, fir_s16_s::rounding_buff, fir_s16_s::rounding_val, ROUNDING_VALUE, and fir_s16_s::shift.

◆ dsps_fird_s16_aexx_free()

esp_err_t dsps_fird_s16_aexx_free ( fir_s16_t * fir)

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
Parameters
firpointer to fir filter structure, that must be initialized before
Returns
  • ESP_OK on success

Definition at line 119 of file dsps_fird_init_s16.c.

120{
121
122 if (fir->free_status == 0) {
123 return ESP_OK;
124 }
125
126 if (fir->free_status & 0x0003) {
127
128 if (fir->free_status & 0x0002) {
129 free(fir->coeffs);
130 }
131#if dsps_fird_s16_arp4_enabled
132 fir->delay = &fir->delay[-8];
133#endif
134 free(fir->delay);
135 }
136
137 if (fir->free_status & 0x0004) {
138 free(fir->rounding_buff);
139 }
140 fir->free_status = 0;
141
142 return ESP_OK;
143}

References fir_s16_s::coeffs, fir_s16_s::delay, ESP_OK, fir_s16_s::free_status, and fir_s16_s::rounding_buff.

Referenced by dsps_resampler_mr_free().

Here is the caller graph for this function: