Skip to content

Commit 6e6ee65

Browse files
committed
RP2040 I2S Support
1 parent 7611f36 commit 6e6ee65

File tree

5 files changed

+83
-27
lines changed

5 files changed

+83
-27
lines changed

examples/examples-stream/streams-generator-i2s/streams-generator-i2s.ino

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@
77

88
#include "AudioTools.h"
99

10-
typedef int16_t sound_t; // sound will be represented as int16_t (with 2 bytes)
1110
uint16_t sample_rate=44100;
1211
uint8_t channels = 2; // The stream will have 2 channels
13-
SineWaveGenerator<sound_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
14-
GeneratedSoundStream<sound_t> sound(sineWave); // Stream generated from sine wave
12+
SineWaveGenerator<int16_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
13+
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
1514
I2SStream out;
1615
StreamCopy copier(out, sound); // copies sound into i2s
1716

1817
// Arduino Setup
1918
void setup(void) {
2019
// Open Serial
2120
Serial.begin(115200);
22-
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
21+
while(!Serial);
22+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
2323

2424
// start I2S
2525
Serial.println("starting I2S...");

src/AudioConfig.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@
9191
#ifndef COPY_DELAY_ON_NODATA
9292
#define COPY_DELAY_ON_NODATA 10
9393
#endif
94+
95+
#ifndef COPY_RETRY_LIMIT
96+
#define COPY_RETRY_LIMIT 20
97+
#endif
98+
99+
94100
/**
95101
* -------------------------------------------------------------------------
96102
* @brief PWM

src/AudioI2S/I2SRP2040.h

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class I2SBasePIO {
3333
}
3434

3535
/// starts the DAC with the default config in TX Mode
36-
bool begin(RxTxMode mode = TX_MODE) {
36+
bool begin(RxTxMode mode = TX_MODE) {
3737
LOGD(LOG_METHOD);
3838
return begin(defaultConfig(mode));
3939
}
@@ -58,19 +58,26 @@ class I2SBasePIO {
5858
LOGE("Unsupported bits_per_sample: %d", cfg.bits_per_sample);
5959
return false;
6060
}
61-
if (cfg.channels != 2 ){
61+
62+
if (cfg.channels < 1 || cfg.channels > 2 ){
6263
LOGE("Unsupported channels: '%d' - only 2 is supported", cfg.channels);
6364
return false;
6465
}
65-
if (!I2S.begin(cfg.sample_rate)){
66+
67+
int rate = cfg.sample_rate;
68+
if (cfg.channels==1){
69+
rate = rate /2;
70+
}
71+
72+
if (!I2S.begin(rate)){
6673
LOGE("Could not start I2S");
6774
return false;
6875
}
6976
return true;
7077
}
7178

7279
/// stops the I2C and unistalls the driver
73-
void end(){
80+
void end() {
7481
I2S.end();
7582
}
7683

@@ -80,37 +87,80 @@ class I2SBasePIO {
8087
}
8188

8289
/// writes the data to the I2S interface
83-
size_t writeBytes(const void *src, size_t size_bytes){
90+
size_t writeBytes(const void *src, size_t size_bytes) {
8491
LOGD(LOG_METHOD);
85-
// size_t result = I2S.write(src, frames);
8692
size_t result = 0;
87-
uint32_t *p32 = (uint32_t *)src;
88-
for (int j=0;j<size_bytes/4;j++){
89-
while (!I2S.write((void*)p32[j], 4)){
90-
delay(5);
91-
}
92-
result = j*4;
93-
}
94-
LOGD("%s: %d -> %d ", LOG_METHOD, size_bytes, result);
93+
int16_t *p16 = (int16_t *)src;
94+
95+
if (cfg.channels==1){
96+
int samples = size_bytes/2;
97+
// multiply 1 channel into 2
98+
int16_t buffer[samples*2]; // from 1 byte to 2 bytes
99+
for (int j=0;j<samples;j++){
100+
buffer[j*2]= p16[j];
101+
buffer[j*2+1]= p16[j];
102+
}
103+
result = I2S.write((const uint8_t*)buffer, size_bytes*2)*2;
104+
} else if (cfg.channels==2){
105+
result = I2S.write((const uint8_t*)src, size_bytes)*4;
106+
}
95107
return result;
96108
}
97109

98-
size_t readBytes(void *dest, size_t size_bytes){
99-
LOGD(LOG_METHOD);
110+
size_t readBytes(void *dest, size_t size_bytes) {
111+
LOGE(LOG_METHOD);
100112
size_t result = 0;
101113
return result;
102114
}
103115

104-
virtual int availableForWrite() {
105-
return I2S.availableForWrite();
116+
int availableForWrite() {
117+
int result = 0;
118+
if (cfg.channels == 1){
119+
// it should be a multiple of 2
120+
result = I2S.availableForWrite()/2*2;
121+
// return half of it because we double when writing
122+
result = result / 2;
123+
} else {
124+
// it should be a multiple of 4
125+
result = I2S.availableForWrite()/4*4;
126+
}
127+
if (result<4){
128+
result = 0;
129+
}
130+
return result;
131+
}
132+
133+
int available() {
134+
return 0;
106135
}
107136

108-
int available() {
109-
return I2S.available();
137+
void flush() {
138+
return I2S.flush();
110139
}
111140

112141
protected:
113142
I2SConfig cfg;
143+
144+
// blocking write
145+
void writeSample(int16_t sample){
146+
int written = I2S.write(sample);
147+
while (!written) {
148+
delay(5);
149+
LOGW("written: %d ", written);
150+
written = I2S.write(sample);
151+
}
152+
}
153+
154+
int writeSamples(int samples, int16_t* values){
155+
int result=0;
156+
for (int j=0;j<samples;j++){
157+
int16_t sample = values[j];
158+
writeSample(sample);
159+
writeSample(sample);
160+
result++;
161+
}
162+
return result;
163+
}
114164

115165
};
116166

src/AudioTools/AudioCopy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ class StreamCopyT {
234234
void *onWriteObj = nullptr;
235235
bool is_first = false;
236236
const char* actual_mime = nullptr;
237-
int retryLimit = 20;
237+
int retryLimit = COPY_RETRY_LIMIT;
238238
int delay_on_no_data = COPY_DELAY_ON_NODATA;
239239

240240
// blocking write - until everything is processed

tests/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11

2-
In the subdirectories you find the test sketches that can be build on the desktop.
3-
For details [see the wiki](https://github.com/pschatzmann/arduino-audio-tools/wiki/Running-an-Audio-Sketch-on-the-Desktop)
2+
In the subdirectories you find the test sketches that can be built on the desktop.
3+
For details [see the Wiki](https://github.com/pschatzmann/arduino-audio-tools/wiki/Running-an-Audio-Sketch-on-the-Desktop)
44

0 commit comments

Comments
 (0)