Class: DTAS::RGState

Inherits:
Object
  • Object
show all
Includes:
Serialize, Util
Defined in:
lib/dtas/rg_state.rb

Overview

:nodoc:

Constant Summary collapse

RG_MODE =
{
  # attribute name => method to use
  "album_gain" => :rg_vol_gain,
  "track_gain" => :rg_vol_gain,
  "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

  "preamp" => 0, # no extra adjustment
  # "mode" => "album_gain", # nil: off
  "mode" => nil, # nil: off
  "fallback_gain" => -6.0, # adjustment dB if necessary RG tag is missing
  "fallback_track" => true,
  "norm_level" => 1.0, # dBFS
}
SIVS =
RG_DEFAULT.keys

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util

#db_to_linear, #linear_to_db

Methods included from Serialize

#ivars_to_hash

Constructor Details

#initializeRGState

Returns a new instance of RGState.


44
45
46
47
48
# File 'lib/dtas/rg_state.rb', line 44

def initialize
  RG_DEFAULT.each do |k,v|
    instance_variable_set("@#{k}", v)
  end
end

Class Method Details

.load(hash) ⇒ Object


50
51
52
53
54
# File 'lib/dtas/rg_state.rb', line 50

def self.load(hash)
  rv = new
  hash.each { |k,v| rv.__send__("#{k}=", v) } if hash
  rv
end

Instance Method Details

#effect(source) ⇒ Object

returns an array (for command-line argument) for the effect needed to apply ReplayGain this may return nil


105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/dtas/rg_state.rb', line 105

def effect(source)
  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")
    warn("tag for #@mode missing, using #{tag}")
  end
  # this may be nil if the adjustment is too small:
  __send__(RG_MODE[@mode], val)
end

#rg_fallback_effect(reason) ⇒ Object

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


96
97
98
99
100
# File 'lib/dtas/rg_state.rb', line 96

def rg_fallback_effect(reason)
  val = (@fallback_gain || 0) + @preamp + vol_db
  warn(reason) if $DEBUG
  to_sox_gain(val)
end

#rg_vol_gain(val) ⇒ Object

returns a dB argument to the “gain” effect, nil if nothing found


80
81
82
83
# File 'lib/dtas/rg_state.rb', line 80

def rg_vol_gain(val)
  val = val.to_f + @preamp + vol_db
  to_sox_gain(val)
end

#rg_vol_norm(val) ⇒ Object

returns a DB argument to the “gain” effect


86
87
88
89
90
# File 'lib/dtas/rg_state.rb', line 86

def rg_vol_norm(val)
  n = @norm_level == 1.0 ? @volume : @norm_level
  diff = n * 2 - val.to_f
  to_sox_gain(linear_to_db(diff))
end

#to_hashObject


56
57
58
# File 'lib/dtas/rg_state.rb', line 56

def to_hash
  ivars_to_hash(SIVS)
end

#to_hshObject


64
65
66
67
# File 'lib/dtas/rg_state.rb', line 64

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

#to_sox_gain(val) ⇒ Object


69
70
71
72
73
74
75
76
77
# File 'lib/dtas/rg_state.rb', line 69

def to_sox_gain(val)
  case val.infinite?
  when -1 then return 'gain -192'
  when 1 then return 'gain 192'
  else
    val.abs <= 0.00000001 and return
    DTAS.dedupe_str(sprintf('gain %0.8f', val))
  end
end

#vol_dbObject


60
61
62
# File 'lib/dtas/rg_state.rb', line 60

def vol_db
  linear_to_db(@volume)
end

#volume=(val) ⇒ Object


39
40
41
42
# File 'lib/dtas/rg_state.rb', line 39

def volume=(val)
  val = 0 if val.to_i < 0
  @volume = val.round(4)
end