# 使用Go播放音频：波形表

## 建立波形表

``````type Gtable struct {
data []float64
}

func NewSineTable(length int) *Gtable {
g := &Gtable{}
if length == 0 {
return g
}
g.data = make([]float64, length+1) // one extra for the guard point.
step := tau / float64(Len(g))
for i := 0; i < Len(g); i++ {
g.data[i] = math.Sin(step * float64(i))
}
// store a guard point
g.data[len(g.data)-1] = g.data[0]
return g
}

``````

## 振荡器

``````type LookupOscillator struct {
Oscillator
Table      *Gtable
SizeOverSr float64 // convenience variable for calculations
}

func NewLookupOscillator(sr int, t *Gtable, phase float64) (*LookupOscillator, error) {
if t == nil || len(t.data) == 0 {
return nil, errors.New("Invalid table provided for lookup oscillator")
}

return &LookupOscillator{
Oscillator: Oscillator{
curfreq:  0.0,
curphase: float64(Len(t)) * phase,
incr:     0.0,
},
Table:      t,
SizeOverSr: float64(Len(t)) / float64(sr),
}, nil
}

``````

``````func (l *LookupOscillator) TruncateTick(freq float64) []float64 {
index := l.curphase
if l.curfreq != freq {
l.curfreq = freq
l.incr = l.SizeOverSr * l.curfreq
}
curphase := l.curphase
curphase += l.incr
for curphase > float64(Len(l.Table)) {
curphase -= float64(Len(l.Table))
}
for curphase < 0.0 {
curphase += float64(Len(l.Table))
}
l.curphase = curphase
return l.Table.data[int(index)]
}

``````

….. …..
10 0.75
11 0.80
12 0.85

``````func (l *LookupOscillator) InterpolateTick(freq float64) float64 {
baseIndex := int(l.curphase)
nextIndex := baseIndex + 1
if l.curfreq != freq {
l.curfreq = freq
l.incr = l.SizeOverSr * l.curfreq
}
curphase := l.curphase
frac := curphase - float64(baseIndex)
val := l.Table.data[baseIndex]
slope := l.Table.data[nextIndex] - val
val += frac * slope
curphase += l.incr

for curphase > float64(Len(l.Table)) {
curphase -= float64(Len(l.Table))
}
for curphase < 0.0 {
curphase += float64(Len(l.Table))
}
l.curphase = curphase
return out
}

``````