paddlec 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+