dtas 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/Documentation/.gitignore +1 -1
- data/Documentation/GNUmakefile +3 -1
- data/Documentation/dtas-archive.txt +61 -0
- data/Documentation/dtas-console.txt +4 -3
- data/Documentation/dtas-ctl.txt +4 -3
- data/Documentation/dtas-cueedit.txt +4 -3
- data/Documentation/dtas-enq.txt +4 -3
- data/Documentation/dtas-env.txt +60 -0
- data/Documentation/dtas-msinkctl.txt +4 -3
- data/Documentation/dtas-player.txt +6 -3
- data/Documentation/dtas-player_effects.txt +4 -3
- data/Documentation/dtas-player_protocol.txt +27 -4
- data/Documentation/dtas-player_sink_examples.txt +7 -3
- data/Documentation/dtas-sinkedit.txt +20 -3
- data/Documentation/dtas-sourceedit.txt +21 -3
- data/Documentation/dtas-splitfx.txt +14 -5
- data/Documentation/dtas-tl.txt +4 -3
- data/Documentation/dtas-xdelay.txt +4 -3
- data/Documentation/update-footer.rb +52 -0
- data/GIT-VERSION-GEN +2 -2
- data/GNUmakefile +1 -1
- data/HACKING +3 -2
- data/INSTALL +6 -6
- data/README +1 -1
- data/Rakefile +2 -3
- data/TODO +1 -1
- data/bin/dtas-archive +187 -0
- data/bin/dtas-console +7 -1
- data/bin/dtas-ctl +1 -1
- data/bin/dtas-cueedit +3 -3
- data/bin/dtas-enq +1 -1
- data/bin/dtas-msinkctl +1 -1
- data/bin/dtas-partstats +10 -4
- data/bin/dtas-player +1 -1
- data/bin/dtas-sinkedit +82 -20
- data/bin/dtas-sourceedit +64 -22
- data/bin/dtas-splitfx +1 -1
- data/bin/dtas-tl +1 -1
- data/bin/dtas-xdelay +1 -1
- data/dtas-linux.gemspec +1 -1
- data/dtas-mpris.gemspec +1 -1
- data/dtas.gemspec +1 -1
- data/examples/splitfx.sample.yml +11 -3
- data/examples/{trimfx.sample.yml → tfx.sample.yml} +1 -1
- data/lib/dtas.rb +2 -1
- data/lib/dtas/buffer.rb +5 -5
- data/lib/dtas/buffer/read_write.rb +8 -5
- data/lib/dtas/buffer/splice.rb +29 -8
- data/lib/dtas/command.rb +2 -2
- data/lib/dtas/compat_onenine.rb +1 -1
- data/lib/dtas/cue_index.rb +3 -1
- data/lib/dtas/disclaimer.rb +1 -1
- data/lib/dtas/edit_client.rb +1 -1
- data/lib/dtas/fadefx.rb +100 -0
- data/lib/dtas/format.rb +4 -2
- data/lib/dtas/parse_time.rb +3 -1
- data/lib/dtas/partstats.rb +8 -10
- data/lib/dtas/pipe.rb +2 -1
- data/lib/dtas/player.rb +33 -11
- data/lib/dtas/player/client_handler.rb +43 -8
- data/lib/dtas/process.rb +6 -14
- data/lib/dtas/replaygain.rb +3 -3
- data/lib/dtas/rg_state.rb +1 -1
- data/lib/dtas/serialize.rb +3 -1
- data/lib/dtas/sigevent.rb +1 -1
- data/lib/dtas/sigevent/efd.rb +5 -4
- data/lib/dtas/sigevent/pipe.rb +4 -1
- data/lib/dtas/sink.rb +4 -4
- data/lib/dtas/source.rb +1 -1
- data/lib/dtas/source/av.rb +2 -2
- data/lib/dtas/source/av_ff_common.rb +22 -11
- data/lib/dtas/source/cmd.rb +3 -3
- data/lib/dtas/source/common.rb +3 -2
- data/lib/dtas/source/ff.rb +2 -2
- data/lib/dtas/source/file.rb +22 -4
- data/lib/dtas/source/mp3gain.rb +1 -1
- data/lib/dtas/source/sox.rb +7 -7
- data/lib/dtas/source/splitfx.rb +99 -0
- data/lib/dtas/spawn_fix.rb +10 -0
- data/lib/dtas/splitfx.rb +63 -24
- data/lib/dtas/state_file.rb +3 -1
- data/lib/dtas/{trimfx.rb → tfx.rb} +50 -24
- data/lib/dtas/tracklist.rb +2 -1
- data/lib/dtas/unix_accepted.rb +2 -2
- data/lib/dtas/unix_client.rb +2 -2
- data/lib/dtas/unix_server.rb +1 -1
- data/lib/dtas/util.rb +1 -1
- data/lib/dtas/watchable.rb +54 -0
- data/lib/dtas/writable_iter.rb +2 -1
- data/lib/dtas/xs.rb +2 -2
- data/perl/dtas-graph +1 -1
- data/test/covshow.rb +1 -1
- data/test/helper.rb +1 -1
- data/test/player_integration.rb +1 -1
- data/test/test_buffer.rb +1 -1
- data/test/test_env.rb +1 -1
- data/test/test_fadefx.rb +45 -0
- data/test/test_format.rb +1 -1
- data/test/test_format_change.rb +1 -1
- data/test/test_player.rb +1 -1
- data/test/test_player_client_handler.rb +1 -1
- data/test/test_player_integration.rb +8 -8
- data/test/test_process.rb +1 -1
- data/test/test_rg_integration.rb +1 -1
- data/test/test_rg_state.rb +1 -1
- data/test/test_sink.rb +1 -1
- data/test/test_sink_pipe_size.rb +2 -2
- data/test/test_sink_tee_integration.rb +1 -1
- data/test/test_source_av.rb +1 -1
- data/test/test_source_sox.rb +1 -1
- data/test/test_splitfx.rb +43 -13
- data/test/test_tfx.rb +85 -0
- data/test/test_tracklist.rb +1 -1
- data/test/test_unixserver.rb +1 -1
- data/test/test_util.rb +1 -1
- metadata +17 -6
- data/lib/dtas/compat_rbx.rb +0 -12
- data/test/test_trimfx.rb +0 -81
@@ -1,8 +1,12 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
require_relative '../xs'
|
4
|
+
require_relative '../parse_time'
|
5
|
+
|
6
|
+
# client protocol handling for -player
|
4
7
|
module DTAS::Player::ClientHandler # :nodoc:
|
5
8
|
include DTAS::XS
|
9
|
+
include DTAS::ParseTime
|
6
10
|
|
7
11
|
# returns true on success, wait_ctl arg on error
|
8
12
|
def set_bool(io, kv, v)
|
@@ -69,7 +73,7 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
69
73
|
|
70
74
|
def __sink_activate(sink)
|
71
75
|
return if sink.pid
|
72
|
-
@targets.concat(sink.
|
76
|
+
@targets.concat(sink.sink_spawn(@format))
|
73
77
|
@targets.sort_by! { |t| t.sink.prio }
|
74
78
|
end
|
75
79
|
|
@@ -150,7 +154,7 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
150
154
|
rv = set_bool(io, kv, v) { |b| sink.__send__("#{k}=", b) }
|
151
155
|
rv == true or return rv
|
152
156
|
when "pipe_size"
|
153
|
-
rv = set_uint(io, kv, v,
|
157
|
+
rv = set_uint(io, kv, v, true) { |u| sink.pipe_size = u }
|
154
158
|
rv == true or return rv
|
155
159
|
when "command" # nothing to validate, this could be "rm -rf /" :>
|
156
160
|
sink.command = v.empty? ? DTAS::Sink::SINK_DEFAULTS["command"] : v
|
@@ -170,7 +174,7 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
170
174
|
io.emit("OK")
|
171
175
|
when "cat"
|
172
176
|
sink = @sinks[name] or return io.emit("ERR #{name} not found")
|
173
|
-
io.emit(sink.
|
177
|
+
io.emit(sink.to_hash.to_yaml)
|
174
178
|
else
|
175
179
|
io.emit("ERR unknown sink op #{msg[0]}")
|
176
180
|
end
|
@@ -181,6 +185,7 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
181
185
|
bytes = bytes < 0 ? 0 : bytes # maybe negative in case of sink errors
|
182
186
|
end
|
183
187
|
|
188
|
+
# returns seek offset as an Integer in sample count
|
184
189
|
def __seek_offset_adj(dir, offset)
|
185
190
|
if offset.sub!(/s\z/, '')
|
186
191
|
offset = offset.to_i
|
@@ -463,7 +468,11 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
463
468
|
def source_handler(io, msg)
|
464
469
|
map = @source_map
|
465
470
|
op = msg.shift
|
466
|
-
|
471
|
+
case op
|
472
|
+
when "restart"
|
473
|
+
__current_requeue
|
474
|
+
return io.emit("OK")
|
475
|
+
when "ls"
|
467
476
|
s = map.keys.sort { |a,b| map[a].tryorder <=> map[b].tryorder }
|
468
477
|
return io.emit(s.join(' '))
|
469
478
|
end
|
@@ -474,7 +483,7 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
474
483
|
when "cat"
|
475
484
|
io.emit(src.to_source_cat.to_yaml)
|
476
485
|
when "ed"
|
477
|
-
before = src.to_state_hash
|
486
|
+
before = src.to_state_hash.inspect
|
478
487
|
sd = src.source_defaults
|
479
488
|
msg.each do |kv|
|
480
489
|
k, v = kv.split(/=/, 2)
|
@@ -492,7 +501,7 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
492
501
|
source_map_reload
|
493
502
|
end
|
494
503
|
end
|
495
|
-
after = src.to_state_hash
|
504
|
+
after = src.to_state_hash.inspect
|
496
505
|
__current_requeue if before != after && @current.class == src.class
|
497
506
|
io.emit("OK")
|
498
507
|
else
|
@@ -526,7 +535,7 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
526
535
|
begin
|
527
536
|
sf.dump(self)
|
528
537
|
rescue => e
|
529
|
-
return io.emit("ERR dumping to #{xs(
|
538
|
+
return io.emit("ERR dumping to #{xs(dest)} #{e.message}")
|
530
539
|
end
|
531
540
|
end
|
532
541
|
io.emit("OK")
|
@@ -674,5 +683,31 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
674
683
|
io.emit("NOCUE")
|
675
684
|
end
|
676
685
|
end
|
686
|
+
|
687
|
+
def trim_handler(io, msg)
|
688
|
+
case msg.size
|
689
|
+
when 0
|
690
|
+
io.emit({ 'trim' => @trim }.to_yaml)
|
691
|
+
when 1, 2
|
692
|
+
case msg[0]
|
693
|
+
when 'off'
|
694
|
+
@trim = nil
|
695
|
+
else
|
696
|
+
begin
|
697
|
+
tbeg = parse_time(msg[0])
|
698
|
+
if tlen = msg[1]
|
699
|
+
absolute = tlen.sub!(/\A=/, '') # 44:00 =44:55
|
700
|
+
tlen = parse_time(tlen)
|
701
|
+
tlen -= tbeg if absolute
|
702
|
+
end
|
703
|
+
@trim = [ tbeg, tlen ] # seconds as float, since we don't know rate
|
704
|
+
rescue => e
|
705
|
+
return io.emit("ERR #{e.message}")
|
706
|
+
end
|
707
|
+
end
|
708
|
+
__current_requeue
|
709
|
+
io.emit('OK')
|
710
|
+
end
|
711
|
+
end
|
677
712
|
end
|
678
713
|
# :startdoc:
|
data/lib/dtas/process.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
require 'io/wait'
|
4
4
|
require_relative '../dtas'
|
5
5
|
require_relative 'xs'
|
6
6
|
|
7
|
+
# process management helpers
|
7
8
|
module DTAS::Process # :nodoc:
|
8
9
|
PIDS = {}
|
9
10
|
include DTAS::XS
|
11
|
+
include DTAS::SpawnFix
|
10
12
|
|
11
13
|
def self.reaper
|
12
14
|
begin
|
@@ -47,12 +49,7 @@ module DTAS::Process # :nodoc:
|
|
47
49
|
opts = { close_others: true, pgroup: true }.merge!(opts)
|
48
50
|
env = env_expand(env, opts)
|
49
51
|
|
50
|
-
pid =
|
51
|
-
Process.spawn(env, cmd, opts)
|
52
|
-
rescue Errno::EINTR
|
53
|
-
# workaround for older Rubies https://bugs.ruby-lang.org/issues/8770
|
54
|
-
retry
|
55
|
-
end
|
52
|
+
pid = spawn(env, cmd, opts)
|
56
53
|
warn [ :spawn, pid, cmd ].inspect if $DEBUG
|
57
54
|
@spawn_at = Time.now.to_f
|
58
55
|
PIDS[pid] = self
|
@@ -76,12 +73,7 @@ module DTAS::Process # :nodoc:
|
|
76
73
|
opts[:err] = we
|
77
74
|
end
|
78
75
|
env = env_expand(env, opts)
|
79
|
-
pid =
|
80
|
-
Process.spawn(env, *cmd, opts)
|
81
|
-
rescue Errno::EINTR
|
82
|
-
# workaround for older Rubies https://bugs.ruby-lang.org/issues/8770
|
83
|
-
retry
|
84
|
-
end
|
76
|
+
pid = spawn(env, *cmd, opts)
|
85
77
|
w.close
|
86
78
|
if err_str
|
87
79
|
we.close
|
@@ -107,6 +99,6 @@ module DTAS::Process # :nodoc:
|
|
107
99
|
_, status = Process.waitpid2(pid)
|
108
100
|
return res if status.success?
|
109
101
|
return status if no_raise
|
110
|
-
raise RuntimeError, "`#{xs(
|
102
|
+
raise RuntimeError, "`#{xs(cmd)}' failed: #{status.inspect}"
|
111
103
|
end
|
112
104
|
end
|
data/lib/dtas/replaygain.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
|
-
|
4
|
-
# Represents ReplayGain metadata for a DTAS::Source
|
3
|
+
|
4
|
+
# Represents ReplayGain metadata for a DTAS::Source, only used by -player
|
5
5
|
# cleanup/validate values to prevent malicious files from making us
|
6
6
|
# run arbitrary commands
|
7
7
|
# *_peak values are 0..inf (1.0 being full scale, but >1 is possible
|
data/lib/dtas/rg_state.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
#
|
4
4
|
# provides support for generating appropriate effects for ReplayGain
|
data/lib/dtas/serialize.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
|
+
|
4
|
+
# used to serialize player state to the state file
|
3
5
|
module DTAS::Serialize # :nodoc:
|
4
6
|
def ivars_to_hash(ivars, rv = {})
|
5
7
|
ivars.each { |k| rv[k] = instance_variable_get("@#{k}") }
|
data/lib/dtas/sigevent.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
begin
|
4
4
|
raise LoadError, "no eventfd with _DTAS_POSIX" if ENV["_DTAS_POSIX"]
|
data/lib/dtas/sigevent/efd.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
|
-
class DTAS::Sigevent < SleepyPenguin::EventFD # :nodoc:
|
4
|
-
include SleepyPenguin
|
5
3
|
|
4
|
+
# used in various places for safe wakeups from IO.select via signals
|
5
|
+
# This requires a modern Linux system and the "sleepy_penguin" RubyGem
|
6
|
+
class DTAS::Sigevent < SleepyPenguin::EventFD # :nodoc:
|
6
7
|
def self.new
|
7
|
-
super(0,
|
8
|
+
super(0, :CLOEXEC)
|
8
9
|
end
|
9
10
|
|
10
11
|
def signal
|
data/lib/dtas/sigevent/pipe.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
|
+
|
4
|
+
# used in various places for safe wakeups from IO.select via signals
|
5
|
+
# A fallback for non-Linux systems lacking the "sleepy_penguin" RubyGem
|
3
6
|
class DTAS::Sigevent # :nodoc:
|
4
7
|
attr_reader :to_io
|
5
8
|
|
data/lib/dtas/sink.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
require 'yaml'
|
4
4
|
require_relative '../dtas'
|
@@ -8,7 +8,7 @@ require_relative 'command'
|
|
8
8
|
require_relative 'format'
|
9
9
|
require_relative 'serialize'
|
10
10
|
|
11
|
-
# this is a sink (endpoint, audio enters but never leaves)
|
11
|
+
# this is a sink (endpoint, audio enters but never leaves), used by -player
|
12
12
|
class DTAS::Sink # :nodoc:
|
13
13
|
attr_accessor :prio # any Integer
|
14
14
|
attr_accessor :active # boolean
|
@@ -66,8 +66,8 @@ class DTAS::Sink # :nodoc:
|
|
66
66
|
super
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
70
|
-
raise "BUG: #{self.inspect}#
|
69
|
+
def sink_spawn(format, opts = {})
|
70
|
+
raise "BUG: #{self.inspect}#sink_spawn called twice" if @pid
|
71
71
|
rv = []
|
72
72
|
|
73
73
|
pclass = @nonblock ? DTAS::PipeNB : DTAS::Pipe
|
data/lib/dtas/source.rb
CHANGED
data/lib/dtas/source/av.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
require_relative '../../dtas'
|
4
4
|
require_relative 'av_ff_common'
|
@@ -10,7 +10,7 @@ class DTAS::Source::Av # :nodoc:
|
|
10
10
|
AV_DEFAULTS = COMMAND_DEFAULTS.merge(
|
11
11
|
"command" =>
|
12
12
|
'avconv -v error $SSPOS $PROBE -i "$INFILE" $AMAP -f sox - |' \
|
13
|
-
'sox -p $SOXFMT - $RGFX',
|
13
|
+
'sox -p $SOXFMT - $TRIMFX $RGFX',
|
14
14
|
|
15
15
|
# this is above ffmpeg because this av is the Debian default and
|
16
16
|
# it's easier for me to test av than ff
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
require_relative '../../dtas'
|
4
4
|
require_relative '../source'
|
@@ -19,8 +19,8 @@ module DTAS::Source::AvFfCommon # :nodoc:
|
|
19
19
|
attr_reader :precision # always 32
|
20
20
|
attr_reader :format
|
21
21
|
|
22
|
-
def try(infile, offset = nil)
|
23
|
-
rv = source_file_dup(infile, offset)
|
22
|
+
def try(infile, offset = nil, trim = nil)
|
23
|
+
rv = source_file_dup(infile, offset, trim)
|
24
24
|
rv.av_ff_ok? or return
|
25
25
|
rv
|
26
26
|
end
|
@@ -101,10 +101,20 @@ module DTAS::Source::AvFfCommon # :nodoc:
|
|
101
101
|
! @astreams.compact.empty?
|
102
102
|
end
|
103
103
|
|
104
|
-
def sspos
|
105
|
-
|
106
|
-
|
107
|
-
sprintf(
|
104
|
+
def sspos
|
105
|
+
return unless @offset || @trim
|
106
|
+
off = offset_samples / @format.rate.to_f
|
107
|
+
sprintf('-ss %0.9g', off)
|
108
|
+
end
|
109
|
+
|
110
|
+
def av_ff_trimfx # for sox
|
111
|
+
return unless @trim
|
112
|
+
tbeg, tlen = @trim # Floats
|
113
|
+
tend = tbeg + tlen
|
114
|
+
off = offset_samples / @format.rate.to_f
|
115
|
+
tlen = tend - off
|
116
|
+
tlen = 0 if tlen < 0
|
117
|
+
sprintf('trim 0 %0.9g', tlen)
|
108
118
|
end
|
109
119
|
|
110
120
|
def select_astream(as)
|
@@ -127,8 +137,8 @@ module DTAS::Source::AvFfCommon # :nodoc:
|
|
127
137
|
raise "BUG: no audio stream in #@infile"
|
128
138
|
end
|
129
139
|
|
130
|
-
def
|
131
|
-
raise "BUG: #{self.inspect}#
|
140
|
+
def src_spawn(player_format, rg_state, opts)
|
141
|
+
raise "BUG: #{self.inspect}#src_spawn called twice" if @to_io
|
132
142
|
amap = nil
|
133
143
|
|
134
144
|
# try to find an audio stream which matches our channel count
|
@@ -148,10 +158,11 @@ module DTAS::Source::AvFfCommon # :nodoc:
|
|
148
158
|
|
149
159
|
e["PROBE"] = @probe_harder ? @probe_harder.join(' ') : nil
|
150
160
|
# make sure these are visible to the source command...
|
151
|
-
e["INFILE"] = @infile
|
161
|
+
e["INFILE"] = xs(@infile)
|
152
162
|
e["AMAP"] = amap
|
153
|
-
e["SSPOS"] =
|
163
|
+
e["SSPOS"] = sspos
|
154
164
|
e["RGFX"] = rg_state.effect(self) || nil
|
165
|
+
e["TRIMFX"] = av_ff_trimfx
|
155
166
|
e.merge!(@rg.to_env) if @rg
|
156
167
|
|
157
168
|
@pid = dtas_spawn(e, command_string, opts)
|
data/lib/dtas/source/cmd.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
require_relative '../../dtas'
|
4
4
|
require_relative '../source'
|
@@ -31,8 +31,8 @@ class DTAS::Source::Cmd # :nodoc:
|
|
31
31
|
|
32
32
|
alias to_hsh to_hash
|
33
33
|
|
34
|
-
def
|
35
|
-
raise "BUG: #{self.inspect}#
|
34
|
+
def src_spawn(format, rg_state, opts)
|
35
|
+
raise "BUG: #{self.inspect}#src_spawn called twice" if @to_io
|
36
36
|
e = format.to_env
|
37
37
|
@pid = dtas_spawn(e.merge!(@env), command_string, opts)
|
38
38
|
end
|
data/lib/dtas/source/common.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
module DTAS::Source::Common # :nodoc:
|
4
|
-
attr_reader :dst_zero_byte
|
4
|
+
attr_reader :dst_zero_byte # first byte this source object saw
|
5
5
|
attr_reader :dst
|
6
6
|
attr_accessor :requeued
|
7
7
|
|
8
|
+
# buf - a DTAS::Buffer object (pipe)
|
8
9
|
def dst_assoc(buf)
|
9
10
|
@dst = buf
|
10
11
|
@dst_zero_byte = buf.bytes_xfer + buf.inflight
|
data/lib/dtas/source/ff.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
require_relative '../../dtas'
|
4
4
|
require_relative 'av_ff_common'
|
@@ -12,7 +12,7 @@ class DTAS::Source::Ff # :nodoc:
|
|
12
12
|
FF_DEFAULTS = COMMAND_DEFAULTS.merge(
|
13
13
|
"command" =>
|
14
14
|
'ffmpeg -v error $SSPOS $PROBE -i "$INFILE" $AMAP -f sox - |' \
|
15
|
-
'sox -p $SOXFMT - $RGFX',
|
15
|
+
'sox -p $SOXFMT - $TRIMFX $RGFX',
|
16
16
|
|
17
17
|
# I haven't tested this much since av is in Debian stable and ff is not
|
18
18
|
"tryorder" => 2,
|
data/lib/dtas/source/file.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
3
|
require_relative '../../dtas'
|
4
4
|
require_relative '../source'
|
@@ -21,17 +21,18 @@ module DTAS::Source::File # :nodoc:
|
|
21
21
|
FILE_SIVS = %w(infile comments command env) # for the "current" command
|
22
22
|
SRC_SIVS = %w(command env tryorder)
|
23
23
|
|
24
|
-
def source_file_dup(infile, offset)
|
24
|
+
def source_file_dup(infile, offset, trim)
|
25
25
|
rv = dup
|
26
|
-
rv.__file_init(infile, offset)
|
26
|
+
rv.__file_init(infile, offset, trim)
|
27
27
|
rv
|
28
28
|
end
|
29
29
|
|
30
|
-
def __file_init(infile, offset)
|
30
|
+
def __file_init(infile, offset, trim)
|
31
31
|
@env = @env.dup
|
32
32
|
@format = nil
|
33
33
|
@infile = infile
|
34
34
|
@offset = offset
|
35
|
+
@trim = trim
|
35
36
|
@comments = nil
|
36
37
|
@samples = nil
|
37
38
|
@cuebp = nil
|
@@ -47,6 +48,13 @@ module DTAS::Source::File # :nodoc:
|
|
47
48
|
# returns any offset in samples (relative to the original source file),
|
48
49
|
# likely zero unless seek was used
|
49
50
|
def offset_samples
|
51
|
+
off = __offset_samples
|
52
|
+
return off unless @trim
|
53
|
+
tbeg = @trim[0] * format.rate
|
54
|
+
tbeg < off ? off : tbeg
|
55
|
+
end
|
56
|
+
|
57
|
+
def __offset_samples
|
50
58
|
return 0 unless @offset
|
51
59
|
case @offset
|
52
60
|
when /\A\d+s\z/
|
@@ -56,6 +64,16 @@ module DTAS::Source::File # :nodoc:
|
|
56
64
|
end
|
57
65
|
end
|
58
66
|
|
67
|
+
# creates the effect to fill the TRIMFX env
|
68
|
+
def trimfx
|
69
|
+
return unless @offset || @trim
|
70
|
+
fx = "trim #{offset_samples}s"
|
71
|
+
if @trim && @trim[1]
|
72
|
+
fx << sprintf(' =%0.9gs', (@trim[0] + @trim[1]) * format.rate)
|
73
|
+
end
|
74
|
+
fx
|
75
|
+
end
|
76
|
+
|
59
77
|
# A user may be downloading the file and start playing
|
60
78
|
# it before the download completes, this refreshes
|
61
79
|
def samples!
|