sointu/oto/oto.go
vsariola 1a5251dbf6 refactor(sointu): change the name of AudioSink into AudioOutput
The interface is never used as anything else as Output so trying to generalize as something more vague like Sink made no sense.
2021-08-30 23:11:33 +03:00

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.AudioOutput {
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
}