PWM Audio Library
Relatively good quality analog audio out can be generated by using the RP2040 onboard PWM hardware. It can drive an amplifier for speaker output, or be decoupled using a capacitor to drive a headphone-level signal. Mono and stereo signals can be generated.
All samples are sent to the
PWMAudio library as signed 16 bits per sample.
Due to frequency limitations of the PWM hardware, at higher bit rates
these 16-bits will automatically be reduced to the maximum the hardware
PWMAudio devices are supported, depending on availability of
The interface for the
PWMAudio device is very similar to the
device, and most code can be ported simply by instantiating a
object in lieu of an
PWM Class API
Creates a mono PWM output port. Any pin can be used, but no
calls are allowed to any other pins using that pin’s PWM slice hardware.
See the RP2040 datasheet for more details about PWM slices.
Creates a stereo PWM output port. Only even pins (left signal) can be used, the next odd
pin will automatically be assigned to the right channel (i.e.
PWMAudio pwm(0, true);
will make GP0 as the left channel, GP1 as the right channel). The same restriction as
in mono mode applies.
bool setBuffers(size_t buffers, size_t bufferWords)
Set the number of DMA buffers and their size in 32-bit words.
When running at high sample rates, it is recommended to increase the
bufferWords to 32 or higher (i.e.
pwm.setBuffers(4, 32); ).
bool setPin(pin_size_t pin)
Adjusts the pin to connect to the PWM audio output. Only legal before
bool setStereo(bool stereo)
Adjusts the mono/stereo setting of the PWM audio output. Only legal before
bool setFrequency(long sampleRate)
Sets the sample frequency, but does not start the PWM device (however if the device was already running, it will wontinue to run at the new frequency).
bool begin()/begin(long sampleRate)
Start the PWM Audio device up with the given sample rate, or with the value set
using the prior
Stops the PWMAudio device.
Waits until all the PWM Audio buffers have been output.
size_t write(int16_t sample, bool sync = true)
Writes a single 16-bit sample to the buffer. It is up to the user to keep track
of left/right channels when in stereo mode. In mono mode, one sample is written
per timestep while in stereo mode two
write() calls are required.
This call will block (wait) until space is available to actually write
the data if
sync is not specified or set to
size_t write(const uint8_t *buffer, size_t size)
Transfers number of bytes from an application buffer to the PWM Audio output buffer.
Be aware that
size is in bytes* and not samples. Size must be a multiple
of 4 bytes. Will not block, so check the return value to find out how
many bytes were actually written.
Returns the number of samples that can be written without potentially blocking.
void onTransmit(void (*fn)(void))
Sets a callback to be called when a PWM Audio DMA buffer is fully transmitted. Will be in an interrupt context so the specified function must operate quickly and not use blocking calls like delay() or write to the PWM Audio.