Skip to content

Commit 9e8c58e

Browse files
committed
DRAFT mp3-xon-xoff example
1 parent b9de863 commit 9e8c58e

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
2+
/**
3+
* @file receive-mp3.ino
4+
* @brief Example of receiving an mp3 stream over serial and playing it over I2S
5+
* using the AudioTools library.
6+
* The processing implements a xon-xoff flow control over Serial. We
7+
* process the data receiving in a separate task and the playback in the main
8+
* loop.
9+
*/
10+
11+
#include "AudioTools.h"
12+
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
13+
#include "AudioTools/AudioLibs/AudioBoardStream.h"
14+
#include "AudioTools/Concurrency/RTOS.h"
15+
16+
// xon/xoff flow control
17+
const char xon = 17;
18+
const char xoff = 19;
19+
const int min_percent = 10;
20+
const int max_percent = 90;
21+
22+
AudioBoardStream i2s(AudioKitEs8388V1); // final output of decoded stream
23+
MP3DecoderHelix helix;
24+
EncodedAudioStream dec(&i2s, &helix); // Decoding stream
25+
// queue
26+
BufferRTOS<uint8_t> buffer(0);
27+
QueueStream<uint8_t> queue(buffer);
28+
// copy
29+
StreamCopy copierFill(queue, Serial1);
30+
StreamCopy copierPlay(dec, queue);
31+
32+
Task task("mp3-copy", 10000, 1, 0);
33+
34+
void setup() {
35+
Serial.begin(115200);
36+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
37+
38+
Serial1.begin(115200);
39+
40+
// set up buffer here to allow PSRAM usage
41+
buffer.resize(1024 * 10); // 10kB buffer
42+
queue.begin(50); // start when half full
43+
44+
// setup i2s
45+
auto config = i2s.defaultConfig(TX_MODE);
46+
i2s.begin(config);
47+
48+
// setup decoder
49+
dec.begin();
50+
51+
// start fill buffer copy task
52+
task.begin([]() {
53+
copierFill.copy();
54+
// data synchronization to prevent buffer overflow
55+
if (buffer.levelPercent() >= max_percent) {
56+
Serial1.write(xoff); // stop receiving
57+
} else if (buffer.levelPercent() <= min_percent) {
58+
Serial1.write(xon); // start receiving
59+
}
60+
});
61+
}
62+
63+
void loop() { copierPlay.copy(); }
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
/**
3+
* @file send-mp3.ino
4+
* @brief Example of sending an mp3 stream over Serial the AudioTools library.
5+
* We use xon/xoff to control the flow of the data.
6+
*/
7+
8+
#include "AudioTools.h"
9+
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
10+
#include "AudioTools/AudioLibs/AudioBoardStream.h"
11+
12+
URLStream url("ssid", "password"); // or replace with ICYStream to get metadata
13+
AudioBoardStream i2s(AudioKitEs8388V1); // final output of decoded stream
14+
StreamCopy copier(Serial1, url); // copy url to decoder
15+
// xon/xoff flow control
16+
const char xon = 17;
17+
const char xoff = 19;
18+
bool is_active = false;
19+
20+
void setup() {
21+
Serial.begin(115200);
22+
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Error);
23+
24+
// setup serial data sink
25+
Serial1.begin(115200);
26+
27+
// mp3 radio
28+
url.begin("http://stream.srg-ssr.ch/m/rsj/mp3_128", "audio/mp3");
29+
}
30+
31+
// Determine if we can send data from the flow control sent by the receiver
32+
bool isAcive() {
33+
char c = Serial1.read();
34+
switch (c) {
35+
case xon:
36+
is_active = true;
37+
break;
38+
case xoff:
39+
is_active = false;
40+
break;
41+
}
42+
return is_active;
43+
}
44+
45+
void loop() {
46+
if (isActive()) {
47+
copier.copy();
48+
}
49+
}

0 commit comments

Comments
 (0)