Class: DTAS::Sink
- Inherits:
-
Object
- Object
- DTAS::Sink
- Defined in:
- lib/dtas/sink.rb
Overview
this is a sink (endpoint, audio enters but never leaves)
Constant Summary collapse
- SINK_DEFAULTS =
COMMAND_DEFAULTS.merge({ "name" => nil, # order matters, this is first "command" => "exec play -q $SOXFMT -", "prio" => 0, "nonblock" => false, "pipe_size" => nil, "active" => false, })
- DEVFD_RE =
%r{/dev/fd/([a-zA-Z]\w*)\b}
- SIVS =
order matters for Ruby 1.9+, this defines to_hsh serialization so we can make the state file human-friendly
%w(name env command prio nonblock pipe_size active)
Constants included from Process
Constants included from Command
Instance Attribute Summary collapse
-
#active ⇒ Object
boolean.
-
#name ⇒ Object
Returns the value of attribute name.
-
#nonblock ⇒ Object
Returns the value of attribute nonblock.
-
#pipe_size ⇒ Object
Returns the value of attribute pipe_size.
-
#prio ⇒ Object
:nodoc:.
Attributes included from Command
#command, #env, #pid, #spawn_at, #to_io
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize ⇒ Sink
constructor
A new instance of Sink.
- #on_death(status) ⇒ Object
- #parse(str) ⇒ Object
- #spawn(format, opts = {}) ⇒ Object
- #to_hash ⇒ Object
- #to_hsh ⇒ Object
-
#valid_name?(s) ⇒ Boolean
allow things that look like audio device names (“hw:1,0” , “/dev/dsp”) or variable names.
Methods included from Serialize
Methods included from Process
#dtas_spawn, #env_expand, #qx, reaper
Methods included from XS
Methods included from Command
#command_init, #command_string
Constructor Details
#initialize ⇒ Sink
Returns a new instance of Sink.
38 39 40 41 |
# File 'lib/dtas/sink.rb', line 38 def initialize command_init(SINK_DEFAULTS) @sink = self end |
Instance Attribute Details
#active ⇒ Object
boolean
14 15 16 |
# File 'lib/dtas/sink.rb', line 14 def active @active end |
#name ⇒ Object
Returns the value of attribute name.
15 16 17 |
# File 'lib/dtas/sink.rb', line 15 def name @name end |
#nonblock ⇒ Object
Returns the value of attribute nonblock.
17 18 19 |
# File 'lib/dtas/sink.rb', line 17 def nonblock @nonblock end |
#pipe_size ⇒ Object
Returns the value of attribute pipe_size.
16 17 18 |
# File 'lib/dtas/sink.rb', line 16 def pipe_size @pipe_size end |
#prio ⇒ Object
:nodoc:
13 14 15 |
# File 'lib/dtas/sink.rb', line 13 def prio @prio end |
Class Method Details
.load(hash) ⇒ Object
49 50 51 52 53 54 55 56 57 |
# File 'lib/dtas/sink.rb', line 49 def self.load(hash) sink = new return sink unless hash (SIVS & hash.keys).each do |k| sink.instance_variable_set("@#{k}", hash[k]) end sink.valid_name?(sink.name) or raise ArgumentError, "invalid sink name" sink end |
Instance Method Details
#on_death(status) ⇒ Object
65 66 67 |
# File 'lib/dtas/sink.rb', line 65 def on_death(status) super end |
#parse(str) ⇒ Object
59 60 61 62 63 |
# File 'lib/dtas/sink.rb', line 59 def parse(str) inputs = {} str.scan(DEVFD_RE) { |w| inputs[w[0]] = nil } inputs end |
#spawn(format, opts = {}) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/dtas/sink.rb', line 69 def spawn(format, opts = {}) raise "BUG: #{self.inspect}#spawn called twice" if @pid rv = [] pclass = @nonblock ? DTAS::PipeNB : DTAS::Pipe cmd = command_string inputs = parse(cmd) if inputs.empty? # /dev/fd/* not specified in the command, assume one input for stdin r, w = pclass.new w.pipe_size = @pipe_size if @pipe_size inputs[:in] = opts[:in] = r w.sink = self rv << w else # multiple inputs, fun!, we'll tee to them inputs.each_key do |name| r, w = pclass.new w.pipe_size = @pipe_size if @pipe_size inputs[name] = r w.sink = self rv << w end opts[:in] = "/dev/null" # map to real /dev/fd/* values and setup proper redirects cmd = cmd.gsub(DEVFD_RE) do read_fd = inputs[$1].fileno opts[read_fd] = read_fd # do not close-on-exec "/dev/fd/#{read_fd}" end end @pid = dtas_spawn(format.to_env.merge!(@env), cmd, opts) inputs.each_value(&:close) rv end |
#to_hash ⇒ Object
109 110 111 |
# File 'lib/dtas/sink.rb', line 109 def to_hash ivars_to_hash(SIVS) end |
#to_hsh ⇒ Object
113 114 115 |
# File 'lib/dtas/sink.rb', line 113 def to_hsh to_hash.delete_if { |k,v| v == SINK_DEFAULTS[k] } end |
#valid_name?(s) ⇒ Boolean
allow things that look like audio device names (“hw:1,0” , “/dev/dsp”) or variable names.
45 46 47 |
# File 'lib/dtas/sink.rb', line 45 def valid_name?(s) !!(s =~ %r{\A[\w:,/-]+\z}) end |