/*
程序: 使用Stream Buffer 对流媒体数据,在任务间进行传输
流媒体,读和写的大小都没有任何的限制
读和写的大小可以不一致, 比如写入100 bytes, 可以分成两次每次50 bytes读取出来
注意: 适合于一个任务写,另外一个任务读
不适合多任务读写
如果必须要用在多任务的读写,请将内容放入CRITICAL SECTION
可以使用 MUTEX 或者 TASK Notification
公众号:孤独的二进制
API:
*/
//不要忘记include stream_buffer.h
#include <freertos/stream_buffer.h>
StreamBufferHandle_t xStreamMusic = NULL; //创建一个 Stream Buffer 的 handler
void downloadTask(void *pvParam) { //下载音乐
String music;
size_t xBytesSent; //The number of bytes written to the stream buffer.
while (1) {
//从网络下载音乐,放一些随机的延迟
for (int i = 0; i < random(20, 40); i++) vTaskDelay(1);
music = randomMusic(); //随机生成一些数据
xBytesSent = xStreamBufferSend( xStreamMusic,
(void *)&music,
sizeof(music),
portMAX_DELAY);
if ( xBytesSent != sizeof( music ) ) {
Serial.println("警告: xStreamBufferSend 写入数据出错"); //Optional
}
vTaskDelay(100);
}
}
void playBackTask(void *pvParam) { //解码并且播放
size_t xReceivedBytes; //The number of bytes read from the stream buffer.
size_t xReadBytes = 8*10-1;
String music;
while (1) {
xReceivedBytes = xStreamBufferReceive( xStreamMusic,
( void * ) &music,
xReadBytes,
portMAX_DELAY );
if ( xReceivedBytes > 0 )
{
decode(music);
}
}
}
void monitorTask (void * pvParam) { //对 streamBuffer进行监控
size_t xAvailable, xUsed;
bool isFull;
while (1) {
//Queries a stream buffer to see if it is full.
if (xStreamBufferIsFull(xStreamMusic) == pdTRUE) Serial.println("xStreamMusic 已满");
//Queries a stream buffer to see how much data it contains
xUsed = xStreamBufferBytesAvailable(xStreamMusic);
//Queries a stream buffer to see how much free space it contains
xAvailable = xStreamBufferSpacesAvailable(xStreamMusic);
char msg[40];
sprintf(msg, "xStreamBuffer已使用 %d 字节", xUsed);
Serial.println(msg);
sprintf(msg, "xStreamBuffer可用空间为 %d 字节", xAvailable);
Serial.println(msg);
vTaskDelay(2000);
}
}
void setup() {
Serial.begin(115200);
//Stream Buffer的最大尺寸,如果超出可能内存空间,那么创建Stream Buffer就会失败
const size_t xStreamBufferSizeBytes = 540;
//Trigger Level - Stream Buffer内数据超过这个数值,才会被读取
const size_t xTriggerLevel = 8;
xStreamMusic = xStreamBufferCreate(xStreamBufferSizeBytes, xTriggerLevel);
if ( xStreamMusic == NULL )
{ //内存不过,无法创建Stream Buffer
Serial.println("UNABLE TO CREATE STREAM BUFFER");
}
else
{
xTaskCreate(downloadTask, "Download Music", 1024 * 8, NULL, 1, NULL); //下载音乐
xTaskCreate(playBackTask, "Playback Music", 1024 * 8, NULL, 1, NULL); //解码播放音乐
xTaskCreate(monitorTask, "Monitor Stream Buffer", 1024 * 8, NULL, 1, NULL); //对Stream Buffer进行监控
}
vTaskDelete(NULL); //setup 和 loop 这个loopBack任务没用了,自宫了
}
void loop() {
}