paddlec 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,349 @@
1
+ /* Copyright (C) 2019 Théotime Bollengier <theotime.bollengier@gmail.com>
2
+ *
3
+ * This file is part of PaddleC
4
+ *
5
+ * PaddleC is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * PaddleC is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with PaddleC. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ #include <stdlib.h>
20
+ #include <math.h>
21
+ #include "libpaddlec.h"
22
+
23
+
24
+ pdlc_buffer_t* pdlc_buffer_abs(const pdlc_buffer_t *fbuf, pdlc_buffer_t *ofbuf)
25
+ {
26
+ size_t i;
27
+
28
+ if (!ofbuf)
29
+ ofbuf = pdlc_buffer_new(fbuf->length);
30
+ else
31
+ pdlc_buffer_resize(ofbuf, fbuf->length, 0);
32
+
33
+ for (i = 0; i < fbuf->length; i++)
34
+ ofbuf->data[i] = fabsf(fbuf->data[i]);
35
+
36
+ return ofbuf;
37
+ }
38
+
39
+
40
+ pdlc_buffer_t* pdlc_buffer_abs_inplace(pdlc_buffer_t *fbuf)
41
+ {
42
+ size_t i;
43
+
44
+ for (i = 0; i < fbuf->length; i++)
45
+ fbuf->data[i] = fabsf(fbuf->data[i]);
46
+
47
+ return fbuf;
48
+ }
49
+
50
+
51
+ pdlc_buffer_t* pdlc_complex_buffer_abs(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
52
+ {
53
+ size_t i;
54
+
55
+ if (!ofbuf)
56
+ ofbuf = pdlc_buffer_new(cbuf->length);
57
+ else
58
+ pdlc_buffer_resize(ofbuf, cbuf->length, 0);
59
+
60
+ for (i = 0; i < cbuf->length; i++)
61
+ ofbuf->data[i] = hypotf(cbuf->data[i].real, cbuf->data[i].imag);
62
+
63
+ return ofbuf;
64
+ }
65
+
66
+
67
+ pdlc_buffer_t* pdlc_buffer_abs2(const pdlc_buffer_t *fbuf, pdlc_buffer_t *ofbuf)
68
+ {
69
+ size_t i;
70
+
71
+ if (!ofbuf)
72
+ ofbuf = pdlc_buffer_new(fbuf->length);
73
+ else
74
+ pdlc_buffer_resize(ofbuf, fbuf->length, 0);
75
+
76
+ for (i = 0; i < fbuf->length; i++)
77
+ ofbuf->data[i] = fbuf->data[i] * fbuf->data[i];
78
+
79
+ return ofbuf;
80
+ }
81
+
82
+
83
+ pdlc_buffer_t* pdlc_buffer_abs2_inplace(pdlc_buffer_t *fbuf)
84
+ {
85
+ size_t i;
86
+
87
+ for (i = 0; i < fbuf->length; i++)
88
+ fbuf->data[i] = fbuf->data[i] * fbuf->data[i];
89
+
90
+ return fbuf;
91
+ }
92
+
93
+
94
+ pdlc_buffer_t* pdlc_complex_buffer_abs2(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
95
+ {
96
+ size_t i;
97
+
98
+ if (!ofbuf)
99
+ ofbuf = pdlc_buffer_new(cbuf->length);
100
+ else
101
+ pdlc_buffer_resize(ofbuf, cbuf->length, 0);
102
+
103
+ for (i = 0; i < cbuf->length; i++)
104
+ ofbuf->data[i] = cbuf->data[i].real * cbuf->data[i].real + cbuf->data[i].imag * cbuf->data[i].imag;
105
+
106
+ return ofbuf;
107
+ }
108
+
109
+
110
+ pdlc_buffer_t* pdlc_buffer_arg(const pdlc_buffer_t *fbuf, pdlc_buffer_t *ofbuf)
111
+ {
112
+ size_t i;
113
+
114
+ if (!ofbuf)
115
+ ofbuf = pdlc_buffer_new(fbuf->length);
116
+ else
117
+ pdlc_buffer_resize(ofbuf, fbuf->length, 0);
118
+
119
+ for (i = 0; i < fbuf->length; i++)
120
+ ofbuf->data[i] = (fbuf->data[i] < 0.0f) ? (float)M_PI : 0.0f;
121
+
122
+ return ofbuf;
123
+ }
124
+
125
+
126
+ pdlc_buffer_t* pdlc_buffer_arg_inplace(pdlc_buffer_t *fbuf)
127
+ {
128
+ size_t i;
129
+
130
+ for (i = 0; i < fbuf->length; i++)
131
+ fbuf->data[i] = (fbuf->data[i] < 0.0f) ? (float)M_PI : 0.0f;
132
+
133
+ return fbuf;
134
+ }
135
+
136
+
137
+ pdlc_buffer_t* pdlc_complex_buffer_arg(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
138
+ {
139
+ size_t i;
140
+
141
+ if (!ofbuf)
142
+ ofbuf = pdlc_buffer_new(cbuf->length);
143
+ else
144
+ pdlc_buffer_resize(ofbuf, cbuf->length, 0);
145
+
146
+ for (i = 0; i < cbuf->length; i++)
147
+ ofbuf->data[i] = atan2f(cbuf->data[i].imag, cbuf->data[i].real);
148
+
149
+ return ofbuf;
150
+ }
151
+
152
+
153
+ pdlc_buffer_t* pdlc_buffer_conjugate(const pdlc_buffer_t *fbuf, pdlc_buffer_t *ofbuf)
154
+ {
155
+ size_t i;
156
+
157
+ if (!ofbuf)
158
+ ofbuf = pdlc_buffer_new(fbuf->length);
159
+ else
160
+ pdlc_buffer_resize(ofbuf, fbuf->length, 0);
161
+
162
+ for (i = 0; i < fbuf->length; i++)
163
+ ofbuf->data[i] = fbuf->data[i];
164
+
165
+ return ofbuf;
166
+ }
167
+
168
+
169
+ pdlc_buffer_t* pdlc_buffer_conjugate_inplace(pdlc_buffer_t *fbuf)
170
+ {
171
+ size_t i;
172
+
173
+ for (i = 0; i < fbuf->length; i++)
174
+ fbuf->data[i] = fbuf->data[i];
175
+
176
+ return fbuf;
177
+ }
178
+
179
+
180
+ pdlc_complex_buffer_t* pdlc_complex_buffer_conjugate(const pdlc_complex_buffer_t *cbuf, pdlc_complex_buffer_t *ocbuf)
181
+ {
182
+ size_t i;
183
+
184
+ if (!ocbuf)
185
+ ocbuf = pdlc_complex_buffer_new(cbuf->length);
186
+ else
187
+ pdlc_complex_buffer_resize(ocbuf, cbuf->length, 0);
188
+
189
+ for (i = 0; i < cbuf->length; i++) {
190
+ ocbuf->data[i].real = cbuf->data[i].real;
191
+ ocbuf->data[i].imag = -cbuf->data[i].imag;
192
+ }
193
+
194
+ return ocbuf;
195
+ }
196
+
197
+
198
+ pdlc_complex_buffer_t* pdlc_complex_buffer_conjugate_inplace(pdlc_complex_buffer_t *cbuf)
199
+ {
200
+ size_t i;
201
+
202
+ for (i = 0; i < cbuf->length; i++) {
203
+ cbuf->data[i].real = cbuf->data[i].real;
204
+ cbuf->data[i].imag = -cbuf->data[i].imag;
205
+ }
206
+
207
+ return cbuf;
208
+ }
209
+
210
+
211
+ pdlc_buffer_t* pdlc_buffer_imag(const pdlc_buffer_t *fbuf, pdlc_buffer_t *ofbuf)
212
+ {
213
+ size_t i;
214
+
215
+ if (!ofbuf)
216
+ ofbuf = pdlc_buffer_new(fbuf->length);
217
+ else
218
+ pdlc_buffer_resize(ofbuf, fbuf->length, 0);
219
+
220
+ for (i = 0; i < fbuf->length; i++)
221
+ ofbuf->data[i] = 0.0f;
222
+
223
+ return ofbuf;
224
+ }
225
+
226
+
227
+ pdlc_buffer_t* pdlc_buffer_imag_inplace(pdlc_buffer_t *fbuf)
228
+ {
229
+ size_t i;
230
+
231
+ for (i = 0; i < fbuf->length; i++)
232
+ fbuf->data[i] = 0.0f;
233
+
234
+ return fbuf;
235
+ }
236
+
237
+
238
+ pdlc_buffer_t* pdlc_complex_buffer_imag(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
239
+ {
240
+ size_t i;
241
+
242
+ if (!ofbuf)
243
+ ofbuf = pdlc_buffer_new(cbuf->length);
244
+ else
245
+ pdlc_buffer_resize(ofbuf, cbuf->length, 0);
246
+
247
+ for (i = 0; i < cbuf->length; i++)
248
+ ofbuf->data[i] = cbuf->data[i].imag;
249
+
250
+ return ofbuf;
251
+ }
252
+
253
+
254
+ pdlc_buffer_t* pdlc_buffer_real(const pdlc_buffer_t *fbuf, pdlc_buffer_t *ofbuf)
255
+ {
256
+ size_t i;
257
+
258
+ if (!ofbuf)
259
+ ofbuf = pdlc_buffer_new(fbuf->length);
260
+ else
261
+ pdlc_buffer_resize(ofbuf, fbuf->length, 0);
262
+
263
+ for (i = 0; i < fbuf->length; i++)
264
+ ofbuf->data[i] = fbuf->data[i];
265
+
266
+ return ofbuf;
267
+ }
268
+
269
+
270
+ pdlc_buffer_t* pdlc_buffer_real_inplace(pdlc_buffer_t *fbuf)
271
+ {
272
+ size_t i;
273
+
274
+ for (i = 0; i < fbuf->length; i++)
275
+ fbuf->data[i] = fbuf->data[i];
276
+
277
+ return fbuf;
278
+ }
279
+
280
+
281
+ pdlc_buffer_t* pdlc_complex_buffer_real(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
282
+ {
283
+ size_t i;
284
+
285
+ if (!ofbuf)
286
+ ofbuf = pdlc_buffer_new(cbuf->length);
287
+ else
288
+ pdlc_buffer_resize(ofbuf, cbuf->length, 0);
289
+
290
+ for (i = 0; i < cbuf->length; i++)
291
+ ofbuf->data[i] = cbuf->data[i].real;
292
+
293
+ return ofbuf;
294
+ }
295
+
296
+
297
+ pdlc_complex_buffer_t* pdlc_buffer_swapIQ(const pdlc_buffer_t *fbuf, pdlc_complex_buffer_t *ocbuf)
298
+ {
299
+ size_t i;
300
+
301
+ if (!ocbuf)
302
+ ocbuf = pdlc_complex_buffer_new(fbuf->length);
303
+ else
304
+ pdlc_complex_buffer_resize(ocbuf, fbuf->length, 0);
305
+
306
+ for (i = 0; i < fbuf->length; i++) {
307
+ ocbuf->data[i].real = 0.0f;
308
+ ocbuf->data[i].imag = fbuf->data[i];
309
+ }
310
+
311
+ return ocbuf;
312
+ }
313
+
314
+
315
+ pdlc_complex_buffer_t* pdlc_complex_buffer_swapIQ(const pdlc_complex_buffer_t *cbuf, pdlc_complex_buffer_t *ocbuf)
316
+ {
317
+ size_t i;
318
+ pdlc_complex_t tmp;
319
+
320
+ if (!ocbuf)
321
+ ocbuf = pdlc_complex_buffer_new(cbuf->length);
322
+ else
323
+ pdlc_complex_buffer_resize(ocbuf, cbuf->length, 0);
324
+
325
+ for (i = 0; i < cbuf->length; i++) {
326
+ tmp.real = cbuf->data[i].imag;
327
+ tmp.imag = cbuf->data[i].real;
328
+ ocbuf->data[i] = tmp;
329
+ }
330
+
331
+ return ocbuf;
332
+ }
333
+
334
+
335
+ pdlc_complex_buffer_t* pdlc_complex_buffer_swapIQ_inplace(pdlc_complex_buffer_t *cbuf)
336
+ {
337
+ size_t i;
338
+ pdlc_complex_t tmp;
339
+
340
+ for (i = 0; i < cbuf->length; i++) {
341
+ tmp.real = cbuf->data[i].imag;
342
+ tmp.imag = cbuf->data[i].real;
343
+ cbuf->data[i] = tmp;
344
+ }
345
+
346
+ return cbuf;
347
+ }
348
+
349
+
@@ -0,0 +1,240 @@
1
+ /* Copyright (C) 2020 Théotime Bollengier <theotime.bollengier@gmail.com>
2
+ *
3
+ * This file is part of PaddleC
4
+ *
5
+ * PaddleC is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * PaddleC is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with PaddleC. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ #include <stdlib.h>
20
+ #include <stdio.h>
21
+ #include <string.h>
22
+ #include <math.h>
23
+ #include "libpaddlec.h"
24
+
25
+
26
+ pdlc_delay_t* pdlc_delay_new(int delay)
27
+ {
28
+ pdlc_delay_t *del;
29
+
30
+ del = malloc(sizeof(pdlc_delay_t));
31
+ del->delay = 0;
32
+ del->index_mask = 0;
33
+ del->index = 0;
34
+ del->data = NULL;
35
+
36
+ if (delay > 0)
37
+ pdlc_delay_initialize(del, delay);
38
+
39
+ return del;
40
+ }
41
+
42
+
43
+ void pdlc_delay_initialize(pdlc_delay_t* del, int delay)
44
+ {
45
+ unsigned int length;
46
+
47
+ if (del->data)
48
+ free(del->data);
49
+
50
+ del->delay = 0;
51
+ del->index_mask = 0;
52
+ del->index = 0;
53
+ del->data = NULL;
54
+
55
+ if (delay <= 0)
56
+ return;
57
+
58
+ if (delay > 134217728) {
59
+ fprintf(stderr, "ERROR: libpaddlec: Delay cannot be greater than 134217728\n");
60
+ exit(EXIT_FAILURE);
61
+ }
62
+
63
+ del->delay = (unsigned int)delay;
64
+ length = (unsigned int)(pow(2.0, ceil(log2(del->delay))));
65
+ del->index_mask = length - 1;
66
+
67
+ del->data = malloc(length*sizeof(pdlc_complex_t));
68
+ if (del->data == NULL) {
69
+ fprintf(stderr, "ERROR: libpaddlec: Cannot allocate %lu bytes for the delay!\n", length * sizeof(pdlc_complex_t));
70
+ exit(EXIT_FAILURE);
71
+ }
72
+
73
+ memset(del->data, 0, length*sizeof(pdlc_complex_t));
74
+ }
75
+
76
+
77
+ void pdlc_delay_free(pdlc_delay_t* del)
78
+ {
79
+ if (del->data)
80
+ free(del->data);
81
+ }
82
+
83
+
84
+ size_t pdlc_delay_size(const pdlc_delay_t* del)
85
+ {
86
+ return sizeof(pdlc_delay_t) + (del->index_mask + 1)*sizeof(pdlc_complex_t);
87
+ }
88
+
89
+
90
+ void pdlc_delay_reset(pdlc_delay_t* del)
91
+ {
92
+ memset(del->data, 0, (del->index_mask + 1)*sizeof(pdlc_complex_t));
93
+ del->index = 0;
94
+ }
95
+
96
+
97
+ float pdlc_delay_delay_float(pdlc_delay_t* del, float value)
98
+ {
99
+ const unsigned int mask = del->index_mask;
100
+ const unsigned int start_index = (mask + del->index + 1 - del->delay) & mask;
101
+ float *ptr = (float*)del->data;
102
+ float res;
103
+
104
+ res = ptr[start_index];
105
+ ptr[del->index] = value;
106
+ del->index = (del->index + 1) & mask;
107
+
108
+ return res;
109
+ }
110
+
111
+
112
+ pdlc_complex_t pdlc_delay_delay_complex(pdlc_delay_t* del, pdlc_complex_t value)
113
+ {
114
+ const unsigned int mask = del->index_mask;
115
+ const unsigned int start_index = (mask + del->index + 1 - del->delay) & mask;
116
+ pdlc_complex_t *ptr = del->data;
117
+ pdlc_complex_t res;
118
+
119
+ res = ptr[start_index];
120
+ ptr[del->index] = value;
121
+ del->index = (del->index + 1) & mask;
122
+
123
+ return res;
124
+ }
125
+
126
+
127
+ pdlc_buffer_t* pdlc_delay_delay_float_buffer(pdlc_delay_t* del, const pdlc_buffer_t *ifbuf, pdlc_buffer_t *ofbuf)
128
+ {
129
+ const unsigned int mask = del->index_mask;
130
+ const unsigned int length = mask + 1;
131
+ const unsigned int delay = del->delay;
132
+ const unsigned int start_index = (length + del->index - delay) & mask;
133
+ float *ptr = (float*)del->data;
134
+ unsigned int len, tocopy, dests = 0, srcs = 0;
135
+
136
+ if (!ofbuf)
137
+ ofbuf = pdlc_buffer_new(ifbuf->length);
138
+ else if (ofbuf->length != ifbuf->length)
139
+ pdlc_buffer_resize(ofbuf, ifbuf->length, 0);
140
+
141
+ /* Delay line to output buffer */
142
+ len = delay;
143
+ if (ifbuf->length < len)
144
+ len = ifbuf->length;
145
+ tocopy = len;
146
+ if ((start_index + tocopy) > length) {
147
+ tocopy = length - start_index;
148
+ memcpy(ofbuf->data + dests, ptr + start_index, tocopy*sizeof(float));
149
+ dests += tocopy;
150
+ tocopy = len - tocopy;
151
+ memcpy(ofbuf->data + dests, ptr, tocopy*sizeof(float));
152
+ }
153
+ else
154
+ memcpy(ofbuf->data + dests, ptr + start_index, tocopy*sizeof(float));
155
+ dests += tocopy;
156
+
157
+ if (ifbuf->length >= delay)
158
+ del->index = 0;
159
+
160
+ /* Input buffer to output buffer */
161
+ if (ifbuf->length > delay) {
162
+ tocopy = ifbuf->length - len;
163
+ memcpy(ofbuf->data + dests, ifbuf->data, tocopy*sizeof(float));
164
+ srcs = tocopy;
165
+ }
166
+
167
+ /* Input buffer to delay line */
168
+ tocopy = len;
169
+ if ((del->index + tocopy) > length) {
170
+ tocopy = length - del->index;
171
+ memcpy(ptr + del->index, ifbuf->data + srcs, tocopy*sizeof(float));
172
+ srcs += tocopy;
173
+ tocopy = len - tocopy;
174
+ memcpy(ptr, ifbuf->data + srcs, tocopy*sizeof(float));
175
+ }
176
+ else
177
+ memcpy(ptr + del->index, ifbuf->data + srcs, tocopy*sizeof(float));
178
+ del->index = (del->index + len) & mask;
179
+
180
+ return ofbuf;
181
+ }
182
+
183
+
184
+ pdlc_complex_buffer_t* pdlc_delay_delay_complex_buffer(pdlc_delay_t* del, const pdlc_complex_buffer_t *icbuf, pdlc_complex_buffer_t *ocbuf)
185
+ {
186
+ const unsigned int mask = del->index_mask;
187
+ const unsigned int length = mask + 1;
188
+ const unsigned int delay = del->delay;
189
+ const unsigned int start_index = (length + del->index - delay) & mask;
190
+ pdlc_complex_t *ptr = del->data;
191
+ unsigned int len, tocopy, dests = 0, srcs = 0;
192
+
193
+ if (!ocbuf)
194
+ ocbuf = pdlc_complex_buffer_new(icbuf->length);
195
+ else if (ocbuf->length != icbuf->length)
196
+ pdlc_complex_buffer_resize(ocbuf, icbuf->length, 0);
197
+
198
+ /* Delay line to output buffer */
199
+ len = delay;
200
+ if (icbuf->length < len)
201
+ len = icbuf->length;
202
+ tocopy = len;
203
+ if ((start_index + tocopy) > length) {
204
+ tocopy = length - start_index;
205
+ memcpy(ocbuf->data + dests, ptr + start_index, tocopy*sizeof(pdlc_complex_t));
206
+ dests += tocopy;
207
+ tocopy = len - tocopy;
208
+ memcpy(ocbuf->data + dests, ptr, tocopy*sizeof(pdlc_complex_t));
209
+ }
210
+ else
211
+ memcpy(ocbuf->data + dests, ptr + start_index, tocopy*sizeof(pdlc_complex_t));
212
+ dests += tocopy;
213
+
214
+ if (icbuf->length >= delay)
215
+ del->index = 0;
216
+
217
+ /* Input buffer to output buffer */
218
+ if (icbuf->length > delay) {
219
+ tocopy = icbuf->length - len;
220
+ memcpy(ocbuf->data + dests, icbuf->data, tocopy*sizeof(pdlc_complex_t));
221
+ srcs = tocopy;
222
+ }
223
+
224
+ /* Input buffer to delay line */
225
+ tocopy = len;
226
+ if ((del->index + tocopy) > length) {
227
+ tocopy = length - del->index;
228
+ memcpy(ptr + del->index, icbuf->data + srcs, tocopy*sizeof(pdlc_complex_t));
229
+ srcs += tocopy;
230
+ tocopy = len - tocopy;
231
+ memcpy(ptr, icbuf->data + srcs, tocopy*sizeof(pdlc_complex_t));
232
+ }
233
+ else
234
+ memcpy(ptr + del->index, icbuf->data + srcs, tocopy*sizeof(pdlc_complex_t));
235
+ del->index = (del->index + len) & mask;
236
+
237
+ return ocbuf;
238
+ }
239
+
240
+