dsprb 1.0.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.
data/sig/dsprb.rbs ADDED
@@ -0,0 +1,385 @@
1
+ module DSP
2
+ VERSION: String
3
+
4
+ type samples = ::Array[::Numeric]
5
+ type frame = ::Array[::Numeric]
6
+ type spectrum = ::Array[::Float]
7
+
8
+ interface _Transform
9
+ def call: (::Array[::Float], ::Array[::Float]) -> [::Array[::Float], ::Array[::Float]]
10
+ def size: () -> ::Integer
11
+ end
12
+
13
+ interface _WindowFunction
14
+ def call: (::Integer) -> ::Array[::Float]
15
+ end
16
+
17
+ type window = _WindowFunction | ::Symbol
18
+
19
+ class Error < ::StandardError
20
+ end
21
+
22
+ class FormatError < Error
23
+ end
24
+
25
+ class UnknownStrategyError < Error
26
+ end
27
+
28
+ def self.read: (::String) -> Waveform
29
+ def self.decode: (::String) -> Waveform
30
+ def self.pitch: (Waveform, **untyped) -> PitchTrack
31
+ def self.formants: (Waveform, **untyped) -> ::Array[::Float]
32
+ def self.decimate: (Waveform, ::Integer) -> Waveform
33
+ def self.lowpass: (Waveform, cutoff: ::Numeric, ?sections: ::Integer) -> Waveform
34
+ def self.highpass: (Waveform, cutoff: ::Numeric, ?sections: ::Integer) -> Waveform
35
+ def self.filter: (Waveform, Biquad, ::Integer) -> Waveform
36
+
37
+ def self.mfcc: (
38
+ Waveform,
39
+ ?size: ::Integer,
40
+ ?coefficients: ::Integer,
41
+ ?window_seconds: ::Float,
42
+ ?hop_seconds: ::Float,
43
+ **untyped
44
+ ) -> ::Array[::Array[::Float]]
45
+
46
+ module Resolver
47
+ def self.call: (untyped, ::Hash[::Symbol, untyped], ::String) -> untyped
48
+ end
49
+
50
+ module Parabolic
51
+ FLAT_TOLERANCE: ::Float
52
+
53
+ def self.vertex_offset: (::Float, ::Float, ::Float) -> ::Float
54
+ end
55
+
56
+ class Waveform
57
+ attr_reader samples: samples
58
+ attr_reader sample_rate: ::Float
59
+
60
+ def self.new: (samples: samples, sample_rate: ::Numeric) -> Waveform
61
+ def length: () -> ::Integer
62
+ def duration: () -> ::Float
63
+ def nyquist: () -> ::Float
64
+ def empty?: () -> bool
65
+ def frames: (window: ::Integer, hop: ::Integer) -> ::Array[frame]
66
+ def seconds_to_samples: (::Numeric) -> ::Integer
67
+ def with: (**untyped) -> Waveform
68
+ def to_h: () -> ::Hash[::Symbol, untyped]
69
+ end
70
+
71
+ module Wav
72
+ PCM: ::Integer
73
+ IEEE_FLOAT: ::Integer
74
+ EXTENSIBLE: ::Integer
75
+ HEADER_BYTES: ::Integer
76
+ CHUNK_HEADER_BYTES: ::Integer
77
+ EIGHT_BIT_MIDPOINT: ::Float
78
+
79
+ def self.read: (::String) -> Waveform
80
+ def self.decode: (::String) -> Waveform
81
+ def self.assert_riff!: (::String) -> void
82
+ def self.decode_samples: (::String, ::Integer?, ::Integer?) -> ::Array[::Float]
83
+ def self.scale: (::Array[::Integer], ::Integer) -> ::Array[::Float]
84
+ def self.decode_packed_24: (::String) -> ::Array[::Float]
85
+ def self.downmix: (::Array[::Float], ::Integer?) -> ::Array[::Float]
86
+ end
87
+
88
+ module Window
89
+ HAMMING: ::Array[::Float]
90
+ HANN: ::Array[::Float]
91
+ BLACKMAN: ::Array[::Float]
92
+ REGISTRY: ::Hash[::Symbol, _WindowFunction]
93
+ DEFAULT: ::Symbol
94
+
95
+ def self.rectangular: (::Integer) -> ::Array[::Float]
96
+ def self.hamming: (::Integer) -> ::Array[::Float]
97
+ def self.hann: (::Integer) -> ::Array[::Float]
98
+ def self.blackman: (::Integer) -> ::Array[::Float]
99
+ def self.cosine_sum: (::Integer, ::Array[::Float]) -> ::Array[::Float]
100
+ def self.apply: (frame, ::Array[::Float]) -> ::Array[::Float]
101
+ def self.assert_length!: (untyped) -> void
102
+ def self.resolve: (window) -> _WindowFunction
103
+ end
104
+
105
+ module Framing
106
+ DEFAULT_PREEMPHASIS: ::Float
107
+
108
+ def self.frames: (samples, window: ::Integer, hop: ::Integer) -> ::Array[frame]
109
+ def self.frame_count: (::Integer, window: ::Integer, hop: ::Integer) -> ::Integer
110
+ def self.preemphasis: (samples, ?coefficient: ::Numeric) -> ::Array[::Float]
111
+ end
112
+
113
+ module Fourier
114
+ class Radix2
115
+ attr_reader size: ::Integer
116
+
117
+ def initialize: (::Integer) -> void
118
+ def call: (::Array[::Float], ::Array[::Float]) -> [::Array[::Float], ::Array[::Float]]
119
+ end
120
+ end
121
+
122
+ class Spectrum
123
+ attr_reader size: ::Integer
124
+ attr_reader bins: ::Integer
125
+ attr_reader transform: _Transform
126
+
127
+ def initialize: (::Integer, ?transform: _Transform?) -> void
128
+ def power: (frame) -> spectrum
129
+ def magnitude: (frame) -> spectrum
130
+ def frequencies: (::Numeric) -> ::Array[::Float]
131
+ def bin_of: (::Numeric, ::Numeric) -> ::Integer
132
+ end
133
+
134
+ module Scales
135
+ MEL_SCALE: ::Float
136
+ MEL_BREAK_HZ: ::Float
137
+ SEMITONES_PER_OCTAVE: ::Float
138
+
139
+ def self.hz_to_mel: (::Numeric) -> ::Float
140
+ def self.mel_to_hz: (::Numeric) -> ::Float
141
+ def self.hz_to_semitones: (::Numeric, reference: ::Numeric) -> ::Float
142
+ def self.semitones_to_hz: (::Numeric, reference: ::Numeric) -> ::Float
143
+ end
144
+
145
+ class MelFilterbank
146
+ class Band
147
+ attr_reader offset: ::Integer
148
+ attr_reader weights: ::Array[::Float]
149
+
150
+ def self.new: (offset: ::Integer, weights: ::Array[::Float]) -> Band
151
+ def length: () -> ::Integer
152
+ end
153
+
154
+ DEFAULT_FILTERS: ::Integer
155
+ DEFAULT_LOW_HZ: ::Float
156
+ ENERGY_FLOOR: ::Float
157
+
158
+ attr_reader sample_rate: ::Float
159
+ attr_reader size: ::Integer
160
+ attr_reader filters: ::Integer
161
+ attr_reader low: ::Float
162
+ attr_reader high: ::Float
163
+ attr_reader warp: ::Float
164
+ attr_reader bands: ::Array[Band]
165
+
166
+ def initialize: (
167
+ sample_rate: ::Numeric,
168
+ size: ::Integer,
169
+ ?filters: ::Integer,
170
+ ?low: ::Numeric,
171
+ ?high: ::Numeric?,
172
+ ?warp: ::Numeric
173
+ ) -> void
174
+
175
+ def energies: (spectrum) -> ::Array[::Float]
176
+ def log_energies: (spectrum) -> ::Array[::Float]
177
+ def center_frequencies: () -> ::Array[::Float]
178
+ end
179
+
180
+ module Dct
181
+ def self.two: (::Array[::Numeric], ::Integer) -> ::Array[::Float]
182
+ end
183
+
184
+ class Mfcc
185
+ DEFAULT_COEFFICIENTS: ::Integer
186
+ DEFAULT_SIZE: ::Integer
187
+ DEFAULT_WINDOW_SECONDS: ::Float
188
+ DEFAULT_HOP_SECONDS: ::Float
189
+
190
+ attr_reader filterbank: MelFilterbank
191
+ attr_reader spectrum: Spectrum
192
+ attr_reader coefficients: ::Integer
193
+
194
+ def self.for: (sample_rate: ::Numeric, ?size: ::Integer, ?coefficients: ::Integer, **untyped) -> Mfcc
195
+ def initialize: (filterbank: MelFilterbank, ?coefficients: ::Integer, ?spectrum: Spectrum?) -> void
196
+ def call: (spectrum) -> ::Array[::Float]
197
+
198
+ def sequence: (
199
+ Waveform,
200
+ ?window_seconds: ::Numeric,
201
+ ?hop_seconds: ::Numeric,
202
+ ?window: window,
203
+ ?preemphasis: ::Numeric?
204
+ ) -> ::Array[::Array[::Float]]
205
+ end
206
+
207
+ class Decimator
208
+ DEFAULT_TAPS: ::Integer
209
+ CUTOFF_RATIO: ::Float
210
+
211
+ attr_reader factor: ::Integer
212
+ attr_reader taps: ::Integer
213
+ attr_reader kernel: ::Array[::Float]
214
+
215
+ def self.factor_for: (::Numeric, ::Numeric) -> ::Integer
216
+ def initialize: (::Integer, ?taps: ::Integer) -> void
217
+ def call: (Waveform) -> Waveform
218
+ end
219
+
220
+ module Autocorrelation
221
+ def self.call: (frame, ::Integer) -> ::Array[::Float]
222
+ end
223
+
224
+ module Lpc
225
+ DENOMINATOR_FLOOR: ::Float
226
+ UNBOUNDED_MAGNITUDE: ::Float
227
+
228
+ class Model
229
+ attr_reader coefficients: ::Array[::Float]
230
+ attr_reader error: ::Float
231
+
232
+ def self.new: (coefficients: ::Array[::Float], error: ::Float) -> Model
233
+ def order: () -> ::Integer
234
+ def envelope: (points: ::Integer) -> ::Array[::Float]
235
+ end
236
+
237
+ def self.solve: (frame, order: ::Integer) -> Model
238
+ def self.levinson: (::Array[::Float], ::Integer) -> Model
239
+ def self.advance: (::Array[::Float], ::Integer, ::Float) -> ::Array[::Float]
240
+ end
241
+
242
+ class Formants
243
+ class Peak
244
+ attr_reader frequency: ::Float
245
+ attr_reader amplitude: ::Float
246
+
247
+ def self.new: (frequency: ::Float, amplitude: ::Float) -> Peak
248
+ end
249
+
250
+ DEFAULT_MAXIMUM_HZ: ::Float
251
+ DEFAULT_COUNT: ::Integer
252
+ DEFAULT_RESOLUTION: ::Integer
253
+ DEFAULT_SEPARATION_HZ: ::Float
254
+ DEFAULT_EDGE_MARGIN_HZ: ::Float
255
+ MINIMUM_SAMPLES: ::Integer
256
+ ENERGY_FLOOR: ::Float
257
+ LOG_FLOOR: ::Float
258
+
259
+ attr_reader maximum_frequency: ::Float
260
+ attr_reader count: ::Integer
261
+ attr_reader resolution: ::Integer
262
+ attr_reader separation: ::Float
263
+ attr_reader edge_margin: ::Float
264
+
265
+ def initialize: (
266
+ ?maximum_frequency: ::Numeric,
267
+ ?count: ::Integer,
268
+ ?resolution: ::Integer,
269
+ ?separation: ::Numeric,
270
+ ?edge_margin: ::Numeric
271
+ ) -> void
272
+
273
+ def call: (Waveform) -> ::Array[::Float]
274
+ def peaks: (Waveform) -> ::Array[Peak]
275
+ end
276
+
277
+ class PitchTrack
278
+ attr_reader f0: ::Array[::Float]
279
+ attr_reader confidence: ::Array[::Float]
280
+ attr_reader times: ::Array[::Float]
281
+ attr_reader hop_seconds: ::Float
282
+
283
+ def self.new: (
284
+ f0: ::Array[::Float],
285
+ confidence: ::Array[::Float],
286
+ times: ::Array[::Float],
287
+ hop_seconds: ::Float
288
+ ) -> PitchTrack
289
+
290
+ def length: () -> ::Integer
291
+ def empty?: () -> bool
292
+ def voiced_frames: () -> ::Integer
293
+ def voiced_ratio: () -> ::Float
294
+ def voiced_f0: () -> ::Array[::Float]
295
+ def each_voiced: () { (::Float, ::Float, ::Float) -> void } -> void
296
+ | () -> ::Enumerator[[::Float, ::Float, ::Float], void]
297
+ end
298
+
299
+ class Yin
300
+ DEFAULT_MINIMUM_HZ: ::Float
301
+ DEFAULT_MAXIMUM_HZ: ::Float
302
+ DEFAULT_HOP_SECONDS: ::Float
303
+ DEFAULT_THRESHOLD: ::Float
304
+ DEFAULT_VOICED_THRESHOLD: ::Float
305
+ DEFAULT_WORKING_RATE: ::Float
306
+ MAXIMUM_LAG: ::Integer
307
+
308
+ attr_reader minimum_frequency: ::Float
309
+ attr_reader maximum_frequency: ::Float
310
+ attr_reader hop_seconds: ::Float
311
+ attr_reader threshold: ::Float
312
+ attr_reader voiced_threshold: ::Float
313
+ attr_reader working_rate: ::Float
314
+
315
+ def initialize: (
316
+ ?minimum_frequency: ::Numeric,
317
+ ?maximum_frequency: ::Numeric,
318
+ ?hop_seconds: ::Numeric,
319
+ ?threshold: ::Numeric,
320
+ ?voiced_threshold: ::Numeric,
321
+ ?working_rate: ::Numeric
322
+ ) -> void
323
+
324
+ def call: (Waveform) -> PitchTrack
325
+ end
326
+
327
+ class SpectralMoments
328
+ ENERGY_FLOOR: ::Float
329
+ VARIANCE_FLOOR: ::Float
330
+ DEFAULT_LOW_HZ: ::Float
331
+ HIGH_MARGIN_HZ: ::Float
332
+
333
+ attr_reader centroid: ::Float
334
+ attr_reader spread: ::Float
335
+ attr_reader skewness: ::Float
336
+ attr_reader kurtosis: ::Float
337
+
338
+ def self.new: (centroid: ::Float, spread: ::Float, skewness: ::Float, kurtosis: ::Float) -> SpectralMoments
339
+ def self.zero: () -> SpectralMoments
340
+
341
+ def self.of: (
342
+ spectrum,
343
+ sample_rate: ::Numeric,
344
+ size: ::Integer,
345
+ ?low: ::Numeric,
346
+ ?high: ::Numeric?
347
+ ) -> SpectralMoments
348
+
349
+ def to_h: () -> ::Hash[::Symbol, ::Float]
350
+ end
351
+
352
+ module Energy
353
+ FLOOR: ::Float
354
+
355
+ def self.frame_db: (frame) -> ::Float
356
+ def self.zero_crossing_rate: (frame) -> ::Float
357
+ def self.envelope_db: (samples, window: ::Integer, hop: ::Integer) -> ::Array[::Float]
358
+ def self.slide: (samples, ::Float, ::Integer, ::Integer, ::Integer) -> ::Float
359
+ def self.to_db: (::Float) -> ::Float
360
+ end
361
+
362
+ class Biquad
363
+ BUTTERWORTH_Q: ::Float
364
+ MINIMUM_NORMALIZED: ::Float
365
+ MAXIMUM_NORMALIZED: ::Float
366
+
367
+ attr_reader b0: ::Float
368
+ attr_reader b1: ::Float
369
+ attr_reader b2: ::Float
370
+ attr_reader a1: ::Float
371
+ attr_reader a2: ::Float
372
+
373
+ def self.new: (b0: ::Float, b1: ::Float, b2: ::Float, a1: ::Float, a2: ::Float) -> Biquad
374
+ def self.lowpass: (sample_rate: ::Numeric, cutoff: ::Numeric, ?q: ::Numeric) -> Biquad
375
+ def self.highpass: (sample_rate: ::Numeric, cutoff: ::Numeric, ?q: ::Numeric) -> Biquad
376
+
377
+ def call: (samples) -> ::Array[::Float]
378
+ def apply: (samples, ?sections: ::Integer) -> ::Array[::Float]
379
+ def to_h: () -> ::Hash[::Symbol, ::Float]
380
+ end
381
+
382
+ module Curve
383
+ def self.resample: (::Array[::Numeric], ::Integer) -> ::Array[::Float]
384
+ end
385
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dsprb
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Den Patin
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rake
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '13.4'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '13.4'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rbs
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '4.1'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '4.1'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rspec
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.13'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.13'
54
+ description: 'Acoustic analysis of speech in pure Ruby: WAV decoding, radix-2 FFT
55
+ and power spectra, generalized cosine windows, mel filterbanks and MFCC, the YIN
56
+ fundamental frequency estimator, linear predictive coding by the Levinson-Durbin
57
+ recursion with formant extraction from the all-pole envelope, spectral moments,
58
+ Butterworth biquads, windowed-sinc decimation and short-term energy measures. No
59
+ dependencies, no native extensions, deterministic output.'
60
+ email: hi@dpat.in
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - CHANGELOG.md
66
+ - LICENSE
67
+ - README.md
68
+ - lib/dsprb.rb
69
+ - lib/dsprb/autocorrelation.rb
70
+ - lib/dsprb/biquad.rb
71
+ - lib/dsprb/curve.rb
72
+ - lib/dsprb/dct.rb
73
+ - lib/dsprb/decimator.rb
74
+ - lib/dsprb/energy.rb
75
+ - lib/dsprb/errors.rb
76
+ - lib/dsprb/formants.rb
77
+ - lib/dsprb/fourier.rb
78
+ - lib/dsprb/framing.rb
79
+ - lib/dsprb/lpc.rb
80
+ - lib/dsprb/mel_filterbank.rb
81
+ - lib/dsprb/mfcc.rb
82
+ - lib/dsprb/parabolic.rb
83
+ - lib/dsprb/pitch_track.rb
84
+ - lib/dsprb/resolver.rb
85
+ - lib/dsprb/scales.rb
86
+ - lib/dsprb/spectral_moments.rb
87
+ - lib/dsprb/spectrum.rb
88
+ - lib/dsprb/version.rb
89
+ - lib/dsprb/wav.rb
90
+ - lib/dsprb/waveform.rb
91
+ - lib/dsprb/window.rb
92
+ - lib/dsprb/yin.rb
93
+ - sig/dsprb.rbs
94
+ homepage: https://github.com/taiwancards/dsprb
95
+ licenses:
96
+ - WTFPL
97
+ metadata:
98
+ source_code_uri: https://github.com/taiwancards/dsprb
99
+ changelog_uri: https://github.com/taiwancards/dsprb/blob/main/CHANGELOG.md
100
+ bug_tracker_uri: https://github.com/taiwancards/dsprb/issues
101
+ rubygems_mfa_required: 'true'
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '3.2'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubygems_version: 4.0.16
117
+ specification_version: 4
118
+ summary: Speech signal processing and acoustic feature extraction for numeric signals
119
+ test_files: []