1 /*
2 * Copyright (c) 2007 - 2015 Joseph Gaeddert
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23 //
24 // Numerically-controlled synthesizer (direct digital synthesis)
25 // with internal phase-locked loop (pll) implementation
26 //
27
28 #include <assert.h>
29 #include <math.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #define SYNTH_PLL_BANDWIDTH_DEFAULT (0.1)
35 #define SYNTH_PLL_GAIN_DEFAULT (1000)
36
37 #define LIQUID_DEBUG_SYNTH (0)
38
SYNTH(_s)39 struct SYNTH(_s) {
40 T theta; // phase
41 T d_theta; // frequency
42 TC * tab; // synth table
43 unsigned int index; // table index
44 unsigned int length; // table length
45 T sumsq;
46
47 TC prev_half;
48 TC current;
49 TC next_half;
50
51 // phase-locked loop
52 T alpha;
53 T beta;
54 };
55
SYNTH(_create)56 SYNTH() SYNTH(_create)(const TC * _table, unsigned int _length)
57 {
58 SYNTH() q = (SYNTH())malloc(sizeof(struct SYNTH(_s)));
59
60 q->length = _length;
61 q->tab = (TC *)malloc(q->length * sizeof(TC));
62 memcpy(q->tab, _table, q->length * sizeof(TC));
63
64 // set default pll bandwidth
65 SYNTH(_pll_set_bandwidth)(q, SYNTH_PLL_BANDWIDTH_DEFAULT);
66
67 // reset object and return
68 SYNTH(_reset)(q);
69 // default frequency is to visit each sample once
70 SYNTH(_set_frequency)(q, (2.f * M_PI) / _length);
71 SYNTH(_compute_synth)(q);
72 return q;
73 }
74
SYNTH(_destroy)75 void SYNTH(_destroy)(SYNTH() _q)
76 {
77 if (!_q) {
78 return;
79 }
80
81 free(_q->tab);
82 free(_q);
83 }
84
SYNTH(_reset)85 void SYNTH(_reset)(SYNTH() _q)
86 {
87 _q->theta = 0;
88 _q->d_theta = 0;
89
90 // reset sine table index
91 _q->index = 0;
92
93 // reset pll filter state
94 SYNTH(_pll_reset)(_q);
95 }
96
SYNTH(_set_frequency)97 void SYNTH(_set_frequency)(SYNTH() _q, T _f)
98 {
99 _q->d_theta = _f;
100 }
101
SYNTH(_adjust_frequency)102 void SYNTH(_adjust_frequency)(SYNTH() _q, T _df)
103 {
104 _q->d_theta += _df;
105 }
106
SYNTH(_set_phase)107 void SYNTH(_set_phase)(SYNTH() _q, T _phi)
108 {
109 _q->theta = _phi;
110 SYNTH(_constrain_phase)(_q);
111 SYNTH(_compute_synth)(_q);
112 }
113
SYNTH(_adjust_phase)114 void SYNTH(_adjust_phase)(SYNTH() _q, T _dphi)
115 {
116 _q->theta += _dphi;
117 SYNTH(_constrain_phase)(_q);
118 }
119
SYNTH(_step)120 void SYNTH(_step)(SYNTH() _q)
121 {
122 _q->theta += _q->d_theta;
123 SYNTH(_constrain_phase)(_q);
124 SYNTH(_compute_synth)(_q);
125 }
126
127 // get phase
SYNTH(_get_phase)128 T SYNTH(_get_phase)(SYNTH() _q)
129 {
130 return _q->theta;
131 }
132
133 // ge frequency
SYNTH(_get_frequency)134 T SYNTH(_get_frequency)(SYNTH() _q)
135 {
136 return _q->d_theta;
137 }
138
SYNTH(_get_length)139 unsigned int SYNTH(_get_length)(SYNTH() _q)
140 {
141 return _q->length;
142 }
143
SYNTH(_get_current)144 TC SYNTH(_get_current)(SYNTH() _q)
145 {
146 return _q->current;
147 }
148
SYNTH(_get_half_previous)149 TC SYNTH(_get_half_previous)(SYNTH() _q)
150 {
151 return _q->prev_half;
152 }
153
SYNTH(_get_half_next)154 TC SYNTH(_get_half_next)(SYNTH() _q)
155 {
156 return _q->next_half;
157 }
158
159 // pll methods
160
161 // reset pll state, retaining base frequency
SYNTH(_pll_reset)162 void SYNTH(_pll_reset)(SYNTH() _q)
163 {
164 }
165
166 // set pll bandwidth
SYNTH(_pll_set_bandwidth)167 void SYNTH(_pll_set_bandwidth)(SYNTH() _q, T _bandwidth)
168 {
169 // validate input
170 if (_bandwidth < 0.0f) {
171 fprintf(stderr, "error: synth_pll_set_bandwidth(), bandwidth must be positive\n");
172 exit(1);
173 }
174
175 _q->alpha = _bandwidth; // frequency proportion
176 _q->beta = sqrtf(_q->alpha); // phase proportion
177 }
178
SYNTH(_pll_step)179 void SYNTH(_pll_step)(SYNTH() _q, T _dphi)
180 {
181 // increase frequency proportional to error
182 SYNTH(_adjust_frequency)(_q, _dphi * _q->alpha);
183
184 // increase phase proportional to error
185 SYNTH(_adjust_phase)(_q, _dphi * _q->beta);
186
187 SYNTH(_compute_synth)(_q);
188
189 // constrain frequency
190 // SYNTH(_constrain_frequency)(_q);
191 }
192
193 // mixing functions
194
SYNTH(_mix_up)195 void SYNTH(_mix_up)(SYNTH() _q, TC _x, TC * _y)
196 {
197 *_y = _x * _q->current;
198 }
199
SYNTH(_mix_down)200 void SYNTH(_mix_down)(SYNTH() _q, TC _x, TC * _y)
201 {
202 *_y = _x * conjf(_q->current);
203 }
204
SYNTH(_mix_block_up)205 void SYNTH(_mix_block_up)(SYNTH() _q, TC * _x, TC * _y, unsigned int _n)
206 {
207 unsigned int i;
208 for (i = 0; i < _n; i++) {
209 // mix single sample up
210 SYNTH(_mix_up)(_q, _x[i], &_y[i]);
211
212 // step SYNTH phase
213 SYNTH(_step)(_q);
214 }
215 }
216
SYNTH(_mix_block_down)217 void SYNTH(_mix_block_down)(SYNTH() _q, TC * _x, TC * _y, unsigned int _n)
218 {
219 unsigned int i;
220 for (i = 0; i < _n; i++) {
221 // mix single sample down
222 SYNTH(_mix_down)(_q, _x[i], &_y[i]);
223
224 // step SYNTH phase
225 SYNTH(_step)(_q);
226 }
227 }
228
SYNTH(_spread)229 void SYNTH(_spread)(SYNTH() _q, TC _x, TC * _y)
230 {
231 unsigned int i;
232 for (i = 0; i < _q->length; i++) {
233 SYNTH(_mix_up)(_q, _x, &_y[i]);
234
235 SYNTH(_step)(_q);
236 }
237 }
238
SYNTH(_despread)239 void SYNTH(_despread)(SYNTH() _q, TC * _x, TC * _y)
240 {
241 TC despread = 0;
242 T sum = 0;
243 unsigned int i;
244 for (i = 0; i < _q->length; i++) {
245 TC temp;
246 SYNTH(_mix_down)(_q, _x[i], &temp);
247
248 despread += temp;
249 sum += cabsf(_x[i]) * cabsf(_q->current);
250
251 SYNTH(_step)(_q);
252 }
253 *_y = despread / sum;
254 }
255
SYNTH(_despread_triple)256 void SYNTH(_despread_triple)(SYNTH() _q, TC * _x, TC * _early, TC * _punctual, TC * _late)
257 {
258 TC despread_early = 0;
259 TC despread_punctual = 0;
260 TC despread_late = 0;
261
262 T sum_early = 0;
263 T sum_punctual = 0;
264 T sum_late = 0;
265
266 unsigned int i;
267 for (i = 0; i < _q->length; i++) {
268 despread_early += _x[i] * conjf(_q->prev_half);
269 despread_punctual += _x[i] * conjf(_q->current);
270 despread_late += _x[i] * conjf(_q->next_half);
271
272 sum_early += cabsf(_x[i]) * cabsf(_q->prev_half);
273 sum_punctual += cabsf(_x[i]) * cabsf(_q->current);
274 sum_late += cabsf(_x[i]) * cabsf(_q->next_half);
275
276 SYNTH(_step)(_q);
277 }
278
279 *_early = despread_early / sum_early;
280 *_punctual = despread_punctual / sum_punctual;
281 *_late = despread_late / sum_late;
282 }
283
284 //
285 // internal methods
286 //
287
288 // constrain frequency of SYNTH object to be in (-pi,pi)
SYNTH(_constrain_frequency)289 void SYNTH(_constrain_frequency)(SYNTH() _q)
290 {
291 if (_q->d_theta > M_PI)
292 _q->d_theta -= 2 * M_PI;
293 else if (_q->d_theta < -M_PI)
294 _q->d_theta += 2 * M_PI;
295 }
296
297 // constrain phase of SYNTH object to be in (-pi,pi)
SYNTH(_constrain_phase)298 void SYNTH(_constrain_phase)(SYNTH() _q)
299 {
300 if (_q->theta > M_PI)
301 _q->theta -= 2 * M_PI;
302 else if (_q->theta < -M_PI)
303 _q->theta += 2 * M_PI;
304 }
305
SYNTH(_compute_synth)306 void SYNTH(_compute_synth)(SYNTH() _q)
307 {
308 // assume phase is constrained to be in (-pi,pi)
309
310 // compute index
311 float index = _q->theta * (float)_q->length / (2 * M_PI) + 2.f * (float)_q->length;
312 _q->index = ((unsigned int)(index + 0.5f)) % _q->length;
313 assert(_q->index < _q->length);
314
315 unsigned int prev_index = (_q->index + _q->length - 1) % _q->length;
316 unsigned int next_index = (_q->index + 1) % _q->length;
317
318 _q->current = _q->tab[_q->index];
319 TC prev = _q->tab[prev_index];
320 TC next = _q->tab[next_index];
321
322 _q->prev_half = (_q->current + prev) / 2;
323 _q->next_half = (_q->current + next) / 2;
324 }
325