pschatzmann / arduino-audio-tools

Arduino Audio Tools (a powerful Audio library not only for Arduino)
GNU General Public License v3.0
1.47k stars 227 forks source link

Error with AudioEncoded.h:78 (count<10) #1637

Closed thanh01pmt closed 2 months ago

thanh01pmt commented 2 months ago

Problem Description

I tried to apply multicore processing to make sound feedback when the user clicks a button on the LCD Touched Screen (LVGL). It worked, but only 9 clicks. On the 10th click, the program crashed and reset itself.

Error (In Serial Monitor): assert failed: virtual void audio_tools::EncodedAudioOutput::addNotifyAudioChange(audio_tools::AudioInfoSupport&) AudioEncoded.h:78 (count<10)

I have no idea on what was wrong with my program. Please help me out...

Device Description

WT32SC01 (ESP32) with I2S speaker.

Sketch

void lvgl_task(void *pvParameters) {
    while (1) {
        // Kiểm tra xem có thể lấy semaphore lvgl_mutex hay không. 
        // Semaphore được sử dụng để đồng bộ hóa truy cập vào tài nguyên chia sẻ. 
        // portMAX_DELAY chỉ định rằng task sẽ đợi vô thời hạn cho đến khi có thể lấy được semaphore.
        if (xSemaphoreTake(lvgl_mutex, portMAX_DELAY) == pdTRUE) {
            updateLVGL();
            xSemaphoreGive(lvgl_mutex);
        }
        vTaskDelay(pdMS_TO_TICKS(5));
    }
}

/////////////////////////////////////////////
//void audioTask(void *parameter) {
//  while (1) {
//    if (buttonState != preButtonState) {
//          preButtonState = buttonState;
//          playSoundClick();
//    }
//    vTaskDelay(pdMS_TO_TICKS(5));
//  }
//}

/////////////////////////////////////////////
void audioTask(void *parameter) {
  while (1) {
    if (buttonState != preButtonState) {
      preButtonState = buttonState;
      if (xQueueSend(soundQueue, &soundId, 0) != pdTRUE) {
        Serial.println("Error: soundQueue full!");
        // Xử lý lỗi, ví dụ: thử gửi lại sau một khoảng thời gian
      }
    }
    vTaskDelay(pdMS_TO_TICKS(5));
  }
}

/////////////////////////////////////////////
void soundClickTask(void *parameter) {
  while (1) {
    if (xQueueReceive(soundQueue, &soundId, portMAX_DELAY) == pdTRUE) {
      // Chờ cho đến khi có thể lấy được Semaphore
      if (xSemaphoreTake(audioSemaphore, portMAX_DELAY) == pdTRUE) {
        // Phát âm thanh
        if (soundId == 1) {
          playSoundClick();
        }
        // Không cần giải phóng Semaphore ở đây, vì nó đã được giải phóng trong playSoundClick() sau khi phát xong
      }
    }
  }
}

/////////////////////////////////////////////
void playSoundClick() {
  uint8_t buffer[512]; // Buffer để lưu trữ dữ liệu âm thanh
  size_t bytesRead;

  mp3.begin(); // Đặt con trỏ MemoryStream về đầu
  helix.begin();
  out.begin();

  // Vòng lặp đọc dữ liệu từ MemoryStream và ghi vào I2SStream
  while (mp3.available() > 0) {

    // Đọc dữ liệu từ MemoryStream vào buffer
    bytesRead = mp3.readBytes(buffer, sizeof(buffer));

    // Ghi dữ liệu từ buffer vào I2SStream
    out.write(buffer, bytesRead);

    // copier.copy();

    // Cho phép các task khác chạy trong khi chờ dữ liệu âm thanh
    vTaskDelay(1);
  }

  // Kết thúc phát âm thanh
  out.end();
  helix.end();

  // Giải phóng Semaphore sau khi kết thúc phát âm thanh
  xSemaphoreGive(audioSemaphore);
}

/////////////////////////////////////////////
void initAudio(){
  //AudioLogger::instance().begin(Serial, AudioLogger::Info);  

  // begin processing
  auto cfg = i2s.defaultConfig(TX_MODE);
  // you could define e.g your pins and change other settings
  cfg.pin_ws = I2S_LRCK;
  cfg.pin_bck = I2S_BCLK;
  cfg.pin_data = I2S_DOUT;
  //cfg.mode = I2S_STD_FORMAT;
  cfg.sample_rate = 44100;
  cfg.channels = 1;

  i2s.begin(cfg);
  out.begin();

  // set initial volume
  volume.begin(cfg);        // we need to provide the bits_per_sample and channels
  volume.setVolume(0.1);

  soundQueue = xQueueCreate(5, sizeof(uint8_t)); // Create Queue which can contains 5 request

    xTaskCreatePinnedToCore(
        audioTask,             /* Function to implement the task */
        "Audio Task",           /* Name of the task */
        4096,                  /* Stack size in words */
        NULL,                  /* Task input parameter */
        3 | portPRIVILEGE_BIT, /* Priority of the task */
        NULL,                  /* Task handle. */
        1                      /* Core where the task should run */
  );

    xTaskCreatePinnedToCore(
        soundClickTask,             /* Function to implement the task */
        "soundClickTask",           /* Name of the task */
        4096,                  /* Stack size in words */
        NULL,                  /* Task input parameter */
        2 | portPRIVILEGE_BIT, /* Priority of the task */
        NULL,                  /* Task handle. */
        1                      /* Core where the task should run */
  );

  audioSemaphore = xSemaphoreCreateBinary();
  xSemaphoreGive(audioSemaphore); // Khởi tạo Semaphore ở trạng thái "available"
}

Other Steps to Reproduce

...no...

What is your development environment

Arduino, ESP32 v2.x

I have checked existing issues, discussions and online documentation

pschatzmann commented 2 months ago

Just install the latest update: I already closed the very same issue quite recently.

thanh01pmt commented 2 months ago

Thank @pschatzmann for your help. It works like a charm when I download the main repo. However, the latest release [v0.9.8] has errors with "AudioCodecs/CodecMP3Helix.h". I test the v.0.9.8 on both esp32 v3.0.3 and esp32 v2.0.17. Now, I stick with main repo on esp32 v3.0.3.