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,28 @@
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
+ #ifndef PADDLEC_FLOAT_BUFFER_H
20
+ #define PADDLEC_FLOAT_BUFFER_H
21
+
22
+ #include <ruby.h>
23
+ #include "libpaddlec.h"
24
+
25
+ void Init_paddlec_float_buffer();
26
+ pdlc_buffer_t* paddlec_float_buffer_get_struct(VALUE obj);
27
+
28
+ #endif /* PADDLEC_FLOAT_BUFFER_H */
@@ -0,0 +1,788 @@
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 <ruby.h>
20
+ #include "paddlec_defs.h"
21
+ #include "libpaddlec.h"
22
+ #include "paddlec.h"
23
+ #include "float_buffer.h"
24
+ #include "complex_buffer.h"
25
+ #include "fir_filter.h"
26
+ #include "delay.h"
27
+ #ifdef HAVE_PULSEAUDIO_L
28
+ #include "pulseaudio.h"
29
+ #endif
30
+
31
+
32
+ /* Document-module: PaddleC
33
+ *
34
+ * PaddleC is an attempt to provide objects and methods to perform real-time processing in Ruby.
35
+ */
36
+
37
+
38
+ ID id_each;
39
+ ID id_collectI;
40
+ ID id_to_enum;
41
+ ID id_length;
42
+ ID id_real;
43
+ ID id_imag;
44
+ ID id_buffer;
45
+ ID id_delayed;
46
+ ID id_zip;
47
+ ID id_join;
48
+ ID id_to_s;
49
+ ID id_to_gplot;
50
+ ID id_acos;
51
+ ID id_acosh;
52
+ ID id_asin;
53
+ ID id_asinh;
54
+ ID id_atan;
55
+ ID id_atanh;
56
+ ID id_cbrt;
57
+ ID id_cos;
58
+ ID id_cosh;
59
+ ID id_erf;
60
+ ID id_erfc;
61
+ ID id_exp;
62
+ ID id_log;
63
+ ID id_log10;
64
+ ID id_log2;
65
+ ID id_sin;
66
+ ID id_sinh;
67
+ ID id_sqrt;
68
+ ID id_tan;
69
+ ID id_tanh;
70
+ ID id_u8;
71
+ ID id_s8;
72
+ ID id_u16;
73
+ ID id_s16;
74
+ ID id_u32;
75
+ ID id_s32;
76
+ ID id_f32;
77
+
78
+
79
+ VALUE m_PaddleC;
80
+
81
+ VALUE c_FFI_Pointer = Qundef;
82
+ VALUE o_FFI_Type_FLOAT = Qnil;
83
+
84
+
85
+
86
+ /* Allow the {https://rubygems.org/gems/gnuplot gnuplot} gem to draw {PaddleC::FloatBuffer}.
87
+ * @return [String]
88
+ */
89
+ static VALUE paddlec_array_to_gplot(VALUE self)
90
+ {
91
+ int len, i;
92
+ VALUE a, b, res, space, bn;
93
+ VALUE *splat;
94
+
95
+ if (rb_obj_is_kind_of(rb_ary_entry(self, 0), rb_cArray) || rb_obj_is_kind_of(rb_ary_entry(self, 0), c_FloatBuffer)) {
96
+ len = rb_array_len(self) - 1;
97
+ if (len < 0)
98
+ len = 0;
99
+ splat = malloc(len*sizeof(VALUE*));
100
+ for (i = 0; i < len; i++)
101
+ splat[i] = rb_ary_entry(self, i+1);
102
+ a = rb_funcallv(rb_ary_entry(self, 0), id_zip, len, splat);
103
+ free(splat);
104
+ len = rb_array_len(a);
105
+ b = rb_ary_new_capa(len + 1);
106
+ space = rb_str_new_cstr(" ");
107
+ for (i = 0; i < len; i++)
108
+ rb_ary_store(b, i, rb_funcallv(rb_ary_entry(a, i), id_join, 1, &space));
109
+ rb_ary_store(b, len, rb_str_new_cstr("e"));
110
+ bn = rb_str_new_cstr("\n");
111
+ res = rb_funcallv(b, id_join, 1, &bn);
112
+ }
113
+ else if (rb_obj_is_kind_of(rb_ary_entry(self, 0), rb_cNumeric)) {
114
+ len = rb_array_len(self);
115
+ res = rb_str_new_cstr("");
116
+ for (i = 0; i < len; i++) {
117
+ a = rb_funcallv(rb_ary_entry(self, i), id_to_s, 0, NULL);
118
+ a = rb_str_cat_cstr(a, "\n");
119
+ res = rb_str_append(res, a);
120
+ }
121
+ }
122
+ else {
123
+ len = rb_array_len(self) - 1;
124
+ if (len < 0)
125
+ len = 0;
126
+ splat = malloc(len*sizeof(VALUE*));
127
+ for (i = 0; i < len; i++)
128
+ splat[i] = rb_ary_entry(self, i+1);
129
+ a = rb_funcallv(rb_ary_entry(self, 0), id_zip, len, splat);
130
+ free(splat);
131
+ res = rb_funcallv(a, id_to_gplot, 0, NULL);
132
+ }
133
+
134
+ return res;
135
+ }
136
+
137
+
138
+ static void paddlec_check_if_FFI_is_defined()
139
+ {
140
+ VALUE mFFI;
141
+ VALUE cType;
142
+
143
+ if (rb_funcall(rb_cObject, rb_intern("const_defined?"), 1, ID2SYM(rb_intern("FFI"))) == Qtrue) {
144
+ mFFI = rb_const_get(rb_cObject, rb_intern("FFI"));
145
+ c_FFI_Pointer = rb_const_get(mFFI, rb_intern("Pointer"));
146
+ cType = rb_const_get(mFFI, rb_intern("Type"));
147
+ o_FFI_Type_FLOAT = rb_const_get(cType, rb_intern("FLOAT"));
148
+ }
149
+ }
150
+
151
+
152
+
153
+ /* @return [Symbol, nil]
154
+ */
155
+ static VALUE paddlec_paddlec_accelerator(VALUE self)
156
+ {
157
+ const char *acc = pdlc_accelerator();
158
+ if (acc[0] == '\0')
159
+ return Qnil;
160
+ return ID2SYM(rb_intern(acc));
161
+ }
162
+
163
+
164
+ /* @!group Mathematic functions. These are methods from the +Math+ module. They can operate on {PaddleC::FloatBuffer} and Float.
165
+ */
166
+
167
+
168
+ /* Computes the arc cosine of x. Returns 0..PI.
169
+ * @return [PaddleC::FloatBuffer, Float]
170
+ * @overload acos(x)
171
+ * @param x [PaddleC::FloatBuffer]
172
+ * @return [PaddleC::FloatBuffer]
173
+ * @overload acos(x)
174
+ * @param x [Float]
175
+ * @return [Float]
176
+ */
177
+ static VALUE paddlec_math_acos(VALUE self, VALUE x)
178
+ {
179
+ VALUE res;
180
+ float sf;
181
+
182
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
183
+ res = rb_funcallv(x, id_acos, 0, NULL);
184
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
185
+ sf = (float)NUM2DBL(x);
186
+ res = DBL2NUM((double)acosf(sf));
187
+ }
188
+ else
189
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
190
+
191
+ return res;
192
+ }
193
+
194
+
195
+ /* Computes the inverse hyperbolic cosine of x.
196
+ * @return [PaddleC::FloatBuffer, Float]
197
+ * @overload acosh(x)
198
+ * @param x [PaddleC::FloatBuffer]
199
+ * @return [PaddleC::FloatBuffer]
200
+ * @overload acosh(x)
201
+ * @param x [Float]
202
+ * @return [Float]
203
+ */
204
+ static VALUE paddlec_math_acosh(VALUE self, VALUE x)
205
+ {
206
+ VALUE res;
207
+ float sf;
208
+
209
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
210
+ res = rb_funcallv(x, id_acosh, 0, NULL);
211
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
212
+ sf = (float)NUM2DBL(x);
213
+ res = DBL2NUM((double)acoshf(sf));
214
+ }
215
+ else
216
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
217
+
218
+ return res;
219
+ }
220
+
221
+
222
+ /* Computes the arc sine of x. Returns -PI/2..PI/2.
223
+ * @return [PaddleC::FloatBuffer, Float]
224
+ * @overload asin(x)
225
+ * @param x [PaddleC::FloatBuffer]
226
+ * @return [PaddleC::FloatBuffer]
227
+ * @overload asin(x)
228
+ * @param x [Float]
229
+ * @return [Float]
230
+ */
231
+ static VALUE paddlec_math_asin(VALUE self, VALUE x)
232
+ {
233
+ VALUE res;
234
+ float sf;
235
+
236
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
237
+ res = rb_funcallv(x, id_asin, 0, NULL);
238
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
239
+ sf = (float)NUM2DBL(x);
240
+ res = DBL2NUM((double)asinf(sf));
241
+ }
242
+ else
243
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
244
+
245
+ return res;
246
+ }
247
+
248
+
249
+ /* Computes the inverse hyperbolic sine of x.
250
+ * @return [PaddleC::FloatBuffer, Float]
251
+ * @overload asinh(x)
252
+ * @param x [PaddleC::FloatBuffer]
253
+ * @return [PaddleC::FloatBuffer]
254
+ * @overload asinh(x)
255
+ * @param x [Float]
256
+ * @return [Float]
257
+ */
258
+ static VALUE paddlec_math_asinh(VALUE self, VALUE x)
259
+ {
260
+ VALUE res;
261
+ float sf;
262
+
263
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
264
+ res = rb_funcallv(x, id_asinh, 0, NULL);
265
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
266
+ sf = (float)NUM2DBL(x);
267
+ res = DBL2NUM((double)asinhf(sf));
268
+ }
269
+ else
270
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
271
+
272
+ return res;
273
+ }
274
+
275
+
276
+ /* Computes the arc tangent of x.
277
+ * @return [PaddleC::FloatBuffer, Float]
278
+ * @overload atan(x)
279
+ * @param x [PaddleC::FloatBuffer]
280
+ * @return [PaddleC::FloatBuffer]
281
+ * @overload atan(x)
282
+ * @param x [Float]
283
+ * @return [Float]
284
+ */
285
+ static VALUE paddlec_math_atan(VALUE self, VALUE x)
286
+ {
287
+ VALUE res;
288
+ float sf;
289
+
290
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
291
+ res = rb_funcallv(x, id_atan, 0, NULL);
292
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
293
+ sf = (float)NUM2DBL(x);
294
+ res = DBL2NUM((double)atanf(sf));
295
+ }
296
+ else
297
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
298
+
299
+ return res;
300
+ }
301
+
302
+
303
+ /* Computes the inverse hyperbolic tangent of x.
304
+ * @return [PaddleC::FloatBuffer, Float]
305
+ * @overload atanh(x)
306
+ * @param x [PaddleC::FloatBuffer]
307
+ * @return [PaddleC::FloatBuffer]
308
+ * @overload atanh(x)
309
+ * @param x [Float]
310
+ * @return [Float]
311
+ */
312
+ static VALUE paddlec_math_atanh(VALUE self, VALUE x)
313
+ {
314
+ VALUE res;
315
+ float sf;
316
+
317
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
318
+ res = rb_funcallv(x, id_atanh, 0, NULL);
319
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
320
+ sf = (float)NUM2DBL(x);
321
+ res = DBL2NUM((double)atanhf(sf));
322
+ }
323
+ else
324
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
325
+
326
+ return res;
327
+ }
328
+
329
+
330
+ /* Returns the cube root of x.
331
+ * @return [PaddleC::FloatBuffer, Float]
332
+ * @overload cbrt(x)
333
+ * @param x [PaddleC::FloatBuffer]
334
+ * @return [PaddleC::FloatBuffer]
335
+ * @overload cbrt(x)
336
+ * @param x [Float]
337
+ * @return [Float]
338
+ */
339
+ static VALUE paddlec_math_cbrt(VALUE self, VALUE x)
340
+ {
341
+ VALUE res;
342
+ float sf;
343
+
344
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
345
+ res = rb_funcallv(x, id_cbrt, 0, NULL);
346
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
347
+ sf = (float)NUM2DBL(x);
348
+ res = DBL2NUM((double)cbrtf(sf));
349
+ }
350
+ else
351
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
352
+
353
+ return res;
354
+ }
355
+
356
+
357
+ /* Computes the cosine of x (expressed in radians). Returns a Float in the range -1.0..1.0.
358
+ * @return [PaddleC::FloatBuffer, Float]
359
+ * @overload cos(x)
360
+ * @param x [PaddleC::FloatBuffer]
361
+ * @return [PaddleC::FloatBuffer]
362
+ * @overload cos(x)
363
+ * @param x [Float]
364
+ * @return [Float]
365
+ */
366
+ static VALUE paddlec_math_cos(VALUE self, VALUE x)
367
+ {
368
+ VALUE res;
369
+ float sf;
370
+
371
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
372
+ res = rb_funcallv(x, id_cos, 0, NULL);
373
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
374
+ sf = (float)NUM2DBL(x);
375
+ res = DBL2NUM((double)cosf(sf));
376
+ }
377
+ else
378
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
379
+
380
+ return res;
381
+ }
382
+
383
+
384
+ /* Computes the hyperbolic cosine of x.
385
+ * @return [PaddleC::FloatBuffer, Float]
386
+ * @overload cosh(x)
387
+ * @param x [PaddleC::FloatBuffer]
388
+ * @return [PaddleC::FloatBuffer]
389
+ * @overload cosh(x)
390
+ * @param x [Float]
391
+ * @return [Float]
392
+ */
393
+ static VALUE paddlec_math_cosh(VALUE self, VALUE x)
394
+ {
395
+ VALUE res;
396
+ float sf;
397
+
398
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
399
+ res = rb_funcallv(x, id_cosh, 0, NULL);
400
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
401
+ sf = (float)NUM2DBL(x);
402
+ res = DBL2NUM((double)coshf(sf));
403
+ }
404
+ else
405
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
406
+
407
+ return res;
408
+ }
409
+
410
+
411
+ /* Calculates the error function of x.
412
+ * @return [PaddleC::FloatBuffer, Float]
413
+ * @overload erf(x)
414
+ * @param x [PaddleC::FloatBuffer]
415
+ * @return [PaddleC::FloatBuffer]
416
+ * @overload erf(x)
417
+ * @param x [Float]
418
+ * @return [Float]
419
+ */
420
+ static VALUE paddlec_math_erf(VALUE self, VALUE x)
421
+ {
422
+ VALUE res;
423
+ float sf;
424
+
425
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
426
+ res = rb_funcallv(x, id_erf, 0, NULL);
427
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
428
+ sf = (float)NUM2DBL(x);
429
+ res = DBL2NUM((double)erff(sf));
430
+ }
431
+ else
432
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
433
+
434
+ return res;
435
+ }
436
+
437
+
438
+ /* Calculates the complementary error function of x.
439
+ * @return [PaddleC::FloatBuffer, Float]
440
+ * @overload erfc(x)
441
+ * @param x [PaddleC::FloatBuffer]
442
+ * @return [PaddleC::FloatBuffer]
443
+ * @overload erfc(x)
444
+ * @param x [Float]
445
+ * @return [Float]
446
+ */
447
+ static VALUE paddlec_math_erfc(VALUE self, VALUE x)
448
+ {
449
+ VALUE res;
450
+ float sf;
451
+
452
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
453
+ res = rb_funcallv(x, id_erfc, 0, NULL);
454
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
455
+ sf = (float)NUM2DBL(x);
456
+ res = DBL2NUM((double)erfcf(sf));
457
+ }
458
+ else
459
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
460
+
461
+ return res;
462
+ }
463
+
464
+
465
+ /* Calculates the value of e (the base of natural logarithms) raised to the power of x.
466
+ * @return [PaddleC::FloatBuffer, Float]
467
+ * @overload exp(x)
468
+ * @param x [PaddleC::FloatBuffer]
469
+ * @return [PaddleC::FloatBuffer]
470
+ * @overload exp(x)
471
+ * @param x [Float]
472
+ * @return [Float]
473
+ */
474
+ static VALUE paddlec_math_exp(VALUE self, VALUE x)
475
+ {
476
+ VALUE res;
477
+ float sf;
478
+
479
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
480
+ res = rb_funcallv(x, id_exp, 0, NULL);
481
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
482
+ sf = (float)NUM2DBL(x);
483
+ res = DBL2NUM((double)expf(sf));
484
+ }
485
+ else
486
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
487
+
488
+ return res;
489
+ }
490
+
491
+
492
+ /* Calculates the natural logarithm of x.
493
+ * @return [PaddleC::FloatBuffer, Float]
494
+ * @overload log(x)
495
+ * @param x [PaddleC::FloatBuffer]
496
+ * @return [PaddleC::FloatBuffer]
497
+ * @overload log(x)
498
+ * @param x [Float]
499
+ * @return [Float]
500
+ */
501
+ static VALUE paddlec_math_log(VALUE self, VALUE x)
502
+ {
503
+ VALUE res;
504
+ float sf;
505
+
506
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
507
+ res = rb_funcallv(x, id_log, 0, NULL);
508
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
509
+ sf = (float)NUM2DBL(x);
510
+ res = DBL2NUM((double)logf(sf));
511
+ }
512
+ else
513
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
514
+
515
+ return res;
516
+ }
517
+
518
+
519
+ /* Calculates the base 10 logarithm of x.
520
+ * @return [PaddleC::FloatBuffer, Float]
521
+ * @overload log10(x)
522
+ * @param x [PaddleC::FloatBuffer]
523
+ * @return [PaddleC::FloatBuffer]
524
+ * @overload log10(x)
525
+ * @param x [Float]
526
+ * @return [Float]
527
+ */
528
+ static VALUE paddlec_math_log10(VALUE self, VALUE x)
529
+ {
530
+ VALUE res;
531
+ float sf;
532
+
533
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
534
+ res = rb_funcallv(x, id_log10, 0, NULL);
535
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
536
+ sf = (float)NUM2DBL(x);
537
+ res = DBL2NUM((double)log10f(sf));
538
+ }
539
+ else
540
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
541
+
542
+ return res;
543
+ }
544
+
545
+
546
+ /* Calculate the base 2 logarithm of x.
547
+ * @return [PaddleC::FloatBuffer, Float]
548
+ * @overload log2(x)
549
+ * @param x [PaddleC::FloatBuffer]
550
+ * @return [PaddleC::FloatBuffer]
551
+ * @overload log2(x)
552
+ * @param x [Float]
553
+ * @return [Float]
554
+ */
555
+ static VALUE paddlec_math_log2(VALUE self, VALUE x)
556
+ {
557
+ VALUE res;
558
+ float sf;
559
+
560
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
561
+ res = rb_funcallv(x, id_log2, 0, NULL);
562
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
563
+ sf = (float)NUM2DBL(x);
564
+ res = DBL2NUM((double)log2f(sf));
565
+ }
566
+ else
567
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
568
+
569
+ return res;
570
+ }
571
+
572
+
573
+ /* Computes the sine of x (expressed in radians). Returns a Float in the range -1.0..1.0.
574
+ * @return [PaddleC::FloatBuffer, Float]
575
+ * @overload sin(x)
576
+ * @param x [PaddleC::FloatBuffer]
577
+ * @return [PaddleC::FloatBuffer]
578
+ * @overload sin(x)
579
+ * @param x [Float]
580
+ * @return [Float]
581
+ */
582
+ static VALUE paddlec_math_sin(VALUE self, VALUE x)
583
+ {
584
+ VALUE res;
585
+ float sf;
586
+
587
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
588
+ res = rb_funcallv(x, id_sin, 0, NULL);
589
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
590
+ sf = (float)NUM2DBL(x);
591
+ res = DBL2NUM((double)sinf(sf));
592
+ }
593
+ else
594
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
595
+
596
+ return res;
597
+ }
598
+
599
+
600
+ /* Computes the hyperbolic sine of x.
601
+ * @return [PaddleC::FloatBuffer, Float]
602
+ * @overload sinh(x)
603
+ * @param x [PaddleC::FloatBuffer]
604
+ * @return [PaddleC::FloatBuffer]
605
+ * @overload sinh(x)
606
+ * @param x [Float]
607
+ * @return [Float]
608
+ */
609
+ static VALUE paddlec_math_sinh(VALUE self, VALUE x)
610
+ {
611
+ VALUE res;
612
+ float sf;
613
+
614
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
615
+ res = rb_funcallv(x, id_sinh, 0, NULL);
616
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
617
+ sf = (float)NUM2DBL(x);
618
+ res = DBL2NUM((double)sinhf(sf));
619
+ }
620
+ else
621
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
622
+
623
+ return res;
624
+ }
625
+
626
+
627
+ /* Computes the non-negative square root of x.
628
+ * @return [PaddleC::FloatBuffer, Float]
629
+ * @overload sqrt(x)
630
+ * @param x [PaddleC::FloatBuffer]
631
+ * @return [PaddleC::FloatBuffer]
632
+ * @overload sqrt(x)
633
+ * @param x [Float]
634
+ * @return [Float]
635
+ */
636
+ static VALUE paddlec_math_sqrt(VALUE self, VALUE x)
637
+ {
638
+ VALUE res;
639
+ float sf;
640
+
641
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
642
+ res = rb_funcallv(x, id_sqrt, 0, NULL);
643
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
644
+ sf = (float)NUM2DBL(x);
645
+ res = DBL2NUM((double)sqrtf(sf));
646
+ }
647
+ else
648
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
649
+
650
+ return res;
651
+ }
652
+
653
+
654
+ /* Computes the tangent of x (expressed in radians).
655
+ * @return [PaddleC::FloatBuffer, Float]
656
+ * @overload tan(x)
657
+ * @param x [PaddleC::FloatBuffer]
658
+ * @return [PaddleC::FloatBuffer]
659
+ * @overload tan(x)
660
+ * @param x [Float]
661
+ * @return [Float]
662
+ */
663
+ static VALUE paddlec_math_tan(VALUE self, VALUE x)
664
+ {
665
+ VALUE res;
666
+ float sf;
667
+
668
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
669
+ res = rb_funcallv(x, id_tan, 0, NULL);
670
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
671
+ sf = (float)NUM2DBL(x);
672
+ res = DBL2NUM((double)tanf(sf));
673
+ }
674
+ else
675
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
676
+
677
+ return res;
678
+ }
679
+
680
+
681
+ /* Computes the hyperbolic tangent of x.
682
+ * @return [PaddleC::FloatBuffer, Float]
683
+ * @overload tanh(x)
684
+ * @param x [PaddleC::FloatBuffer]
685
+ * @return [PaddleC::FloatBuffer]
686
+ * @overload tanh(x)
687
+ * @param x [Float]
688
+ * @return [Float]
689
+ */
690
+ static VALUE paddlec_math_tanh(VALUE self, VALUE x)
691
+ {
692
+ VALUE res;
693
+ float sf;
694
+
695
+ if (rb_obj_is_kind_of(x, c_FloatBuffer))
696
+ res = rb_funcallv(x, id_tanh, 0, NULL);
697
+ else if (rb_obj_is_kind_of(x, rb_cNumeric) && !rb_obj_is_kind_of(x, rb_cComplex)) {
698
+ sf = (float)NUM2DBL(x);
699
+ res = DBL2NUM((double)tanhf(sf));
700
+ }
701
+ else
702
+ rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a non complex Numeric, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(x)));
703
+
704
+ return res;
705
+ }
706
+
707
+ /* @!endgroup
708
+ */
709
+
710
+ void Init_paddlec()
711
+ {
712
+ id_each = rb_intern("each");
713
+ id_collectI = rb_intern("collect!");
714
+ id_to_enum = rb_intern("to_enum");
715
+ id_length = rb_intern("length");
716
+ id_real = rb_intern("real");
717
+ id_imag = rb_intern("imag");
718
+ id_buffer = rb_intern("buffer");
719
+ id_delayed = rb_intern("delayed");
720
+ id_zip = rb_intern("zip");
721
+ id_join = rb_intern("join");
722
+ id_to_s = rb_intern("to_s");
723
+ id_to_gplot = rb_intern("to_gplot");
724
+ id_acos = rb_intern("acos");
725
+ id_acosh = rb_intern("acosh");
726
+ id_asin = rb_intern("asin");
727
+ id_asinh = rb_intern("asinh");
728
+ id_atan = rb_intern("atan");
729
+ id_atanh = rb_intern("atanh");
730
+ id_cbrt = rb_intern("cbrt");
731
+ id_cos = rb_intern("cos");
732
+ id_cosh = rb_intern("cosh");
733
+ id_erf = rb_intern("erf");
734
+ id_erfc = rb_intern("erfc");
735
+ id_exp = rb_intern("exp");
736
+ id_log = rb_intern("log");
737
+ id_log10 = rb_intern("log10");
738
+ id_log2 = rb_intern("log2");
739
+ id_sin = rb_intern("sin");
740
+ id_sinh = rb_intern("sinh");
741
+ id_sqrt = rb_intern("sqrt");
742
+ id_tan = rb_intern("tan");
743
+ id_tanh = rb_intern("tanh");
744
+ id_u8 = rb_intern("u8");
745
+ id_s8 = rb_intern("s8");
746
+ id_u16 = rb_intern("u16");
747
+ id_s16 = rb_intern("s16");
748
+ id_u32 = rb_intern("u32");
749
+ id_s32 = rb_intern("s32");
750
+ id_f32 = rb_intern("f32");
751
+
752
+ paddlec_check_if_FFI_is_defined();
753
+
754
+ m_PaddleC = rb_define_module("PaddleC");
755
+ rb_define_module_function(m_PaddleC, "accelerator", paddlec_paddlec_accelerator, 0);
756
+ rb_define_module_function(m_PaddleC, "acos", paddlec_math_acos, 1);
757
+ rb_define_module_function(m_PaddleC, "acosh", paddlec_math_acosh, 1);
758
+ rb_define_module_function(m_PaddleC, "asin", paddlec_math_asin, 1);
759
+ rb_define_module_function(m_PaddleC, "asinh", paddlec_math_asinh, 1);
760
+ rb_define_module_function(m_PaddleC, "atan", paddlec_math_atan, 1);
761
+ rb_define_module_function(m_PaddleC, "atanh", paddlec_math_atanh, 1);
762
+ rb_define_module_function(m_PaddleC, "cbrt", paddlec_math_cbrt, 1);
763
+ rb_define_module_function(m_PaddleC, "cos", paddlec_math_cos, 1);
764
+ rb_define_module_function(m_PaddleC, "cosh", paddlec_math_cosh, 1);
765
+ rb_define_module_function(m_PaddleC, "erf", paddlec_math_erf, 1);
766
+ rb_define_module_function(m_PaddleC, "erfc", paddlec_math_erfc, 1);
767
+ rb_define_module_function(m_PaddleC, "exp", paddlec_math_exp, 1);
768
+ rb_define_module_function(m_PaddleC, "log", paddlec_math_log, 1);
769
+ rb_define_module_function(m_PaddleC, "log10", paddlec_math_log10, 1);
770
+ rb_define_module_function(m_PaddleC, "log2", paddlec_math_log2, 1);
771
+ rb_define_module_function(m_PaddleC, "sin", paddlec_math_sin, 1);
772
+ rb_define_module_function(m_PaddleC, "sinh", paddlec_math_sinh, 1);
773
+ rb_define_module_function(m_PaddleC, "sqrt", paddlec_math_sqrt, 1);
774
+ rb_define_module_function(m_PaddleC, "tan", paddlec_math_tan, 1);
775
+ rb_define_module_function(m_PaddleC, "tanh", paddlec_math_tanh, 1);
776
+
777
+ Init_paddlec_float_buffer();
778
+ Init_paddlec_complex_buffer();
779
+ Init_paddlec_fir_filter();
780
+ Init_paddlec_delay();
781
+
782
+ #ifdef HAVE_PULSEAUDIO_L
783
+ Init_paddlec_pulseaudio();
784
+ #endif
785
+
786
+ rb_define_method(rb_cArray, "to_gplot", paddlec_array_to_gplot, 0);
787
+ }
788
+