Skip to content

esphome-libs/micro-wav

microWAV - Streaming WAV Decoder

CI Component Registry

Streaming WAV parser and decoder for embedded devices. Extracts audio from WAV containers byte-by-byte with a 4-byte internal accumulator. No external buffering required.

A project from the Open Home Foundation

Features

  • Wide format support: PCM (8/16/24/32-bit), G.711 A-law/mu-law, and IEEE float 32-bit
  • Byte-by-byte streaming: Feed data in any chunk size
  • Single API: One decode() call for both header parsing and audio decoding
  • Chunk-aware: Automatically skips unknown chunks (LIST, INFO, etc.)
  • Extensible headers: Handles standard and extended fmt chunks (WAVE_FORMAT_EXTENSIBLE)
  • No dynamic allocation: Zero heap usage

Usage Example

ESP-IDF Component Manager

dependencies:
  esphome/micro-wav: "~0.1.0"

PlatformIO

lib_deps = https://github.com/esphome-libs/micro-wav.git

CMake Subdirectory

add_subdirectory(micro-wav)
target_link_libraries(your_target PRIVATE micro_wav)

Decoding

#include "micro_wav/wav_decoder.h"

micro_wav::WAVDecoder decoder;
uint8_t data[512];
uint8_t output[1024];
size_t bytes_consumed = 0;
size_t samples_decoded = 0;

// Feed chunks as they arrive from a file, network socket, etc.
while (size_t len = read_chunk(data, sizeof(data))) {
    const uint8_t* p = data;

    while (len > 0) {
        auto result = decoder.decode(p, len, output, sizeof(output),
                                     bytes_consumed, samples_decoded);
        p += bytes_consumed;
        len -= bytes_consumed;

        if (result == micro_wav::WAV_DECODER_HEADER_READY) {
            // Header parsed, stream info now available
            uint32_t rate = decoder.get_sample_rate();
            uint16_t channels = decoder.get_channels();
            uint16_t bps = decoder.get_bits_per_sample();
        } else if (result == micro_wav::WAV_DECODER_SUCCESS) {
            // output contains samples_decoded decoded samples
            process_audio(output, samples_decoded);
        } else if (result == micro_wav::WAV_DECODER_END_OF_STREAM) {
            return;
        } else if (result < 0) {
            handle_error(result);
            return;
        }
        // NEED_MORE_DATA: inner loop exits, outer loop reads next chunk
    }
}

API Reference

Methods

Method Description
decode(input, input_len, output, output_size, bytes_consumed, samples_decoded) Feed input bytes; parses header or decodes audio samples
reset() Reset decoder to initial state for a new stream
get_sample_rate() Sample rate in Hz
get_channels() Number of audio channels
get_bits_per_sample() Output bit depth per sample
get_audio_format() Audio format tag (WAVAudioFormat)
get_data_chunk_size() Size of the data chunk in bytes
get_bytes_per_output_sample() Bytes per decoded output sample
get_bytes_remaining() Audio data bytes remaining to decode
is_header_ready() Whether header parsing is complete

Result Codes

decode() returns WAVDecoderResult: non-negative values indicate success/informational states, negative values indicate errors or warnings.

Value Description
WAV_DECODER_SUCCESS Samples decoded (check samples_decoded)
WAV_DECODER_HEADER_READY Header fully parsed; stream info available
WAV_DECODER_END_OF_STREAM All data chunk bytes consumed
WAV_DECODER_NEED_MORE_DATA More bytes needed; call decode() again with additional data
WAV_DECODER_WARNING_OUTPUT_TOO_SMALL Output buffer is null or too small for one sample
WAV_DECODER_ERROR_UNSUPPORTED Audio format not supported; e.g., 64-bit float, unknown codec
WAV_DECODER_ERROR_FAILED Generic decode failure; e.g., malformed chunk
WAV_DECODER_ERROR_NO_WAVE RIFF container found but missing WAVE identifier
WAV_DECODER_ERROR_NO_RIFF Input does not start with a RIFF tag

Audio Formats

get_audio_format() returns WAVAudioFormat after the header is parsed. Unrecognized tags return WAV_FORMAT_UNKNOWN.

Value Description
WAV_FORMAT_PCM Uncompressed integer PCM
WAV_FORMAT_IEEE_FLOAT IEEE 754 floating-point
WAV_FORMAT_ALAW A-law companded
WAV_FORMAT_MULAW mu-law companded
WAV_FORMAT_UNKNOWN Unrecognized format tag

Known Limitations

  • IEEE float decoding assumes the host platform uses little-endian IEEE 754 floats. This is true for all common targets (ESP32, x86, ARM Cortex) but will produce incorrect results on big-endian platforms.

License

Apache 2.0

Links

About

Streaming WAV parser and decoder for embedded devices. Extracts audio from WAV containers byte-by-byte with a 4-byte internal accumulator. No external buffering required.

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors