diff options
author | Eric Wong <normalperson@yhbt.net> | 2014-06-23 07:21:30 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2014-06-23 08:03:21 +0000 |
commit | 34a5c2c0ae02d261191442acc3907f2346bf2f95 (patch) | |
tree | 68214c227edebf96d83f5fbb1841da861e4a068d | |
parent | a92c8d37a094d76b2b8b691dd6cd9732011d37b3 (diff) | |
download | dtas-34a5c2c0ae02d261191442acc3907f2346bf2f95.tar.gz |
The names are subject to change, but the idea is to make multiple passes over the audio if effects overlap and combine everything afterwards. Unedited portions will be passed through sox (via trim and no other effects)
-rw-r--r-- | lib/dtas/trimfx.rb | 62 | ||||
-rw-r--r-- | test/test_trimfx.rb | 31 |
2 files changed, 93 insertions, 0 deletions
diff --git a/lib/dtas/trimfx.rb b/lib/dtas/trimfx.rb index 94ccd7a..391bbc2 100644 --- a/lib/dtas/trimfx.rb +++ b/lib/dtas/trimfx.rb @@ -75,4 +75,66 @@ class DTAS::TrimFX @tbeg = tbeg @tlen = tlen end + + def <=>(other) + tbeg <=> other.tbeg + end + + # for stable sorting + class TFXSort < Struct.new(:tfx, :idx) + def <=>(other) + cmp = tfx <=> other.tfx + 0 == cmp ? idx <=> other.idx : cmp + end + end + + # there'll be multiple epochs if ranges overlap + def self.schedule(ary) + sorted = [] + ary.each_with_index { |tfx, i| sorted << TFXSort[tfx, i] } + sorted.sort! + rv = [] + epoch = 0 + prev_end = 0 + defer = [] + begin + while tfxsort = sorted.shift + tfx = tfxsort.tfx + if tfx.tbeg >= prev_end + prev_end = tfx.tbeg + tfx.tlen + (rv[epoch] ||= []) << tfx + else + defer << tfxsort + end + end + if defer[0] + epoch += 1 + sorted = defer + defer = [] + prev_end = 0 + end + end while sorted[0] + rv + end + + def self.expand(ary, total_len) + rv = [] + schedule(ary).each_with_index do |sary, i| + tip = 0 + dst = rv[i] = [] + while tfx = sary.shift + if tfx.tbeg > tip + nfx = new(%W(trim #{tip} =#{tfx.tbeg})) + dst << nfx + dst << tfx + tip = tfx.tbeg + tfx.tlen + end + end + if tip < total_len + nfx = new(%W(trim #{tip} =#{total_len})) + dst << nfx + end + end + rv + end end diff --git a/test/test_trimfx.rb b/test/test_trimfx.rb index ff40594..3a3bdc0 100644 --- a/test/test_trimfx.rb +++ b/test/test_trimfx.rb @@ -47,4 +47,35 @@ class TestTrimFX < Testcase tfx = DTAS::TrimFX.new(%w(trim 1 sox vol -1dB)) assert_equal %w(sox $SOXIN $SOXOUT $TRIMFX vol -1dB $FADEFX), tfx.cmd end + + def test_schedule_simple + fx = [ + DTAS::TrimFX.new(%w(trim 1 0.3)), + DTAS::TrimFX.new(%w(trim 2 0.2)), + DTAS::TrimFX.new(%w(trim 0.5 0.5)), + ].shuffle + ary = DTAS::TrimFX.schedule(fx) + assert_operator 1, :==, ary.size + assert_equal [ 0.5, 1, 2 ], ary[0].map(&:tbeg) + assert_equal [ 0.5, 0.3, 0.2 ], ary[0].map(&:tlen) + end + + def test_schedule_overlaps + fx = [ + DTAS::TrimFX.new(%w(trim 1 0.3 sox)), + DTAS::TrimFX.new(%w(trim 1.1 0.2 sox)), + DTAS::TrimFX.new(%w(trim 0.5 0.5 sox)), + ] + ary = DTAS::TrimFX.schedule(fx) + assert_equal 2, ary.size + assert_equal [ 0.5, 1 ], ary[0].map(&:tbeg) + assert_equal [ 1.1 ], ary[1].map(&:tbeg) + + ex = DTAS::TrimFX.expand(fx, 10) + assert_equal 2, ex.size + assert_equal 0, ex[0][0].tbeg + assert_equal 3, ex[0].size + assert_equal 0, ex[1][0].tbeg + assert_equal 3, ex[1].size + end end |