voicemeeter_api_ruby 4.1.5 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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