voicemeeter_api_ruby 4.1.0 → 4.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e855e458e3debb64c2fe076bcad06c73643f8750c60d9a719f1eb5bb95ab3886
4
- data.tar.gz: 68a4ff2917b5f62a7e1846d09b9dff380e7e5991f6403fabf55e350ef99f65be
3
+ metadata.gz: e99dfb41a7d8359e0e0edca1c7aa08b1b6bbd1dc62589bc9ecfce0d1c443ef5c
4
+ data.tar.gz: 63219e2967bb25192e0c3a0214c083d514b92d29a32ba9382a65fcdf798d3e36
5
5
  SHA512:
6
- metadata.gz: 8d9297aaf1dbc13b231f1aa0b3388f58b13ae5fcbfb630a4bb7bfdb4b6d29ea559ef3b58c7c2df2725d6dc7d16a0369549c2fa331caf128b3c784e63315cbcd0
7
- data.tar.gz: a430dccd4348bc9d04ec2e54f6579d66df12227ff25d7d38577e979e88e1135ff68537346d8a6be9b67cd90b131bb43f6d58e1a7a91280ac14728c800e7990a1
6
+ metadata.gz: fa9d9737e6d27bccde45f7ab7038d2e3d40b7b7ccf8589fcfaf1e4c17ea38f645cb6ccdaa287d0c34e5c4b6fa9457ccf0eec6f5a81016702e477ccb6a19ed592
7
+ data.tar.gz: c72689ee90ec97c188194aab515b23759f9c2b4c3659a2452e82ef5b2a5c71f1a64dbedc528fa1078e56772458baba59edf71f93f1b4a7f768638802adf8b952
data/README.md CHANGED
@@ -374,7 +374,7 @@ vm.vban.outstream[0].set_multi(on: true, name: 'streamname', bit: 24)
374
374
 
375
375
  ## Config Files
376
376
 
377
- `vm.set_config(<configname>)`
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.set_config('example') }
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,218 +1,219 @@
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
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
- end
38
-
39
- def init_thread
40
- @running = true
41
- @cache['strip_level'], @cache['bus_level'] = _get_levels
42
- Thread.new do
43
- loop do
44
- Thread.stop if !@running
45
- if pdirty?
46
- changed
47
- notify_observers('pdirty')
48
- elsif mdirty?
49
- changed
50
- notify_observers('mdirty')
51
- elsif ldirty?
52
- changed
53
- @_strip_comp =
54
- @cache['strip_level'].map.with_index do |x, i|
55
- !(x == @strip_buf[i])
56
- end
57
- @_bus_comp =
58
- @cache['bus_level'].map.with_index do |x, i|
59
- !(x == @bus_buf[i])
60
- end
61
- @cache['strip_level'] = @strip_buf
62
- @cache['bus_level'] = @bus_buf
63
- notify_observers('ldirty')
64
- end
65
- sleep(@ratelimit)
66
- end
67
- end
68
- end
69
-
70
- def end_thread
71
- @running = false
72
- end
73
-
74
- def login
75
- @@cdll.call(:login)
76
- clear_polling
77
- rescue CAPIErrors => error
78
- case
79
- when error.value == 1
80
- self.start(@kind.name)
81
- clear_polling
82
- when error.value < 0
83
- raise
84
- end
85
- end
86
-
87
- def logout
88
- clear_polling
89
- sleep(0.1)
90
- @@cdll.call(:logout)
91
- end
92
-
93
- def type
94
- c_type = FFI::MemoryPointer.new(:long, SIZE)
95
- @@cdll.call(:vmtype, c_type)
96
- types = { 1 => 'basic', 2 => 'banana', 3 => 'potato' }
97
- types[c_type.read_long]
98
- end
99
-
100
- def version
101
- c_ver = FFI::MemoryPointer.new(:long, SIZE)
102
- @@cdll.call(:vmversion, c_ver)
103
- v1 = (c_ver.read_long & 0xFF000000) >> 24
104
- v2 = (c_ver.read_long & 0x00FF0000) >> 16
105
- v3 = (c_ver.read_long & 0x0000FF00) >> 8
106
- v4 = c_ver.read_long & 0x000000FF
107
- "#{v1}.#{v2}.#{v3}.#{v4}"
108
- end
109
-
110
- def get_parameter(name, is_string = false)
111
- self.polling('get_parameter', name: name) do
112
- if is_string
113
- c_get = FFI::MemoryPointer.new(:string, 512, true)
114
- @@cdll.call(:get_parameter_string, name, c_get)
115
- c_get.read_string
116
- else
117
- c_get = FFI::MemoryPointer.new(:float, SIZE)
118
- @@cdll.call(:get_parameter_float, name, c_get)
119
- c_get.read_float.round(1)
120
- end
121
- end
122
- end
123
-
124
- def set_parameter(name, value)
125
- if value.is_a? String
126
- @@cdll.call(:set_parameter_string, name, value)
127
- else
128
- @@cdll.call(:set_parameter_float, name, value.to_f)
129
- end
130
- @cache.store(name, value)
131
- end
132
-
133
- def get_buttonstatus(id, mode)
134
- self.polling('get_buttonstatus', id: id, mode: mode) do
135
- c_get = FFI::MemoryPointer.new(:float, SIZE)
136
- @@cdll.call(:get_buttonstatus, id, c_get, mode)
137
- c_get.read_float.to_i
138
- end
139
- end
140
-
141
- def set_buttonstatus(id, state, mode)
142
- @@cdll.call(:set_buttonstatus, id, state, mode)
143
- @cache.store("mb_#{id}_#{mode}", state)
144
- end
145
-
146
- def set_parameter_multi(param_hash)
147
- param_hash.each do |(key, val)|
148
- prop, m2, m3, *rem = key.to_s.split('_')
149
- if m2.to_i.to_s == m2
150
- m2 = m2.to_i
151
- elsif m3.to_i.to_s == m3
152
- m3 = m3.to_i
153
- end
154
-
155
- case prop
156
- when 'strip'
157
- self.strip[m2].set_multi(val)
158
- when 'bus'
159
- self.bus[m2].set_multi(val)
160
- when 'button', 'mb'
161
- self.button[m2].set_multi(val)
162
- when 'vban'
163
- if %w[instream in].include? m2
164
- self.vban.instream[m3].set_multi(val)
165
- elsif %w[outstream out].include? m2
166
- self.vban.outstream[m3].set_multi(val)
167
- end
168
- end
169
- sleep(DELAY)
170
- end
171
- end
172
-
173
- def get_level(type, index)
174
- c_get = FFI::MemoryPointer.new(:float, SIZE)
175
- @@cdll.call(:get_level, type, index, c_get)
176
- c_get.read_float
177
- end
178
-
179
- def _get_levels
180
- s = (0...(2 * @p_in + 8 * @v_in)).map { |i| get_level(0, i) }
181
- b = (0...(8 * (@p_out + @v_out))).map { |i| get_level(3, i) }
182
- [s, b]
183
- end
184
-
185
- def get_num_devices(direction)
186
- unless %w[in out].include? direction
187
- raise VMRemoteErrors.new('expected in or out')
188
- end
189
- if direction == 'in'
190
- val = @@cdll.call(:get_num_indevices)
191
- else
192
- val = @@cdll.call(:get_num_outdevices)
193
- end
194
- val[0]
195
- end
196
-
197
- def get_device_description(index, direction)
198
- unless %w[in out].include? direction
199
- raise VMRemoteErrors.new('expected in or out')
200
- end
201
- c_type = FFI::MemoryPointer.new(:long, SIZE)
202
- c_name = FFI::MemoryPointer.new(:string, 256, true)
203
- c_hwid = FFI::MemoryPointer.new(:string, 256, true)
204
- if direction == 'in'
205
- @@cdll.call(:get_desc_indevices, index, c_type, c_name, c_hwid)
206
- else
207
- @@cdll.call(:get_desc_outdevices, index, c_type, c_name, c_hwid)
208
- end
209
- [c_name.read_string, c_type.read_long, c_hwid.read_string]
210
- end
211
-
212
- alias_method 'set_multi', :set_parameter_multi
213
- alias_method 'get', :get_parameter
214
- alias_method 'set', :set_parameter
215
- alias_method 'pdirty', :pdirty?
216
- alias_method 'mdirty', :mdirty?
217
- alias_method 'ldirty', :ldirty?
218
- 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
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 "get", :get_parameter
215
+ alias_method "set", :set_parameter
216
+ alias_method "pdirty", :pdirty?
217
+ alias_method "mdirty", :mdirty?
218
+ alias_method "ldirty", :ldirty?
219
+ end
data/lib/bus.rb CHANGED
@@ -1,97 +1,97 @@
1
- require_relative 'iremote'
2
- require_relative 'mixin'
1
+ require_relative "iremote"
2
+ require_relative "mixin"
3
3
 
4
4
  class Bus < IRemote
5
- '
6
- Concrete Bus class
7
- '
8
- include Channel_Meta_Functions
9
- include Fades
10
-
11
- attr_accessor :mode, :levels
12
-
13
- def self.make(remote, layout_bus)
14
- '
15
- Factory function for Bus classes.
16
- '
17
- p_out, v_out = layout_bus.values
18
- (0...(p_out + v_out)).map do |i|
19
- i < p_out ? PhysicalBus.new(remote, i) : VirtualBus.new(remote, i)
20
- end
5
+ "
6
+ Concrete Bus class
7
+ "
8
+ include Channel_Meta_Functions
9
+ include Fades
10
+
11
+ attr_accessor :mode, :levels
12
+
13
+ def self.make(remote, layout_bus)
14
+ "
15
+ Factory function for Bus classes.
16
+ "
17
+ p_out, v_out = layout_bus.values
18
+ (0...(p_out + v_out)).map do |i|
19
+ i < p_out ? PhysicalBus.new(remote, i) : VirtualBus.new(remote, i)
21
20
  end
21
+ end
22
22
 
23
- def initialize(remote, i)
24
- super
25
- self.make_accessor_bool :mute, :mono, :eq, :sel
26
- self.make_accessor_float :gain
27
- self.make_accessor_string :label
23
+ def initialize(remote, i)
24
+ super
25
+ self.make_accessor_bool :mute, :mono, :eq, :sel
26
+ self.make_accessor_float :gain
27
+ self.make_accessor_string :label
28
28
 
29
- @mode = BusModes.new(remote, i)
30
- @levels = BusLevels.new(remote, i)
31
- end
29
+ @mode = BusModes.new(remote, i)
30
+ @levels = BusLevels.new(remote, i)
31
+ end
32
32
 
33
- def identifier
34
- "bus[#{@index}]"
35
- end
33
+ def identifier
34
+ "bus[#{@index}]"
35
+ end
36
36
  end
37
37
 
38
38
  class PhysicalBus < Bus
39
- def initialize(remote, i)
40
- super
41
- self.make_reader_only :device, :sr
42
- end
39
+ def initialize(remote, i)
40
+ super
41
+ self.make_reader_only :device, :sr
42
+ end
43
43
  end
44
44
 
45
45
  class VirtualBus < Bus
46
46
  end
47
47
 
48
48
  class BusModes < IRemote
49
- include Channel_Meta_Functions
50
-
51
- def initialize(remote, i)
52
- super
53
- self.make_bus_modes :normal,
54
- :amix,
55
- :bmix,
56
- :repeat,
57
- :composite,
58
- :tvmix,
59
- :upmix21,
60
- :upmix41,
61
- :upmix61,
62
- :centeronly,
63
- :lfeonly,
64
- :rearonly
65
- end
66
-
67
- def identifier
68
- "bus[#{@index}].mode"
69
- end
49
+ include Channel_Meta_Functions
50
+
51
+ def initialize(remote, i)
52
+ super
53
+ self.make_bus_modes :normal,
54
+ :amix,
55
+ :bmix,
56
+ :repeat,
57
+ :composite,
58
+ :tvmix,
59
+ :upmix21,
60
+ :upmix41,
61
+ :upmix61,
62
+ :centeronly,
63
+ :lfeonly,
64
+ :rearonly
65
+ end
66
+
67
+ def identifier
68
+ "bus[#{@index}].mode"
69
+ end
70
70
  end
71
71
 
72
72
  class BusLevels < IRemote
73
- def initialize(remote, i)
74
- super
75
- @init = i * 8
76
- @offset = 8
73
+ def initialize(remote, i)
74
+ super
75
+ @init = i * 8
76
+ @offset = 8
77
+ end
78
+
79
+ def identifier
80
+ "bus[#{@index}]"
81
+ end
82
+
83
+ def getter(mode)
84
+ if @remote.running
85
+ vals = @remote.cache["bus_level"][@init, @offset]
86
+ else
87
+ vals = (@init...@offset).map { |i| @remote.get_level(mode, i) }
77
88
  end
89
+ vals.map { |x| x > 0 ? (20 * Math.log(x, 10)).round(1) : -200.0 }
90
+ end
78
91
 
79
- def identifier
80
- "bus[#{@index}]"
81
- end
82
-
83
- def getter(mode)
84
- if @remote.running
85
- vals = @remote.cache['bus_level'][@init, @offset]
86
- else
87
- vals = (@init...@offset).map { |i| @remote.get_level(mode, i) }
88
- end
89
- vals.map { |x| x > 0 ? (20 * Math.log(x, 10)).round(1) : -200.0 }
90
- end
91
-
92
- def all
93
- getter(3)
94
- end
92
+ def all
93
+ getter(3)
94
+ end
95
95
 
96
- def isdirty?() = @remote._bus_comp[@init, @offset].any?
96
+ def isdirty? = @remote._bus_comp[@init, @offset].any?
97
97
  end