pulse

package module
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 13 Imported by: 0

README

pulse

GoDoc

PulseAudio client implementation in pure Go.

Based on github.com/yobert/pulse, which provided a very useful starting point.

Uses the pulseaudio native protocol to play audio without any CGO. The proto package exposes a very low-level API while the pulse package is more convenient to use.

status

  • proto supports almost all of the protocol, shm support is still missing.

  • pulse implements sufficient functionality for most audio playing/recording applications.

examples

see demo/play and demo/record

Documentation

Overview

Package pulse implements the pulseaudio protocol in pure go.

Index

Constants

View Source
const EndOfData endOfData = false

EndOfData is a special error value that can be returned by a reader to stop the stream.

View Source
const ErrConnectionClosed = pulseError("pulseaudio: connection closed")

ErrConnectionClosed is a special error value indicating that the server closed the connection.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

The Client is the connection to the pulseaudio server. An application typically only uses a single client.

func NewClient

func NewClient(opts ...ClientOption) (*Client, error)

NewClient connects to the server.

func (*Client) Close

func (c *Client) Close()

Close closes the client. Calling methods on a closed client may panic.

func (*Client) DefaultSink

func (c *Client) DefaultSink() (*Sink, error)

DefaultSink returns the default output device.

func (*Client) DefaultSource

func (c *Client) DefaultSource() (*Source, error)

DefaultSource returns the default input device.

func (*Client) GetServerInfo

func (c *Client) GetServerInfo() (proto.GetServerInfoReply, error)

GetServerInfo return information about pulseaudio server

func (*Client) ListModules

func (c *Client) ListModules() ([]*proto.GetModuleInfoReply, error)

ListModules list all loaded modules.

func (*Client) ListSinks

func (c *Client) ListSinks() ([]*Sink, error)

ListSinks returns a list of all available output devices.

func (*Client) ListSources

func (c *Client) ListSources() ([]*Source, error)

ListSources returns a list of all available input devices.

func (*Client) LoadModule

func (c *Client) LoadModule(name string, args string) (uint32, error)

LoadModule loads module described by the definition.

func (*Client) NewPlayback

func (c *Client) NewPlayback(r Reader, opts ...PlaybackOption) (*PlaybackStream, error)

NewPlayback creates a playback stream. The created stream wil not be running, it must be started with Start(). If the reader returns any error, the stream will be stopped. The special error value EndOfData can be used to intentionally stop the stream from within the callback. The order of options is important in some cases, see the documentation of the individual PlaybackOptions.

func (*Client) NewRecord

func (c *Client) NewRecord(w Writer, opts ...RecordOption) (*RecordStream, error)

NewRecord creates a record stream. If the reader returns any error, the stream will be stopped. The created stream wil not be running, it must be started with Start(). The order of options is important in some cases, see the documentation of the individual RecordOptions.

func (*Client) RawRequest

func (c *Client) RawRequest(req proto.RequestArgs, rpl proto.Reply) error

RawRequest can be used to send arbitrary requests.

req should be one of the request types defined by the proto package.

rpl must be a pointer to the correct reply type or nil. This funcion will panic if rpl has the wrong type.

The returned error can be compared against errors defined by the proto package to check for specific errors.

The function will always block until the server has replied, even if rpl is nil.

func (*Client) SetSinkMute

func (c *Client) SetSinkMute(name string, mute bool) error

SetSinkMute sets mute flag on a sink with the given name.

func (*Client) SetSinkVolume

func (c *Client) SetSinkVolume(name string, volume proto.ChannelVolumes) error

SetSinkVolume sets volume on a sink with the given name.

func (*Client) SinkByID

func (c *Client) SinkByID(name string) (*Sink, error)

SinkByID looks up a sink id.

func (*Client) SourceByID

func (c *Client) SourceByID(name string) (*Source, error)

SourceByID looks up a source id.

func (*Client) UnloadModule

func (c *Client) UnloadModule(idx uint32) error

UnloadModule unloads module by index.

type ClientOption

type ClientOption func(*Client)

A ClientOption supplies configuration when creating the client.

func ClientApplicationIconName

func ClientApplicationIconName(name string) ClientOption

ClientApplicationIconName sets the application icon using an xdg icon name. This will e.g. be displayed by a volume control application to identity the application.

func ClientApplicationName

func ClientApplicationName(name string) ClientOption

ClientApplicationName sets the application name. This will e.g. be displayed by a volume control application to identity the application. It should be human-readable and localized.

func ClientServerString

func ClientServerString(s string) ClientOption

ClientServerString will override the default server strings. Server strings are used to connect to the server. For the server string format see https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/ServerStrings/

func ClientTimeout

func ClientTimeout(d time.Duration) ClientOption

ClientTimeout sets the timeout of requests to the specified duration. If d is 0, the default value (1 s) will be used.

type Float32Reader

type Float32Reader func([]float32) (int, error)

Float32Reader implements the Reader interface. The semantics are the same as io.Reader's Read, but it returns the number of float32 values read, not the number of bytes.

func (Float32Reader) Format

func (c Float32Reader) Format() byte

func (Float32Reader) Read

func (c Float32Reader) Read(buf []byte) (int, error)

type Float32Writer

type Float32Writer func([]float32) (int, error)

Float32Writer implements the Writer interface. The semantics are the same as io.Writer's Write, but it returns the number of float32 values written, not the number of bytes.

func (Float32Writer) Format

func (c Float32Writer) Format() byte

func (Float32Writer) Write

func (c Float32Writer) Write(buf []byte) (int, error)

type Int16Reader

type Int16Reader func([]int16) (int, error)

Int16Reader implements the Reader interface. The semantics are the same as io.Reader's Read, but it returns the number of int16 values read, not the number of bytes.

func (Int16Reader) Format

func (c Int16Reader) Format() byte

func (Int16Reader) Read

func (c Int16Reader) Read(buf []byte) (int, error)

type Int16Writer

type Int16Writer func([]int16) (int, error)

Int16Writer implements the Writer interface. The semantics are the same as io.Writer's Write, but it returns the number of int16 values written, not the number of bytes.

func (Int16Writer) Format

func (c Int16Writer) Format() byte

func (Int16Writer) Write

func (c Int16Writer) Write(buf []byte) (int, error)

type Int32Reader

type Int32Reader func([]int32) (int, error)

Int32Reader implements the Reader interface. The semantics are the same as io.Reader's Read, but it returns the number of int32 values read, not the number of bytes.

func (Int32Reader) Format

func (c Int32Reader) Format() byte

func (Int32Reader) Read

func (c Int32Reader) Read(buf []byte) (int, error)

type Int32Writer

type Int32Writer func([]int32) (int, error)

Int32Writer implements the Writer interface. The semantics are the same as io.Writer's Write, but it returns the number of int32 values written, not the number of bytes.

func (Int32Writer) Format

func (c Int32Writer) Format() byte

func (Int32Writer) Write

func (c Int32Writer) Write(buf []byte) (int, error)

type PlaybackOption

type PlaybackOption func(*PlaybackStream)

A PlaybackOption supplies configuration when creating streams.

var PlaybackMono PlaybackOption = func(p *PlaybackStream) {
	p.createRequest.ChannelMap = proto.ChannelMap{proto.ChannelMono}
	p.createRequest.Channels = 1
}

PlaybackMono sets a stream to a single channel.

var PlaybackStereo PlaybackOption = func(p *PlaybackStream) {
	p.createRequest.ChannelMap = proto.ChannelMap{proto.ChannelFrontLeft, proto.ChannelFrontRight}
	p.createRequest.Channels = 2
}

PlaybackStereo sets a stream to two channels.

func PlaybackBufferSize

func PlaybackBufferSize(samples int) PlaybackOption

PlaybackBufferSize sets the size of the server-side buffer. Setting the buffer size too small causes underflows, resulting in audible artifacts.

Buffer size and latency should not be set at the same time.

func PlaybackChannels

func PlaybackChannels(m proto.ChannelMap) PlaybackOption

PlaybackChannels sets a stream to use a custom channel map.

func PlaybackLatency

func PlaybackLatency(seconds float64) PlaybackOption

PlaybackLatency sets the stream's latency in seconds. Setting the latency too low causes underflows, resulting in audible artifacts. Applications should generally use the highest acceptable latency.

This should be set after sample rate and channel options.

Buffer size and latency should not be set at the same time.

func PlaybackMediaIconName

func PlaybackMediaIconName(name string) PlaybackOption

PlaybackMediaIconName sets the streams media icon using an xdg icon name. This will e.g. be displayed by a volume control application to identity the stream.

func PlaybackMediaName

func PlaybackMediaName(name string) PlaybackOption

PlaybackMediaName sets the streams media name. This will e.g. be displayed by a volume control application to identity the stream.

func PlaybackRawOption

func PlaybackRawOption(o func(*proto.CreatePlaybackStream)) PlaybackOption

PlaybackRawOption can be used to create custom options.

This is an advanced function, similar to (*Client).RawRequest.

func PlaybackSampleRate

func PlaybackSampleRate(rate int) PlaybackOption

PlaybackSampleRate sets the stream's sample rate.

func PlaybackSink

func PlaybackSink(sink *Sink) PlaybackOption

PlaybackSink sets the sink the stream should send audio to.

func PlaybackVolumeChanges

func PlaybackVolumeChanges(changes chan proto.ChannelVolumes) PlaybackOption

PlaybackVolumeChanges sets a channel to receive volume changes on. These changes can come either from changing the volume directly (through SetVolume) or from the system volume mixer.

The channel should be buffered (1 element is sufficient) to avoid losing volume changes due to race conditions or a slow receiver. It will be closed when the playback is closed.

type PlaybackStream

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

A PlaybackStream is used for playing audio. When creating a stream, the user must provide a callback that will be used to buffer audio data.

func (*PlaybackStream) BufferSize

func (p *PlaybackStream) BufferSize() int

BufferSize returns the size of the server-side buffer in samples.

func (*PlaybackStream) BufferSizeBytes

func (p *PlaybackStream) BufferSizeBytes() int

BufferSizeBytes returns the size of the server-side buffer in bytes.

func (*PlaybackStream) Channels

func (p *PlaybackStream) Channels() int

Channels returns the number of channels.

func (*PlaybackStream) Close

func (p *PlaybackStream) Close() error

Close closes the stream. The local side is released whether or not the server acknowledges, so a failure here is worth reporting but never worth retrying.

func (*PlaybackStream) Closed

func (p *PlaybackStream) Closed() bool

Closed returns wether the stream was closed.

func (*PlaybackStream) Drain

func (p *PlaybackStream) Drain() error

Drain waits until everything buffered has played out. It has no deadline of its own, because how long that takes is the length of the audio still held by the server, which only the caller knows; it does return if the connection drops. Use DrainContext to bound it.

Drain does not return when the stream is paused.

func (*PlaybackStream) DrainContext added in v0.5.0

func (p *PlaybackStream) DrainContext(ctx context.Context) error

DrainContext waits until everything buffered has played out, or ctx is done.

It is answered once the server has played everything it was given, and the reader goes on giving it audio until the track ends — so draining is how a caller waits for playback to finish, and the deadline it needs is the length of the audio, not that of a protocol round trip.

What matters here is whether the server is playing the stream out, not whether the local reader still has audio to hand over. A track shorter than the buffer exhausts its reader before the caller can even ask to drain; skipping the flush in that case discards the audio that was already sent, which is precisely the short announcement the appliance most needs to play. A corked stream is skipped instead, since the server will never play it out and the wait would not end.

func (*PlaybackStream) Error

func (p *PlaybackStream) Error() error

Error returns the last error the stream ran into — from its reader, or from sending the data on.

func (*PlaybackStream) Pause

func (p *PlaybackStream) Pause() error

Pause stops playing audio immediately.

func (*PlaybackStream) Resume

func (p *PlaybackStream) Resume() error

Resume resumes a paused stream.

func (*PlaybackStream) Running

func (p *PlaybackStream) Running() bool

Running returns wether the stream is currently playing.

func (*PlaybackStream) SampleRate

func (p *PlaybackStream) SampleRate() int

SampleRate returns the stream's sample rate (samples per second).

func (*PlaybackStream) SetVolume

func (p *PlaybackStream) SetVolume(volumes proto.ChannelVolumes) error

SetVolume changes the volume of each channel in the playback.

Do not set the volume when opening a playback stream, PulseAudio will pick an appropriate volume for the stream automatically (and may save it for next time). In particular, don't set it to 100% because depending on the configuration this could actually set the volume to the maximum volume the hardware is capable of which is usually way too loud. Instead, only change the volume as a direct result of user input.

If you use this API, you should also query the volume on startup and listen for playback volume changes from the system mixer (many desktops allow users to change application volume from the system tray). That way, you can keep the volume slider in the application synchronized with the system volume mixer.

func (*PlaybackStream) Start

func (p *PlaybackStream) Start() error

Start starts playing audio, waiting for the server to confirm the stream is running. The wait is bounded by the client timeout; use StartContext to choose the deadline.

func (*PlaybackStream) StartContext added in v0.5.0

func (p *PlaybackStream) StartContext(ctx context.Context) error

StartContext starts playing audio and returns once the server reports the stream as started, or ctx is done.

Some deadline is essential. A server that never sends the Started event — one that is shutting down, or whose sink has gone away — otherwise leaves the caller waiting forever with nothing to say why.

func (*PlaybackStream) Stop

func (p *PlaybackStream) Stop()

Stop stops playing audio; the callback will no longer be called. If the buffer size/latency is large, audio may continue to play for some time after the call to Stop.

func (*PlaybackStream) StreamIndex

func (p *PlaybackStream) StreamIndex() uint32

StreamIndex returns the stream index. This should only be used together with (*Cient).RawRequest.

func (*PlaybackStream) StreamInputIndex

func (p *PlaybackStream) StreamInputIndex() uint32

func (*PlaybackStream) Underflow

func (p *PlaybackStream) Underflow() bool

Underflow returns true if any underflows happend since the last call to Start or Resume. Underflows usually happen because the latency/buffer size is too low or because the callback takes too long to run.

func (*PlaybackStream) Volume

func (p *PlaybackStream) Volume() (proto.ChannelVolumes, error)

Volume returns the volume of each channel in the playback.

type Reader

type Reader interface {
	io.Reader
	Format() byte // Format should return one of the format constants defined by the proto package
}

A Reader provides audio data in a specific format.

func NewReader

func NewReader(r io.Reader, format byte) Reader

NewReader creates a reader from an io.Reader and a format. The format must be one of the constants defined in the proto package.

type RecordOption

type RecordOption func(*RecordStream)

A RecordOption supplies configuration when creating streams.

var RecordMono RecordOption = func(r *RecordStream) {
	r.createRequest.ChannelMap = proto.ChannelMap{proto.ChannelMono}
	r.createRequest.Channels = 1
}

RecordMono sets a stream to a single channel.

var RecordStereo RecordOption = func(r *RecordStream) {
	r.createRequest.ChannelMap = proto.ChannelMap{proto.ChannelLeft, proto.ChannelRight}
	r.createRequest.Channels = 2
}

RecordStereo sets a stream to two channels.

func RecordBufferFragmentSize

func RecordBufferFragmentSize(size uint32) RecordOption

RecordBufferFragmentSize sets the fragment size. This is the size (in bytes) of the buffer passed to the callback. Lower values reduce latency, at the cost of more overhead.

Fragment size and latency should not be set at the same time.

func RecordChannels

func RecordChannels(m proto.ChannelMap) RecordOption

RecordChannels sets a stream to use a custom channel map.

func RecordLatency

func RecordLatency(seconds float64) RecordOption

RecordLatency sets the stream's latency in seconds.

This should be set after sample rate and channel options.

Fragment size and latency should not be set at the same time.

func RecordMediaIconName

func RecordMediaIconName(name string) RecordOption

RecordMediaIconName sets the streams media icon using an xdg icon name. This will e.g. be displayed by a volume control application to identity the stream.

func RecordMediaName

func RecordMediaName(name string) RecordOption

RecordMediaName sets the streams media name. This will e.g. be displayed by a volume control application to identity the stream.

func RecordMonitor

func RecordMonitor(sink *Sink) RecordOption

RecordMonitor sets the stream to receive audio sent to the sink.

func RecordRawOption

func RecordRawOption(o func(*proto.CreateRecordStream)) RecordOption

RecordRawOption can be used to create custom options.

This is an advanced function, similar to (*Client).RawRequest.

func RecordSampleRate

func RecordSampleRate(rate int) RecordOption

RecordSampleRate sets the stream's sample rate.

func RecordSource

func RecordSource(source *Source) RecordOption

RecordSource sets the source the stream should receive audio from.

type RecordStream

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

A RecordStream is used for recording audio. When creating a stream, the user must provide a callback that will be called with the recorded audio data.

func (*RecordStream) Channels

func (r *RecordStream) Channels() int

Channels returns the number of channels.

func (*RecordStream) Close

func (r *RecordStream) Close()

Close closes the stream.

func (*RecordStream) Closed

func (r *RecordStream) Closed() bool

Closed returns wether the stream was closed. Calling other methods on a closed stream may panic.

func (*RecordStream) Error

func (r *RecordStream) Error() error

Error returns the last error returned by the stream's writer.

func (*RecordStream) Running

func (r *RecordStream) Running() bool

Running returns wether the stream is currently recording.

func (*RecordStream) SampleRate

func (r *RecordStream) SampleRate() int

SampleRate returns the stream's sample rate (samples per second).

func (*RecordStream) Start

func (r *RecordStream) Start()

Start starts recording audio.

func (*RecordStream) Stop

func (r *RecordStream) Stop()

Stop stops recording audio; the callback will no longer be called.

func (*RecordStream) StreamIndex

func (r *RecordStream) StreamIndex() uint32

StreamIndex returns the stream index. This should only be used together with (*Cient).RawRequest.

type Sink

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

A Sink is an output device.

func (*Sink) Channels

func (s *Sink) Channels() proto.ChannelMap

Channels returns the default channel map.

func (*Sink) ID

func (s *Sink) ID() string

ID returns the sink name. Sink names are unique identifiers, but not necessarily human-readable.

func (*Sink) IsMute

func (s *Sink) IsMute() bool

IsMute returns true when the sink is in mute state

func (*Sink) Name

func (s *Sink) Name() string

Name is a human-readable name describing the sink.

func (*Sink) SampleRate

func (s *Sink) SampleRate() int

SampleRate returns the default sample rate.

func (*Sink) SinkIndex

func (s *Sink) SinkIndex() uint32

SinkIndex returns the sink index. This should only be used together with (*Cient).RawRequest.

func (*Sink) Volume

func (s *Sink) Volume() ([]uint32, uint32)

Volume returns channel volumes and the number of volume steps.

type Source

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

A Source is an input device.

func (*Source) Channels

func (s *Source) Channels() proto.ChannelMap

Channels returns the default channel map.

func (*Source) ID

func (s *Source) ID() string

ID returns the source name. Source names are unique identifiers, but not necessarily human-readable.

func (*Source) Name

func (s *Source) Name() string

Name is a human-readable name describing the source.

func (*Source) SampleRate

func (s *Source) SampleRate() int

SampleRate returns the default sample rate.

func (*Source) SourceIndex

func (s *Source) SourceIndex() uint32

SourceIndex returns the source index. This should only be used together with (*Cient).RawRequest.

type Uint8Reader

type Uint8Reader func([]byte) (int, error)

Uint8Reader implements the Reader interface. The semantics are the same as io.Reader's Read.

func (Uint8Reader) Format

func (c Uint8Reader) Format() byte

func (Uint8Reader) Read

func (c Uint8Reader) Read(buf []byte) (int, error)

type Uint8Writer

type Uint8Writer func([]byte) (int, error)

Uint8Writer implements the Writer interface. The semantics are the same as io.Writer's Write.

func (Uint8Writer) Format

func (c Uint8Writer) Format() byte

func (Uint8Writer) Write

func (c Uint8Writer) Write(buf []byte) (int, error)

type Writer

type Writer interface {
	io.Writer
	Format() byte // Format should return one of the format constants defined by the proto package
}

A Writer accepts audio data in a specific format.

func NewWriter

func NewWriter(w io.Writer, format byte) Writer

NewWriter creates a writer from an io.Writer and a format. The format must be one of the constants defined in the proto package.

Directories

Path Synopsis
demo
play command
record command
subscription command

Jump to

Keyboard shortcuts

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