voicemeeter_api_ruby 4.0.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1665d58c08963437a1f97aea620c0d92d660135c653791e136a8e16b468430e
4
- data.tar.gz: 4c9b65a8bc057ecde1206007c48321ea90205828e7f5618279c283e621a35632
3
+ metadata.gz: e855e458e3debb64c2fe076bcad06c73643f8750c60d9a719f1eb5bb95ab3886
4
+ data.tar.gz: 68a4ff2917b5f62a7e1846d09b9dff380e7e5991f6403fabf55e350ef99f65be
5
5
  SHA512:
6
- metadata.gz: 49412d436f0a24d23f68d06757f6b4c6f652ad1c3489f83483d98b1128f26e7d4c22db192248361ce223e57ee8c3cdf1ad4e3e513b3d6055e34fea8b0c5916ef
7
- data.tar.gz: 7a95182d33363a4301a00c17329b0b782b084d9558d6fa348207508aec7d498a71644b5444677405d7e34282e5fd18fd9d825ecd9f30800b09c7e5aa15cd9669
6
+ metadata.gz: 8d9297aaf1dbc13b231f1aa0b3388f58b13ae5fcbfb630a4bb7bfdb4b6d29ea559ef3b58c7c2df2725d6dc7d16a0369549c2fa331caf128b3c784e63315cbcd0
7
+ data.tar.gz: a430dccd4348bc9d04ec2e54f6579d66df12227ff25d7d38577e979e88e1135ff68537346d8a6be9b67cd90b131bb43f6d58e1a7a91280ac14728c800e7990a1
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,218 @@
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
+ 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