beeps 0.3.11 → 0.3.12
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 +4 -4
- data/.doc/ext/beeps/sound_player.cpp +57 -0
- data/.github/workflows/release-gem.yml +3 -0
- data/.github/workflows/utils.rb +88 -17
- data/ChangeLog.md +14 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/beeps.gemspec +3 -4
- data/ext/beeps/extconf.rb +1 -1
- data/ext/beeps/sound_player.cpp +64 -1
- data/include/beeps/defs.h +2 -0
- data/include/beeps/filter.h +6 -0
- data/include/beeps/generator.h +8 -2
- data/include/beeps/processor.h +10 -8
- data/include/beeps/ruby.h +2 -2
- data/include/beeps/signals.h +14 -0
- data/include/beeps/sound.h +12 -0
- data/include/beeps.h +2 -2
- data/lib/beeps/extension.rb +8 -2
- data/lib/beeps/sound.rb +1 -1
- data/src/analyser.cpp +10 -3
- data/src/envelope.cpp +2 -5
- data/src/file_in.cpp +7 -1
- data/src/gain.cpp +7 -0
- data/src/mixer.cpp +16 -3
- data/src/oscillator.cpp +7 -1
- data/src/osx/signals.mm +4 -4
- data/src/osx/text_in.mm +1 -1
- data/src/processor.cpp +51 -38
- data/src/processor.h +1 -5
- data/src/reverb.cpp +2 -3
- data/src/sequencer.cpp +4 -4
- data/src/signals.cpp +178 -161
- data/src/signals.h +2 -15
- data/src/sound.cpp +154 -5
- data/src/time_stretch.cpp +2 -2
- data/src/value.cpp +8 -2
- data/src/win32/signals.cpp +9 -9
- data/src/x_pass.h +2 -3
- data/test/test_sound_player.rb +70 -0
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8a848993e9610dd9598a6685f4ef669083aea313d68b533fb6d222b723348cd9
|
|
4
|
+
data.tar.gz: ea8610eb20594ac731580377a1d7966fac499afb36074973149d2449deaab14e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7942136dd8a5cedc43842ff907211d73e38864b80b7aa4a79287d95d2e9bc5531d551afd8a08acf6ca294c9f73e66feb37c2a02be996d8484e9347e94c663b6f
|
|
7
|
+
data.tar.gz: 6ea818cccb69bbc0967700687dc23ef699802d5c915770be1153fc175a9150f0ae5a0bd845831c17ae86c8239c42915bd596718f1a5ca1b98662ea73f09b88d7
|
|
@@ -61,6 +61,57 @@ VALUE get_state(VALUE self)
|
|
|
61
61
|
return value(THIS->state());
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
static
|
|
65
|
+
VALUE set_position(VALUE self, VALUE position)
|
|
66
|
+
{
|
|
67
|
+
CHECK;
|
|
68
|
+
|
|
69
|
+
THIS->set_position(to<uint>(position));
|
|
70
|
+
return position;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static
|
|
74
|
+
VALUE get_position(VALUE self)
|
|
75
|
+
{
|
|
76
|
+
CHECK;
|
|
77
|
+
|
|
78
|
+
return value(THIS->position());
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static
|
|
82
|
+
VALUE set_time(VALUE self, VALUE time)
|
|
83
|
+
{
|
|
84
|
+
CHECK;
|
|
85
|
+
|
|
86
|
+
THIS->set_time(to<float>(time));
|
|
87
|
+
return time;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static
|
|
91
|
+
VALUE get_time(VALUE self)
|
|
92
|
+
{
|
|
93
|
+
CHECK;
|
|
94
|
+
|
|
95
|
+
return value(THIS->time());
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static
|
|
99
|
+
VALUE set_time_scale(VALUE self, VALUE scale)
|
|
100
|
+
{
|
|
101
|
+
CHECK;
|
|
102
|
+
|
|
103
|
+
THIS->set_time_scale(to<float>(scale));
|
|
104
|
+
return scale;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static
|
|
108
|
+
VALUE get_time_scale(VALUE self)
|
|
109
|
+
{
|
|
110
|
+
CHECK;
|
|
111
|
+
|
|
112
|
+
return value(THIS->time_scale());
|
|
113
|
+
}
|
|
114
|
+
|
|
64
115
|
static
|
|
65
116
|
VALUE set_gain(VALUE self, VALUE gain)
|
|
66
117
|
{
|
|
@@ -116,6 +167,12 @@ Init_beeps_sound_player ()
|
|
|
116
167
|
rb_define_method(cSoundPlayer, "rewind", RUBY_METHOD_FUNC(rewind), 0);
|
|
117
168
|
rb_define_method(cSoundPlayer, "stop", RUBY_METHOD_FUNC(stop), 0);
|
|
118
169
|
rb_define_method(cSoundPlayer, "state", RUBY_METHOD_FUNC(get_state), 0);
|
|
170
|
+
rb_define_method(cSoundPlayer, "position=", RUBY_METHOD_FUNC(set_position), 1);
|
|
171
|
+
rb_define_method(cSoundPlayer, "position", RUBY_METHOD_FUNC(get_position), 0);
|
|
172
|
+
rb_define_method(cSoundPlayer, "time=", RUBY_METHOD_FUNC(set_time), 1);
|
|
173
|
+
rb_define_method(cSoundPlayer, "time", RUBY_METHOD_FUNC(get_time), 0);
|
|
174
|
+
rb_define_method(cSoundPlayer, "time_scale=", RUBY_METHOD_FUNC(set_time_scale), 1);
|
|
175
|
+
rb_define_method(cSoundPlayer, "time_scale", RUBY_METHOD_FUNC(get_time_scale), 0);
|
|
119
176
|
rb_define_method(cSoundPlayer, "gain=", RUBY_METHOD_FUNC(set_gain), 1);
|
|
120
177
|
rb_define_method(cSoundPlayer, "gain", RUBY_METHOD_FUNC(get_gain), 0);
|
|
121
178
|
rb_define_method(cSoundPlayer, "loop=", RUBY_METHOD_FUNC(set_loop), 1);
|
data/.github/workflows/utils.rb
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
require 'shellwords'
|
|
2
|
+
|
|
3
|
+
ALL_REPO = 'xord/all'
|
|
4
|
+
ALL_DIR = '../all'
|
|
5
|
+
ALL_FETCH_DEPTH = 100
|
|
6
|
+
|
|
1
7
|
RENAMES = {reflex: 'reflexion'}
|
|
2
8
|
|
|
3
9
|
def sh(cmd)
|
|
@@ -5,7 +11,7 @@ def sh(cmd)
|
|
|
5
11
|
system cmd
|
|
6
12
|
end
|
|
7
13
|
|
|
8
|
-
def setup_dependencies(
|
|
14
|
+
def setup_dependencies(only: nil)
|
|
9
15
|
gemspec_path = `git ls-files`.lines(chomp: true).find {|l| l =~ /\.gemspec$/}
|
|
10
16
|
return unless gemspec_path
|
|
11
17
|
|
|
@@ -13,44 +19,109 @@ def setup_dependencies(build: true, only: nil)
|
|
|
13
19
|
name = File.basename gemspec_path, '.gemspec'
|
|
14
20
|
|
|
15
21
|
exts = File.readlines('Rakefile')
|
|
16
|
-
.map {|l| l[%r|^\s*require\W+(\w+)/extension\W+$|, 1]}
|
|
22
|
+
.map {|l| l[%r|^\s*require\W+([\w\-\_]+)/extension\W+$|, 1]}
|
|
17
23
|
.compact
|
|
18
24
|
.reject {|ext| ext == name}
|
|
19
25
|
exts = exts & [only].flatten.map(&:to_s) if only
|
|
26
|
+
return if exts.empty?
|
|
27
|
+
|
|
28
|
+
unless setup_dependencies_via_monorepo(exts)
|
|
29
|
+
setup_dependencies_via_each_repo_by_version(gemspec, exts)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
exts.each {|ext| sh %( cd ../#{ext} && rake ext )}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def setup_dependencies_via_monorepo(exts)
|
|
36
|
+
return false unless checkout_monorepo
|
|
37
|
+
exts.each {|ext| sh %( ln -snf all/#{ext} ../#{ext} )}
|
|
38
|
+
true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def checkout_monorepo()
|
|
42
|
+
uuid = `git log -1 --format=%B`[/^\[\[([0-9a-fA-F-]+)\]\]$/, 1]
|
|
43
|
+
return false unless uuid
|
|
44
|
+
|
|
45
|
+
commit = setup_monorepo uuid
|
|
46
|
+
return false unless commit
|
|
47
|
+
|
|
48
|
+
Dir.chdir(ALL_DIR) {sh %( git checkout -q #{commit} )}
|
|
49
|
+
true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def setup_monorepo(uuid)
|
|
53
|
+
unless File.directory? ALL_DIR
|
|
54
|
+
url = "https://github.com/#{ALL_REPO}.git"
|
|
55
|
+
sh %( git clone --no-tags --depth #{ALL_FETCH_DEPTH} #{url} #{ALL_DIR} )
|
|
56
|
+
end
|
|
57
|
+
loop do
|
|
58
|
+
commit = find_monorepo_commit uuid
|
|
59
|
+
return commit if commit
|
|
60
|
+
|
|
61
|
+
deepened = Dir.chdir ALL_DIR do
|
|
62
|
+
before = `git rev-list --count HEAD`.to_i
|
|
63
|
+
sh %( git fetch --deepen #{ALL_FETCH_DEPTH} )
|
|
64
|
+
`git rev-list --count HEAD`.to_i > before
|
|
65
|
+
end
|
|
66
|
+
return nil unless deepened
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def find_monorepo_commit(uuid)
|
|
71
|
+
Dir.chdir ALL_DIR do
|
|
72
|
+
out = `git log origin/HEAD -F --grep="[[#{uuid}]]" --format=%H -1`.strip
|
|
73
|
+
out.empty? ? nil : out
|
|
74
|
+
end
|
|
75
|
+
end
|
|
20
76
|
|
|
77
|
+
def setup_dependencies_via_each_repo_by_version(gemspec, exts)
|
|
21
78
|
exts.each do |ext|
|
|
22
79
|
gem = RENAMES[ext.to_sym].then {|s| s || ext}
|
|
23
|
-
ver = gemspec[/add_dependency.*['"]#{gem}['"].*['"]\s
|
|
80
|
+
ver = gemspec[/add_dependency.*['"]#{gem}['"].*['"]\s*~>\s*([\d\.]+)\s*['"]/, 1]
|
|
24
81
|
opts = '-c advice.detachedHead=false --depth 1'
|
|
25
82
|
clone = "git clone #{opts} https://github.com/xord/#{ext}.git ../#{ext}"
|
|
26
83
|
|
|
27
84
|
# 'rake subtree:push' pushes all subrepos, so cloning by new tag
|
|
28
85
|
# often fails before tagging each new tag
|
|
29
86
|
sh %( #{clone} --branch v#{ver} || #{clone} )
|
|
30
|
-
sh %( cd ../#{ext} && rake ext )
|
|
31
87
|
end
|
|
32
88
|
end
|
|
33
89
|
|
|
34
90
|
def tag_versions()
|
|
35
|
-
|
|
36
|
-
|
|
91
|
+
changes = changelogs
|
|
92
|
+
tags = `git tag`.lines chomp: true
|
|
93
|
+
vers = `git log --oneline ./VERSION`
|
|
37
94
|
.lines(chomp: true)
|
|
38
95
|
.map {|line| line.split.first[/^\w+$/]}
|
|
39
|
-
.map {|
|
|
40
|
-
.select {|ver,
|
|
96
|
+
.map {|sha| [`git cat-file -p #{sha}:./VERSION 2>/dev/null`[/[\d\.]+/], sha]}
|
|
97
|
+
.select {|ver, sha| ver && sha}
|
|
41
98
|
.reverse
|
|
42
99
|
.to_h
|
|
43
100
|
|
|
44
|
-
|
|
45
|
-
.split(/^\s*##\s*\[\s*v([\d\.]+)\s*\].*$/)
|
|
46
|
-
.slice(1..-1)
|
|
47
|
-
.each_slice(2)
|
|
48
|
-
.to_h
|
|
49
|
-
.transform_values(&:strip!)
|
|
50
|
-
|
|
51
|
-
vers.to_a.reverse.each do |ver, hash|
|
|
101
|
+
vers.to_a.reverse.each do |ver, sha|
|
|
52
102
|
tag = "v#{ver}"
|
|
53
103
|
break if tags.include?(tag)
|
|
54
|
-
sh %( git tag -a -m \"#{changes[
|
|
104
|
+
sh %( git tag -a -m \"#{changes[tag]&.gsub '"', '\\"'}\" #{tag} #{sha} )
|
|
55
105
|
end
|
|
56
106
|
end
|
|
107
|
+
|
|
108
|
+
def release(*paths)
|
|
109
|
+
tag = ENV['GITHUB_REF']&.sub(%r|^refs/tags/|, '') || raise('GITHUB_REF tag not set')
|
|
110
|
+
notes = (changelogs[tag] || '').shellescape
|
|
111
|
+
paths = paths.flatten.join ' '
|
|
112
|
+
|
|
113
|
+
sh(%( gh release create #{tag} #{paths} --notes #{notes} )) ||
|
|
114
|
+
sh(%( gh release upload #{tag} #{paths} --clobber )) ||
|
|
115
|
+
raise('failed to upload to releases')
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def changelogs()
|
|
119
|
+
File.read('ChangeLog.md')
|
|
120
|
+
.split(/^\s*##\s*\[\s*(v[\d\.]+)\s*\].*$/)
|
|
121
|
+
.slice(1..)
|
|
122
|
+
.each_slice(2)
|
|
123
|
+
.to_h
|
|
124
|
+
.transform_values(&:strip!)
|
|
125
|
+
rescue Errno::ENOENT
|
|
126
|
+
raise 'failed to get changelogs'
|
|
127
|
+
end
|
data/ChangeLog.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
# beeps ChangeLog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [v0.3.12] - 2026-05-10
|
|
5
|
+
|
|
6
|
+
- Support WebAssembly
|
|
7
|
+
- Add adaptive stream buffering to prevent audio underruns
|
|
8
|
+
- Add position(), time(), time_scale() to SoundPlayer and seekable() to Processor
|
|
9
|
+
- Add constructors, clear(), and append() to Signals as public API
|
|
10
|
+
- Move set_buffering_seconds() from Filter to Processor
|
|
11
|
+
- Rename max_segment_size_for_process() to get_max_segment_size_for_process()
|
|
12
|
+
- Bump AudioFile from 1.1.1 to 1.1.4 to fix Windows CI
|
|
13
|
+
- Remove deprecated has_rdoc= from gemspecs
|
|
14
|
+
|
|
15
|
+
- Fix SignalSamples copying channel 0 data to all channels
|
|
16
|
+
|
|
17
|
+
|
|
4
18
|
## [v0.3.11] - 2026-04-17
|
|
5
19
|
|
|
6
20
|
- Update dependencies
|
data/Rakefile
CHANGED
|
@@ -25,7 +25,7 @@ use_external_library 'https://github.com/thestk/stk',
|
|
|
25
25
|
excludes: %w[stk/src/include Tcp Udp Socket Thread Mutex InetWv /Rt]
|
|
26
26
|
|
|
27
27
|
use_external_library 'https://github.com/adamstark/AudioFile',
|
|
28
|
-
tag: '1.1.
|
|
28
|
+
tag: '1.1.4',
|
|
29
29
|
srcdirs: 'NOSRC',
|
|
30
30
|
excludes: %w[examples/ tests/]
|
|
31
31
|
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.3.
|
|
1
|
+
0.3.12
|
data/beeps.gemspec
CHANGED
|
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
ext = Beeps::Extension
|
|
13
|
-
name = ext.name
|
|
13
|
+
name = ext.name true
|
|
14
14
|
rdocs = glob.call *%w[README .doc/ext/**/*.cpp]
|
|
15
15
|
|
|
16
16
|
s.name = name
|
|
@@ -25,14 +25,13 @@ Gem::Specification.new do |s|
|
|
|
25
25
|
s.platform = Gem::Platform::RUBY
|
|
26
26
|
s.required_ruby_version = '>= 3.0.0'
|
|
27
27
|
|
|
28
|
-
s.add_dependency 'xot', '~> 0.3.
|
|
29
|
-
s.add_dependency 'rucy', '~> 0.3.
|
|
28
|
+
s.add_dependency 'xot', '~> 0.3.12'
|
|
29
|
+
s.add_dependency 'rucy', '~> 0.3.12'
|
|
30
30
|
|
|
31
31
|
s.files = `git ls-files`.split $/
|
|
32
32
|
s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
|
|
33
33
|
s.test_files = s.files.grep %r{^(test|spec|features)/}
|
|
34
34
|
s.extra_rdoc_files = rdocs.to_a
|
|
35
|
-
s.has_rdoc = true
|
|
36
35
|
|
|
37
36
|
s.metadata['msys2_mingw_dependencies'] = 'openal'
|
|
38
37
|
|
data/ext/beeps/extconf.rb
CHANGED
data/ext/beeps/sound_player.cpp
CHANGED
|
@@ -67,6 +67,63 @@ RUCY_DEF0(get_state)
|
|
|
67
67
|
}
|
|
68
68
|
RUCY_END
|
|
69
69
|
|
|
70
|
+
static
|
|
71
|
+
RUCY_DEF1(set_position, position)
|
|
72
|
+
{
|
|
73
|
+
CHECK;
|
|
74
|
+
|
|
75
|
+
THIS->set_position(to<uint>(position));
|
|
76
|
+
return position;
|
|
77
|
+
}
|
|
78
|
+
RUCY_END
|
|
79
|
+
|
|
80
|
+
static
|
|
81
|
+
RUCY_DEF0(get_position)
|
|
82
|
+
{
|
|
83
|
+
CHECK;
|
|
84
|
+
|
|
85
|
+
return value(THIS->position());
|
|
86
|
+
}
|
|
87
|
+
RUCY_END
|
|
88
|
+
|
|
89
|
+
static
|
|
90
|
+
RUCY_DEF1(set_time, time)
|
|
91
|
+
{
|
|
92
|
+
CHECK;
|
|
93
|
+
|
|
94
|
+
THIS->set_time(to<float>(time));
|
|
95
|
+
return time;
|
|
96
|
+
}
|
|
97
|
+
RUCY_END
|
|
98
|
+
|
|
99
|
+
static
|
|
100
|
+
RUCY_DEF0(get_time)
|
|
101
|
+
{
|
|
102
|
+
CHECK;
|
|
103
|
+
|
|
104
|
+
return value(THIS->time());
|
|
105
|
+
}
|
|
106
|
+
RUCY_END
|
|
107
|
+
|
|
108
|
+
static
|
|
109
|
+
RUCY_DEF1(set_time_scale, scale)
|
|
110
|
+
{
|
|
111
|
+
CHECK;
|
|
112
|
+
|
|
113
|
+
THIS->set_time_scale(to<float>(scale));
|
|
114
|
+
return scale;
|
|
115
|
+
}
|
|
116
|
+
RUCY_END
|
|
117
|
+
|
|
118
|
+
static
|
|
119
|
+
RUCY_DEF0(get_time_scale)
|
|
120
|
+
{
|
|
121
|
+
CHECK;
|
|
122
|
+
|
|
123
|
+
return value(THIS->time_scale());
|
|
124
|
+
}
|
|
125
|
+
RUCY_END
|
|
126
|
+
|
|
70
127
|
static
|
|
71
128
|
RUCY_DEF1(set_gain, gain)
|
|
72
129
|
{
|
|
@@ -126,7 +183,13 @@ Init_beeps_sound_player ()
|
|
|
126
183
|
cSoundPlayer.define_method("pause", pause);
|
|
127
184
|
cSoundPlayer.define_method("rewind", rewind);
|
|
128
185
|
cSoundPlayer.define_method("stop", stop);
|
|
129
|
-
cSoundPlayer.define_method("state",
|
|
186
|
+
cSoundPlayer.define_method("state", get_state);
|
|
187
|
+
cSoundPlayer.define_method("position=", set_position);
|
|
188
|
+
cSoundPlayer.define_method("position", get_position);
|
|
189
|
+
cSoundPlayer.define_method("time=", set_time);
|
|
190
|
+
cSoundPlayer.define_method("time", get_time);
|
|
191
|
+
cSoundPlayer.define_method("time_scale=", set_time_scale);
|
|
192
|
+
cSoundPlayer.define_method("time_scale", get_time_scale);
|
|
130
193
|
cSoundPlayer.define_method("gain=", set_gain);
|
|
131
194
|
cSoundPlayer.define_method("gain", get_gain);
|
|
132
195
|
cSoundPlayer.define_method("loop=", set_loop);
|
data/include/beeps/defs.h
CHANGED
data/include/beeps/filter.h
CHANGED
|
@@ -27,6 +27,8 @@ namespace Beeps
|
|
|
27
27
|
|
|
28
28
|
virtual float gain () const;
|
|
29
29
|
|
|
30
|
+
bool seekable () const override;
|
|
31
|
+
|
|
30
32
|
struct Data;
|
|
31
33
|
|
|
32
34
|
Xot::PImpl<Data> self;
|
|
@@ -70,6 +72,8 @@ namespace Beeps
|
|
|
70
72
|
|
|
71
73
|
virtual operator bool () const override;
|
|
72
74
|
|
|
75
|
+
bool seekable () const override;
|
|
76
|
+
|
|
73
77
|
struct Data;
|
|
74
78
|
|
|
75
79
|
Xot::PImpl<Data> self;
|
|
@@ -303,6 +307,8 @@ namespace Beeps
|
|
|
303
307
|
|
|
304
308
|
virtual operator bool () const override;
|
|
305
309
|
|
|
310
|
+
bool seekable () const override;
|
|
311
|
+
|
|
306
312
|
struct Data;
|
|
307
313
|
|
|
308
314
|
Xot::PImpl<Data> self;
|
data/include/beeps/generator.h
CHANGED
|
@@ -63,6 +63,8 @@ namespace Beeps
|
|
|
63
63
|
|
|
64
64
|
virtual const_iterator end () const;
|
|
65
65
|
|
|
66
|
+
bool seekable () const override;
|
|
67
|
+
|
|
66
68
|
struct Data;
|
|
67
69
|
|
|
68
70
|
Xot::PImpl<Data> self;
|
|
@@ -72,7 +74,7 @@ namespace Beeps
|
|
|
72
74
|
virtual void generate (
|
|
73
75
|
Context* context, Signals* signals, uint* offset) override;
|
|
74
76
|
|
|
75
|
-
virtual int
|
|
77
|
+
virtual int get_max_segment_size_for_process (
|
|
76
78
|
double sample_rate, uint nsamples) const override;
|
|
77
79
|
|
|
78
80
|
};// Value
|
|
@@ -140,6 +142,8 @@ namespace Beeps
|
|
|
140
142
|
|
|
141
143
|
virtual operator bool () const override;
|
|
142
144
|
|
|
145
|
+
bool seekable () const override;
|
|
146
|
+
|
|
143
147
|
struct Data;
|
|
144
148
|
|
|
145
149
|
Xot::PImpl<Data> self;
|
|
@@ -149,7 +153,7 @@ namespace Beeps
|
|
|
149
153
|
virtual void generate (
|
|
150
154
|
Context* context, Signals* signals, uint* offset) override;
|
|
151
155
|
|
|
152
|
-
virtual int
|
|
156
|
+
virtual int get_max_segment_size_for_process (
|
|
153
157
|
double sample_rate, uint nsamples) const override;
|
|
154
158
|
|
|
155
159
|
};// Oscillator
|
|
@@ -240,6 +244,8 @@ namespace Beeps
|
|
|
240
244
|
|
|
241
245
|
virtual operator bool () const override;
|
|
242
246
|
|
|
247
|
+
bool seekable () const override;
|
|
248
|
+
|
|
243
249
|
struct Data;
|
|
244
250
|
|
|
245
251
|
Xot::PImpl<Data> self;
|
data/include/beeps/processor.h
CHANGED
|
@@ -24,7 +24,7 @@ namespace Beeps
|
|
|
24
24
|
|
|
25
25
|
class Context {};
|
|
26
26
|
|
|
27
|
-
typedef Xot::Ref<This>
|
|
27
|
+
typedef Xot::Ref<This> Ref;
|
|
28
28
|
|
|
29
29
|
typedef std::map<uint, Ref> Map;
|
|
30
30
|
|
|
@@ -38,6 +38,8 @@ namespace Beeps
|
|
|
38
38
|
|
|
39
39
|
virtual const Processor* input () const;
|
|
40
40
|
|
|
41
|
+
virtual bool seekable () const;
|
|
42
|
+
|
|
41
43
|
virtual void on_start ();
|
|
42
44
|
|
|
43
45
|
virtual operator bool () const;
|
|
@@ -58,17 +60,19 @@ namespace Beeps
|
|
|
58
60
|
|
|
59
61
|
virtual void filter (Context* context, Signals* signals, uint* offset);
|
|
60
62
|
|
|
61
|
-
virtual int max_segment_size_for_process (
|
|
62
|
-
double sample_rate, uint nsamples) const;
|
|
63
|
-
|
|
64
|
-
virtual uint get_segment_size (double sample_rate, uint nsamples) const;
|
|
65
|
-
|
|
66
63
|
virtual void set_sub_input (uint index, Processor* input);
|
|
67
64
|
|
|
68
65
|
virtual Processor* sub_input (uint index) const;
|
|
69
66
|
|
|
70
67
|
virtual void clear_sub_input_unless_processing (uint index);
|
|
71
68
|
|
|
69
|
+
virtual uint get_segment_size (double sample_rate, uint nsamples) const;
|
|
70
|
+
|
|
71
|
+
virtual int get_max_segment_size_for_process (
|
|
72
|
+
double sample_rate, uint nsamples) const;
|
|
73
|
+
|
|
74
|
+
void set_buffering_seconds (float seconds);
|
|
75
|
+
|
|
72
76
|
virtual void set_updated ();
|
|
73
77
|
|
|
74
78
|
friend class ProcessorContext;
|
|
@@ -102,8 +106,6 @@ namespace Beeps
|
|
|
102
106
|
|
|
103
107
|
Filter (Processor* input = NULL);
|
|
104
108
|
|
|
105
|
-
void set_buffering_seconds (float seconds);
|
|
106
|
-
|
|
107
109
|
private:
|
|
108
110
|
|
|
109
111
|
void generate (
|
data/include/beeps/ruby.h
CHANGED
data/include/beeps/signals.h
CHANGED
|
@@ -19,10 +19,24 @@ namespace Beeps
|
|
|
19
19
|
|
|
20
20
|
Signals ();
|
|
21
21
|
|
|
22
|
+
Signals (uint capacity, uint nchannels = 1, double sample_rate = 0);
|
|
23
|
+
|
|
24
|
+
Signals (
|
|
25
|
+
const float* const* channels, uint nsamples, uint nchannels,
|
|
26
|
+
double sample_rate = 0, uint capacity = 0);
|
|
27
|
+
|
|
22
28
|
~Signals ();
|
|
23
29
|
|
|
24
30
|
Signals dup () const;
|
|
25
31
|
|
|
32
|
+
void clear (uint capacity = 0);
|
|
33
|
+
|
|
34
|
+
uint append (
|
|
35
|
+
const float* const* channels, uint nsamples, uint nchannels,
|
|
36
|
+
double sample_rate = 0);
|
|
37
|
+
|
|
38
|
+
uint append (const Signals& source, uint source_offset = 0);
|
|
39
|
+
|
|
26
40
|
double sample_rate () const;
|
|
27
41
|
|
|
28
42
|
uint nchannels () const;
|
data/include/beeps/sound.h
CHANGED
|
@@ -47,6 +47,18 @@ namespace Beeps
|
|
|
47
47
|
|
|
48
48
|
State state () const;
|
|
49
49
|
|
|
50
|
+
void set_position (uint position);
|
|
51
|
+
|
|
52
|
+
uint position () const;
|
|
53
|
+
|
|
54
|
+
void set_time (float time);
|
|
55
|
+
|
|
56
|
+
float time () const;
|
|
57
|
+
|
|
58
|
+
void set_time_scale (float scale);
|
|
59
|
+
|
|
60
|
+
float time_scale () const;
|
|
61
|
+
|
|
50
62
|
void set_gain (float gain);
|
|
51
63
|
|
|
52
64
|
float gain () const;
|
data/include/beeps.h
CHANGED
data/lib/beeps/extension.rb
CHANGED
|
@@ -5,8 +5,10 @@ module Beeps
|
|
|
5
5
|
|
|
6
6
|
module_function
|
|
7
7
|
|
|
8
|
-
def name()
|
|
9
|
-
super.split('::')[-2]
|
|
8
|
+
def name(downcase = false)
|
|
9
|
+
super().split('::')[-2].then {|s|
|
|
10
|
+
downcase ? s.gsub(/([a-z])([A-Z])/) {"#{$1}-#{$2}"}.downcase : s
|
|
11
|
+
}
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def version()
|
|
@@ -29,6 +31,10 @@ module Beeps
|
|
|
29
31
|
root_dir 'ext'
|
|
30
32
|
end
|
|
31
33
|
|
|
34
|
+
def lib_name()
|
|
35
|
+
"#{name true}.dll" if /mswin|ming|cygwin/.match? RUBY_PLATFORM
|
|
36
|
+
end
|
|
37
|
+
|
|
32
38
|
end# Extension
|
|
33
39
|
|
|
34
40
|
|
data/lib/beeps/sound.rb
CHANGED
data/src/analyser.cpp
CHANGED
|
@@ -55,7 +55,7 @@ namespace Beeps
|
|
|
55
55
|
|
|
56
56
|
clear();
|
|
57
57
|
|
|
58
|
-
signals =
|
|
58
|
+
signals = Signals(std::min(size, (uint) Beeps::sample_rate()));
|
|
59
59
|
pffft .reset(pffft_new_setup(size, PFFFT_REAL));
|
|
60
60
|
fft_buffer.reset((float*) pffft_aligned_malloc(sizeof(float) * size));
|
|
61
61
|
fft_size = size;
|
|
@@ -192,6 +192,13 @@ namespace Beeps
|
|
|
192
192
|
return self->is_valid();
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
bool
|
|
196
|
+
Analyser::seekable () const
|
|
197
|
+
{
|
|
198
|
+
const Processor* in = input();
|
|
199
|
+
return !in || in->seekable();
|
|
200
|
+
}
|
|
201
|
+
|
|
195
202
|
static void
|
|
196
203
|
shift (Signals* signals, uint nsamples)
|
|
197
204
|
{
|
|
@@ -199,7 +206,7 @@ namespace Beeps
|
|
|
199
206
|
return;
|
|
200
207
|
|
|
201
208
|
if (nsamples > signals->nsamples())
|
|
202
|
-
return
|
|
209
|
+
return signals->clear();
|
|
203
210
|
|
|
204
211
|
Sample* from = Signals_at(signals, nsamples);
|
|
205
212
|
Sample* to = Signals_at(signals, 0);
|
|
@@ -237,7 +244,7 @@ namespace Beeps
|
|
|
237
244
|
auto& my = self->signals;
|
|
238
245
|
|
|
239
246
|
if (my.nchannels() != in.nchannels() || my.sample_rate() != in.sample_rate())
|
|
240
|
-
my =
|
|
247
|
+
my = Signals(my.capacity(), in.nchannels(), in.sample_rate());
|
|
241
248
|
|
|
242
249
|
uint total_nsamples = my.nsamples() + in.nsamples();
|
|
243
250
|
if (total_nsamples > my.capacity())
|
data/src/envelope.cpp
CHANGED
|
@@ -261,12 +261,9 @@ namespace Beeps
|
|
|
261
261
|
Super::filter(context, signals, offset);
|
|
262
262
|
|
|
263
263
|
if (!self->adsr_signals)
|
|
264
|
-
|
|
265
|
-
self->adsr_signals =
|
|
266
|
-
Signals_create(signals->nsamples(), 1, signals->sample_rate());
|
|
267
|
-
}
|
|
264
|
+
self->adsr_signals = Signals(signals->nsamples(), 1, signals->sample_rate());
|
|
268
265
|
else
|
|
269
|
-
|
|
266
|
+
self->adsr_signals.clear(signals->nsamples());
|
|
270
267
|
|
|
271
268
|
process_envelope_signals(this, &self->adsr_signals);
|
|
272
269
|
if (self->adsr_signals.nsamples() < signals->nsamples())
|