wavspa 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
![FFT result](example/Call_To_Quarters-fft.png)
|
@@ -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
|
![wavelet result](example/Call_To_Quarters-wavelet.png)
|
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
|
![wavelet result](example/Call_To_Quarters-wavelet2.png)
|
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
|