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 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