乐鑫技术交流
直播中

张勇

7年用户 1426经验值
私信 关注
[问答]

maxLength将缓冲区大小从1024增加到2048时,崩溃了是为什么?

当我将 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() {
}



               


                        

回帖(1)

杨福林

2024-4-10 16:36:29
首先,增加缓冲区大小不会直接导致崩溃,但可能会导致其他问题,例如占用更多的内存,减慢处理速度等。因此,您需要查看崩溃的具体原因,例如通过检查错误日志或使用调试器。

在衡量网络服务器瓶颈方面,您可以尝试使用一些网络性能工具,例如网络监视器或流量分析器,以查看网络吞吐量,延迟和包丢失等指标。

如果您正在循环使用数据“填充”网络服务器,那么可能会导致性能瓶颈。您可以尝试使用多线程或异步处理来提高性能。此外,您还可以通过使用压缩或数据缓存等技术来减少数据传输量,从而提高性能。
举报

更多回帖

×
20
完善资料,
赚取积分