miniaudio

0.11.22

Audio playback and capture library written in C, in a single source file.
mackron/miniaudio

What's New

Version 0.11.22

2025-02-24T06:43:22Z

v0.11.22 - 2025-02-24

  • Starting from version 0.12, miniaudio will be switching to a split .c/h pair, away from a single header. In preparation for this, a file named "miniaudio.c" has been added to repository. Currently this is just a simple wrapper around miniaudio.h and MINIAUDIO_IMPLEMENTATION. Nothing has changed in miniaudio.h, however when version 0.12 is released you will need to use miniaudio.c for the implementation. It's recommended you start the transition away from MINIAUDIO_IMPLEMENTATION and towards miniaudio.c. If you want to keep building your project as a single translation unit, you can do #include "miniaudio.c" which will continue to be supported with version 0.12 and beyond.
  • In the extras folder, the miniaudio_libvorbis.h and miniaudio_libopus.h files have been deprecated. They have been replaced with versions in the extras/decoders folder. They are now split into a separate .c and .h files. The old files still exist for compatibility, but you need to transition over to the new versions. The transition should be trivial. Compile the .c files like a normal source file, and include the .h file like a normal header.
  • Add MA_SOUND_FLAG_LOOPING and MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_LOOPING flags. These can be used to initialize sounds and resource managed data sources to loop by default. This is the recommended way to enable looping for streams. The isLooping config option in ma_sound_config and ma_resource_manager_data_source_config has been deprecated. If you are using those, you should switch to the new flag or else you'll get compiler errors when upgrading to a future version.
  • ma_rb_commit_read(), ma_rb_commit_write(), ma_pcm_rb_commit_read() and ma_pcm_rb_commit_write() no longer return MA_AT_END. The reason for this change is that there's no real notion of an "end" in a ring buffer which makes this result code confusing. In addition, it's possible for these functions to return something other than MA_SUCCESS even when the operation completed successfully which adds to the confusion. The correct way to check if there is any more room in the ring buffer is to look at the frame count returned by *rb_acquire_read/write().
  • The ma_pcm_rb data source implementation has been modified to pad output data with silence if there is not enough data in the ring buffer to fill the request. What this means is for an ma_pcm_rb, ma_data_source_read_pcm_frames() should no longer return a frame count of less than what you requested, and will therefore never return MA_AT_END which does not make sense for a ring buffer since it does not have the notion of an end. This change should make it much easier to use a ring buffer as the data source for a ma_sound.
  • There has been a minor change to ma_calculate_buffer_size_in_milliseconds_from_frames() to have it return a value rounded up to the nearest integer.
  • When initialization of a decoder fails, it will now return the first error code encountered rather than always returning MA_NO_BACKEND regardless of the error.
  • Add ma_device_id_equal() for comparing device IDs.
  • Add support for MA_NO_RUNTIME_LINKING to the AAudio backend.
  • Fix a buffer overrun bug with ma_sound processing.
  • Fix a bug relating to node detachment.
  • Fix a bug where amplification with ma_device_set_master_volume() does not work.
  • Fix a bug where sounds loaded with MA_SOUND_FLAG_DECODE do not loop.
  • Fix a bug with initialization of the band pass biquad filter.
  • Fix a bug where a device would output distorted audio if initialized without a data callback.
  • Fix various compiler and static analysis warnings.
  • Various documentation updates.
  • WASAPI: Fix an error when stopping the device. The "Failed to reset internal playback device." error should be significantly reduced in frequency.
  • WASAPI: Fix an error when stopping the device where it was possible miniaudio would not wait for the device to be drained due to an error with the wait time calculation.
  • WASAPI: Fix a COM related crash with device rerouting.
  • DirectSound: Add support for specifying an explicit window handle for SetCooperativeLevel().
  • ALSA: Fix a bug where a playback device can fail to start.
  • ALSA: Fix some warnings relating to unhandled return value of read().
  • Web: Fix ScriptProcessorNode path when compiling with --closure=1. Note that the Audio Worklets path is not currently working due to the callback specified in emscripten_create_wasm_audio_worklet_processor_async never getting fired.
  • Web: Fix an error with the unlocked notification when compiling as C++.
  • Web: Fix a JavaScript error when initializing and then uninitializing a context before any interactivity.
  • Web: miniaudio will now enable threading when the -pthread command line flag is used.
  • Web: Infrastructure has been added to support configurable buffer sizes. In practice this is still restricted to 128 frames, but once Emscripten adds full support for configuration of the buffer size, it will be trivial to add support to miniaudio.
  • AAudio: Fix some crashes relating to stream rerouting.
  • AAudio: Fix an error where the device is silenced after rerouting. With this change, miniaudio will no longer give AAudio a hint to use your supplied period size which will therefore result in AAudio using its default latency configuration. If you want AAudio to try to use the period size you supply in the device config, which is the old behaviour, set aaudio.allowSetBufferCapacity to true in the device config. Note, however, if you do this you may end up with errors when rerouting between devices.
  • AAudio: The default minimum SDK version has been increased from 26 to 27 when enabling AAudio. If you need to support version 26, you can use #define MA_AAUDIO_MIN_ANDROID_SDK_VERSION 26.
  • AAudio: Fix ma_device_get_info() implementation.
  • AAudio: Fix an error when an assertion can trigger due to AAudio reporting a frame count of 0.
  • PulseAudio: Add a configuration option to control the PulseAudio-defined channel map to use.
  • PulseAudio: Fix an extremely unlikely race condition with device initialization.
  • PulseAudio: Fix a bug with the miniaudio-generated stream name. Previously this would create names like "miniaudi0" when it was supposed to be "miniaudio:0".
  • iOS: Fix an error when trying to capture audio from the simulator with iOS version 16 and newer.
  • sndio: Fix a crash with device uninitialization.

miniaudio

An audio playback and capture library in a single source file.

discord mastodon

Features - Examples - Building - Documentation - Supported Platforms - Security - License

miniaudio is written in C with no dependencies except the standard library and should compile clean on all major compilers without the need to install any additional development packages. All major desktop and mobile platforms are supported.

Features

  • Simple build system with no external dependencies.
  • Simple and flexible API.
  • Low-level API for direct access to raw audio data.
  • High-level API for sound management, mixing, effects and optional 3D spatialization.
  • Flexible node graph system for advanced mixing and effect processing.
  • Resource management for loading sound files.
  • Decoding, with built-in support for WAV, FLAC and MP3, in addition to being able to plug in custom decoders.
  • Encoding (WAV only).
  • Data conversion.
  • Resampling, including custom resamplers.
  • Channel mapping.
  • Basic generation of waveforms and noise.
  • Basic effects and filters.

Refer to the Programming Manual for a more complete description of available features in miniaudio.

Examples

This example shows one way to play a sound using the high level API.

#include "miniaudio.h"

#include <stdio.h>

int main()
{
    ma_result result;
    ma_engine engine;

    result = ma_engine_init(NULL, &engine);
    if (result != MA_SUCCESS) {
        return -1;
    }

    ma_engine_play_sound(&engine, "sound.wav", NULL);

    printf("Press Enter to quit...");
    getchar();

    ma_engine_uninit(&engine);

    return 0;
}

This example shows how to decode and play a sound using the low level API.

#include "miniaudio.h"

#include <stdio.h>

void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
{
    ma_decoder* pDecoder = (ma_decoder*)pDevice->pUserData;
    if (pDecoder == NULL) {
        return;
    }

    ma_decoder_read_pcm_frames(pDecoder, pOutput, frameCount, NULL);

    (void)pInput;
}

int main(int argc, char** argv)
{
    ma_result result;
    ma_decoder decoder;
    ma_device_config deviceConfig;
    ma_device device;

    if (argc < 2) {
        printf("No input file.\n");
        return -1;
    }

    result = ma_decoder_init_file(argv[1], NULL, &decoder);
    if (result != MA_SUCCESS) {
        return -2;
    }

    deviceConfig = ma_device_config_init(ma_device_type_playback);
    deviceConfig.playback.format   = decoder.outputFormat;
    deviceConfig.playback.channels = decoder.outputChannels;
    deviceConfig.sampleRate        = decoder.outputSampleRate;
    deviceConfig.dataCallback      = data_callback;
    deviceConfig.pUserData         = &decoder;

    if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
        printf("Failed to open playback device.\n");
        ma_decoder_uninit(&decoder);
        return -3;
    }

    if (ma_device_start(&device) != MA_SUCCESS) {
        printf("Failed to start playback device.\n");
        ma_device_uninit(&device);
        ma_decoder_uninit(&decoder);
        return -4;
    }

    printf("Press Enter to quit...");
    getchar();

    ma_device_uninit(&device);
    ma_decoder_uninit(&decoder);

    return 0;
}

More examples can be found in the examples folder or online here: https://miniaud.io/docs/examples/

Building

Just compile miniaudio.c like any other source file and include miniaudio.h like a normal header. There's no need to install any dependencies. On Windows and macOS there's no need to link to anything. On Linux and BSD just link to -lpthread and -lm. On iOS you need to compile as Objective-C. Link to -ldl if you get errors about dlopen(), etc.

If you get errors about undefined references to __sync_val_compare_and_swap_8, __atomic_load_8, etc. you need to link with -latomic.

ABI compatibility is not guaranteed between versions so take care if compiling as a DLL/SO. The suggested way to integrate miniaudio is by adding it directly to your source tree.

You can also use CMake if that's your preference.

Documentation

Online documentation can be found here: https://miniaud.io/docs/

Documentation can also be found at the top of miniaudio.h which is always the most up-to-date and authoritative source of information on how to use miniaudio. All other documentation is generated from this in-code documentation.

Supported Platforms

  • Windows
  • macOS, iOS
  • Linux
  • FreeBSD / OpenBSD / NetBSD
  • Android
  • Raspberry Pi
  • Emscripten / HTML5

miniaudio should compile clean on other platforms, but it will not include any support for playback or capture by default. To support that, you would need to implement a custom backend. You can do this without needing to modify the miniaudio source code. See the custom_backend example.

Backends

  • WASAPI
  • DirectSound
  • WinMM
  • Core Audio (Apple)
  • ALSA
  • PulseAudio
  • JACK
  • sndio (OpenBSD)
  • audio(4) (NetBSD and OpenBSD)
  • OSS (FreeBSD)
  • AAudio (Android 8.0+)
  • OpenSL|ES (Android only)
  • Web Audio (Emscripten)
  • Null (Silence)
  • Custom

Security

I deal with all security related issues publicly and transparently, and it can sometimes take a while before I get a chance to address it. If this is an issue for you, you need to use another library. The fastest way to get a bug fixed is to submit a pull request, but if this is unpractical for you please post a ticket to the public GitHub issue tracker.

License

Your choice of either public domain or MIT No Attribution.

Description

  • Swift Tools
View More Packages from this Author

Dependencies

  • None
Last updated: Thu May 15 2025 23:10:33 GMT-0900 (Hawaii-Aleutian Daylight Time)