From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS22989 208.118.235.0/24 X-Spam-Status: No, score=-2.2 required=3.0 tests=AWL,BAYES_00,URIBL_BLOCKED shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: dtas-all@80x24.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 477601F7F3 for ; Sat, 27 Dec 2014 12:03:21 +0000 (UTC) Received: from localhost ([::1]:55722 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y4q5Y-0001kD-Na for dtas-all@80x24.org; Sat, 27 Dec 2014 07:03:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45455) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y4q5T-0001iy-U5 for dtas-all@nongnu.org; Sat, 27 Dec 2014 07:03:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Y4q5P-00066N-BE for dtas-all@nongnu.org; Sat, 27 Dec 2014 07:03:15 -0500 Received: from dcvr.yhbt.net ([64.71.152.64]:37772) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y4q5P-00066B-2X for dtas-all@nongnu.org; Sat, 27 Dec 2014 07:03:11 -0500 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 617D51F7EC; Sat, 27 Dec 2014 12:03:09 +0000 (UTC) From: Eric Wong To: Subject: [PATCH 2/3] player: support playing splitfx YAML files Date: Sat, 27 Dec 2014 12:02:57 +0000 Message-Id: <1419681778-6183-3-git-send-email-e@80x24.org> X-Mailer: git-send-email 2.1.2.571.ged78782.dirty In-Reply-To: <1419681778-6183-1-git-send-email-e@80x24.org> References: <1419681778-6183-1-git-send-email-e@80x24.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 64.71.152.64 Cc: Eric Wong X-BeenThere: dtas-all@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dtas-all-bounces+dtas-all=80x24.org@nongnu.org Sender: dtas-all-bounces+dtas-all=80x24.org@nongnu.org This allows splitfx users to test CUE breakpoints and run file-specific effects without interrupting their normal flow. --- examples/splitfx.sample.yml | 8 ++++ lib/dtas/player.rb | 4 +- lib/dtas/source/splitfx.rb | 92 +++++++++++++++++++++++++++++++++++++++++ lib/dtas/splitfx.rb | 8 ++++ test/test_player_integration.rb | 6 +-- 5 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 lib/dtas/source/splitfx.rb diff --git a/examples/splitfx.sample.yml b/examples/splitfx.sample.yml index 297e50b..3826012 100644 --- a/examples/splitfx.sample.yml +++ b/examples/splitfx.sample.yml @@ -11,6 +11,14 @@ comments: ARTIST: John Smith ALBUM: Hello World YEAR: 2013 +# override the normal sox command for dtas-player playback: +command: exec sox "$INFILE" $SOXFMT - $TRIMFX $RGFX $FX +env: + # these effects may be used in any command in this file, including targets + FX: + highpass -1 120 highpass 40 highpass 40 + ladspa -lr tap_limiter -10 9.5 + stats track_start: 1 # 0 for pregap/intro tracks cdda_align: true tracks: diff --git a/lib/dtas/player.rb b/lib/dtas/player.rb index 39e5abf..0ae8cef 100644 --- a/lib/dtas/player.rb +++ b/lib/dtas/player.rb @@ -8,6 +8,7 @@ require_relative 'source' require_relative 'source/sox' require_relative 'source/av' require_relative 'source/ff' +require_relative 'source/splitfx' require_relative 'source/cmd' require_relative 'sink' require_relative 'unix_server' @@ -44,9 +45,10 @@ class DTAS::Player # :nodoc: @current = nil @watchers = {} @source_map = { - "sox" => DTAS::Source::Sox.new, + "sox" => (sox = DTAS::Source::Sox.new), "av" => DTAS::Source::Av.new, "ff" => DTAS::Source::Ff.new, + "splitfx" => DTAS::Source::SplitFX.new(sox), } source_map_reload end diff --git a/lib/dtas/source/splitfx.rb b/lib/dtas/source/splitfx.rb new file mode 100644 index 0000000..ad9e7c1 --- /dev/null +++ b/lib/dtas/source/splitfx.rb @@ -0,0 +1,92 @@ +# Copyright (C) 2014, all contributors +# License: GPLv3 or later +require 'yaml' +require_relative 'sox' +require_relative '../splitfx' + +class DTAS::Source::SplitFX < DTAS::Source::Sox # :nodoc: + MAX_YAML_SIZE = 512 * 1024 + attr_writer :sox + + SPLITFX_DEFAULTS = SOX_DEFAULTS.merge("tryorder" => 3) + + def initialize(sox = DTAS::Source::Sox.new) + command_init(SPLITFX_DEFAULTS) + @sox = sox + end + + def try(ymlfile, offset = nil) + @splitfx = @ymlhash = nil + st = File.stat(ymlfile) + return false if !st.file? || st.size > MAX_YAML_SIZE + + # read 4 bytes first to ensure we have a YAML file with a hash: + buf = "" + File.open(ymlfile, "rb") do |fp| + return false if fp.read(4, buf) != "---\n" + buf << fp.read + end + + sfx = DTAS::SplitFX.new + begin + Dir.chdir(File.dirname(ymlfile)) do # ugh + sfx.import(@ymlhash = YAML.load(buf)) + sfx.infile.replace(File.expand_path(sfx.infile)) + end + @splitfx = sfx + rescue + return false + end + @infile = ymlfile + sox = @sox.try(sfx.infile, offset) or return false + rv = source_file_dup(ymlfile, offset) + rv.sox = sox + rv.env = sfx.env + rv + end + + def __load_comments + @ymlhash["comments"] || @sox.__load_comments + end + + def command_string + @ymlhash["command"] || @sox.command_string + end + + def spawn(player_format, rg_state, opts) + raise "BUG: #{self.inspect}#spawn called twice" if @to_io + e = @env.merge!(player_format.to_env) + e["INFILE"] = @sox.infile + + # make sure these are visible to the "current" command... + e["TRIMFX"] = @offset ? "trim #@offset" : nil + e["RGFX"] = rg_state.effect(self) || nil + e.merge!(@rg.to_env) if @rg + + @pid = dtas_spawn(e, command_string, opts) + end + + def to_hsh + to_hash.delete_if { |k,v| v == SPLITFX_DEFAULTS[k] } + end + + def format + @sox.format + end + + def samples! + @sox.samples! + end + + def samples + @sox.samples + end + + def source_defaults + SPLITFX_DEFAULTS + end + + def cuebreakpoints + @splitfx.cuebreakpoints + end +end diff --git a/lib/dtas/splitfx.rb b/lib/dtas/splitfx.rb index ac39233..9af3faf 100644 --- a/lib/dtas/splitfx.rb +++ b/lib/dtas/splitfx.rb @@ -12,6 +12,7 @@ class DTAS::SplitFX # :nodoc: '$TRIMFX $RATEFX $DITHERFX' include DTAS::Process include DTAS::XS + attr_reader :infile, :env class Skip < Struct.new(:tstart) # :nodoc: def commit(_) @@ -76,6 +77,7 @@ class DTAS::SplitFX # :nodoc: } @tracks = [] @infmt = nil # wait until input is assigned + @cuebp = nil # for playback end def _bool(hash, key) @@ -334,4 +336,10 @@ class DTAS::SplitFX # :nodoc: end false end + + def cuebreakpoints + rv = @cuebp and return rv + require_relative 'cue_index' + @cuebp = @tracks.map { |t| DTAS::CueIndex.new(1, "#{t.tstart}s") } + end end diff --git a/test/test_player_integration.rb b/test/test_player_integration.rb index 66f599e..2525ac5 100644 --- a/test/test_player_integration.rb +++ b/test/test_player_integration.rb @@ -208,11 +208,11 @@ class TestPlayerIntegration < Testcase def test_source_ed s = client_socket - assert_equal "sox av ff", s.req("source ls") + assert_equal "sox av ff splitfx", s.req("source ls") s.req_ok("source ed av tryorder=-1") - assert_equal "av sox ff", s.req("source ls") + assert_equal "av sox ff splitfx", s.req("source ls") s.req_ok("source ed av tryorder=") - assert_equal "sox av ff", s.req("source ls") + assert_equal "sox av ff splitfx", s.req("source ls") s.req_ok("source ed sox command=true") sox = YAML.load(s.req("source cat sox")) -- EW