mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
51 lines
1.3 KiB
Go
51 lines
1.3 KiB
Go
package oto
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/hajimehoshi/oto"
|
|
"github.com/vsariola/sointu/audio"
|
|
)
|
|
|
|
// OtoPlayer wraps github.com/hajimehoshi/oto to play sointu-style float32[] audio
|
|
type OtoPlayer struct {
|
|
context *oto.Context
|
|
player *oto.Player
|
|
}
|
|
|
|
// Play implements the audio.Player interface for OtoPlayer
|
|
func (o *OtoPlayer) Play(floatBuffer []float32) (err error) {
|
|
if byteBuffer, err := audio.FloatBufferTo16BitLE(floatBuffer); err != nil {
|
|
return fmt.Errorf("cannot convert buffer to bytes: %w", err)
|
|
} else if _, err := o.player.Write(byteBuffer); err != nil {
|
|
return fmt.Errorf("cannot write to player: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Close disposes of resources
|
|
func (o *OtoPlayer) Close() error {
|
|
if err := o.player.Close(); err != nil {
|
|
return fmt.Errorf("cannot close player: %w", err)
|
|
}
|
|
if err := o.context.Close(); err != nil {
|
|
return fmt.Errorf("cannot close oto context: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
const otoBufferSize = 8192
|
|
|
|
// NewPlayer creates and initializes a new OtoPlayer
|
|
func NewPlayer() (*OtoPlayer, error) {
|
|
context, err := oto.NewContext(44100, 2, 2, otoBufferSize)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot create oto context: %w", err)
|
|
}
|
|
|
|
player := context.NewPlayer()
|
|
return &OtoPlayer{
|
|
context: context,
|
|
player: player,
|
|
}, nil
|
|
}
|