Kirika/audio/filter/resample_filter_cgo.go
DataHoarder 09f3cf3b56
All checks were successful
continuous-integration/drone/push Build is passing
Use generics to implement TypedSource[float32|int16|int32]
2022-07-22 12:07:01 +02:00

70 lines
1.6 KiB
Go

//go:build cgo
package filter
import (
"git.gammaspectra.live/S.O.N.G/Kirika/audio"
"github.com/dh1tw/gosamplerate"
"log"
)
const (
QualityBest ResampleQuality = gosamplerate.SRC_SINC_BEST_QUALITY
QualityGood ResampleQuality = gosamplerate.SRC_SINC_MEDIUM_QUALITY
QualityFast ResampleQuality = gosamplerate.SRC_SINC_FASTEST
QualityFastest ResampleQuality = gosamplerate.SRC_LINEAR
)
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()
blockSize := f.blockSize * source.GetChannels()
samplerateConverter, err := gosamplerate.New(int(f.quality), source.GetChannels(), blockSize)
if err != nil {
log.Panic(err)
}
defer gosamplerate.Delete(samplerateConverter)
ratio := float64(f.sampleRate) / float64(source.GetSampleRate())
for block := range source.ToFloat32().GetBlocks() {
for len(block) >= blockSize {
b, err := samplerateConverter.Process(block[0:blockSize], ratio, false)
if err != nil {
log.Panic(err)
}
if len(b) > 0 {
outSource.IngestFloat32(b)
}
block = block[blockSize:]
}
if len(block) > 0 {
b, err := samplerateConverter.Process(block, ratio, false)
if err != nil {
log.Panic(err)
}
if len(b) > 0 {
outSource.IngestFloat32(b)
}
}
}
b, err := samplerateConverter.Process([]float32{}, ratio, true)
if err != nil {
log.Panic(err)
}
if len(b) > 0 {
outSource.IngestFloat32(b)
}
}()
return outSource
}