Improved normalization filter
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
1189316ff5
commit
ace1c78c0a
|
@ -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
2
go.mod
|
@ -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
4
go.sum
|
@ -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=
|
||||
|
|
Loading…
Reference in a new issue