Kirika/audio/filter/resample_filter_nocgo.go
DataHoarder 6fde234fe6
All checks were successful
continuous-integration/drone/push Build is passing
Reduce dependencies, vendor resampler part of github.com/oov/audio
2022-11-30 08:09:16 +01:00

69 lines
1.8 KiB
Go

//go:build !cgo
package filter
import (
"git.gammaspectra.live/S.O.N.G/Kirika/audio"
"git.gammaspectra.live/S.O.N.G/Kirika/audio/filter/internal/resampler"
"log"
)
const (
QualityBest ResampleQuality = 10
QualityGood ResampleQuality = 8
QualityFast ResampleQuality = 5
QualityFastest ResampleQuality = 0
)
func (f ResampleFilter) Process(source audio.Source) audio.Source {
if source.GetSampleRate() == f.sampleRate { //no change
return source
}
outSource := audio.NewSource[float32](source.GetBitDepth(), f.sampleRate, source.GetChannels())
go func() {
defer outSource.Close()
samplerateConverter := resampler.New(source.GetChannels(), source.GetSampleRate(), f.sampleRate, int(f.quality))
for block := range source.ToFloat32().GetBlocks() {
output := make([][]float32, source.GetChannels())
input := make([][]float32, source.GetChannels())
outputBufferLength := 0
for i := 0; i < source.GetChannels(); i++ {
input[i] = make([]float32, len(block)/source.GetChannels())
ix := 0
for j := i; j < len(block); j += source.GetChannels() {
input[i][ix] = block[j]
ix++
}
output[i] = make([]float32, int(float64(len(block)/source.GetChannels())*(float64(f.sampleRate)/float64(source.GetSampleRate()))*1.1)) //resize to match expected output, with a fuzz factor of 10%
read, written := samplerateConverter.ProcessFloat32(i, input[i], output[i])
if read != len(input[i]) {
log.Panicf("could not read whole input: %d vs %d", len(input[i]), read)
}
output[i] = output[i][:written]
outputBufferLength += written
}
buffer := make([]float32, outputBufferLength)
for i, b := range output {
for j := range b {
buffer[i+j*len(output)] = b[j]
}
}
outSource.IngestFloat32(buffer)
}
}()
return outSource
}