dtas 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/Documentation/.gitignore +1 -1
  4. data/Documentation/GNUmakefile +3 -1
  5. data/Documentation/dtas-archive.txt +61 -0
  6. data/Documentation/dtas-console.txt +4 -3
  7. data/Documentation/dtas-ctl.txt +4 -3
  8. data/Documentation/dtas-cueedit.txt +4 -3
  9. data/Documentation/dtas-enq.txt +4 -3
  10. data/Documentation/dtas-env.txt +60 -0
  11. data/Documentation/dtas-msinkctl.txt +4 -3
  12. data/Documentation/dtas-player.txt +6 -3
  13. data/Documentation/dtas-player_effects.txt +4 -3
  14. data/Documentation/dtas-player_protocol.txt +27 -4
  15. data/Documentation/dtas-player_sink_examples.txt +7 -3
  16. data/Documentation/dtas-sinkedit.txt +20 -3
  17. data/Documentation/dtas-sourceedit.txt +21 -3
  18. data/Documentation/dtas-splitfx.txt +14 -5
  19. data/Documentation/dtas-tl.txt +4 -3
  20. data/Documentation/dtas-xdelay.txt +4 -3
  21. data/Documentation/update-footer.rb +52 -0
  22. data/GIT-VERSION-GEN +2 -2
  23. data/GNUmakefile +1 -1
  24. data/HACKING +3 -2
  25. data/INSTALL +6 -6
  26. data/README +1 -1
  27. data/Rakefile +2 -3
  28. data/TODO +1 -1
  29. data/bin/dtas-archive +187 -0
  30. data/bin/dtas-console +7 -1
  31. data/bin/dtas-ctl +1 -1
  32. data/bin/dtas-cueedit +3 -3
  33. data/bin/dtas-enq +1 -1
  34. data/bin/dtas-msinkctl +1 -1
  35. data/bin/dtas-partstats +10 -4
  36. data/bin/dtas-player +1 -1
  37. data/bin/dtas-sinkedit +82 -20
  38. data/bin/dtas-sourceedit +64 -22
  39. data/bin/dtas-splitfx +1 -1
  40. data/bin/dtas-tl +1 -1
  41. data/bin/dtas-xdelay +1 -1
  42. data/dtas-linux.gemspec +1 -1
  43. data/dtas-mpris.gemspec +1 -1
  44. data/dtas.gemspec +1 -1
  45. data/examples/splitfx.sample.yml +11 -3
  46. data/examples/{trimfx.sample.yml → tfx.sample.yml} +1 -1
  47. data/lib/dtas.rb +2 -1
  48. data/lib/dtas/buffer.rb +5 -5
  49. data/lib/dtas/buffer/read_write.rb +8 -5
  50. data/lib/dtas/buffer/splice.rb +29 -8
  51. data/lib/dtas/command.rb +2 -2
  52. data/lib/dtas/compat_onenine.rb +1 -1
  53. data/lib/dtas/cue_index.rb +3 -1
  54. data/lib/dtas/disclaimer.rb +1 -1
  55. data/lib/dtas/edit_client.rb +1 -1
  56. data/lib/dtas/fadefx.rb +100 -0
  57. data/lib/dtas/format.rb +4 -2
  58. data/lib/dtas/parse_time.rb +3 -1
  59. data/lib/dtas/partstats.rb +8 -10
  60. data/lib/dtas/pipe.rb +2 -1
  61. data/lib/dtas/player.rb +33 -11
  62. data/lib/dtas/player/client_handler.rb +43 -8
  63. data/lib/dtas/process.rb +6 -14
  64. data/lib/dtas/replaygain.rb +3 -3
  65. data/lib/dtas/rg_state.rb +1 -1
  66. data/lib/dtas/serialize.rb +3 -1
  67. data/lib/dtas/sigevent.rb +1 -1
  68. data/lib/dtas/sigevent/efd.rb +5 -4
  69. data/lib/dtas/sigevent/pipe.rb +4 -1
  70. data/lib/dtas/sink.rb +4 -4
  71. data/lib/dtas/source.rb +1 -1
  72. data/lib/dtas/source/av.rb +2 -2
  73. data/lib/dtas/source/av_ff_common.rb +22 -11
  74. data/lib/dtas/source/cmd.rb +3 -3
  75. data/lib/dtas/source/common.rb +3 -2
  76. data/lib/dtas/source/ff.rb +2 -2
  77. data/lib/dtas/source/file.rb +22 -4
  78. data/lib/dtas/source/mp3gain.rb +1 -1
  79. data/lib/dtas/source/sox.rb +7 -7
  80. data/lib/dtas/source/splitfx.rb +99 -0
  81. data/lib/dtas/spawn_fix.rb +10 -0
  82. data/lib/dtas/splitfx.rb +63 -24
  83. data/lib/dtas/state_file.rb +3 -1
  84. data/lib/dtas/{trimfx.rb → tfx.rb} +50 -24
  85. data/lib/dtas/tracklist.rb +2 -1
  86. data/lib/dtas/unix_accepted.rb +2 -2
  87. data/lib/dtas/unix_client.rb +2 -2
  88. data/lib/dtas/unix_server.rb +1 -1
  89. data/lib/dtas/util.rb +1 -1
  90. data/lib/dtas/watchable.rb +54 -0
  91. data/lib/dtas/writable_iter.rb +2 -1
  92. data/lib/dtas/xs.rb +2 -2
  93. data/perl/dtas-graph +1 -1
  94. data/test/covshow.rb +1 -1
  95. data/test/helper.rb +1 -1
  96. data/test/player_integration.rb +1 -1
  97. data/test/test_buffer.rb +1 -1
  98. data/test/test_env.rb +1 -1
  99. data/test/test_fadefx.rb +45 -0
  100. data/test/test_format.rb +1 -1
  101. data/test/test_format_change.rb +1 -1
  102. data/test/test_player.rb +1 -1
  103. data/test/test_player_client_handler.rb +1 -1
  104. data/test/test_player_integration.rb +8 -8
  105. data/test/test_process.rb +1 -1
  106. data/test/test_rg_integration.rb +1 -1
  107. data/test/test_rg_state.rb +1 -1
  108. data/test/test_sink.rb +1 -1
  109. data/test/test_sink_pipe_size.rb +2 -2
  110. data/test/test_sink_tee_integration.rb +1 -1
  111. data/test/test_source_av.rb +1 -1
  112. data/test/test_source_sox.rb +1 -1
  113. data/test/test_splitfx.rb +43 -13
  114. data/test/test_tfx.rb +85 -0
  115. data/test/test_tracklist.rb +1 -1
  116. data/test/test_unixserver.rb +1 -1
  117. data/test/test_util.rb +1 -1
  118. metadata +17 -6
  119. data/lib/dtas/compat_rbx.rb +0 -12
  120. data/test/test_trimfx.rb +0 -81
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  require 'dtas/unix_client'
5
5
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  require 'tempfile'
5
5
  require 'dtas/xs'
@@ -49,7 +49,7 @@ ARGV.each do |file|
49
49
  # avoid an expensive update if the user didn't change anything
50
50
  current = File.binread(tmp.path)
51
51
  if current == original
52
- $stderr.puts "tags for #{xs(Array(file))} unchanged" if $DEBUG
52
+ $stderr.puts "tags for #{xs(file)} unchanged" if $DEBUG
53
53
  next
54
54
  end
55
55
 
@@ -65,7 +65,7 @@ ARGV.each do |file|
65
65
  warn err_msg(cmd, $?)
66
66
  warn "E: restoring original from backup"
67
67
  x!(*%W(metaflac --import-cuesheet-from=#{backup.path} #{file}))
68
- warn "E: backup cuesheet restored, #{xs(Array(file))} unchanged"
68
+ warn "E: backup cuesheet restored, #{xs(file)} unchanged"
69
69
  exit(false)
70
70
  end
71
71
  ensure
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  require 'dtas/unix_client'
5
5
  c = DTAS::UNIXClient.new
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  require 'yaml'
5
5
  require 'dtas/unix_client'
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  # TODO
5
5
  # - option parsing: sox effects, stats effect options
@@ -9,9 +9,15 @@
9
9
  require 'dtas/partstats'
10
10
  infile = ARGV[0] or abort "usage: #$0 INFILE"
11
11
  ps = DTAS::PartStats.new(infile)
12
- opts = {
13
- jobs: `nproc 2>/dev/null || echo 2`.to_i
14
- }
12
+
13
+ def nproc
14
+ require 'etc'
15
+ Etc.nprocessors
16
+ rescue NoMethodError
17
+ `nproc 2>/dev/null || echo 2`.to_i
18
+ end
19
+
20
+ opts = { jobs: nproc }
15
21
  stats = ps.run(opts)
16
22
 
17
23
  headers = ps.key_idx.to_a
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  Thread.abort_on_exception = $stderr.sync = $stdout.sync = true
5
5
  require 'yaml'
@@ -1,40 +1,102 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
+ require 'optparse'
4
5
  require 'dtas/edit_client'
6
+ require 'dtas/sigevent'
7
+ require 'dtas/watchable'
5
8
  include DTAS::EditClient
6
9
  c = client_socket
7
10
  sinks = c.req('sink ls') || "(unknown)"
8
- usage = "Usage: #{DTAS_PROGNAME} SINKNAME\n" \
11
+ usage = "Usage: #{DTAS_PROGNAME} [OPTIONS] SINKNAME\n" \
9
12
  "available SINKNAME values: #{sinks}"
13
+ dry_run = verbose = false
14
+ watch = defined?(DTAS::Watchable)
15
+
16
+ OptionParser.new('', 24, ' ') do |op|
17
+ op.banner = usage
18
+ watch and
19
+ op.on('-N', '--no-watch', 'disable inotify support') { watch = false }
20
+
21
+ op.on('-n', '--dry-run', 'only print commands, do not run them') {
22
+ dry_run = true
23
+ }
24
+ op.on('-V', '--verbose', 'print out commands sent to change the sink') {
25
+ verbose = true
26
+ }
27
+ op.on('-h', '--help') { puts(op.to_s); exit }
28
+ op.parse!(ARGV)
29
+ end
30
+
10
31
  ARGV.size == 1 or abort usage
11
32
  name = ARGV[0]
12
33
 
13
- tmp = tmpyaml
34
+ st_in = $stdin.stat
35
+
14
36
  buf = c.req(%W(sink cat #{name}))
15
37
  abort(buf) if buf =~ /\AERR/
16
38
  orig = YAML.load(buf)
17
39
 
18
- tmp.write(buf << DTAS_DISCLAIMER)
19
- cmd = "#{editor} #{tmp.path}"
20
- system(cmd) or abort "#{cmd} failed: #$?"
21
- sink = YAML.load(File.read(tmp.path))
40
+ commit_update = lambda do |buf|
41
+ sink = YAML.load(buf)
42
+ cmd = %W(sink ed #{name})
43
+ update_cmd_env(cmd, orig, sink)
22
44
 
23
- cmd = %W(sink ed #{name})
24
- update_cmd_env(cmd, orig, sink)
45
+ # both of these default to false
46
+ %w(nonblock active).each do |field|
47
+ cmd << "#{field}=#{sink[field] ? 'true' : 'false'}"
48
+ end
25
49
 
26
- # both of these default to false
27
- %w(nonblock active).each do |field|
28
- cmd << "#{field}=#{sink[field] ? 'true' : 'false'}"
29
- end
50
+ %w(prio).each do |field|
51
+ value = sink[field] and cmd << "#{field}=#{value}"
52
+ end
30
53
 
31
- %w(prio pipe_size).each do |field|
32
- value = sink[field] and cmd << "#{field}=#{value}"
33
- end
54
+ %w(pipe_size).each { |field| cmd << "#{field}=#{sink[field]}" }
55
+
56
+ # nil OK
57
+ %w(command).each do |field|
58
+ cmd << "#{field}=#{sink[field]}"
59
+ end
34
60
 
35
- # nil OK
36
- %w(command).each do |field|
37
- cmd << "#{field}=#{sink[field]}"
61
+ warn(Shellwords.join(cmd)) if verbose || dry_run
62
+ c.req_ok(cmd) unless dry_run
63
+ orig = sink
38
64
  end
39
65
 
40
- c.req_ok(cmd)
66
+ if st_in.file? || st_in.pipe?
67
+ buf = $stdin.read
68
+ commit_update.call(buf)
69
+ else
70
+ include DTAS::SpawnFix
71
+ tmp = tmpyaml
72
+ tmp_path = tmp.path
73
+ do_update = lambda { commit_update.call(File.read(tmp_path)) }
74
+ tmp.write(buf << DTAS_DISCLAIMER)
75
+ cmd = "#{editor} #{tmp_path}"
76
+
77
+ sev = DTAS::Sigevent.new
78
+ rset = [ sev ]
79
+ if watch
80
+ ino = DTAS::Watchable::InotifyReadableIter.new
81
+ ino.watch_file(tmp_path, do_update)
82
+ rset << ino
83
+ end
84
+
85
+ trap(:CHLD) { sev.signal }
86
+ pid = spawn(cmd)
87
+ begin
88
+ r = IO.select(rset) or next
89
+ r[0].each do |io|
90
+ case io
91
+ when sev
92
+ _, status = Process.waitpid2(pid, Process::WNOHANG)
93
+ status or next
94
+ status.success? or abort "#{cmd} failed: #{status.inspect}"
95
+ do_update.call
96
+ exit
97
+ when ino
98
+ ino.readable_iter # calls do_update
99
+ end
100
+ end
101
+ end while true
102
+ end
@@ -1,16 +1,32 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
+ require 'optparse'
4
5
  require 'dtas/edit_client'
6
+ require 'dtas/sigevent'
7
+ require 'dtas/watchable'
5
8
  include DTAS::EditClient
6
9
  c = client_socket
7
10
  sources = c.req('source ls') || "(unknown)"
8
- usage = "Usage: #{DTAS_PROGNAME} [-n|--dry-run][-V|--verbose] SOURCENAME\n" \
9
- "available SOURCENAME values: #{sources}"
11
+ usage = "Usage: #{DTAS_PROGNAME} [OPTIONS] SOURCENAME\n" \
12
+ "available SOURCENAME values: #{sources}\n" \
10
13
 
11
- # use a real option parser if we have anything more complex
12
- dry_run = !!(ARGV.delete('-n') || ARGV.delete('--dry-run'))
13
- verbose = !!(ARGV.delete('-V') || ARGV.delete('--verbose'))
14
+ dry_run = verbose = false
15
+ watch = defined?(DTAS::Watchable)
16
+ OptionParser.new('', 24, ' ') do |op|
17
+ op.banner = usage
18
+ watch and
19
+ op.on('-N', '--no-watch', 'disable inotify support') { watch = false }
20
+
21
+ op.on('-n', '--dry-run', 'only print commands, do not run them') {
22
+ dry_run = true
23
+ }
24
+ op.on('-V', '--verbose', 'print out commands sent to change the source') {
25
+ verbose = true
26
+ }
27
+ op.on('-h', '--help') { puts(op.to_s); exit }
28
+ op.parse!(ARGV)
29
+ end
14
30
 
15
31
  ARGV.size <= 1 or abort usage
16
32
  name = ARGV[0] || "sox"
@@ -21,27 +37,53 @@ buf = c.req(%W(source cat #{name}))
21
37
  abort(buf) if buf =~ /\AERR/
22
38
  orig = YAML.load(buf)
23
39
 
40
+ commit_update = lambda do |buf|
41
+ source = YAML.load(buf)
42
+ cmd = %W(source ed #{name})
43
+ update_cmd_env(cmd, orig, source)
44
+
45
+ # nil OK
46
+ %w(tryorder command).each { |field| cmd << "#{field}=#{source[field]}" }
47
+
48
+ warn(Shellwords.join(cmd)) if verbose || dry_run
49
+ c.req_ok(cmd) unless dry_run
50
+ orig = source
51
+ end
52
+
24
53
  if st_in.file? || st_in.pipe?
25
54
  buf = $stdin.read
55
+ commit_update.call(buf)
26
56
  else
57
+ include DTAS::SpawnFix
27
58
  tmp = tmpyaml
59
+ tmp_path = tmp.path
60
+ do_update = lambda { commit_update.call(File.read(tmp_path)) }
28
61
  tmp.write(buf << DTAS_DISCLAIMER)
29
- cmd = "#{editor} #{tmp.path}"
30
- system(cmd) or abort "#{cmd} failed: #$?"
31
- buf = File.read(tmp.path)
32
- end
62
+ cmd = "#{editor} #{tmp_path}"
33
63
 
34
- source = YAML.load(buf)
35
- cmd = %W(source ed #{name})
36
- update_cmd_env(cmd, orig, source)
64
+ sev = DTAS::Sigevent.new
65
+ rset = [ sev ]
66
+ if watch
67
+ ino = DTAS::Watchable::InotifyReadableIter.new
68
+ ino.watch_file(tmp_path, do_update)
69
+ rset << ino
70
+ end
37
71
 
38
- # nil OK
39
- %w(tryorder command).each do |field|
40
- cmd << "#{field}=#{source[field]}"
72
+ trap(:CHLD) { sev.signal }
73
+ pid = spawn(cmd)
74
+ begin
75
+ r = IO.select(rset) or next
76
+ r[0].each do |io|
77
+ case io
78
+ when sev
79
+ _, status = Process.waitpid2(pid, Process::WNOHANG)
80
+ status or next
81
+ status.success? or abort "#{cmd} failed: #{status.inspect}"
82
+ do_update.call
83
+ exit
84
+ when ino
85
+ ino.readable_iter # calls do_update
86
+ end
87
+ end
88
+ end while true
41
89
  end
42
-
43
- if verbose || dry_run
44
- warn Shellwords.join(cmd)
45
- end
46
-
47
- c.req_ok(cmd) unless dry_run
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  require 'yaml'
5
5
  require 'optparse'
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  #
5
5
  # WARNING: totally unstable API, use dtas-ctl for scripting (but the protocol
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
2
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
3
3
  # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
  USAGE = "Usage: #$0 [-x FREQ] [-l] /dev/fd/LO /dev/fd/HI DELAY [DELAY ...]"
5
5
  require 'optparse'
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
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
  # this just declares dependencies to make gem installation a little easier
@@ -1,4 +1,4 @@
1
- # Copyright 2013-2014, Eric Wong <e@80x24.org> and all contributors.
1
+ # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
2
2
  # License: GPLv2 or later <http://www.gnu.org/licenses/gpl-2.0.txt>
3
3
  # This is GPLv2+ instead of GPLv3+ because ruby-dbus is LGPLv2.1 (only)
4
4
  Gem::Specification.new do |s|
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
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
  Gem::Specification.new do |s|
4
4
  manifest = File.read('.gem-manifest').split(/\n/)
@@ -4,13 +4,21 @@
4
4
  # test_splitfx.rb relies on this.
5
5
  ---
6
6
  infile: foo.flac
7
- env:
8
- PATH: $PATH
9
- SOX_OPTS: $SOX_OPTS -R
10
7
  comments:
11
8
  ARTIST: John Smith
12
9
  ALBUM: Hello World
13
10
  YEAR: 2013
11
+ # the sox command for dtas-player playback, there is no need to
12
+ # specify this as it is the default:
13
+ # command: exec sox "$INFILE" $SOXFMT - $TRIMFX $RGFX $FX
14
+ env: !omap
15
+ PATH: $PATH
16
+ # these effects may be used in any command in this file, including targets
17
+ SOX_OPTS: $SOX_OPTS -R
18
+ FX:
19
+ # highpass -1 120 highpass 40 highpass 40
20
+ # vol +1.5dB
21
+ stats
14
22
  track_start: 1 # 0 for pregap/intro tracks
15
23
  cdda_align: true
16
24
  tracks:
@@ -4,7 +4,7 @@
4
4
  # test_trimfx.rb relies on this.
5
5
  ---
6
6
  infile: foo.flac
7
- env:
7
+ env: !omap
8
8
  PATH: $PATH
9
9
  SOX_OPTS: $SOX_OPTS -R
10
10
  I2: second.flac
@@ -1,6 +1,7 @@
1
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
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 # :nodoc:
4
4
  end
5
5
 
6
6
  require_relative 'dtas/compat_onenine'
7
+ require_relative 'dtas/spawn_fix'
@@ -1,9 +1,9 @@
1
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
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
- require_relative 'compat_rbx' # IO#nread
6
5
 
6
+ # pipe buffer management for -player
7
7
  class DTAS::Buffer # :nodoc:
8
8
  begin
9
9
  raise LoadError, "no splice with _DTAS_POSIX" if ENV["_DTAS_POSIX"]
@@ -48,14 +48,14 @@ class DTAS::Buffer # :nodoc:
48
48
  # - subset of targets array for :wait_writable
49
49
  # - some type of StandardError
50
50
  # - nil
51
- def broadcast(targets)
51
+ def broadcast(targets, limit = nil)
52
52
  case targets.size
53
53
  when 0
54
54
  :ignore # this will pause decoders
55
55
  when 1
56
- broadcast_one(targets)
56
+ broadcast_one(targets, limit)
57
57
  else # infinity
58
- broadcast_inf(targets)
58
+ broadcast_inf(targets, limit)
59
59
  end
60
60
  end
61
61
 
@@ -1,9 +1,11 @@
1
- # Copyright (C) 2013-2014, Eric Wong <e@80x24.org> and all contributors
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/nonblock'
4
4
  require_relative '../../dtas'
5
5
  require_relative '../pipe'
6
6
 
7
+ # compatibility code for systems lacking "splice" support via the
8
+ # "io-splice" RubyGem. Used only by -player
7
9
  module DTAS::Buffer::ReadWrite # :nodoc:
8
10
  MAX_AT_ONCE = 512 # min PIPE_BUF value in POSIX
9
11
  attr_accessor :buffer_size
@@ -24,9 +26,9 @@ module DTAS::Buffer::ReadWrite # :nodoc:
24
26
  end
25
27
 
26
28
  # always block when we have a single target
27
- def broadcast_one(targets)
29
+ def broadcast_one(targets, limit = nil)
28
30
  buf = _rbuf
29
- @to_io.read_nonblock(MAX_AT_ONCE, buf)
31
+ @to_io.read_nonblock(limit || MAX_AT_ONCE, buf)
30
32
  n = targets[0].write(buf) # IO#write has write-in-full behavior
31
33
  @bytes_xfer += n
32
34
  :wait_readable
@@ -40,7 +42,7 @@ module DTAS::Buffer::ReadWrite # :nodoc:
40
42
  nil # do not return error here, we already spewed an error message
41
43
  end
42
44
 
43
- def broadcast_inf(targets)
45
+ def broadcast_inf(targets, limit = nil)
44
46
  nr_nb = targets.count(&:nonblock?)
45
47
  if nr_nb == 0 || nr_nb == targets.size
46
48
  # if all targets are full, don't start until they're all writable
@@ -59,7 +61,8 @@ module DTAS::Buffer::ReadWrite # :nodoc:
59
61
 
60
62
  # don't pin too much on one target
61
63
  bytes = inflight
62
- bytes = bytes > MAX_AT_ONCE ? MAX_AT_ONCE : bytes
64
+ limit ||= MAX_AT_ONCE
65
+ bytes = bytes > limit ? limit : bytes
63
66
  buf = _rbuf
64
67
  @to_io.read(bytes, buf)
65
68
  n = buf.bytesize