diff --git a/internal/playback/audio.go b/internal/playback/audio.go new file mode 100644 index 0000000..0d37fc5 --- /dev/null +++ b/internal/playback/audio.go @@ -0,0 +1,42 @@ +package playback + +import "context" + +// AudioFrame contains deinterleaved F32 audio samples. +// +// Samples contains one byte slice per channel. Each channel contains +// SampleCount float32 samples. +// +// The sample payload may borrow source-owned memory. AudioSink must finish +// reading it before ConsumeAudio returns. +type AudioFrame struct { + Index uint64 + SampleCount uint64 + Channels uint64 + + SampleRateNumerator int64 + SampleRateDenominator int64 + + Samples [][]byte +} + +// AudioReader reads batches from one audio feed. +// +// ReadAudio must not be called again until the previous frame has been +// consumed. +type AudioReader interface { + ReadAudio(context.Context) (AudioFrame, error) + Close() error +} + +// AudioReaderFactory opens a reader for the configured audio feed. +type AudioReaderFactory interface { + OpenAudio(context.Context, FeedConfig) (AudioReader, error) +} + +// AudioSink synchronously consumes one borrowed audio batch. +// +// ConsumeAudio must not retain frame.Samples or their underlying byte slices. +type AudioSink interface { + ConsumeAudio(context.Context, AudioFrame) error +}