cc.audio.dfpwm

Convert between streams of DFPWM audio data and a list of amplitudes.

DFPWM (Dynamic Filter Pulse Width Modulation) is an audio codec designed by GreaseMonkey. It's a relatively compact format compared to raw PCM data, only using 1 bit per sample, but is simple enough to encode and decode in real time.

Typically DFPWM audio is read from the filesystem or a a web request as a string, and converted a format suitable for speaker.playAudio.

Encoding and decoding files

This module exposes two key functions, make_decoder and make_encoder, which construct a new decoder or encoder. The returned encoder/decoder is itself a function, which converts between the two kinds of data.

These encoders and decoders have lots of hidden state, so you should be careful to use the same encoder or decoder for a specific audio stream. Typically you will want to create a decoder for each stream of audio you read, and an encoder for each one you write.

Converting audio to DFPWM

DFPWM is not a popular file format and so standard audio processing tools may not have an option to export to it. Instead, you can convert audio files online using music.madefor.cc, the LionRay Wav Converter Java application or FFmpeg 5.1 or later.

Usage

See also

Changes

make_encoder()Create a new encoder for converting PCM audio data into DFPWM.
encode(input)A convenience function for encoding a complete file of audio at once.
make_decoder()Create a new decoder for converting DFPWM into PCM audio data.
decode(input)A convenience function for decoding a complete file of audio at once.
make_encoder()Source

Create a new encoder for converting PCM audio data into DFPWM.

The returned encoder is itself a function. This function accepts a table of amplitude data between -128 and 127 and returns the encoded DFPWM data.

Reusing encoders

Encoders have lots of internal state which tracks the state of the current stream. If you reuse an encoder for multiple streams, or use different encoders for the same stream, the resulting audio may not sound correct.

Returns

  1. function(pcm: { number... }):string The encoder function

See also

  • encode A helper function for encoding an entire file of audio at once.
encode(input)Source

A convenience function for encoding a complete file of audio at once.

This should only be used for complete pieces of audio. If you are writing multiple chunks to the same place, you should use an encoder returned by make_encoder instead.

Parameters

  1. input { number... } The table of amplitude data.

Returns

  1. string The encoded DFPWM data.

See also

make_decoder()Source

Create a new decoder for converting DFPWM into PCM audio data.

The returned decoder is itself a function. This function accepts a string and returns a table of amplitudes, each value between -128 and 127.

Reusing decoders

Decoders have lots of internal state which tracks the state of the current stream. If you reuse an decoder for multiple streams, or use different decoders for the same stream, the resulting audio may not sound correct.

Returns

  1. function(dfpwm: string):{ number... } The encoder function

Usage

  • Reads "data/example.dfpwm" in blocks of 16KiB (the speaker can accept a maximum of 128×1024 samples), decodes them and then plays them through the speaker.

    local dfpwm = require "cc.audio.dfpwm"
    local speaker = peripheral.find("speaker")
    
    local decoder = dfpwm.make_decoder()
    for input in io.lines("data/example.dfpwm", 16 * 1024) do
      local decoded = decoder(input)
      while not speaker.playAudio(decoded) do
        os.pullEvent("speaker_audio_empty")
      end
    end

See also

  • decode A helper function for decoding an entire file of audio at once.
decode(input)Source

A convenience function for decoding a complete file of audio at once.

This should only be used for short files. For larger files, one should read the file in chunks and process it using make_decoder.

Parameters

  1. input string The DFPWM data to convert.

Returns

  1. { number... } The produced amplitude data.

See also