resample.go
package audio
// DefaultMaxSampleRate is the maximum sample rate for spectrograms.
const DefaultMaxSampleRate = 16000
// ResampleRate converts samples from one sample rate to another using linear interpolation.
// This is used to downsample high sample rate audio for spectrogram visualization.
// fromRate: original sample rate (e.g., 250000)
// toRate: target sample rate (e.g., 16000)
func ResampleRate(samples []float64, fromRate, toRate int) []float64 {
if fromRate == toRate || len(samples) == 0 {
return samples
}
// speed = fromRate/toRate: e.g. 250000/16000 = 15.625 (skip samples to downsample)
return Resample(samples, float64(fromRate)/float64(toRate))
}
// Resample changes playback speed using linear interpolation.
// speed > 1.0 = faster (fewer samples), speed < 1.0 = slower (more samples).
// For half-speed playback, use speed=0.5 which doubles the sample count.
func Resample(samples []float64, speed float64) []float64 {
if speed == 1.0 || len(samples) == 0 {
return samples
}
// Calculate new length: slower speed = more samples
newLen := int(float64(len(samples)) / speed)
if newLen <= 0 {
return samples
}
result := make([]float64, newLen)
for i := range newLen {
// Source index in original samples (floating point)
srcIdx := float64(i) * speed
idx0 := int(srcIdx)
idx1 := idx0 + 1
// Clamp to valid range
if idx0 >= len(samples) {
idx0 = len(samples) - 1
}
if idx1 >= len(samples) {
idx1 = len(samples) - 1
}
// Linear interpolation between adjacent samples
frac := srcIdx - float64(idx0)
result[i] = samples[idx0]*(1-frac) + samples[idx1]*frac
}
return result
}