wavspa 0.2.1 → 0.3.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 +4 -4
- data/README.md +30 -15
- data/bin/wavfft +20 -4
- data/bin/wavlet +12 -8
- data/ext/wavspa/fb/rb_fb.c +110 -20
- data/ext/wavspa/fft/fft.c +10 -6
- data/ext/wavspa/fft/rb_fft.c +5 -2
- data/lib/wavspa/version.rb +1 -1
- data/lib/wavspa/wavfft/main.rb +33 -35
- data/lib/wavspa/wavfft/preset.rb +15 -3
- data/lib/wavspa/wavlet/main.rb +38 -49
- data/wavspa.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 016b7487caeb4a42705bb51e79db41769ba020fe43f7aca190c71f08333cda53
|
4
|
+
data.tar.gz: 7fe6ee374e29d9b47c74944959ab4f0cd9a525821a1cb7e55bb1204de025c4f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44df366c15ba55ca2ec19c077d140cf3c1c85caa37d855d43b1c40ebfd515af0f910d1a46776f9d12f7ea99496ffcb1d854b85d8d6a0fc1726c7f63510793aec
|
7
|
+
data.tar.gz: 3e2316a4d6c88748c25ea5e5635ad0f915f1dd716a9e8c701870a9945b3247fd0bdfdb3dceea0fbaac47f87ab669a5c91aa88184f7bfe750a992ddb2fcbd13ed
|
data/README.md
CHANGED
@@ -32,19 +32,21 @@ wavfft [options] WAV-FILE
|
|
32
32
|
options:
|
33
33
|
-o, --output=FILE
|
34
34
|
-p, --preset=NAME
|
35
|
+
-a, --amplitude-mode
|
35
36
|
-f, --fft-size=SIZE
|
36
|
-
-u, --unit-time=
|
37
|
+
-u, --unit-time=MSEC
|
37
38
|
-W, --output-width=SIZE
|
38
39
|
-w, --window-function=FUNCTION
|
39
40
|
-r, --frequency-range=LO,HI
|
40
|
-
|
41
|
+
--floor-gain=DB
|
42
|
+
--ceil-gain=DB
|
43
|
+
-g, --frequency-grid=BASIS,STEP
|
41
44
|
-m, --scale-mode=MODE
|
42
|
-
--show-params
|
43
45
|
-c, --col-steps=SIZE
|
44
|
-
|
45
|
-
-
|
46
|
+
--show-params
|
47
|
+
-F, --no-draw-freq-line
|
48
|
+
-T, --no-draw-time-line
|
46
49
|
-v, --verbose
|
47
|
-
-h, --help
|
48
50
|
```
|
49
51
|
|
50
52
|
#### options
|
@@ -56,6 +58,10 @@ options:
|
|
56
58
|
<dt>-p, --preset=NAME</dt>
|
57
59
|
<dd>specify preset settings. you can specify one of "default", "32k" or "cd".</dd>
|
58
60
|
|
61
|
+
<dt>-a, --amplitude-mode</dt>
|
62
|
+
<dd>When this option is specified, the amplitude spectrum is output (otherwise, the power spectrum is output).</dd>
|
63
|
+
|
64
|
+
|
59
65
|
<dt>-f, --fft-size=FFT</dt>
|
60
66
|
<dd>specify the FFT size (by number of samples, this value must spcify a power of 2).</dd>
|
61
67
|
|
@@ -65,9 +71,18 @@ options:
|
|
65
71
|
<dt>-W, --output-width=SIZE</dt>
|
66
72
|
<dd>specify the hight of output PNG (by number of pixels).</dd>
|
67
73
|
|
74
|
+
<dt>-w, --window-function=FUNCTION</dt>
|
75
|
+
<dd>specify name of windows function for short time FFT. you can specify one of "RECTANGULAR", "HAMMING", "HANN", "BLACKMAN", "BLACKMAN\_NUTTALL", "FLAT\_TOP". </dd>
|
76
|
+
|
68
77
|
<dt>-r, --frequency-range=LO,HI</dt>
|
69
78
|
<dd>specify the frequency band show on the output PNG (upper limit to "HI", and lower limit to "LO").<dd>
|
70
79
|
|
80
|
+
<dt>--floor-gain=DB</dt>
|
81
|
+
<dd>specify the upper limit value of the gain to be displayed. values exceeding this number are displayed as saturated. effective only for amplitude mode.</dd>
|
82
|
+
|
83
|
+
<dt>--ceil-gain=DB</dt>
|
84
|
+
<dd>specify the lower limit value of the gain to be displayed. values less than this number will be masked. effective only for amplitude mode.</dd>
|
85
|
+
|
71
86
|
<dt>-g, --frequency-grid=BASIS,STEP</dt>
|
72
87
|
<dd>specify frequency grid settings. basis frequency to "BASIS" and step value to "STEP". "STEP" is evaluated as a ratio for neighbor grid when the scale mode is LOGSCALE, and as a difference for neighbor grid when LINEARSCALE.</dd>
|
73
88
|
|
@@ -80,11 +95,11 @@ options:
|
|
80
95
|
<dt>--show-params</dt>
|
81
96
|
<dd>show sumarry of settings.</dd>
|
82
97
|
|
83
|
-
<dt>-F, --draw-freq-line</dt>
|
84
|
-
<dd>
|
98
|
+
<dt>-F, --no-draw-freq-line</dt>
|
99
|
+
<dd>disable frequency line (vertical grid).</dd>
|
85
100
|
|
86
|
-
<dt>-F, --draw-freq-line</dt>
|
87
|
-
<dd>
|
101
|
+
<dt>-F, --no-draw-freq-line</dt>
|
102
|
+
<dd>disable time line (horizontal grid).</dd>
|
88
103
|
|
89
104
|
<dt>-v, --verbose</dt>
|
90
105
|
<dd>enable verbose mode</dd>
|
@@ -140,10 +155,10 @@ options:
|
|
140
155
|
<dd>specify the frequency band show on the output PNG (upper limit to "HI", and lower limit to "LO").<dd>
|
141
156
|
|
142
157
|
<dt>--floor-gain=DB</dt>
|
143
|
-
<dd>specify the upper limit value of the gain to be displayed. values exceeding this number are displayed as saturated.</dd>
|
158
|
+
<dd>specify the upper limit value of the gain to be displayed. values exceeding this number are displayed as saturated. effective only for amplitude mode.</dd>
|
144
159
|
|
145
160
|
<dt>--ceil-gain=DB</dt>
|
146
|
-
<dd>specify the lower limit value of the gain to be displayed. values less than this number will be masked.</dd>
|
161
|
+
<dd>specify the lower limit value of the gain to be displayed. values less than this number will be masked. effective only for amplitude mode.</dd>
|
147
162
|
|
148
163
|
<dt>-g, --frequency-grid=BASIS,STEP</dt>
|
149
164
|
<dd>specify frequency grid settings. basis frequency to "BASIS" and step value to "STEP". "STEP" is evaluated as a ratio for neighbor grid when the scale mode is LOGSCALE, and as a difference for neighbor grid when LINEARSCALE.</dd>
|
@@ -176,7 +191,7 @@ As a sample data, transformed from "Call to Quarters" (https://archive.org/detai
|
|
176
191
|
|
177
192
|
### FFT
|
178
193
|
```
|
179
|
-
wavfft -p cd -
|
194
|
+
wavfft -p cd -c 2 -v -o Call_To_Quarters-fft.png Call_To_Quarters.wav
|
180
195
|
```
|
181
196
|
|
182
197
|

|
@@ -184,12 +199,12 @@ As a sample data, transformed from "Call to Quarters" (https://archive.org/detai
|
|
184
199
|
|
185
200
|
### Wavelet
|
186
201
|
```
|
187
|
-
wavlet -p cd -
|
202
|
+
wavlet -p cd -c 2 -v -o Call_To_Quarters-wavelet.png Call_To_Quarters.wav
|
188
203
|
```
|
189
204
|

|
190
205
|
|
191
206
|
```
|
192
|
-
wavlet -p cd -
|
207
|
+
wavlet -p cd -c 2 --floor-gain -110 -v -o Call_To_Quarters-wavelet2.png Call_To_Quarters.wav
|
193
208
|
```
|
194
209
|

|
195
210
|
|
data/bin/wavfft
CHANGED
@@ -52,6 +52,10 @@ output = nil
|
|
52
52
|
#
|
53
53
|
|
54
54
|
OptionParser.new {|opt|
|
55
|
+
$draw_freq_line = true
|
56
|
+
$draw_time_line = true
|
57
|
+
$verbose = false
|
58
|
+
|
55
59
|
window_funcs = %w{
|
56
60
|
RECTANGULAR HAMMING HANN BLACKMAN BLACKMAN_NUTTALL FLAT_TOP
|
57
61
|
}
|
@@ -80,6 +84,10 @@ OptionParser.new {|opt|
|
|
80
84
|
end
|
81
85
|
}
|
82
86
|
|
87
|
+
opt.on("-a", "--amplitude-mode", Integer) {|val|
|
88
|
+
params[:transform_mode] = :AMPLITUDE
|
89
|
+
}
|
90
|
+
|
83
91
|
opt.on("-f", "--fft-size=SIZE", Integer) {|val|
|
84
92
|
params[:fft_size] = val
|
85
93
|
}
|
@@ -111,6 +119,14 @@ OptionParser.new {|opt|
|
|
111
119
|
params[:range] = [val[0].to_f, val[1].to_f]
|
112
120
|
}
|
113
121
|
|
122
|
+
opt.on("--floor-gain=DB", Float) {|val|
|
123
|
+
params[:floor] = val
|
124
|
+
}
|
125
|
+
|
126
|
+
opt.on("--ceil-gain=DB", Float) {|val|
|
127
|
+
params[:ceil] = val
|
128
|
+
}
|
129
|
+
|
114
130
|
opt.on("-g", "--frequency-grid=BASIS,STEP", Array) { |val|
|
115
131
|
params[:basis_freq] = val[0].to_f
|
116
132
|
params[:grid_step] = val[1].to_f
|
@@ -140,12 +156,12 @@ OptionParser.new {|opt|
|
|
140
156
|
exit
|
141
157
|
}
|
142
158
|
|
143
|
-
opt.on("-F", "--draw-freq-line") {
|
144
|
-
$draw_freq_line =
|
159
|
+
opt.on("-F", "--no-draw-freq-line") {
|
160
|
+
$draw_freq_line = false
|
145
161
|
}
|
146
162
|
|
147
|
-
opt.on("-T", "--draw-time-line") {
|
148
|
-
$draw_time_line =
|
163
|
+
opt.on("-T", "--no-draw-time-line") {
|
164
|
+
$draw_time_line = false
|
149
165
|
}
|
150
166
|
|
151
167
|
opt.on('-v', "--verbose") {
|
data/bin/wavlet
CHANGED
@@ -52,6 +52,10 @@ output = nil
|
|
52
52
|
#
|
53
53
|
|
54
54
|
OptionParser.new {|opt|
|
55
|
+
$draw_freq_line = true
|
56
|
+
$draw_time_line = true
|
57
|
+
$verbose = false
|
58
|
+
|
55
59
|
opt.banner += " WAV-FILE"
|
56
60
|
opt.version = VERSION
|
57
61
|
|
@@ -77,14 +81,14 @@ OptionParser.new {|opt|
|
|
77
81
|
end
|
78
82
|
}
|
79
83
|
|
80
|
-
opt.on("-s", "--sigma=NUMBER", Float) {|val|
|
81
|
-
params[:sigma] = val
|
82
|
-
}
|
83
|
-
|
84
84
|
opt.on("-a", "--amplitude-mode", Integer) {|val|
|
85
85
|
params[:transform_mode] = :AMPLITUDE
|
86
86
|
}
|
87
87
|
|
88
|
+
opt.on("-s", "--sigma=NUMBER", Float) {|val|
|
89
|
+
params[:sigma] = val
|
90
|
+
}
|
91
|
+
|
88
92
|
opt.on("-u", "--unit-time=CENTISECOND", Integer) {|val|
|
89
93
|
params[:unit_time] = val * 10
|
90
94
|
}
|
@@ -136,12 +140,12 @@ OptionParser.new {|opt|
|
|
136
140
|
exit
|
137
141
|
}
|
138
142
|
|
139
|
-
opt.on("-F", "--draw-freq-line") {
|
140
|
-
$draw_freq_line =
|
143
|
+
opt.on("-F", "--no-draw-freq-line") {
|
144
|
+
$draw_freq_line = false
|
141
145
|
}
|
142
146
|
|
143
|
-
opt.on("-T", "--draw-time-line") {
|
144
|
-
$draw_time_line =
|
147
|
+
opt.on("-T", "--no-draw-time-line") {
|
148
|
+
$draw_time_line = false
|
145
149
|
}
|
146
150
|
|
147
151
|
opt.on('-v', "--verbose") {
|
data/ext/wavspa/fb/rb_fb.c
CHANGED
@@ -25,6 +25,10 @@ typedef struct {
|
|
25
25
|
int stride;
|
26
26
|
int size;
|
27
27
|
|
28
|
+
double ceil;
|
29
|
+
double floor;
|
30
|
+
double range;
|
31
|
+
|
28
32
|
VALUE buf;
|
29
33
|
} rb_fb_t;
|
30
34
|
|
@@ -297,6 +301,8 @@ static const char* opts_keys[] = {
|
|
297
301
|
"column_step",
|
298
302
|
"margin_x",
|
299
303
|
"margin_y",
|
304
|
+
"ceil",
|
305
|
+
"floor",
|
300
306
|
};
|
301
307
|
|
302
308
|
static ID opts_ids[N(opts_keys)];
|
@@ -351,6 +357,9 @@ rb_fb_alloc(VALUE self)
|
|
351
357
|
ptr->step = 1;
|
352
358
|
ptr->margin_x = 0;
|
353
359
|
ptr->margin_y = 0;
|
360
|
+
ptr->ceil = -10.0;
|
361
|
+
ptr->floor = -90.0;
|
362
|
+
ptr->range = ptr->ceil - ptr->floor;
|
354
363
|
ptr->size = -1;
|
355
364
|
ptr->buf = Qnil;
|
356
365
|
|
@@ -398,6 +407,12 @@ rb_fb_initialize(int argc, VALUE* argv, VALUE self)
|
|
398
407
|
|
399
408
|
// :margin_y
|
400
409
|
if (opts[2] != Qundef) ptr->margin_y = FIX2INT(opts[2]);
|
410
|
+
|
411
|
+
// :ceil
|
412
|
+
if (opts[3] != Qundef) ptr->ceil = NUM2DBL(opts[3]);
|
413
|
+
|
414
|
+
// :floor
|
415
|
+
if (opts[4] != Qundef) ptr->floor = NUM2DBL(opts[4]);
|
401
416
|
}
|
402
417
|
|
403
418
|
ptr->width = FIX2INT(width);
|
@@ -407,6 +422,8 @@ rb_fb_initialize(int argc, VALUE* argv, VALUE self)
|
|
407
422
|
ptr->size = ptr->stride * (ptr->height + ptr->margin_y);
|
408
423
|
ptr->buf = rb_str_buf_new(ptr->size);
|
409
424
|
|
425
|
+
ptr->range = ptr->ceil - ptr->floor;
|
426
|
+
|
410
427
|
/*
|
411
428
|
* clear buffer
|
412
429
|
*/
|
@@ -456,16 +473,15 @@ rb_fb_to_s(VALUE self)
|
|
456
473
|
}
|
457
474
|
|
458
475
|
static VALUE
|
459
|
-
|
476
|
+
rb_fb_draw_power(VALUE self, VALUE col, VALUE dat)
|
460
477
|
{
|
461
478
|
rb_fb_t* ptr;
|
462
479
|
uint8_t* p;
|
463
|
-
uint8_t
|
464
|
-
|
465
|
-
|
480
|
+
uint8_t* src;
|
481
|
+
double x;
|
482
|
+
int v;
|
466
483
|
int i;
|
467
484
|
int j;
|
468
|
-
int k;
|
469
485
|
|
470
486
|
/*
|
471
487
|
* extract context data
|
@@ -476,37 +492,110 @@ rb_fb_put_column(VALUE self, VALUE col, VALUE dat)
|
|
476
492
|
* check argument
|
477
493
|
*/
|
478
494
|
Check_Type(col, T_FIXNUM);
|
479
|
-
Check_Type(dat,
|
495
|
+
Check_Type(dat, T_STRING);
|
480
496
|
|
481
497
|
if (FIX2INT(col) < 0 || FIX2INT(col) >= ptr->width) {
|
482
498
|
ARGUMENT_ERROR("invalid column number");
|
483
499
|
}
|
484
500
|
|
485
|
-
if (
|
501
|
+
if (RSTRING_LEN(dat) != (int)((sizeof(double) * ptr->height))) {
|
486
502
|
ARGUMENT_ERROR("invalid data length");
|
487
503
|
}
|
488
504
|
|
489
505
|
/*
|
490
506
|
* put pixel data
|
491
507
|
*/
|
492
|
-
p
|
493
|
-
|
494
|
-
|
508
|
+
p = (uint8_t*)RSTRING_PTR(ptr->buf) +
|
509
|
+
((ptr->margin_x + (FIX2INT(col) * ptr->step)) * 3);
|
510
|
+
src = (uint8_t*)RSTRING_PTR(dat) + (sizeof(double) * (ptr->height - 1));
|
511
|
+
|
512
|
+
for (i = 0; i < ptr->height; i++) {
|
513
|
+
memcpy(&x, src, sizeof(double));
|
514
|
+
|
515
|
+
v = round(x * 3.5);
|
495
516
|
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
517
|
+
if (v < 0) {
|
518
|
+
v = 0;
|
519
|
+
|
520
|
+
} else if (v > 255.0) {
|
521
|
+
v = 255;
|
522
|
+
}
|
523
|
+
|
524
|
+
for (j = 0; j < ptr->step; j++) {
|
525
|
+
p[0] = v / 3;
|
526
|
+
p[1] = v;
|
527
|
+
p[2] = v / 2;
|
528
|
+
|
529
|
+
p += 3;
|
530
|
+
}
|
500
531
|
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
532
|
+
p += (ptr->stride - (j * 3));
|
533
|
+
src -= sizeof(double);
|
534
|
+
}
|
535
|
+
|
536
|
+
return self;
|
537
|
+
}
|
538
|
+
|
539
|
+
static VALUE
|
540
|
+
rb_fb_draw_amplitude(VALUE self, VALUE col, VALUE dat)
|
541
|
+
{
|
542
|
+
rb_fb_t* ptr;
|
543
|
+
uint8_t* p;
|
544
|
+
uint8_t* src;
|
545
|
+
double x;
|
546
|
+
int v;
|
547
|
+
int i;
|
548
|
+
int j;
|
549
|
+
|
550
|
+
/*
|
551
|
+
* extract context data
|
552
|
+
*/
|
553
|
+
TypedData_Get_Struct(self, rb_fb_t, &fb_data_type, ptr);
|
554
|
+
|
555
|
+
/*
|
556
|
+
* check argument
|
557
|
+
*/
|
558
|
+
Check_Type(col, T_FIXNUM);
|
559
|
+
Check_Type(dat, T_STRING);
|
560
|
+
|
561
|
+
if (FIX2INT(col) < 0 || FIX2INT(col) >= ptr->width) {
|
562
|
+
ARGUMENT_ERROR("invalid column number");
|
563
|
+
}
|
564
|
+
|
565
|
+
if (RSTRING_LEN(dat) != (int)((sizeof(double) * ptr->height))) {
|
566
|
+
ARGUMENT_ERROR("invalid data length");
|
567
|
+
}
|
568
|
+
|
569
|
+
/*
|
570
|
+
* put pixel data
|
571
|
+
*/
|
572
|
+
p = (uint8_t*)RSTRING_PTR(ptr->buf) +
|
573
|
+
((ptr->margin_x + (FIX2INT(col) * ptr->step)) * 3);
|
574
|
+
src = (uint8_t*)RSTRING_PTR(dat) + (sizeof(double) * (ptr->height - 1));
|
575
|
+
|
576
|
+
for (i = 0; i < ptr->height; i++) {
|
577
|
+
memcpy(&x, src, sizeof(double));
|
578
|
+
|
579
|
+
if (x >= ptr->ceil) {
|
580
|
+
v = 255;
|
581
|
+
|
582
|
+
} else if (x <= ptr->floor) {
|
583
|
+
v = 0;
|
584
|
+
|
585
|
+
} else {
|
586
|
+
v = (uint8_t)((255.0 * (x - ptr->floor)) / ptr->range);
|
587
|
+
}
|
588
|
+
|
589
|
+
for (j = 0; j < ptr->step; j++) {
|
590
|
+
p[0] = v / 3;
|
591
|
+
p[1] = v;
|
592
|
+
p[2] = v / 2;
|
505
593
|
|
506
594
|
p += 3;
|
507
595
|
}
|
508
596
|
|
509
|
-
p
|
597
|
+
p += (ptr->stride - (j * 3));
|
598
|
+
src -= sizeof(double);
|
510
599
|
}
|
511
600
|
|
512
601
|
return self;
|
@@ -680,7 +769,8 @@ Init_fb()
|
|
680
769
|
rb_define_method(fb_klass, "width", rb_fb_width, 0);
|
681
770
|
rb_define_method(fb_klass, "height", rb_fb_height, 0);
|
682
771
|
rb_define_method(fb_klass, "to_s", rb_fb_to_s, 0);
|
683
|
-
rb_define_method(fb_klass, "
|
772
|
+
rb_define_method(fb_klass, "draw_power", rb_fb_draw_power, 2);
|
773
|
+
rb_define_method(fb_klass, "draw_amplitude", rb_fb_draw_amplitude, 2);
|
684
774
|
rb_define_method(fb_klass, "hline", rb_fb_hline, 2);
|
685
775
|
rb_define_method(fb_klass, "vline", rb_fb_vline, 2);
|
686
776
|
|
data/ext/wavspa/fft/fft.c
CHANGED
@@ -776,9 +776,15 @@ fft_calc_spectrum(fft_t* fft, double* dst)
|
|
776
776
|
int j;
|
777
777
|
double* a;
|
778
778
|
double v;
|
779
|
+
double base;
|
779
780
|
lc_t* lc;
|
780
781
|
|
781
782
|
do {
|
783
|
+
/*
|
784
|
+
* initialize
|
785
|
+
*/
|
786
|
+
ret = 0;
|
787
|
+
|
782
788
|
/*
|
783
789
|
* argument check
|
784
790
|
*/
|
@@ -795,20 +801,18 @@ fft_calc_spectrum(fft_t* fft, double* dst)
|
|
795
801
|
/*
|
796
802
|
* calc power spectrum
|
797
803
|
*/
|
804
|
+
//base = (double)fft->used;
|
805
|
+
|
798
806
|
for (i = 0, lc = (lc_t*)fft->line; i < fft->width; i++, lc++) {
|
799
807
|
v = 0;
|
800
808
|
|
801
809
|
for(j = 0, a = fft->a + (lc->pos * 2); j < lc->n; j++, a += 2) {
|
802
|
-
v +=
|
810
|
+
//v += 10.0 * log10(((a[0] * a[0]) + (a[1] * a[1])) / base);
|
811
|
+
v += 10.0 * log10((a[0] * a[0]) + (a[1] * a[1]));
|
803
812
|
}
|
804
813
|
|
805
814
|
dst[i] = v / j;
|
806
815
|
}
|
807
|
-
|
808
|
-
/*
|
809
|
-
* mark success
|
810
|
-
*/
|
811
|
-
ret = 0;
|
812
816
|
} while(0);
|
813
817
|
|
814
818
|
return ret;
|
data/ext/wavspa/fft/rb_fft.c
CHANGED
@@ -348,6 +348,8 @@ rb_fft_spectrum(VALUE self)
|
|
348
348
|
rb_fft_t* ptr;
|
349
349
|
VALUE ret;
|
350
350
|
int err;
|
351
|
+
int i;
|
352
|
+
double* dat;
|
351
353
|
|
352
354
|
/*
|
353
355
|
* strip object
|
@@ -361,9 +363,10 @@ rb_fft_spectrum(VALUE self)
|
|
361
363
|
rb_str_set_len(ret, sizeof(double) * ptr->fft->width);
|
362
364
|
|
363
365
|
/*
|
364
|
-
* call
|
366
|
+
* call transform function
|
365
367
|
*/
|
366
|
-
|
368
|
+
dat = RSTRING_PTR(ret);
|
369
|
+
err = fft_calc_spectrum(ptr->fft, dat);
|
367
370
|
if (err) {
|
368
371
|
RUNTIME_ERROR( "fft_calc_spectrum() failed. [err = %d]\n", err);
|
369
372
|
}
|
data/lib/wavspa/version.rb
CHANGED
data/lib/wavspa/wavfft/main.rb
CHANGED
@@ -19,25 +19,28 @@ module WavSpectrumAnalyzer
|
|
19
19
|
|
20
20
|
class << self
|
21
21
|
def load_param(param)
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
25
|
-
@
|
26
|
-
|
27
|
-
|
28
|
-
@
|
29
|
-
@
|
30
|
-
@
|
31
|
-
|
32
|
-
|
33
|
-
@
|
34
|
-
|
35
|
-
@
|
36
|
-
@
|
37
|
-
|
38
|
-
|
39
|
-
@
|
40
|
-
@
|
22
|
+
@transform_mode = param[:transform_mode]
|
23
|
+
@unit_time = param[:unit_time]
|
24
|
+
@fft_size = param[:fft_size]
|
25
|
+
@output_width = param[:output_width]
|
26
|
+
@win_func = param[:window_function]
|
27
|
+
|
28
|
+
@freq_range = param[:range]
|
29
|
+
@ceil = param[:ceil]
|
30
|
+
@floor = param[:floor]
|
31
|
+
@col_step = param[:col_step]
|
32
|
+
|
33
|
+
@scale_mode = param[:scale_mode]
|
34
|
+
@logscale = (param[:scale_mode] == :LOGSCALE)
|
35
|
+
@basis_freq = param[:basis_freq] || 440.0
|
36
|
+
@grid_step = param[:grid_step] || ((@logscale)? 2.0: 2000.0)
|
37
|
+
|
38
|
+
@lo_freq = @freq_range[0]
|
39
|
+
@hi_freq = @freq_range[1]
|
40
|
+
@freq_width = (@hi_freq - @lo_freq)
|
41
|
+
|
42
|
+
@log_step = (@hi_freq / @lo_freq) ** (1.0 / @output_width)
|
43
|
+
@log_base = Math.log(@log_step)
|
41
44
|
end
|
42
45
|
private :load_param
|
43
46
|
|
@@ -52,7 +55,6 @@ module WavSpectrumAnalyzer
|
|
52
55
|
fft.scale_mode = @scale_mode
|
53
56
|
fft.frequency = @freq_range.clone.unshift(wav.sample_rate)
|
54
57
|
|
55
|
-
line = []
|
56
58
|
rows = 0
|
57
59
|
usize = (wav.sample_rate / 100) * @unit_time
|
58
60
|
nblk = (wav.data_size / (wav.sample_size / 8)) / usize
|
@@ -61,7 +63,9 @@ module WavSpectrumAnalyzer
|
|
61
63
|
@output_width,
|
62
64
|
:column_step => @col_step,
|
63
65
|
:margin_x => ($draw_freq_line)? 50:0,
|
64
|
-
:margin_y => ($draw_time_line)? 30:0
|
66
|
+
:margin_y => ($draw_time_line)? 30:0,
|
67
|
+
:ceil => @ceil,
|
68
|
+
:floor => @floor)
|
65
69
|
|
66
70
|
if $verbose
|
67
71
|
STDERR.print <<~EOT
|
@@ -83,6 +87,9 @@ module WavSpectrumAnalyzer
|
|
83
87
|
height: #{fb.height}px
|
84
88
|
freq range: #{@lo_freq} - #{@hi_freq}Hz
|
85
89
|
scale mode: #{@scale_mode}
|
90
|
+
plot mode : #{@transform_mode}
|
91
|
+
ceil: #{@ceil}
|
92
|
+
floor: #{@floor}
|
86
93
|
|
87
94
|
EOT
|
88
95
|
end
|
@@ -97,20 +104,11 @@ module WavSpectrumAnalyzer
|
|
97
104
|
|
98
105
|
fft << wav.read(usize)
|
99
106
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
rescue
|
106
|
-
x = 0
|
107
|
-
end
|
108
|
-
|
109
|
-
line.unshift(x / 3, x, x / 2)
|
110
|
-
}
|
111
|
-
|
112
|
-
fb.put_column(rows, line)
|
113
|
-
line.clear
|
107
|
+
if @transfer_mode == :POWER
|
108
|
+
fb.draw_power(rows, fft.spectrum)
|
109
|
+
else
|
110
|
+
fb.draw_amplitude(rows, fft.amplitude)
|
111
|
+
end
|
114
112
|
|
115
113
|
rows += 1
|
116
114
|
end
|
data/lib/wavspa/wavfft/preset.rb
CHANGED
@@ -16,7 +16,10 @@ module WavSpectrumAnalyzer
|
|
16
16
|
:output_width => 240,
|
17
17
|
:window_function => :FLAT_TOP,
|
18
18
|
:scale_mode => :LOGSCALE,
|
19
|
-
:
|
19
|
+
:transform_mode => :POWER,
|
20
|
+
:range => [200, 8000],
|
21
|
+
:ceil => -10.0,
|
22
|
+
:floor => -90.0,
|
20
23
|
:col_step => 1,
|
21
24
|
},
|
22
25
|
|
@@ -26,7 +29,10 @@ module WavSpectrumAnalyzer
|
|
26
29
|
:output_width => 360,
|
27
30
|
:window_function => :FLAT_TOP,
|
28
31
|
:scale_mode => :LOGSCALE,
|
29
|
-
:
|
32
|
+
:transform_mode => :POWER,
|
33
|
+
:range => [200, 16000],
|
34
|
+
:ceil => -10.0,
|
35
|
+
:floor => -90.0,
|
30
36
|
:col_step => 1,
|
31
37
|
},
|
32
38
|
|
@@ -36,7 +42,10 @@ module WavSpectrumAnalyzer
|
|
36
42
|
:output_width => 480,
|
37
43
|
:window_function => :FLAT_TOP,
|
38
44
|
:scale_mode => :LOGSCALE,
|
39
|
-
:
|
45
|
+
:transform_mode => :POWER,
|
46
|
+
:range => [50, 22000],
|
47
|
+
:ceil => -10.0,
|
48
|
+
:floor => -90.0,
|
40
49
|
:col_step => 1,
|
41
50
|
},
|
42
51
|
|
@@ -46,7 +55,10 @@ module WavSpectrumAnalyzer
|
|
46
55
|
:window_function => :FLAT_TOP,
|
47
56
|
:output_width => 640,
|
48
57
|
:scale_mode => :LOGSCALE,
|
58
|
+
:transform_mode => :POWER,
|
49
59
|
:range => [200, 32000],
|
60
|
+
:ceil => -10.0,
|
61
|
+
:floor => -90.0,
|
50
62
|
:col_step => 1,
|
51
63
|
},
|
52
64
|
}
|
data/lib/wavspa/wavlet/main.rb
CHANGED
@@ -19,27 +19,27 @@ module WavSpectrumAnalyzer
|
|
19
19
|
|
20
20
|
class << self
|
21
21
|
def load_param(param)
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
25
|
-
@
|
26
|
-
|
27
|
-
@
|
28
|
-
|
29
|
-
@
|
30
|
-
@
|
31
|
-
|
32
|
-
@
|
33
|
-
|
34
|
-
@basis_freq
|
35
|
-
@grid_step
|
36
|
-
|
37
|
-
@lo_freq
|
38
|
-
@hi_freq
|
39
|
-
@freq_width
|
40
|
-
|
41
|
-
@log_step
|
42
|
-
@log_base
|
22
|
+
@transform_mode = param[:transform_mode]
|
23
|
+
@unit_time = param[:unit_time]
|
24
|
+
@sigma = param[:sigma]
|
25
|
+
@output_width = param[:output_width]
|
26
|
+
|
27
|
+
@freq_range = param[:range]
|
28
|
+
@ceil = param[:ceil]
|
29
|
+
@floor = param[:floor]
|
30
|
+
@col_step = param[:col_step]
|
31
|
+
|
32
|
+
@scale_mode = param[:scale_mode]
|
33
|
+
@logscale = (param[:scale_mode] == :LOGSCALE)
|
34
|
+
@basis_freq = param[:basis_freq] || 440.0
|
35
|
+
@grid_step = param[:grid_step] || ((@logscale)? 2.0: 2000.0)
|
36
|
+
|
37
|
+
@lo_freq = @freq_range[0]
|
38
|
+
@hi_freq = @freq_range[1]
|
39
|
+
@freq_width = (@hi_freq - @lo_freq)
|
40
|
+
|
41
|
+
@log_step = (@hi_freq / @lo_freq) ** (1.0 / @output_width)
|
42
|
+
@log_base = Math.log(@log_step)
|
43
43
|
end
|
44
44
|
private :load_param
|
45
45
|
|
@@ -57,9 +57,7 @@ module WavSpectrumAnalyzer
|
|
57
57
|
|
58
58
|
wl.put_in("s%dle" % wav.sample_size, wav.read)
|
59
59
|
|
60
|
-
|
61
|
-
rows = 0
|
62
|
-
|
60
|
+
row = 0
|
63
61
|
usize = (wav.sample_rate * @unit_time) / 1000
|
64
62
|
nblk = (wav.data_size / wav.block_size) / usize
|
65
63
|
|
@@ -67,7 +65,9 @@ module WavSpectrumAnalyzer
|
|
67
65
|
@output_width,
|
68
66
|
:column_step => @col_step,
|
69
67
|
:margin_x => ($draw_freq_line)? 50:0,
|
70
|
-
:margin_y => ($draw_time_line)? 30:0
|
68
|
+
:margin_y => ($draw_time_line)? 30:0,
|
69
|
+
:ceil => @ceil,
|
70
|
+
:floor => @floor)
|
71
71
|
|
72
72
|
if $verbose
|
73
73
|
STDERR.print <<~EOT
|
@@ -79,18 +79,18 @@ module WavSpectrumAnalyzer
|
|
79
79
|
sample size: #{wav.sample_size} bits
|
80
80
|
data rate: #{wav.bytes_per_sec} bytes/sec
|
81
81
|
|
82
|
-
-
|
82
|
+
- WAVELET parameter
|
83
83
|
sigma: #{@sigma}
|
84
84
|
unit time: #{@unit_time} ms
|
85
|
-
ceil: #{@ceil}
|
86
|
-
floor: #{@floor}
|
87
|
-
mode : #{@tran_mode}
|
88
85
|
|
89
86
|
- OUTPUT
|
90
87
|
width: #{fb.width}px
|
91
88
|
height: #{fb.height}px
|
92
89
|
freq range: #{@lo_freq} - #{@hi_freq}Hz
|
93
90
|
scale mode: #{@scale_mode}
|
91
|
+
plot mode : #{@transform_mode}
|
92
|
+
ceil: #{@ceil}
|
93
|
+
floor: #{@floor}
|
94
94
|
|
95
95
|
EOT
|
96
96
|
end
|
@@ -100,28 +100,17 @@ module WavSpectrumAnalyzer
|
|
100
100
|
"(support only monoral data).")
|
101
101
|
end
|
102
102
|
|
103
|
-
until
|
104
|
-
STDERR.printf("\rtransform #{
|
105
|
-
wl.transform(
|
106
|
-
|
107
|
-
result = (@transform_mode == :POWER)? wl.power: wl.amplitude
|
108
|
-
|
109
|
-
result.unpack("d*").each {|x|
|
110
|
-
if x > @ceil
|
111
|
-
x = 255
|
112
|
-
elsif x < @floor
|
113
|
-
x = 0
|
114
|
-
else
|
115
|
-
x = ((255 * (x - @floor)) / (@ceil - @floor)).floor
|
116
|
-
end
|
117
|
-
|
118
|
-
line.unshift(x / 3, x, x / 2)
|
119
|
-
}
|
103
|
+
until row >= nblk
|
104
|
+
STDERR.printf("\rtransform #{row + 1}/#{nblk}", row) if $verbose
|
105
|
+
wl.transform(row * usize)
|
120
106
|
|
121
|
-
|
122
|
-
|
107
|
+
if @transform_mode == :POWER
|
108
|
+
fb.draw_power(row, wl.power)
|
109
|
+
else
|
110
|
+
fb.draw_amplitude(row, wl.amplitude)
|
111
|
+
end
|
123
112
|
|
124
|
-
|
113
|
+
row += 1
|
125
114
|
end
|
126
115
|
|
127
116
|
STDERR.printf(" ... done\n") if $verbose
|
data/wavspa.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wavspa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hirosho Kuwagata
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.5.
|
47
|
+
version: 0.5.4
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.5.
|
54
|
+
version: 0.5.4
|
55
55
|
description: spectrum analyzer for wav file.
|
56
56
|
email:
|
57
57
|
- kgt9221@gmail.com
|