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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd2d32dcf12a061f9555e5cd32be4e6f9623e45622f838614077d03a13f1c625
4
- data.tar.gz: '0906de0b8e96773d3e61a73fada4b1675a1925a44b6234d9db144b69524cf931'
3
+ metadata.gz: 016b7487caeb4a42705bb51e79db41769ba020fe43f7aca190c71f08333cda53
4
+ data.tar.gz: 7fe6ee374e29d9b47c74944959ab4f0cd9a525821a1cb7e55bb1204de025c4f1
5
5
  SHA512:
6
- metadata.gz: 7654f8485ac753d0691029422ff367c469c7597577865fda342da8ae923c96587447db33a47332a815b27c5e473bdb8235951ab4ffe1f2f1a7c76f81cd79ed8b
7
- data.tar.gz: 5f35c4b6845fc6827314f9f5038a831db73f8a60aeb4519c258cfaefa18fa9c4b6d9f0a6610d6e4a9daa8059c476e1aeb2e8722716c2a53eacdd9f4fd0ff5bb2
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=CS
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
- -g, --frequnecy-grid=BASIS,STEP
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
- -F, --draw-freq-line
45
- -T, --draw-time-line
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>enable frequency line (vertical grid).</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>enable time line (horizontal grid).</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 -F -T -v -o Call_To_Quarters-fft.png Call_To_Quarters.wav
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 -F -T -c 2 -v -o Call_To_Quarters-wavelet.png Call_To_Quarters.wav
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 -F -T -c 2 --floor-gain -110 -v -o Call_To_Quarters-wavelet2.png Call_To_Quarters.wav
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 = true
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 = true
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 = true
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 = true
147
+ opt.on("-T", "--no-draw-time-line") {
148
+ $draw_time_line = false
145
149
  }
146
150
 
147
151
  opt.on('-v', "--verbose") {
@@ -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
- rb_fb_put_column(VALUE self, VALUE col, VALUE dat)
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 r;
464
- uint8_t g;
465
- uint8_t b;
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, T_ARRAY);
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 (RARRAY_LEN(dat) != (ptr->height * 3)) {
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 = (uint8_t*)RSTRING_PTR(ptr->buf) +
493
- ((ptr->margin_x + (FIX2INT(col) * ptr->step)) * 3);
494
- i = 0;
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
- for (j = 0; j < ptr->height; j++) {
497
- r = FIX2ULONG(rb_ary_entry(dat, i++)) & 0xff;
498
- g = FIX2ULONG(rb_ary_entry(dat, i++)) & 0xff;
499
- b = FIX2ULONG(rb_ary_entry(dat, i++)) & 0xff;
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
- for (k = 0; k < ptr->step; k++) {
502
- p[0] = r;
503
- p[1] = g;
504
- p[2] = b;
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 += (ptr->stride - (k * 3));
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, "put_column", rb_fb_put_column, 2);
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 += (10 * log10((a[0] * a[0]) + (a[1] * a[1])));
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;
@@ -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 inverse function
366
+ * call transform function
365
367
  */
366
- err = fft_calc_spectrum(ptr->fft, (double*)RSTRING_PTR(ret));
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
  }
@@ -1,3 +1,3 @@
1
1
  module WavSpectrumAnalyzer
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -19,25 +19,28 @@ module WavSpectrumAnalyzer
19
19
 
20
20
  class << self
21
21
  def load_param(param)
22
- @unit_time = param[:unit_time]
23
- @fft_size = param[:fft_size]
24
- @output_width = param[:output_width]
25
- @win_func = param[:window_function]
26
-
27
- @freq_range = param[:range]
28
- @scale_mode = param[:scale_mode]
29
- @logscale = (param[:scale_mode] == :LOGSCALE)
30
- @col_step = param[:col_step]
31
-
32
- @basis_freq = param[:basis_freq] || 440.0
33
- @grid_step = param[:grid_step] || ((@logscale)? 2.0: 2000.0)
34
-
35
- @lo_freq = @freq_range[0]
36
- @hi_freq = @freq_range[1]
37
- @freq_width = (@hi_freq - @lo_freq)
38
-
39
- @log_step = (@hi_freq / @lo_freq) ** (1.0 / @output_width)
40
- @log_base = Math.log(@log_step)
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
- fft.spectrum.unpack("d*").each {|x|
101
- begin
102
- x = (x * 3.5).round
103
- x = 0 if x < 0
104
- x = 255 if x > 255
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
@@ -16,7 +16,10 @@ module WavSpectrumAnalyzer
16
16
  :output_width => 240,
17
17
  :window_function => :FLAT_TOP,
18
18
  :scale_mode => :LOGSCALE,
19
- :range => [200, 8000],
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
- :range => [200, 16000],
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
- :range => [50, 22000],
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
  }
@@ -19,27 +19,27 @@ module WavSpectrumAnalyzer
19
19
 
20
20
  class << self
21
21
  def load_param(param)
22
- @unit_time = param[:unit_time]
23
- @sigma = param[:sigma]
24
- @ceil = param[:ceil]
25
- @floor = param[:floor]
26
- @tran_mode = param[:transform_mode]
27
- @output_width = param[:output_width]
28
-
29
- @freq_range = param[:range]
30
- @scale_mode = param[:scale_mode]
31
- @logscale = (param[:scale_mode] == :LOGSCALE)
32
- @col_step = param[:col_step]
33
-
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)
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
- line = []
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
- - FFT parameter
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 rows >= nblk
104
- STDERR.printf("\rtransform #{rows + 1}/#{nblk}", rows) if $verbose
105
- wl.transform(rows * usize)
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
- fb.put_column(rows, line)
122
- line.clear
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
- rows += 1
113
+ row += 1
125
114
  end
126
115
 
127
116
  STDERR.printf(" ... done\n") if $verbose
data/wavspa.gemspec CHANGED
@@ -43,5 +43,5 @@ Gem::Specification.new do |spec|
43
43
 
44
44
  spec.add_development_dependency "bundler", "~> 2.0"
45
45
  spec.add_development_dependency "rake", "~> 10.0"
46
- spec.add_dependency "libpng-ruby", "~> 0.5.2"
46
+ spec.add_dependency "libpng-ruby", "~> 0.5.4"
47
47
  end
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.2.1
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-02 00:00:00.000000000 Z
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.2
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.2
54
+ version: 0.5.4
55
55
  description: spectrum analyzer for wav file.
56
56
  email:
57
57
  - kgt9221@gmail.com