mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
Throughout sointu, we assume stereo audiobuffers, but were passing around []float32. This had several issues, including len(buf)/2 and numSamples*2 type of length conversion in many places. Also, it caused one bug in a test case, causing it to succeed when it should have not (the test had +-1 when it should have had +-2). This refactoring makes it impossible to have odd length buffer issues.
56 lines
1.4 KiB
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.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 sointu.AudioBuffer) (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
|
|
}
|