From bbd2a006152cce4e5fa28bb2793d239ebdfdb491 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 13 Oct 2013 08:54:05 +0000 Subject: trimfx: initial bits This will allow editing individual portions of audio of a larger file while creating cross fade effects to join them. --- examples/trimfx.sample.yml | 30 +++++++++++++++++++++ lib/dtas/trimfx.rb | 67 ++++++++++++++++++++++++++++++++++++++++++++++ test/test_trimfx.rb | 35 ++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 examples/trimfx.sample.yml create mode 100644 lib/dtas/trimfx.rb create mode 100644 test/test_trimfx.rb diff --git a/examples/trimfx.sample.yml b/examples/trimfx.sample.yml new file mode 100644 index 0000000..e205b03 --- /dev/null +++ b/examples/trimfx.sample.yml @@ -0,0 +1,30 @@ +# To the extent possible under law, Eric Wong has waived all copyright and +# related or neighboring rights to this example. +# Note: be sure to update test/test_trimfx.rb if you change this, +# test_trimfx.rb relies on this. +--- +infile: foo.flac +env: + PATH: $PATH + SOX_OPTS: $SOX_OPTS -R + I2: second.flac + I3: third.flac +comments: + ARTIST: John Smith + ALBUM: Hello World + YEAR: 2013 +track_start: 1 +effects: +# the fade parameter sets the default fade for every subsequent effect +- fade=t1,t1;t1,t1 # fade-out-orig,fade-in-new;fade-out-orig;fade-in-new + +# the following commands are equivalent +- trim 52 =53 sh sox $SOXIN $SOXOUT $TRIMFX vol -6dB $FADEFX +- trim 52 1 sox vol -6dB # shorthand + +# as are the following (for little endian machines) +- trim 52 1 eca -eadb:-6 +- trim 52 1 sh sox $SOXIN $SOX2ECA $TRIMFX | ecasound $ECAFMT + -i stdin -o stdout -eadb:-6 | sox $ECA2SOX - $SOXOUT $FADEFX +# SOX2ECA='-tf32 -c$CHANNELS -r$RATE' +# ECAFMT='-f32_le,$CHANNELS,$RATE diff --git a/lib/dtas/trimfx.rb b/lib/dtas/trimfx.rb new file mode 100644 index 0000000..5cfac26 --- /dev/null +++ b/lib/dtas/trimfx.rb @@ -0,0 +1,67 @@ +# Copyright (C) 2013, Eric Wong and all contributors +# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) +require_relative '../dtas' +require 'shellwords' + +class DTAS::TrimFX + attr_reader :tbeg + attr_reader :tlen + + def initialize(args) + args = args.dup + case args.shift + when "trim" + parse_trim!(args) + when "all" + @tbeg = 0 + @tlen = nil + else + raise ArgumentError, "#{args.inspect} not understood" + end + end + + def to_sox_arg(format) + if @tbeg && @tlen + %W(trim #{@tbeg * format.rate}s #{@tlen * format.rate}s) + else + [] + end + end + + def parse_time(tbeg) + case tbeg + when /\A\d+\z/ + tbeg.to_i + when /\A[\d\.]+\z/ + tbeg.to_f + when /\A[:\d\.]+\z/ + hhmmss = tbeg.dup + rv = hhmmss.sub!(/\.(\d+)\z/, "") ? "0.#$1".to_f : 0 + + # deal with HH:MM:SS + t = hhmmss.split(/:/) + raise ArgumentError, "Bad time format: #{hhmmss}" if t.size > 3 + + mult = 1 + while part = t.pop + rv += part.to_i * mult + mult *= 60 + end + rv + else + raise ArgumentError, "unparseable: #{tbeg.inspect}" + end + end + + def parse_trim!(args) + tbeg = parse_time(args.shift) + tlen = args.shift + is_stop_time = tlen.sub!(/\A=/, "") ? true : false + tlen = parse_time(tlen) + if is_stop_time + tlen = tlen - tbeg + end + @tbeg = tbeg + @tlen = tlen + end +end diff --git a/test/test_trimfx.rb b/test/test_trimfx.rb new file mode 100644 index 0000000..107946f --- /dev/null +++ b/test/test_trimfx.rb @@ -0,0 +1,35 @@ +# Copyright (C) 2013, Eric Wong and all contributors +# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) +require './test/helper' +require 'dtas/trimfx' +require 'yaml' + +class TestTrimFX < Testcase + def test_example + ex = YAML.load(File.read("examples/trimfx.sample.yml")) + effects = [] + ex["effects"].each do |line| + words = Shellwords.split(line) + case words[0] + when "trim" + tfx = DTAS::TrimFX.new(words) + assert_equal 52.0, tfx.tbeg + assert_equal 1.0, tfx.tlen + effects << tfx + end + end + assert_equal 4, effects.size + end + + def test_all + tfx = DTAS::TrimFX.new(%w(all)) + assert_equal 0, tfx.tbeg + assert_nil tfx.tlen + end + + def test_time + tfx = DTAS::TrimFX.new(%w(trim 2:30 3.1)) + assert_equal 150, tfx.tbeg + assert_equal 3.1, tfx.tlen + end +end -- cgit v1.2.3-24-ge0c7