portaudio Go Wrapper

repository·master·Indexed 21 days ago

https://github.com/gordonklaus/portaudio

A Go wrapper providing an interface to the PortAudio C library for audio input and output operations. It supports both callback-based and blocking I/O processing modes, allowing developers to manage audio streams, enumerate host APIs and devices, and handle audio hardware interactions via Go.

Tokens
2.8K
Snippets
8
Records
12
Agent score
24%

What's inside portaudio

  1. Install PortAudio development headers and libraries

    master

    Before building this package, you must have the PortAudio development headers and libraries installed on your system.

    On Ubuntu and Debian-based systems, you can install them using: apt-get install portaudio19-dev.

    On other operating systems, you may need to install PortAudio from source or via your specific package manager.

    apt-get install portaudio19-dev
  2. How StreamCallbacks and Buffers work in PortAudio

    master

    PortAudio supports two modes of audio processing: Callback-based and Blocking I/O.

    1. Callback-based Streams

    In this mode, you provide a StreamCallback function to OpenStream. The library calls this function periodically to process audio.

    StreamCallback Signature: func(in Buffer, out Buffer, timeInfo StreamCallbackTimeInfo, flags StreamCallbackFlags)

    The final one or two parameters may be omitted depending on whether the stream is input-only, output-only, or both.

    Buffer Formats:

    • Non-interleaved: [][]SampleType (where len(buf) == numChannels and len(buf[i]) == framesPerBuffer).
    • Interleaved: []SampleType (where len(buf) == numChannels * framesPerBuffer).

    2. Blocking I/O (Read/Write)

    In this mode, you provide buffers to OpenStream instead of a callback. The Read() and Write() methods do not accept buffer arguments; they use the buffers provided during stream initialization. The number of samples processed is determined by the size of those buffers.

    Note: You cannot use Read() or Write() on a stream opened with a callback.

    // Example Callback Signature
    func myCallback(in [][]float32, out [][]float32, timeInfo portaudio.StreamCallbackTimeInfo, flags portaudio.StreamCallbackFlags) {
        // Process audio here
    }
  3. Initialize and Terminate PortAudio

    master

    Before using any other PortAudio API functions, you MUST call Initialize(). If Initialize() is called multiple times, each successful call must be matched with a corresponding call to Terminate().

    Terminate() must be called before exiting your program to prevent resource leaks (e.g., audio devices remaining unavailable until a reboot). If Initialize() returns an error, do NOT call Terminate().

    Note: Version(), VersionText(), and ErrorText() (via the Error type) can be called without initialization.

    err := portaudio.Initialize()
    if err != nil {
    	log.Fatal(err)
    }
    // ... use portaudio ...
    portaudio.Terminate()
  4. Open a stream with OpenDefaultStream()

    master

    OpenDefaultStream is a convenience function that opens the system's default input and/or output devices.

    Parameters:

    • numInputChannels: Number of input channels (0 if input-only).
    • numOutputChannels: Number of output channels (0 if output-only).
    • sampleRate: The desired sample rate.
    • framesPerBuffer: The number of frames per buffer.
    • args...: Either a StreamCallback or buffers for blocking I/O.

    By default, this function uses HighLatencyParameters for the device settings.

    // Open default input and output for callback processing
    stream, err := portaudio.OpenDefaultStream(1, 2, 44100, 256, myCallback)
  5. Enumerate Host APIs and Audio Devices

    master

    PortAudio allows you to inspect available audio hardware and host APIs (like ALSA, CoreAudio, ASIO, etc.).

    • HostApis(): Returns a slice of all available HostApiInfo objects.
    • HostApi(apiType HostApiType): Returns information for a specific HostApiType.
    • DefaultHostApi(): Returns the default HostApiInfo for the current platform.
    • Devices(): Returns a slice of all available DeviceInfo objects.
    • DefaultInputDevice(): Returns the default input DeviceInfo.
    • DefaultOutputDevice(): Returns the default output DeviceInfo.

    DeviceInfo Fields:

    • Index: The device index.
    • Name: The device name.
    • MaxInputChannels / MaxOutputChannels: Maximum channel counts.
    • DefaultLowInputLatency / DefaultLowOutputLatency: Recommended low-latency durations.
    • DefaultHighInputLatency / DefaultHighOutputLatency: Recommended high-latency durations.
    • DefaultSampleRate: The device's default sample rate.
    devs, err := portaudio.Devices()
    for _, dev := range devs {
        fmt.Printf("Device %d: %s\n", dev.Index, dev.Name)
    }
  6. Open a stream with OpenStream()

    master

    OpenStream creates an instance of a Stream. It requires a StreamParameters object and arguments that define the processing mode.

    Arguments:

    • For Callback streams: Pass a single StreamCallback function.
    • For Blocking streams: Pass one or two Buffer arguments (pointers to slices) representing the input and/or output buffers. For an input-only stream, the output buffer argument can be omitted. For an output-only stream, the input buffer argument can be omitted.

    StreamParameters: Combines StreamDeviceParameters for both input and output, the SampleRate, FramesPerBuffer, and Flags.

    // Callback stream example
    params := portaudio.StreamParameters{
        Input:  portaudio.StreamDeviceParameters{Device: inDev, Channels: 1, Latency: time.Millisecond * 10},
        Output: portaudio.StreamDeviceParameters{Device: outDev, Channels: 2, Latency: time.Millisecond * 10},
        SampleRate: 44100,
        FramesPerBuffer: 256,
    }
    stream, err := portaudio.OpenStream(params, myCallback)
    
    // Blocking stream example
    inBuf := make([]float32, 1024)
    outBuf := make([]float32, 1024)
    stream, err := portaudio.OpenStream(params, &inBuf, &outBuf)
  7. Get PortAudio version information

    master

    Use these functions to check the version of the underlying PortAudio library.

    • Version(): Returns the release number as an int.
    • VersionText(): Returns a textual description of the release as a string.
    fmt.Printf("Version: %d (%s)\n", portaudio.Version(), portaudio.VersionText())
  8. Manage a Stream lifecycle (Start, Stop, Abort, Close)

    master

    Once a Stream is opened, use the following methods to control audio processing:

    • Start(): Commences audio processing.
    • Stop(): Terminates audio processing. It waits until all pending audio buffers have been played before returning.
    • Abort(): Terminates audio processing immediately without waiting for pending buffers.
    • Close(): Terminates the stream and releases its resources.
    err := stream.Start()
    // ... process ...
    err = stream.Stop()
    err = stream.Close()
  9. Reference: PortAudio Error Codes

    master

    The Error type wraps PaError. When an error occurs, it can be checked against these constants.

    const (
    	NotInitialized                        Error = C.paNotInitialized
    	InvalidChannelCount                   Error = C.paInvalidChannelCount
    	InvalidSampleRate                     Error = C.paInvalidSampleRate
    	InvalidDevice                         Error = C.paInvalidDevice
    	InvalidFlag                           Error = C.paInvalidFlag
    	SampleFormatNotSupported              Error = C.paSampleFormatNotSupported
    	BadIODeviceCombination                Error = C.paBadIODeviceCombination
    	InsufficientMemory                    Error = C.paInsufficientMemory
    	BufferTooBig                          Error = C.paBufferTooBig
    	BufferTooSmall                        Error = C.paBufferTooSmall
    	NullCallback                          Error = C.paNullCallback
    	BadStreamPtr                          Error = C.paBadStreamPtr
    	TimedOut                              Error = C.paTimedOut
    	InternalError                         Error = C.paInternalError
    	DeviceUnavailable                     Error = C.paDeviceUnavailable
    	IncompatibleHostApiSpecificStreamInfo Error = C.paIncompatibleHostApiSpecificStreamInfo
    	StreamIsStopped                       Error = C.paStreamIsStopped
    	StreamIsNotStopped                    Error = C.paStreamIsNotStopped
    	InputOverflowed                       Error = C.paInputOverflowed
    	OutputUnderflowed                     Error = C.paOutputUnderflowed
    	HostApiNotFound                       Error = C.paHostApiNotFound
    	InvalidHostApi                        Error = C.paInvalidHostApi
    	CanNotReadFromACallbackStream         Error = C.paCanNotReadFromACallbackStream
    	CanNotWriteToACallbackStream         Error = C.paCanNotWriteToACallbackStream
    	CanNotReadFromAnOutputOnlyStream      Error = C.paCanNotReadFromAnOutputOnlyStream
    	CanNotWriteToAnInputOnlyStream        Error = C.paCanNotWriteToAnInputOnlyStream
    	IncompatibleStreamHostApi             Error = C.paIncompatibleStreamHostApi
    	BadBufferPtr                          Error = C.paBadBufferPtr
    	NoDefaultInputDevice                  Error = -1
    	NoDefaultOutputDevice                 Error = -2
    )
  10. Reference: StreamFlags

    master

    Flags used to configure stream behavior in StreamParameters.

    const (
    	NoFlag                                StreamFlags = C.paNoFlag
    	ClipOff                               StreamFlags = C.paClipOff
    	DitherOff                             StreamFlags = C.paDitherOff
    	NeverDropInput                        StreamFlags = C.paNeverDropInput
    	PrimeOutputBuffersUsingStreamCallback StreamFlags = C.paPrimeOutputBuffersUsingStreamCallback
    	PlatformSpecificFlags                 StreamFlags = C.paPlatformSpecificFlags
    )
  11. Reference: HostApiType constants

    master

    These constants represent the different Host APIs available on various platforms.

    const (
    	InDevelopment   HostApiType = C.paInDevelopment
    	DirectSound     HostApiType = C.paDirectSound
    	MME             HostApiType = C.paMME
    	ASIO            HostApiType = C.paASIO
    	SoundManager    HostApiType = C.paSoundManager
    	CoreAudio       HostApiType = C.paCoreAudio
    	OSS             HostApiType = C.paOSS
    	ALSA            HostApiType = C.paALSA
    	AL              HostApiType = C.paAL
    	BeOS            HostApiType = C.paBeOS
    	WDMkS           HostApiType = C.paWDMKS
    	JACK            HostApiType = C.paJACK
    	WASAPI          HostApiType = C.paWASAPI
    	AudioScienceHPI HostApiType = C.paAudioScienceHPI
    )