wavspa 0.3.2 → 0.4.2

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: 3625b56c19b4e498a53f7315d2439d4c7f4f75c77b46c7d155b35f4e4cc792c4
4
- data.tar.gz: c557a8053812bc666cd5d4a9345442ce297d5fb79b7e12aaf0e28af6aecd5a38
3
+ metadata.gz: 844dc6500de04cf1cd5f297fa6a979dd4c233f5e203e135865e1e810537a0666
4
+ data.tar.gz: 892077f9f61abf70463c16c70c29f33063f14ae691e2c42c98552240280aa9b3
5
5
  SHA512:
6
- metadata.gz: c26524dacf4725c2032d5e4ce99eef6c24f52a0fc10416918524e7ace1393a53de44905763b51684c8675b7524e66e28a660c2e22669a36ef9b4ce78ed930467
7
- data.tar.gz: fe5a7dbdebd6bf3f41a73f9f0076161794304567326592bcc67eabe4bc012f248edede2066ede39b954f7684304a8a99a6ba1d620b7afc567af526e354a633ce
6
+ metadata.gz: cc99f998f7065d64d86fefdcfd22f6053b126ff28e87178fc7f92828ca36a3d55b7d445c33099ed2301d441f696cb7a646fe00d3935a812865fda08640b073a3
7
+ data.tar.gz: b69d4f4e2ec12b78e57893d5a2dfa0e7a8abe4173a914ce081b26a15e950ae5dee7153cb1f5ed96ab56f309c003f783408c0afa550f50e531af6f1442de2c92d
data/README.md CHANGED
@@ -40,6 +40,7 @@ options:
40
40
  -r, --frequency-range=LO,HI
41
41
  --floor-gain=DB
42
42
  --ceil-gain=DB
43
+ --luminance=NUMBER
43
44
  -g, --frequency-grid=BASIS,STEP
44
45
  -m, --scale-mode=MODE
45
46
  -c, --col-steps=SIZE
@@ -83,6 +84,9 @@ options:
83
84
  <dt>--ceil-gain=DB</dt>
84
85
  <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
86
 
87
+ <dt>--luminance=NUMBER</dt>
88
+ <dd>specify correction value of luminance for pixel drawing (default is 3.5). effective only for power spectrum mode.</dd>
89
+
86
90
  <dt>-g, --frequency-grid=BASIS,STEP</dt>
87
91
  <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>
88
92
 
@@ -123,6 +127,7 @@ options:
123
127
  -r, --frequency-range=LO,HI
124
128
  --floor-gain=DB
125
129
  --ceil-gain=DB
130
+ --luminance=NUMBER
126
131
  -g, --frequnecy-grid=BASIS,STEP
127
132
  -m, --scale-mode=STRING
128
133
  -c, --col-steps=SIZE
@@ -156,14 +161,15 @@ options:
156
161
 
157
162
  <dt>--floor-gain=DB</dt>
158
163
  <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>
159
-
160
164
  <dt>--ceil-gain=DB</dt>
161
165
  <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>
162
166
 
167
+ <dt>--luminance=NUMBER</dt>
168
+ <dd>specify correction value of luminance for pixel drawing (default is 3.5). effective only for power spectrum mode.</dd>
169
+
163
170
  <dt>-g, --frequency-grid=BASIS,STEP</dt>
164
171
  <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>
165
172
 
166
-
167
173
  <dt>-m, --scale=mode</dt>
168
174
  <dd>specify the mode of grid scale in vertical direction of th output PNG. you can specify one of "LOGSCALE" or "LINEARSCALE" (default is "LOGSCALE").</dd>
169
175
 
@@ -204,7 +210,7 @@ As a sample data, transformed from "Call to Quarters" (https://archive.org/detai
204
210
  ![wavelet result](example/Call_To_Quarters-wavelet.png)
205
211
 
206
212
  ```
207
- wavlet -p cd -c 2 --floor-gain -110 -v -o Call_To_Quarters-wavelet2.png Call_To_Quarters.wav
213
+ wavlet -p cd -c 2 -a --floor-gain -110 -v -o Call_To_Quarters-wavelet2.png Call_To_Quarters.wav
208
214
  ```
209
215
  ![wavelet result](example/Call_To_Quarters-wavelet2.png)
210
216
 
data/bin/wavfft CHANGED
@@ -127,6 +127,10 @@ OptionParser.new {|opt|
127
127
  params[:ceil] = val
128
128
  }
129
129
 
130
+ opt.on("--luminance=NUM", Float) { |val|
131
+ params[:luminance] = val
132
+ }
133
+
130
134
  opt.on("-g", "--frequency-grid=BASIS,STEP", Array) { |val|
131
135
  params[:basis_freq] = val[0].to_f
132
136
  params[:grid_step] = val[1].to_f
data/bin/wavlet CHANGED
@@ -89,6 +89,10 @@ OptionParser.new {|opt|
89
89
  params[:sigma] = val
90
90
  }
91
91
 
92
+ opt.on("-t", "--gabor-threshold=NUMBER", Float) {|val|
93
+ params[:threshold] = val
94
+ }
95
+
92
96
  opt.on("-u", "--unit-time=CENTISECOND", Integer) {|val|
93
97
  params[:unit_time] = val * 10
94
98
  }
@@ -109,6 +113,10 @@ OptionParser.new {|opt|
109
113
  params[:ceil] = val
110
114
  }
111
115
 
116
+ opt.on("--luminance=NUM", Float) { |val|
117
+ params[:luminance] = val
118
+ }
119
+
112
120
  opt.on("-g", "--frequency-grid=BASIS,STEP", Array) { |val|
113
121
  params[:basis_freq] = val[0].to_f
114
122
  params[:grid_step] = val[1].to_f
Binary file
Binary file
Binary file
@@ -28,6 +28,7 @@ typedef struct {
28
28
  double ceil;
29
29
  double floor;
30
30
  double range;
31
+ double lumi;
31
32
 
32
33
  VALUE buf;
33
34
  } rb_fb_t;
@@ -303,6 +304,7 @@ static const char* opts_keys[] = {
303
304
  "margin_y",
304
305
  "ceil",
305
306
  "floor",
307
+ "luminance",
306
308
  };
307
309
 
308
310
  static ID opts_ids[N(opts_keys)];
@@ -360,6 +362,7 @@ rb_fb_alloc(VALUE self)
360
362
  ptr->ceil = -10.0;
361
363
  ptr->floor = -90.0;
362
364
  ptr->range = ptr->ceil - ptr->floor;
365
+ ptr->lumi = 3.5;
363
366
  ptr->size = -1;
364
367
  ptr->buf = Qnil;
365
368
 
@@ -413,6 +416,9 @@ rb_fb_initialize(int argc, VALUE* argv, VALUE self)
413
416
 
414
417
  // :floor
415
418
  if (opts[4] != Qundef) ptr->floor = NUM2DBL(opts[4]);
419
+
420
+ // :numinance
421
+ if (opts[5] != Qundef) ptr->lumi = NUM2DBL(opts[5]);
416
422
  }
417
423
 
418
424
  ptr->width = FIX2INT(width);
@@ -512,7 +518,7 @@ rb_fb_draw_power(VALUE self, VALUE col, VALUE dat)
512
518
  for (i = 0; i < ptr->height; i++) {
513
519
  memcpy(&x, src, sizeof(double));
514
520
 
515
- v = round(x * 3.5);
521
+ v = round(x * 1024 * ptr->lumi);
516
522
 
517
523
  if (v < 0) {
518
524
  v = 0;
@@ -650,7 +656,7 @@ put_string(rb_fb_t* ptr, int row, int col,
650
656
  p += (ptr->stride - (5 * 3));
651
657
  }
652
658
 
653
- col += 5;
659
+ col += 6;
654
660
  }
655
661
  }
656
662
 
data/ext/wavspa/fft/fft.c CHANGED
@@ -573,6 +573,8 @@ set_linear_mapping(fft_t* fft)
573
573
  head = tail;
574
574
  lc++;
575
575
  }
576
+
577
+ fft->step = step;
576
578
  }
577
579
 
578
580
  static void
@@ -600,6 +602,8 @@ set_log_mapping(fft_t* fft)
600
602
  head = tail;
601
603
  lc++;
602
604
  }
605
+
606
+ fft->step = step;
603
607
  }
604
608
 
605
609
  static void
@@ -769,15 +773,15 @@ fft_transform(fft_t* fft)
769
773
  }
770
774
 
771
775
  int
772
- fft_calc_spectrum(fft_t* fft, double* dst)
776
+ fft_calc_power(fft_t* fft, double* dst)
773
777
  {
774
778
  int ret;
775
779
  int i;
776
780
  int j;
777
781
  double* a;
778
- double v;
779
- double base;
780
782
  lc_t* lc;
783
+ double v;
784
+ double fq;
781
785
 
782
786
  do {
783
787
  /*
@@ -801,14 +805,18 @@ fft_calc_spectrum(fft_t* fft, double* dst)
801
805
  /*
802
806
  * calc power spectrum
803
807
  */
804
- //base = (double)fft->used;
805
808
 
806
809
  for (i = 0, lc = (lc_t*)fft->line; i < fft->width; i++, lc++) {
807
- v = 0;
810
+ v = 0.0;
811
+
812
+ if (fft->mode == FFT_LINEARSCALE_MODE) {
813
+ fq = fft->fq_l + (fft->step * i);
814
+ } else {
815
+ fq = fft->fq_l * pow(fft->step, i);
816
+ }
808
817
 
809
818
  for(j = 0, a = fft->a + (lc->pos * 2); j < lc->n; j++, a += 2) {
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]));
819
+ v += (sqrt((a[0] * a[0]) + (a[1] * a[1])) / fq);
812
820
  }
813
821
 
814
822
  dst[i] = v / j;
@@ -849,7 +857,7 @@ fft_calc_amplitude(fft_t* fft, double* dst)
849
857
  }
850
858
 
851
859
  /*
852
- * calc power spectrum
860
+ * calc amplitude spectrum
853
861
  */
854
862
  base = (double)fft->used;
855
863
 
data/ext/wavspa/fft/fft.h CHANGED
@@ -32,13 +32,15 @@ typedef struct {
32
32
  int magnify;
33
33
 
34
34
  void* line;
35
- int width;
36
35
 
37
- int mode;
38
36
  double fq_s; // as "sampline frequency"
39
37
  double fq_h; // as "high-side frequency"
40
38
  double fq_l; // as "low-side frequency"
41
39
 
40
+ int mode;
41
+ int width;
42
+ double step;
43
+
42
44
  double* a;
43
45
  int* ip;
44
46
  double* w;
@@ -55,7 +57,7 @@ int fft_set_frequency(fft_t* fft, double s, double l, double h);
55
57
  int fft_shift_in(fft_t* fft, void* data, int n);
56
58
  int fft_reset(fft_t* fft);
57
59
  int fft_transform(fft_t* fft);
58
- int fft_calc_spectrum(fft_t* fft, double* dst);
60
+ int fft_calc_power(fft_t* fft, double* dst);
59
61
  int fft_calc_amplitude(fft_t* fft, double* dst);
60
62
  int fft_calc_absolute(fft_t* fft, double* dst);
61
63
 
@@ -343,7 +343,7 @@ rb_fft_set_frequency(VALUE self, VALUE freq)
343
343
 
344
344
 
345
345
  static VALUE
346
- rb_fft_spectrum(VALUE self)
346
+ rb_fft_power(VALUE self)
347
347
  {
348
348
  rb_fft_t* ptr;
349
349
  VALUE ret;
@@ -366,9 +366,9 @@ rb_fft_spectrum(VALUE self)
366
366
  * call transform function
367
367
  */
368
368
  dat = RSTRING_PTR(ret);
369
- err = fft_calc_spectrum(ptr->fft, dat);
369
+ err = fft_calc_power(ptr->fft, dat);
370
370
  if (err) {
371
- RUNTIME_ERROR( "fft_calc_spectrum() failed. [err = %d]\n", err);
371
+ RUNTIME_ERROR( "fft_calc_power() failed. [err = %d]\n", err);
372
372
  }
373
373
 
374
374
  return ret;
@@ -455,7 +455,7 @@ Init_fft()
455
455
  rb_define_method(fft_klass, "transform", rb_fft_transform, 0);
456
456
  rb_define_method(fft_klass, "enqueue", rb_fft_enqueue, 1);
457
457
  rb_define_method(fft_klass, "<<", rb_fft_enqueue, 1);
458
- rb_define_method(fft_klass, "spectrum", rb_fft_spectrum, 0);
458
+ rb_define_method(fft_klass, "power", rb_fft_power, 0);
459
459
  rb_define_method(fft_klass, "amplitude", rb_fft_amplitude, 0);
460
460
  rb_define_method(fft_klass, "absolute", rb_fft_absolute, 0);
461
461
  }
@@ -26,6 +26,7 @@ static VALUE wavelet_klass;
26
26
 
27
27
  static const char* wavelet_opts_keys[] = {
28
28
  "sigma", // {float}
29
+ "gabor_threshold", // {float}
29
30
  "frequency", // {float}
30
31
  "range", // {Range}
31
32
  "scale_mode", // {str}
@@ -73,6 +74,19 @@ eval_wavelet_opt_sigma(rb_wavelet_t* ptr, VALUE opt)
73
74
  }
74
75
  }
75
76
 
77
+ static void
78
+ eval_wavelet_opt_gabor_threshold(rb_wavelet_t* ptr, VALUE opt)
79
+ {
80
+ int err;
81
+
82
+ if (opt != Qundef) {
83
+ err = walet_set_gabor_threshold(ptr->wl, NUM2DBL(opt));
84
+ if (err) {
85
+ RUNTIME_ERROR("walet_set_gabor_threshold() failed. [err=%d]", err);
86
+ }
87
+ }
88
+ }
89
+
76
90
  static void
77
91
  eval_wavelet_opt_frequency(rb_wavelet_t* ptr, VALUE opt)
78
92
  {
@@ -154,10 +168,11 @@ set_wavelet_context(rb_wavelet_t* ptr, VALUE opt)
154
168
  * set context
155
169
  */
156
170
  eval_wavelet_opt_sigma(ptr, opts[0]);
157
- eval_wavelet_opt_frequency(ptr, opts[1]);
158
- eval_wavelet_opt_range(ptr, opts[2]);
159
- eval_wavelet_opt_scale_mode(ptr, opts[3]);
160
- eval_wavelet_opt_output_width(ptr, opts[4]);
171
+ eval_wavelet_opt_gabor_threshold(ptr, opts[1]);
172
+ eval_wavelet_opt_frequency(ptr, opts[2]);
173
+ eval_wavelet_opt_range(ptr, opts[3]);
174
+ eval_wavelet_opt_scale_mode(ptr, opts[4]);
175
+ eval_wavelet_opt_output_width(ptr, opts[5]);
161
176
  }
162
177
 
163
178
  static VALUE
@@ -236,6 +251,43 @@ rb_wavelet_set_sigma(VALUE self, VALUE sigma)
236
251
  return sigma;
237
252
  }
238
253
 
254
+ static VALUE
255
+ rb_wavelet_get_gabor_threshold(VALUE self)
256
+ {
257
+ VALUE ret;
258
+ rb_wavelet_t* ptr;
259
+
260
+ /*
261
+ * strip object
262
+ */
263
+ Data_Get_Struct(self, rb_wavelet_t, ptr);
264
+
265
+ /*
266
+ * create return paramter
267
+ */
268
+ ret = DBL2NUM(ptr->wl->gth);
269
+
270
+ return ret;
271
+ }
272
+
273
+ static VALUE
274
+ rb_wavelet_set_gabor_threshold(VALUE self, VALUE th)
275
+ {
276
+ rb_wavelet_t* ptr;
277
+
278
+ /*
279
+ * strip object
280
+ */
281
+ Data_Get_Struct(self, rb_wavelet_t, ptr);
282
+
283
+ /*
284
+ * call setter function
285
+ */
286
+ eval_wavelet_opt_gabor_threshold(ptr, th);
287
+
288
+ return th;
289
+ }
290
+
239
291
  static VALUE
240
292
  rb_wavelet_get_frequency(VALUE self)
241
293
  {
@@ -683,6 +735,10 @@ Init_wavelet()
683
735
  rb_define_method(wavelet_klass, "initialize", rb_wavelet_initialize, -1);
684
736
  rb_define_method(wavelet_klass, "sigma", rb_wavelet_get_sigma, 0);
685
737
  rb_define_method(wavelet_klass, "sigma=", rb_wavelet_set_sigma, 1);
738
+ rb_define_method(wavelet_klass, "gabor_threshold",
739
+ rb_wavelet_get_gabor_threshold, 0);
740
+ rb_define_method(wavelet_klass, "gabor_threshold=",
741
+ rb_wavelet_set_gabor_threshold, 1);
686
742
  rb_define_method(wavelet_klass, "frequency", rb_wavelet_get_frequency, 0);
687
743
  rb_define_method(wavelet_klass, "frequency=", rb_wavelet_set_frequency, 1);
688
744
  rb_define_method(wavelet_klass, "range", rb_wavelet_get_range, 0);
@@ -30,29 +30,31 @@
30
30
  #define DEFAULT_LOW_FREQ 100.0
31
31
  #define DEFAULT_HIGH_FREQ 2000.0
32
32
  #define DEFAULT_SIGMA 3.0
33
+ #define DEFAULT_GABOR_THRESHOLD 0.01
33
34
  #define DEFAULT_OUTPUT_WIDTH 360
34
35
  #define DEFAULT_SCALE_MODE WALET_LOGSCALE_MODE
35
-
36
- #define GABOR_THRESHOLD 0.01
37
36
 
38
37
  #define F_DIRTY 0x00000001
39
38
 
40
- #define CALC_WK0(sig) ((sig) * sqrt(-2.0 * log(GABOR_THRESHOLD)))
39
+ #define CALC_WK0(sig,th) ((sig) * sqrt(-2.0 * log(th)))
41
40
  #define CALC_WK1(sig) (1.0 / sqrt(M_PI2 * (sig) * (sig)))
42
41
  #define CALC_WK2(sig) (2.0 * (sig) * (sig))
43
42
 
44
43
  static double
45
- calc_step(int mode, double low, double high, int width)
44
+ calc_step(int mode, double low, double high, int width, double* tbl)
46
45
  {
47
46
  double ret;
47
+ int i;
48
48
 
49
49
  switch (mode) {
50
50
  case WALET_LINEARSCALE_MODE:
51
51
  ret = (high - low) / width;
52
+ for (i = 0; i < width; i++) tbl[i] = low + (ret * i);
52
53
  break;
53
54
 
54
55
  case WALET_LOGSCALE_MODE:
55
56
  ret = pow(high / low, 1.0 / (double)width);
57
+ for (i = 0; i < width; i++) tbl[i] = low * pow(ret, i);
56
58
  break;
57
59
 
58
60
  default:
@@ -67,17 +69,9 @@ static void
67
69
  reset_window_size_table(walet_t* ptr)
68
70
  {
69
71
  int i;
70
- double fq;
71
72
 
72
- fq = ptr->fq_l;
73
73
  for (i = 0; i < ptr->width; i++) {
74
- ptr->ws[i] = (int)(((1.0 / fq) * ptr->wk0) * ptr->fq_s);
75
-
76
- if (ptr->mode == WALET_LINEARSCALE_MODE) {
77
- fq += ptr->step;
78
- } else {
79
- fq *= ptr->step;
80
- }
74
+ ptr->ws[i] = (int)(((1.0 / ptr->ft[i]) * ptr->wk0) * ptr->fq_s);
81
75
  }
82
76
  }
83
77
 
@@ -88,6 +82,7 @@ walet_new(walet_t** _obj)
88
82
  walet_t* obj;
89
83
  int* ws;
90
84
  double* wt;
85
+ double* ft;
91
86
 
92
87
  /*
93
88
  * initialize
@@ -96,6 +91,7 @@ walet_new(walet_t** _obj)
96
91
  obj = NULL;
97
92
  wt = NULL;
98
93
  ws = NULL;
94
+ ft = NULL;
99
95
 
100
96
  do {
101
97
  /*
@@ -127,6 +123,12 @@ walet_new(walet_t** _obj)
127
123
  break;
128
124
  }
129
125
 
126
+ ft = NALLOC(double, DEFAULT_OUTPUT_WIDTH);
127
+ if (ft == NULL) {
128
+ ret = ERR;
129
+ break;
130
+ }
131
+
130
132
  /*
131
133
  * set initial parameter
132
134
  */
@@ -135,15 +137,17 @@ walet_new(walet_t** _obj)
135
137
  obj->fq_l = DEFAULT_LOW_FREQ;
136
138
  obj->fq_h = DEFAULT_HIGH_FREQ;
137
139
  obj->sigma = DEFAULT_SIGMA;
138
- obj->wk0 = CALC_WK0(DEFAULT_SIGMA);
140
+ obj->gth = DEFAULT_GABOR_THRESHOLD;
141
+ obj->wk0 = CALC_WK0(DEFAULT_SIGMA, obj->gth);
139
142
  obj->wk1 = CALC_WK1(DEFAULT_SIGMA);
140
143
  obj->wk2 = CALC_WK2(DEFAULT_SIGMA);
141
144
  obj->width = DEFAULT_OUTPUT_WIDTH;
142
145
  obj->mode = DEFAULT_SCALE_MODE;
143
- obj->step = calc_step(obj->mode, obj->fq_l, obj->fq_h, obj->width);
146
+ obj->step = calc_step(obj->mode, obj->fq_l, obj->fq_h, obj->width, ft);
144
147
  obj->smpl = NULL;
145
148
  obj->ws = ws;
146
149
  obj->wt = wt;
150
+ obj->ft = ft;
147
151
 
148
152
  /*
149
153
  * put return parameter
@@ -155,9 +159,10 @@ walet_new(walet_t** _obj)
155
159
  * post process
156
160
  */
157
161
  if (ret) {
158
- if (obj != NULL) free(obj);
159
- if (wt != NULL) free(wt);
160
162
  if (ws != NULL) free(ws);
163
+ if (wt != NULL) free(wt);
164
+ if (ft != NULL) free(ft);
165
+ if (obj != NULL) free(obj);
161
166
  }
162
167
 
163
168
  return ret;
@@ -183,7 +188,7 @@ walet_set_sigma(walet_t* ptr, double sigma)
183
188
  */
184
189
  if (!ret) {
185
190
  ptr->sigma = sigma;
186
- ptr->wk0 = CALC_WK0(sigma);
191
+ ptr->wk0 = CALC_WK0(sigma, ptr->gth);
187
192
  ptr->wk1 = CALC_WK1(sigma);
188
193
  ptr->wk2 = CALC_WK2(sigma);
189
194
 
@@ -193,6 +198,36 @@ walet_set_sigma(walet_t* ptr, double sigma)
193
198
  return ret;
194
199
  }
195
200
 
201
+ int
202
+ walet_set_gabor_threshold(walet_t* ptr, double th)
203
+ {
204
+ int ret;
205
+
206
+ /*
207
+ * initialize
208
+ */
209
+ ret = 0;
210
+
211
+ /*
212
+ * argument check
213
+ */
214
+ if (ptr == NULL) ret = ERR;
215
+
216
+ /*
217
+ * set parameter
218
+ */
219
+ if (!ret) {
220
+ ptr->gth = th;
221
+ ptr->wk0 = CALC_WK0(ptr->sigma, th);
222
+ ptr->wk1 = CALC_WK1(ptr->sigma);
223
+ ptr->wk2 = CALC_WK2(ptr->sigma);
224
+
225
+ ptr->flags |= F_DIRTY;
226
+ }
227
+
228
+ return ret;
229
+ }
230
+
196
231
  int
197
232
  walet_set_frequency(walet_t* ptr, double freq)
198
233
  {
@@ -263,7 +298,7 @@ walet_set_range(walet_t* ptr, double low, double high)
263
298
  /*
264
299
  * calc step
265
300
  */
266
- step = calc_step(ptr->mode, low, high, ptr->width);
301
+ step = calc_step(ptr->mode, low, high, ptr->width, ptr->ft);
267
302
  if (isnan(step)) {
268
303
  ret = ERR;
269
304
  break;
@@ -311,7 +346,7 @@ walet_set_scale_mode(walet_t* ptr, int mode)
311
346
  /*
312
347
  * calc step
313
348
  */
314
- step = calc_step(mode, ptr->fq_l, ptr->fq_h, ptr->width);
349
+ step = calc_step(mode, ptr->fq_l, ptr->fq_h, ptr->width, ptr->ft);
315
350
  if (isnan(step)) {
316
351
  ret = ERR;
317
352
  break;
@@ -335,6 +370,7 @@ walet_set_output_width(walet_t* ptr, int width)
335
370
  int ret;
336
371
  int* ws;
337
372
  double* wt;
373
+ double* ft;
338
374
  double step;
339
375
 
340
376
  /*
@@ -343,6 +379,7 @@ walet_set_output_width(walet_t* ptr, int width)
343
379
  ret = 0;
344
380
  ws = NULL;
345
381
  wt = NULL;
382
+ ft = NULL;
346
383
 
347
384
  do {
348
385
  /*
@@ -359,25 +396,27 @@ walet_set_output_width(walet_t* ptr, int width)
359
396
  }
360
397
 
361
398
  /*
362
- * alloc window size area
399
+ * alloc new buffers
363
400
  */
364
401
  ws = NALLOC(int, width);
365
402
  if (ws == NULL) {
366
403
  ret = ERR;
367
404
  }
368
405
 
369
- /*
370
- * alloc result area
371
- */
372
406
  wt = NALLOC(double, width * 2);
373
407
  if (wt == NULL) {
374
408
  ret = ERR;
375
409
  }
376
410
 
411
+ ft = NALLOC(double, width);
412
+ if (ft == NULL) {
413
+ ret = ERR;
414
+ }
415
+
377
416
  /*
378
417
  * calc step
379
418
  */
380
- step = calc_step(ptr->mode, ptr->fq_l, ptr->fq_h, width);
419
+ step = calc_step(ptr->mode, ptr->fq_l, ptr->fq_h, width, ft);
381
420
  if (isnan(step)) {
382
421
  ret = ERR;
383
422
  break;
@@ -388,11 +427,13 @@ walet_set_output_width(walet_t* ptr, int width)
388
427
  */
389
428
  if (ptr->wt != NULL) free(ptr->wt);
390
429
  if (ptr->ws != NULL) free(ptr->ws);
430
+ if (ptr->ft != NULL) free(ptr->ft);
391
431
 
392
- ptr->width = width;
393
- ptr->ws = ws;
394
- ptr->wt = wt;
395
- ptr->step = step;
432
+ ptr->width = width;
433
+ ptr->ws = ws;
434
+ ptr->wt = wt;
435
+ ptr->ft = ft;
436
+ ptr->step = step;
396
437
 
397
438
  ptr->flags |= F_DIRTY;
398
439
  } while (0);
@@ -604,7 +645,6 @@ int
604
645
  walet_transform(walet_t* ptr, int pos)
605
646
  {
606
647
  int ret;
607
- double fq;
608
648
  int dx;
609
649
 
610
650
  int i;
@@ -650,7 +690,6 @@ walet_transform(walet_t* ptr, int pos)
650
690
  /*
651
691
  * integla for window
652
692
  */
653
- fq = ptr->fq_l;
654
693
  for (i = 0, wt = ptr->wt; i < ptr->width; i++, wt += 2) {
655
694
  dx = ptr->ws[i];
656
695
 
@@ -664,7 +703,7 @@ walet_transform(walet_t* ptr, int pos)
664
703
  #pragma omp parallel for private(t,gss,omt) reduction(+:re,im)
665
704
  #endif /* defined(_OPENMP) */
666
705
  for (j = st; j <= ed; j++) {
667
- t = ((double)j / ptr->fq_s) * fq;
706
+ t = ((double)j / ptr->fq_s) * ptr->ft[i];
668
707
  gss = ptr->wk1 * exp(-t * (t / ptr->wk2)) * (ptr->smpl[pos + j]);
669
708
  omt = M_PI2 * t;
670
709
 
@@ -675,12 +714,6 @@ walet_transform(walet_t* ptr, int pos)
675
714
 
676
715
  wt[0] = re;
677
716
  wt[1] = im;
678
-
679
- if (ptr->mode == WALET_LINEARSCALE_MODE) {
680
- fq += ptr->step;
681
- } else {
682
- fq *= ptr->step;
683
- }
684
717
  }
685
718
 
686
719
  } while (0);
@@ -694,7 +727,6 @@ walet_calc_power(walet_t* ptr, double* dst)
694
727
  int ret;
695
728
  int i;
696
729
  double* wt;
697
- double base;
698
730
 
699
731
  /*
700
732
  * initialize
@@ -720,12 +752,14 @@ walet_calc_power(walet_t* ptr, double* dst)
720
752
  */
721
753
 
722
754
  #ifdef _OPENMP
723
- #pragma omp parallel private(base,wt)
755
+ #pragma omp parallel private(wt)
724
756
  #endif /* defined(_OPENMP) */
757
+
725
758
  for (i = 0; i < ptr->width; i++) {
726
- wt = ptr->wt + (i * 2);
727
- base = ptr->ws[i] * 2;
728
- dst[i] = 10 * log10(((wt[0] * wt[0]) + (wt[1] * wt[1])) / base);
759
+ wt = ptr->wt + (i * 2);
760
+
761
+ // 末尾の計数256はFFTでの表示に合わせて適当に値を見繕ってるので注意
762
+ dst[i] = (sqrt((wt[0] * wt[0]) + (wt[1] * wt[1])) / ptr->ft[i]) * 256;
729
763
  }
730
764
  } while (0);
731
765
 
@@ -795,7 +829,9 @@ walet_destroy(walet_t* ptr)
795
829
  */
796
830
  if (!ret) {
797
831
  if (ptr->smpl != NULL) free(ptr->smpl);
832
+ if (ptr->ws != NULL) free(ptr->ws);
798
833
  if (ptr->wt != NULL) free(ptr->wt);
834
+ if (ptr->ft != NULL) free(ptr->ft);
799
835
  free(ptr);
800
836
  }
801
837
 
@@ -21,31 +21,34 @@
21
21
  typedef struct __walet__ {
22
22
  int flags;
23
23
 
24
- double fq_s; // as "sampleing frequency"
25
- double fq_l; // as "low side frequency"
26
- double fq_h; // as "high side fequency"
24
+ double fq_s; // as "sampleing frequency"
25
+ double fq_l; // as "low side frequency"
26
+ double fq_h; // as "high side fequency"
27
27
 
28
28
  double sigma;
29
+ double gth; // as "gabor threshold"
29
30
  double wk0;
30
31
  double wk1;
31
32
  double wk2;
32
- int* ws; // as window size list
33
+ int* ws; // as window size list
33
34
  double** exp;
34
35
 
35
36
  int width;
36
37
  int mode;
37
38
  double step;
38
39
 
39
- double* smpl; // as "sample data"
40
- int n; // as "number of sample size"
40
+ double* smpl; // as "sample data"
41
+ int n; // as "number of sample size"
41
42
 
42
43
  double* wt;
44
+ double* ft; // as "frequency table"
43
45
  } walet_t;
44
46
 
45
47
  int walet_new(walet_t** ptr);
46
48
  int walet_destroy(walet_t* ptr);
47
49
 
48
50
  int walet_set_sigma(walet_t* ptr, double sigma);
51
+ int walet_set_gabor_threshold(walet_t* ptr, double th);
49
52
  int walet_set_frequency(walet_t* ptr, double freq);
50
53
  int walet_set_range(walet_t* ptr, double low, double high);
51
54
  int walet_set_scale_mode(walet_t* ptr, int mode);
@@ -1,3 +1,3 @@
1
1
  module WavSpectrumAnalyzer
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.2"
3
3
  end
@@ -28,6 +28,7 @@ module WavSpectrumAnalyzer
28
28
  @freq_range = param[:range]
29
29
  @ceil = param[:ceil]
30
30
  @floor = param[:floor]
31
+ @luminance = param[:luminance]
31
32
  @col_step = param[:col_step]
32
33
 
33
34
  @scale_mode = param[:scale_mode]
@@ -65,7 +66,8 @@ module WavSpectrumAnalyzer
65
66
  :margin_x => ($draw_freq_line)? 50:0,
66
67
  :margin_y => ($draw_time_line)? 30:0,
67
68
  :ceil => @ceil,
68
- :floor => @floor)
69
+ :floor => @floor,
70
+ :luminance => @luminance)
69
71
 
70
72
  if $verbose
71
73
  STDERR.print <<~EOT
@@ -104,8 +106,8 @@ module WavSpectrumAnalyzer
104
106
 
105
107
  fft << wav.read(usize)
106
108
 
107
- if @transfer_mode == :POWER
108
- fb.draw_power(rows, fft.spectrum)
109
+ if @transform_mode == :POWER
110
+ fb.draw_power(rows, fft.power)
109
111
  else
110
112
  fb.draw_amplitude(rows, fft.amplitude)
111
113
  end
@@ -20,6 +20,7 @@ module WavSpectrumAnalyzer
20
20
  :range => [200, 8000],
21
21
  :ceil => -10.0,
22
22
  :floor => -90.0,
23
+ :luminance => 3.5,
23
24
  :col_step => 1,
24
25
  },
25
26
 
@@ -33,6 +34,7 @@ module WavSpectrumAnalyzer
33
34
  :range => [200, 16000],
34
35
  :ceil => -10.0,
35
36
  :floor => -90.0,
37
+ :luminance => 3.5,
36
38
  :col_step => 1,
37
39
  },
38
40
 
@@ -46,6 +48,7 @@ module WavSpectrumAnalyzer
46
48
  :range => [50, 22000],
47
49
  :ceil => -10.0,
48
50
  :floor => -90.0,
51
+ :luminance => 3.5,
49
52
  :col_step => 1,
50
53
  },
51
54
 
@@ -59,6 +62,7 @@ module WavSpectrumAnalyzer
59
62
  :range => [200, 32000],
60
63
  :ceil => -10.0,
61
64
  :floor => -90.0,
65
+ :luminance => 3.5,
62
66
  :col_step => 1,
63
67
  },
64
68
  }
@@ -22,11 +22,13 @@ module WavSpectrumAnalyzer
22
22
  @transform_mode = param[:transform_mode]
23
23
  @unit_time = param[:unit_time]
24
24
  @sigma = param[:sigma]
25
+ @threshold = param[:threshold]
25
26
  @output_width = param[:output_width]
26
27
 
27
28
  @freq_range = param[:range]
28
29
  @ceil = param[:ceil]
29
30
  @floor = param[:floor]
31
+ @luminance = param[:luminance]
30
32
  @col_step = param[:col_step]
31
33
 
32
34
  @scale_mode = param[:scale_mode]
@@ -49,11 +51,13 @@ module WavSpectrumAnalyzer
49
51
  wav = WavFile.open(input)
50
52
  wl = Wavelet.new
51
53
 
52
- wl.frequency = wav.sample_rate
53
- wl.sigma = @sigma
54
- wl.range = (@lo_freq .. @hi_freq)
55
- wl.scale_mode = @scale_mode
56
- wl.width = @output_width
54
+ wl.frequency = wav.sample_rate
55
+ wl.sigma = @sigma
56
+ wl.gabor_threshold = @threshold
57
+ wl.range = (@lo_freq .. @hi_freq)
58
+ wl.scale_mode = @scale_mode
59
+ wl.width = @output_width
60
+
57
61
 
58
62
  wl.put_in("s%dle" % wav.sample_size, wav.read)
59
63
 
@@ -67,30 +71,32 @@ module WavSpectrumAnalyzer
67
71
  :margin_x => ($draw_freq_line)? 50:0,
68
72
  :margin_y => ($draw_time_line)? 30:0,
69
73
  :ceil => @ceil,
70
- :floor => @floor)
74
+ :floor => @floor,
75
+ :luminance => @luminance)
71
76
 
72
77
  if $verbose
73
78
  STDERR.print <<~EOT
74
79
  - input data
75
80
  #{input}
76
- data size: #{wav.data_size}
77
- channel num: #{wav.channel_num}
78
- sample rate: #{wav.sample_rate} Hz
79
- sample size: #{wav.sample_size} bits
80
- data rate: #{wav.bytes_per_sec} bytes/sec
81
+ data size: #{wav.data_size}
82
+ channel num: #{wav.channel_num}
83
+ sample rate: #{wav.sample_rate} Hz
84
+ sample size: #{wav.sample_size} bits
85
+ data rate: #{wav.bytes_per_sec} bytes/sec
81
86
 
82
87
  - WAVELET parameter
83
- sigma: #{@sigma}
84
- unit time: #{@unit_time} ms
88
+ sigma: #{@sigma}
89
+ gabor threshold: #{@threshold}
90
+ unit time: #{@unit_time} ms
85
91
 
86
92
  - OUTPUT
87
- width: #{fb.width}px
88
- height: #{fb.height}px
89
- freq range: #{@lo_freq} - #{@hi_freq}Hz
90
- scale mode: #{@scale_mode}
91
- plot mode : #{@transform_mode}
92
- ceil: #{@ceil}
93
- floor: #{@floor}
93
+ width: #{fb.width}px
94
+ height: #{fb.height}px
95
+ freq range: #{@lo_freq} - #{@hi_freq}Hz
96
+ scale mode: #{@scale_mode}
97
+ plot mode : #{@transform_mode}
98
+ ceil: #{@ceil}
99
+ floor: #{@floor}
94
100
 
95
101
  EOT
96
102
  end
@@ -12,6 +12,7 @@ module WavSpectrumAnalyzer
12
12
  PRESET_TABLE = {
13
13
  "default" => {
14
14
  :sigma => 24.0,
15
+ :threshold => 0.01,
15
16
  :unit_time => 10 * 10,
16
17
  :scale_mode => :LOGSCALE,
17
18
  :transform_mode => :POWER,
@@ -19,11 +20,13 @@ module WavSpectrumAnalyzer
19
20
  :range => [200.0, 8000.0],
20
21
  :ceil => -10.0,
21
22
  :floor => -90.0,
23
+ :luminance => 3.5,
22
24
  :col_step => 1,
23
25
  },
24
26
 
25
27
  "cd" => {
26
28
  :sigma => 24.0,
29
+ :threshold => 0.01,
27
30
  :unit_time => 5 * 10,
28
31
  :scale_mode => :LOGSCALE,
29
32
  :transform_mode => :POWER,
@@ -31,6 +34,7 @@ module WavSpectrumAnalyzer
31
34
  :range => [50.0, 22050.0],
32
35
  :ceil => -10.0,
33
36
  :floor => -90.0,
37
+ :luminance => 3.5,
34
38
  :col_step => 1,
35
39
  },
36
40
  }
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.3.2
4
+ version: 0.4.2
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-06 00:00:00.000000000 Z
11
+ date: 2019-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler