|
- package audio
-
- // ResampledSource adapts a WAVSource to a different sample rate using
- // linear interpolation between adjacent samples.
- type ResampledSource struct {
- src *WAVSource
- ratio float64 // source rate / target rate
- position float64 // fractional position in source frames
- }
-
- // NewResampledSource wraps a WAV source with rate conversion.
- func NewResampledSource(src *WAVSource, targetSampleRate float64) *ResampledSource {
- ratio := 1.0
- if src != nil && src.SampleRate > 0 && targetSampleRate > 0 {
- ratio = float64(src.SampleRate) / targetSampleRate
- }
- return &ResampledSource{src: src, ratio: ratio}
- }
-
- // NextFrame returns the next interpolated stereo frame.
- func (s *ResampledSource) NextFrame() Frame {
- if s.src == nil || len(s.src.frames) == 0 {
- return NewFrame(0, 0)
- }
-
- n := len(s.src.frames)
- idx0 := int(s.position) % n
- idx1 := (idx0 + 1) % n
- frac := s.position - float64(int(s.position))
-
- f0 := s.src.frames[idx0]
- f1 := s.src.frames[idx1]
-
- l := float64(f0.L)*(1-frac) + float64(f1.L)*frac
- r := float64(f0.R)*(1-frac) + float64(f1.R)*frac
-
- s.position += s.ratio
- for s.position >= float64(n) {
- s.position -= float64(n)
- }
-
- return NewFrame(Sample(l), Sample(r))
- }
|