voicemeeter_api_ruby 4.4.0 → 4.4.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 +4 -4
- data/README.md +3 -3
- data/lib/voicemeeter/base.rb +211 -255
- data/lib/voicemeeter/button.rb +25 -25
- data/lib/voicemeeter/command.rb +38 -38
- data/lib/voicemeeter/configs.rb +83 -83
- data/lib/voicemeeter/errors.rb +43 -43
- data/lib/voicemeeter/inst.rb +27 -27
- data/lib/voicemeeter/iremote.rb +34 -34
- data/lib/voicemeeter/kinds.rb +79 -79
- data/lib/voicemeeter/meta.rb +251 -251
- data/lib/voicemeeter/recorder.rb +20 -20
- data/lib/voicemeeter/remote.rb +77 -0
- data/lib/voicemeeter/runvm.rb +31 -31
- data/lib/voicemeeter/vban.rb +80 -80
- data/lib/voicemeeter/version.rb +25 -25
- data/lib/voicemeeter/worker.rb +43 -0
- data/lib/voicemeeter.rb +9 -86
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d5c6df9dba5f3f6bb249665cc26a6aeb8541c6e77712b4ff45f73452cfac8c4
|
4
|
+
data.tar.gz: a4c14273ab0cff0f004a68b4b9aa1816c087c775627bb2ab7872c8275b497859
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad89a1cd012ccc74a42e7f8886c17a531e72b5af8180bba87e28da1df191dee74ac2b24d6531c11c0493e554652779a334241823d31af1e73718a76fc1bdbb11
|
7
|
+
data.tar.gz: d7f1d28cc751ed6d40d770f66691e2d012e71d9a29e72d236d2a7800fca3b19f1bbb536fa066e9b0b392a109e27df76be8658dca0605d41769afbe82670eb1a9
|
data/README.md
CHANGED
data/lib/voicemeeter/base.rb
CHANGED
@@ -1,255 +1,211 @@
|
|
1
|
-
require "observer"
|
2
|
-
|
3
|
-
require_relative "
|
4
|
-
require_relative "
|
5
|
-
require_relative "
|
6
|
-
require_relative "
|
7
|
-
require_relative "
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
include
|
18
|
-
include
|
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
|
-
end
|
213
|
-
res[0]
|
214
|
-
end
|
215
|
-
|
216
|
-
def get_device_description(index, direction)
|
217
|
-
unless %w[in out].include? direction
|
218
|
-
raise VMRemoteErrors.new("expected in or out")
|
219
|
-
end
|
220
|
-
c_type = FFI::MemoryPointer.new(:long, SIZE)
|
221
|
-
c_name = FFI::MemoryPointer.new(:string, 256, true)
|
222
|
-
c_hwid = FFI::MemoryPointer.new(:string, 256, true)
|
223
|
-
if direction == "in"
|
224
|
-
@@cdll.call(:get_desc_indevices, index, c_type, c_name, c_hwid)
|
225
|
-
else
|
226
|
-
@@cdll.call(:get_desc_outdevices, index, c_type, c_name, c_hwid)
|
227
|
-
end
|
228
|
-
[c_name.read_string, c_type.read_long, c_hwid.read_string]
|
229
|
-
end
|
230
|
-
|
231
|
-
def get_midi_message
|
232
|
-
c_msg = FFI::MemoryPointer.new(:string, 1024, true)
|
233
|
-
res = @@cdll.call(:get_midi_message, c_msg, 1024)
|
234
|
-
if res[0] > 0
|
235
|
-
vals = c_msg.read_string.bytes
|
236
|
-
vals.each_slice(3) do |ch, key, vel|
|
237
|
-
@midi.channel = ch if @midi.channel.nil? || @midi.channel != ch
|
238
|
-
@midi.current = key.to_i
|
239
|
-
@midi.set(key.to_i, vel.to_i)
|
240
|
-
end
|
241
|
-
elsif res[0] == -1 || res[0] == -2
|
242
|
-
raise CAPIErrors.new("VBVMR_GetMidiMessage returned #{msg[0]}")
|
243
|
-
end
|
244
|
-
res[0] > 0
|
245
|
-
end
|
246
|
-
|
247
|
-
alias_method "set_multi", :set_parameter_multi
|
248
|
-
alias_method "apply", :set_parameter_multi
|
249
|
-
alias_method "get", :get_parameter
|
250
|
-
alias_method "set", :set_parameter
|
251
|
-
alias_method "pdirty", :pdirty?
|
252
|
-
alias_method "mdirty", :mdirty?
|
253
|
-
alias_method "ldirty", :ldirty?
|
254
|
-
end
|
255
|
-
end
|
1
|
+
require "observer"
|
2
|
+
|
3
|
+
require_relative "worker"
|
4
|
+
require_relative "runvm"
|
5
|
+
require_relative "configs"
|
6
|
+
require_relative "errors"
|
7
|
+
require_relative "event"
|
8
|
+
require_relative "midi"
|
9
|
+
|
10
|
+
module Voicemeeter
|
11
|
+
class Base
|
12
|
+
"
|
13
|
+
Base class responsible for wrapping the C Remote API
|
14
|
+
|
15
|
+
Mixin required modules
|
16
|
+
"
|
17
|
+
include Observable
|
18
|
+
include Configs
|
19
|
+
include RunVM
|
20
|
+
include Worker
|
21
|
+
|
22
|
+
attr_accessor :strip, :bus, :button, :vban, :command, :recorder, :device
|
23
|
+
attr_accessor :midi
|
24
|
+
attr_accessor :strip_mode, :event
|
25
|
+
|
26
|
+
attr_reader :kind, :p_in, :v_in, :p_out, :v_out, :retval, :cache
|
27
|
+
attr_reader :running, :_strip_comp, :_bus_comp, :delay
|
28
|
+
|
29
|
+
DELAY = 0.001
|
30
|
+
SYNC = false
|
31
|
+
RATELIMIT = 0.033
|
32
|
+
SIZE = 1
|
33
|
+
|
34
|
+
def initialize(kind, **kwargs)
|
35
|
+
@kind = kind
|
36
|
+
@sync = kwargs.delete(:sync) || SYNC
|
37
|
+
@ratelimit = kwargs.delete(:ratelimit) || RATELIMIT
|
38
|
+
@p_in, @v_in = kind.layout[:strip].values
|
39
|
+
@p_out, @v_out = kind.layout[:bus].values
|
40
|
+
@running = false
|
41
|
+
@strip_mode = 0
|
42
|
+
@delay = DELAY
|
43
|
+
@cache = Hash.new
|
44
|
+
@midi = Midi.new
|
45
|
+
@event = Event.new(**kwargs)
|
46
|
+
end
|
47
|
+
|
48
|
+
def login
|
49
|
+
@@cdll.call(:login)
|
50
|
+
clear_polling
|
51
|
+
rescue CAPIErrors => error
|
52
|
+
case
|
53
|
+
when error.value == 1
|
54
|
+
self.start(@kind.name)
|
55
|
+
clear_polling
|
56
|
+
when error.value < 0
|
57
|
+
raise
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def logout
|
62
|
+
clear_polling
|
63
|
+
sleep(0.1)
|
64
|
+
@@cdll.call(:logout)
|
65
|
+
end
|
66
|
+
|
67
|
+
def type
|
68
|
+
c_type = FFI::MemoryPointer.new(:long, SIZE)
|
69
|
+
@@cdll.call(:vmtype, c_type)
|
70
|
+
types = { 1 => "basic", 2 => "banana", 3 => "potato" }
|
71
|
+
types[c_type.read_long]
|
72
|
+
end
|
73
|
+
|
74
|
+
def version
|
75
|
+
c_ver = FFI::MemoryPointer.new(:long, SIZE)
|
76
|
+
@@cdll.call(:vmversion, c_ver)
|
77
|
+
v1 = (c_ver.read_long & 0xFF000000) >> 24
|
78
|
+
v2 = (c_ver.read_long & 0x00FF0000) >> 16
|
79
|
+
v3 = (c_ver.read_long & 0x0000FF00) >> 8
|
80
|
+
v4 = c_ver.read_long & 0x000000FF
|
81
|
+
"#{v1}.#{v2}.#{v3}.#{v4}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def get_parameter(name, is_string = false)
|
85
|
+
self.polling("get_parameter", name: name) do
|
86
|
+
if is_string
|
87
|
+
c_get = FFI::MemoryPointer.new(:string, 512, true)
|
88
|
+
@@cdll.call(:get_parameter_string, name, c_get)
|
89
|
+
c_get.read_string
|
90
|
+
else
|
91
|
+
c_get = FFI::MemoryPointer.new(:float, SIZE)
|
92
|
+
@@cdll.call(:get_parameter_float, name, c_get)
|
93
|
+
c_get.read_float.round(1)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def set_parameter(name, value)
|
99
|
+
if value.is_a? String
|
100
|
+
@@cdll.call(:set_parameter_string, name, value)
|
101
|
+
else
|
102
|
+
@@cdll.call(:set_parameter_float, name, value.to_f)
|
103
|
+
end
|
104
|
+
@cache.store(name, value)
|
105
|
+
end
|
106
|
+
|
107
|
+
def get_buttonstatus(id, mode)
|
108
|
+
self.polling("get_buttonstatus", id: id, mode: mode) do
|
109
|
+
c_get = FFI::MemoryPointer.new(:float, SIZE)
|
110
|
+
@@cdll.call(:get_buttonstatus, id, c_get, mode)
|
111
|
+
c_get.read_float.to_i
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def set_buttonstatus(id, state, mode)
|
116
|
+
@@cdll.call(:set_buttonstatus, id, state, mode)
|
117
|
+
@cache.store("mb_#{id}_#{mode}", state)
|
118
|
+
end
|
119
|
+
|
120
|
+
def set_parameter_multi(param_hash)
|
121
|
+
param_hash.each do |(key, val)|
|
122
|
+
prop, m2, m3, *rem = key.to_s.split("_")
|
123
|
+
if m2.to_i.to_s == m2
|
124
|
+
m2 = m2.to_i
|
125
|
+
elsif m3.to_i.to_s == m3
|
126
|
+
m3 = m3.to_i
|
127
|
+
end
|
128
|
+
|
129
|
+
case prop
|
130
|
+
when "strip"
|
131
|
+
self.strip[m2].set_multi(val)
|
132
|
+
when "bus"
|
133
|
+
self.bus[m2].set_multi(val)
|
134
|
+
when "button", "mb"
|
135
|
+
self.button[m2].set_multi(val)
|
136
|
+
when "vban"
|
137
|
+
if %w[instream in].include? m2
|
138
|
+
self.vban.instream[m3].set_multi(val)
|
139
|
+
elsif %w[outstream out].include? m2
|
140
|
+
self.vban.outstream[m3].set_multi(val)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
sleep(DELAY)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def get_level(type, index)
|
148
|
+
c_get = FFI::MemoryPointer.new(:float, SIZE)
|
149
|
+
@@cdll.call(:get_level, type, index, c_get)
|
150
|
+
c_get.read_float
|
151
|
+
end
|
152
|
+
|
153
|
+
def _get_levels
|
154
|
+
[
|
155
|
+
(0...(2 * @p_in + 8 * @v_in)).map { |i| get_level(@strip_mode, i) },
|
156
|
+
(0...(8 * (@p_out + @v_out))).map { |i| get_level(3, i) }
|
157
|
+
]
|
158
|
+
end
|
159
|
+
|
160
|
+
def get_num_devices(direction)
|
161
|
+
unless %w[in out].include? direction
|
162
|
+
raise VMRemoteErrors.new("expected in or out")
|
163
|
+
end
|
164
|
+
if direction == "in"
|
165
|
+
res = @@cdll.call(:get_num_indevices)
|
166
|
+
else
|
167
|
+
res = @@cdll.call(:get_num_outdevices)
|
168
|
+
end
|
169
|
+
res[0]
|
170
|
+
end
|
171
|
+
|
172
|
+
def get_device_description(index, direction)
|
173
|
+
unless %w[in out].include? direction
|
174
|
+
raise VMRemoteErrors.new("expected in or out")
|
175
|
+
end
|
176
|
+
c_type = FFI::MemoryPointer.new(:long, SIZE)
|
177
|
+
c_name = FFI::MemoryPointer.new(:string, 256, true)
|
178
|
+
c_hwid = FFI::MemoryPointer.new(:string, 256, true)
|
179
|
+
if direction == "in"
|
180
|
+
@@cdll.call(:get_desc_indevices, index, c_type, c_name, c_hwid)
|
181
|
+
else
|
182
|
+
@@cdll.call(:get_desc_outdevices, index, c_type, c_name, c_hwid)
|
183
|
+
end
|
184
|
+
[c_name.read_string, c_type.read_long, c_hwid.read_string]
|
185
|
+
end
|
186
|
+
|
187
|
+
def get_midi_message
|
188
|
+
c_msg = FFI::MemoryPointer.new(:string, 1024, true)
|
189
|
+
res = @@cdll.call(:get_midi_message, c_msg, 1024)
|
190
|
+
if res[0] > 0
|
191
|
+
vals = c_msg.read_string.bytes
|
192
|
+
vals.each_slice(3) do |ch, key, vel|
|
193
|
+
@midi.channel = ch if @midi.channel.nil? || @midi.channel != ch
|
194
|
+
@midi.current = key.to_i
|
195
|
+
@midi.set(key.to_i, vel.to_i)
|
196
|
+
end
|
197
|
+
elsif res[0] == -1 || res[0] == -2
|
198
|
+
raise CAPIErrors.new("VBVMR_GetMidiMessage returned #{msg[0]}")
|
199
|
+
end
|
200
|
+
res[0] > 0
|
201
|
+
end
|
202
|
+
|
203
|
+
alias_method "set_multi", :set_parameter_multi
|
204
|
+
alias_method "apply", :set_parameter_multi
|
205
|
+
alias_method "get", :get_parameter
|
206
|
+
alias_method "set", :set_parameter
|
207
|
+
alias_method "pdirty", :pdirty?
|
208
|
+
alias_method "mdirty", :mdirty?
|
209
|
+
alias_method "ldirty", :ldirty?
|
210
|
+
end
|
211
|
+
end
|
data/lib/voicemeeter/button.rb
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
-
require_relative "iremote"
|
2
|
-
require_relative "meta"
|
3
|
-
|
4
|
-
module Voicemeeter
|
5
|
-
class MacroButton < IRemote
|
6
|
-
include MacroButton_Meta_Functions
|
7
|
-
|
8
|
-
def self.make(remote, num_buttons)
|
9
|
-
(0...num_buttons).map { |i| MacroButton.new(remote, i) }
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize(remote, i)
|
13
|
-
super
|
14
|
-
self.make_accessor_macrobutton :state, :stateonly, :trigger
|
15
|
-
end
|
16
|
-
|
17
|
-
def getter(mode)
|
18
|
-
@remote.get_buttonstatus(@index, mode)
|
19
|
-
end
|
20
|
-
|
21
|
-
def setter(set, mode)
|
22
|
-
@remote.set_buttonstatus(@index, set, mode)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
1
|
+
require_relative "iremote"
|
2
|
+
require_relative "meta"
|
3
|
+
|
4
|
+
module Voicemeeter
|
5
|
+
class MacroButton < IRemote
|
6
|
+
include MacroButton_Meta_Functions
|
7
|
+
|
8
|
+
def self.make(remote, num_buttons)
|
9
|
+
(0...num_buttons).map { |i| MacroButton.new(remote, i) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(remote, i)
|
13
|
+
super
|
14
|
+
self.make_accessor_macrobutton :state, :stateonly, :trigger
|
15
|
+
end
|
16
|
+
|
17
|
+
def getter(mode)
|
18
|
+
@remote.get_buttonstatus(@index, mode)
|
19
|
+
end
|
20
|
+
|
21
|
+
def setter(set, mode)
|
22
|
+
@remote.set_buttonstatus(@index, set, mode)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/voicemeeter/command.rb
CHANGED
@@ -1,38 +1,38 @@
|
|
1
|
-
require_relative "iremote"
|
2
|
-
require_relative "meta"
|
3
|
-
|
4
|
-
module Voicemeeter
|
5
|
-
class Command < IRemote
|
6
|
-
include Commands_Meta_Functions
|
7
|
-
|
8
|
-
def initialize(remote)
|
9
|
-
super
|
10
|
-
self.make_action_prop :show, :restart, :shutdown
|
11
|
-
self.make_writer_bool :showvbanchat, :lock
|
12
|
-
end
|
13
|
-
|
14
|
-
def identifier
|
15
|
-
:command
|
16
|
-
end
|
17
|
-
|
18
|
-
def hide
|
19
|
-
self.setter("show", 0)
|
20
|
-
end
|
21
|
-
|
22
|
-
def load(value)
|
23
|
-
raise VMRemoteErrors.new("Expected a string") unless value.is_a? String
|
24
|
-
self.setter("load", value)
|
25
|
-
sleep(0.2)
|
26
|
-
end
|
27
|
-
|
28
|
-
def save(value)
|
29
|
-
raise VMRemoteErrors.new("Expected a string") unless value.is_a? String
|
30
|
-
self.setter("save", value)
|
31
|
-
sleep(0.2)
|
32
|
-
end
|
33
|
-
|
34
|
-
def reset
|
35
|
-
@remote.set_config("reset")
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
1
|
+
require_relative "iremote"
|
2
|
+
require_relative "meta"
|
3
|
+
|
4
|
+
module Voicemeeter
|
5
|
+
class Command < IRemote
|
6
|
+
include Commands_Meta_Functions
|
7
|
+
|
8
|
+
def initialize(remote)
|
9
|
+
super
|
10
|
+
self.make_action_prop :show, :restart, :shutdown
|
11
|
+
self.make_writer_bool :showvbanchat, :lock
|
12
|
+
end
|
13
|
+
|
14
|
+
def identifier
|
15
|
+
:command
|
16
|
+
end
|
17
|
+
|
18
|
+
def hide
|
19
|
+
self.setter("show", 0)
|
20
|
+
end
|
21
|
+
|
22
|
+
def load(value)
|
23
|
+
raise VMRemoteErrors.new("Expected a string") unless value.is_a? String
|
24
|
+
self.setter("load", value)
|
25
|
+
sleep(0.2)
|
26
|
+
end
|
27
|
+
|
28
|
+
def save(value)
|
29
|
+
raise VMRemoteErrors.new("Expected a string") unless value.is_a? String
|
30
|
+
self.setter("save", value)
|
31
|
+
sleep(0.2)
|
32
|
+
end
|
33
|
+
|
34
|
+
def reset
|
35
|
+
@remote.set_config("reset")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|