# USB I2S Speaker

![](img/speaker.jpg)

This code implements a USB speaker streaming audio to an I2S device, based on [Phil Schatzmann's port](https://www.pschatzmann.ch/home/2024/10/13/tinyusb-audio-on-an-rp2040-in-arduino/) of the TinyUSB Audio class for the rp2040.

## Dependencies

This code uses the [Arduino pico](https://github.com/earlephilhower/arduino-pico) core, and two libraries:

- [Adafruit TinyUSB](https://github.com/pschatzmann/Adafruit_TinyUSB_Arduino/tree/Audio): this is the version modified by Phil Schatzmann to handle the Audio class on the rp2040.
- [I2S]: Arduino's standard I2S library.

## Code

```
#include <Adafruit_TinyUSB.h>
#include <I2S.h>

#define I2S_CLK 1
#define I2S_FRAME (I2S_CLK+1)
#define I2S_DATA 4
#define SAMPLE_RATE 44100
#define SAMPLE_BITS 16

Adafruit_USBD_Audio usb;

I2S i2s(OUTPUT);

size_t writeCB(const uint8_t* data, size_t len, Adafruit_USBD_Audio& ref) {
  int16_t* data16 = (int16_t*)data;

  size_t n_written = i2s.write(data, len);

  // returns the amount written (and convert to bytes)
  return n_written * 2 *  sizeof(int16_t);
}

void setup() {
  // init USB
  if (!TinyUSBDevice.isInitialized()) {
    TinyUSBDevice.begin(0);
  }

  Serial.begin(115200);

  // reconfigure USB
  usb.setWriteCallback(writeCB);
  usb.begin(SAMPLE_RATE, 2, SAMPLE_BITS);
  if (TinyUSBDevice.mounted()) {
    TinyUSBDevice.detach();
    delay(10);
    TinyUSBDevice.attach();
  }

  // start I2S
  i2s.setBCLK(I2S_CLK);
  i2s.setDATA(I2S_DATA);
  i2s.setBitsPerSample(SAMPLE_BITS);
  i2s.begin(SAMPLE_RATE);
}

void loop() {
  #ifdef TINYUSB_NEED_POLLING_TASK
  TinyUSBDevice.task();
  #endif
}
```