beeps 0.3.6 → 0.3.7

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/beeps/beeps.cpp +7 -0
  3. data/.doc/ext/beeps/high_pass.cpp +63 -0
  4. data/.doc/ext/beeps/low_pass.cpp +63 -0
  5. data/.doc/ext/beeps/native.cpp +8 -0
  6. data/.doc/ext/beeps/oscillator.cpp +87 -10
  7. data/.doc/ext/beeps/processor.cpp +14 -1
  8. data/.doc/ext/beeps/reverb.cpp +99 -0
  9. data/.doc/ext/beeps/signals.cpp +128 -0
  10. data/ChangeLog.md +24 -0
  11. data/Rakefile +1 -1
  12. data/VERSION +1 -1
  13. data/beeps.gemspec +2 -2
  14. data/ext/beeps/beeps.cpp +8 -0
  15. data/ext/beeps/high_pass.cpp +66 -0
  16. data/ext/beeps/low_pass.cpp +66 -0
  17. data/ext/beeps/native.cpp +8 -0
  18. data/ext/beeps/oscillator.cpp +95 -12
  19. data/ext/beeps/processor.cpp +15 -1
  20. data/ext/beeps/reverb.cpp +106 -0
  21. data/ext/beeps/signals.cpp +136 -0
  22. data/include/beeps/beeps.h +2 -2
  23. data/include/beeps/defs.h +3 -0
  24. data/include/beeps/filter.h +118 -17
  25. data/include/beeps/generator.h +50 -17
  26. data/include/beeps/processor.h +23 -6
  27. data/include/beeps/ruby/filter.h +33 -0
  28. data/include/beeps/ruby/signals.h +40 -0
  29. data/include/beeps/signals.h +1 -1
  30. data/lib/beeps/processor.rb +46 -1
  31. data/lib/beeps/signals.rb +19 -0
  32. data/lib/beeps.rb +1 -0
  33. data/src/analyser.cpp +34 -37
  34. data/src/beeps.cpp +7 -6
  35. data/src/envelope.cpp +60 -46
  36. data/src/file_in.cpp +6 -6
  37. data/src/gain.cpp +5 -5
  38. data/src/high_pass.cpp +57 -0
  39. data/src/low_pass.cpp +57 -0
  40. data/src/mic_in.cpp +16 -14
  41. data/src/mixer.cpp +38 -20
  42. data/src/oscillator.cpp +260 -168
  43. data/src/pitch_shift.cpp +6 -6
  44. data/src/processor.cpp +118 -11
  45. data/src/processor.h +8 -0
  46. data/src/reverb.cpp +124 -0
  47. data/src/sequencer.cpp +18 -14
  48. data/src/signals.cpp +264 -106
  49. data/src/signals.h +28 -89
  50. data/src/sound.cpp +28 -20
  51. data/src/time_stretch.cpp +6 -6
  52. data/src/win32/signals.cpp +8 -7
  53. data/src/x_pass.h +51 -0
  54. data/test/helper.rb +14 -0
  55. data/test/test_analyser.rb +26 -0
  56. data/test/test_envelope.rb +55 -0
  57. data/test/test_file_in.rb +22 -1
  58. data/test/test_gain.rb +28 -0
  59. data/test/test_high_pass.rb +41 -0
  60. data/test/test_low_pass.rb +41 -0
  61. data/test/test_mixer.rb +63 -0
  62. data/test/test_oscillator.rb +58 -0
  63. data/test/test_pitch_shift.rb +32 -0
  64. data/test/test_processor.rb +7 -0
  65. data/test/test_signals.rb +60 -0
  66. data/test/test_time_stretch.rb +36 -0
  67. metadata +48 -10
@@ -0,0 +1,63 @@
1
+ require_relative 'helper'
2
+
3
+
4
+ class TestMixer < Test::Unit::TestCase
5
+
6
+ B = Beeps
7
+
8
+ def mixer(*inputs)
9
+ B::Mixer.new.tap {_1.add_input(*inputs)}
10
+ end
11
+
12
+ def const(value = 1)
13
+ B::Oscillator.new samples: [value]
14
+ end
15
+
16
+ def envelope(note_off_seconds, a = 0, r = 0)
17
+ B::Envelope.new attack: a, decay: 0, sustain: 1, release: r do
18
+ note_on
19
+ note_off note_off_seconds
20
+ end
21
+ end
22
+
23
+ def test_inputs()
24
+ m = mixer const(0.1), const(0.2)
25
+ assert_equal 2, m.inputs.size
26
+ end
27
+
28
+ def test_process()
29
+ m = mixer const(0.1), const(0.2)
30
+ assert_each_in_epsilon [0.3] * 4, get_samples(3, m)
31
+ end
32
+
33
+ def test_mix_difference_duration()
34
+ mixer(
35
+ const(0.1) >> envelope(1),
36
+ const(0.2) >> envelope(1)
37
+ ).tap do |m|
38
+ assert_each_in_epsilon [0.3] * 11, get_samples(10, m)
39
+ end
40
+
41
+ mixer(
42
+ const(0.1) >> envelope(0.1),
43
+ const(0.2) >> envelope(0.5)
44
+ ).tap do |m|
45
+ assert_each_in_epsilon [0.3] * 2 + [0.2] * 4, get_samples(10, m)
46
+ end
47
+
48
+ mixer(
49
+ const(0.1) >> envelope(0.5),
50
+ const(0.2) >> envelope(0.1)
51
+ ).tap do |m|
52
+ assert_each_in_epsilon [0.3] * 2 + [0.1] * 4, get_samples(10, m)
53
+ end
54
+
55
+ mixer(
56
+ const(0.1) >> envelope(0.5),
57
+ const(0.2) >> envelope(1.5)
58
+ ).tap do |m|
59
+ assert_each_in_epsilon [0.3] * 6 + [0.2] * 10, get_samples(10, m, seconds: 2)
60
+ end
61
+ end
62
+
63
+ end# TestMixer
@@ -0,0 +1,58 @@
1
+ require_relative 'helper'
2
+
3
+
4
+ class TestOscillator < Test::Unit::TestCase
5
+
6
+ B = Beeps
7
+
8
+ def osc(type = :sine, samples: nil, freq: 1, **kwargs)
9
+ B::Oscillator.new(type, samples: samples, freq: freq, **kwargs)
10
+ end
11
+
12
+ def test_initialize()
13
+ assert_equal 1, osc(frequency: 1).frequency
14
+ assert_equal 2, osc(frequency: 2).freq
15
+ assert_equal 3, osc(freq: 3).frequency
16
+ assert_equal 4, osc(freq: 4).freq
17
+ assert_in_delta 0.5, osc(phase: 5.5).phase
18
+ assert_equal 6, osc(gain: 6).gain
19
+ assert_equal 7, osc(offset: 7).offset
20
+ assert_in_delta 0.8, osc(duty: 0.8).duty
21
+ end
22
+
23
+ def test_offset()
24
+ assert_in_delta 0, get_samples(10000, osc(offset: 0)).sum / 10000
25
+ assert_in_delta 3, get_samples(10000, osc(offset: 3)).sum / 10000
26
+ assert_in_delta -3, get_samples(10000, osc(offset: -3)).sum / 10000
27
+ end
28
+
29
+ def test_gain()
30
+ assert_in_delta 3, get_samples(100, osc(gain: 3)).max
31
+ assert_in_delta -3, get_samples(100, osc(gain: 3)).min
32
+ end
33
+
34
+ def test_offset_and_gain()
35
+ assert_in_delta 13, get_samples(100, osc(offset: 10, gain: 3)).max
36
+ assert_in_delta 7, get_samples(100, osc(offset: 10, gain: 3)).min
37
+ end
38
+
39
+ def test_waves()
40
+ assert_in_delta 0, get_samples(10000, osc(:sine)) .sum / 10000
41
+ assert_in_delta 0, get_samples(10000, osc(:triangle)).sum / 10000
42
+ assert_in_delta 0, get_samples(10000, osc(:square)) .sum / 10000
43
+ assert_in_delta 0, get_samples(10000, osc(:sawtooth)).sum / 10000, 0.05
44
+ end
45
+
46
+ def test_square_with_duty()
47
+ assert_not_equal(
48
+ get_samples(1000, osc(:square, duty: 0.1)),
49
+ get_samples(1000, osc(:square, duty: 0.2)))
50
+ end
51
+
52
+ def test_samples_wave()
53
+ assert_each_in_delta [1] * 1001, get_samples(1000, osc(samples: [1]))
54
+ assert_each_in_delta [1, 1, 1], get_samples(2, osc(samples: [1]))
55
+ assert_each_in_delta [1, 0, 1], get_samples(2, osc(samples: [1, 0])), 0.005
56
+ end
57
+
58
+ end# TestOscillator
@@ -0,0 +1,32 @@
1
+ require_relative 'helper'
2
+
3
+
4
+ class TestPitchShift < Test::Unit::TestCase
5
+
6
+ B = Beeps
7
+
8
+ def shift(...)
9
+ B::PitchShift.new(...)
10
+ end
11
+
12
+ def osc(...)
13
+ B::Oscillator.new(...)
14
+ end
15
+
16
+ def test_initialize()
17
+ assert_equal 1, shift.shift
18
+ end
19
+
20
+ def test_process()
21
+ assert_equal(
22
+ get_samples(10, osc(:sine)),
23
+ get_samples(10, osc(:sine) >> shift(shift: 1)))
24
+ end
25
+
26
+ def _test_pitch_shift()
27
+ assert_equal(
28
+ get_samples(1000, osc(:sine, freq: 880)),
29
+ get_samples(1000, osc(:sine, freq: 440) >> shift(shift: 2)))
30
+ end
31
+
32
+ end# TestPitchShift
@@ -4,6 +4,7 @@ require_relative 'helper'
4
4
  class TestProcessor < Test::Unit::TestCase
5
5
 
6
6
  B = Beeps
7
+ P = B::Processor
7
8
 
8
9
  def processor()
9
10
  B::Gain.new
@@ -44,4 +45,10 @@ class TestProcessor < Test::Unit::TestCase
44
45
  assert_equal gain1, gain2.input
45
46
  end
46
47
 
48
+ def test_get_signals()
49
+ assert_equal 4000, P.get_signals(
50
+ B::Oscillator.new, seconds: 2, nchannels: 2, sample_rate: 1000
51
+ ).to_a.size
52
+ end
53
+
47
54
  end# TestProcessor
@@ -0,0 +1,60 @@
1
+ require_relative 'helper'
2
+
3
+
4
+ class TestSignals < Test::Unit::TestCase
5
+
6
+ B = Beeps
7
+
8
+ def signals(**kwargs)
9
+ B::Processor.get_signals B::Oscillator.new, **kwargs
10
+ end
11
+
12
+ def test_initialize()
13
+ assert_true B::Signals.new.empty?
14
+ end
15
+
16
+ def test_dup()
17
+ sig = signals nchannels: 10, sample_rate: 20
18
+ assert_equal 10, sig.dup.nchannels
19
+ assert_equal 20, sig.dup.sample_rate
20
+ assert_not_equal sig.object_id, sig.dup.object_id
21
+ end
22
+
23
+ def test_sample_rate()
24
+ assert_equal 44100, signals .sample_rate
25
+ assert_equal 100, signals(sample_rate: 100).sample_rate
26
+ end
27
+
28
+ def test_nchannels()
29
+ assert_equal 1, signals .nchannels
30
+ assert_equal 2, signals(nchannels: 2).nchannels
31
+ end
32
+
33
+ def test_nsamples()
34
+ assert_equal 44100, signals .nsamples
35
+
36
+ assert_equal 44100, signals(seconds: 1) .nsamples
37
+ assert_equal 88200, signals(seconds: 2) .nsamples
38
+
39
+ assert_equal 100, signals(seconds: 1, sample_rate: 100).nsamples
40
+ assert_equal 200, signals(seconds: 2, sample_rate: 100).nsamples
41
+ assert_equal 50, signals(seconds: 0.5, sample_rate: 100).nsamples
42
+
43
+ assert_equal 100, signals(nchannels: 1, sample_rate: 100).nsamples
44
+ assert_equal 100, signals(nchannels: 2, sample_rate: 100).nsamples
45
+ end
46
+
47
+ def test_each()
48
+ assert_equal 100, signals(nchannels: 1, sample_rate: 100).each .to_a.size
49
+ assert_equal 200, signals(seconds: 2, sample_rate: 100).each .to_a.size
50
+ assert_equal 200, signals(nchannels: 2, sample_rate: 100).each .to_a.size
51
+ assert_equal 100, signals(nchannels: 2, sample_rate: 100).each(channel: 0).to_a.size
52
+ assert_equal 100, signals(nchannels: 2, sample_rate: 100).each(channel: 1).to_a.size
53
+
54
+ assert_raise(ArgumentError) {signals(nchannels: 2).each(channel: -1).to_a}
55
+ assert_raise(ArgumentError) {signals(nchannels: 2).each(channel: 2).to_a}
56
+
57
+ assert_in_delta 0, signals(sample_rate: 100).each.to_a.then {_1.sum / _1.size}, 0.001
58
+ end
59
+
60
+ end# TestSignals
@@ -0,0 +1,36 @@
1
+ require_relative 'helper'
2
+
3
+
4
+ class TestTimeStretch < Test::Unit::TestCase
5
+
6
+ B = Beeps
7
+
8
+ def stretch(...)
9
+ B::TimeStretch.new(...)
10
+ end
11
+
12
+ def osc(...)
13
+ B::Oscillator.new(...)
14
+ end
15
+
16
+ def env(off_time = 1, *a, **k)
17
+ B::Envelope.new(*a, **k) {note_off off_time}
18
+ end
19
+
20
+ def test_initialize()
21
+ assert_equal 1, stretch.scale
22
+ end
23
+
24
+ def test_process()
25
+ assert_equal(
26
+ get_samples(10, osc(:sine)),
27
+ get_samples(10, osc(:sine) >> stretch(scale: 1)))
28
+ end
29
+
30
+ def test_time_stretch()
31
+ assert_equal 11, get_samples(10, osc(:sine) >> env >> stretch(scale: 1)) .size
32
+ assert_equal 6, get_samples(10, osc(:sine) >> env >> stretch(scale: 0.5)).size
33
+ assert_equal 2, get_samples(10, osc(:sine) >> env >> stretch(scale: 0.1)).size
34
+ end
35
+
36
+ end# TestTimeStretch
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beeps
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - xordog
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-08 00:00:00.000000000 Z
11
+ date: 2025-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xot
@@ -16,40 +16,40 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.3.6
19
+ version: 0.3.7
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 0.3.6
22
+ version: 0.3.7
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: 0.3.6
29
+ version: 0.3.7
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 0.3.6
32
+ version: 0.3.7
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rucy
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 0.3.6
39
+ version: 0.3.7
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 0.3.6
42
+ version: 0.3.7
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: 0.3.6
49
+ version: 0.3.7
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: 0.3.6
52
+ version: 0.3.7
53
53
  description: Synthesize and play beep sounds.
54
54
  email: xordog@gmail.com
55
55
  executables: []
@@ -62,13 +62,17 @@ extra_rdoc_files:
62
62
  - ".doc/ext/beeps/exception.cpp"
63
63
  - ".doc/ext/beeps/file_in.cpp"
64
64
  - ".doc/ext/beeps/gain.cpp"
65
+ - ".doc/ext/beeps/high_pass.cpp"
66
+ - ".doc/ext/beeps/low_pass.cpp"
65
67
  - ".doc/ext/beeps/mic_in.cpp"
66
68
  - ".doc/ext/beeps/mixer.cpp"
67
69
  - ".doc/ext/beeps/native.cpp"
68
70
  - ".doc/ext/beeps/oscillator.cpp"
69
71
  - ".doc/ext/beeps/pitch_shift.cpp"
70
72
  - ".doc/ext/beeps/processor.cpp"
73
+ - ".doc/ext/beeps/reverb.cpp"
71
74
  - ".doc/ext/beeps/sequencer.cpp"
75
+ - ".doc/ext/beeps/signals.cpp"
72
76
  - ".doc/ext/beeps/sound.cpp"
73
77
  - ".doc/ext/beeps/sound_player.cpp"
74
78
  - ".doc/ext/beeps/time_stretch.cpp"
@@ -79,13 +83,17 @@ files:
79
83
  - ".doc/ext/beeps/exception.cpp"
80
84
  - ".doc/ext/beeps/file_in.cpp"
81
85
  - ".doc/ext/beeps/gain.cpp"
86
+ - ".doc/ext/beeps/high_pass.cpp"
87
+ - ".doc/ext/beeps/low_pass.cpp"
82
88
  - ".doc/ext/beeps/mic_in.cpp"
83
89
  - ".doc/ext/beeps/mixer.cpp"
84
90
  - ".doc/ext/beeps/native.cpp"
85
91
  - ".doc/ext/beeps/oscillator.cpp"
86
92
  - ".doc/ext/beeps/pitch_shift.cpp"
87
93
  - ".doc/ext/beeps/processor.cpp"
94
+ - ".doc/ext/beeps/reverb.cpp"
88
95
  - ".doc/ext/beeps/sequencer.cpp"
96
+ - ".doc/ext/beeps/signals.cpp"
89
97
  - ".doc/ext/beeps/sound.cpp"
90
98
  - ".doc/ext/beeps/sound_player.cpp"
91
99
  - ".doc/ext/beeps/time_stretch.cpp"
@@ -111,13 +119,17 @@ files:
111
119
  - ext/beeps/extconf.rb
112
120
  - ext/beeps/file_in.cpp
113
121
  - ext/beeps/gain.cpp
122
+ - ext/beeps/high_pass.cpp
123
+ - ext/beeps/low_pass.cpp
114
124
  - ext/beeps/mic_in.cpp
115
125
  - ext/beeps/mixer.cpp
116
126
  - ext/beeps/native.cpp
117
127
  - ext/beeps/oscillator.cpp
118
128
  - ext/beeps/pitch_shift.cpp
119
129
  - ext/beeps/processor.cpp
130
+ - ext/beeps/reverb.cpp
120
131
  - ext/beeps/sequencer.cpp
132
+ - ext/beeps/signals.cpp
121
133
  - ext/beeps/sound.cpp
122
134
  - ext/beeps/sound_player.cpp
123
135
  - ext/beeps/time_stretch.cpp
@@ -136,6 +148,7 @@ files:
136
148
  - include/beeps/ruby/filter.h
137
149
  - include/beeps/ruby/generator.h
138
150
  - include/beeps/ruby/processor.h
151
+ - include/beeps/ruby/signals.h
139
152
  - include/beeps/ruby/sound.h
140
153
  - include/beeps/signals.h
141
154
  - include/beeps/sound.h
@@ -145,6 +158,7 @@ files:
145
158
  - lib/beeps/ext.rb
146
159
  - lib/beeps/extension.rb
147
160
  - lib/beeps/processor.rb
161
+ - lib/beeps/signals.rb
148
162
  - lib/beeps/sound.rb
149
163
  - src/analyser.cpp
150
164
  - src/beeps.cpp
@@ -153,6 +167,8 @@ files:
153
167
  - src/exception.cpp
154
168
  - src/file_in.cpp
155
169
  - src/gain.cpp
170
+ - src/high_pass.cpp
171
+ - src/low_pass.cpp
156
172
  - src/mic_in.cpp
157
173
  - src/mic_in.h
158
174
  - src/mixer.cpp
@@ -164,6 +180,7 @@ files:
164
180
  - src/pitch_shift.cpp
165
181
  - src/processor.cpp
166
182
  - src/processor.h
183
+ - src/reverb.cpp
167
184
  - src/sequencer.cpp
168
185
  - src/signals.cpp
169
186
  - src/signals.h
@@ -174,13 +191,24 @@ files:
174
191
  - src/win32/exception.cpp
175
192
  - src/win32/exception.h
176
193
  - src/win32/signals.cpp
194
+ - src/x_pass.h
177
195
  - test/helper.rb
196
+ - test/test_analyser.rb
178
197
  - test/test_beeps.rb
179
198
  - test/test_beeps_init.rb
199
+ - test/test_envelope.rb
180
200
  - test/test_file_in.rb
201
+ - test/test_gain.rb
202
+ - test/test_high_pass.rb
203
+ - test/test_low_pass.rb
204
+ - test/test_mixer.rb
205
+ - test/test_oscillator.rb
206
+ - test/test_pitch_shift.rb
181
207
  - test/test_processor.rb
208
+ - test/test_signals.rb
182
209
  - test/test_sound.rb
183
210
  - test/test_sound_player.rb
211
+ - test/test_time_stretch.rb
184
212
  homepage: https://github.com/xord/beeps
185
213
  licenses:
186
214
  - MIT
@@ -207,9 +235,19 @@ specification_version: 4
207
235
  summary: Plays beep sound.
208
236
  test_files:
209
237
  - test/helper.rb
238
+ - test/test_analyser.rb
210
239
  - test/test_beeps.rb
211
240
  - test/test_beeps_init.rb
241
+ - test/test_envelope.rb
212
242
  - test/test_file_in.rb
243
+ - test/test_gain.rb
244
+ - test/test_high_pass.rb
245
+ - test/test_low_pass.rb
246
+ - test/test_mixer.rb
247
+ - test/test_oscillator.rb
248
+ - test/test_pitch_shift.rb
213
249
  - test/test_processor.rb
250
+ - test/test_signals.rb
214
251
  - test/test_sound.rb
215
252
  - test/test_sound_player.rb
253
+ - test/test_time_stretch.rb