当我将 maxLength 设置为 2048 时,一切仍然运行良好。当我将缓冲区大小从 1024 增加到 2048 时,它崩溃了。为什么?我怎样才能增加缓冲区?
目前我可以发送 16bit@22kHz 的音频,但我的目标是 44.1kHz 甚至 48kHz。因此尝试增加缓冲区大小。由于我没有运行缓冲区,我猜网络服务器是瓶颈。我该如何衡量呢?填充正弦波函数中的数据缓冲区大约需要 8 毫秒。
正在循环使用数据“填充”网络服务器的方式吗?
还有其他方法可以加快速度吗?
代码:
全选#include
#include
#include
#include
#include
const char *ssid = "***";
const char *password = "***";
AsyncWebServer server(80);
const uint16_t buffer_size = 1024; //256 - 1024. maxLen = 1064 but seems worse than 1024.
CircularBuffer audio_buffer;
uint8_t makenoise = 1;
uint32_t t;
struct audio_spec{
float bitdepth = 16.0;
float samplerate = 22050; //44100.0; 32000;
uint16_t num_channels = 2;
float
tick = 1/samplerate;
float twopitick = 2*PI*tick;
float amplitude = pow(2, bitdepth)/2.0; //0dB mind your ears!
} audio_res;
struct wave_header_pcm{
char riff_tag[4]{'R','I','F','F'};
uint32_t riff_length{4294967295};//4294967295
char wave_tag[4]{'W','A','V','E'};
char format_tag[4]{'f','m','t',' '}; //mind the space!!
uint32_t format_length{16};
uint16_t format_code{1};
uint16_t num_channels;
uint32_t sample_rate;
uint32_t byte_rate;
uint16_t block_align;
uint16_t bit_depth;
char data_tag[4]{'d','a','t','a'};
uint32_t data_length{4294967295}; //4294967295 max length as we stream. Should resend the header when max is reached.
} header_pcm;
void fill_header(uint16_t bit_depth, uint32_t sample_rate, uint16_t num_channels){
header_pcm.num_channels = num_channels;
header_pcm.sample_rate = sample_rate;
header_pcm.byte_rate = sample_rate*(bit_depth/8)*num_channels;
header_pcm.block_align = bit_depth/8;
header_pcm.bit_depth = bit_depth;
}
void sinewave(float frequency){
static float f_twopitick = frequency*audio_res.twopitick;
static uint32_t cnt = 0;
while(makenoise){
while(!audio_buffer.isFull()){
int16_t amplitude = (audio_res.amplitude * sin(cnt*f_twopitick));
audio_buffer.push((amplitude >> 8 & 0xff));
audio_buffer.push((amplitude & 0xff));
if(audio_res.num_channels == 2){
audio_buffer.push((amplitude >> 8 & 0xff));
audio_buffer.push((amplitude & 0xff));
}
cnt++; //takes ~8ms
}
while(audio_buffer.isFull()){
//Serial.println("Buffer Full!");
yield();
// 2-5ms with every now and then a peak 1000+ and 3000+
}
}
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network\nIP Address: ");
Serial.println(WiFi.localIP());
fill_header(audio_res.bitdepth, audio_res.samplerate, audio_res.num_channels);
server.on("/sinewave", HTTP_GET, [](AsyncWebServerRequest * request) {
AsyncWebServerResponse* response = request->beginChunkedResponse(
"audio/wave",
[](uint8_t* buffer, size_t maxLen, size_t index){
size_t len;
// first chunk does not have the full maxLen available
// http-headers(?) Send these plus the WAVE header first.
// after that just the audio data
if(index == 0){
uint8_t* pcm_bytes = static_cast(static_cast(&header_pcm));
for (size_t i = 0; i < sizeof(header_pcm); i++){
buffer
= pcm_bytes;
}
len = (1064 - maxLen) + sizeof(header_pcm);
return len;
}
else{
//maxLen = 2048;
size_t len = buffer_size;
if (!audio_buffer.isEmpty()){
for (size_t i = 0; i < len; i++){
buffer = audio_buffer.shift();
}
}
else{
while(audio_buffer.isEmpty()){
Serial.println("Buffer Empty!");
}
}
return len;
}
}
);
response->addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response->addHeader("Pragma", "no-cache");
response->addHeader("Expires", "-1");
request->send(response);
});
server.begin();
Serial.println("HTTP server started");
sinewave(250.0);
}
void loop() {
}