From 3e09ac0c10c95bb24a08af62393b4f761e2743d0 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 24 Aug 2013 09:54:45 +0000 Subject: initial commit --- lib/dtas/sink_reader_play.rb | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 lib/dtas/sink_reader_play.rb (limited to 'lib/dtas/sink_reader_play.rb') diff --git a/lib/dtas/sink_reader_play.rb b/lib/dtas/sink_reader_play.rb new file mode 100644 index 0000000..17a0190 --- /dev/null +++ b/lib/dtas/sink_reader_play.rb @@ -0,0 +1,70 @@ +# -*- encoding: binary -*- +# :stopdoc: +# Copyright (C) 2013, Eric Wong +# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) +require_relative '../dtas' + +# parses lines from play(1) -S/--show-progress like this: +# In:0.00% 00:00:37.34 [00:00:00.00] Out:1.65M [ -====|==== ] Clip:0 +# +# The authors of sox probably did not intend for the output of play(1) to +# be parsed, but we do it anyways. We need to be ready to update this +# code in case play(1) output changes. +# play -S/--show-progress +class DTAS::SinkReaderPlay + attr_reader :time, :out, :meter, :clips, :headroom + attr_reader :to_io + attr_reader :wr # this is stderr of play(1) + + def initialize + @to_io, @wr = IO.pipe + reset + end + + def readable_iter + buf = Thread.current[:dtas_lbuf] ||= "" + begin + @rbuf << @to_io.read_nonblock(1024, buf) + + # do not OOM in case SoX changes output format on us + @rbuf.clear if @rbuf.size > 0x10000 + + # don't handle partial read + next unless / Clip:\S+ *\z/ =~ @rbuf + + if @rbuf.gsub!(/(.*)\rIn:\S+ (\S+) \S+ Out:(\S+)\s+(\[[^\]]+\]) /m, "") + err = $1 + @time = $2 + @out = $3 + @meter = $4 + if @rbuf.gsub!(/Hd:(\d+\.\d+) Clip:(\S+) */, "") + @headroom = $1 + @clips = $2 + elsif @rbuf.gsub!(/\s+Clip:(\S+) */, "") + @headroom = nil + @clips = $1 + end + + $stderr.write(err) + end + rescue EOFError + return nil + rescue Errno::EAGAIN + return :wait_readable + end while true + end + + def close + @wr.close unless @wr.closed? + @to_io.close + end + + def reset + @rbuf = "" + @time = @out = @meter = @headroom = @clips = nil + end + + def closed? + @to_io.closed? + end +end -- cgit v1.2.3-24-ge0c7