Kirika/audio/filter/resample_filter_cgo.go
2022-05-20 17:23:50 +02:00

74 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.SampleRate == f.sampleRate { //no change
return source
}
outBlocks := make(chan []float32)
go func() {
defer close(outBlocks)
blockSize := f.blockSize * source.Channels
samplerateConverter, err := gosamplerate.New(int(f.quality), source.Channels, blockSize)
if err != nil {
log.Panic(err)
}
defer gosamplerate.Delete(samplerateConverter)
ratio := float64(f.sampleRate) / float64(source.SampleRate)
for block := range source.Blocks {
for len(block) >= blockSize {
b, err := samplerateConverter.Process(block[0:blockSize], ratio, false)
if err != nil {
log.Panic(err)
}
if len(b) > 0 {
outBlocks <- 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 {
outBlocks <- b
}
}
}
b, err := samplerateConverter.Process([]float32{}, ratio, true)
if err != nil {
log.Panic(err)
}
if len(b) > 0 {
outBlocks <- b
}
}()
return audio.Source{
Channels: source.Channels,
SampleRate: f.sampleRate,
Blocks: outBlocks,
}
}