voicemeeter_api_ruby 4.1.2 → 4.1.5
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/README.md +7 -7
- data/lib/base.rb +220 -221
- data/lib/bus.rb +86 -78
- data/lib/button.rb +23 -23
- data/lib/cbindings.rb +115 -118
- data/lib/command.rb +36 -36
- data/lib/configs.rb +80 -81
- data/lib/device.rb +15 -15
- data/lib/errors.rb +30 -28
- data/lib/inst.rb +27 -29
- data/lib/iremote.rb +32 -30
- data/lib/kinds.rb +77 -77
- data/lib/meta.rb +275 -282
- data/lib/recorder.rb +20 -20
- data/lib/runvm.rb +29 -29
- data/lib/strip.rb +120 -116
- data/lib/vban.rb +78 -78
- data/lib/version.rb +3 -3
- data/lib/voicemeeter.rb +86 -86
- metadata +2 -3
- data/lib/mixin.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29df5251a1e4d779dd265a785112c0c8907b89f5f9a30a45a9e50985ed2400e7
|
4
|
+
data.tar.gz: c4a9acbbbe3330aca966d4470373b9ec9f9fe3bcefa0b1f6e60ed665b853c712
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9e8f17bd773dbbbb9980f5bb91283b0f97be75acff6f2bf0c2315721fdfc9916509ec86a0a28e6db3d548fadbb161c3b40da9cbd8639b4fc98719fe309d1e27
|
7
|
+
data.tar.gz: 12d256fb220ab60c3492d65855ed6cdf714af851f1a7dfcb2d6b3297e2c844a9776162ff600351c9f4baeb71a3a2e99492e19388a588f459301ed1aff4259d7d
|
data/README.md
CHANGED
@@ -339,11 +339,11 @@ vm.run { (0...vm.device.ins).each { |i| puts vm.device.input(i) } }
|
|
339
339
|
|
340
340
|
### Multiple parameters
|
341
341
|
|
342
|
-
- `
|
342
|
+
- `apply`
|
343
343
|
Set many strip/bus/macrobutton/vban parameters at once, for example:
|
344
344
|
|
345
345
|
```ruby
|
346
|
-
vm.
|
346
|
+
vm.apply(
|
347
347
|
{
|
348
348
|
strip_0: {
|
349
349
|
mute: true,
|
@@ -368,13 +368,13 @@ vm.set_multi(
|
|
368
368
|
Or for each class you may do:
|
369
369
|
|
370
370
|
```ruby
|
371
|
-
vm.strip[0].
|
372
|
-
vm.vban.outstream[0].
|
371
|
+
vm.strip[0].apply(mute: true, gain: 3.2, A1: true)
|
372
|
+
vm.vban.outstream[0].apply(on: true, name: 'streamname', bit: 24)
|
373
373
|
```
|
374
374
|
|
375
375
|
## Config Files
|
376
376
|
|
377
|
-
`vm.
|
377
|
+
`vm.apply_config(<configname>)`
|
378
378
|
|
379
379
|
You may load config files in TOML format.
|
380
380
|
Three example configs have been included with the package. Remember to save
|
@@ -383,10 +383,10 @@ current settings before loading a config. To set one you may do:
|
|
383
383
|
```ruby
|
384
384
|
require 'voicemeeter'
|
385
385
|
vm = Voicemeeter.remote('banana')
|
386
|
-
vm.run { vm.
|
386
|
+
vm.run { vm.apply_config('example') }
|
387
387
|
```
|
388
388
|
|
389
|
-
will load a config file at configs/banana/example.toml for Voicemeeter Banana.
|
389
|
+
will load a config file at mydir/configs/banana/example.toml for Voicemeeter Banana.
|
390
390
|
|
391
391
|
## `Voicemeeter Module`
|
392
392
|
|
data/lib/base.rb
CHANGED
@@ -1,221 +1,220 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
|
7
|
-
class Base
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
end
|
1
|
+
require "observer"
|
2
|
+
|
3
|
+
require_relative "runvm"
|
4
|
+
require_relative "configs"
|
5
|
+
require_relative "errors"
|
6
|
+
|
7
|
+
class Base
|
8
|
+
"
|
9
|
+
Base class responsible for wrapping the C Remote API
|
10
|
+
|
11
|
+
Mixin required modules
|
12
|
+
"
|
13
|
+
include Observable
|
14
|
+
include Configs
|
15
|
+
include RunVM
|
16
|
+
|
17
|
+
attr_accessor :strip, :bus, :button, :vban, :command, :recorder, :device
|
18
|
+
attr_accessor :strip_mode
|
19
|
+
|
20
|
+
attr_reader :kind, :p_in, :v_in, :p_out, :v_out, :retval, :cache
|
21
|
+
attr_reader :running, :_strip_comp, :_bus_comp, :delay
|
22
|
+
|
23
|
+
DELAY = 0.001
|
24
|
+
SYNC = false
|
25
|
+
RATELIMIT = 0.033
|
26
|
+
SIZE = 1
|
27
|
+
|
28
|
+
def initialize(kind, **kwargs)
|
29
|
+
@kind = kind
|
30
|
+
@p_in, @v_in = kind.layout[:strip].values
|
31
|
+
@p_out, @v_out = kind.layout[:bus].values
|
32
|
+
@cache = Hash.new
|
33
|
+
@sync = kwargs[:sync] || SYNC
|
34
|
+
@ratelimit = kwargs[:ratelimit] || RATELIMIT
|
35
|
+
@running = false
|
36
|
+
@strip_mode = 0
|
37
|
+
@delay = DELAY
|
38
|
+
end
|
39
|
+
|
40
|
+
def init_thread
|
41
|
+
@running = true
|
42
|
+
@cache["strip_level"], @cache["bus_level"] = _get_levels
|
43
|
+
Thread.new do
|
44
|
+
loop do
|
45
|
+
Thread.stop if !@running
|
46
|
+
if pdirty?
|
47
|
+
changed
|
48
|
+
notify_observers("pdirty")
|
49
|
+
end
|
50
|
+
if mdirty?
|
51
|
+
changed
|
52
|
+
notify_observers("mdirty")
|
53
|
+
end
|
54
|
+
if ldirty?
|
55
|
+
changed
|
56
|
+
@_strip_comp =
|
57
|
+
@cache["strip_level"].map.with_index do |x, i|
|
58
|
+
!(x == @strip_buf[i])
|
59
|
+
end
|
60
|
+
@_bus_comp =
|
61
|
+
@cache["bus_level"].map.with_index { |x, i| !(x == @bus_buf[i]) }
|
62
|
+
@cache["strip_level"] = @strip_buf
|
63
|
+
@cache["bus_level"] = @bus_buf
|
64
|
+
notify_observers("ldirty")
|
65
|
+
end
|
66
|
+
sleep(@ratelimit)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def end_thread
|
72
|
+
@running = false
|
73
|
+
end
|
74
|
+
|
75
|
+
def login
|
76
|
+
@@cdll.call(:login)
|
77
|
+
clear_polling
|
78
|
+
rescue CAPIErrors => error
|
79
|
+
case
|
80
|
+
when error.value == 1
|
81
|
+
self.start(@kind.name)
|
82
|
+
clear_polling
|
83
|
+
when error.value < 0
|
84
|
+
raise
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def logout
|
89
|
+
clear_polling
|
90
|
+
sleep(0.1)
|
91
|
+
@@cdll.call(:logout)
|
92
|
+
end
|
93
|
+
|
94
|
+
def type
|
95
|
+
c_type = FFI::MemoryPointer.new(:long, SIZE)
|
96
|
+
@@cdll.call(:vmtype, c_type)
|
97
|
+
types = { 1 => "basic", 2 => "banana", 3 => "potato" }
|
98
|
+
types[c_type.read_long]
|
99
|
+
end
|
100
|
+
|
101
|
+
def version
|
102
|
+
c_ver = FFI::MemoryPointer.new(:long, SIZE)
|
103
|
+
@@cdll.call(:vmversion, c_ver)
|
104
|
+
v1 = (c_ver.read_long & 0xFF000000) >> 24
|
105
|
+
v2 = (c_ver.read_long & 0x00FF0000) >> 16
|
106
|
+
v3 = (c_ver.read_long & 0x0000FF00) >> 8
|
107
|
+
v4 = c_ver.read_long & 0x000000FF
|
108
|
+
"#{v1}.#{v2}.#{v3}.#{v4}"
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_parameter(name, is_string = false)
|
112
|
+
self.polling("get_parameter", name: name) do
|
113
|
+
if is_string
|
114
|
+
c_get = FFI::MemoryPointer.new(:string, 512, true)
|
115
|
+
@@cdll.call(:get_parameter_string, name, c_get)
|
116
|
+
c_get.read_string
|
117
|
+
else
|
118
|
+
c_get = FFI::MemoryPointer.new(:float, SIZE)
|
119
|
+
@@cdll.call(:get_parameter_float, name, c_get)
|
120
|
+
c_get.read_float.round(1)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def set_parameter(name, value)
|
126
|
+
if value.is_a? String
|
127
|
+
@@cdll.call(:set_parameter_string, name, value)
|
128
|
+
else
|
129
|
+
@@cdll.call(:set_parameter_float, name, value.to_f)
|
130
|
+
end
|
131
|
+
@cache.store(name, value)
|
132
|
+
end
|
133
|
+
|
134
|
+
def get_buttonstatus(id, mode)
|
135
|
+
self.polling("get_buttonstatus", id: id, mode: mode) do
|
136
|
+
c_get = FFI::MemoryPointer.new(:float, SIZE)
|
137
|
+
@@cdll.call(:get_buttonstatus, id, c_get, mode)
|
138
|
+
c_get.read_float.to_i
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def set_buttonstatus(id, state, mode)
|
143
|
+
@@cdll.call(:set_buttonstatus, id, state, mode)
|
144
|
+
@cache.store("mb_#{id}_#{mode}", state)
|
145
|
+
end
|
146
|
+
|
147
|
+
def set_parameter_multi(param_hash)
|
148
|
+
param_hash.each do |(key, val)|
|
149
|
+
prop, m2, m3, *rem = key.to_s.split("_")
|
150
|
+
if m2.to_i.to_s == m2
|
151
|
+
m2 = m2.to_i
|
152
|
+
elsif m3.to_i.to_s == m3
|
153
|
+
m3 = m3.to_i
|
154
|
+
end
|
155
|
+
|
156
|
+
case prop
|
157
|
+
when "strip"
|
158
|
+
self.strip[m2].set_multi(val)
|
159
|
+
when "bus"
|
160
|
+
self.bus[m2].set_multi(val)
|
161
|
+
when "button", "mb"
|
162
|
+
self.button[m2].set_multi(val)
|
163
|
+
when "vban"
|
164
|
+
if %w[instream in].include? m2
|
165
|
+
self.vban.instream[m3].set_multi(val)
|
166
|
+
elsif %w[outstream out].include? m2
|
167
|
+
self.vban.outstream[m3].set_multi(val)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
sleep(DELAY)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def get_level(type, index)
|
175
|
+
c_get = FFI::MemoryPointer.new(:float, SIZE)
|
176
|
+
@@cdll.call(:get_level, type, index, c_get)
|
177
|
+
c_get.read_float
|
178
|
+
end
|
179
|
+
|
180
|
+
def _get_levels
|
181
|
+
s = (0...(2 * @p_in + 8 * @v_in)).map { |i| get_level(@strip_mode, i) }
|
182
|
+
b = (0...(8 * (@p_out + @v_out))).map { |i| get_level(3, i) }
|
183
|
+
[s, b]
|
184
|
+
end
|
185
|
+
|
186
|
+
def get_num_devices(direction)
|
187
|
+
unless %w[in out].include? direction
|
188
|
+
raise VMRemoteErrors.new("expected in or out")
|
189
|
+
end
|
190
|
+
if direction == "in"
|
191
|
+
val = @@cdll.call(:get_num_indevices)
|
192
|
+
else
|
193
|
+
val = @@cdll.call(:get_num_outdevices)
|
194
|
+
end
|
195
|
+
val[0]
|
196
|
+
end
|
197
|
+
|
198
|
+
def get_device_description(index, direction)
|
199
|
+
unless %w[in out].include? direction
|
200
|
+
raise VMRemoteErrors.new("expected in or out")
|
201
|
+
end
|
202
|
+
c_type = FFI::MemoryPointer.new(:long, SIZE)
|
203
|
+
c_name = FFI::MemoryPointer.new(:string, 256, true)
|
204
|
+
c_hwid = FFI::MemoryPointer.new(:string, 256, true)
|
205
|
+
if direction == "in"
|
206
|
+
@@cdll.call(:get_desc_indevices, index, c_type, c_name, c_hwid)
|
207
|
+
else
|
208
|
+
@@cdll.call(:get_desc_outdevices, index, c_type, c_name, c_hwid)
|
209
|
+
end
|
210
|
+
[c_name.read_string, c_type.read_long, c_hwid.read_string]
|
211
|
+
end
|
212
|
+
|
213
|
+
alias_method "set_multi", :set_parameter_multi
|
214
|
+
alias_method "apply", :set_parameter_multi
|
215
|
+
alias_method "get", :get_parameter
|
216
|
+
alias_method "set", :set_parameter
|
217
|
+
alias_method "pdirty", :pdirty?
|
218
|
+
alias_method "mdirty", :mdirty?
|
219
|
+
alias_method "ldirty", :ldirty?
|
220
|
+
end
|