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)) }