malgo
repository·master·Indexed 19 days ago
https://github.com/gen2brain/malgoGo bindings for the miniaudio C library, providing cross-platform audio playback and recording capabilities. It supports a wide range of platforms and backends, including WASAPI, DirectSound, and WinMM on Windows; PulseAudio, ALSA, and JACK on Linux; CoreAudio on macOS/iOS; and OpenSL|ES and AAudio on Android. The library allows for detailed configuration of audio contexts, device settings, resampling, and full-duplex I/O via callbacks.
What's inside malgo
- malgo provides Go bindings for the miniaudio library. It is designed to provide cross-platform audio capabilities across various operating systems and hardware backends.
Install malgo via Go
masterTo use malgo in your Go project, install the package using
go get. Note that malgo requirescgoto function. On Windows and macOS, no additional linking is required, while on Linux and BSD systems, it links against-ldl.go get -u github.com/gen2brain/malgoDefine audio processing callbacks with DeviceCallbacks
masterThe
DeviceCallbacksstruct is used duringInitDeviceto define how the application responds to audio events.Data (DataProc): A function called for full-duplex I/O. It receivespOutputSample(for playback),pInputSamples(for capture), and theframecount.- If the device is playback-only,
pInputSampleswill benil. - If the device is capture-only,
pOutputSamplewill benil. - The slices provided are byte slices (
[]byte) representing the raw audio data.
- If the device is playback-only,
Stop (StopProc): A function called when the device has stopped.
type DataProc func(pOutputSample, pInputSamples []byte, framecount uint32) type StopProc func() type DeviceCallbacks struct { Data DataProc Stop StopProc }Configure the malgo Context
masterThe
ContextConfigstruct allows you to customize the behavior of the audio context, including thread priority, memory allocation callbacks, and backend-specific settings.Backend-Specific Configurations
- Alsa:
AlsaContextConfigprovidesUseVerboseDeviceEnumeration. - PulseAudio:
PulseContextConfigallows settingPApplicationName,PServerName, andTryAutoSpawn(to autospawn the daemon). - CoreAudio:
CoreAudioConfigmanagesSessionCategoryandSessionCategoryOptions. - Jack:
JackContextConfigallows settingPClientNameandTryStartServer.
Global Settings
ThreadPriority: Sets the priority for the audio threads.AllocationCallbacks: Allows providing customOnMalloc,OnRealloc, andOnFreefunctions.LogCallback: ALogProcfunction to handle logging.
- Alsa:
Supported platforms and audio backends
mastermalgo supports a wide range of platforms and their respective audio backends:
- Windows: WASAPI, DirectSound, WinMM
- Linux: PulseAudio, ALSA, JACK
- FreeBSD/NetBSD/OpenBSD: OSS/audio(4)/sndio
- macOS/iOS: CoreAudio
- Android: OpenSL|ES, AAudio
Set a logging callback for a Context
masterYou can intercept internal malgo logs by providing a
LogProcfunction toSetLogProc. ALogProcis a function with the signaturefunc(message string).To stop logging, call
SetLogProc(nil).ctx.SetLogProc(func(message string) { fmt.Printf("malgo log: %s\n", message) })Handle errors using the Result type
masterThe
Resulttype is anint32that implements the Goerrorinterface. It wraps miniaudio result codes. When an operation returns aResultthat is notMA_SUCCESS, you can call its.Error()method to retrieve a descriptive error string prefixed withminiaudio:.To check if an operation was successful, compare the returned
ResultagainstErrGeneric(which representsMA_ERROR) or check if it matches the success state (though in practice, most users check if the result is non-zero or use the provided error constants).// Example of how a Result might be used res := someMalgoFunction() if res != 0 { // Assuming 0 is success fmt.Println("Error occurred:", res.Error()) }Control device playback and capture with Start, Stop, and Uninit
masterOnce a
Deviceis initialized, you can control its lifecycle using the following methods:Start(): Activates the device. For playback devices, this begins audio output. For capture devices, this begins recording. Note that for playback,Start()will wait until an initial chunk of audio data is retrieved from yourDatacallback to ensure the buffer is not empty before playback begins.Stop(): Puts the device to sleep without uninitializing it. This is useful if you want to pause audio and resume later usingStart(). This method waits for the backend to stop properly.Uninit(): Completely shuts down the device and releases its resources. This explicitly callsStop()internally. You do not need to callStop()manually beforeUninit(), but it is safe to do so.
err := device.Start() if err != nil { // handle error } // ... later ... err = device.Stop() // ... when finished ... device.Uninit()Retrieve audio devices from a Context
masterYou can query a
Contextto find available audio hardware usingDevicesorDeviceInfo.List all devices
Use
Devices(kind DeviceType)to get a slice ofDeviceInfofor eitherCaptureorPlaybackdevices.Get specific device info
Use
DeviceInfo(kind DeviceType, id DeviceID, mode ShareMode)to retrieve detailed information about a specific device identified by itsDeviceIDand requestedShareMode.// List all playback devices devices, err := ctx.Devices(malgo.Playback) if err != nil { // handle error } for _, device := range devices { fmt.Printf("Device: %s\n", device.Name) }Calculate sample size in bytes with SampleSizeInBytes
masterUse
SampleSizeInBytes(format FormatType)to determine how many bytes a single sample occupies for a specific audio format. This is useful when manually managing audio buffers or calculating buffer sizes based on theFormatTypebeing used.// Example usage (assuming FormatType is defined elsewhere in the package) bytes := malgo.SampleSizeInBytes(malgo.FormatS16)Initialize a default DeviceConfig
masterUse
DefaultDeviceConfig(deviceType DeviceType)to create aDeviceConfigpopulated with the library's default settings for a specific device type (e.g., playback or capture). This is the recommended starting point for configuring audio devices.// Example: Initialize a default playback configuration config := malgo.DefaultDeviceConfig(malgo.DeviceTypePlayback)Inspect device properties and negotiated formats
masterAfter initialization, you can query the
Deviceto see the requested and negotiated audio parameters. This is critical because audio backends (like ALSA) may perform internal resampling or format conversion, meaning the actual hardware settings might differ from your requestedDeviceConfig.Requested Formats
SampleRate(): The requested sample rate.PlaybackFormat(): The requested playback format.CaptureFormat(): The requested capture format.PlaybackChannels(): The requested number of playback channels.CaptureChannels(): The requested number of capture channels.
Negotiated (Internal) Formats
Use these methods to see what the audio backend is actually using:
PlaybackInternalSampleRate(): The actual sample rate used for playback.CaptureInternalSampleRate(): The actual sample rate used for capture.PlaybackInternalFormat(): The actual sample format used for playback.CaptureInternalFormat(): The actual sample format used for capture.PlaybackInternalChannels(): The actual number of playback channels.CaptureInternalChannels(): The actual number of capture channels.
Status
IsStarted(): Returnstrueif the device is currently active.