lib/dtas/rg_state.rb in dtas-0.12.1 vs lib/dtas/rg_state.rb in dtas-0.13.0
- old
+ new
@@ -1,7 +1,8 @@
-# Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
-# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
+# Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
+# License: GPL-3.0+ (https://www.gnu.org/licenses/gpl-3.0.txt)
+# frozen_string_literal: true
#
# provides support for generating appropriate effects for ReplayGain
# MAYBE: account for non-standard reference loudness (89.0 dB is standard)
require_relative '../dtas'
require_relative 'serialize'
@@ -17,10 +18,11 @@
"album_peak" => :rg_vol_norm,
"track_peak" => :rg_vol_norm,
}
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,
"preamp" => 0, # no extra adjustment
@@ -32,10 +34,17 @@
}
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)
end
end
@@ -48,48 +57,63 @@
def to_hash
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).freeze
+ 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
- return if (@norm_level - diff).abs < @norm_threshold
- diff += @norm_level
- sprintf('gain %0.8g', linear_to_db(diff))
+ n = @norm_level == 1.0 ? @volume : @norm_level
+ diff = n - val.to_f
+ return if (n - diff).abs < @norm_threshold
+ diff += n
+ to_sox_gain(linear_to_db(diff))
end
# The ReplayGain fallback adjustment value (in dB), in case a file is
# missing ReplayGain tags. This is useful to avoid damage to speakers,
# 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
- rg = source.replaygain or
- return rg_fallback_effect("ReplayGain tags missing")
+ unless @mode
+ return @volume == 1.0 ? nil : to_sox_gain(vol_db)
+ end
+ rg = source.replaygain(@mode) or
+ return rg_fallback_effect("ReplayGain tags missing for #@mode")
val = rg.__send__(@mode)
if ! val && @fallback_track && @mode =~ /\Aalbum_(\w+)/
tag = "track_#$1"
val = rg.__send__(tag) or
return rg_fallback_effect("ReplayGain tag for #@mode missing")