dtas 0.17.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/Documentation/.gitignore +1 -1
  4. data/Documentation/GNUmakefile +1 -1
  5. data/Documentation/dtas-archive.pod +1 -1
  6. data/Documentation/dtas-console.pod +1 -1
  7. data/Documentation/dtas-ctl.pod +1 -1
  8. data/Documentation/dtas-cueedit.pod +1 -1
  9. data/Documentation/dtas-enq.pod +1 -1
  10. data/Documentation/dtas-env.pod +1 -1
  11. data/Documentation/dtas-msinkctl.pod +1 -1
  12. data/Documentation/dtas-player.pod +1 -1
  13. data/Documentation/dtas-player_effects.pod +1 -1
  14. data/Documentation/dtas-player_protocol.pod +1 -1
  15. data/Documentation/dtas-player_sink_examples.pod +1 -1
  16. data/Documentation/dtas-sinkedit.pod +2 -2
  17. data/Documentation/dtas-sourceedit.pod +2 -2
  18. data/Documentation/dtas-splitfx.pod +42 -9
  19. data/Documentation/dtas-tl.pod +3 -1
  20. data/Documentation/dtas-xdelay.pod +1 -1
  21. data/Documentation/update-footer.rb +1 -1
  22. data/GIT-VERSION-FILE +1 -1
  23. data/GIT-VERSION-GEN +2 -2
  24. data/GNUmakefile +13 -1
  25. data/HACKING +1 -1
  26. data/INSTALL +17 -25
  27. data/NEWS +121 -0
  28. data/README +13 -7
  29. data/Rakefile +1 -1
  30. data/TODO +1 -1
  31. data/bin/dtas-archive +7 -3
  32. data/bin/dtas-console +49 -16
  33. data/bin/dtas-ctl +1 -1
  34. data/bin/dtas-cueedit +1 -1
  35. data/bin/dtas-enq +1 -1
  36. data/bin/dtas-mlib +1 -1
  37. data/bin/dtas-msinkctl +2 -3
  38. data/bin/dtas-partstats +3 -9
  39. data/bin/dtas-player +1 -2
  40. data/bin/dtas-readahead +11 -25
  41. data/bin/dtas-sinkedit +3 -4
  42. data/bin/dtas-sourceedit +3 -4
  43. data/bin/dtas-splitfx +17 -5
  44. data/bin/dtas-tl +32 -27
  45. data/bin/dtas-xdelay +1 -1
  46. data/dtas-linux.gemspec +1 -1
  47. data/dtas-mpris.gemspec +1 -1
  48. data/dtas.gemspec +3 -3
  49. data/dtas.sh +8 -0
  50. data/examples/splitfx.sample.yml +1 -1
  51. data/examples/tfx.sample.yml +1 -1
  52. data/lib/dtas/buffer/fiddle_splice.rb +217 -0
  53. data/lib/dtas/buffer/read_write.rb +3 -4
  54. data/lib/dtas/buffer/splice.rb +5 -2
  55. data/lib/dtas/buffer.rb +11 -8
  56. data/lib/dtas/command.rb +1 -1
  57. data/lib/dtas/cue_index.rb +1 -1
  58. data/lib/dtas/disclaimer.rb +1 -1
  59. data/lib/dtas/edit_client.rb +2 -3
  60. data/lib/dtas/encoding.rb +8 -9
  61. data/lib/dtas/fadefx.rb +2 -2
  62. data/lib/dtas/format.rb +1 -1
  63. data/lib/dtas/mcache.rb +14 -3
  64. data/lib/dtas/mlib/migrations/0001_initial.rb +1 -1
  65. data/lib/dtas/mlib.rb +23 -13
  66. data/lib/dtas/parse_freq.rb +1 -1
  67. data/lib/dtas/parse_time.rb +1 -1
  68. data/lib/dtas/partstats.rb +3 -5
  69. data/lib/dtas/pipe.rb +14 -11
  70. data/lib/dtas/pipeline.rb +1 -4
  71. data/lib/dtas/player/client_handler.rb +25 -17
  72. data/lib/dtas/player.rb +6 -12
  73. data/lib/dtas/process.rb +3 -5
  74. data/lib/dtas/replaygain.rb +1 -1
  75. data/lib/dtas/rg_state.rb +2 -2
  76. data/lib/dtas/serialize.rb +1 -1
  77. data/lib/dtas/sigevent/efd.rb +3 -1
  78. data/lib/dtas/sigevent/fiddle_efd.rb +37 -0
  79. data/lib/dtas/sigevent/pipe.rb +3 -4
  80. data/lib/dtas/sigevent.rb +6 -3
  81. data/lib/dtas/sink.rb +1 -2
  82. data/lib/dtas/source/av.rb +1 -1
  83. data/lib/dtas/source/av_ff_common.rb +4 -4
  84. data/lib/dtas/source/cmd.rb +1 -1
  85. data/lib/dtas/source/common.rb +1 -1
  86. data/lib/dtas/source/ff.rb +1 -1
  87. data/lib/dtas/source/file.rb +1 -1
  88. data/lib/dtas/source/mp3gain.rb +1 -1
  89. data/lib/dtas/source/sox.rb +4 -4
  90. data/lib/dtas/source/splitfx.rb +2 -3
  91. data/lib/dtas/source.rb +1 -1
  92. data/lib/dtas/splitfx.rb +22 -10
  93. data/lib/dtas/state_file.rb +2 -2
  94. data/lib/dtas/tfx.rb +1 -1
  95. data/lib/dtas/track.rb +2 -2
  96. data/lib/dtas/tracklist.rb +1 -1
  97. data/lib/dtas/unix_accepted.rb +12 -37
  98. data/lib/dtas/unix_client.rb +2 -2
  99. data/lib/dtas/unix_server.rb +2 -14
  100. data/lib/dtas/util.rb +1 -1
  101. data/lib/dtas/version.rb +1 -1
  102. data/lib/dtas/watchable/fiddle_ino.rb +78 -0
  103. data/lib/dtas/watchable/inotify.rb +13 -0
  104. data/lib/dtas/watchable.rb +58 -58
  105. data/lib/dtas/writable_iter.rb +1 -1
  106. data/lib/dtas/xs.rb +1 -1
  107. data/lib/dtas.rb +13 -21
  108. data/man/dtas-archive.1 +2 -2
  109. data/man/dtas-console.1 +2 -2
  110. data/man/dtas-ctl.1 +2 -2
  111. data/man/dtas-cueedit.1 +2 -2
  112. data/man/dtas-enq.1 +2 -2
  113. data/man/dtas-env.7 +2 -2
  114. data/man/dtas-msinkctl.1 +2 -2
  115. data/man/dtas-player.1 +2 -2
  116. data/man/dtas-player_effects.7 +2 -2
  117. data/man/dtas-player_protocol.7 +2 -2
  118. data/man/dtas-player_sink_examples.7 +2 -2
  119. data/man/dtas-sinkedit.1 +3 -3
  120. data/man/dtas-sourceedit.1 +3 -3
  121. data/man/dtas-splitfx.1 +43 -13
  122. data/man/dtas-tl.1 +4 -2
  123. data/man/dtas-xdelay.1 +2 -2
  124. data/{perl → script}/dtas-graph +1 -1
  125. data/setup.rb +1 -2
  126. data/test/covshow.rb +1 -1
  127. data/test/helper.rb +1 -1
  128. data/test/player_integration.rb +1 -2
  129. data/test/test_buffer.rb +8 -8
  130. data/test/test_encoding.rb +2 -3
  131. data/test/test_env.rb +1 -1
  132. data/test/test_fadefx.rb +1 -1
  133. data/test/test_format.rb +1 -1
  134. data/test/test_format_change.rb +2 -2
  135. data/test/test_mcache.rb +15 -5
  136. data/test/test_mlib.rb +1 -1
  137. data/test/test_parse_freq.rb +1 -1
  138. data/test/test_pipeline.rb +1 -1
  139. data/test/test_player.rb +1 -1
  140. data/test/test_player_client_handler.rb +2 -2
  141. data/test/test_player_integration.rb +7 -8
  142. data/test/test_process.rb +1 -1
  143. data/test/test_rg_integration.rb +9 -9
  144. data/test/test_rg_state.rb +1 -1
  145. data/test/test_sigevent.rb +20 -0
  146. data/test/test_sink.rb +2 -2
  147. data/test/test_sink_pipe_size.rb +13 -16
  148. data/test/test_sink_tee_integration.rb +1 -1
  149. data/test/test_source_av.rb +1 -1
  150. data/test/test_source_sox.rb +1 -1
  151. data/test/test_splitfx.rb +2 -5
  152. data/test/test_tfx.rb +2 -3
  153. data/test/test_tracklist.rb +1 -1
  154. data/test/test_unixserver.rb +2 -2
  155. data/test/test_util.rb +1 -1
  156. metadata +11 -8
  157. data/lib/dtas/compat_onenine.rb +0 -17
  158. data/lib/dtas/nonblock.rb +0 -24
  159. data/lib/dtas/spawn_fix.rb +0 -10
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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 = DTAS.dedupe_str(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[DTAS.dedupe_str($1)] = v
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.sub!(/s\z/, '') and return offset.to_i
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
- if offset.sub!(/s\z/, '')
208
- offset = offset.to_i
209
- else # time
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.sub!(/\A\+/, '')
400
- offset = __seek_offset_adj(1, offset)
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) 2013-2016 all contributors <dtas-all@nongnu.org>
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'] = DTAS.dedupe_str(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) 2013-2016 all contributors <dtas-all@nongnu.org>
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 = DTAS::Nonblock.pipe
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 = DTAS::Nonblock.pipe
95
+ re, we = IO.pipe
98
96
  re.binmode
99
97
  opts[:err] = we
100
98
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
 
data/lib/dtas/rg_state.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
- DTAS.dedupe_str(sprintf('gain %0.8f', val))
75
+ -sprintf('gain %0.8f', val)
76
76
  end
77
77
  end
78
78
 
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
 
@@ -1,8 +1,10 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
@@ -1,15 +1,14 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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 "sleepy_penguin" RubyGem
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 = DTAS::Nonblock.pipe
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-2016 all contributors <dtas-all@nongnu.org>
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
- require 'sleepy_penguin'
7
- require_relative 'sigevent/efd'
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) 2013-2016 all contributors <dtas-all@nongnu.org>
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'
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
  require_relative '../../dtas'
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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[DTAS.dedupe_str($1.upcase)] = DTAS.dedupe_str($2)
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[DTAS.dedupe_str($1.upcase)] = DTAS.dedupe_str($2)
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"] = xs(@infile)
189
+ e["INFILE"] = @infile
190
190
  e["AMAP"] = amap
191
191
  e["SSPOS"] = sspos
192
192
  e["RGFX"] = rg_state.effect(self) || nil
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
  require_relative '../../dtas'
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
  require_relative '../../dtas'
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
  require_relative '../../dtas'
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
  require_relative '../process'
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2019 all contributors <dtas-all@nongnu.org>
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.dedupe_str(DTAS.try_enc($1.upcase, enc))
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] = DTAS.dedupe_str(v)
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"] = xs(@infile)
116
+ e["INFILE"] = @infile
117
117
 
118
118
  # make sure these are visible to the "current" command...
119
119
  e["TRIMFX"] = trimfx
@@ -1,7 +1,6 @@
1
- # Copyright (C) 2014-2016 all contributors <dtas-all@nongnu.org>
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 = YAML.load(buf)
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
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
  require_relative '../dtas'
data/lib/dtas/splitfx.rb CHANGED
@@ -1,10 +1,9 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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 = val
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
- [ dtas_spawn(env, command, pgroup: false), comments ]
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"] = xs(infile)
416
+ env["INFILE"] = infile
405
417
  dir, base = File.split(File.expand_path(infile))
406
- env["INDIR"] = xs(dir)
407
- env["INBASE"] = xs(base)
418
+ env["INDIR"] = dir
419
+ env["INBASE"] = base
408
420
  end
409
421
 
410
422
  def expand_cmd(env, command) # for display purposes only
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
- YAML.load(IO.binread(@path)) if File.readable?(@path)
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
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
  require_relative '../dtas'
data/lib/dtas/track.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2015-2016 all contributors <dtas-all@nongnu.org>
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
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
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
  require_relative '../dtas'