voicemeeter_api_ruby 2.0.4 → 4.1.0

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.
data/lib/command.rb CHANGED
@@ -1,41 +1,36 @@
1
+ require_relative 'iremote'
1
2
  require_relative 'meta'
2
3
 
3
-
4
- class ICommand
4
+ class Command < IRemote
5
5
  include Commands_Meta_Functions
6
6
 
7
- attr_accessor :remote
8
-
9
7
  def initialize(remote)
10
- self.remote = remote
8
+ super
9
+ self.make_action_prop :show, :restart, :shutdown
10
+ self.make_writer_bool :showvbanchat, :lock
11
11
  end
12
12
 
13
- def setter(param, value)
14
- @remote.set_parameter("#{self.cmd}.#{param}", value)
13
+ def identifier
14
+ :command
15
15
  end
16
16
 
17
- def cmd
18
- return "command"
19
- end
20
- end
21
-
22
-
23
- class Command < ICommand
24
- def initialize(remote)
25
- super
26
- self.make_action_prop :show, :restart, :reset, :shutdown
27
- self.make_writer_bool :showvbanchat, :lock
17
+ def hide
18
+ self.setter('show', 0)
28
19
  end
29
20
 
30
21
  def load(value)
31
- raise VMRemoteErrors.new("Expected a string") unless value.is_a? String
32
- self.setter("load", value)
22
+ raise VMRemoteErrors.new('Expected a string') unless value.is_a? String
23
+ self.setter('load', value)
33
24
  sleep(0.2)
34
25
  end
35
26
 
36
27
  def save(value)
37
- raise VMRemoteErrors.new("Expected a string") unless value.is_a? String
38
- self.setter("save", value)
28
+ raise VMRemoteErrors.new('Expected a string') unless value.is_a? String
29
+ self.setter('save', value)
39
30
  sleep(0.2)
40
31
  end
32
+
33
+ def reset
34
+ @remote.set_config('reset')
35
+ end
41
36
  end
data/lib/configs.rb ADDED
@@ -0,0 +1,79 @@
1
+ require 'kinds'
2
+ require 'toml'
3
+
4
+ module Configs
5
+ private
6
+
7
+ @@configs = Hash.new
8
+
9
+ class TOMLStrBuilder
10
+ def initialize(kind)
11
+ @p_in, @v_in = kind[:layout][:strip].values
12
+ @p_out, @v_out = kind[:layout][:bus].values
13
+ @vs_params =
14
+ ['mute = false', 'mono = false', 'solo = false', 'gain = 0.0'] +
15
+ (1..@p_out).map { |i| "A#{i} = false" } +
16
+ (1..@v_out).map { |i| "B#{i} = false" }
17
+
18
+ @ps_params = @vs_params + ['comp = 0.0', 'gate = 0.0']
19
+ @bus_params = ['mono = false', 'eq = false', 'mute = false']
20
+ end
21
+
22
+ def build
23
+ '
24
+ Builds a TOML script for the parser
25
+ '
26
+ @ps = (0...@p_in).map { |i| ["[strip_#{i}]"] + @ps_params }
27
+ @ps.map! { |a| a.map { |s| s.gsub('B1 = false', 'B1 = true') } }
28
+ @vs =
29
+ (@p_in...(@p_in + @v_in)).map do |i|
30
+ ["[strip_#{i}]"] + @vs_params
31
+ end
32
+ @vs.map! { |a| a.map { |s| s.gsub('A1 = false', 'A1 = true') } }
33
+
34
+ @b =
35
+ (0...(@p_out + @v_out)).map { |i| ["[bus_#{i}]"] + @bus_params }
36
+
37
+ [@ps + @vs + @b].join("\n")
38
+ end
39
+ end
40
+
41
+ def parser(data)
42
+ TOML::Parser.new(data).parsed
43
+ end
44
+
45
+ def get_configs(kind_id)
46
+ file_pattern =
47
+ File.join(File.dirname(__dir__), 'configs', "#{kind_id}", '*.toml')
48
+
49
+ Dir
50
+ .glob(file_pattern)
51
+ .to_h do |toml_file|
52
+ filename = File.basename(toml_file, '.toml')
53
+ puts "loading config #{kind_id}/#{filename} into memory"
54
+ [filename, parser(File.read(toml_file))]
55
+ end
56
+ end
57
+
58
+ def loader
59
+ if @@configs.empty?
60
+ builder = TOMLStrBuilder.new(@kind)
61
+ puts 'loading config reset into memory'
62
+ @@configs['reset'] = parser(builder.build)
63
+ @@configs.merge!(get_configs(@kind.name.to_s))
64
+ end
65
+ end
66
+
67
+ public
68
+
69
+ def set_config(value)
70
+ loader
71
+ unless @@configs.key? value
72
+ raise VMRemoteErrors.new("No profile with name #{value} was loaded")
73
+ end
74
+
75
+ self.send('set_multi', @@configs[value])
76
+ puts "config #{@kind.name}/#{value} applied!"
77
+ sleep(@remote.DELAY)
78
+ end
79
+ end
data/lib/device.rb ADDED
@@ -0,0 +1,24 @@
1
+ require_relative 'iremote'
2
+ require_relative 'meta'
3
+
4
+ class Device
5
+ def initialize(remote)
6
+ @remote = remote
7
+ end
8
+
9
+ def getter(**kwargs)
10
+ return @remote.get_num_devices(kwargs[:direction]) if kwargs[:index].nil?
11
+
12
+ vals = @remote.get_device_description(kwargs[:index], kwargs[:direction])
13
+ types = { 1 => 'mme', 3 => 'wdm', 4 => 'ks', 5 => 'asio' }
14
+ { 'name': vals[0], 'type': types[vals[1]], 'id': vals[2] }
15
+ end
16
+
17
+ def ins() = getter(direction: 'in')
18
+
19
+ def outs() = getter(direction: 'out')
20
+
21
+ def input(i) = getter(index: i, direction: 'in')
22
+
23
+ def output(i) = getter(index: i, direction: 'out')
24
+ end
data/lib/errors.rb CHANGED
@@ -1,37 +1,39 @@
1
- module Errors
2
- class VMRemoteErrors < StandardError; end
3
-
4
- class InstallErrors < VMRemoteErrors; end
5
-
6
- class CAPIErrors < VMRemoteErrors
7
- attr_accessor :value, :func
8
-
9
- def initialize(value, func)
10
- self.value = value
11
- self.func = func
12
- end
13
-
14
- def message
15
- "When attempting to run function #{@func} the
16
- C API returned value #{@value}. See documentation for further info"
17
- end
18
- end
19
-
20
- class OutOfBoundsErrors < VMRemoteErrors
21
- attr_accessor :range
22
-
23
- def initialize(range)
24
- self.range = range
25
- end
26
-
27
- def message
28
- if @range.kind_of?(Range)
29
- "Value error, expected value in range (#{range.first}..#{range.last})"
30
- elsif @range.kind_of?(Array)
31
- "Value error, expected one of: #{@range}"
32
- else
33
- "Value error, expected #{@range}"
34
- end
35
- end
36
- end
37
- end
1
+ module Errors
2
+ class VMRemoteErrors < StandardError
3
+ end
4
+
5
+ class InstallErrors < VMRemoteErrors
6
+ end
7
+
8
+ class CAPIErrors < VMRemoteErrors
9
+ attr_accessor :value, :func
10
+
11
+ def initialize(value, func)
12
+ self.value = value
13
+ self.func = func
14
+ end
15
+
16
+ def message
17
+ "When attempting to run function #{@func} the
18
+ C API returned value #{@value}. See documentation for further info"
19
+ end
20
+ end
21
+
22
+ class OutOfBoundsErrors < VMRemoteErrors
23
+ attr_accessor :range
24
+
25
+ def initialize(range)
26
+ self.range = range
27
+ end
28
+
29
+ def message
30
+ if @range.kind_of?(Range)
31
+ "Value error, expected value in range (#{range.first}..#{range.last})"
32
+ elsif @range.kind_of?(Array)
33
+ "Value error, expected one of: #{@range}"
34
+ else
35
+ "Value error, expected #{@range}"
36
+ end
37
+ end
38
+ end
39
+ end
data/lib/inst.rb CHANGED
@@ -6,22 +6,13 @@ include Errors
6
6
 
7
7
  module InstallationFunctions
8
8
  private
9
- def get_arch
10
- key = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
11
- Win32::Registry::HKEY_LOCAL_MACHINE.open(key) do |reg|
12
- os_bits = reg["PROCESSOR_ARCHITECTURE"]
13
- if os_bits.include? 64.to_s
14
- return 64
15
- end
16
- return 32
17
- end
18
- end
19
9
 
20
10
  def get_vmpath(os_bits)
21
- vm_key = "VB:Voicemeeter {17359A74-1236-5467}"
22
- reg_key = "Software#{os_bits == 64 ? "\\WOW6432Node" : ""}\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
23
- Win32::Registry::HKEY_LOCAL_MACHINE.open(reg_key + vm_key) do |reg|
24
- value = reg["UninstallString"]
11
+ vm_key = 'VB:Voicemeeter {17359A74-1236-5467}'
12
+ reg_key =
13
+ "Software#{os_bits == 64 ? "\\WOW6432Node" : ''}\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
14
+ Win32::Registry::HKEY_LOCAL_MACHINE.open(reg_key + vm_key) do |reg|
15
+ value = reg['UninstallString']
25
16
 
26
17
  pn = Pathname.new(value)
27
18
  return pn.dirname
@@ -29,8 +20,10 @@ module InstallationFunctions
29
20
  raise InstallErrors.new('Could not get the Voicemeeter path')
30
21
  end
31
22
 
32
- def vmr_dll=(value)
33
- raise InstallErrors.new('Could not fetch the dll file') unless value.file?
34
- @vmr_dll = value
23
+ def vm_dll=(value)
24
+ unless value.file?
25
+ raise InstallErrors.new('Could not fetch the dll file')
26
+ end
27
+ @vm_dll = value
35
28
  end
36
29
  end
data/lib/iremote.rb ADDED
@@ -0,0 +1,30 @@
1
+ require_relative 'meta'
2
+ require_relative 'errors'
3
+
4
+ class IRemote
5
+ '
6
+ Common interface between base class and higher classes.
7
+ '
8
+ include Meta_Functions
9
+
10
+ def initialize(remote, i = nil)
11
+ @remote = remote
12
+ @index = i
13
+ end
14
+
15
+ def getter(param, is_string = false)
16
+ @remote.get_parameter("#{self.identifier}.#{param}", is_string)
17
+ end
18
+
19
+ def setter(param, value)
20
+ @remote.set_parameter("#{self.identifier}.#{param}", value)
21
+ end
22
+
23
+ def identifier
24
+ raise 'Called abstract method: identifier'
25
+ end
26
+
27
+ def set_multi(param_hash)
28
+ param_hash.each { |(key, val)| self.send("#{key}=", val) }
29
+ end
30
+ end
data/lib/kinds.rb ADDED
@@ -0,0 +1,77 @@
1
+ module Kinds
2
+ '
3
+ A Kind struct for each version of Voicemeeter
4
+ '
5
+ attr_reader :kind_map, :kinds_all
6
+
7
+ Kind = Struct.new(:name, :layout)
8
+ basic =
9
+ Kind.new(
10
+ 'basic',
11
+ {
12
+ strip: {
13
+ p_in: 2,
14
+ v_in: 1,
15
+ },
16
+ bus: {
17
+ p_out: 1,
18
+ v_out: 1,
19
+ },
20
+ vban: {
21
+ instream: 4,
22
+ outstream: 4,
23
+ },
24
+ mb: 80,
25
+ },
26
+ )
27
+
28
+ banana =
29
+ Kind.new(
30
+ 'banana',
31
+ {
32
+ strip: {
33
+ p_in: 3,
34
+ v_in: 2,
35
+ },
36
+ bus: {
37
+ p_out: 3,
38
+ v_out: 2,
39
+ },
40
+ vban: {
41
+ instream: 8,
42
+ outstream: 8,
43
+ },
44
+ mb: 80,
45
+ },
46
+ )
47
+
48
+ potato =
49
+ Kind.new(
50
+ 'potato',
51
+ {
52
+ strip: {
53
+ p_in: 5,
54
+ v_in: 3,
55
+ },
56
+ bus: {
57
+ p_out: 5,
58
+ v_out: 3,
59
+ },
60
+ vban: {
61
+ instream: 8,
62
+ outstream: 8,
63
+ },
64
+ mb: 80,
65
+ },
66
+ )
67
+
68
+ @kind_map = [basic, banana, potato].to_h { |kind| [kind.name, kind] }
69
+
70
+ def get_kind(kind_id)
71
+ @kind_map[kind_id]
72
+ end
73
+
74
+ @kinds_all = @kind_map.values
75
+
76
+ module_function :get_kind
77
+ end
data/lib/meta.rb CHANGED
@@ -1,20 +1,34 @@
1
1
  require_relative 'errors'
2
2
 
3
- class FalseClass; def to_i; 0 end end
4
- class TrueClass; def to_i; 1 end end
3
+ module Conversions
4
+ module_function
5
+
6
+ def Boolean(value)
7
+ case value
8
+ when true, 1
9
+ true
10
+ when false, nil, 0
11
+ false
12
+ else
13
+ raise ArgumentError,
14
+ "invalid value for Boolean(): \"#{value.inspect}\""
15
+ end
16
+ end
17
+ end
5
18
 
6
19
  module Meta_Functions
7
20
  private
21
+
22
+ include Conversions
23
+
8
24
  def make_accessor_bool(*params)
9
25
  params.each do |param|
10
26
  define_singleton_method("#{param}") do
11
27
  return !(self.getter("#{param}")).zero?
12
28
  end
13
29
 
14
- opts = [false, true, 0, 1]
15
30
  define_singleton_method("#{param}=") do |value|
16
- raise OutOfBoundsErrors.new(opts) unless opts.include? value
17
- self.setter("#{param}", value.to_i == 1 ? 1 : 0)
31
+ self.setter("#{param}", Boolean(value) ? 1 : 0)
18
32
  end
19
33
  end
20
34
  end
@@ -62,38 +76,44 @@ module Meta_Functions
62
76
 
63
77
  def make_writer_only(*params)
64
78
  params.each do |param|
65
- define_singleton_method("#{param}=") do |value=1|
79
+ define_singleton_method("#{param}=") do |value = 1|
66
80
  self.setter("#{param}", value)
67
81
  end
68
82
  end
69
83
  end
70
84
 
71
85
  def make_channel_props(num_A, num_B)
72
- (1..(num_A + num_B)).map do |i|
73
- i <= num_A ? "A#{i}" : "B#{i - num_A}"
86
+ (1..(num_A + num_B)).map { |i| i <= num_A ? "A#{i}" : "B#{i - num_A}" }
87
+ end
88
+
89
+ def make_action_prop(*params)
90
+ params.each do |param|
91
+ define_singleton_method("#{param}") { self.setter("#{param}", 1) }
74
92
  end
75
93
  end
76
94
  end
77
95
 
78
-
79
96
  module Channel_Meta_Functions
97
+ private
98
+
99
+ include Conversions
80
100
  include Meta_Functions
81
101
 
82
102
  def make_accessor_bool(*params)
83
103
  params.each do |param|
84
- cmds = {
85
- :eq => 'EQ.on',
86
- }
87
- if cmds[param] then val = cmds[param] else val = param end
104
+ cmds = { eq: 'EQ.on' }
105
+ if cmds.key? param
106
+ cmd = cmds[param]
107
+ else
108
+ cmd = param
109
+ end
88
110
 
89
111
  define_singleton_method("#{param}") do
90
- return !(self.getter("#{val}")).zero?
112
+ return !(self.getter("#{cmd}")).zero?
91
113
  end
92
114
 
93
- opts = [false, true, 0, 1]
94
115
  define_singleton_method("#{param}=") do |value|
95
- raise OutOfBoundsErrors.new(opts) unless opts.include? value
96
- self.setter("#{val}", value.to_i == 1 ? 1 : 0)
116
+ self.setter("#{cmd}", Boolean(value) ? 1 : 0)
97
117
  end
98
118
  end
99
119
  end
@@ -104,13 +124,7 @@ module Channel_Meta_Functions
104
124
  return self.getter("#{param}")
105
125
  end
106
126
 
107
- opts = {
108
- :gain => [-60,12],
109
- :comp => [0,10],
110
- :gate => [0,10],
111
- }
112
127
  define_singleton_method("#{param}=") do |value|
113
- raise OutOfBoundsErrors.new(opts[param]) unless value.between? *opts[param]
114
128
  self.setter("#{param}", value)
115
129
  end
116
130
  end
@@ -122,11 +136,7 @@ module Channel_Meta_Functions
122
136
  return self.getter("#{param}").to_i
123
137
  end
124
138
 
125
- opts = {
126
- :limit => (-40..12),
127
- }
128
139
  define_singleton_method("#{param}=") do |value|
129
- raise OutOfBoundsErrors.new(opts[param]) unless opts[param].member? value
130
140
  self.setter("#{param}", value)
131
141
  end
132
142
  end
@@ -134,26 +144,42 @@ module Channel_Meta_Functions
134
144
 
135
145
  def make_reader_only(*params)
136
146
  params.each do |param|
137
- cmds = {
138
- :device => 'device.name',
139
- :sr => 'device.sr',
140
- }
141
- if cmds[param] then val = cmds[param] else val = param end
147
+ cmds = { device: 'device.name', sr: 'device.sr' }
148
+ if cmds.key? param
149
+ cmd = cmds[param]
150
+ else
151
+ cmd = param
152
+ end
142
153
 
143
154
  define_singleton_method("#{param}") do
144
155
  case param
145
156
  when :device
146
- return self.getter("#{val}", true)
157
+ return self.getter("#{cmd}", true)
147
158
  when :sr
148
- return self.getter("#{val}", true).to_i
159
+ return self.getter("#{cmd}").to_i
149
160
  end
150
161
  end
151
162
  end
152
163
  end
153
- end
154
164
 
165
+ def make_bus_modes(*params)
166
+ params.each do |param|
167
+ define_singleton_method("#{param}") do
168
+ @remote.clear_polling
169
+ return !(self.getter("#{param}")).zero?
170
+ end
171
+
172
+ define_singleton_method("#{param}=") do |value|
173
+ self.setter("#{param}", Boolean(value) ? 1 : 0)
174
+ end
175
+ end
176
+ end
177
+ end
155
178
 
156
179
  module Vban_Meta_Functions
180
+ private
181
+
182
+ include Conversions
157
183
  include Meta_Functions
158
184
 
159
185
  def make_reader_int(*params)
@@ -181,16 +207,28 @@ module Vban_Meta_Functions
181
207
  end
182
208
 
183
209
  opts = {
184
- :sr => [11025, 16000, 22050, 24000, 32000, 44100, 48000,
185
- 64000, 88200, 96000],
186
- :channel => (1..8),
187
- :bit => [16,24],
188
- :quality => (0..4),
189
- :route => (0..8),
210
+ sr: [
211
+ 11_025,
212
+ 16_000,
213
+ 22_050,
214
+ 24_000,
215
+ 32_000,
216
+ 44_100,
217
+ 48_000,
218
+ 64_000,
219
+ 88_200,
220
+ 96_000,
221
+ ],
222
+ channel: (1..8),
223
+ bit: [16, 24],
224
+ quality: (0..4),
225
+ route: (0..8),
190
226
  }
191
227
 
192
228
  define_singleton_method("#{param}=") do |value|
193
- raise OutOfBoundsErrors.new(opts[param]) unless opts[param].member? value
229
+ unless opts[param].member? value
230
+ raise OutOfBoundsErrors.new(opts[param])
231
+ end
194
232
  case param
195
233
  when :bit
196
234
  self.setter("#{param}", value == 16 ? 1 : 2)
@@ -202,50 +240,42 @@ module Vban_Meta_Functions
202
240
  end
203
241
  end
204
242
 
205
-
206
243
  module MacroButton_Meta_Functions
244
+ private
245
+
246
+ include Conversions
247
+
207
248
  def make_accessor_macrobutton(*params)
208
249
  params.each do |param|
209
- mode = {
210
- :state => 1,
211
- :stateonly => 2,
212
- :trigger => 3,
213
- }
250
+ mode = { state: 1, stateonly: 2, trigger: 3 }
214
251
 
215
252
  define_singleton_method("#{param}") do
216
253
  return !(self.getter(mode[param])).zero?
217
254
  end
218
255
 
219
- opts = [false, true, 0, 1]
220
256
  define_singleton_method("#{param}=") do |value|
221
- raise OutOfBoundsErrors.new(opts[param]) unless opts.include? value
222
- self.setter(value.to_i == 1 ? 1 : 0, mode[param])
257
+ self.setter(Boolean(value) ? 1 : 0, mode[param])
223
258
  end
224
259
  end
225
260
  end
226
261
  end
227
262
 
228
263
  module Commands_Meta_Functions
229
- include Meta_Functions
230
- def make_action_prop(*params)
231
- params.each do |param|
232
- define_singleton_method("#{param}") do
233
- self.setter("#{param}", 1)
234
- end
235
- end
236
- end
264
+ private
237
265
 
266
+ include Conversions
267
+ include Meta_Functions
238
268
  def make_writer_bool(*params)
239
269
  params.each do |param|
240
- cmds = {
241
- :showvbanchat => 'DialogShow.VBANCHAT',
242
- }
243
- if cmds[param] then val = cmds[param] else val = param end
270
+ cmds = { showvbanchat: 'DialogShow.VBANCHAT' }
271
+ if cmds.key? param
272
+ cmd = cmds[param]
273
+ else
274
+ cmd = param
275
+ end
244
276
 
245
- opts = [false, true]
246
277
  define_singleton_method("#{param}=") do |value|
247
- raise OutOfBoundsErrors.new(opts) unless opts.include? value
248
- self.setter("#{param}", value.to_i == 1 ? 1 : 0)
278
+ self.setter("#{cmd}", Boolean(value) ? 1 : 0)
249
279
  end
250
280
  end
251
281
  end
data/lib/mixin.rb ADDED
@@ -0,0 +1,11 @@
1
+ module Fades
2
+ def fadeto(target, time)
3
+ self.setter('FadeTo', "(#{target}, #{time})")
4
+ sleep(@remote.DELAY)
5
+ end
6
+
7
+ def fadeby(change, time)
8
+ self.setter('FadeBy', "(#{change}, #{time})")
9
+ sleep(@remote.DELAY)
10
+ end
11
+ end