about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/dtas/mlib.rb36
-rw-r--r--lib/dtas/source/av_ff_common.rb1
-rw-r--r--lib/dtas/source/sox.rb4
-rw-r--r--lib/dtas/source/splitfx.rb4
4 files changed, 30 insertions, 15 deletions
diff --git a/lib/dtas/mlib.rb b/lib/dtas/mlib.rb
index 1f61369..3bfed8f 100644
--- a/lib/dtas/mlib.rb
+++ b/lib/dtas/mlib.rb
@@ -5,6 +5,10 @@
 #
 require_relative '../dtas'
 require_relative 'process'
+require_relative 'source/sox'
+require_relative 'source/av'
+require_relative 'source/ff'
+require_relative 'source/splitfx'
 require 'socket'
 
 # For the DTAS Music Library, based on what MPD uses.
@@ -53,12 +57,18 @@ class DTAS::Mlib # :nodoc:
     @tag_map = nil
     @suffixes = nil
     @work = nil
+    @sources = [ # order matters
+      (sox = DTAS::Source::Sox.new),
+      DTAS::Source::Av.new,
+      DTAS::Source::Ff.new,
+      DTAS::Source::SplitFX.new(sox),
+    ]
   end
 
   def init_suffixes
     `sox --help 2>/dev/null` =~ /\nAUDIO FILE FORMATS:\s*([^\n]+)/s
     re = $1.split(/\s+/).map { |x| Regexp.quote(x) }.join('|')
-    @suffixes = Regexp.new("\\.(?:#{re})\\z", Regexp::IGNORECASE)
+    @suffixes = Regexp.new("\\.(?:#{re}|yml)\\z", Regexp::IGNORECASE)
   end
 
   def worker(todo)
@@ -89,22 +99,17 @@ class DTAS::Mlib # :nodoc:
       Dir.chdir(wd)
       @pwd = wd
     end
-    tmp = {}
     path = job.path
-    tlen = qx(%W(soxi -D #{path}), no_raise: true)
-    return ignore(job) unless String === tlen
-    tlen = tlen.to_f
+    found = nil
+    @sources.each do |src|
+      found = src.try(path) and break
+    end
+    return ignore(job) unless found
+    tlen = found.duration
     return ignore(job) if tlen < 0
     tlen = tlen.round
-    buf = qx(%W(soxi -a #{path}), no_raise: true)
-    return ignore(job) unless String === buf
-
-    # no, we don't support comments with newlines in them
-    buf = buf.split("\n")
-    while line = buf.shift
-      tag, value = line.split('=', 2)
-      tag && value or next
-      tag.downcase!
+    tmp = {}
+    found.comments.each do |tag, value|
       tag_id = @tag_map[tag] or next
       value.strip!
 
@@ -183,6 +188,8 @@ class DTAS::Mlib # :nodoc:
     %w(track disc).each do |x|
       tag_id = tag_map[x] and tag_map["#{x}number"] = tag_id
     end
+    @tag_rmap = tag_map.invert.freeze
+    tag_map.merge!(Hash[*(tag_map.map { |k,v| [k.upcase.freeze, v] }.flatten!)])
     @tag_map = tag_map.freeze
   end
 
@@ -354,7 +361,6 @@ class DTAS::Mlib # :nodoc:
 
     # success
     load_tags
-    @tag_rmap = @tag_map.invert
     if found[:tlen] == DM_DIR
       emit_recurse(found, cache, cb)
     else
diff --git a/lib/dtas/source/av_ff_common.rb b/lib/dtas/source/av_ff_common.rb
index 0fb3ace..58d9f54 100644
--- a/lib/dtas/source/av_ff_common.rb
+++ b/lib/dtas/source/av_ff_common.rb
@@ -19,6 +19,7 @@ module DTAS::Source::AvFfCommon # :nodoc:
 
   attr_reader :precision # always 32
   attr_reader :format
+  attr_reader :duration
 
   def try(infile, offset = nil, trim = nil)
     rv = source_file_dup(infile, offset, trim)
diff --git a/lib/dtas/source/sox.rb b/lib/dtas/source/sox.rb
index 9d128a6..db1ace2 100644
--- a/lib/dtas/source/sox.rb
+++ b/lib/dtas/source/sox.rb
@@ -53,6 +53,10 @@ class DTAS::Source::Sox # :nodoc:
     @format ||= DTAS::Format.from_file(@env, @infile)
   end
 
+  def duration
+    samples / format.rate.to_f
+  end
+
   # This is the number of samples according to the samples in the source
   # file itself, not the decoded output
   def samples
diff --git a/lib/dtas/source/splitfx.rb b/lib/dtas/source/splitfx.rb
index d824959..f746bee 100644
--- a/lib/dtas/source/splitfx.rb
+++ b/lib/dtas/source/splitfx.rb
@@ -107,6 +107,10 @@ class DTAS::Source::SplitFX < DTAS::Source::Sox # :nodoc:
     @sox.samples
   end
 
+  def duration
+    @sox.duration
+  end
+
   def source_defaults
     SPLITFX_DEFAULTS
   end