voicemeeter 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +775 -0
- data/lib/voicemeeter/base.rb +225 -0
- data/lib/voicemeeter/bus.rb +129 -0
- data/lib/voicemeeter/button.rb +70 -0
- data/lib/voicemeeter/cbindings.rb +81 -0
- data/lib/voicemeeter/command.rb +35 -0
- data/lib/voicemeeter/configs.rb +117 -0
- data/lib/voicemeeter/device.rb +28 -0
- data/lib/voicemeeter/event.rb +82 -0
- data/lib/voicemeeter/fx.rb +42 -0
- data/lib/voicemeeter/install.rb +38 -0
- data/lib/voicemeeter/iremote.rb +51 -0
- data/lib/voicemeeter/kinds.rb +51 -0
- data/lib/voicemeeter/logger.rb +9 -0
- data/lib/voicemeeter/meta.rb +75 -0
- data/lib/voicemeeter/midi.rb +14 -0
- data/lib/voicemeeter/mixins.rb +83 -0
- data/lib/voicemeeter/option.rb +69 -0
- data/lib/voicemeeter/patch.rb +79 -0
- data/lib/voicemeeter/recorder.rb +90 -0
- data/lib/voicemeeter/remote.rb +102 -0
- data/lib/voicemeeter/strip.rb +254 -0
- data/lib/voicemeeter/util.rb +35 -0
- data/lib/voicemeeter/vban.rb +105 -0
- data/lib/voicemeeter/version.rb +25 -0
- data/lib/voicemeeter/worker.rb +64 -0
- data/lib/voicemeeter.rb +56 -0
- metadata +149 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module Events
|
3
|
+
module Director
|
4
|
+
def observers
|
5
|
+
@observers ||= {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def on(event, method = nil, &block)
|
9
|
+
(observers[event] ||= []) << (block || method)
|
10
|
+
end
|
11
|
+
|
12
|
+
def register(cbs)
|
13
|
+
cbs = Array(cbs) unless cbs.respond_to? :each
|
14
|
+
cbs.each { |cb| on(cb.name[3..].to_sym, cb) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def deregister(cbs)
|
18
|
+
cbs = Array(cbs) unless cbs.respond_to? :each
|
19
|
+
cbs.each { |cb| observers[cb.name[3..].to_sym]&.reject! { |o| cbs.include? o } }
|
20
|
+
end
|
21
|
+
|
22
|
+
def fire(event)
|
23
|
+
observers[event]&.each { |block| block.call }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Tracker
|
28
|
+
include Logging
|
29
|
+
|
30
|
+
attr_reader :pdirty, :mdirty, :midi, :ldirty
|
31
|
+
|
32
|
+
def initialize(**kwargs)
|
33
|
+
make_writer_methods :pdirty, :mdirty, :midi, :ldirty
|
34
|
+
|
35
|
+
kwargs.each do |key, value|
|
36
|
+
instance_variable_set("@#{key}", value || false)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
self.class.name.split("::").last.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
def info(msg = nil)
|
45
|
+
info_msg = msg ? ["#{msg} events."] : []
|
46
|
+
info_msg << if any?
|
47
|
+
["Now listening for #{get.join(", ")} events"]
|
48
|
+
else
|
49
|
+
["Not listening for any events"]
|
50
|
+
end
|
51
|
+
logger.info info_msg.join(" ")
|
52
|
+
end
|
53
|
+
|
54
|
+
private def make_writer_methods(*params)
|
55
|
+
params.each do |param|
|
56
|
+
define_singleton_method("#{param}=") do |value|
|
57
|
+
instance_variable_set("@#{param}", value)
|
58
|
+
info("#{param} #{value ? "added to" : "removed from"}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def get
|
64
|
+
%i[pdirty mdirty midi ldirty].reject { |ev| !send(ev) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def any?
|
68
|
+
[pdirty, mdirty, midi, ldirty].any?
|
69
|
+
end
|
70
|
+
|
71
|
+
def add(events)
|
72
|
+
events = [events] unless events.respond_to? :each
|
73
|
+
events.each { |e| send("#{e}=", true) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def remove(events)
|
77
|
+
events = [events] unless events.respond_to? :each
|
78
|
+
events.each { |e| send("#{e}=", false) }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
class Fx
|
3
|
+
include IRemote
|
4
|
+
attr_reader :reverb, :delay
|
5
|
+
|
6
|
+
def initialize(remote)
|
7
|
+
super
|
8
|
+
@reverb = FxReverb.new(remote)
|
9
|
+
@delay = FxDelay.new(remote)
|
10
|
+
end
|
11
|
+
|
12
|
+
def identifier
|
13
|
+
:fx
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class FxReverb
|
18
|
+
include IRemote
|
19
|
+
|
20
|
+
def initialize(remote)
|
21
|
+
super
|
22
|
+
make_accessor_bool :on, :ab
|
23
|
+
end
|
24
|
+
|
25
|
+
def identifier
|
26
|
+
"fx.reverb"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class FxDelay
|
31
|
+
include IRemote
|
32
|
+
|
33
|
+
def initialize(remote)
|
34
|
+
super
|
35
|
+
make_accessor_bool :on, :ab
|
36
|
+
end
|
37
|
+
|
38
|
+
def identifier
|
39
|
+
"fx.delay"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
private
|
3
|
+
|
4
|
+
module Install
|
5
|
+
extend Logging
|
6
|
+
|
7
|
+
OS_BITS = (FFI::Platform::CPU.downcase == "x64") ? 64 : 32
|
8
|
+
|
9
|
+
def get_vmpath
|
10
|
+
reg_key = [
|
11
|
+
:Software,
|
12
|
+
((OS_BITS == 64) ? :WOW6432Node : nil),
|
13
|
+
:Microsoft,
|
14
|
+
:Windows,
|
15
|
+
:CurrentVersion,
|
16
|
+
:Uninstall,
|
17
|
+
:"VB:Voicemeeter {17359A74-1236-5467}"
|
18
|
+
]
|
19
|
+
|
20
|
+
Win32::Registry::HKEY_LOCAL_MACHINE.open(
|
21
|
+
reg_key.compact.join("\\")
|
22
|
+
) do |reg|
|
23
|
+
value = reg["UninstallString"]
|
24
|
+
|
25
|
+
Pathname.new(value).dirname
|
26
|
+
end
|
27
|
+
rescue Win32::Registry::Error => e
|
28
|
+
err_msg = [
|
29
|
+
"#{e.class.name}: #{e.message}",
|
30
|
+
*e.backtrace
|
31
|
+
]
|
32
|
+
logger.error err_msg.join("\n")
|
33
|
+
raise Errors::VMInstallError.new "unable to read Voicemeeter path from the registry"
|
34
|
+
end
|
35
|
+
|
36
|
+
module_function :get_vmpath
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
# Common interface with the base Remote class.
|
3
|
+
module IRemote
|
4
|
+
include Logging
|
5
|
+
include MetaFunctions
|
6
|
+
|
7
|
+
def initialize(remote, i = nil)
|
8
|
+
@remote = remote
|
9
|
+
@index = i
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"#{self.class.name.split("::").last}#{@index}#{@remote.kind}"
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def getter(param, is_string = false)
|
19
|
+
logger.debug "getter: #{_cmd(param)}"
|
20
|
+
@remote.get(_cmd(param), is_string)
|
21
|
+
end
|
22
|
+
|
23
|
+
def setter(param, value)
|
24
|
+
logger.debug "setter: #{_cmd(param)}=#{value}"
|
25
|
+
@remote.set(_cmd(param), value)
|
26
|
+
end
|
27
|
+
|
28
|
+
def _cmd(param)
|
29
|
+
param.empty? ? identifier : "#{identifier}.#{param}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def identifier
|
33
|
+
raise "Called abstract method: identifier"
|
34
|
+
end
|
35
|
+
|
36
|
+
public
|
37
|
+
|
38
|
+
def apply(params)
|
39
|
+
params.each do |key, val|
|
40
|
+
if val.is_a? Hash
|
41
|
+
target = send(key)
|
42
|
+
target.apply(val)
|
43
|
+
elsif key == :mode
|
44
|
+
mode.send("#{val}=", true)
|
45
|
+
else
|
46
|
+
send("#{key}=", val)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module Kinds
|
3
|
+
private
|
4
|
+
|
5
|
+
module KindEnum
|
6
|
+
BASIC = 1
|
7
|
+
BANANA = 2
|
8
|
+
POTATO = 3
|
9
|
+
POTATOX64 = 6
|
10
|
+
end
|
11
|
+
|
12
|
+
KindMap =
|
13
|
+
Data.define(:name, :ins, :outs, :vban, :asio, :insert, :num_buttons) do
|
14
|
+
def phys_in = ins.first
|
15
|
+
|
16
|
+
def virt_in = ins.last
|
17
|
+
|
18
|
+
def phys_out = outs.first
|
19
|
+
|
20
|
+
def virt_out = outs.last
|
21
|
+
|
22
|
+
def num_strip = ins.sum
|
23
|
+
|
24
|
+
def num_bus = outs.sum
|
25
|
+
|
26
|
+
def num_strip_levels = 2 * phys_in + 8 * virt_in
|
27
|
+
|
28
|
+
def num_bus_levels = 8 * (phys_out + virt_out)
|
29
|
+
|
30
|
+
def to_s = name.to_s.capitalize
|
31
|
+
end
|
32
|
+
|
33
|
+
basic = KindMap.new(:basic, [2, 1], [1, 1], [4, 4, 1, 1], [0, 0], 0, 80)
|
34
|
+
|
35
|
+
banana = KindMap.new(:banana, [3, 2], [3, 2], [8, 8, 1, 1], [6, 8], 22, 80)
|
36
|
+
|
37
|
+
potato = KindMap.new(:potato, [5, 3], [5, 3], [8, 8, 1, 1], [10, 8], 34, 80)
|
38
|
+
|
39
|
+
KIND_MAPS = [basic, banana, potato].to_h { |kind| [kind.name, kind] }
|
40
|
+
|
41
|
+
public
|
42
|
+
|
43
|
+
def get(kind_id)
|
44
|
+
KIND_MAPS.fetch(kind_id)
|
45
|
+
end
|
46
|
+
|
47
|
+
ALL = KIND_MAPS.values
|
48
|
+
|
49
|
+
module_function :get
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module MetaFunctions
|
3
|
+
private
|
4
|
+
|
5
|
+
# Accessor methods
|
6
|
+
def make_accessor_bool(*params)
|
7
|
+
params.each do |param|
|
8
|
+
define_singleton_method(param) { getter(param).to_i == 1 }
|
9
|
+
|
10
|
+
define_singleton_method("#{param}=") do |value|
|
11
|
+
setter(param, value && 1 || 0)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def make_accessor_string(*params)
|
17
|
+
params.each do |param|
|
18
|
+
define_singleton_method(param) { getter(param, true) }
|
19
|
+
|
20
|
+
define_singleton_method("#{param}=") { |value| setter(param, value) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def make_accessor_int(*params)
|
25
|
+
params.each do |param|
|
26
|
+
define_singleton_method(param) { getter(param).to_i }
|
27
|
+
|
28
|
+
define_singleton_method("#{param}=") { |value| setter(param, value) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def make_accessor_float(*params)
|
33
|
+
params.each do |param|
|
34
|
+
define_singleton_method(param) { getter(param) }
|
35
|
+
|
36
|
+
define_singleton_method("#{param}=") { |value| setter(param, value) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# reader methods
|
41
|
+
def make_reader_string(*params)
|
42
|
+
params.each do |param|
|
43
|
+
define_singleton_method(param) { getter(param, true) }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def make_reader_int(*params)
|
48
|
+
params.each do |param|
|
49
|
+
define_singleton_method(param) { getter(param).to_i }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# writer methods
|
54
|
+
def make_writer_bool(*params)
|
55
|
+
params.each do |param|
|
56
|
+
define_singleton_method("#{param}=") do |value|
|
57
|
+
setter(param, value && 1 || 0)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def make_writer_string(*params)
|
63
|
+
params.each do |param|
|
64
|
+
define_singleton_method("#{param}=") { |value| setter(param, value) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# methods for performing certain actions as opposed to setting values
|
69
|
+
def make_action_method(*params)
|
70
|
+
params.each do |param|
|
71
|
+
define_singleton_method(param) { setter(param, 1) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module Mixins
|
3
|
+
module Fades
|
4
|
+
def fadeto(target, time)
|
5
|
+
setter("FadeTo", "(#{target}, #{time})")
|
6
|
+
sleep(@remote.delay)
|
7
|
+
end
|
8
|
+
|
9
|
+
def fadeby(change, time)
|
10
|
+
setter("FadeBy", "(#{change}, #{time})")
|
11
|
+
sleep(@remote.delay)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Return
|
16
|
+
def initialize(remote, i)
|
17
|
+
super
|
18
|
+
make_accessor_float :returnreverb, :returndelay, :returnfx1, :returnfx2
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module Apps
|
23
|
+
def appgain(name, gain)
|
24
|
+
setter("AppGain", "(\"#{name}\", #{gain})")
|
25
|
+
end
|
26
|
+
|
27
|
+
def appmute(name, mute)
|
28
|
+
setter("AppMute", "(\"#{name}\", #{mute ? 1 : 0})")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module Outputs
|
33
|
+
def initialize(*args)
|
34
|
+
super
|
35
|
+
remote, *_ = args
|
36
|
+
num_a, num_b = remote.kind.outs
|
37
|
+
channels =
|
38
|
+
(1..(num_a + num_b)).map do |i|
|
39
|
+
(i <= num_a) ? "A#{i}" : "B#{i - num_a}"
|
40
|
+
end
|
41
|
+
make_accessor_bool(*channels)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module Xy
|
46
|
+
module Pan
|
47
|
+
def initialize(remote, i)
|
48
|
+
super
|
49
|
+
make_accessor_float :pan_x, :pan_y
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module Color
|
54
|
+
def initialize(remote, i)
|
55
|
+
super
|
56
|
+
make_accessor_float :color_x, :color_y
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module Fx
|
61
|
+
def initialize(remote, i)
|
62
|
+
super
|
63
|
+
make_accessor_float :fx_x, :fx_y
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
module Fx
|
69
|
+
def initialize(remote, i)
|
70
|
+
super
|
71
|
+
make_accessor_float :reverb, :delay, :fx1, :fx2
|
72
|
+
make_accessor_bool :postreverb, :postdelay, :postfx1, :postfx2
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module LevelEnum
|
77
|
+
PREFADER = 0
|
78
|
+
POSTFADER = 1
|
79
|
+
POSTMUTE = 2
|
80
|
+
BUS = 3
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module Option
|
3
|
+
class Base
|
4
|
+
include IRemote
|
5
|
+
attr_reader :delay, :buffer, :mode
|
6
|
+
|
7
|
+
def initialize(remote)
|
8
|
+
super
|
9
|
+
make_accessor_int :sr
|
10
|
+
make_accessor_bool :asiosr, :monitoronsel, :slidermode
|
11
|
+
|
12
|
+
@delay = (0...remote.kind.phys_out).map { OptionDelay.new(remote, _1) }
|
13
|
+
@buffer = OptionBuffer.new(remote)
|
14
|
+
@mode = OptionMode.new(remote)
|
15
|
+
end
|
16
|
+
|
17
|
+
def identifier
|
18
|
+
:option
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class OptionDelay
|
23
|
+
include IRemote
|
24
|
+
|
25
|
+
def initialize(remote, i)
|
26
|
+
super
|
27
|
+
make_accessor_bool :on, :ab
|
28
|
+
end
|
29
|
+
|
30
|
+
def identifier
|
31
|
+
"option.delay"
|
32
|
+
end
|
33
|
+
|
34
|
+
def get
|
35
|
+
getter("[#{@index}]").to_i
|
36
|
+
end
|
37
|
+
|
38
|
+
def set(val)
|
39
|
+
setter("[#{@index}]", val)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class OptionBuffer
|
44
|
+
include IRemote
|
45
|
+
|
46
|
+
def initialize(remote)
|
47
|
+
super
|
48
|
+
make_accessor_int :mme, :wdm, :ks, :asio
|
49
|
+
end
|
50
|
+
|
51
|
+
def identifier
|
52
|
+
"option.buffer"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class OptionMode
|
57
|
+
include IRemote
|
58
|
+
|
59
|
+
def initialize(remote)
|
60
|
+
super
|
61
|
+
make_accessor_bool :exclusif, :swift
|
62
|
+
end
|
63
|
+
|
64
|
+
def identifier
|
65
|
+
"option.mode"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module Patch
|
3
|
+
# Base class for Patch
|
4
|
+
class Base
|
5
|
+
include IRemote
|
6
|
+
attr_reader :asio, :A2, :A3, :A4, :A5, :composite, :insert
|
7
|
+
|
8
|
+
def initialize(remote)
|
9
|
+
super
|
10
|
+
make_accessor_bool :postfadercomposite, :postfxinsert
|
11
|
+
|
12
|
+
asio_in, asio_out = remote.kind.asio
|
13
|
+
@asio = (0...asio_in).map { PatchAsioIn.new(remote, _1) }
|
14
|
+
%i[A2 A3 A4 A5].each do |param|
|
15
|
+
instance_variable_set("@#{param}", (0...asio_out).map { PatchAsioOut.new(remote, _1, param) })
|
16
|
+
end
|
17
|
+
@composite = (0...8).map { PatchComposite.new(remote, _1) }
|
18
|
+
@insert = (0...remote.kind.insert).map { PatchInsert.new(remote, _1) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class PatchAsio
|
23
|
+
include IRemote
|
24
|
+
|
25
|
+
def identifier
|
26
|
+
:patch
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class PatchAsioIn < PatchAsio
|
31
|
+
def get
|
32
|
+
getter("asio[#{@index}]").to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def set(val)
|
36
|
+
setter("asio[#{@index}]", val)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class PatchAsioOut < PatchAsio
|
41
|
+
def initialize(remote, i, param)
|
42
|
+
super(remote, i)
|
43
|
+
@param = param
|
44
|
+
end
|
45
|
+
|
46
|
+
def get
|
47
|
+
getter("out#{@param}[#{@index}]").to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
def set(val)
|
51
|
+
setter("out#{@param}[#{@index}]", val)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class PatchComposite
|
56
|
+
include IRemote
|
57
|
+
|
58
|
+
def get
|
59
|
+
getter("composite[#{@index}]").to_i
|
60
|
+
end
|
61
|
+
|
62
|
+
def set(val)
|
63
|
+
setter("composite[#{@index}]", val)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class PatchInsert
|
68
|
+
include IRemote
|
69
|
+
|
70
|
+
def get
|
71
|
+
getter("insert[#{@index}]").to_i == 1
|
72
|
+
end
|
73
|
+
|
74
|
+
def set(val)
|
75
|
+
setter("insert[#{@index}]", val && 1 || 0)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Voicemeeter
|
2
|
+
module Recorder
|
3
|
+
module FileTypeEnum
|
4
|
+
WAV = 1
|
5
|
+
AIFF = 2
|
6
|
+
BWF = 3
|
7
|
+
MP3 = 100
|
8
|
+
end
|
9
|
+
|
10
|
+
# Base class for Recorder
|
11
|
+
class Base
|
12
|
+
include IRemote
|
13
|
+
include Mixins::Outputs
|
14
|
+
|
15
|
+
attr_reader :mode, :armstrip, :armbus
|
16
|
+
|
17
|
+
def initialize(remote)
|
18
|
+
super
|
19
|
+
make_action_method :play, :stop, :pause, :replay, :record, :ff, :rew
|
20
|
+
make_accessor_int :bitresolution, :channel, :kbps
|
21
|
+
make_accessor_float :gain
|
22
|
+
|
23
|
+
@mode = RecorderMode.new(remote)
|
24
|
+
@armstrip = (0...remote.kind.num_strip).map { RecorderArmStrip.new(remote, _1) }
|
25
|
+
@armbus = (0...remote.kind.num_bus).map { RecorderArmBus.new(remote, _1) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def identifier
|
29
|
+
:recorder
|
30
|
+
end
|
31
|
+
|
32
|
+
def load(filepath)
|
33
|
+
setter("load", filepath)
|
34
|
+
end
|
35
|
+
|
36
|
+
def goto(timestr)
|
37
|
+
unless /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$/.match?(timestr)
|
38
|
+
logger.error "goto got: '#{timestr}', but expects a time string in the format 'hh:mm:ss'"
|
39
|
+
return
|
40
|
+
end
|
41
|
+
dt = DateTime.parse(timestr)
|
42
|
+
seconds = dt.hour * 3600 + dt.min * 60 + dt.second
|
43
|
+
setter("goto", seconds)
|
44
|
+
end
|
45
|
+
|
46
|
+
def filetype(val)
|
47
|
+
opts = {wav: FileTypeEnum::WAV, aiff: FileTypeEnum::AIFF, bwf: FileTypeEnum::BWF, mp3: FileTypeEnum::MP3}
|
48
|
+
setter("filetype", opts[val])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class RecorderMode
|
53
|
+
include IRemote
|
54
|
+
|
55
|
+
def initialize(remote)
|
56
|
+
super
|
57
|
+
make_accessor_bool :recbus, :playonload, :loop, :multitrack
|
58
|
+
end
|
59
|
+
|
60
|
+
def identifier
|
61
|
+
"recorder.mode"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class RecorderArmChannel
|
66
|
+
include IRemote
|
67
|
+
|
68
|
+
def initialize(remote, j)
|
69
|
+
super(remote)
|
70
|
+
@j = j
|
71
|
+
end
|
72
|
+
|
73
|
+
def set
|
74
|
+
setter("", val && 1 || 0)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class RecorderArmStrip < RecorderArmChannel
|
79
|
+
def identifier
|
80
|
+
"recorder.armstrip[#{@j}]"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class RecorderArmBus < RecorderArmChannel
|
85
|
+
def identifier
|
86
|
+
"recorder.armbus[#{@j}]"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|