From 74350addbafab84f016145323d6c37506d374d64 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 27 Jan 2015 01:20:06 +0000 Subject: fadefx: effects chain generation We need to generate a coherent command set for wrapping portions together, this sets us up for that. --- lib/dtas/fadefx.rb | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/dtas/format.rb | 1 + test/test_fadefx.rb | 17 ++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/lib/dtas/fadefx.rb b/lib/dtas/fadefx.rb index d67f896..899505b 100644 --- a/lib/dtas/fadefx.rb +++ b/lib/dtas/fadefx.rb @@ -2,7 +2,9 @@ # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) require_relative '../dtas' require_relative 'parse_time' +require_relative 'xs' +# note: This is sox-specific # --------- time ---------> # _____ _______ ______ # \ / \ / @@ -15,6 +17,7 @@ require_relative 'parse_time' # in_next - controls the upward slope into next class DTAS::FadeFX # :nodoc: include DTAS::ParseTime + include DTAS::XS attr_reader :out_prev, :in_cur, :out_cur, :in_next F = Struct.new(:type, :flen) @@ -28,6 +31,59 @@ class DTAS::FadeFX # :nodoc: end end + def fade_cur_fx(format, tbeg, tlen, args = []) + fx = %W(trim #{tbeg}s #{tlen}s) + fx.concat(args) + if @in_cur && @out_cur && @in_cur.type == @out_cur.type + f = %W(fade #{@in_cur.type} #{@in_cur.flen} #{tlen}s #{@out_cur.flen}) + fx.concat(f) + else # differing fade types for in/out, chain them: + fpart = @in_cur and + fx.concat(%W(fade #{fpart.type} #{fpart.flen} 0 0)) + fpart = @out_cur and + fx.concat(%W(fade #{fpart.type} 0 #{tlen}s #{fpart.flen})) + end + fx + end + + def fade_out_prev_fx(format, tbeg, tlen) + fx = %W(trim #{tbeg}s) + + if fpart = @out_prev + out_len = format.hhmmss_to_samples(fpart.flen) + fx.concat(%W(fade #{fpart.type} 0 #{out_len}s #{out_len}s)) + remain = tlen - out_len + + # fade-out is longer than tlen, so truncate again: + remain < 0 and fx.concat(%W(trim 0 #{tlen}s)) + + # pad with silence, this is where fade_cur_fx goes + remain > 0 and fx.concat(%W(pad #{remain}s@#{out_len}s)) + end + fx + end + + def fade_in_next_fx(format, tbeg, tlen) + fpart = @in_next + flen = fpart ? fpart.flen : 0 + nlen = format.hhmmss_to_samples(flen) + nbeg = tbeg + tlen - nlen + npad = nbeg - tbeg + if npad < 0 + warn("in_next should not exceed range: #{inspect} @trim " \ + "#{tbeg}s #{tlen}s\nclamping to #{tbeg}") + nbeg = tbeg + end + + fx = %W(trim #{nbeg}s #{nlen}s) + nlen != 0 and + fx.concat(%W(fade #{fpart.type} #{nlen}s 0 0)) + + # likely, the pad section is where fade_cur_fx goes + npad > 0 and fx.concat(%W(pad #{npad}s@0s)) + fx + end + # q - quarter of a sine wave # h - half a sine wave # t - linear (`triangular') slope diff --git a/lib/dtas/format.rb b/lib/dtas/format.rb index a76b893..a6314bd 100644 --- a/lib/dtas/format.rb +++ b/lib/dtas/format.rb @@ -165,6 +165,7 @@ class DTAS::Format # :nodoc: # HH:MM:SS.frac (don't bother with more complex times, too much code) # part of me wants to drop this feature from playq, feels like bloat... def hhmmss_to_samples(hhmmss) + Numeric === hhmmss and return hhmmss * @rate time = hhmmss.dup rv = 0 if time.sub!(/\.(\d+)\z/, "") diff --git a/test/test_fadefx.rb b/test/test_fadefx.rb index 942a4b6..5c84578 100644 --- a/test/test_fadefx.rb +++ b/test/test_fadefx.rb @@ -2,6 +2,7 @@ # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) require_relative 'helper' require 'dtas/fadefx' +require 'dtas/format' class TestFadeFX < Testcase def test_fadefx @@ -14,6 +15,22 @@ class TestFadeFX < Testcase assert_equal 4, ffx.out_cur.flen assert_equal 't', ffx.in_next.type assert_equal 1, ffx.in_next.flen + + fmt = DTAS::Format.new + fmt.rate = 48000 + tbeg = 0 + tlen = 48000 * 9 + + # XXX: this isn't testing much... + cur = ffx.fade_cur_fx(fmt, tbeg, tlen, %w(vol +3dB)) + assert_equal(%w(trim 0s 432000s vol +3dB + fade t 3.1 0 0 fade l 0 432000s 4), cur) + out = ffx.fade_out_prev_fx(fmt, tbeg, tlen) + assert_equal(%w(trim 0s + fade t 0 48000s 48000s pad 384000s@48000s), out) + inn = ffx.fade_in_next_fx(fmt, tbeg, tlen) + assert_equal(%w(trim 384000s 48000s + fade t 48000s 0 0 pad 384000s@0s), inn) end def test_fadefx_no_cur -- cgit v1.2.3-24-ge0c7