voicemeeter_api_ruby 4.0.0 → 4.1.2

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: e1665d58c08963437a1f97aea620c0d92d660135c653791e136a8e16b468430e
4
- data.tar.gz: 4c9b65a8bc057ecde1206007c48321ea90205828e7f5618279c283e621a35632
3
+ metadata.gz: 3cd92424de9feeec41ef5367eae28c9dfe4c5db4c62f3944e14e9fd4c632390d
4
+ data.tar.gz: e9dc4356b8b2fcb54337a6eea85c62e73f3c9259be339abd25bba00a805b42c3
5
5
  SHA512:
6
- metadata.gz: 49412d436f0a24d23f68d06757f6b4c6f652ad1c3489f83483d98b1128f26e7d4c22db192248361ce223e57ee8c3cdf1ad4e3e513b3d6055e34fea8b0c5916ef
7
- data.tar.gz: 7a95182d33363a4301a00c17329b0b782b084d9558d6fa348207508aec7d498a71644b5444677405d7e34282e5fd18fd9d825ecd9f30800b09c7e5aa15cd9669
6
+ metadata.gz: 2f77f65c9099f66c1a1938c8b40658b3fb1e8ab00b1914819b4d6e99a21bd87ee94ae20043bd52e381e314864b272d65ba03773550dc25765b10caa3490f6661
7
+ data.tar.gz: 345b8c4b80b8fe8e2bfe62b729eba3c2067f550017c3d4de15425a6368384fdb698d2bd4d01f04324ef3d33f3c5e3c8450ea97c880114d8fddb79c3af0a2bbce
data/CHANGELOG.md CHANGED
@@ -9,14 +9,45 @@ Before any major/minor/patch is released all unit tests will be run to verify th
9
9
 
10
10
  ## [Unreleased] - These changes have not been added to RubyGems yet
11
11
 
12
- - [x] type, version added to base class
13
- - [x] device class implemented
14
- - [x] common interface iremote defined
15
- - [x] configs reworked. configs are now loaded lazily.
16
- - [x] TOMLStrBuilder added to config, builds a default reset config
17
- - [x] command.reset now applies reset config from toml parser.
18
- - [x] profiles dir renamed to configs
19
- - [x] major version bump
12
+ - [ ] add xy parameters to strip/bus
13
+
14
+ ## [4.1.0] - 2022-07-19
15
+
16
+ ### Added
17
+
18
+ - Conversion module in meta
19
+ - strip/bus levels implemented, ldirty added to notifications.
20
+
21
+ ### Changed
22
+
23
+ - 1, 0 switched for true false in example configs
24
+ - observer example updated.
25
+ - minor version bump
26
+
27
+ ### Removed
28
+
29
+ - Boolean class monkey patch
30
+ - type checks
31
+
32
+ ## [4.0.0] - 2022-06-27
33
+
34
+ ### Added
35
+
36
+ - type, version added to base class
37
+ - device class implemented
38
+ - TOMLStrBuilder added to config, builds a default reset config
39
+ - support for observers to subscribe to updates
40
+ - observer example added
41
+ - device, sr, sel added to bus
42
+ - audibility, bass, mid, treble added to strip
43
+
44
+ ### Changed
45
+
46
+ - common interface iremote defined
47
+ - configs reworked. configs are now loaded lazily.
48
+ - command.reset now applies reset config from toml parser.
49
+ - profiles dir renamed to configs
50
+ - major version bump due to non-backwards compatible changes
20
51
 
21
52
  ## [3.0.0] - 2022-05-03
22
53
 
data/README.md CHANGED
@@ -23,21 +23,17 @@ For an outline of past/future changes refer to: [CHANGELOG](CHANGELOG.md)
23
23
 
24
24
  ## Installation
25
25
 
26
- ### Gem
27
-
28
- Install voicemeeter_api_ruby gem from your console
29
-
30
- `gem 'voicemeeter_api_ruby'`
31
-
32
26
  ### Bundler
33
27
 
34
28
  Put this in your Gemfile:
35
29
 
36
30
  `gem 'voicemeeter_api_ruby'`
37
31
 
38
- or use bundlers built in git functionality:
32
+ ### Gem
33
+
34
+ Install voicemeeter_api_ruby gem from your console
39
35
 
40
- `gem "voicemeeter_api_ruby", :git => "git://github.com/onyx-and-iris/voicemeeter-api-ruby"`
36
+ `gem install 'voicemeeter_api_ruby'`
41
37
 
42
38
  ## `Use`
43
39
 
@@ -110,7 +106,7 @@ vm.strip[3].gain = 3.7
110
106
  puts vm.strip[0].label
111
107
  ```
112
108
 
113
- The following methods are Available.
109
+ The following methods are available.
114
110
 
115
111
  - `appgain(name, value)`: string, float, from 0.0 to 1.0
116
112
 
@@ -123,8 +119,8 @@ Set mute state as value for the app matching name.
123
119
  example:
124
120
 
125
121
  ```ruby
126
- vm.strip[5].appmute('Spotify', true)
127
122
  vm.strip[5].appgain('Spotify', 0.5)
123
+ vm.strip[5].appmute('Spotify', true)
128
124
  ```
129
125
 
130
126
  ##### Gainlayers
@@ -139,6 +135,22 @@ vm.strip[3].gainlayer[3].gain = 3.7
139
135
 
140
136
  Gainlayers are defined for potato version only.
141
137
 
138
+ ##### Levels
139
+
140
+ The following properties are available.
141
+
142
+ - `prefader`
143
+ - `postfader`
144
+ - `postmute`
145
+
146
+ example:
147
+
148
+ ```ruby
149
+ puts vm.strip[3].levels.prefader
150
+ ```
151
+
152
+ Level properties will return -200.0 if no audio detected.
153
+
142
154
  ### Bus
143
155
 
144
156
  The following properties are available.
@@ -182,6 +194,20 @@ example:
182
194
  vm.bus[4].mode.amix = true
183
195
  ```
184
196
 
197
+ ##### Levels
198
+
199
+ The following properties are available.
200
+
201
+ - `all`
202
+
203
+ example:
204
+
205
+ ```ruby
206
+ puts vm.bus[0].levels.all
207
+ ```
208
+
209
+ `levels.all` will return -200.0 if no audio detected.
210
+
185
211
  ### Strip | Bus
186
212
 
187
213
  The following methods are Available
@@ -357,7 +383,7 @@ current settings before loading a config. To set one you may do:
357
383
  ```ruby
358
384
  require 'voicemeeter'
359
385
  vm = Voicemeeter.remote('banana')
360
- vm.run { vm.set_profile('example') }
386
+ vm.run { vm.set_config('example') }
361
387
  ```
362
388
 
363
389
  will load a config file at configs/banana/example.toml for Voicemeeter Banana.
data/lib/base.rb CHANGED
@@ -1,209 +1,221 @@
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
-
19
- attr_reader :kind, :retval, :cache, :delay
20
-
21
- DELAY = 0.001
22
- SYNC = false
23
- RATELIMIT = 0.033
24
- SIZE = 1
25
-
26
- def initialize(kind, **kwargs)
27
- @kind = kind
28
- @p_in, @v_in = kind.layout[:strip].values
29
- @p_out, @v_out = kind.layout[:bus].values
30
- @cache = Hash.new
31
- @sync = kwargs[:sync] || SYNC
32
- @ratelimit = kwargs[:ratelimit] || RATELIMIT
33
- @delay = DELAY
34
- @running = true
35
- end
36
-
37
- def init_thread
38
- Thread.new do
39
- loop do
40
- Thread.stop if !@running
41
- if pdirty?
42
- changed
43
- notify_observers('pdirty')
44
- elsif mdirty?
45
- changed
46
- notify_observers('mdirty')
47
- end
48
- sleep(@ratelimit)
49
- end
50
- end
51
- end
52
-
53
- def end_thread
54
- @running = false
55
- end
56
-
57
- def login
58
- @@cdll.call(:login)
59
- clear_polling
60
- rescue CAPIErrors => error
61
- case
62
- when error.value == 1
63
- self.start(@kind.name)
64
- clear_polling
65
- when error.value < 0
66
- raise
67
- end
68
- end
69
-
70
- def logout
71
- clear_polling
72
- sleep(0.1)
73
- @@cdll.call(:logout)
74
- end
75
-
76
- def type
77
- c_type = FFI::MemoryPointer.new(:long, SIZE)
78
- @@cdll.call(:vmtype, c_type)
79
- types = { 1 => 'basic', 2 => 'banana', 3 => 'potato' }
80
- types[c_type.read_long]
81
- end
82
-
83
- def version
84
- c_ver = FFI::MemoryPointer.new(:long, SIZE)
85
- @@cdll.call(:vmversion, c_ver)
86
- v1 = (c_ver.read_long & 0xFF000000) >> 24
87
- v2 = (c_ver.read_long & 0x00FF0000) >> 16
88
- v3 = (c_ver.read_long & 0x0000FF00) >> 8
89
- v4 = c_ver.read_long & 0x000000FF
90
- "#{v1}.#{v2}.#{v3}.#{v4}"
91
- end
92
-
93
- def get_parameter(name, is_string = false)
94
- self.polling('get_parameter', name: name) do
95
- if is_string
96
- c_get = FFI::MemoryPointer.new(:string, 512, true)
97
- @@cdll.call(:get_parameter_string, name, c_get)
98
- c_get.read_string
99
- else
100
- c_get = FFI::MemoryPointer.new(:float, SIZE)
101
- @@cdll.call(:get_parameter_float, name, c_get)
102
- c_get.read_float.round(1)
103
- end
104
- end
105
- end
106
-
107
- def set_parameter(name, value)
108
- if value.is_a? String
109
- @@cdll.call(:set_parameter_string, name, value)
110
- else
111
- @@cdll.call(:set_parameter_float, name, value.to_f)
112
- end
113
- @cache.store(name, value)
114
- end
115
-
116
- def get_buttonstatus(id, mode)
117
- self.polling('get_buttonstatus', id: id, mode: mode) do
118
- c_get = FFI::MemoryPointer.new(:float, SIZE)
119
- @@cdll.call(:get_buttonstatus, id, c_get, mode)
120
- c_get.read_float.to_i
121
- end
122
- end
123
-
124
- def set_buttonstatus(id, state, mode)
125
- @@cdll.call(:set_buttonstatus, id, state, mode)
126
- @cache.store("mb_#{id}_#{mode}", state)
127
- end
128
-
129
- def set_parameter_multi(param_hash)
130
- param_hash.each do |(key, val)|
131
- prop, m2, m3, *rem = key.to_s.split('_')
132
- if m2.to_i.to_s == m2
133
- m2 = m2.to_i
134
- elsif m3.to_i.to_s == m3
135
- m3 = m3.to_i
136
- end
137
-
138
- case prop
139
- when 'strip'
140
- self.strip[m2].set_multi(val)
141
- when 'bus'
142
- self.bus[m2].set_multi(val)
143
- when 'button', 'mb'
144
- self.button[m2].set_multi(val)
145
- when 'vban'
146
- if %w[instream in].include? m2
147
- self.vban.instream[m3].set_multi(val)
148
- elsif %w[outstream out].include? m2
149
- self.vban.outstream[m3].set_multi(val)
150
- end
151
- end
152
- sleep(DELAY)
153
- end
154
- end
155
-
156
- def get_level(type, index)
157
- c_get = FFI::MemoryPointer.new(:float, SIZE)
158
- @@cdll.call(:get_level, type, index, c_get)
159
- c_get.read_float
160
- end
161
-
162
- def strip_levels
163
- '
164
- Returns the full level array for strips, PREFADER mode,
165
- before math conversion
166
- '
167
- (0...(2 * @p_in + 8 * @v_in)).map { |i| get_level(0, i) }
168
- end
169
-
170
- def bus_levels
171
- '
172
- Returns the full level array for buses, before math conversion
173
- '
174
- (0...(8 * (@p_out + @v_out))).map { |i| get_level(3, i) }
175
- end
176
-
177
- def get_num_devices(direction)
178
- unless %w[in out].include? direction
179
- raise VMRemoteErrors.new('expected in or out')
180
- end
181
- if direction == 'in'
182
- val = @@cdll.call(:get_num_indevices)
183
- else
184
- val = @@cdll.call(:get_num_outdevices)
185
- end
186
- val[0]
187
- end
188
-
189
- def get_device_description(index, direction)
190
- unless %w[in out].include? direction
191
- raise VMRemoteErrors.new('expected in or out')
192
- end
193
- c_type = FFI::MemoryPointer.new(:long, SIZE)
194
- c_name = FFI::MemoryPointer.new(:string, 256, true)
195
- c_hwid = FFI::MemoryPointer.new(:string, 256, true)
196
- if direction == 'in'
197
- @@cdll.call(:get_desc_indevices, index, c_type, c_name, c_hwid)
198
- else
199
- @@cdll.call(:get_desc_outdevices, index, c_type, c_name, c_hwid)
200
- end
201
- [c_name.read_string, c_type.read_long, c_hwid.read_string]
202
- end
203
-
204
- alias_method 'set_multi', :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
- 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 do |x, i|
62
+ !(x == @bus_buf[i])
63
+ end
64
+ @cache['strip_level'] = @strip_buf
65
+ @cache['bus_level'] = @bus_buf
66
+ notify_observers('ldirty')
67
+ end
68
+ sleep(@ratelimit)
69
+ end
70
+ end
71
+ end
72
+
73
+ def end_thread
74
+ @running = false
75
+ end
76
+
77
+ def login
78
+ @@cdll.call(:login)
79
+ clear_polling
80
+ rescue CAPIErrors => error
81
+ case
82
+ when error.value == 1
83
+ self.start(@kind.name)
84
+ clear_polling
85
+ when error.value < 0
86
+ raise
87
+ end
88
+ end
89
+
90
+ def logout
91
+ clear_polling
92
+ sleep(0.1)
93
+ @@cdll.call(:logout)
94
+ end
95
+
96
+ def type
97
+ c_type = FFI::MemoryPointer.new(:long, SIZE)
98
+ @@cdll.call(:vmtype, c_type)
99
+ types = { 1 => 'basic', 2 => 'banana', 3 => 'potato' }
100
+ types[c_type.read_long]
101
+ end
102
+
103
+ def version
104
+ c_ver = FFI::MemoryPointer.new(:long, SIZE)
105
+ @@cdll.call(:vmversion, c_ver)
106
+ v1 = (c_ver.read_long & 0xFF000000) >> 24
107
+ v2 = (c_ver.read_long & 0x00FF0000) >> 16
108
+ v3 = (c_ver.read_long & 0x0000FF00) >> 8
109
+ v4 = c_ver.read_long & 0x000000FF
110
+ "#{v1}.#{v2}.#{v3}.#{v4}"
111
+ end
112
+
113
+ def get_parameter(name, is_string = false)
114
+ self.polling('get_parameter', name: name) do
115
+ if is_string
116
+ c_get = FFI::MemoryPointer.new(:string, 512, true)
117
+ @@cdll.call(:get_parameter_string, name, c_get)
118
+ c_get.read_string
119
+ else
120
+ c_get = FFI::MemoryPointer.new(:float, SIZE)
121
+ @@cdll.call(:get_parameter_float, name, c_get)
122
+ c_get.read_float.round(1)
123
+ end
124
+ end
125
+ end
126
+
127
+ def set_parameter(name, value)
128
+ if value.is_a? String
129
+ @@cdll.call(:set_parameter_string, name, value)
130
+ else
131
+ @@cdll.call(:set_parameter_float, name, value.to_f)
132
+ end
133
+ @cache.store(name, value)
134
+ end
135
+
136
+ def get_buttonstatus(id, mode)
137
+ self.polling('get_buttonstatus', id: id, mode: mode) do
138
+ c_get = FFI::MemoryPointer.new(:float, SIZE)
139
+ @@cdll.call(:get_buttonstatus, id, c_get, mode)
140
+ c_get.read_float.to_i
141
+ end
142
+ end
143
+
144
+ def set_buttonstatus(id, state, mode)
145
+ @@cdll.call(:set_buttonstatus, id, state, mode)
146
+ @cache.store("mb_#{id}_#{mode}", state)
147
+ end
148
+
149
+ def set_parameter_multi(param_hash)
150
+ param_hash.each do |(key, val)|
151
+ prop, m2, m3, *rem = key.to_s.split('_')
152
+ if m2.to_i.to_s == m2
153
+ m2 = m2.to_i
154
+ elsif m3.to_i.to_s == m3
155
+ m3 = m3.to_i
156
+ end
157
+
158
+ case prop
159
+ when 'strip'
160
+ self.strip[m2].set_multi(val)
161
+ when 'bus'
162
+ self.bus[m2].set_multi(val)
163
+ when 'button', 'mb'
164
+ self.button[m2].set_multi(val)
165
+ when 'vban'
166
+ if %w[instream in].include? m2
167
+ self.vban.instream[m3].set_multi(val)
168
+ elsif %w[outstream out].include? m2
169
+ self.vban.outstream[m3].set_multi(val)
170
+ end
171
+ end
172
+ sleep(DELAY)
173
+ end
174
+ end
175
+
176
+ def get_level(type, index)
177
+ c_get = FFI::MemoryPointer.new(:float, SIZE)
178
+ @@cdll.call(:get_level, type, index, c_get)
179
+ c_get.read_float
180
+ end
181
+
182
+ def _get_levels
183
+ s = (0...(2 * @p_in + 8 * @v_in)).map { |i| get_level(@strip_mode, i) }
184
+ b = (0...(8 * (@p_out + @v_out))).map { |i| get_level(3, i) }
185
+ [s, b]
186
+ end
187
+
188
+ def get_num_devices(direction)
189
+ unless %w[in out].include? direction
190
+ raise VMRemoteErrors.new('expected in or out')
191
+ end
192
+ if direction == 'in'
193
+ val = @@cdll.call(:get_num_indevices)
194
+ else
195
+ val = @@cdll.call(:get_num_outdevices)
196
+ end
197
+ val[0]
198
+ end
199
+
200
+ def get_device_description(index, direction)
201
+ unless %w[in out].include? direction
202
+ raise VMRemoteErrors.new('expected in or out')
203
+ end
204
+ c_type = FFI::MemoryPointer.new(:long, SIZE)
205
+ c_name = FFI::MemoryPointer.new(:string, 256, true)
206
+ c_hwid = FFI::MemoryPointer.new(:string, 256, true)
207
+ if direction == 'in'
208
+ @@cdll.call(:get_desc_indevices, index, c_type, c_name, c_hwid)
209
+ else
210
+ @@cdll.call(:get_desc_outdevices, index, c_type, c_name, c_hwid)
211
+ end
212
+ [c_name.read_string, c_type.read_long, c_hwid.read_string]
213
+ end
214
+
215
+ alias_method 'set_multi', :set_parameter_multi
216
+ alias_method 'get', :get_parameter
217
+ alias_method 'set', :set_parameter
218
+ alias_method 'pdirty', :pdirty?
219
+ alias_method 'mdirty', :mdirty?
220
+ alias_method 'ldirty', :ldirty?
221
+ end