Files
muse/lib/audio/oscillator.go

81 lines
2.0 KiB
Go

package audio
import "math"
// Generates audio samples for a given waveform type
func (g *Generator) generateOscillator(waveType string, freq, duration, amplitude, phase float64) []float64 {
samples := int(duration * g.sampleRate)
if samples <= 0 {
return nil
}
output := make([]float64, samples)
sampleRateInv := 1.0 / g.sampleRate
twoPiFreq := 2 * math.Pi * freq
fadeSamples := int(math.Min(0.005*g.sampleRate, float64(samples)*0.1))
fadeSamplesInv := 1.0 / float64(fadeSamples)
switch waveType {
case "sine":
for i := 0; i < samples; i++ {
t := float64(i)*sampleRateInv + phase
sample := math.Sin(twoPiFreq*t) * amplitude
if i < fadeSamples {
sample *= float64(i) * fadeSamplesInv
} else if i >= samples-fadeSamples {
sample *= float64(samples-i) * fadeSamplesInv
}
output[i] = sample
}
case "square":
for i := 0; i < samples; i++ {
t := float64(i)*sampleRateInv + phase
var sample float64
if math.Sin(twoPiFreq*t) > 0 {
sample = amplitude
} else {
sample = -amplitude
}
if i < fadeSamples {
sample *= float64(i) * fadeSamplesInv
} else if i >= samples-fadeSamples {
sample *= float64(samples-i) * fadeSamplesInv
}
output[i] = sample
}
case "saw":
for i := 0; i < samples; i++ {
t := float64(i)*sampleRateInv + phase
sample := (2*(t*freq-math.Floor(0.5+t*freq))) * amplitude
if i < fadeSamples {
sample *= float64(i) * fadeSamplesInv
} else if i >= samples-fadeSamples {
sample *= float64(samples-i) * fadeSamplesInv
}
output[i] = sample
}
case "triangle":
for i := 0; i < samples; i++ {
t := float64(i)*sampleRateInv + phase
sample := (math.Abs(2*(t*freq-math.Floor(t*freq+0.5)))*2 - 1) * amplitude
if i < fadeSamples {
sample *= float64(i) * fadeSamplesInv
} else if i >= samples-fadeSamples {
sample *= float64(samples-i) * fadeSamplesInv
}
output[i] = sample
}
default:
return output
}
return output
}