DataHoarder
6fde234fe6
All checks were successful
continuous-integration/drone/push Build is passing
69 lines
1.8 KiB
Go
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
|
|
}
|