Newer
Older
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.
An example board is available on How to Make (Almost) Anything's website (hello.MAX98357A.RP2040):
[https://academy.cba.mit.edu/classes/output_devices/](https://academy.cba.mit.edu/classes/output_devices/)
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](https://docs.arduino.cc/learn/built-in-libraries/i2s/): Arduino's standard I2S library.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#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
}