I2S (Digital Audio) Output Library¶
While the RP2040 chip on the Raspberry Pi Pico does not include a hardware I2S device, it is possible to use the PIO (Programmable I/O) state machines to implement one dynamically.
This I2S library uses the
pico-extras I2S audio library and wraps it in
an Arduino I2S library. It supports 16 bits/sample and frequencies of up
to 48kHZ, with configurable BCLK, LRCLK(always pin “BCLK + 1”), and DOUT pins.
Note: This I2S device takes over the entire PIO1 (second) unit and adjusts its clock frequency to meet the I2S needs. That means when only 4 Tones or only 4 Servos may be used when the I2S device is used.
I2S Class API¶
bool setBCLK(pin_size_t pin)¶
Sets the BCLK pin of the I2S device. The LRCLK/word clock will be
pin + 1
due to limitations of the PIO state machines. Call this before
Default BCLK = 26, LRCLK = 27
bool setDOUT(pin_size_t pin)¶
Sets the DOUT pin of the I2S device. Any pin may be used. Default DOUT = 28
bool begin(long sampleRate)¶
Start the I2S device up with the given sample rate. The pins selected above will be turned to output and the I2S will begin to drive silence frames (all zero) out.
Stops the I2S device. Note, at present the memory allocated for I2S buffers is not freed leading to a memory leak when ``end()`` is called. This is due to the state of the ``pico-extras`` release which this code uses.
Sends any partial frames in memory to the I2S output device. They may NOT play immediately. Potential use case for this call would be when the frequency of the output will be changing.
Provided for compatibility, but not very useful. Writes a sample from 0…255
to the I2S buffer. See
write(int16_t) for a better one
size_t write(const uint8_t *buffer, size_t size)¶
Transfers number of bytes from an application buffer to the I2S output buffer.
Be aware that
size is in bytes* and not samples. Size must be a multiple
of 4 bytes (i.e. one left/right sample). Will not block, so check
the return value to find out how many bytes were actually written.
Returns the number of 32-bit L/R samples that can be written without potentially blocking.
bool setFrequency(int newFreq)¶
Adjusts the I2S output frequency. When changing frequency while I2S output
is underway, be sure to use
I2S.flush() before changing the frequency to
ensure the older data is played at the right frequency.
Writes a single 16-bit left or right sample to the I2S output buffer. The
user is required to ensure that an even number of samples is written (i.e.
left and right) over the application lifetime. The application also needs
to track which sample is next to be written (right/left). For this reason,
write(void *b, size_t lrsamples) call may be easier and faster to use.
size_t write(const void *buffer, size_t lrsamples)¶
Writes up to size left+right packed samples to the I2S device. Non-blocking,
will writefrom 0…size samples and return that count. Be sure your app
handles partial writes (i.e. by
yield() ing and then retrying to write the
onTransmit callback is not supported.
See the ESP8266Audio library for a working example, or look at the included sample tone generator.