made Volume filter work on integer samples natively

This commit is contained in:
DataHoarder 2022-07-29 11:41:39 +02:00
parent cd71da809b
commit 9ece89c3e6
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
3 changed files with 50 additions and 17 deletions

View file

@ -173,10 +173,10 @@ func (f RealTimeFilter) Process(source audio.Source) audio.Source {
}
type VolumeFilter struct {
adjustment float32
adjustment float64
}
func NewVolumeFilter(adjustment float32) VolumeFilter {
func NewVolumeFilter(adjustment float64) VolumeFilter {
return VolumeFilter{
adjustment: adjustment,
}
@ -187,21 +187,54 @@ func (f VolumeFilter) Process(source audio.Source) audio.Source {
return source
}
outSource := audio.NewSource[float32](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
go func() {
defer outSource.Close()
for block := range source.ToFloat32().GetBlocks() {
out := make([]float32, len(block))
for i := range block {
out[i] = block[i] * f.adjustment
if int32Source, ok := source.(audio.TypedSource[int32]); ok {
bpsMultiplier := int64((1 << (source.GetBitDepth() - 1)) - 1)
adjustment := int64(f.adjustment * float64(bpsMultiplier))
outSource := audio.NewSource[int32](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
go func() {
defer outSource.Close()
for block := range int32Source.GetBlocks() {
out := make([]int32, len(block))
for i := range block {
out[i] = int32((int64(block[i]) * adjustment) / bpsMultiplier)
}
outSource.IngestNative(out, source.GetBitDepth())
}
outSource.IngestFloat32(out)
}
}()
return outSource
} else if int16Source, ok := source.(audio.TypedSource[int16]); ok {
bpsMultiplier := int32((1 << (source.GetBitDepth() - 1)) - 1)
adjustment := int32(f.adjustment * float64(bpsMultiplier))
outSource := audio.NewSource[int16](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
go func() {
defer outSource.Close()
for block := range int16Source.GetBlocks() {
out := make([]int16, len(block))
for i := range block {
out[i] = int16((int32(block[i]) * adjustment) / bpsMultiplier)
}
outSource.IngestNative(out, source.GetBitDepth())
}
}()
return outSource
} else {
adjustment := float32(f.adjustment)
outSource := audio.NewSource[float32](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
go func() {
defer outSource.Close()
}()
for block := range source.ToFloat32().GetBlocks() {
out := make([]float32, len(block))
for i := range block {
out[i] = block[i] * adjustment
}
outSource.IngestNative(out, source.GetBitDepth())
}
return outSource
}()
return outSource
}
}
type StereoFilter struct {

View file

@ -22,7 +22,7 @@ func TestFilterChainNoResample(t *testing.T) {
return
}
result := NewFilterChain(source, MonoFilter{}, StereoFilter{})
result := NewFilterChain(source, NewVolumeFilter(0.5), MonoFilter{}, StereoFilter{})
sink := audio.NewForwardSink(audio.NewNullSink())
sink.Process(result)

View file

@ -5,11 +5,11 @@ import (
"math"
)
//NewReplayGainFilter Creates a VolumeFilter applying calculated ReplayGain values, pre amplifying by preAmp. Values are in dB
// NewReplayGainFilter Creates a VolumeFilter applying calculated ReplayGain values, pre amplifying by preAmp. Values are in dB
func NewReplayGainFilter(gain, peak, preAmp float64) filter.VolumeFilter {
volume := math.Pow(10, (gain+preAmp)/20)
//prevent clipping
volume = math.Min(volume, 1/peak)
return filter.NewVolumeFilter(float32(volume))
return filter.NewVolumeFilter(volume)
}