DataHoarder
09f3cf3b56
All checks were successful
continuous-integration/drone/push Build is passing
70 lines
1.6 KiB
Go
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
|
|
}
|