SDDC_Driver
Loading...
Searching...
No Matches
pf_mixer.h
1/*
2This software is part of pffft/pfdsp, a set of simple DSP routines.
3
4Copyright (c) 2014, Andras Retzler <randras@sdr.hu>
5Copyright (c) 2020 Hayati Ayguen <h_ayguen@web.de>
6All rights reserved.
7
8Redistribution and use in source and binary forms, with or without
9modification, are permitted provided that the following conditions are met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 * Neither the name of the copyright holder nor the
16 names of its contributors may be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22DISCLAIMED. IN NO EVENT SHALL ANDRAS RETZLER BE LIABLE FOR ANY
23DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*/
30
31#ifndef _PF_MIXER_H_
32#define _PF_MIXER_H_
33
34#include <stdio.h>
35#include <stdint.h>
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41
42/*
43 _____ _
44 / ____| | |
45 | | ___ _ __ ___ _ __ | | _____ __
46 | | / _ \| '_ ` _ \| '_ \| |/ _ \ \/ /
47 | |___| (_) | | | | | | |_) | | __/> <
48 \_____\___/|_| |_| |_| .__/|_|\___/_/\_\
49 | |
50 |_|
51*/
52
53typedef struct complexf_s { float i; float q; } complexf;
54
55// =================================================================================
56
57int have_sse_shift_mixer_impl();
58
59
60/*********************************************************************/
61
62/**************/
63/*** ALGO A ***/
64/**************/
65
66float shift_math_cc(complexf *input, complexf* output, int input_size, float rate, float starting_phase);
67
68
69/*********************************************************************/
70
71/**************/
72/*** ALGO B ***/
73/**************/
74
75typedef struct shift_table_data_s
76{
77 float* table;
78 int table_size;
80
81void shift_table_deinit(shift_table_data_t table_data);
82shift_table_data_t shift_table_init(int table_size);
83float shift_table_cc(complexf* input, complexf* output, int input_size, float rate, shift_table_data_t table_data, float starting_phase);
84
85/*********************************************************************/
86
87/**************/
88/*** ALGO C ***/
89/**************/
90
92{
93 float dsin[4];
94 float dcos[4];
95 float phase_increment;
97
98shift_addfast_data_t shift_addfast_init(float rate);
99float shift_addfast_cc(complexf *input, complexf* output, int input_size, shift_addfast_data_t* d, float starting_phase);
100float shift_addfast_inp_c(complexf *in_out, int N_cplx, shift_addfast_data_t* d, float starting_phase);
101
102
103/*********************************************************************/
104
105/**************/
106/*** ALGO D ***/
107/**************/
108
110{
111 float* dsin;
112 float* dcos;
113 float phase_increment;
114 int size;
116
117shift_unroll_data_t shift_unroll_init(float rate, int size);
118void shift_unroll_deinit(shift_unroll_data_t* d);
119float shift_unroll_cc(complexf *input, complexf* output, int size, shift_unroll_data_t* d, float starting_phase);
120float shift_unroll_inp_c(complexf* in_out, int size, shift_unroll_data_t* d, float starting_phase);
121
122
123/*********************************************************************/
124
125/**************/
126/*** ALGO E ***/
127/**************/
128
129/* similar to shift_unroll_cc() - but, have fixed and limited precalc size
130 * idea: smaller cache usage by table
131 * size must be multiple of CSDR_SHIFT_LIMITED_SIMD (= 4)
132 */
133#define PF_SHIFT_LIMITED_UNROLL_SIZE 128
134#define PF_SHIFT_LIMITED_SIMD_SZ 4
135
137{
138 float dcos[PF_SHIFT_LIMITED_UNROLL_SIZE];
139 float dsin[PF_SHIFT_LIMITED_UNROLL_SIZE];
140 complexf complex_phase;
141 float phase_increment;
143
144shift_limited_unroll_data_t shift_limited_unroll_init(float rate);
145/* size must be multiple of PF_SHIFT_LIMITED_SIMD_SZ */
146/* starting_phase for next call is kept internal in state */
147void shift_limited_unroll_cc(const complexf *input, complexf* output, int size, shift_limited_unroll_data_t* d);
148void shift_limited_unroll_inp_c(complexf* in_out, int size, shift_limited_unroll_data_t* d);
149
150
151/*********************************************************************/
152
153/**************/
154/*** ALGO F ***/
155/**************/
156
158{
159 /* small/limited trig table */
160 float dcos[PF_SHIFT_LIMITED_UNROLL_SIZE+PF_SHIFT_LIMITED_SIMD_SZ];
161 float dsin[PF_SHIFT_LIMITED_UNROLL_SIZE+PF_SHIFT_LIMITED_SIMD_SZ];
162 /* 4 times complex phase */
163 float phase_state_i[PF_SHIFT_LIMITED_SIMD_SZ];
164 float phase_state_q[PF_SHIFT_LIMITED_SIMD_SZ];
165 /* N_cplx_per_block times increment - for future parallel variants */
166 float dcos_blk;
167 float dsin_blk;
168 /* */
169 float phase_increment;
171
172shift_limited_unroll_A_sse_data_t shift_limited_unroll_A_sse_init(float relative_freq, float phase_start_rad);
173void shift_limited_unroll_A_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_A_sse_data_t* d);
174
175
176/*********************************************************************/
177
178/**************/
179/*** ALGO G ***/
180/**************/
181
183{
184 /* small/limited trig table */
185 float dtrig[PF_SHIFT_LIMITED_UNROLL_SIZE+PF_SHIFT_LIMITED_SIMD_SZ];
186 /* 4 times complex phase */
187 float phase_state_i[PF_SHIFT_LIMITED_SIMD_SZ];
188 float phase_state_q[PF_SHIFT_LIMITED_SIMD_SZ];
189 /* N_cplx_per_block times increment - for future parallel variants */
190 float dcos_blk;
191 float dsin_blk;
192 /* */
193 float phase_increment;
195
196shift_limited_unroll_B_sse_data_t shift_limited_unroll_B_sse_init(float relative_freq, float phase_start_rad);
197void shift_limited_unroll_B_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_B_sse_data_t* d);
198
199/*********************************************************************/
200
201/**************/
202/*** ALGO H ***/
203/**************/
204
206{
207 /* small/limited trig table - interleaved: 4 cos, 4 sin, 4 cos, .. */
208 float dinterl_trig[2*(PF_SHIFT_LIMITED_UNROLL_SIZE+PF_SHIFT_LIMITED_SIMD_SZ)];
209 /* 4 times complex phase */
210 float phase_state_i[PF_SHIFT_LIMITED_SIMD_SZ];
211 float phase_state_q[PF_SHIFT_LIMITED_SIMD_SZ];
212 /* N_cplx_per_block times increment - for future parallel variants */
213 float dcos_blk;
214 float dsin_blk;
215 /* */
216 float phase_increment;
218
219shift_limited_unroll_C_sse_data_t shift_limited_unroll_C_sse_init(float relative_freq, float phase_start_rad);
220void shift_limited_unroll_C_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_C_sse_data_t* d);
221
222
223
224/*********************************************************************/
225
226/**************/
227/*** ALGO I ***/
228/**************/
229
230/* Recursive Quadrature Oscillator functions "recursive_osc"
231 * see https://www.vicanek.de/articles/QuadOsc.pdf
232 */
233#define PF_SHIFT_RECURSIVE_SIMD_SZ 8
235{
236 float u_cos[PF_SHIFT_RECURSIVE_SIMD_SZ];
237 float v_sin[PF_SHIFT_RECURSIVE_SIMD_SZ];
239
241{
242 float k1;
243 float k2;
245
246void shift_recursive_osc_init(float rate, float starting_phase, shift_recursive_osc_conf_t *conf, shift_recursive_osc_t *state);
247void shift_recursive_osc_update_rate(float rate, shift_recursive_osc_conf_t *conf, shift_recursive_osc_t* state);
248
249/* size must be multiple of PF_SHIFT_LIMITED_SIMD_SZ */
250/* starting_phase for next call is kept internal in state */
251void shift_recursive_osc_cc(const complexf *input, complexf* output, int size, const shift_recursive_osc_conf_t *conf, shift_recursive_osc_t* state);
252void shift_recursive_osc_inp_c(complexf* output, int size, const shift_recursive_osc_conf_t *conf, shift_recursive_osc_t* state);
253void gen_recursive_osc_c(complexf* output, int size, const shift_recursive_osc_conf_t *conf, shift_recursive_osc_t* state);
254
255/*********************************************************************/
256
257/**************/
258/*** ALGO J ***/
259/**************/
260
261#define PF_SHIFT_RECURSIVE_SIMD_SSE_SZ 4
263{
264 float u_cos[PF_SHIFT_RECURSIVE_SIMD_SSE_SZ];
265 float v_sin[PF_SHIFT_RECURSIVE_SIMD_SSE_SZ];
267
269{
270 float k1;
271 float k2;
273
274void shift_recursive_osc_sse_init(float rate, float starting_phase, shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t *state);
275void shift_recursive_osc_sse_update_rate(float rate, shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t* state);
276void shift_recursive_osc_sse_inp_c(complexf* in_out, int N_cplx, const shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t* state_ext);
277
278
279#ifdef __cplusplus
280}
281#endif
282
283#endif
Definition pf_mixer.h:53
Definition pf_mixer.h:92
Definition pf_mixer.h:158
Definition pf_mixer.h:183
Definition pf_mixer.h:206
Definition pf_mixer.h:137
Definition pf_mixer.h:241
Definition pf_mixer.h:235
Definition pf_mixer.h:269
Definition pf_mixer.h:263
Definition pf_mixer.h:76
Definition pf_mixer.h:110