voicemeeter_api_ruby 4.1.5 → 4.2.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.
@@ -0,0 +1,27 @@
1
+ require "win32/registry"
2
+ require "pathname"
3
+ require "voicemeeter/errors"
4
+
5
+ module Voicemeeter
6
+ module InstallationFunctions
7
+ private
8
+
9
+ def get_vmpath(os_bits)
10
+ vm_key = "VB:Voicemeeter {17359A74-1236-5467}"
11
+ reg_key =
12
+ "Software#{os_bits == 64 ? "\\WOW6432Node" : ""}\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
13
+ Win32::Registry::HKEY_LOCAL_MACHINE.open(reg_key + vm_key) do |reg|
14
+ value = reg["UninstallString"]
15
+
16
+ pn = Pathname.new(value)
17
+ return pn.dirname
18
+ end
19
+ raise InstallErrors.new("Could not get the Voicemeeter path")
20
+ end
21
+
22
+ def vm_dll=(value)
23
+ raise InstallErrors.new("Could not fetch the dll file") unless value.file?
24
+ @vm_dll = value
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ require "voicemeeter/meta"
2
+ require "voicemeeter/errors"
3
+
4
+ module Voicemeeter
5
+ class IRemote
6
+ "
7
+ Common interface between base class and higher classes.
8
+ "
9
+ include Meta_Functions
10
+
11
+ def initialize(remote, i = nil)
12
+ @remote = remote
13
+ @index = i
14
+ end
15
+
16
+ def getter(param, is_string = false)
17
+ @remote.get_parameter("#{self.identifier}.#{param}", is_string)
18
+ end
19
+
20
+ def setter(param, value)
21
+ @remote.set_parameter("#{self.identifier}.#{param}", value)
22
+ end
23
+
24
+ def identifier
25
+ raise "Called abstract method: identifier"
26
+ end
27
+
28
+ def set_multi(param_hash)
29
+ param_hash.each { |(key, val)| self.send("#{key}=", val) }
30
+ end
31
+
32
+ alias_method "apply", :set_multi
33
+ end
34
+ end
File without changes
@@ -1,4 +1,4 @@
1
- require_relative "errors"
1
+ require "voicemeeter/errors"
2
2
 
3
3
  module Conversions
4
4
  module_function
@@ -37,6 +37,7 @@ module Meta_Functions
37
37
  define_singleton_method("#{param}") do
38
38
  return self.getter("#{param}").to_i
39
39
  end
40
+
40
41
  define_singleton_method("#{param}=") do |value|
41
42
  self.setter("#{param}", value)
42
43
  end
@@ -46,6 +47,7 @@ module Meta_Functions
46
47
  def make_accessor_float(*params)
47
48
  params.each do |param|
48
49
  define_singleton_method("#{param}") { return self.getter("#{param}") }
50
+
49
51
  define_singleton_method("#{param}=") do |value|
50
52
  self.setter("#{param}", value)
51
53
  end
@@ -57,6 +59,7 @@ module Meta_Functions
57
59
  define_singleton_method("#{param}") do
58
60
  return self.getter("#{param}", true)
59
61
  end
62
+
60
63
  define_singleton_method("#{param}=") do |value|
61
64
  self.setter("#{param}", value)
62
65
  end
@@ -91,7 +94,6 @@ end
91
94
  module Channel_Meta_Functions
92
95
  private
93
96
 
94
- include Conversions
95
97
  include Meta_Functions
96
98
 
97
99
  def make_accessor_bool(*params)
@@ -113,28 +115,6 @@ module Channel_Meta_Functions
113
115
  end
114
116
  end
115
117
 
116
- def make_accessor_float(*params)
117
- params.each do |param|
118
- define_singleton_method("#{param}") { return self.getter("#{param}") }
119
-
120
- define_singleton_method("#{param}=") do |value|
121
- self.setter("#{param}", value)
122
- end
123
- end
124
- end
125
-
126
- def make_accessor_int(*params)
127
- params.each do |param|
128
- define_singleton_method("#{param}") do
129
- return self.getter("#{param}").to_i
130
- end
131
-
132
- define_singleton_method("#{param}=") do |value|
133
- self.setter("#{param}", value)
134
- end
135
- end
136
- end
137
-
138
118
  def make_reader_only(*params)
139
119
  params.each do |param|
140
120
  cmds = { device: "device.name", sr: "device.sr" }
@@ -172,7 +152,6 @@ end
172
152
  module Vban_Meta_Functions
173
153
  private
174
154
 
175
- include Conversions
176
155
  include Meta_Functions
177
156
 
178
157
  def make_reader_int(*params)
@@ -256,7 +235,6 @@ end
256
235
  module Commands_Meta_Functions
257
236
  private
258
237
 
259
- include Conversions
260
238
  include Meta_Functions
261
239
  def make_writer_bool(*params)
262
240
  params.each do |param|
@@ -0,0 +1,22 @@
1
+ require "voicemeeter/iremote"
2
+ require "voicemeeter/meta"
3
+
4
+ module Voicemeeter
5
+ class Recorder < IRemote
6
+ "
7
+ Concrete Recorder class
8
+ "
9
+
10
+ def initialize(remote)
11
+ super
12
+ self.make_action_prop :play, :stop, :record, :ff, :rew
13
+
14
+ num_A, num_B = remote.kind.layout[:bus].values
15
+ self.make_accessor_bool *make_channel_props(num_A, num_B)
16
+ end
17
+
18
+ def identifier
19
+ :recorder
20
+ end
21
+ end
22
+ end
@@ -1,7 +1,7 @@
1
- require_relative "cbindings"
2
- require_relative "kinds"
1
+ require "voicemeeter/cbindings"
2
+ require "voicemeeter/kinds"
3
3
 
4
- include CBindings
4
+ include Voicemeeter::CBindings
5
5
  include Kinds
6
6
 
7
7
  module RunVM
@@ -0,0 +1,137 @@
1
+ require "voicemeeter/iremote"
2
+
3
+ module Voicemeeter
4
+ class Strip < IRemote
5
+ "
6
+ Concrete Strip class
7
+ "
8
+ include Channel_Meta_Functions
9
+
10
+ attr_accessor :gainlayer, :levels
11
+
12
+ def self.make(remote, layout_strip)
13
+ "
14
+ Factory function for Strip classes.
15
+ "
16
+ p_in, v_in = layout_strip.values
17
+ (0...(p_in + v_in)).map do |i|
18
+ i < p_in ? PhysicalStrip.new(remote, i) : VirtualStrip.new(remote, i)
19
+ end
20
+ end
21
+
22
+ def initialize(remote, i)
23
+ super
24
+ self.make_accessor_bool :solo, :mute, :mono
25
+ self.make_accessor_float :gain
26
+ self.make_accessor_int :limit
27
+ self.make_accessor_string :label
28
+
29
+ num_A, num_B = remote.kind.layout[:bus].values
30
+ self.make_accessor_bool *make_channel_props(num_A, num_B)
31
+
32
+ @gainlayer = (0...8).map { |j| GainLayer.new(remote, i, j) }
33
+ @levels = StripLevels.new(remote, i)
34
+ end
35
+
36
+ def identifier
37
+ "strip[#{@index}]"
38
+ end
39
+
40
+ def fadeto(target, time)
41
+ self.setter("FadeTo", "(#{target}, #{time})")
42
+ sleep(@remote.delay)
43
+ end
44
+
45
+ def fadeby(change, time)
46
+ self.setter("FadeBy", "(#{change}, #{time})")
47
+ sleep(@remote.delay)
48
+ end
49
+ end
50
+
51
+ class PhysicalStrip < Strip
52
+ def initialize(remote, i)
53
+ super
54
+ self.make_accessor_float :comp, :gate, :audibility
55
+ self.make_reader_only :device, :sr
56
+ end
57
+ end
58
+
59
+ class VirtualStrip < Strip
60
+ def initialize(remote, i)
61
+ super
62
+ self.make_accessor_bool :mc
63
+ self.make_accessor_int :k
64
+ self.make_accessor_float :bass, :mid, :treble
65
+ end
66
+
67
+ def appgain(name, gain)
68
+ self.setter("AppGain", "(\"#{name}\", #{gain})")
69
+ end
70
+
71
+ def appmute(name, mute)
72
+ self.setter("AppMute", "(\"#{name}\", #{mute ? 1 : 0})")
73
+ end
74
+ end
75
+
76
+ class GainLayer < IRemote
77
+ def initialize(remote, i, j)
78
+ super(remote, i)
79
+ @j = j
80
+ end
81
+
82
+ def identifier
83
+ "strip[#{@index}]"
84
+ end
85
+
86
+ def gain
87
+ self.getter("gainlayer[#{@j}]")
88
+ end
89
+
90
+ def gain=(value)
91
+ self.setter("gainlayer[#{@j}]", value)
92
+ end
93
+ end
94
+
95
+ class StripLevels < IRemote
96
+ def initialize(remote, i)
97
+ super
98
+ if i < @remote.p_in
99
+ @init = i * 2
100
+ @offset = 2
101
+ else
102
+ @init = (@remote.p_in * 2) + ((i - @remote.p_in) * 8)
103
+ @offset = 8
104
+ end
105
+ end
106
+
107
+ def identifier
108
+ "strip[#{@index}]"
109
+ end
110
+
111
+ def get_level(mode)
112
+ if @remote.running
113
+ vals = @remote.cache["strip_level"][@init, @offset]
114
+ else
115
+ vals = (@init...@offset).map { |i| get_level(mode, i) }
116
+ end
117
+ vals.map { |x| x > 0 ? (20 * Math.log(x, 10)).round(1) : -200.0 }
118
+ end
119
+
120
+ def prefader
121
+ @remote.strip_mode = 0
122
+ get_level(0)
123
+ end
124
+
125
+ def postfader
126
+ @remote.strip_mode = 1
127
+ get_level(1)
128
+ end
129
+
130
+ def postmute
131
+ @remote.strip_mode = 2
132
+ get_level(2)
133
+ end
134
+
135
+ def isdirty? = @remote._strip_comp[@init, @offset].any?
136
+ end
137
+ end
@@ -0,0 +1,80 @@
1
+ require "voicemeeter/iremote"
2
+ require "voicemeeter/meta"
3
+ require "voicemeeter/errors"
4
+
5
+ module Voicemeeter
6
+ class VbanStream < IRemote
7
+ "
8
+ A class representing a VBAN stream
9
+ "
10
+ include Vban_Meta_Functions
11
+
12
+ def initialize(remote, i)
13
+ super
14
+ self.make_accessor_bool :on
15
+ self.make_accessor_string :name, :ip
16
+ self.make_accessor_int :quality, :route
17
+ end
18
+
19
+ def identifier
20
+ "vban.#{self.direction}stream[#{@index}]"
21
+ end
22
+
23
+ def direction
24
+ raise "Called abstract mehod: direction"
25
+ end
26
+ end
27
+
28
+ class VbanInstream < VbanStream
29
+ "
30
+ A subclass representing a VBAN Instream
31
+ "
32
+ def initialize(remote, i)
33
+ super
34
+ self.make_reader_int :sr, :channel, :bit
35
+ end
36
+
37
+ def direction
38
+ :in
39
+ end
40
+ end
41
+
42
+ class VbanOutstream < VbanStream
43
+ "
44
+ A subclass representing a VBAN Outstream
45
+ "
46
+ def initialize(remote, i)
47
+ super
48
+ self.make_accessor_int :sr, :channel, :bit
49
+ end
50
+
51
+ def direction
52
+ :out
53
+ end
54
+ end
55
+
56
+ class Vban
57
+ attr_accessor :instream, :outstream
58
+
59
+ def initialize(remote, vban_streams)
60
+ "
61
+ Initializes a Vban class
62
+
63
+ Creates an array for each in/out stream
64
+ "
65
+ vban_in, vban_out = vban_streams.values
66
+ self.instream = (0...vban_in).map { |i| VbanInstream.new(remote, i) }
67
+ self.outstream = (0...vban_out).map { |i| VbanOutstream.new(remote, i) }
68
+
69
+ @remote = remote
70
+ end
71
+
72
+ def enable
73
+ @remote.set_parameter("vban.enable", 1)
74
+ end
75
+
76
+ def disable
77
+ @remote.set_parameter("vban.enable", 0)
78
+ end
79
+ end
80
+ end
@@ -1,3 +1,3 @@
1
1
  module Voicemeeter_API_Ruby
2
- VERSION = "4.1.5"
2
+ VERSION = "4.2.0"
3
3
  end
data/lib/voicemeeter.rb CHANGED
@@ -1,11 +1,11 @@
1
- require_relative "base"
2
- require_relative "strip"
3
- require_relative "bus"
4
- require_relative "button"
5
- require_relative "vban"
6
- require_relative "command"
7
- require_relative "recorder"
8
- require_relative "device"
1
+ require "voicemeeter/base"
2
+ require "voicemeeter/strip"
3
+ require "voicemeeter/bus"
4
+ require "voicemeeter/button"
5
+ require "voicemeeter/vban"
6
+ require "voicemeeter/command"
7
+ require "voicemeeter/recorder"
8
+ require "voicemeeter/device"
9
9
 
10
10
  module Voicemeeter
11
11
  include RunVM
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: voicemeeter_api_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.5
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - onyx_online
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-22 00:00:00.000000000 Z
11
+ date: 2022-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -84,24 +84,24 @@ files:
84
84
  - CHANGELOG.md
85
85
  - LICENSE
86
86
  - README.md
87
- - lib/base.rb
88
- - lib/bus.rb
89
- - lib/button.rb
90
- - lib/cbindings.rb
91
- - lib/command.rb
92
- - lib/configs.rb
93
- - lib/device.rb
94
- - lib/errors.rb
95
- - lib/inst.rb
96
- - lib/iremote.rb
97
- - lib/kinds.rb
98
- - lib/meta.rb
99
- - lib/recorder.rb
100
- - lib/runvm.rb
101
- - lib/strip.rb
102
- - lib/vban.rb
103
- - lib/version.rb
104
87
  - lib/voicemeeter.rb
88
+ - lib/voicemeeter/base.rb
89
+ - lib/voicemeeter/bus.rb
90
+ - lib/voicemeeter/button.rb
91
+ - lib/voicemeeter/cbindings.rb
92
+ - lib/voicemeeter/command.rb
93
+ - lib/voicemeeter/configs.rb
94
+ - lib/voicemeeter/device.rb
95
+ - lib/voicemeeter/errors.rb
96
+ - lib/voicemeeter/inst.rb
97
+ - lib/voicemeeter/iremote.rb
98
+ - lib/voicemeeter/kinds.rb
99
+ - lib/voicemeeter/meta.rb
100
+ - lib/voicemeeter/recorder.rb
101
+ - lib/voicemeeter/runvm.rb
102
+ - lib/voicemeeter/strip.rb
103
+ - lib/voicemeeter/vban.rb
104
+ - lib/voicemeeter/version.rb
105
105
  homepage: https://rubygems.org/gems/voicemeeter_api_ruby
106
106
  licenses:
107
107
  - MIT
data/lib/base.rb DELETED
@@ -1,220 +0,0 @@
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