Skip to content

Commit

Permalink
#12 Clipping prevention done outside EBUR128
Browse files Browse the repository at this point in the history
  • Loading branch information
kartik-venugopal committed Aug 21, 2024
1 parent 4720d91 commit f6cd831
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 28 deletions.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ class ReplayGainUnit: EffectsUnit, ReplayGainUnitProtocol {
var replayGain: ReplayGain? {

didSet {

if preventClipping {
replayGain?.applyClippingPrevention(usingMaxPeakLevel: maxPeakLevel.decibels)
}

parmsChanged()
}
}
Expand All @@ -48,6 +53,11 @@ class ReplayGainUnit: EffectsUnit, ReplayGainUnitProtocol {
var maxPeakLevel: ReplayGainMaxPeakLevel {

didSet {

if preventClipping {
replayGain?.applyClippingPrevention(usingMaxPeakLevel: maxPeakLevel.decibels)
}

parmsChanged()
}
}
Expand Down
13 changes: 1 addition & 12 deletions Source/Core/EBUR128/EBUR128State.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,8 @@ class EBUR128State {
let loudness = try computeLoudness()
let peak = try computePeak()
let replayGain = Self.targetLoudness - loudness
var replayGainToPreventClipping: Double = replayGain

let newPeak = pow(10.0, replayGain / 20) * peak

if newPeak > Self.maxPeak {

let adjustment = 20 * log10(newPeak / Self.maxPeak)
replayGainToPreventClipping -= adjustment
}

return EBUR128AnalysisResult(loudness: loudness, peak: peak, replayGain: replayGain, replayGainToPreventClipping: replayGainToPreventClipping)
return EBUR128AnalysisResult(loudness: loudness, peak: peak, replayGain: replayGain)
}

func computeLoudness() throws -> Double {
Expand Down Expand Up @@ -154,7 +145,5 @@ struct EBUR128AnalysisResult {

let loudness: Double
let peak: Double

let replayGain: Double
let replayGainToPreventClipping: Double
}
42 changes: 26 additions & 16 deletions Source/Core/TrackIO/Model/ReplayGain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,51 @@ struct ReplayGain {

let trackGain: Float?
let trackPeak: Float?
let trackGainToPreventClipping: Float?

var trackGainToPreventClipping: Float? = nil

let albumGain: Float?
let albumPeak: Float?
let albumGainToPreventClipping: Float?

private static let maxPeak: Float = 1
var albumGainToPreventClipping: Float? = nil

init?(trackGain: Float? = nil, trackPeak: Float? = nil, albumGain: Float? = nil, albumPeak: Float? = nil) {

guard trackGain != nil || albumGain != nil else {return nil}

func gainToPreventClipping(gain: Float, peak: Float) -> Float {

let newPeak = pow(10.0, gain / 20) * peak
return newPeak > Self.maxPeak ? gain - (20 * log10(newPeak / Self.maxPeak)) : gain
}

self.trackGain = trackGain
self.trackPeak = trackPeak

self.albumGain = albumGain
self.albumPeak = albumPeak
}

private func gainToPreventClipping(gain: Float, peak: Float, usingMaxPeakLevel maxPeakLevel: Float) -> Float {

let newPeak = pow(10.0, gain / 20) * peak
return newPeak > maxPeakLevel ? gain - (20 * log10(newPeak / maxPeakLevel)) : gain
}

mutating func applyClippingPrevention(usingMaxPeakLevel maxPeakLevel: Float) {

applyClippingPreventionToTrackGain(usingMaxPeakLevel: maxPeakLevel)
applyClippingPreventionToAlbumGain(usingMaxPeakLevel: maxPeakLevel)
}

mutating func applyClippingPreventionToTrackGain(usingMaxPeakLevel maxPeakLevel: Float) {

if let theTrackGain = trackGain, let theTrackPeak = trackPeak {
self.trackGainToPreventClipping = gainToPreventClipping(gain: theTrackGain, peak: theTrackPeak)
self.trackGainToPreventClipping = gainToPreventClipping(gain: theTrackGain, peak: theTrackPeak, usingMaxPeakLevel: maxPeakLevel)

} else {
self.trackGainToPreventClipping = nil
}
self.albumGain = albumGain
self.albumPeak = albumPeak
}

mutating func applyClippingPreventionToAlbumGain(usingMaxPeakLevel maxPeakLevel: Float) {

if let theAlbumGain = albumGain, let theAlbumPeak = albumPeak {
self.albumGainToPreventClipping = gainToPreventClipping(gain: theAlbumGain, peak: theAlbumPeak)
self.albumGainToPreventClipping = gainToPreventClipping(gain: theAlbumGain, peak: theAlbumPeak, usingMaxPeakLevel: maxPeakLevel)
} else {
self.albumGainToPreventClipping = nil
}
Expand All @@ -56,10 +68,8 @@ struct ReplayGain {

self.trackGain = Float(ebur128AnalysisResult.replayGain)
self.trackPeak = Float(ebur128AnalysisResult.peak)
self.trackGainToPreventClipping = Float(ebur128AnalysisResult.replayGainToPreventClipping)

self.albumGain = nil
self.albumPeak = nil
self.albumGainToPreventClipping = nil
}
}

0 comments on commit f6cd831

Please sign in to comment.