stelleengine

package
v0.0.0-...-b8436b2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultSampleRate = 48000
	DefaultChannels   = 2
)
View Source
const (
	RingBufferFrames = DefaultSampleRate * 3
	DecodeChunkSize  = 11520
)

Variables

This section is empty.

Functions

func ConvertChannels

func ConvertChannels(in []float32, inCh, outCh int) []float32

ConvertChannels converts audio samples between different channel layouts.

params:
      in:    input samples (interleaved)
      inCh:  source channel count
      outCh: target channel count
returns:
      []float32
Note: Handles Mono (1) to Stereo (2), Stereo (2) to Mono (1), and a generic
      multichannel (>2) downmix to stereo by averaging odd/even source
      channels. Unhandled layouts return the input unchanged.

func ConvertInt16BytesToFloat32

func ConvertInt16BytesToFloat32(in []byte) []float32

ConvertInt16BytesToFloat32 converts a byte slice containing little-endian int16 audio samples to a slice of float32 [-1.0, 1.0].

params:
      in: raw bytes (2 bytes per sample, little-endian)
returns:
      []float32

func ConvertInt16ToFloat32

func ConvertInt16ToFloat32(in []int16) []float32

ConvertInt16ToFloat32 converts a slice of int16 audio samples to float32 [-1.0, 1.0].

params:
      in: raw int16 PCM samples
returns:
      []float32

func ProbeCodecs

func ProbeCodecs()

func Resample

func Resample(in []float32, inRate, outRate, channels int) []float32

Resample performs linear interpolation resampling on interleaved float32 samples.

params:
      in:       input samples (interleaved)
      inRate:   source sample rate
      outRate:  target sample rate
      channels: number of interleaved channels
returns:
      []float32: resampled output

Types

type ChunkDecoder

type ChunkDecoder interface {
	ReadSamples(buf []float32) (int, error)
	Channels() int
	SampleRate() int
	TotalFrames() int64
	Close() error
}

ChunkDecoder is a thin read-cursor over a decoded audio stream. Each codec (opus, vorbis, mp3) wraps its native C library into this interface.

type FlacChunkDecoder

type FlacChunkDecoder struct {
	// contains filtered or unexported fields
}

func (*FlacChunkDecoder) Channels

func (c *FlacChunkDecoder) Channels() int

Channels returns the number of audio channels.

func (*FlacChunkDecoder) Close

func (c *FlacChunkDecoder) Close() error

Close releases all resources associated with the decoder.

returns:
      error

func (*FlacChunkDecoder) ReadSamples

func (c *FlacChunkDecoder) ReadSamples(buf []float32) (int, error)

ReadSamples decodes audio from the FLAC stream into the provided buffer. Emits native-rate, native-channel PCM; the streaming layer handles channel and sample-rate normalization.

params:
      buf: destination buffer for float32 interleaved samples
returns:
      int: number of samples written
      error: io.EOF or decoding errors

func (*FlacChunkDecoder) SampleRate

func (c *FlacChunkDecoder) SampleRate() int

SampleRate returns the native sample rate of the file.

func (*FlacChunkDecoder) SeekToFrame

func (c *FlacChunkDecoder) SeekToFrame(frame int64) error

SeekToFrame moves the playback cursor to a specific sample frame.

params:
      frame: target frame offset
returns:
      error

func (*FlacChunkDecoder) TotalFrames

func (c *FlacChunkDecoder) TotalFrames() int64

TotalFrames returns the total number of audio frames.

type FlacDecoder

type FlacDecoder struct{}

func NewFlacDecoder

func NewFlacDecoder() *FlacDecoder

NewFlacDecoder returns a new FLAC decoder factory.

returns:
      *FlacDecoder

func (*FlacDecoder) CanHandle

func (d *FlacDecoder) CanHandle(ext string) bool

func (*FlacDecoder) Name

func (d *FlacDecoder) Name() string

type Mp3ChunkDecoder

type Mp3ChunkDecoder struct {
	// contains filtered or unexported fields
}

func (*Mp3ChunkDecoder) Channels

func (c *Mp3ChunkDecoder) Channels() int

func (*Mp3ChunkDecoder) Close

func (c *Mp3ChunkDecoder) Close() error

func (*Mp3ChunkDecoder) ReadSamples

func (c *Mp3ChunkDecoder) ReadSamples(buf []float32) (int, error)

ReadSamples decodes 16-bit PCM from the MP3 stream and converts to float32. Emits native-rate, native-channel samples; the streaming layer handles channel and sample-rate normalization.

params:
      buf: destination buffer for interleaved float32 samples
returns:
      int:   number of float32 values written
      error: io.EOF on end of stream

func (*Mp3ChunkDecoder) SampleRate

func (c *Mp3ChunkDecoder) SampleRate() int

func (*Mp3ChunkDecoder) SeekToFrame

func (c *Mp3ChunkDecoder) SeekToFrame(frame int64) error

SeekToFrame seeks to the specified PCM frame position using mpg123_seek.

params:
      frame: target frame offset
returns:
      error

func (*Mp3ChunkDecoder) TotalFrames

func (c *Mp3ChunkDecoder) TotalFrames() int64

type Mp3Decoder

type Mp3Decoder struct{}

func NewMp3Decoder

func NewMp3Decoder() *Mp3Decoder

NewMp3Decoder creates a new MP3 decoder instance.

returns:
      *Mp3Decoder

func (*Mp3Decoder) CanHandle

func (d *Mp3Decoder) CanHandle(ext string) bool

func (*Mp3Decoder) Name

func (d *Mp3Decoder) Name() string

type OggVorbis_File

type OggVorbis_File [2048]byte

OggVorbis_File is an opaque C struct (~700-1000 bytes). 2048 bytes covers all platforms.

type OpusChunkDecoder

type OpusChunkDecoder struct {
	// contains filtered or unexported fields
}

func (*OpusChunkDecoder) Channels

func (c *OpusChunkDecoder) Channels() int

func (*OpusChunkDecoder) Close

func (c *OpusChunkDecoder) Close() error

func (*OpusChunkDecoder) ReadSamples

func (c *OpusChunkDecoder) ReadSamples(buf []float32) (int, error)

ReadSamples decodes interleaved stereo float32 PCM from the Opus stream.

params:
      buf: destination buffer for interleaved samples
returns:
      int:   number of float32 values written
      error: io.EOF on end of stream

func (*OpusChunkDecoder) SampleRate

func (c *OpusChunkDecoder) SampleRate() int

func (*OpusChunkDecoder) SeekToFrame

func (c *OpusChunkDecoder) SeekToFrame(frame int64) error

SeekToFrame seeks to the specified PCM frame position.

params:
      frame: target frame offset
returns:
      error

func (*OpusChunkDecoder) TotalFrames

func (c *OpusChunkDecoder) TotalFrames() int64

type OpusDecoder

type OpusDecoder struct{}

func NewOpusDecoder

func NewOpusDecoder() *OpusDecoder

NewOpusDecoder creates a new Opus decoder instance.

returns:
      *OpusDecoder

func (*OpusDecoder) CanHandle

func (d *OpusDecoder) CanHandle(ext string) bool

func (*OpusDecoder) Name

func (d *OpusDecoder) Name() string

type RingBuffer

type RingBuffer struct {
	// contains filtered or unexported fields
}

RingBuffer is a lock-free circular buffer used to decouple the decoder goroutine from the SDL audio callback. The decoder writes decoded PCM float32 samples in, and the SDL callback reads them out.

func NewRingBuffer

func NewRingBuffer(frames, channels int) *RingBuffer

NewRingBuffer allocates a new ring buffer.

params:
      frames:   number of audio frames to buffer
      channels: number of audio channels (e.g. 2 for stereo)
returns:
      *RingBuffer

func (*RingBuffer) Available

func (rb *RingBuffer) Available() int

Available returns how many float32 samples are currently buffered.

func (*RingBuffer) Clear

func (rb *RingBuffer) Clear()

Clear resets the ring buffer read cursor to the write cursor to empty it.

func (*RingBuffer) Close

func (rb *RingBuffer) Close()

Close marks the buffer as closed.

func (*RingBuffer) Read

func (rb *RingBuffer) Read(dst []float32) int

Read copies available samples from the ring buffer into dst.

params:
      dst: destination slice to fill with samples
returns:
      int: number of float32 values actually copied

func (*RingBuffer) Reopen

func (rb *RingBuffer) Reopen()

Reopen resets the buffer to an empty, open state for reuse.

func (*RingBuffer) Write

func (rb *RingBuffer) Write(samples []float32) bool

Write pushes interleaved float32 samples into the ring buffer. Blocks if the buffer is full until space is available or the buffer is closed.

params:
      samples: interleaved float32 PCM data to write
returns:
      bool: false if the buffer was closed during the write

type SeekableChunkDecoder

type SeekableChunkDecoder interface {
	ChunkDecoder
	SeekToFrame(frame int64) error
}

SeekableChunkDecoder is the optional extension for decoders with native seek. Decoders that don't implement this get automatic re-open+skip seeking for free via the streaming goroutine fallback in streaming.go.

type StelleEngine

type StelleEngine struct {
	// contains filtered or unexported fields
}

func NewStelleEngine

func NewStelleEngine(volume float32) (*StelleEngine, error)

NewStelleEngine creates a new Stelle engine instance and initializes the SDL audio subsystem.

params:
      volume: default volume of the audio engine (0.0 - 1.0)
returns:
      *StelleEngine
      error: if the SDL audio subsystem fails to initialize

func (*StelleEngine) Close

func (e *StelleEngine) Close() error

Close tears down any active playback and shuts down the SDL audio subsystem. After Close the engine must not be reused.

returns:
      error
Note: Pairs with the sdl.Init in NewStelleEngine. Safe to call more than
      once; subsequent calls are no-ops.

func (*StelleEngine) GetChannels

func (e *StelleEngine) GetChannels() int

GetChannels returns the actual channel count of the current audio track.

returns:
      int

func (*StelleEngine) GetDuration

func (e *StelleEngine) GetDuration() float64

GetDuration returns the total duration of the current track in seconds.

returns:
      float64

func (*StelleEngine) GetPosition

func (e *StelleEngine) GetPosition() float64

GetPosition returns the current playback position in seconds.

returns:
      float64

func (*StelleEngine) GetSampleRate

func (e *StelleEngine) GetSampleRate() int

GetSampleRate returns the actual sample rate of the current audio track.

returns:
      int

func (*StelleEngine) GetState

func (e *StelleEngine) GetState() AudioEngine.PlaybackState

GetState returns the current playback state.

returns:
      AudioEngine.PlaybackState

func (*StelleEngine) GetUnderruns

func (e *StelleEngine) GetUnderruns() int64

GetUnderruns returns the total number of audio underruns detected on the active stream source.

func (*StelleEngine) Pause

func (e *StelleEngine) Pause() error

Pause pauses playback, preserving the current ring buffer state.

returns:
      error

func (*StelleEngine) Play

func (e *StelleEngine) Play(filePath string, seekTo float64, volume int) error

Play starts playing the audio file from the given position.

params:
      filePath: path to the audio file
      seekTo:   start position in seconds
      volume:   playback volume (0-100)
returns:
      error

func (*StelleEngine) Resume

func (e *StelleEngine) Resume(seekTo float64, volume int) error

Resume resumes a paused stream. Optionally repositions if seekTo is non-zero.

params:
      seekTo: position in seconds (0 = resume from current)
      volume: playback volume (0-100)
returns:
      error

func (*StelleEngine) Seek

func (e *StelleEngine) Seek(position float64, volume int) error

Seek jumps to the specified position while maintaining current playback state.

params:
      position: target position in seconds
      volume:   playback volume (0-100)
returns:
      error

func (*StelleEngine) SetOnComplete

func (e *StelleEngine) SetOnComplete(callback func())

SetOnComplete sets the callback invoked when playback finishes naturally.

params:
      callback: function to call on completion

func (*StelleEngine) SetVolume

func (e *StelleEngine) SetVolume(volume int)

SetVolume updates the playback volume dynamically.

params:
      volume: playback volume (0-100)

func (*StelleEngine) Stop

func (e *StelleEngine) Stop() error

Stop stops playback and resets state.

returns:
      error

type StreamingAudioSource

type StreamingAudioSource struct {
	// contains filtered or unexported fields
}

StreamingAudioSource is the decoder-agnostic bridge between a ChunkDecoder and the SDL audio callback. A background goroutine reads decoded PCM into the ring buffer, and the SDL callback drains it.

func NewStreamingSource

func NewStreamingSource(open openFn, seekTo float64) (*StreamingAudioSource, error)

NewStreamingSource opens a streaming source using the provided factory and spawns the background decoder goroutine.

params:
      open:   factory function that creates a ChunkDecoder
      seekTo: initial playback position in seconds
returns:
      *StreamingAudioSource, error

func (*StreamingAudioSource) AdvanceFrames

func (s *StreamingAudioSource) AdvanceFrames(n int64)

AdvanceFrames increments the internal position counter by n frames.

params:
      n: number of frames consumed by the SDL callback

func (*StreamingAudioSource) Channels

func (s *StreamingAudioSource) Channels() int

Channels returns the native channel count of the loaded audio file.

func (*StreamingAudioSource) Duration

func (s *StreamingAudioSource) Duration() float64

Duration returns the total duration of the audio source in seconds.

returns:
      float64: 0 if unknown

func (*StreamingAudioSource) Position

func (s *StreamingAudioSource) Position() float64

Position returns the current playback position in seconds.

returns:
      float64

func (*StreamingAudioSource) SampleRate

func (s *StreamingAudioSource) SampleRate() int

SampleRate returns the native sample rate of the loaded audio file.

func (*StreamingAudioSource) Seek

func (s *StreamingAudioSource) Seek(positionSecs float64)

Seek sends a seek request to the decoder goroutine. Drains any pending request before sending the new one (latest-wins).

params:
      positionSecs: target position in seconds

func (*StreamingAudioSource) SetVolume

func (s *StreamingAudioSource) SetVolume(v float32)

SetVolume updates the playback volume.

params:
      v: volume level (0.0 - 1.0)

func (*StreamingAudioSource) Volume

func (s *StreamingAudioSource) Volume() float32

Volume returns the current playback volume.

returns:
      float32: 0.0 - 1.0

type VorbisChunkDecoder

type VorbisChunkDecoder struct {
	// contains filtered or unexported fields
}

func (*VorbisChunkDecoder) Channels

func (c *VorbisChunkDecoder) Channels() int

func (*VorbisChunkDecoder) Close

func (c *VorbisChunkDecoder) Close() error

func (*VorbisChunkDecoder) ReadSamples

func (c *VorbisChunkDecoder) ReadSamples(buf []float32) (int, error)

ReadSamples decodes interleaved float32 PCM from the Vorbis stream. Converts the planar C float arrays into Go interleaved layout.

params:
      buf: destination buffer for interleaved samples
returns:
      int:   number of float32 values written
      error: io.EOF on end of stream

func (*VorbisChunkDecoder) SampleRate

func (c *VorbisChunkDecoder) SampleRate() int

func (*VorbisChunkDecoder) SeekToFrame

func (c *VorbisChunkDecoder) SeekToFrame(frame int64) error

SeekToFrame seeks to the specified PCM frame position.

params:
      frame: target frame offset
returns:
      error

func (*VorbisChunkDecoder) TotalFrames

func (c *VorbisChunkDecoder) TotalFrames() int64

type VorbisDecoder

type VorbisDecoder struct{}

func NewVorbisDecoder

func NewVorbisDecoder() *VorbisDecoder

NewVorbisDecoder creates a new Vorbis decoder instance.

returns:
      *VorbisDecoder

func (*VorbisDecoder) CanHandle

func (d *VorbisDecoder) CanHandle(ext string) bool

func (*VorbisDecoder) Name

func (d *VorbisDecoder) Name() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL