voicemeeter 0.0.1
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +775 -0
- data/lib/voicemeeter/base.rb +225 -0
- data/lib/voicemeeter/bus.rb +129 -0
- data/lib/voicemeeter/button.rb +70 -0
- data/lib/voicemeeter/cbindings.rb +81 -0
- data/lib/voicemeeter/command.rb +35 -0
- data/lib/voicemeeter/configs.rb +117 -0
- data/lib/voicemeeter/device.rb +28 -0
- data/lib/voicemeeter/event.rb +82 -0
- data/lib/voicemeeter/fx.rb +42 -0
- data/lib/voicemeeter/install.rb +38 -0
- data/lib/voicemeeter/iremote.rb +51 -0
- data/lib/voicemeeter/kinds.rb +51 -0
- data/lib/voicemeeter/logger.rb +9 -0
- data/lib/voicemeeter/meta.rb +75 -0
- data/lib/voicemeeter/midi.rb +14 -0
- data/lib/voicemeeter/mixins.rb +83 -0
- data/lib/voicemeeter/option.rb +69 -0
- data/lib/voicemeeter/patch.rb +79 -0
- data/lib/voicemeeter/recorder.rb +90 -0
- data/lib/voicemeeter/remote.rb +102 -0
- data/lib/voicemeeter/strip.rb +254 -0
- data/lib/voicemeeter/util.rb +35 -0
- data/lib/voicemeeter/vban.rb +105 -0
- data/lib/voicemeeter/version.rb +25 -0
- data/lib/voicemeeter/worker.rb +64 -0
- data/lib/voicemeeter.rb +56 -0
- metadata +149 -0
@@ -0,0 +1,102 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
# Builder module for Remote factories.
|
3
|
+
module Builder
|
4
|
+
private
|
5
|
+
|
6
|
+
def steps(step)
|
7
|
+
case step
|
8
|
+
when :strip then -> { (0...kind.num_strip).map { Strip::Base.make(self, _1) } }
|
9
|
+
when :bus then -> { (0...kind.num_bus).map { Bus::Base.make(self, _1) } }
|
10
|
+
when :button then -> { (0...kind.num_buttons).map { Button::Base.new(self, _1) } }
|
11
|
+
when :vban then -> { Vban::Base.new(self) }
|
12
|
+
when :command then -> { Command.new(self) }
|
13
|
+
when :recorder then -> { Recorder::Base.new(self) }
|
14
|
+
when :device then -> { Device.new(self) }
|
15
|
+
when :fx then -> { Fx.new(self) }
|
16
|
+
when :patch then -> { Patch::Base.new(self) }
|
17
|
+
when :option then -> { Option::Base.new(self) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def director
|
22
|
+
%i[strip bus button vban command device option]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Remote
|
27
|
+
extend Logging
|
28
|
+
|
29
|
+
# Concrete class for Remote
|
30
|
+
class Remote < Base
|
31
|
+
include Builder
|
32
|
+
|
33
|
+
public attr_reader :strip, :bus, :button, :vban, :command, :device, :option
|
34
|
+
|
35
|
+
def initialize(...)
|
36
|
+
super
|
37
|
+
director.each { |step| instance_variable_set("@#{step}", steps(step).call) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def configs
|
41
|
+
Configs.get(kind.name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def run
|
45
|
+
login
|
46
|
+
if event.any?
|
47
|
+
init_event_threads
|
48
|
+
end
|
49
|
+
|
50
|
+
yield(self) if block_given?
|
51
|
+
ensure
|
52
|
+
end_event_threads
|
53
|
+
logout
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Represents a RemoteBasic type
|
58
|
+
class RemoteBasic < Remote; end
|
59
|
+
|
60
|
+
# Represents a RemoteBanana type
|
61
|
+
class RemoteBanana < Remote
|
62
|
+
public attr_reader :recorder, :patch
|
63
|
+
|
64
|
+
private def director
|
65
|
+
super | [:recorder, :patch]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Represents a RemotePotato type
|
70
|
+
class RemotePotato < Remote
|
71
|
+
public attr_reader :recorder, :patch, :fx
|
72
|
+
|
73
|
+
private def director
|
74
|
+
super | [:recorder, :patch, :fx]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Factory class for Remote. Returns a Remote class of a kind.
|
79
|
+
class RequestRemote
|
80
|
+
def self.for(kind, **)
|
81
|
+
case kind.name
|
82
|
+
when :basic
|
83
|
+
RemoteBasic.new(kind, **)
|
84
|
+
when :banana
|
85
|
+
RemoteBanana.new(kind, **)
|
86
|
+
when :potato
|
87
|
+
RemotePotato.new(kind, **)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Interface entry point. Wraps factory class and handles kind errors.
|
93
|
+
def self.new(kind_id, **)
|
94
|
+
kind = Kinds.get(kind_id)
|
95
|
+
rescue KeyError => e
|
96
|
+
logger.error "#{e.class.name}: #{e.message}"
|
97
|
+
raise Errors::VMError.new "unknown Voicemeeter kind '#{kind_id}'"
|
98
|
+
else
|
99
|
+
RequestRemote.for(kind, **)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module Strip
|
3
|
+
# Base class for Strip
|
4
|
+
class Base
|
5
|
+
include IRemote
|
6
|
+
include Mixins::Outputs
|
7
|
+
include Mixins::Fades
|
8
|
+
|
9
|
+
attr_reader :gainlayer, :levels
|
10
|
+
|
11
|
+
def self.make(remote, i)
|
12
|
+
(i < remote.kind.phys_in) ? PhysicalStrip.new(remote, i) : VirtualStrip.new(remote, i)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(remote, i)
|
16
|
+
super
|
17
|
+
make_accessor_bool :solo, :mute, :mono
|
18
|
+
make_accessor_float :gain
|
19
|
+
make_accessor_int :limit
|
20
|
+
make_accessor_string :label
|
21
|
+
|
22
|
+
@gainlayer = (0...8).map { GainLayer.new(remote, i, _1) }
|
23
|
+
@levels = StripLevels.new(remote, i)
|
24
|
+
end
|
25
|
+
|
26
|
+
def identifier
|
27
|
+
"strip[#{@index}]"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Represents a Physical Strip
|
32
|
+
class PhysicalStrip < Base
|
33
|
+
include Mixins::Xy::Pan
|
34
|
+
include Mixins::Xy::Color
|
35
|
+
include Mixins::Xy::Fx
|
36
|
+
include Mixins::Fx
|
37
|
+
|
38
|
+
attr_reader :comp, :gate, :denoiser, :eq, :device
|
39
|
+
|
40
|
+
def initialize(remote, i)
|
41
|
+
super
|
42
|
+
make_accessor_float :audibility
|
43
|
+
|
44
|
+
@comp = StripComp.new(remote, i)
|
45
|
+
@gate = StripGate.new(remote, i)
|
46
|
+
@denoiser = StripDenoiser.new(remote, i)
|
47
|
+
@eq = StripEq.new(remote, i)
|
48
|
+
@device = StripDevice.new(remote, i)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class StripComp
|
53
|
+
include IRemote
|
54
|
+
|
55
|
+
def initialize(remote, i)
|
56
|
+
super
|
57
|
+
make_accessor_float :gainin,
|
58
|
+
:ratio,
|
59
|
+
:threshold,
|
60
|
+
:attack,
|
61
|
+
:release,
|
62
|
+
:knee,
|
63
|
+
:gainout
|
64
|
+
make_accessor_bool :makeup
|
65
|
+
end
|
66
|
+
|
67
|
+
def identifier
|
68
|
+
"strip[#{@index}].comp"
|
69
|
+
end
|
70
|
+
|
71
|
+
def knob
|
72
|
+
getter("")
|
73
|
+
end
|
74
|
+
|
75
|
+
def knob=(val)
|
76
|
+
setter("", val)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class StripGate
|
81
|
+
include IRemote
|
82
|
+
|
83
|
+
def initialize(remote, i)
|
84
|
+
super
|
85
|
+
make_accessor_float :threshold, :damping, :attack, :hold, :release
|
86
|
+
make_accessor_int :bpsidechain
|
87
|
+
end
|
88
|
+
|
89
|
+
def identifier
|
90
|
+
"strip[#{@index}].gate"
|
91
|
+
end
|
92
|
+
|
93
|
+
def knob
|
94
|
+
getter("")
|
95
|
+
end
|
96
|
+
|
97
|
+
def knob=(val)
|
98
|
+
setter("", val)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class StripDenoiser
|
103
|
+
include IRemote
|
104
|
+
|
105
|
+
def identifier
|
106
|
+
"strip[#{@index}].denoiser"
|
107
|
+
end
|
108
|
+
|
109
|
+
def knob
|
110
|
+
getter("")
|
111
|
+
end
|
112
|
+
|
113
|
+
def knob=(val)
|
114
|
+
setter("", val)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class StripEq
|
119
|
+
include IRemote
|
120
|
+
|
121
|
+
def initialize(remote, i)
|
122
|
+
super
|
123
|
+
make_accessor_bool :on, :ab
|
124
|
+
end
|
125
|
+
|
126
|
+
def identifier
|
127
|
+
"strip[#{@index}].eq"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class StripDevice
|
132
|
+
include IRemote
|
133
|
+
|
134
|
+
def initialize(remote, i)
|
135
|
+
super
|
136
|
+
make_reader_int :sr
|
137
|
+
make_reader_string :name
|
138
|
+
make_writer_string :wdm, :ks, :mme, :asio
|
139
|
+
end
|
140
|
+
|
141
|
+
def identifier
|
142
|
+
"strip[#{@index}].device"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Represents a Virtual Strip
|
147
|
+
class VirtualStrip < Base
|
148
|
+
include Mixins::Xy::Pan
|
149
|
+
include Mixins::Apps
|
150
|
+
|
151
|
+
def initialize(remote, i)
|
152
|
+
super
|
153
|
+
make_accessor_bool :mc
|
154
|
+
make_accessor_int :karaoke
|
155
|
+
end
|
156
|
+
|
157
|
+
def bass
|
158
|
+
round(getter("EQGain1"), 1)
|
159
|
+
end
|
160
|
+
|
161
|
+
def bass=(val)
|
162
|
+
setter("EQGain1", val)
|
163
|
+
end
|
164
|
+
|
165
|
+
def mid
|
166
|
+
round(getter("EQGain2"), 1)
|
167
|
+
end
|
168
|
+
|
169
|
+
def mid=(val)
|
170
|
+
setter("EQGain2", val)
|
171
|
+
end
|
172
|
+
|
173
|
+
def treble
|
174
|
+
round(getter("EQGain3"), 1)
|
175
|
+
end
|
176
|
+
|
177
|
+
def treble=(val)
|
178
|
+
setter("EQGain3", val)
|
179
|
+
end
|
180
|
+
|
181
|
+
alias_method :med, :mid
|
182
|
+
alias_method :med=, :mid=
|
183
|
+
alias_method :high, :treble
|
184
|
+
alias_method :high=, :treble=
|
185
|
+
end
|
186
|
+
|
187
|
+
class GainLayer
|
188
|
+
include IRemote
|
189
|
+
|
190
|
+
def initialize(remote, i, j)
|
191
|
+
super(remote, i)
|
192
|
+
@j = j
|
193
|
+
end
|
194
|
+
|
195
|
+
def identifier
|
196
|
+
"strip[#{@index}]"
|
197
|
+
end
|
198
|
+
|
199
|
+
def gain
|
200
|
+
getter("gainlayer[#{@j}]")
|
201
|
+
end
|
202
|
+
|
203
|
+
def gain=(value)
|
204
|
+
setter("gainlayer[#{@j}]", value)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
class StripLevels
|
209
|
+
include IRemote
|
210
|
+
|
211
|
+
def initialize(remote, i)
|
212
|
+
super
|
213
|
+
p_in = remote.kind.phys_in
|
214
|
+
if i < p_in
|
215
|
+
@init = i * 2
|
216
|
+
@offset = 2
|
217
|
+
else
|
218
|
+
@init = (p_in * 2) + ((i - p_in) * 8)
|
219
|
+
@offset = 8
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def identifier
|
224
|
+
"strip[#{@index}]"
|
225
|
+
end
|
226
|
+
|
227
|
+
def get_level(mode)
|
228
|
+
convert = ->(x) { (x > 0) ? (20 * Math.log(x, 10)).round(1) : -200.0 }
|
229
|
+
|
230
|
+
@remote.cache[:strip_mode] = mode
|
231
|
+
vals = if @remote.running? && @remote.event.ldirty
|
232
|
+
@remote.cache[:strip_level][@init, @offset]
|
233
|
+
else
|
234
|
+
(@init...@init + @offset).map { |i| @remote.get_level(mode, i) }
|
235
|
+
end
|
236
|
+
vals.map(&convert)
|
237
|
+
end
|
238
|
+
|
239
|
+
def prefader
|
240
|
+
get_level(Mixins::LevelEnum::PREFADER)
|
241
|
+
end
|
242
|
+
|
243
|
+
def postfader
|
244
|
+
get_level(Mixins::LevelEnum::POSTFADER)
|
245
|
+
end
|
246
|
+
|
247
|
+
def postmute
|
248
|
+
get_level(Mixins::LevelEnum::POSTMUTE)
|
249
|
+
end
|
250
|
+
|
251
|
+
def isdirty? = @remote.cache[:strip_comp][@init, @offset].any?
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module Util
|
3
|
+
module CoreExtensions
|
4
|
+
refine String do
|
5
|
+
def snakecase
|
6
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
7
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
8
|
+
.tr("-", "_")
|
9
|
+
.gsub(/\s/, "_")
|
10
|
+
.gsub(/__+/, "_")
|
11
|
+
.downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
def camelcase
|
15
|
+
self if self !~ /_/ && self =~ /[A-Z]+.*/
|
16
|
+
split("_").map(&:capitalize).join
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Cache
|
22
|
+
def get(name, is_string = false)
|
23
|
+
return cache.delete(name) if cache.key? name
|
24
|
+
clear_dirty if @sync
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_buttonstatus(id, mode)
|
29
|
+
return cache.delete("mb_#{id}_#{mode}") if cache.key? "mb_#{id}_#{mode}"
|
30
|
+
clear_dirty if @sync
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module Vban
|
3
|
+
# Base class for Vban In/Out Streams
|
4
|
+
class VbanStream
|
5
|
+
include IRemote
|
6
|
+
|
7
|
+
def initialize(remote, i)
|
8
|
+
super
|
9
|
+
make_accessor_bool :on
|
10
|
+
make_accessor_string :name, :ip
|
11
|
+
make_accessor_int :quality, :route
|
12
|
+
end
|
13
|
+
|
14
|
+
def identifier
|
15
|
+
"vban.#{direction}stream[#{@index}]"
|
16
|
+
end
|
17
|
+
|
18
|
+
def direction
|
19
|
+
raise "Called abstract method: direction"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Represents a Vban InStream
|
24
|
+
class VbanInstream < VbanStream
|
25
|
+
def initialize(remote, i)
|
26
|
+
super
|
27
|
+
make_reader_int :sr, :channel, :bit
|
28
|
+
end
|
29
|
+
|
30
|
+
def direction
|
31
|
+
:in
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Represents a Vban Audio InStream
|
36
|
+
class VbanAudioInstream < VbanInstream; end
|
37
|
+
|
38
|
+
# Represents a Vban Midi InStream
|
39
|
+
class VbanMidiInstream < VbanInstream; end
|
40
|
+
|
41
|
+
# Represents a Vban Text InStream
|
42
|
+
class VbanTextInstream < VbanInstream; end
|
43
|
+
|
44
|
+
# Represents a Vban OutStream
|
45
|
+
class VbanOutstream < VbanStream
|
46
|
+
def initialize(remote, i)
|
47
|
+
super
|
48
|
+
make_accessor_int :sr, :channel, :bit
|
49
|
+
end
|
50
|
+
|
51
|
+
def direction
|
52
|
+
:out
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Represents a Vban Audio OutStream
|
57
|
+
class VbanAudioOutstream < VbanOutstream; end
|
58
|
+
|
59
|
+
# Represents a Vban Midi OutStream
|
60
|
+
class VbanMidiOutstream < VbanOutstream; end
|
61
|
+
|
62
|
+
class RequestVbanStream
|
63
|
+
def self.for(remote, i, dir)
|
64
|
+
vban_in, vban_out, midi, _ = remote.kind.vban
|
65
|
+
case dir
|
66
|
+
when :in
|
67
|
+
if i < vban_in
|
68
|
+
VbanAudioInstream.new(remote, i)
|
69
|
+
elsif i < vban_in + midi
|
70
|
+
VbanMidiInstream.new(remote, i)
|
71
|
+
else
|
72
|
+
VbanTextInstream.new(remote, i)
|
73
|
+
end
|
74
|
+
when :out
|
75
|
+
if i < vban_out
|
76
|
+
VbanAudioOutstream.new(remote, i)
|
77
|
+
elsif i < vban_out + midi
|
78
|
+
VbanMidiOutstream.new(remote, i)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Base class for Vban
|
85
|
+
class Base
|
86
|
+
attr_reader :instream, :outstream
|
87
|
+
|
88
|
+
def initialize(remote)
|
89
|
+
vban_in, vban_out, midi, text = remote.kind.vban
|
90
|
+
@instream = (0...vban_in + midi + text).map { RequestVbanStream.for(remote, _1, :in) }
|
91
|
+
@outstream = (0...vban_out + midi).map { RequestVbanStream.for(remote, _1, :out) }
|
92
|
+
|
93
|
+
@remote = remote
|
94
|
+
end
|
95
|
+
|
96
|
+
def enable
|
97
|
+
@remote.set("vban.enable", 1)
|
98
|
+
end
|
99
|
+
|
100
|
+
def disable
|
101
|
+
@remote.set("vban.enable", 0)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module VERSION
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def major
|
6
|
+
0
|
7
|
+
end
|
8
|
+
|
9
|
+
def minor
|
10
|
+
0
|
11
|
+
end
|
12
|
+
|
13
|
+
def patch
|
14
|
+
1
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_a
|
18
|
+
[major, minor, patch]
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
to_a.join(".")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module Worker
|
3
|
+
include Logging
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def init_producer(que)
|
8
|
+
@producer = Thread.new do
|
9
|
+
Thread.current.name = "producer"
|
10
|
+
Thread.current[:running] = true
|
11
|
+
while Thread.current[:running]
|
12
|
+
que << :pdirty if event.pdirty
|
13
|
+
que << :mdirty if event.mdirty
|
14
|
+
que << :midi if event.midi
|
15
|
+
que << :ldirty if event.ldirty
|
16
|
+
sleep(@ratelimit)
|
17
|
+
end
|
18
|
+
logger.debug "closing #{Thread.current.name} thread"
|
19
|
+
que << Thread.current[:running]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def init_worker(que)
|
24
|
+
logger.info "Listening for #{event.get.join(", ")} events"
|
25
|
+
cache[:strip_level], cache[:bus_level] = _get_levels
|
26
|
+
cache[:strip_comp] = Array.new(kind.num_strip_levels, false)
|
27
|
+
cache[:bus_comp] = Array.new(kind.num_bus_levels, false)
|
28
|
+
Thread.new do
|
29
|
+
Thread.current.name = "worker"
|
30
|
+
while (event = que.pop)
|
31
|
+
fire :pdirty if event == :pdirty && pdirty?
|
32
|
+
fire :mdirty if event == :mdirty && mdirty?
|
33
|
+
fire :midi if event == :midi && get_midi_message
|
34
|
+
if event == :ldirty && ldirty?
|
35
|
+
cache[:strip_comp] = cache[:strip_level].zip(cache[:strip_buf]).map { |a, b| a != b }
|
36
|
+
cache[:bus_comp] = cache[:bus_level].zip(cache[:bus_buf]).map { |a, b| a != b }
|
37
|
+
cache[:strip_level] = cache[:strip_buf]
|
38
|
+
cache[:bus_level] = cache[:bus_buf]
|
39
|
+
fire :ldirty
|
40
|
+
end
|
41
|
+
end
|
42
|
+
logger.debug "closing #{Thread.current.name} thread"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
public
|
47
|
+
|
48
|
+
def running?
|
49
|
+
@producer&.alive?
|
50
|
+
end
|
51
|
+
|
52
|
+
def init_event_threads
|
53
|
+
que = Queue.new
|
54
|
+
init_worker(que) and init_producer(que)
|
55
|
+
end
|
56
|
+
|
57
|
+
def end_event_threads
|
58
|
+
if running?
|
59
|
+
@producer[:running] = false
|
60
|
+
@producer.join
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/voicemeeter.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "pathname"
|
3
|
+
require "win32/registry"
|
4
|
+
require "ffi"
|
5
|
+
require "date"
|
6
|
+
require "logger"
|
7
|
+
|
8
|
+
require_relative "voicemeeter/logger"
|
9
|
+
require_relative "voicemeeter/worker"
|
10
|
+
require_relative "voicemeeter/event"
|
11
|
+
require_relative "voicemeeter/util"
|
12
|
+
require_relative "voicemeeter/meta"
|
13
|
+
require_relative "voicemeeter/iremote"
|
14
|
+
require_relative "voicemeeter/mixins"
|
15
|
+
require_relative "voicemeeter/install"
|
16
|
+
|
17
|
+
require_relative "voicemeeter/base"
|
18
|
+
require_relative "voicemeeter/bus"
|
19
|
+
require_relative "voicemeeter/button"
|
20
|
+
require_relative "voicemeeter/cbindings"
|
21
|
+
require_relative "voicemeeter/command"
|
22
|
+
require_relative "voicemeeter/configs"
|
23
|
+
require_relative "voicemeeter/device"
|
24
|
+
require_relative "voicemeeter/fx"
|
25
|
+
require_relative "voicemeeter/kinds"
|
26
|
+
require_relative "voicemeeter/midi"
|
27
|
+
require_relative "voicemeeter/option"
|
28
|
+
require_relative "voicemeeter/patch"
|
29
|
+
require_relative "voicemeeter/recorder"
|
30
|
+
require_relative "voicemeeter/remote"
|
31
|
+
require_relative "voicemeeter/strip"
|
32
|
+
require_relative "voicemeeter/vban"
|
33
|
+
|
34
|
+
require_relative "voicemeeter/version"
|
35
|
+
|
36
|
+
module Voicemeeter
|
37
|
+
module Errors
|
38
|
+
# Base Voicemeeter error class
|
39
|
+
class VMError < StandardError; end
|
40
|
+
|
41
|
+
# Raised when errors occur during installation.
|
42
|
+
class VMInstallError < VMError; end
|
43
|
+
|
44
|
+
# Raised when the C-API returns error codes
|
45
|
+
class VMCAPIError < VMError
|
46
|
+
attr_reader :fn_name, :code
|
47
|
+
|
48
|
+
# create a new VMCAPIError with given C-API function name and error code
|
49
|
+
def initialize(fn_name, code)
|
50
|
+
@fn_name = fn_name
|
51
|
+
@code = code
|
52
|
+
super("#{fn_name} returned #{code}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|