audio

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Mar 28, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const ChunkBytes = WindowSize * 2 * 2

ChunkBytes is the number of raw bytes per FFT frame (stereo, 16-bit). 2048 samples × 2 channels × 2 bytes = 8192.

View Source
const NumBands = 64

NumBands is the number of frequency bands in FFT output.

View Source
const WindowSize = 2048

WindowSize is the number of mono samples per FFT frame. 2048 at 44100 Hz = ~46 ms, a good latency/resolution tradeoff.

Variables

View Source
var DefaultFormat = PCMFormat{SampleRate: 44100, Channels: 2, BitDepth: 16}

DefaultFormat is librespot's default output: 44100 Hz, stereo, 16-bit signed LE.

Functions

func DecodeFrame

func DecodeFrame(r io.Reader, fd *FrequencyData) error

DecodeFrame reads a fixed-size binary frame from r into fd.

func EncodeFrame

func EncodeFrame(w io.Writer, fd *FrequencyData) error

EncodeFrame writes a FrequencyData as a fixed-size binary frame to w.

Types

type Analyzer

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

Analyzer performs FFT analysis on PCM audio chunks and produces FrequencyData.

func NewAnalyzer

func NewAnalyzer(windowSize int) *Analyzer

NewAnalyzer creates an Analyzer with a precomputed Hann window of the given size.

func (*Analyzer) Analyze

func (a *Analyzer) Analyze(samples []int16) FrequencyData

Analyze takes interleaved stereo int16 PCM samples and returns FrequencyData. The samples slice must contain at least WindowSize*2 values (stereo pairs).

type FrequencyData

type FrequencyData struct {
	Bands      [NumBands]float32 // log-spaced frequency bands, normalized 0.0–1.0
	Peak       float32           // overall peak amplitude this frame
	Bass       float32           // average of bands 0–7
	Mid        float32           // average of bands 8–31
	High       float32           // average of bands 32–63
	ProgressMs int32             // playback progress derived from PCM sample count
}

FrequencyData holds FFT output mapped to visualization-friendly bands.

func (*FrequencyData) ComputeConvenienceFields

func (fd *FrequencyData) ComputeConvenienceFields()

ComputeConvenienceFields fills Bass, Mid, and High from Bands.

type PCMFormat

type PCMFormat struct {
	SampleRate int
	Channels   int
	BitDepth   int
}

PCMFormat describes the expected audio format from librespot.

type Receiver

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

Receiver listens on a unix socket for FrequencyData from the audio worker.

func NewReceiver

func NewReceiver() *Receiver

NewReceiver creates a Receiver with an auto-generated socket path.

func (*Receiver) Latest

func (r *Receiver) Latest() *FrequencyData

Latest returns the most recent FrequencyData, or nil if no fresh data. Returns nil if the last frame is older than 150ms (e.g., paused). Thread-safe; called from the Bubble Tea goroutine.

func (*Receiver) SocketPath

func (r *Receiver) SocketPath() string

SocketPath returns the path for the audio worker to connect to.

func (*Receiver) Start

func (r *Receiver) Start() error

Start creates the unix socket and begins accepting connections.

func (*Receiver) Stop

func (r *Receiver) Stop()

Stop closes the listener and cleans up the socket file. Safe to call multiple times.

type Worker

type Worker struct {
	Format     PCMFormat
	SocketPath string
}

Worker reads PCM from stdin, plays it via oto, and sends FFT data over a unix socket.

func (*Worker) Run

func (w *Worker) Run(ctx context.Context, stdin io.Reader) error

Run is the main loop. It blocks until the context is cancelled, stdin is closed, or an error occurs.

Jump to

Keyboard shortcuts

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