everything related to duct tape audio suite (dtas)
 help / color / mirror / Atom feed
* [PATCH 0/3] more functionality for editing audio
@ 2014-12-27 12:02 Eric Wong
  2014-12-27 12:02 ` [PATCH 1/3] dtas-console: keys for "cue next/prev" Eric Wong
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Eric Wong @ 2014-12-27 12:02 UTC (permalink / raw)
  To: dtas-all

[PATCH 1/3] dtas-console: keys for "cue next/prev"
- this made it easier to test [PATCH 2/3]

[PATCH 2/3] player: support playing splitfx YAML files
- I'm loving this feature already, it lets me save/edit small
  YAML files instead of wasting space by storing edited copies
  for optimal listening.

[PATCH 3/3] player: support "source restart" command
- Until I figure out what I'm doing wrong with inotify...


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] dtas-console: keys for "cue next/prev"
  2014-12-27 12:02 [PATCH 0/3] more functionality for editing audio Eric Wong
@ 2014-12-27 12:02 ` Eric Wong
  2014-12-27 12:02 ` [PATCH 2/3] player: support playing splitfx YAML files Eric Wong
  2014-12-27 12:02 ` [PATCH 3/3] player: support "source restart" command Eric Wong
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2014-12-27 12:02 UTC (permalink / raw)
  To: dtas-all; +Cc: Eric Wong

The '!' and '@' keys are used in mplayer to skip chapters,
so perhaps this is a good analogy.
---
 bin/dtas-console | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bin/dtas-console b/bin/dtas-console
index 98d3f43..ee0c126 100755
--- a/bin/dtas-console
+++ b/bin/dtas-console
@@ -202,6 +202,8 @@ begin
         when "f" then c.req_ok("rg fallback_gain-=1")
         when ">" then c.req_ok("tl next")
         when "<" then c.req_ok("tl prev")
+        when "!" then c.req_ok("cue prev")
+        when "@" then c.req_ok("cue next")
         when " "
           c.req("play_pause")
         when "r" # cycle through replaygain modes
-- 
EW



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/3] player: support playing splitfx YAML files
  2014-12-27 12:02 [PATCH 0/3] more functionality for editing audio Eric Wong
  2014-12-27 12:02 ` [PATCH 1/3] dtas-console: keys for "cue next/prev" Eric Wong
@ 2014-12-27 12:02 ` Eric Wong
  2014-12-27 12:02 ` [PATCH 3/3] player: support "source restart" command Eric Wong
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2014-12-27 12:02 UTC (permalink / raw)
  To: dtas-all; +Cc: Eric Wong

This allows splitfx users to test CUE breakpoints and run
file-specific effects without interrupting their normal flow.
---
 examples/splitfx.sample.yml     |  8 ++++
 lib/dtas/player.rb              |  4 +-
 lib/dtas/source/splitfx.rb      | 92 +++++++++++++++++++++++++++++++++++++++++
 lib/dtas/splitfx.rb             |  8 ++++
 test/test_player_integration.rb |  6 +--
 5 files changed, 114 insertions(+), 4 deletions(-)
 create mode 100644 lib/dtas/source/splitfx.rb

diff --git a/examples/splitfx.sample.yml b/examples/splitfx.sample.yml
index 297e50b..3826012 100644
--- a/examples/splitfx.sample.yml
+++ b/examples/splitfx.sample.yml
@@ -11,6 +11,14 @@ comments:
   ARTIST: John Smith
   ALBUM: Hello World
   YEAR: 2013
+# override the normal sox command for dtas-player playback:
+command: exec sox "$INFILE" $SOXFMT - $TRIMFX $RGFX $FX
+env:
+  # these effects may be used in any command in this file, including targets
+  FX:
+    highpass -1 120 highpass 40 highpass 40
+    ladspa -lr tap_limiter -10 9.5
+    stats
 track_start: 1 # 0 for pregap/intro tracks
 cdda_align: true
 tracks:
diff --git a/lib/dtas/player.rb b/lib/dtas/player.rb
index 39e5abf..0ae8cef 100644
--- a/lib/dtas/player.rb
+++ b/lib/dtas/player.rb
@@ -8,6 +8,7 @@ require_relative 'source'
 require_relative 'source/sox'
 require_relative 'source/av'
 require_relative 'source/ff'
+require_relative 'source/splitfx'
 require_relative 'source/cmd'
 require_relative 'sink'
 require_relative 'unix_server'
@@ -44,9 +45,10 @@ class DTAS::Player # :nodoc:
     @current = nil
     @watchers = {}
     @source_map = {
-      "sox" => DTAS::Source::Sox.new,
+      "sox" => (sox = DTAS::Source::Sox.new),
       "av" => DTAS::Source::Av.new,
       "ff" => DTAS::Source::Ff.new,
+      "splitfx" => DTAS::Source::SplitFX.new(sox),
     }
     source_map_reload
   end
diff --git a/lib/dtas/source/splitfx.rb b/lib/dtas/source/splitfx.rb
new file mode 100644
index 0000000..ad9e7c1
--- /dev/null
+++ b/lib/dtas/source/splitfx.rb
@@ -0,0 +1,92 @@
+# Copyright (C) 2014, all contributors <dtas-all@nongnu.org>
+# License: GPLv3 or later <https://www.gnu.org/licenses/gpl-3.0.txt>
+require 'yaml'
+require_relative 'sox'
+require_relative '../splitfx'
+
+class DTAS::Source::SplitFX < DTAS::Source::Sox # :nodoc:
+  MAX_YAML_SIZE = 512 * 1024
+  attr_writer :sox
+
+  SPLITFX_DEFAULTS = SOX_DEFAULTS.merge("tryorder" => 3)
+
+  def initialize(sox = DTAS::Source::Sox.new)
+    command_init(SPLITFX_DEFAULTS)
+    @sox = sox
+  end
+
+  def try(ymlfile, offset = nil)
+    @splitfx = @ymlhash = nil
+    st = File.stat(ymlfile)
+    return false if !st.file? || st.size > MAX_YAML_SIZE
+
+    # read 4 bytes first to ensure we have a YAML file with a hash:
+    buf = ""
+    File.open(ymlfile, "rb") do |fp|
+      return false if fp.read(4, buf) != "---\n"
+      buf << fp.read
+    end
+
+    sfx = DTAS::SplitFX.new
+    begin
+      Dir.chdir(File.dirname(ymlfile)) do # ugh
+        sfx.import(@ymlhash = YAML.load(buf))
+        sfx.infile.replace(File.expand_path(sfx.infile))
+      end
+      @splitfx = sfx
+    rescue
+      return false
+    end
+    @infile = ymlfile
+    sox = @sox.try(sfx.infile, offset) or return false
+    rv = source_file_dup(ymlfile, offset)
+    rv.sox = sox
+    rv.env = sfx.env
+    rv
+  end
+
+  def __load_comments
+    @ymlhash["comments"] || @sox.__load_comments
+  end
+
+  def command_string
+    @ymlhash["command"] || @sox.command_string
+  end
+
+  def spawn(player_format, rg_state, opts)
+    raise "BUG: #{self.inspect}#spawn called twice" if @to_io
+    e = @env.merge!(player_format.to_env)
+    e["INFILE"] = @sox.infile
+
+    # make sure these are visible to the "current" command...
+    e["TRIMFX"] = @offset ? "trim #@offset" : nil
+    e["RGFX"] = rg_state.effect(self) || nil
+    e.merge!(@rg.to_env) if @rg
+
+    @pid = dtas_spawn(e, command_string, opts)
+  end
+
+  def to_hsh
+    to_hash.delete_if { |k,v| v == SPLITFX_DEFAULTS[k] }
+  end
+
+  def format
+    @sox.format
+  end
+
+  def samples!
+    @sox.samples!
+  end
+
+  def samples
+    @sox.samples
+  end
+
+  def source_defaults
+    SPLITFX_DEFAULTS
+  end
+
+  def cuebreakpoints
+    @splitfx.cuebreakpoints
+  end
+end
diff --git a/lib/dtas/splitfx.rb b/lib/dtas/splitfx.rb
index ac39233..9af3faf 100644
--- a/lib/dtas/splitfx.rb
+++ b/lib/dtas/splitfx.rb
@@ -12,6 +12,7 @@ class DTAS::SplitFX # :nodoc:
         '$TRIMFX $RATEFX $DITHERFX'
   include DTAS::Process
   include DTAS::XS
+  attr_reader :infile, :env
 
   class Skip < Struct.new(:tstart) # :nodoc:
     def commit(_)
@@ -76,6 +77,7 @@ class DTAS::SplitFX # :nodoc:
     }
     @tracks = []
     @infmt = nil # wait until input is assigned
+    @cuebp = nil # for playback
   end
 
   def _bool(hash, key)
@@ -334,4 +336,10 @@ class DTAS::SplitFX # :nodoc:
     end
     false
   end
+
+  def cuebreakpoints
+    rv = @cuebp and return rv
+    require_relative 'cue_index'
+    @cuebp = @tracks.map { |t| DTAS::CueIndex.new(1, "#{t.tstart}s") }
+  end
 end
diff --git a/test/test_player_integration.rb b/test/test_player_integration.rb
index 66f599e..2525ac5 100644
--- a/test/test_player_integration.rb
+++ b/test/test_player_integration.rb
@@ -208,11 +208,11 @@ class TestPlayerIntegration < Testcase
 
   def test_source_ed
     s = client_socket
-    assert_equal "sox av ff", s.req("source ls")
+    assert_equal "sox av ff splitfx", s.req("source ls")
     s.req_ok("source ed av tryorder=-1")
-    assert_equal "av sox ff", s.req("source ls")
+    assert_equal "av sox ff splitfx", s.req("source ls")
     s.req_ok("source ed av tryorder=")
-    assert_equal "sox av ff", s.req("source ls")
+    assert_equal "sox av ff splitfx", s.req("source ls")
 
     s.req_ok("source ed sox command=true")
     sox = YAML.load(s.req("source cat sox"))
-- 
EW



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 3/3] player: support "source restart" command
  2014-12-27 12:02 [PATCH 0/3] more functionality for editing audio Eric Wong
  2014-12-27 12:02 ` [PATCH 1/3] dtas-console: keys for "cue next/prev" Eric Wong
  2014-12-27 12:02 ` [PATCH 2/3] player: support playing splitfx YAML files Eric Wong
@ 2014-12-27 12:02 ` Eric Wong
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2014-12-27 12:02 UTC (permalink / raw)
  To: dtas-all; +Cc: Eric Wong

This becomes useful for systems without inotify when we're editing
YAML (or whatever) files frequently and want changes to be reflected
right away during playback.  This is a weaker version of the plain
"restart" command, which restarts the entire playback chain.
---
 Documentation/dtas-player_protocol.txt | 12 +++++++++++-
 lib/dtas/player/client_handler.rb      |  6 +++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/Documentation/dtas-player_protocol.txt b/Documentation/dtas-player_protocol.txt
index b8f8264..ff8f7ae 100644
--- a/Documentation/dtas-player_protocol.txt
+++ b/Documentation/dtas-player_protocol.txt
@@ -169,7 +169,9 @@ Commands here should be alphabetized according to `LC_ALL=C sort'
 * restart - restarts all processes in the current pipeline.  Playback
   will be momentarily interrupted while this change occurs.  This is
   necessary if one of the commands (e.g. sox or ecasound) or loaded
-  libraries (e.g. a LADSPA plugin) is upgraded.
+  libraries (e.g. a LADSPA plugin) is upgraded.  Use "source restart"
+  instead to only restart the source chain, leaving the sinks
+  untouched.
 
 * rg RGARGS - configure ReplayGain support
   All FLOAT values may be adjusted via '+=' or '-=' instead of simple
@@ -233,6 +235,14 @@ Commands here should be alphabetized according to `LC_ALL=C sort'
         1. input type (flac/opus/mp3/etc)
         2. transport protocol (local FS/http/ftp/sftp/etc)
 
+* source ls - dump the names of sources sorted by tryorder
+
+* source restart - restart the current source command
+  This can be useful if the source file is changed during playback
+  and the current player process is holding onto an unlinked inode.
+  This is advantageous over a full "restart" as there is no audible
+  gap on most systems.
+
 * state dump [FILENAME]
   Immediately dump the state of the player.  If a FILENAME is specified,
   the state is written to that file.  Otherwise, the default state file
diff --git a/lib/dtas/player/client_handler.rb b/lib/dtas/player/client_handler.rb
index 37357f7..35f85c2 100644
--- a/lib/dtas/player/client_handler.rb
+++ b/lib/dtas/player/client_handler.rb
@@ -463,7 +463,11 @@ module DTAS::Player::ClientHandler # :nodoc:
   def source_handler(io, msg)
     map = @source_map
     op = msg.shift
-    if op == "ls"
+    case op
+    when "restart"
+      __current_requeue
+      return io.emit("OK")
+    when "ls"
       s = map.keys.sort { |a,b| map[a].tryorder <=> map[b].tryorder }
       return io.emit(s.join(' '))
     end
-- 
EW



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-12-27 12:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-27 12:02 [PATCH 0/3] more functionality for editing audio Eric Wong
2014-12-27 12:02 ` [PATCH 1/3] dtas-console: keys for "cue next/prev" Eric Wong
2014-12-27 12:02 ` [PATCH 2/3] player: support playing splitfx YAML files Eric Wong
2014-12-27 12:02 ` [PATCH 3/3] player: support "source restart" command Eric Wong

everything related to duct tape audio suite (dtas)

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://80x24.org/dtas-all
	git clone --mirror http://ou63pmih66umazou.onion/dtas-all

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 dtas-all dtas-all/ https://80x24.org/dtas-all \
		dtas-all@nongnu.org
	public-inbox-index dtas-all

Example config snippet for mirrors.
Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.audio.dtas
	nntp://ou63pmih66umazou.onion/inbox.comp.audio.dtas
 note: .onion URLs require Tor: https://www.torproject.org/

code repositories for the project(s) associated with this inbox:

	../../../dtas.git

AGPL code for this site: git clone http://ou63pmih66umazou.onion/public-inbox.git