dtas 0.17.0 → 0.18.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 +1 -1
- data/Documentation/dtas-tl.pod +1 -1
- data/Documentation/dtas-xdelay.pod +1 -1
- data/Documentation/update-footer.rb +1 -1
- data/GIT-VERSION-GEN +2 -2
- data/GNUmakefile +1 -1
- data/HACKING +1 -1
- data/INSTALL +9 -19
- data/README +6 -5
- data/Rakefile +1 -1
- data/TODO +1 -1
- data/bin/dtas-archive +1 -1
- data/bin/dtas-console +1 -1
- 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 +1 -1
- data/bin/dtas-partstats +1 -1
- data/bin/dtas-player +1 -1
- data/bin/dtas-readahead +1 -1
- data/bin/dtas-sinkedit +1 -1
- data/bin/dtas-sourceedit +1 -1
- 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/lib/dtas.rb +9 -1
- data/lib/dtas/buffer.rb +10 -7
- data/lib/dtas/buffer/fiddle_splice.rb +216 -0
- data/lib/dtas/buffer/read_write.rb +3 -3
- data/lib/dtas/buffer/splice.rb +3 -1
- data/lib/dtas/command.rb +1 -1
- data/lib/dtas/compat_onenine.rb +1 -1
- data/lib/dtas/cue_index.rb +1 -1
- data/lib/dtas/disclaimer.rb +1 -1
- data/lib/dtas/edit_client.rb +1 -1
- data/lib/dtas/encoding.rb +1 -1
- data/lib/dtas/fadefx.rb +1 -1
- data/lib/dtas/format.rb +1 -1
- data/lib/dtas/mcache.rb +1 -1
- data/lib/dtas/mlib.rb +1 -1
- data/lib/dtas/mlib/migrations/0001_initial.rb +1 -1
- data/lib/dtas/nonblock.rb +1 -1
- data/lib/dtas/parse_freq.rb +1 -1
- data/lib/dtas/parse_time.rb +1 -1
- data/lib/dtas/partstats.rb +1 -1
- data/lib/dtas/pipe.rb +13 -9
- data/lib/dtas/pipeline.rb +1 -1
- data/lib/dtas/player.rb +1 -1
- data/lib/dtas/player/client_handler.rb +1 -1
- data/lib/dtas/process.rb +1 -1
- data/lib/dtas/replaygain.rb +1 -1
- data/lib/dtas/rg_state.rb +1 -1
- data/lib/dtas/serialize.rb +1 -1
- data/lib/dtas/sigevent.rb +6 -3
- data/lib/dtas/sigevent/efd.rb +3 -1
- data/lib/dtas/sigevent/fiddle_efd.rb +38 -0
- data/lib/dtas/sigevent/pipe.rb +2 -2
- data/lib/dtas/sink.rb +1 -1
- data/lib/dtas/source.rb +1 -1
- data/lib/dtas/source/av.rb +1 -1
- data/lib/dtas/source/av_ff_common.rb +1 -1
- 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 +1 -1
- data/lib/dtas/source/splitfx.rb +1 -1
- data/lib/dtas/spawn_fix.rb +1 -1
- data/lib/dtas/splitfx.rb +1 -1
- data/lib/dtas/state_file.rb +1 -1
- data/lib/dtas/tfx.rb +1 -1
- data/lib/dtas/track.rb +1 -1
- data/lib/dtas/tracklist.rb +1 -1
- data/lib/dtas/unix_accepted.rb +1 -1
- data/lib/dtas/unix_client.rb +1 -1
- data/lib/dtas/unix_server.rb +1 -1
- data/lib/dtas/util.rb +1 -1
- data/lib/dtas/watchable.rb +59 -58
- data/lib/dtas/watchable/fiddle_ino.rb +78 -0
- data/lib/dtas/watchable/inotify.rb +13 -0
- data/lib/dtas/writable_iter.rb +1 -1
- data/lib/dtas/xs.rb +1 -1
- data/perl/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 -1
- data/test/test_buffer.rb +6 -6
- data/test/test_encoding.rb +1 -1
- 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 +1 -1
- data/test/test_mcache.rb +1 -1
- 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 +1 -1
- data/test/test_player_integration.rb +1 -1
- 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_sigevent.rb +20 -0
- data/test/test_sink.rb +1 -1
- 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 +1 -1
- data/test/test_tfx.rb +1 -1
- data/test/test_tracklist.rb +1 -1
- data/test/test_unixserver.rb +1 -1
- data/test/test_util.rb +1 -1
- metadata +8 -3
data/lib/dtas/pipeline.rb
CHANGED
data/lib/dtas/player.rb
CHANGED
data/lib/dtas/process.rb
CHANGED
data/lib/dtas/replaygain.rb
CHANGED
data/lib/dtas/rg_state.rb
CHANGED
data/lib/dtas/serialize.rb
CHANGED
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/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,38 @@
|
|
1
|
+
# Copyright (C) 2013-2020 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_relative '../nonblock'
|
8
|
+
require 'fiddle'
|
9
|
+
class DTAS::Sigevent # :nodoc:
|
10
|
+
|
11
|
+
EventFD = Fiddle::Function.new(DTAS.libc['eventfd'],
|
12
|
+
[ Fiddle::TYPE_INT, Fiddle::TYPE_INT ], # initval, flags
|
13
|
+
Fiddle::TYPE_INT) # fd
|
14
|
+
|
15
|
+
attr_reader :to_io
|
16
|
+
ONE = [ 1 ].pack('Q').freeze
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
fd = EventFD.call(0, 02000000|00004000) # EFD_CLOEXEC|EFD_NONBLOCK
|
20
|
+
raise "eventfd failed: #{Fiddle.last_error}" if fd < 0
|
21
|
+
@to_io = DTAS::Nonblock.for_fd(fd)
|
22
|
+
@buf = ''.b
|
23
|
+
end
|
24
|
+
|
25
|
+
def signal
|
26
|
+
@to_io.syswrite(ONE)
|
27
|
+
end
|
28
|
+
|
29
|
+
def readable_iter
|
30
|
+
@to_io.read_nonblock(8, @buf, exception: false)
|
31
|
+
yield self, nil # calls DTAS::Process.reaper
|
32
|
+
:wait_readable
|
33
|
+
end
|
34
|
+
|
35
|
+
def close
|
36
|
+
@to_io.close
|
37
|
+
end
|
38
|
+
end
|
data/lib/dtas/sigevent/pipe.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
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
|
|
5
5
|
# used in various places for safe wakeups from IO.select via signals
|
6
|
-
# A fallback for non-Linux systems lacking the "
|
6
|
+
# A fallback for non-Linux systems lacking the "splice" syscall
|
7
7
|
require_relative '../nonblock'
|
8
8
|
class DTAS::Sigevent # :nodoc:
|
9
9
|
attr_reader :to_io
|
data/lib/dtas/sink.rb
CHANGED
data/lib/dtas/source.rb
CHANGED
data/lib/dtas/source/av.rb
CHANGED
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
data/lib/dtas/source/splitfx.rb
CHANGED
data/lib/dtas/spawn_fix.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
|
# workaround for older Rubies: https://bugs.ruby-lang.org/issues/8770
|
4
4
|
module DTAS::SpawnFix # :nodoc:
|
data/lib/dtas/splitfx.rb
CHANGED
data/lib/dtas/state_file.rb
CHANGED
data/lib/dtas/tfx.rb
CHANGED
data/lib/dtas/track.rb
CHANGED
data/lib/dtas/tracklist.rb
CHANGED
data/lib/dtas/unix_accepted.rb
CHANGED
data/lib/dtas/unix_client.rb
CHANGED
data/lib/dtas/unix_server.rb
CHANGED
data/lib/dtas/util.rb
CHANGED
data/lib/dtas/watchable.rb
CHANGED
@@ -1,71 +1,72 @@
|
|
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
|
+
require_relative '../dtas'
|
5
|
+
require_relative 'nonblock'
|
4
6
|
begin
|
5
|
-
|
7
|
+
module DTAS::Watchable # :nodoc:
|
8
|
+
module InotifyCommon # :nodoc:
|
9
|
+
FLAGS = 8 | 128 # IN_CLOSE_WRITE | IN_MOVED_TO
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
w = @watches[event.wd] or next
|
21
|
-
if (event.mask & FLAGS) != 0 && w[event.name]
|
22
|
-
or_call = true
|
11
|
+
def readable_iter
|
12
|
+
or_call = false
|
13
|
+
while event = take(true) # drain the buffer
|
14
|
+
w = @watches[event.wd] or next
|
15
|
+
if (event.mask & FLAGS) != 0 && w[event.name]
|
16
|
+
or_call = true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
if or_call
|
20
|
+
@on_readable.call
|
21
|
+
:delete
|
22
|
+
else
|
23
|
+
:wait_readable
|
23
24
|
end
|
24
25
|
end
|
25
|
-
if or_call
|
26
|
-
@on_readable.call
|
27
|
-
:delete
|
28
|
-
else
|
29
|
-
:wait_readable
|
30
|
-
end
|
31
|
-
end
|
32
26
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
27
|
+
# we must watch the directory, since
|
28
|
+
def watch_files(paths, blk)
|
29
|
+
@watches = {} # wd -> { basename -> true }
|
30
|
+
@on_readable = blk
|
31
|
+
@dir2wd = {}
|
32
|
+
Array(paths).each do |path|
|
33
|
+
watchdir, watchbase = File.split(File.expand_path(path))
|
34
|
+
begin
|
35
|
+
wd = @dir2wd[watchdir] ||= add_watch(watchdir, FLAGS)
|
36
|
+
m = @watches[wd] ||= {}
|
37
|
+
m[watchbase] = true
|
38
|
+
rescue SystemCallError => e
|
39
|
+
warn "#{watchdir.dump}: #{e.message} (#{e.class})"
|
40
|
+
end
|
46
41
|
end
|
47
42
|
end
|
48
|
-
end
|
49
|
-
end
|
43
|
+
end # module InotifyCommon
|
50
44
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
45
|
+
begin
|
46
|
+
require_relative 'watchable/inotify'
|
47
|
+
rescue LoadError
|
48
|
+
# TODO: support kevent
|
49
|
+
require_relative 'watchable/fiddle_ino'
|
50
|
+
end
|
56
51
|
|
57
|
-
|
58
|
-
|
59
|
-
|
52
|
+
def watch_begin(blk)
|
53
|
+
@ino = DTAS::Watchable::InotifyReadableIter.new
|
54
|
+
@ino.watch_files(@watch_extra << @infile, blk)
|
55
|
+
@ino
|
56
|
+
end
|
60
57
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
def watch_end(srv)
|
65
|
-
srv.wait_ctl(@ino, :delete)
|
66
|
-
@ino = @ino.close
|
67
|
-
end
|
68
|
-
end
|
58
|
+
def watch_extra(paths)
|
59
|
+
@ino.watch_extra(paths)
|
60
|
+
end
|
69
61
|
|
70
|
-
|
71
|
-
|
62
|
+
# Closing the inotify descriptor (instead of using inotify_rm_watch)
|
63
|
+
# is cleaner because it avoids EINVAL on race conditions in case
|
64
|
+
# a directory is deleted: https://lkml.org/lkml/2007/7/9/3
|
65
|
+
def watch_end(srv)
|
66
|
+
srv.wait_ctl(@ino, :delete)
|
67
|
+
@ino = @ino.close
|
68
|
+
end
|
69
|
+
end # module DTAS::Watchable
|
70
|
+
rescue LoadError, StandardError => e
|
71
|
+
warn "#{e.message} (#{e.class})"
|
72
|
+
end # begin
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Copyright (C) 2013-2020 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
|
+
require 'fiddle'
|
5
|
+
|
6
|
+
# used to restart DTAS::Source::SplitFX processing in dtas-player
|
7
|
+
# if the YAML file is edited
|
8
|
+
class DTAS::Watchable::InotifyReadableIter # :nodoc:
|
9
|
+
include DTAS::Watchable::InotifyCommon
|
10
|
+
|
11
|
+
Inotify_init = Fiddle::Function.new(DTAS.libc['inotify_init1'],
|
12
|
+
[ Fiddle::TYPE_INT ],
|
13
|
+
Fiddle::TYPE_INT)
|
14
|
+
|
15
|
+
Inotify_add_watch = Fiddle::Function.new(DTAS.libc['inotify_add_watch'],
|
16
|
+
[ Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT ],
|
17
|
+
Fiddle::TYPE_INT)
|
18
|
+
|
19
|
+
# IO.select compatibility
|
20
|
+
attr_reader :to_io #:nodoc:
|
21
|
+
|
22
|
+
def initialize # :nodoc:
|
23
|
+
fd = Inotify_init.call(02000000 | 04000) # CLOEXEC | NONBLOCK
|
24
|
+
raise "inotify_init failed: #{Fiddle.last_error}" if fd < 0
|
25
|
+
@to_io = DTAS::Nonblock.for_fd(fd)
|
26
|
+
@buf = ''.b
|
27
|
+
@q = []
|
28
|
+
end
|
29
|
+
|
30
|
+
# struct inotify_event {
|
31
|
+
# int wd; /* Watch descriptor */
|
32
|
+
# uint32_t mask; /* Mask describing event */
|
33
|
+
# uint32_t cookie; /* Unique cookie associating related
|
34
|
+
# events (for rename(2)) */
|
35
|
+
# uint32_t len; /* Size of name field */
|
36
|
+
# char name[]; /* Optional null-terminated name */
|
37
|
+
InotifyEvent = Struct.new(:wd, :mask, :cookie, :len, :name) # :nodoc:
|
38
|
+
|
39
|
+
def take(nonblock) # :nodoc:
|
40
|
+
event = @q.pop and return event
|
41
|
+
case rv = @to_io.read_nonblock(16384, @buf, exception: false)
|
42
|
+
when :wait_readable, nil
|
43
|
+
return
|
44
|
+
else
|
45
|
+
until rv.empty?
|
46
|
+
hdr = rv.slice!(0,16)
|
47
|
+
name = nil
|
48
|
+
wd, mask, cookie, len = res = hdr.unpack('iIII')
|
49
|
+
wd && mask && cookie && len or
|
50
|
+
raise "bogus inotify_event #{res.inspect} hdr=#{hdr.inspect}"
|
51
|
+
if len > 0
|
52
|
+
name = rv.slice!(0, len)
|
53
|
+
name.size == len or raise "short name #{name.inspect} != #{len}"
|
54
|
+
name.sub!(/\0+\z/, '') or
|
55
|
+
raise "missing: `\\0', inotify_event.name=#{name.inspect}"
|
56
|
+
name = DTAS.dedupe_str(name)
|
57
|
+
end
|
58
|
+
ie = InotifyEvent.new(wd, mask, cookie, len, name)
|
59
|
+
if event
|
60
|
+
@q << ie
|
61
|
+
else
|
62
|
+
event = ie
|
63
|
+
end
|
64
|
+
end # /until rv.empty?
|
65
|
+
return event
|
66
|
+
end while true
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_watch(watchdir, flags)
|
70
|
+
wd = Inotify_add_watch.call(@to_io.fileno, watchdir, flags)
|
71
|
+
raise "inotify_add_watch failed: #{Fiddle.last_error}" if wd < 0
|
72
|
+
wd
|
73
|
+
end
|
74
|
+
|
75
|
+
def close
|
76
|
+
@to_io = @to_io.close if @to_io
|
77
|
+
end
|
78
|
+
end
|