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), used by -player
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
- #sink_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, #env_expand_ary, #env_expand_i, #qx, reaper
Methods included from SpawnFix
Methods included from XS
Methods included from Command
#command_init, #command_string
Constructor Details
#initialize ⇒ Sink
Returns a new instance of Sink.
39 40 41 42 |
# File 'lib/dtas/sink.rb', line 39 def initialize command_init(SINK_DEFAULTS) @sink = self end |
Instance Attribute Details
#active ⇒ Object
boolean
15 16 17 |
# File 'lib/dtas/sink.rb', line 15 def active @active end |
#name ⇒ Object
Returns the value of attribute name.
16 17 18 |
# File 'lib/dtas/sink.rb', line 16 def name @name end |
#nonblock ⇒ Object
Returns the value of attribute nonblock.
18 19 20 |
# File 'lib/dtas/sink.rb', line 18 def nonblock @nonblock end |
#pipe_size ⇒ Object
Returns the value of attribute pipe_size.
17 18 19 |
# File 'lib/dtas/sink.rb', line 17 def pipe_size @pipe_size end |
#prio ⇒ Object
:nodoc:
14 15 16 |
# File 'lib/dtas/sink.rb', line 14 def prio @prio end |
Class Method Details
.load(hash) ⇒ Object
50 51 52 53 54 55 56 57 58 |
# File 'lib/dtas/sink.rb', line 50 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
66 67 68 |
# File 'lib/dtas/sink.rb', line 66 def on_death(status) super end |
#parse(str) ⇒ Object
60 61 62 63 64 |
# File 'lib/dtas/sink.rb', line 60 def parse(str) inputs = {} str.scan(DEVFD_RE) { |w| inputs[w[0]] = nil } inputs end |
#sink_spawn(format, opts = {}) ⇒ Object
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 108 |
# File 'lib/dtas/sink.rb', line 70 def sink_spawn(format, opts = {}) raise "BUG: #{self.inspect}#sink_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] = DTAS.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
110 111 112 |
# File 'lib/dtas/sink.rb', line 110 def to_hash ivars_to_hash(SIVS) end |
#to_hsh ⇒ Object
114 115 116 |
# File 'lib/dtas/sink.rb', line 114 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.
46 47 48 |
# File 'lib/dtas/sink.rb', line 46 def valid_name?(s) !!(s =~ %r{\A[\w:,/-]+\z}) end |