Skip to content

Commit

Permalink
#12 Clipping prevention - a start
Browse files Browse the repository at this point in the history
  • Loading branch information
kartik-venugopal committed Aug 19, 2024
1 parent 84c9360 commit e21842f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 9 deletions.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class FFmpegReplayGainScanner: ReplayGainScanner {

let ctx = try FFmpegFileContext(for: file)

guard let stream = ctx.bestAudioStream else {return .noResult}
guard let stream = ctx.bestAudioStream else {return nil}
let codec = try FFmpegAudioCodec(fromParameters: stream.avStream.codecpar)

channelCount = Int(codec.channelCount)
Expand Down
24 changes: 16 additions & 8 deletions Source/Core/EBUR128/EBUR128State.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class EBUR128State {
let sampleRate: Int
let mode: EBUR128Mode

static let targetLoudness: Double = -18
static let maxPeak: Double = 1

init(channelCount: Int, sampleRate: Int, mode: EBUR128Mode) throws {

self.channelCount = channelCount
Expand All @@ -50,8 +53,18 @@ 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)
return EBUR128AnalysisResult(loudness: loudness, peak: peak, replayGain: replayGain, replayGainToPreventClipping: replayGainToPreventClipping)
}

func computeLoudness() throws -> Double {
Expand Down Expand Up @@ -112,14 +125,9 @@ enum EBUR128Mode {

struct EBUR128AnalysisResult {

static let targetLoudness: Double = -18

let loudness: Double
let peak: Double

var replayGain: Double {
Self.targetLoudness - loudness
}

static let noResult: EBUR128AnalysisResult = .init(loudness: 0, peak: 0)
let replayGain: Double
let replayGainToPreventClipping: Double
}
33 changes: 33 additions & 0 deletions Source/Core/TrackIO/Model/ReplayGain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,49 @@ struct ReplayGain {

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

let albumGain: Float?
let albumPeak: Float?

private static let maxPeak: Float = 1

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

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

self.trackGain = trackGain
self.trackPeak = trackPeak

var trackGainToPreventClipping: Float

if let theTrackGain = trackGain, let theTrackPeak = trackPeak {

trackGainToPreventClipping = theTrackGain

let newPeak = pow(10.0, theTrackGain / 20) * theTrackPeak

if newPeak > Self.maxPeak {
trackGainToPreventClipping -= (20 * log10(newPeak / Self.maxPeak))
}

self.trackGainToPreventClipping = trackGainToPreventClipping

} else {
self.trackGainToPreventClipping = nil
}

self.albumGain = albumGain
self.albumPeak = albumPeak
}

init(ebur128AnalysisResult: EBUR128AnalysisResult) {

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

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

0 comments on commit e21842f

Please sign in to comment.