about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-12-14 08:04:32 +0000
committerEric Wong <e@80x24.org>2015-12-14 08:20:34 +0000
commit7bed564d979ce7eceac9cd382be5c993cf0acfc5 (patch)
tree058d06d065f88fdcd65bf91c50bfb40e93105546 /lib
parent9263eecf93555beb3567af401a2bfdf25df5e8cd (diff)
downloaddtas-7bed564d979ce7eceac9cd382be5c993cf0acfc5.tar.gz
This is on a linear scale from 0.0 (mute) to 1.0 (no change)
This is in the MPRIS spec and mpd as well (scaled to 0-100)

This changes dtas-console key bindings (0/9) slightly to match
mplayer more closely.  ReplayGain preamp adjustment has moved from
'0'/'9' to '7'/'8' keys.  The 'm' key also toggles mute state (the
pre-mute volume is stored in the dtas-console instance, not in
dtas-player itself).
Diffstat (limited to 'lib')
-rw-r--r--lib/dtas/player/client_handler.rb2
-rw-r--r--lib/dtas/rg_state.rb38
2 files changed, 31 insertions, 9 deletions
diff --git a/lib/dtas/player/client_handler.rb b/lib/dtas/player/client_handler.rb
index a27e4f5..498388e 100644
--- a/lib/dtas/player/client_handler.rb
+++ b/lib/dtas/player/client_handler.rb
@@ -259,7 +259,7 @@ module DTAS::Player::ClientHandler # :nodoc:
         rv = set_bool(io, kv, v) { |b| @rg.fallback_track = b }
         rv == true or return rv
       when %r{(?:gain_threshold|norm_threshold|
-              preamp|norm_level|fallback_gain)[+-]?\z}x
+              preamp|norm_level|fallback_gain|volume)[+-]?\z}x
         rv = adjust_numeric(io, @rg, k, v)
         rv == true or return rv
       end
diff --git a/lib/dtas/rg_state.rb b/lib/dtas/rg_state.rb
index b124098..67706aa 100644
--- a/lib/dtas/rg_state.rb
+++ b/lib/dtas/rg_state.rb
@@ -19,6 +19,7 @@ class DTAS::RGState # :nodoc:
   }
 
   RG_DEFAULT = {
+    "volume" => 1.0,
     # skip the effect if the adjustment is too small to be noticeable
     "gain_threshold" => 0.00000001, # in dB
     "norm_threshold" => 0.00000001,
@@ -34,6 +35,13 @@ class DTAS::RGState # :nodoc:
   SIVS = RG_DEFAULT.keys
   SIVS.each { |iv| attr_accessor iv }
 
+  undef_method :volume=
+
+  def volume=(val)
+    val = 0 if val.to_i < 0
+    @volume = val.round(4)
+  end
+
   def initialize
     RG_DEFAULT.each do |k,v|
       instance_variable_set("@#{k}", v)
@@ -50,24 +58,37 @@ class DTAS::RGState # :nodoc:
     ivars_to_hash(SIVS)
   end
 
+  def vol_db
+    linear_to_db(@volume)
+  end
+
   def to_hsh
     # no point in dumping default values, it's just a waste of space
     to_hash.delete_if { |k,v| RG_DEFAULT[k] == v }
   end
 
+  def to_sox_gain(val)
+    case val.infinite?
+    when -1 then return 'gain -192'
+    when 1 then return 'gain 192'
+    else
+      sprintf('gain %0.8g', val)
+    end
+  end
+
   # returns a dB argument to the "gain" effect, nil if nothing found
   def rg_vol_gain(val)
-    val = val.to_f + @preamp
+    val = val.to_f + @preamp + vol_db
     return if val.abs < @gain_threshold
-    sprintf('gain %0.8g', val)
+    to_sox_gain(val)
   end
 
   # returns a DB argument to the "gain" effect
   def rg_vol_norm(val)
-    diff = @norm_level - val.to_f
+    diff = @norm_level - val.to_f + @volume
     return if (@norm_level - diff).abs < @norm_threshold
     diff += @norm_level
-    sprintf('gain %0.8g', linear_to_db(diff))
+    to_sox_gain(linear_to_db(diff))
   end
 
   # The ReplayGain fallback adjustment value (in dB), in case a file is
@@ -75,18 +96,19 @@ class DTAS::RGState # :nodoc:
   # eardrums and amplifiers in case a file without then necessary ReplayGain
   # tag slips into the queue
   def rg_fallback_effect(reason)
-    @fallback_gain or return
-    val = @fallback_gain + @preamp
+    val = (@fallback_gain || 0) + @preamp + vol_db
     return if val.abs < @gain_threshold
     warn(reason) if $DEBUG
-    "gain #{val}"
+    to_sox_gain(val)
   end
 
   # returns an array (for command-line argument) for the effect needed
   # to apply ReplayGain
   # this may return nil
   def effect(source)
-    return unless @mode
+    unless @mode
+      return @volume == 1.0 ? nil : to_sox_gain(vol_db)
+    end
     rg = source.replaygain or
       return rg_fallback_effect("ReplayGain tags missing")
     val = rg.__send__(@mode)