func (o *Osc) Sample() (output float64) {
	if o == nil {
		return
	}
	o.currentSample++
	if o.CurrentPhaseAngle < -math.Pi {
		o.CurrentPhaseAngle += TwoPi
	} else if o.CurrentPhaseAngle > math.Pi {
		o.CurrentPhaseAngle -= TwoPi
	}
	var amp float64
	if o.attackInSamples > o.currentSample {
		amp = float64(o.currentSample) * (o.Amplitude / float64(o.attackInSamples))
	} else {
		amp = o.Amplitude
	}
	switch o.Shape {
	case WaveSine:
		output = amp*Sine(o.CurrentPhaseAngle) + o.DcOffset
	case WaveTriangle:
		output = amp*Triangle(o.CurrentPhaseAngle) + o.DcOffset
	case WaveSaw:
		output = amp*Sawtooth(o.CurrentPhaseAngle) + o.DcOffset
	case WaveSqr:
		fmt.Println(o.CurrentPhaseAngle)
		output = amp*Square(o.CurrentPhaseAngle) + o.DcOffset
	}
	o.CurrentPhaseAngle += o.phaseAngleIncr
	return output
}
Sample returns the next sample generated by the oscillator
package generator
import (
	"fmt"
	"math"
	"github.com/go-audio/audio"
)
type Osc struct {
	Shape     WaveType
	Amplitude float64
	DcOffset  float64
	Freq      float64
	Fs                int
	PhaseOffset       float64
	CurrentPhaseAngle float64
	phaseAngleIncr    float64
	currentSample int
	attackInSamples int
}
func NewOsc(shape WaveType, hz float64, fs int) *Osc {
	return &Osc{Shape: shape, Amplitude: 1, Freq: hz, Fs: fs, phaseAngleIncr: ((hz * TwoPi) / float64(fs))}
}
func (o *Osc) Reset() {
	o.phaseAngleIncr = ((o.Freq * TwoPi) / float64(o.Fs))
	o.currentSample = 0
}
func (o *Osc) SetFreq(hz float64) {
	if o.Freq != hz {
		o.Freq = hz
		o.phaseAngleIncr = ((hz * TwoPi) / float64(o.Fs))
	}
}
func (o *Osc) SetAttackInMs(ms int) {
	if o == nil {
		return
	}
	if ms <= 0 {
		o.attackInSamples = 0
		return
	}
	o.attackInSamples = int(float32(o.Fs) / (1000.0 / float32(ms)))
}
func (o *Osc) Signal(length int) []float64 {
	output := make([]float64, length)
	for i := 0; i < length; i++ {
		output[i] = o.Sample()
	}
	return output
}
func (o *Osc) Fill(buf *audio.FloatBuffer) error {
	if o == nil {
		return nil
	}
	numChans := 1
	if f := buf.Format; f != nil {
		numChans = f.NumChannels
	}
	frameCount := buf.NumFrames()
	var sample float64
	for i := 0; i < frameCount; i++ {
		sample = o.Sample()
		for j := 0; j < numChans; j++ {
			buf.Data[i*numChans+j] = sample
		}
	}
	return nil
}