sointu/oto/oto.go

56 lines
1.4 KiB
Go

package oto
import (
"fmt"
"github.com/hajimehoshi/oto"
"github.com/vsariola/sointu"
)
type OtoContext oto.Context
type OtoOutput struct {
player *oto.Player
tmpBuffer []byte
}
func (c *OtoContext) Output() sointu.AudioSink {
return &OtoOutput{player: (*oto.Context)(c).NewPlayer(), tmpBuffer: make([]byte, 0)}
}
const otoBufferSize = 8192
// NewPlayer creates and initializes a new OtoPlayer
func NewContext() (*OtoContext, error) {
context, err := oto.NewContext(44100, 2, 2, otoBufferSize)
if err != nil {
return nil, fmt.Errorf("cannot create oto context: %w", err)
}
return (*OtoContext)(context), nil
}
func (c *OtoContext) Close() error {
if err := (*oto.Context)(c).Close(); err != nil {
return fmt.Errorf("cannot close oto context: %w", err)
}
return nil
}
// Play implements the audio.Player interface for OtoPlayer
func (o *OtoOutput) WriteAudio(floatBuffer []float32) (err error) {
// we reuse the old capacity tmpBuffer by setting its length to zero. then,
// we save the tmpBuffer so we can reuse it next time
o.tmpBuffer = FloatBufferTo16BitLE(floatBuffer, o.tmpBuffer[:0])
if _, err := o.player.Write(o.tmpBuffer); err != nil {
return fmt.Errorf("cannot write to player: %w", err)
}
return nil
}
// Close disposes of resources
func (o *OtoOutput) Close() error {
if err := o.player.Close(); err != nil {
return fmt.Errorf("cannot close oto player: %w", err)
}
return nil
}