Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

recording WAV to SD is not working with ADPCM #1690

Closed
1 task done
ffaerber opened this issue Sep 6, 2024 · 1 comment
Closed
1 task done

recording WAV to SD is not working with ADPCM #1690

ffaerber opened this issue Sep 6, 2024 · 1 comment

Comments

@ffaerber
Copy link

ffaerber commented Sep 6, 2024

Problem Description

i try this example https://www.pschatzmann.ch/home/2023/05/21/adpcm-and-wav-files/
and this https://github.com/pschatzmann/arduino-audio-tools/blob/main/tests-cmake/codec/wav/wav.cpp but its not working.
if i record a wav with ADPCM. the wav file is only containing silence with some cracking noises.

Device Description

xiao esp32s3 sense

Sketch

SdFs SD;
AudioInfo info(16000, 1, 16);
I2SStream microphone;
SdFile wavFile;
ADPCMEncoder adpcm_encoder(AV_CODEC_ID_ADPCM_IMA_WAV); 
EncodedAudioStream wavEncoderToFile(&wavFile, new WAVEncoder(adpcm_encoder, AudioFormat::ADPCM));
VolumeStream vol(wavEncoderToFile);
StreamCopy micToFileCopier(wavEncoderToFile, microphone);

I2SStream speaker;
MP3DecoderHelix mp3Decoder;
EncodedAudioStream mp3DecoderToSpeaker(&speaker, &mp3Decoder);
URLStream url;
StreamCopy urlToSpeakerCopier(mp3DecoderToSpeaker, url);


void recorder(void *pvParameters) {
  int randomNumber = random(1000, 10000);
  sprintf(filename, "/%04d.wav", randomNumber);
  if (SD.begin(21)) {
    if (wavFile.open(filename, O_WRONLY | O_CREAT )) {
      Serial.println("wavFile is open");
    }else{
      Serial.println("error open wavFile");
    }
  }
  wavEncoderToFile.begin();
  while (1) {
    if (recording) {
      micToFileCopier.copy();
    } else {
      wavEncoderToFile.end();
      Serial.println("record Stop");
      wavFile.close();
      sendNotification(xHttpControllerHandle, UPLOAD_VOICE_RECORD);
      vTaskDelete(NULL);
    }
  }
}

void player(void *pvParameters) {
  playing = true;
  String apiUrl = String(apiProtocol) + String(apiHostname) + String(":") + String(apiPort);
  String _messageAudioUrl = apiUrl + String("/messages/") + messageId + String("/audio");
  const char* messageAudioUrl = _messageAudioUrl.c_str();
  url.begin(messageAudioUrl, "audio/mp3");
  mp3DecoderToSpeaker.begin();
  urlToSpeakerCopier.copyAll();
  mp3DecoderToSpeaker.end();
  playing = false;
  vTaskDelete(NULL);
}


void audioController(void *pvParameter) {
  uint32_t ulNotificationValue;
  const TickType_t xTicksToWait = portMAX_DELAY;
  TaskHandle_t xRecorderHandle = NULL;
  TaskHandle_t xPlayerHandle = NULL;

  AudioLogger::instance().begin(Serial, AudioLogger::Warning);

  auto microphone_cfg = microphone.defaultConfig(RX_MODE);
  microphone_cfg.copyFrom(info);
  microphone_cfg.signal_type = PDM;
  microphone_cfg.i2s_format = I2S_PCM;    
  microphone_cfg.pin_bck = I2S_PIN_NO_CHANGE;
  microphone_cfg.pin_ws = 42;
  microphone_cfg.pin_data = 41;
  microphone_cfg.port_no = 0;

  auto vol_cfg = vol.defaultConfig();
  vol_cfg.copyFrom(info);
  vol_cfg.allow_boost = true;
  vol.begin(vol_cfg);
  vol.setVolume(12);

  auto speaker_cfg = speaker.defaultConfig(TX_MODE);
  speaker_cfg.copyFrom(info); 
  speaker_cfg.i2s_format = I2S_STD_FORMAT;
  speaker_cfg.port_no = 1;
  speaker_cfg.pin_bck = 4; // BCLK
  speaker_cfg.pin_ws = 43; // LRC
  speaker_cfg.pin_data = 3; // DIN - Data Input
  speaker_cfg.port_no = 1;
  speaker.begin(speaker_cfg);
  
  microphone.begin(microphone_cfg);
  wavEncoderToFile.begin(info);
  mp3DecoderToSpeaker.begin();

  while (true) {
    if (xTaskNotifyWait(pdFALSE, ULONG_MAX, &ulNotificationValue, xTicksToWait) == pdPASS) {
      EventCode currentEvent = static_cast<EventCode>(ulNotificationValue);

      switch (currentEvent) {

        case START_VOICE_RECORD:
          Serial.println("START_VOICE_RECORD");
          recording = true;
          xTaskCreatePinnedToCore(recorder, "recorder", 12*1024, NULL, 1, &xRecorderHandle, APP_CPU);
          break;

        case STOP_VOICE_RECORD:
          Serial.println("STOP_VOICE_RECORD");
          recording = false;
          sendNotification(xMqttControllerHandle, PUBLISH_APP_STATE);
          break;

        case START_PLAY:
          Serial.println("START_PLAY");
          xTaskCreatePinnedToCore(player, "player", 24*1024, NULL, 1, &xPlayerHandle, APP_CPU);
          break;

        default:
          Serial.println("Unknown event in microphone");
          break;
      }
    } else {
      Serial.println("Failed to receive from appEventQueue");
    }

    vTaskDelay(100 / portTICK_PERIOD_MS);
  }
}

Other Steps to Reproduce

recording to SD without ADPCMEncoder works fine.

What is your development environment

Arduino

I have checked existing issues, discussions and online documentation

  • I confirm I have checked existing issues, discussions and online documentation
@pschatzmann
Copy link
Owner

pschatzmann commented Sep 25, 2024

The adpcm test case was passing successfully.
The WAV codec was indeed broken: I committed a correction and added a corresponding test case

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants