Improved normalization filter
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
DataHoarder 2022-03-08 12:50:15 +01:00
parent 1189316ff5
commit ace1c78c0a
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
3 changed files with 48 additions and 9 deletions

View file

@ -4,6 +4,7 @@ import (
"git.gammaspectra.live/S.O.N.G/Kirika/audio"
libebur128 "git.gammaspectra.live/S.O.N.G/go-ebur128"
"math"
"time"
)
//NewReplayGainFilter Creates a VolumeFilter applying calculated ReplayGain values, pre amplifying by preAmp. Values are in dB
@ -17,6 +18,13 @@ func NewReplayGainFilter(gain, peak, preAmp float64) audio.VolumeFilter {
// NormalizationFilter Normalizes running audio source
type NormalizationFilter struct {
delay int
}
func NewNormalizationFilter(delayInSeconds int) NormalizationFilter {
return NormalizationFilter{
delay: delayInSeconds,
}
}
func (f NormalizationFilter) Process(source audio.Source) audio.Source {
@ -30,12 +38,21 @@ func (f NormalizationFilter) Process(source audio.Source) audio.Source {
}
defer state.Close()
if state.SetMaxWindow(time.Second*time.Duration(f.delay)) != nil {
return
}
var sampleBuffer []float32
var adjustment float32 = 1.0
for block := range source.Blocks {
if state.AddFloat(block) != nil {
return
}
loudness, _ := state.GetLoudnessShortTerm()
sampleBuffer = append(sampleBuffer, block...)
loudness, _ := state.GetLoudnessWindow(time.Second * time.Duration(f.delay))
peakSlice, _ := state.GetPreviousSamplePeak()
var peak float64
@ -45,15 +62,37 @@ func (f NormalizationFilter) Process(source audio.Source) audio.Source {
}
}
volume := math.Pow(10, (referenceLevel-loudness)/20)
gain := referenceLevel - loudness
if gain > 52 {
gain = 52
} else if gain < -52 {
gain = -52
}
volume := math.Pow(10, (gain)/20)
//prevent clipping
volume = math.Min(volume, 1/peak)
adjustment := float32(volume)
adjustment = float32(volume)
out := make([]float32, len(block))
for i := range block {
out[i] = block[i] * adjustment
nsamples := source.SampleRate * source.Channels * f.delay
if len(sampleBuffer) > nsamples {
size := len(sampleBuffer) - nsamples
out := make([]float32, size)
for i, e := range sampleBuffer[:size] {
out[i] = e * adjustment
}
outBlocks <- out
sampleBuffer = sampleBuffer[size:]
}
}
//flush
if len(sampleBuffer) > 0 {
out := make([]float32, len(sampleBuffer))
for i := range sampleBuffer {
out[i] = sampleBuffer[i] * adjustment
}
outBlocks <- out
}

2
go.mod
View file

@ -3,7 +3,7 @@ module git.gammaspectra.live/S.O.N.G/Kirika
go 1.18
require (
git.gammaspectra.live/S.O.N.G/go-ebur128 v0.0.0-20220308105126-3299585e6a9a
git.gammaspectra.live/S.O.N.G/go-ebur128 v0.0.0-20220308113719-afad5c6e5c28
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220228131722-e9cb84c52f48
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220227175608-6cc027f24dba
git.gammaspectra.live/S.O.N.G/go-tta v0.2.1-0.20220226150007-096de1072bd6

4
go.sum
View file

@ -1,5 +1,5 @@
git.gammaspectra.live/S.O.N.G/go-ebur128 v0.0.0-20220308105126-3299585e6a9a h1:cEkgIB5RSBFcyeB/VhpHiuYof2V/nMU5js46UroYs4c=
git.gammaspectra.live/S.O.N.G/go-ebur128 v0.0.0-20220308105126-3299585e6a9a/go.mod h1:5H4eVW9uknpn8REFr+C3ejhvXdncgm/pbGqKGC43gFY=
git.gammaspectra.live/S.O.N.G/go-ebur128 v0.0.0-20220308113719-afad5c6e5c28 h1:7YLU2eyGBX8juV445KlBxW71NjFAzbRvfotZBUP16Bs=
git.gammaspectra.live/S.O.N.G/go-ebur128 v0.0.0-20220308113719-afad5c6e5c28/go.mod h1:5H4eVW9uknpn8REFr+C3ejhvXdncgm/pbGqKGC43gFY=
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220228131722-e9cb84c52f48 h1:MaKiBfXQl0keyfdCi1PxGOKRTiWhIs8PqCal5GhKDi0=
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220228131722-e9cb84c52f48/go.mod h1:pkWt//S9hLVEQaJDPu/cHHPk8vPpo/0+zHy0me4LIP4=
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220227175608-6cc027f24dba h1:JEaxCVgdr3XXAuDCPAx7ttLFZaaHzTEzG+oRnVUtUKU=