dtas 0.17.0 → 0.20.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 +1 -1
- data/Documentation/dtas-archive.pod +1 -1
- data/Documentation/dtas-console.pod +1 -1
- data/Documentation/dtas-ctl.pod +1 -1
- data/Documentation/dtas-cueedit.pod +1 -1
- data/Documentation/dtas-enq.pod +1 -1
- data/Documentation/dtas-env.pod +1 -1
- data/Documentation/dtas-msinkctl.pod +1 -1
- data/Documentation/dtas-player.pod +1 -1
- data/Documentation/dtas-player_effects.pod +1 -1
- data/Documentation/dtas-player_protocol.pod +1 -1
- data/Documentation/dtas-player_sink_examples.pod +1 -1
- data/Documentation/dtas-sinkedit.pod +2 -2
- data/Documentation/dtas-sourceedit.pod +2 -2
- data/Documentation/dtas-splitfx.pod +42 -9
- data/Documentation/dtas-tl.pod +3 -1
- data/Documentation/dtas-xdelay.pod +1 -1
- data/Documentation/update-footer.rb +1 -1
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +2 -2
- data/GNUmakefile +13 -1
- data/HACKING +1 -1
- data/INSTALL +17 -25
- data/NEWS +121 -0
- data/README +13 -7
- data/Rakefile +1 -1
- data/TODO +1 -1
- data/bin/dtas-archive +7 -3
- data/bin/dtas-console +49 -16
- data/bin/dtas-ctl +1 -1
- data/bin/dtas-cueedit +1 -1
- data/bin/dtas-enq +1 -1
- data/bin/dtas-mlib +1 -1
- data/bin/dtas-msinkctl +2 -3
- data/bin/dtas-partstats +3 -9
- data/bin/dtas-player +1 -2
- data/bin/dtas-readahead +11 -25
- data/bin/dtas-sinkedit +3 -4
- data/bin/dtas-sourceedit +3 -4
- data/bin/dtas-splitfx +17 -5
- data/bin/dtas-tl +32 -27
- data/bin/dtas-xdelay +1 -1
- data/dtas-linux.gemspec +1 -1
- data/dtas-mpris.gemspec +1 -1
- data/dtas.gemspec +3 -3
- data/dtas.sh +8 -0
- data/examples/splitfx.sample.yml +1 -1
- data/examples/tfx.sample.yml +1 -1
- data/lib/dtas/buffer/fiddle_splice.rb +217 -0
- data/lib/dtas/buffer/read_write.rb +3 -4
- data/lib/dtas/buffer/splice.rb +5 -2
- data/lib/dtas/buffer.rb +11 -8
- data/lib/dtas/command.rb +1 -1
- data/lib/dtas/cue_index.rb +1 -1
- data/lib/dtas/disclaimer.rb +1 -1
- data/lib/dtas/edit_client.rb +2 -3
- data/lib/dtas/encoding.rb +8 -9
- data/lib/dtas/fadefx.rb +2 -2
- data/lib/dtas/format.rb +1 -1
- data/lib/dtas/mcache.rb +14 -3
- data/lib/dtas/mlib/migrations/0001_initial.rb +1 -1
- data/lib/dtas/mlib.rb +23 -13
- data/lib/dtas/parse_freq.rb +1 -1
- data/lib/dtas/parse_time.rb +1 -1
- data/lib/dtas/partstats.rb +3 -5
- data/lib/dtas/pipe.rb +14 -11
- data/lib/dtas/pipeline.rb +1 -4
- data/lib/dtas/player/client_handler.rb +25 -17
- data/lib/dtas/player.rb +6 -12
- data/lib/dtas/process.rb +3 -5
- data/lib/dtas/replaygain.rb +1 -1
- data/lib/dtas/rg_state.rb +2 -2
- data/lib/dtas/serialize.rb +1 -1
- data/lib/dtas/sigevent/efd.rb +3 -1
- data/lib/dtas/sigevent/fiddle_efd.rb +37 -0
- data/lib/dtas/sigevent/pipe.rb +3 -4
- data/lib/dtas/sigevent.rb +6 -3
- data/lib/dtas/sink.rb +1 -2
- data/lib/dtas/source/av.rb +1 -1
- data/lib/dtas/source/av_ff_common.rb +4 -4
- data/lib/dtas/source/cmd.rb +1 -1
- data/lib/dtas/source/common.rb +1 -1
- data/lib/dtas/source/ff.rb +1 -1
- data/lib/dtas/source/file.rb +1 -1
- data/lib/dtas/source/mp3gain.rb +1 -1
- data/lib/dtas/source/sox.rb +4 -4
- data/lib/dtas/source/splitfx.rb +2 -3
- data/lib/dtas/source.rb +1 -1
- data/lib/dtas/splitfx.rb +22 -10
- data/lib/dtas/state_file.rb +2 -2
- data/lib/dtas/tfx.rb +1 -1
- data/lib/dtas/track.rb +2 -2
- data/lib/dtas/tracklist.rb +1 -1
- data/lib/dtas/unix_accepted.rb +12 -37
- data/lib/dtas/unix_client.rb +2 -2
- data/lib/dtas/unix_server.rb +2 -14
- data/lib/dtas/util.rb +1 -1
- data/lib/dtas/version.rb +1 -1
- data/lib/dtas/watchable/fiddle_ino.rb +78 -0
- data/lib/dtas/watchable/inotify.rb +13 -0
- data/lib/dtas/watchable.rb +58 -58
- data/lib/dtas/writable_iter.rb +1 -1
- data/lib/dtas/xs.rb +1 -1
- data/lib/dtas.rb +13 -21
- data/man/dtas-archive.1 +2 -2
- data/man/dtas-console.1 +2 -2
- data/man/dtas-ctl.1 +2 -2
- data/man/dtas-cueedit.1 +2 -2
- data/man/dtas-enq.1 +2 -2
- data/man/dtas-env.7 +2 -2
- data/man/dtas-msinkctl.1 +2 -2
- data/man/dtas-player.1 +2 -2
- data/man/dtas-player_effects.7 +2 -2
- data/man/dtas-player_protocol.7 +2 -2
- data/man/dtas-player_sink_examples.7 +2 -2
- data/man/dtas-sinkedit.1 +3 -3
- data/man/dtas-sourceedit.1 +3 -3
- data/man/dtas-splitfx.1 +43 -13
- data/man/dtas-tl.1 +4 -2
- data/man/dtas-xdelay.1 +2 -2
- data/{perl → script}/dtas-graph +1 -1
- data/setup.rb +1 -2
- data/test/covshow.rb +1 -1
- data/test/helper.rb +1 -1
- data/test/player_integration.rb +1 -2
- data/test/test_buffer.rb +8 -8
- data/test/test_encoding.rb +2 -3
- data/test/test_env.rb +1 -1
- data/test/test_fadefx.rb +1 -1
- data/test/test_format.rb +1 -1
- data/test/test_format_change.rb +2 -2
- data/test/test_mcache.rb +15 -5
- data/test/test_mlib.rb +1 -1
- data/test/test_parse_freq.rb +1 -1
- data/test/test_pipeline.rb +1 -1
- data/test/test_player.rb +1 -1
- data/test/test_player_client_handler.rb +2 -2
- data/test/test_player_integration.rb +7 -8
- data/test/test_process.rb +1 -1
- data/test/test_rg_integration.rb +9 -9
- data/test/test_rg_state.rb +1 -1
- data/test/test_sigevent.rb +20 -0
- data/test/test_sink.rb +2 -2
- data/test/test_sink_pipe_size.rb +13 -16
- 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 +2 -5
- data/test/test_tfx.rb +2 -3
- data/test/test_tracklist.rb +1 -1
- data/test/test_unixserver.rb +2 -2
- data/test/test_util.rb +1 -1
- metadata +11 -8
- data/lib/dtas/compat_onenine.rb +0 -17
- data/lib/dtas/nonblock.rb +0 -24
- data/lib/dtas/spawn_fix.rb +0 -10
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
require_relative '../xs'
|
@@ -135,7 +135,7 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
135
135
|
# or variable names.
|
136
136
|
sink.valid_name?(name) or return io.emit("ERR sink name invalid")
|
137
137
|
|
138
|
-
sink.name =
|
138
|
+
sink.name = -name
|
139
139
|
active_before = sink.active
|
140
140
|
before = __sink_snapshot(sink)
|
141
141
|
|
@@ -144,7 +144,7 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
144
144
|
k, v = kv.split('=', 2)
|
145
145
|
case k
|
146
146
|
when %r{\Aenv\.([^=]+)\z}
|
147
|
-
sink.env[
|
147
|
+
sink.env[$1] = v
|
148
148
|
when %r{\Aenv#([^=]+)\z}
|
149
149
|
v == nil or return io.emit("ERR unset env has no value")
|
150
150
|
sink.env.delete($1)
|
@@ -197,19 +197,20 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
197
197
|
end
|
198
198
|
end
|
199
199
|
|
200
|
+
def __offset_to_i(offset, src)
|
201
|
+
# either "999s" for 999 samples or HH:MM:SS for time
|
202
|
+
offset.sub!(/s\z/, '') ? offset.to_i : src.format.hhmmss_to_samples(offset)
|
203
|
+
end
|
204
|
+
|
200
205
|
def __offset_to_samples(offset)
|
201
|
-
offset
|
202
|
-
@current.format.hhmmss_to_samples(offset)
|
206
|
+
__offset_to_i(offset, @current)
|
203
207
|
end
|
204
208
|
|
205
209
|
# returns seek offset as an Integer in sample count
|
206
|
-
def __seek_offset_adj(dir, offset
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
offset = @current.format.hhmmss_to_samples(offset)
|
211
|
-
end
|
212
|
-
n = __current_decoded_samples + (dir * offset)
|
210
|
+
def __seek_offset_adj(dir, offset,
|
211
|
+
src = @current,
|
212
|
+
current_decoded_samples = __current_decoded_samples)
|
213
|
+
n = current_decoded_samples + (dir * __offset_to_i(offset, src))
|
213
214
|
n = 0 if n < 0
|
214
215
|
"#{n}s"
|
215
216
|
end
|
@@ -391,15 +392,17 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
391
392
|
end
|
392
393
|
end
|
393
394
|
|
395
|
+
def __offset_direction(offset)
|
396
|
+
offset.sub!(/\A\+/, '') ? 1 : (offset.sub!(/\A-/, '') ? -1 : nil)
|
397
|
+
end
|
398
|
+
|
394
399
|
def dpc_seek(io, msg)
|
395
400
|
offset = msg[0] or return io.emit('ERR usage: seek OFFSET')
|
396
401
|
if @current
|
397
402
|
if @current.respond_to?(:infile)
|
398
403
|
begin
|
399
|
-
if offset
|
400
|
-
offset = __seek_offset_adj(
|
401
|
-
elsif offset.sub!(/\A-/, '')
|
402
|
-
offset = __seek_offset_adj(-1, offset)
|
404
|
+
if direction = __offset_direction(offset)
|
405
|
+
offset = __seek_offset_adj(direction, offset)
|
403
406
|
# else: pass to sox directly
|
404
407
|
end
|
405
408
|
rescue ArgumentError
|
@@ -413,7 +416,12 @@ module DTAS::Player::ClientHandler # :nodoc:
|
|
413
416
|
case file = @queue[0]
|
414
417
|
when String
|
415
418
|
@queue[0] = [ file, offset ]
|
416
|
-
when Array
|
419
|
+
when Array # offset already stored, adjust
|
420
|
+
if direction = __offset_direction(offset)
|
421
|
+
tmp = try_file(*file)
|
422
|
+
cur_off = __offset_to_i(file[1].dup, tmp)
|
423
|
+
offset = __seek_offset_adj(direction, offset, tmp, cur_off)
|
424
|
+
end
|
417
425
|
file[1] = offset
|
418
426
|
else
|
419
427
|
return io.emit("ERR unseekable")
|
data/lib/dtas/player.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
|
-
require 'yaml'
|
5
4
|
require 'shellwords'
|
5
|
+
require 'yaml'
|
6
6
|
require_relative '../dtas'
|
7
7
|
require_relative 'xs'
|
8
8
|
require_relative 'source'
|
@@ -123,10 +123,6 @@ class DTAS::Player # :nodoc:
|
|
123
123
|
rv
|
124
124
|
end
|
125
125
|
|
126
|
-
def to_omap(hash)
|
127
|
-
YAML::Omap === hash ? hash : YAML::Omap.new.merge!(hash)
|
128
|
-
end
|
129
|
-
|
130
126
|
def self.load(hash)
|
131
127
|
rv = new
|
132
128
|
rv.instance_eval do
|
@@ -157,7 +153,6 @@ class DTAS::Player # :nodoc:
|
|
157
153
|
@source_map.each do |name, src|
|
158
154
|
src_hsh = v[name] or next
|
159
155
|
src.load!(src_hsh)
|
160
|
-
src.env = to_omap(src.env)
|
161
156
|
end
|
162
157
|
source_map_reload
|
163
158
|
end
|
@@ -168,9 +163,8 @@ class DTAS::Player # :nodoc:
|
|
168
163
|
|
169
164
|
if sinks = hash["sinks"]
|
170
165
|
sinks.each do |sink_hsh|
|
171
|
-
sink_hsh['name'] =
|
166
|
+
sink_hsh['name'] = -sink_hsh['name']
|
172
167
|
sink = DTAS::Sink.load(sink_hsh)
|
173
|
-
sink.env = to_omap(sink.env)
|
174
168
|
@sinks[sink.name] = sink
|
175
169
|
end
|
176
170
|
end
|
@@ -208,13 +202,13 @@ class DTAS::Player # :nodoc:
|
|
208
202
|
command = msg.shift
|
209
203
|
case command
|
210
204
|
when "enq"
|
211
|
-
enq_handler(io, msg[0])
|
205
|
+
enq_handler(io, -msg[0])
|
212
206
|
when "enq-cmd"
|
213
|
-
enq_handler(io, { "command" => msg[0]})
|
207
|
+
enq_handler(io, { "command" => -msg[0]})
|
214
208
|
when "pause", "play", "play_pause"
|
215
209
|
play_pause_handler(io, command)
|
216
210
|
when "pwd"
|
217
|
-
io.emit(Dir.pwd)
|
211
|
+
io.emit(-Dir.pwd)
|
218
212
|
else
|
219
213
|
m = "dpc_#{command.tr('-', '_')}"
|
220
214
|
__send__(m, io, msg) if respond_to?(m)
|
data/lib/dtas/process.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
require 'io/wait'
|
5
5
|
require 'shellwords'
|
6
6
|
require_relative '../dtas'
|
7
7
|
require_relative 'xs'
|
8
|
-
require_relative 'nonblock'
|
9
8
|
|
10
9
|
# process management helpers
|
11
10
|
module DTAS::Process # :nodoc:
|
12
11
|
PIDS = {}
|
13
12
|
include DTAS::XS
|
14
|
-
include DTAS::SpawnFix
|
15
13
|
|
16
14
|
def self.reaper
|
17
15
|
begin
|
@@ -89,12 +87,12 @@ module DTAS::Process # :nodoc:
|
|
89
87
|
env = {}
|
90
88
|
end
|
91
89
|
buf = ''.b
|
92
|
-
r, w =
|
90
|
+
r, w = IO.pipe
|
93
91
|
opts = opts.merge(out: w)
|
94
92
|
r.binmode
|
95
93
|
no_raise = opts.delete(:no_raise)
|
96
94
|
if err_str = opts.delete(:err_str)
|
97
|
-
re, we =
|
95
|
+
re, we = IO.pipe
|
98
96
|
re.binmode
|
99
97
|
opts[:err] = we
|
100
98
|
end
|
data/lib/dtas/replaygain.rb
CHANGED
data/lib/dtas/rg_state.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
#
|
@@ -72,7 +72,7 @@ class DTAS::RGState # :nodoc:
|
|
72
72
|
when 1 then return 'gain 192'
|
73
73
|
else
|
74
74
|
val.abs <= 0.00000001 and return
|
75
|
-
|
75
|
+
-sprintf('gain %0.8f', val)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
data/lib/dtas/serialize.rb
CHANGED
data/lib/dtas/sigevent/efd.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2020 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
|
4
4
|
# used in various places for safe wakeups from IO.select via signals
|
5
5
|
# This requires a modern Linux system and the "sleepy_penguin" RubyGem
|
6
|
+
require 'sleepy_penguin'
|
7
|
+
|
6
8
|
class DTAS::Sigevent < SleepyPenguin::EventFD # :nodoc:
|
7
9
|
def self.new
|
8
10
|
super(0, :CLOEXEC)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
|
+
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
# used in various places for safe wakeups from IO.select via signals
|
6
|
+
# This requires a modern GNU/Linux system with eventfd(2) support
|
7
|
+
require 'fiddle'
|
8
|
+
class DTAS::Sigevent # :nodoc:
|
9
|
+
|
10
|
+
EventFD = Fiddle::Function.new(DTAS.libc['eventfd'],
|
11
|
+
[ Fiddle::TYPE_INT, Fiddle::TYPE_INT ], # initval, flags
|
12
|
+
Fiddle::TYPE_INT) # fd
|
13
|
+
|
14
|
+
attr_reader :to_io
|
15
|
+
ONE = -([ 1 ].pack('Q'))
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
fd = EventFD.call(0, 02000000|00004000) # EFD_CLOEXEC|EFD_NONBLOCK
|
19
|
+
raise "eventfd failed: #{Fiddle.last_error}" if fd < 0
|
20
|
+
@to_io = IO.for_fd(fd)
|
21
|
+
@buf = ''.b
|
22
|
+
end
|
23
|
+
|
24
|
+
def signal
|
25
|
+
@to_io.syswrite(ONE)
|
26
|
+
end
|
27
|
+
|
28
|
+
def readable_iter
|
29
|
+
@to_io.read_nonblock(8, @buf, exception: false)
|
30
|
+
yield self, nil # calls DTAS::Process.reaper
|
31
|
+
:wait_readable
|
32
|
+
end
|
33
|
+
|
34
|
+
def close
|
35
|
+
@to_io.close
|
36
|
+
end
|
37
|
+
end
|
data/lib/dtas/sigevent/pipe.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
5
|
# used in various places for safe wakeups from IO.select via signals
|
6
|
-
# A fallback for non-Linux systems lacking the "
|
7
|
-
require_relative '../nonblock'
|
6
|
+
# A fallback for non-Linux systems lacking the "splice" syscall
|
8
7
|
class DTAS::Sigevent # :nodoc:
|
9
8
|
attr_reader :to_io
|
10
9
|
|
11
10
|
def initialize
|
12
|
-
@to_io, @wr =
|
11
|
+
@to_io, @wr = IO.pipe
|
13
12
|
@rbuf = ''.b
|
14
13
|
end
|
15
14
|
|
data/lib/dtas/sigevent.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2020 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
begin
|
5
5
|
raise LoadError, "no eventfd with _DTAS_POSIX" if ENV["_DTAS_POSIX"]
|
6
|
-
|
7
|
-
|
6
|
+
begin
|
7
|
+
require_relative 'sigevent/efd'
|
8
|
+
rescue LoadError
|
9
|
+
require_relative 'sigevent/fiddle_efd'
|
10
|
+
end
|
8
11
|
rescue LoadError
|
9
12
|
require_relative 'sigevent/pipe'
|
10
13
|
end
|
data/lib/dtas/sink.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
|
-
require 'yaml'
|
5
4
|
require_relative '../dtas'
|
6
5
|
require_relative 'pipe'
|
7
6
|
require_relative 'process'
|
data/lib/dtas/source/av.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
require_relative '../../dtas'
|
@@ -110,7 +110,7 @@ module DTAS::Source::AvFfCommon # :nodoc:
|
|
110
110
|
f =~ /^duration=([\d\.]+)\s*$/nm and @duration = $1.to_f
|
111
111
|
# TODO: multi-line/multi-value/repeated tags
|
112
112
|
f.gsub!(/^TAG:([^=]+)=(.*)$/ni) { |_|
|
113
|
-
@comments[
|
113
|
+
@comments[$1.upcase] = -($2)
|
114
114
|
}
|
115
115
|
end
|
116
116
|
|
@@ -118,7 +118,7 @@ module DTAS::Source::AvFfCommon # :nodoc:
|
|
118
118
|
s.scan(%r{^\[format\.tags\]\n(.*?)\n\n}m) do |_|
|
119
119
|
f = $1.dup
|
120
120
|
f.gsub!(/^([^=]+)=(.*)$/ni) { |_|
|
121
|
-
@comments[
|
121
|
+
@comments[$1.upcase] = -$2
|
122
122
|
}
|
123
123
|
end
|
124
124
|
s.scan(%r{^\[format\]\n(.*?)\n\n}m) do |_|
|
@@ -186,7 +186,7 @@ module DTAS::Source::AvFfCommon # :nodoc:
|
|
186
186
|
|
187
187
|
e["PROBE"] = @probe_harder ? @probe_harder.join(' ') : nil
|
188
188
|
# make sure these are visible to the source command...
|
189
|
-
e["INFILE"] =
|
189
|
+
e["INFILE"] = @infile
|
190
190
|
e["AMAP"] = amap
|
191
191
|
e["SSPOS"] = sspos
|
192
192
|
e["RGFX"] = rg_state.effect(self) || nil
|
data/lib/dtas/source/cmd.rb
CHANGED
data/lib/dtas/source/common.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2013-
|
1
|
+
# Copyright (C) 2013-2020 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
module DTAS::Source::Common # :nodoc:
|
4
4
|
attr_reader :dst_zero_byte # first byte this source object saw
|
data/lib/dtas/source/ff.rb
CHANGED
data/lib/dtas/source/file.rb
CHANGED
data/lib/dtas/source/mp3gain.rb
CHANGED
data/lib/dtas/source/sox.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
# encoding: binary
|
@@ -56,14 +56,14 @@ class DTAS::Source::Sox # :nodoc:
|
|
56
56
|
key = nil
|
57
57
|
$1.split(/\n/n).each do |line|
|
58
58
|
if line.sub!(/^([^=]+)=/ni, '')
|
59
|
-
key = DTAS.
|
59
|
+
key = DTAS.try_enc($1.upcase, enc)
|
60
60
|
end
|
61
61
|
(comments[key] ||= ''.b) << "#{line}\n" unless line.empty?
|
62
62
|
end
|
63
63
|
comments.each do |k,v|
|
64
64
|
v.chomp!
|
65
65
|
DTAS.try_enc(v, enc)
|
66
|
-
comments[k] =
|
66
|
+
comments[k] = -v
|
67
67
|
end
|
68
68
|
end
|
69
69
|
dst
|
@@ -113,7 +113,7 @@ class DTAS::Source::Sox # :nodoc:
|
|
113
113
|
def src_spawn(player_format, rg_state, opts)
|
114
114
|
raise "BUG: #{self.inspect}#src_spawn called twice" if @to_io
|
115
115
|
e = @env.merge!(player_format.to_env)
|
116
|
-
e["INFILE"] =
|
116
|
+
e["INFILE"] = @infile
|
117
117
|
|
118
118
|
# make sure these are visible to the "current" command...
|
119
119
|
e["TRIMFX"] = trimfx
|
data/lib/dtas/source/splitfx.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
|
-
require 'yaml'
|
5
4
|
require_relative 'sox'
|
6
5
|
require_relative '../splitfx'
|
7
6
|
require_relative '../watchable'
|
@@ -36,7 +35,7 @@ class DTAS::Source::SplitFX < DTAS::Source::Sox # :nodoc:
|
|
36
35
|
|
37
36
|
sfx = DTAS::SplitFX.new
|
38
37
|
Dir.chdir(File.dirname(ymlfile)) do # ugh
|
39
|
-
@ymlhash =
|
38
|
+
@ymlhash = DTAS.yaml_load(buf)
|
40
39
|
@ymlhash['tracks'] ||= [ "t 0 default" ]
|
41
40
|
sfx.import(@ymlhash)
|
42
41
|
sfx.infile.replace(File.expand_path(sfx.infile))
|
data/lib/dtas/source.rb
CHANGED
data/lib/dtas/splitfx.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
require_relative '../dtas'
|
5
5
|
require_relative 'format'
|
6
6
|
require_relative 'process'
|
7
|
-
require_relative 'xs'
|
8
7
|
require 'tempfile'
|
9
8
|
|
10
9
|
# The backend for dtas-splitfx(1) command, but also supported by dtas-player
|
@@ -13,7 +12,6 @@ require 'tempfile'
|
|
13
12
|
class DTAS::SplitFX # :nodoc:
|
14
13
|
CMD = 'sox "$INFILE" $COMMENTS $OUTFMT $OUTDST $TRIMFX $FX $RATEFX $DITHERFX'
|
15
14
|
include DTAS::Process
|
16
|
-
include DTAS::XS
|
17
15
|
attr_reader :infile, :env, :command
|
18
16
|
|
19
17
|
# for --trim on the command-line
|
@@ -115,7 +113,7 @@ class DTAS::SplitFX # :nodoc:
|
|
115
113
|
end
|
116
114
|
|
117
115
|
case v = hash["track_zpad"]
|
118
|
-
when Integer then @track_zpad =
|
116
|
+
when Integer then @track_zpad = v
|
119
117
|
else
|
120
118
|
_bool(hash, "track_zpad") { |val| @track_zpad = val }
|
121
119
|
end
|
@@ -207,11 +205,11 @@ class DTAS::SplitFX # :nodoc:
|
|
207
205
|
env["DITHERFX"] = "dither -s"
|
208
206
|
end
|
209
207
|
comments = Tempfile.new(%W(dtas-splitfx-#{t.comments["TRACKNUMBER"]} .txt))
|
210
|
-
comments.sync = true
|
211
208
|
t.comments.each do |k,v|
|
212
209
|
env[k] = v.to_s
|
213
210
|
comments.puts("#{k}=#{v}")
|
214
211
|
end
|
212
|
+
comments.flush
|
215
213
|
env["COMMENTS"] = "--comment-file=#{comments.path}"
|
216
214
|
infile_env(env, @infile)
|
217
215
|
outarg = outfmt.to_sox_arg
|
@@ -250,7 +248,10 @@ class DTAS::SplitFX # :nodoc:
|
|
250
248
|
command = 'true' if opts[:dryrun] # still gotta fork
|
251
249
|
|
252
250
|
# pgroup: false so Ctrl-C on command-line will immediately stop everything
|
253
|
-
|
251
|
+
o = { pgroup: false }
|
252
|
+
e = opts[:err_suffix] and
|
253
|
+
o[:err] = [ "#{env['OUTDIR']}#{env['TRACKNUMBER']}#{e}", 'a' ]
|
254
|
+
[ dtas_spawn(env, command, o), comments ]
|
254
255
|
end
|
255
256
|
|
256
257
|
def load_tracks!(hash)
|
@@ -298,6 +299,7 @@ class DTAS::SplitFX # :nodoc:
|
|
298
299
|
t.fade_in = $1.split(/\s+/)
|
299
300
|
when %r{\Afade_out=(.+)\z} # $1 = "t 4" or just "4"
|
300
301
|
t.fade_out = $1.split(/\s+/)
|
302
|
+
when %r{\Aenv\.([^=]+)=(.+)\z} then t.env[$1] = -$2
|
301
303
|
when %r{\A\.(\w+)=(.+)\z} then t.comments[$1] = $2
|
302
304
|
else
|
303
305
|
raise ArgumentError, "unrecognized arg(s): #{xs(argv)}"
|
@@ -355,9 +357,19 @@ class DTAS::SplitFX # :nodoc:
|
|
355
357
|
@rate = opts[:rate]
|
356
358
|
@bits = opts[:bits]
|
357
359
|
trim = opts[:trim] and @tracks = [ UTrim.new(trim, @env, @comments) ]
|
358
|
-
|
360
|
+
if trim && opts[:filter]
|
361
|
+
raise ArgumentError, 'trim and filter are mutually exclusive'
|
362
|
+
end
|
359
363
|
fails = []
|
360
364
|
tracks = @tracks.dup
|
365
|
+
(opts[:filter] || []).each do |re|
|
366
|
+
field, val = re.split(/=/, 2)
|
367
|
+
if val
|
368
|
+
tracks.delete_if { |t| (t.comments[field] || '') !~ /#{val}/ }
|
369
|
+
else
|
370
|
+
tracks.delete_if { |t| t.comments.values.grep(/#{re}/).empty? }
|
371
|
+
end
|
372
|
+
end
|
361
373
|
pids = {}
|
362
374
|
jobs = opts[:jobs] || tracks.size # jobs == nil => everything at once
|
363
375
|
if opts[:sox_pipe]
|
@@ -401,10 +413,10 @@ class DTAS::SplitFX # :nodoc:
|
|
401
413
|
end
|
402
414
|
|
403
415
|
def infile_env(env, infile)
|
404
|
-
env["INFILE"] =
|
416
|
+
env["INFILE"] = infile
|
405
417
|
dir, base = File.split(File.expand_path(infile))
|
406
|
-
env["INDIR"] =
|
407
|
-
env["INBASE"] =
|
418
|
+
env["INDIR"] = dir
|
419
|
+
env["INBASE"] = base
|
408
420
|
end
|
409
421
|
|
410
422
|
def expand_cmd(env, command) # for display purposes only
|
data/lib/dtas/state_file.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
require 'yaml'
|
@@ -14,7 +14,7 @@ class DTAS::StateFile # :nodoc:
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def tryload
|
17
|
-
|
17
|
+
DTAS.yaml_load(IO.binread(@path)) if File.readable?(@path)
|
18
18
|
end
|
19
19
|
|
20
20
|
def dump(obj, force_fsync = false)
|
data/lib/dtas/tfx.rb
CHANGED
data/lib/dtas/track.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2015-
|
1
|
+
# Copyright (C) 2015-2020 all contributors <dtas-all@nongnu.org>
|
2
2
|
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
require_relative '../dtas'
|
@@ -9,6 +9,6 @@ class DTAS::Track # :nodoc:
|
|
9
9
|
|
10
10
|
def initialize(track_id, path)
|
11
11
|
@track_id = track_id
|
12
|
-
@to_path = path
|
12
|
+
@to_path = -path
|
13
13
|
end
|
14
14
|
end
|
data/lib/dtas/tracklist.rb
CHANGED