wavspa 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +196 -0
- data/Rakefile +2 -0
- data/bin/wavfft +167 -0
- data/bin/wavlet +160 -0
- data/example/Call_To_Quarters-fft.png +0 -0
- data/example/Call_To_Quarters-wavelet.png +0 -0
- data/ext/wavspa/fb/extconf.rb +3 -0
- data/ext/wavspa/fb/rb_fb.c +690 -0
- data/ext/wavspa/fft/extconf.rb +6 -0
- data/ext/wavspa/fft/fft.c +918 -0
- data/ext/wavspa/fft/fft.h +62 -0
- data/ext/wavspa/fft/fftsg.c +3314 -0
- data/ext/wavspa/fft/rb_fft.c +458 -0
- data/ext/wavspa/wavelet/extconf.rb +37 -0
- data/ext/wavspa/wavelet/rb_wavelet.c +706 -0
- data/ext/wavspa/wavelet/walet.c +803 -0
- data/ext/wavspa/wavelet/walet.h +59 -0
- data/lib/wav.rb +87 -0
- data/lib/wavspa/common.rb +74 -0
- data/lib/wavspa/version.rb +3 -0
- data/lib/wavspa/wavfft/main.rb +130 -0
- data/lib/wavspa/wavfft/preset.rb +54 -0
- data/lib/wavspa/wavlet/main.rb +139 -0
- data/lib/wavspa/wavlet/preset.rb +38 -0
- data/wavspa.gemspec +47 -0
- metadata +119 -0
@@ -0,0 +1,706 @@
|
|
1
|
+
/*
|
2
|
+
* Wavelet library interface for Ruby.
|
3
|
+
*
|
4
|
+
* Copyright (C) 2016 Hiroshi Kuwagata <kgt9221@gmail.com>
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <string.h>
|
9
|
+
|
10
|
+
#include "ruby.h"
|
11
|
+
#include "ruby/thread.h"
|
12
|
+
#include "walet.h"
|
13
|
+
|
14
|
+
#define N(x) (sizeof((x))/sizeof(*(x)))
|
15
|
+
#define RUNTIME_ERROR(...) rb_raise(rb_eRuntimeError, __VA_ARGS__)
|
16
|
+
#define ARGUMENT_ERROR(...) rb_raise(rb_eArgError, __VA_ARGS__)
|
17
|
+
#define RB_FFT(p) ((rb_fft_t*)(p))
|
18
|
+
#define EQ_STR(val,str) (rb_to_id(val) == rb_intern(str))
|
19
|
+
|
20
|
+
typedef struct {
|
21
|
+
walet_t* wl;
|
22
|
+
} rb_wavelet_t;
|
23
|
+
|
24
|
+
static VALUE wavspa_module;
|
25
|
+
static VALUE wavelet_klass;
|
26
|
+
|
27
|
+
static const char* wavelet_opts_keys[] = {
|
28
|
+
"sigma", // {float}
|
29
|
+
"frequency", // {float}
|
30
|
+
"range", // {Range}
|
31
|
+
"scale_mode", // {str}
|
32
|
+
"output_width", // {int}
|
33
|
+
};
|
34
|
+
|
35
|
+
static ID wavelet_opts_ids[N(wavelet_opts_keys)];
|
36
|
+
|
37
|
+
VALUE symb_linear_scale;
|
38
|
+
VALUE symb_log_scale;
|
39
|
+
|
40
|
+
static void
|
41
|
+
rb_wavelet_free(void* _ptr)
|
42
|
+
{
|
43
|
+
rb_wavelet_t* ptr;
|
44
|
+
|
45
|
+
ptr = (rb_wavelet_t*)_ptr;
|
46
|
+
|
47
|
+
if (ptr->wl != NULL) walet_destroy(ptr->wl);
|
48
|
+
|
49
|
+
free(ptr);
|
50
|
+
}
|
51
|
+
|
52
|
+
static VALUE
|
53
|
+
rb_wavelet_alloc(VALUE self)
|
54
|
+
{
|
55
|
+
rb_wavelet_t* ptr;
|
56
|
+
|
57
|
+
ptr = ALLOC(rb_wavelet_t);
|
58
|
+
memset(ptr, 0, sizeof(*ptr));
|
59
|
+
|
60
|
+
return Data_Wrap_Struct(wavelet_klass, 0, rb_wavelet_free, ptr);
|
61
|
+
}
|
62
|
+
|
63
|
+
static void
|
64
|
+
eval_wavelet_opt_sigma(rb_wavelet_t* ptr, VALUE opt)
|
65
|
+
{
|
66
|
+
int err;
|
67
|
+
|
68
|
+
if (opt != Qundef) {
|
69
|
+
err = walet_set_sigma(ptr->wl, NUM2DBL(opt));
|
70
|
+
if (err) {
|
71
|
+
RUNTIME_ERROR("walet_set_sigma() failed. [err=%d]", err);
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
static void
|
77
|
+
eval_wavelet_opt_frequency(rb_wavelet_t* ptr, VALUE opt)
|
78
|
+
{
|
79
|
+
int err;
|
80
|
+
|
81
|
+
if (opt != Qundef) {
|
82
|
+
err = walet_set_frequency(ptr->wl, NUM2DBL(opt));
|
83
|
+
if (err) {
|
84
|
+
RUNTIME_ERROR("walet_set_frequency() failed. [err=%d]", err);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
static void
|
90
|
+
eval_wavelet_opt_range(rb_wavelet_t* ptr, VALUE opt)
|
91
|
+
{
|
92
|
+
VALUE begin;
|
93
|
+
VALUE end;
|
94
|
+
int err;
|
95
|
+
|
96
|
+
if (opt != Qundef) {
|
97
|
+
begin = rb_funcall(opt, rb_intern("begin"), 0);
|
98
|
+
end = rb_funcall(opt, rb_intern("end"), 0);
|
99
|
+
err = walet_set_range(ptr->wl, NUM2DBL(begin), NUM2DBL(end));
|
100
|
+
if (err) {
|
101
|
+
RUNTIME_ERROR("walet_set_range() failed. [err=%d]", err);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
static void
|
107
|
+
eval_wavelet_opt_scale_mode(rb_wavelet_t* ptr, VALUE opt)
|
108
|
+
{
|
109
|
+
int err;
|
110
|
+
int mode;
|
111
|
+
|
112
|
+
if (opt != Qundef) {
|
113
|
+
if (EQ_STR(opt, "LINEARSCALE") || EQ_STR(opt, "LINEAR")) {
|
114
|
+
mode = WALET_LINEARSCALE_MODE;
|
115
|
+
|
116
|
+
} else if (EQ_STR(opt, "LOGSCALE") || EQ_STR(opt, "LOG")) {
|
117
|
+
mode = WALET_LOGSCALE_MODE;
|
118
|
+
|
119
|
+
} else {
|
120
|
+
ARGUMENT_ERROR("unsupported value.");
|
121
|
+
}
|
122
|
+
|
123
|
+
err = walet_set_scale_mode(ptr->wl, mode);
|
124
|
+
if (err) {
|
125
|
+
RUNTIME_ERROR("walet_set_scale_mode() failed. [err=%d]", err);
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
static void
|
131
|
+
eval_wavelet_opt_output_width(rb_wavelet_t* ptr, VALUE opt)
|
132
|
+
{
|
133
|
+
int err;
|
134
|
+
|
135
|
+
if (opt != Qundef) {
|
136
|
+
err = walet_set_output_width(ptr->wl, FIX2INT(opt));
|
137
|
+
if (err) {
|
138
|
+
RUNTIME_ERROR("walet_set_output_width() failed. [err=%d]", err);
|
139
|
+
}
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
static void
|
144
|
+
set_wavelet_context(rb_wavelet_t* ptr, VALUE opt)
|
145
|
+
{
|
146
|
+
VALUE opts[N(wavelet_opts_ids)];
|
147
|
+
|
148
|
+
/*
|
149
|
+
* parse options
|
150
|
+
*/
|
151
|
+
rb_get_kwargs(opt, wavelet_opts_ids, 0, N(wavelet_opts_ids), opts);
|
152
|
+
|
153
|
+
/*
|
154
|
+
* set context
|
155
|
+
*/
|
156
|
+
eval_wavelet_opt_sigma(ptr, opts[0]);
|
157
|
+
eval_wavelet_opt_frequency(ptr, opts[1]);
|
158
|
+
eval_wavelet_opt_range(ptr, opts[2]);
|
159
|
+
eval_wavelet_opt_scale_mode(ptr, opts[3]);
|
160
|
+
eval_wavelet_opt_output_width(ptr, opts[4]);
|
161
|
+
}
|
162
|
+
|
163
|
+
static VALUE
|
164
|
+
rb_wavelet_initialize(int argc, VALUE argv[], VALUE self)
|
165
|
+
{
|
166
|
+
rb_wavelet_t* ptr;
|
167
|
+
int err;
|
168
|
+
VALUE opt;
|
169
|
+
|
170
|
+
/*
|
171
|
+
* strip object
|
172
|
+
*/
|
173
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
174
|
+
|
175
|
+
/*
|
176
|
+
* parse argument
|
177
|
+
*/
|
178
|
+
rb_scan_args(argc, argv, "01", &opt);
|
179
|
+
|
180
|
+
if (opt != Qnil) {
|
181
|
+
Check_Type(opt, T_HASH);
|
182
|
+
}
|
183
|
+
|
184
|
+
/*
|
185
|
+
* create wavelet context
|
186
|
+
*/
|
187
|
+
err = walet_new(&ptr->wl);
|
188
|
+
if (err) {
|
189
|
+
RUNTIME_ERROR("walet_new() failes [err=%d]\n", err);
|
190
|
+
}
|
191
|
+
|
192
|
+
/*
|
193
|
+
* set context
|
194
|
+
*/
|
195
|
+
if (opt != Qnil) {
|
196
|
+
set_wavelet_context(ptr, opt);
|
197
|
+
}
|
198
|
+
|
199
|
+
return self;
|
200
|
+
}
|
201
|
+
|
202
|
+
static VALUE
|
203
|
+
rb_wavelet_get_sigma(VALUE self)
|
204
|
+
{
|
205
|
+
VALUE ret;
|
206
|
+
rb_wavelet_t* ptr;
|
207
|
+
|
208
|
+
/*
|
209
|
+
* strip object
|
210
|
+
*/
|
211
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
212
|
+
|
213
|
+
/*
|
214
|
+
* create return paramter
|
215
|
+
*/
|
216
|
+
ret = DBL2NUM(ptr->wl->sigma);
|
217
|
+
|
218
|
+
return ret;
|
219
|
+
}
|
220
|
+
|
221
|
+
static VALUE
|
222
|
+
rb_wavelet_set_sigma(VALUE self, VALUE sigma)
|
223
|
+
{
|
224
|
+
rb_wavelet_t* ptr;
|
225
|
+
|
226
|
+
/*
|
227
|
+
* strip object
|
228
|
+
*/
|
229
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
230
|
+
|
231
|
+
/*
|
232
|
+
* call setter function
|
233
|
+
*/
|
234
|
+
eval_wavelet_opt_sigma(ptr, sigma);
|
235
|
+
|
236
|
+
return sigma;
|
237
|
+
}
|
238
|
+
|
239
|
+
static VALUE
|
240
|
+
rb_wavelet_get_frequency(VALUE self)
|
241
|
+
{
|
242
|
+
VALUE ret;
|
243
|
+
rb_wavelet_t* ptr;
|
244
|
+
|
245
|
+
/*
|
246
|
+
* strip object
|
247
|
+
*/
|
248
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
249
|
+
|
250
|
+
/*
|
251
|
+
* create return paramter
|
252
|
+
*/
|
253
|
+
ret = DBL2NUM(ptr->wl->fq_s);
|
254
|
+
|
255
|
+
return ret;
|
256
|
+
}
|
257
|
+
|
258
|
+
static VALUE
|
259
|
+
rb_wavelet_set_frequency(VALUE self, VALUE fq)
|
260
|
+
{
|
261
|
+
rb_wavelet_t* ptr;
|
262
|
+
|
263
|
+
/*
|
264
|
+
* strip object
|
265
|
+
*/
|
266
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
267
|
+
|
268
|
+
/*
|
269
|
+
* call setter function
|
270
|
+
*/
|
271
|
+
eval_wavelet_opt_frequency(ptr, fq);
|
272
|
+
|
273
|
+
return fq;
|
274
|
+
}
|
275
|
+
|
276
|
+
static VALUE
|
277
|
+
rb_wavelet_get_range(VALUE self)
|
278
|
+
{
|
279
|
+
VALUE ret;
|
280
|
+
rb_wavelet_t* ptr;
|
281
|
+
|
282
|
+
VALUE begin;
|
283
|
+
VALUE end;
|
284
|
+
|
285
|
+
/*
|
286
|
+
* strip object
|
287
|
+
*/
|
288
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
289
|
+
|
290
|
+
/*
|
291
|
+
* create return paramter
|
292
|
+
*/
|
293
|
+
begin = rb_float_new(ptr->wl->fq_l);
|
294
|
+
end = rb_float_new(ptr->wl->fq_h);
|
295
|
+
ret = rb_range_new(begin, end, 0);
|
296
|
+
|
297
|
+
return ret;
|
298
|
+
}
|
299
|
+
|
300
|
+
static VALUE
|
301
|
+
rb_wavelet_set_range(VALUE self, VALUE range)
|
302
|
+
{
|
303
|
+
rb_wavelet_t* ptr;
|
304
|
+
|
305
|
+
/*
|
306
|
+
* strip object
|
307
|
+
*/
|
308
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
309
|
+
|
310
|
+
/*
|
311
|
+
* call setter function
|
312
|
+
*/
|
313
|
+
eval_wavelet_opt_range(ptr, range);
|
314
|
+
|
315
|
+
return range;
|
316
|
+
}
|
317
|
+
|
318
|
+
static VALUE
|
319
|
+
rb_wavelet_get_scale_mode(VALUE self)
|
320
|
+
{
|
321
|
+
VALUE ret;
|
322
|
+
rb_wavelet_t* ptr;
|
323
|
+
|
324
|
+
/*
|
325
|
+
* strip object
|
326
|
+
*/
|
327
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
328
|
+
|
329
|
+
/*
|
330
|
+
* create return parameter
|
331
|
+
*/
|
332
|
+
switch (ptr->wl->mode) {
|
333
|
+
case 1:
|
334
|
+
ret = symb_linear_scale;
|
335
|
+
break;
|
336
|
+
|
337
|
+
case 2:
|
338
|
+
ret = symb_log_scale;
|
339
|
+
break;
|
340
|
+
|
341
|
+
default:
|
342
|
+
RUNTIME_ERROR("Really?");
|
343
|
+
}
|
344
|
+
|
345
|
+
return ret;
|
346
|
+
}
|
347
|
+
|
348
|
+
static VALUE
|
349
|
+
rb_wavelet_set_scale_mode(VALUE self, VALUE mode)
|
350
|
+
{
|
351
|
+
rb_wavelet_t* ptr;
|
352
|
+
|
353
|
+
/*
|
354
|
+
* strip object
|
355
|
+
*/
|
356
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
357
|
+
|
358
|
+
/*
|
359
|
+
* call setter function
|
360
|
+
*/
|
361
|
+
eval_wavelet_opt_scale_mode(ptr, mode);
|
362
|
+
|
363
|
+
return mode;
|
364
|
+
}
|
365
|
+
|
366
|
+
static VALUE
|
367
|
+
rb_wavelet_get_output_width(VALUE self)
|
368
|
+
{
|
369
|
+
VALUE ret;
|
370
|
+
rb_wavelet_t* ptr;
|
371
|
+
|
372
|
+
/*
|
373
|
+
* strip object
|
374
|
+
*/
|
375
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
376
|
+
|
377
|
+
/*
|
378
|
+
* create return paramter
|
379
|
+
*/
|
380
|
+
ret = INT2FIX(ptr->wl->width);
|
381
|
+
|
382
|
+
return ret;
|
383
|
+
}
|
384
|
+
|
385
|
+
|
386
|
+
static VALUE
|
387
|
+
rb_wavelet_set_output_width(VALUE self, VALUE width)
|
388
|
+
{
|
389
|
+
rb_wavelet_t* ptr;
|
390
|
+
|
391
|
+
/*
|
392
|
+
* strip object
|
393
|
+
*/
|
394
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
395
|
+
|
396
|
+
/*
|
397
|
+
* call setter function
|
398
|
+
*/
|
399
|
+
eval_wavelet_opt_output_width(ptr, width);
|
400
|
+
|
401
|
+
return width;
|
402
|
+
}
|
403
|
+
|
404
|
+
static int
|
405
|
+
copy_rb_string(char* dst, VALUE _src, int lim)
|
406
|
+
{
|
407
|
+
int ret;
|
408
|
+
char* src;
|
409
|
+
int n;
|
410
|
+
|
411
|
+
/*
|
412
|
+
* initialize
|
413
|
+
*/
|
414
|
+
ret = 0;
|
415
|
+
src = RSTRING_PTR(_src);
|
416
|
+
n = RSTRING_LEN(_src);
|
417
|
+
|
418
|
+
do {
|
419
|
+
/*
|
420
|
+
* check length
|
421
|
+
*/
|
422
|
+
if (n >= lim) {
|
423
|
+
ret = !0;
|
424
|
+
break;
|
425
|
+
}
|
426
|
+
|
427
|
+
/*
|
428
|
+
* copy data
|
429
|
+
*/
|
430
|
+
memset(dst, 0, lim);
|
431
|
+
memcpy(dst, src, n);
|
432
|
+
} while (0);
|
433
|
+
|
434
|
+
return ret;
|
435
|
+
|
436
|
+
}
|
437
|
+
|
438
|
+
static VALUE
|
439
|
+
rb_wavelet_put_in(VALUE self, VALUE _fmt, VALUE _smpl)
|
440
|
+
{
|
441
|
+
rb_wavelet_t* ptr;
|
442
|
+
int err;
|
443
|
+
void* smpl;
|
444
|
+
char fmt[8];
|
445
|
+
int n;
|
446
|
+
|
447
|
+
/*
|
448
|
+
* check argument
|
449
|
+
*/
|
450
|
+
Check_Type(_fmt, T_STRING);
|
451
|
+
Check_Type(_smpl, T_STRING);
|
452
|
+
|
453
|
+
/*
|
454
|
+
* stript object
|
455
|
+
*/
|
456
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
457
|
+
|
458
|
+
/*
|
459
|
+
* unpack argument
|
460
|
+
*/
|
461
|
+
smpl = RSTRING_PTR(_smpl);
|
462
|
+
n = RSTRING_LEN(_smpl);
|
463
|
+
|
464
|
+
err = copy_rb_string(fmt, _fmt, N(fmt));
|
465
|
+
if (err) {
|
466
|
+
ARGUMENT_ERROR("Illeagal format string.\n");
|
467
|
+
}
|
468
|
+
|
469
|
+
/*
|
470
|
+
* eval format
|
471
|
+
*/
|
472
|
+
if (strcasecmp("u8", fmt) == 0) {
|
473
|
+
/* Nothing */
|
474
|
+
|
475
|
+
} else if(strcasecmp("u16be", fmt) == 0 ||
|
476
|
+
strcasecmp("u16le", fmt) == 0 ||
|
477
|
+
strcasecmp("s16be", fmt) == 0 ||
|
478
|
+
strcasecmp("s16le", fmt) == 0 ) {
|
479
|
+
n /= 2;
|
480
|
+
|
481
|
+
} else if(strcasecmp("u24be", fmt) == 0 ||
|
482
|
+
strcasecmp("u24le", fmt) == 0) {
|
483
|
+
n /= 3;
|
484
|
+
|
485
|
+
} else {
|
486
|
+
ARGUMENT_ERROR("Illeagal format string.\n");
|
487
|
+
}
|
488
|
+
|
489
|
+
/*
|
490
|
+
* call base library
|
491
|
+
*/
|
492
|
+
err = walet_put_in(ptr->wl, fmt, smpl, n);
|
493
|
+
if (err) {
|
494
|
+
RUNTIME_ERROR("walet_put_in() failed [err=%d]\n", err);
|
495
|
+
}
|
496
|
+
|
497
|
+
return self;
|
498
|
+
}
|
499
|
+
|
500
|
+
typedef struct {
|
501
|
+
int err;
|
502
|
+
walet_t* ptr;
|
503
|
+
int pos;
|
504
|
+
} transform_arg_t;
|
505
|
+
|
506
|
+
static void*
|
507
|
+
_transform(void* data)
|
508
|
+
{
|
509
|
+
transform_arg_t* arg;
|
510
|
+
|
511
|
+
arg = (transform_arg_t*)data;
|
512
|
+
|
513
|
+
arg->err = walet_transform(arg->ptr, arg->pos);
|
514
|
+
|
515
|
+
return NULL;
|
516
|
+
}
|
517
|
+
|
518
|
+
static int
|
519
|
+
transform(walet_t* ptr, int pos)
|
520
|
+
{
|
521
|
+
transform_arg_t arg;
|
522
|
+
|
523
|
+
arg.ptr = ptr;
|
524
|
+
arg.pos = pos;
|
525
|
+
|
526
|
+
rb_thread_call_without_gvl(_transform, &arg, RUBY_UBF_PROCESS, NULL);
|
527
|
+
|
528
|
+
return arg.err;
|
529
|
+
}
|
530
|
+
|
531
|
+
static VALUE
|
532
|
+
rb_wavelet_transform(VALUE self, VALUE pos)
|
533
|
+
{
|
534
|
+
rb_wavelet_t* ptr;
|
535
|
+
int err;
|
536
|
+
|
537
|
+
/*
|
538
|
+
* stript object
|
539
|
+
*/
|
540
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
541
|
+
|
542
|
+
/*
|
543
|
+
* call base library
|
544
|
+
*/
|
545
|
+
err = transform(ptr->wl, NUM2INT(pos));
|
546
|
+
if (err) {
|
547
|
+
RUNTIME_ERROR("walet_transform() failed [err=%d]\n", err);
|
548
|
+
}
|
549
|
+
|
550
|
+
return self;
|
551
|
+
}
|
552
|
+
|
553
|
+
typedef struct {
|
554
|
+
int err;
|
555
|
+
walet_t* ptr;
|
556
|
+
double* dst;
|
557
|
+
} calc_power_arg_t;
|
558
|
+
|
559
|
+
static void*
|
560
|
+
_calc_power(void* data)
|
561
|
+
{
|
562
|
+
calc_power_arg_t* arg;
|
563
|
+
|
564
|
+
arg = (calc_power_arg_t*)data;
|
565
|
+
|
566
|
+
arg->err = walet_calc_power(arg->ptr, arg->dst);
|
567
|
+
|
568
|
+
return NULL;
|
569
|
+
}
|
570
|
+
|
571
|
+
static int
|
572
|
+
calc_power(walet_t* ptr, double* dst)
|
573
|
+
{
|
574
|
+
calc_power_arg_t arg;
|
575
|
+
|
576
|
+
arg.ptr = ptr;
|
577
|
+
arg.dst = dst;
|
578
|
+
|
579
|
+
rb_thread_call_without_gvl(_calc_power, &arg, RUBY_UBF_PROCESS, NULL);
|
580
|
+
|
581
|
+
return arg.err;
|
582
|
+
}
|
583
|
+
|
584
|
+
static VALUE
|
585
|
+
rb_wavelet_power(VALUE self)
|
586
|
+
{
|
587
|
+
rb_wavelet_t* ptr;
|
588
|
+
VALUE ret;
|
589
|
+
int err;
|
590
|
+
|
591
|
+
/*
|
592
|
+
* strip object
|
593
|
+
*/
|
594
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
595
|
+
|
596
|
+
/*
|
597
|
+
* create return buffer
|
598
|
+
*/
|
599
|
+
ret = rb_str_buf_new(sizeof(double) * ptr->wl->width);
|
600
|
+
rb_str_set_len(ret, sizeof(double) * ptr->wl->width);
|
601
|
+
|
602
|
+
/*
|
603
|
+
* call base library
|
604
|
+
*/
|
605
|
+
err = calc_power(ptr->wl, (double*)RSTRING_PTR(ret));
|
606
|
+
if (err) {
|
607
|
+
RUNTIME_ERROR("walet_calc_power() failed [err=%d]\n", err);
|
608
|
+
}
|
609
|
+
|
610
|
+
return ret;
|
611
|
+
}
|
612
|
+
|
613
|
+
typedef struct {
|
614
|
+
int err;
|
615
|
+
walet_t* ptr;
|
616
|
+
double* dst;
|
617
|
+
} calc_amplitude_arg_t;
|
618
|
+
|
619
|
+
static void*
|
620
|
+
_calc_amplitude(void* data)
|
621
|
+
{
|
622
|
+
calc_amplitude_arg_t* arg;
|
623
|
+
|
624
|
+
arg = (calc_amplitude_arg_t*)data;
|
625
|
+
|
626
|
+
arg->err = walet_calc_amplitude(arg->ptr, arg->dst);
|
627
|
+
|
628
|
+
return NULL;
|
629
|
+
}
|
630
|
+
|
631
|
+
static int
|
632
|
+
calc_amplitude(walet_t* ptr, double* dst)
|
633
|
+
{
|
634
|
+
calc_amplitude_arg_t arg;
|
635
|
+
|
636
|
+
arg.ptr = ptr;
|
637
|
+
arg.dst = dst;
|
638
|
+
|
639
|
+
rb_thread_call_without_gvl(_calc_amplitude, &arg, RUBY_UBF_PROCESS, NULL);
|
640
|
+
|
641
|
+
return arg.err;
|
642
|
+
}
|
643
|
+
|
644
|
+
static VALUE
|
645
|
+
rb_wavelet_amplitude(VALUE self)
|
646
|
+
{
|
647
|
+
rb_wavelet_t* ptr;
|
648
|
+
VALUE ret;
|
649
|
+
int err;
|
650
|
+
|
651
|
+
/*
|
652
|
+
* strip object
|
653
|
+
*/
|
654
|
+
Data_Get_Struct(self, rb_wavelet_t, ptr);
|
655
|
+
|
656
|
+
/*
|
657
|
+
* create return buffer
|
658
|
+
*/
|
659
|
+
ret = rb_str_buf_new(sizeof(double) * ptr->wl->width);
|
660
|
+
rb_str_set_len(ret, sizeof(double) * ptr->wl->width);
|
661
|
+
|
662
|
+
/*
|
663
|
+
* call base library
|
664
|
+
*/
|
665
|
+
err = calc_amplitude(ptr->wl, (double*)RSTRING_PTR(ret));
|
666
|
+
if (err) {
|
667
|
+
RUNTIME_ERROR("walet_calc_amplitude() failed [err=%d]\n", err);
|
668
|
+
}
|
669
|
+
|
670
|
+
return ret;
|
671
|
+
}
|
672
|
+
|
673
|
+
void
|
674
|
+
Init_wavelet()
|
675
|
+
{
|
676
|
+
int i;
|
677
|
+
|
678
|
+
wavspa_module = rb_define_module("WavSpectrumAnalyzer");
|
679
|
+
wavelet_klass = rb_define_class_under(wavspa_module, "Wavelet", rb_cObject);
|
680
|
+
|
681
|
+
rb_define_alloc_func(wavelet_klass, rb_wavelet_alloc);
|
682
|
+
|
683
|
+
rb_define_method(wavelet_klass, "initialize", rb_wavelet_initialize, -1);
|
684
|
+
rb_define_method(wavelet_klass, "sigma", rb_wavelet_get_sigma, 0);
|
685
|
+
rb_define_method(wavelet_klass, "sigma=", rb_wavelet_set_sigma, 1);
|
686
|
+
rb_define_method(wavelet_klass, "frequency", rb_wavelet_get_frequency, 0);
|
687
|
+
rb_define_method(wavelet_klass, "frequency=", rb_wavelet_set_frequency, 1);
|
688
|
+
rb_define_method(wavelet_klass, "range", rb_wavelet_get_range, 0);
|
689
|
+
rb_define_method(wavelet_klass, "range=", rb_wavelet_set_range, 1);
|
690
|
+
rb_define_method(wavelet_klass, "scale_mode", rb_wavelet_get_scale_mode, 0);
|
691
|
+
rb_define_method(wavelet_klass, "scale_mode=", rb_wavelet_set_scale_mode, 1);
|
692
|
+
rb_define_method(wavelet_klass, "width", rb_wavelet_get_output_width, 0);
|
693
|
+
rb_define_method(wavelet_klass, "width=", rb_wavelet_set_output_width, 1);
|
694
|
+
|
695
|
+
rb_define_method(wavelet_klass, "put_in", rb_wavelet_put_in, 2);
|
696
|
+
rb_define_method(wavelet_klass, "transform", rb_wavelet_transform, 1);
|
697
|
+
rb_define_method(wavelet_klass, "power", rb_wavelet_power, 0);
|
698
|
+
rb_define_method(wavelet_klass, "amplitude", rb_wavelet_amplitude, 0);
|
699
|
+
|
700
|
+
for (i = 0; i < (int)N(wavelet_opts_keys); i++) {
|
701
|
+
wavelet_opts_ids[i] = rb_intern(wavelet_opts_keys[i]);
|
702
|
+
}
|
703
|
+
|
704
|
+
symb_linear_scale = ID2SYM(rb_intern_const("LINEAR_SCALE"));
|
705
|
+
symb_log_scale = ID2SYM(rb_intern_const("LOG_SCALE"));
|
706
|
+
}
|