cancel
Showing results for 
Search instead for 
Did you mean: 

Acoustic Echo Cancelling U5

eduarm
Associate

Hello everyone,

I'm experiencing an issue integrating the FP-AUD-AEC1 v1.2.0 library into my U5 microcontroller project and would appreciate some guidance on the echo cancellation algorithm's behavior.

My Setup:

  • Audio Input: 1 MEMS microphone acquiring data at 8 kHz.
  • Audio Output: Audio streaming data received via CAN FD and played through a speaker.
  • Data Handling: DMA is used for both audio reception and playback.

The Issue: In my processAudioData function, I observed that the algorithm (specifically, the AcousticEC_Data_Input function) buffers data until it accumulates 128 bytes (with ECHO_BUFF set to 128). My expectation was that the algorithm would fill my output buffer with 8 bytes every 1 ms based on the 8 kHz sample rate—not in 128-byte (approximately 16 ms) segments.

Currently, the behavior appears as follows:

  • Initial Phase: The EchoOut buffer starts with zeros.
  • Processing: The algorithm alternates between zeros and echo-cancelled values until the 320-byte output buffer is fully populated.
  • Result: With echo cancellation enabled, the output is noisy.

My Questions:

  1. Segmentation: Why is the algorithm designed to process and update data in 128-byte segments (approximately 16 ms of audio) rather than filling 8 bytes to my output buffer every 1 ms?
  2. Operational Insight: How does this segmentation fit into the intended operation of the echo cancellation algorithm?
  3. Potential Misconfiguration: Could this behaviour indicate a configuration or usage error on my part?

For additional context, my application involves two nodes, each equipped with a MEMS microphone and a speaker, communicating over CAN FD. Without the AEC enabled, the system works perfectly.

Any insights or recommendations would be greatly appreciated.

Thank you in advance for your help!

See below the code

 

 

// FS_AEC = 8000/1000
// int32_t i32_dataBuff[320] = {0};               // Input buffer: 320 bytes from MIC (24-bit data per sample)
// uint32_t u32_Buff_Output_Speaker[320] = {0};   // Output buffer: 320 bytes for speaker (24-bit data per sample)
// Processing 320 bytes to fill half of the SAI DMA buffer (40 ms of audio at 8 kHz)

#if ECHO_CANCELL
  // Copy half of the audio buffer from the speaker acoustic queue
  if (!FIFO_copyFromBuffer(&s_SpeakerAcusticQueue, &u32_Buff_Output_Speaker[0], AUDIO_BUFFER_SIZE / 2)) {
    // Handle buffer copy failure if needed
  }

  // Calculate the number of 1 ms frames: 320 bytes / (8000 Hz / 1000) = 40 ms
  u16_counter = _u16_audioSize / FS_AEC;

  for (u16_counterAC = 0; u16_counterAC < u16_counter; u16_counterAC++) {
    // Convert 24-bit MIC data to 16-bit PCM for echo cancellation
    for (int u16_i = 0; u16_i < FS_AEC; ++u16_i) {
      PCM_BufferAC[u16_i] = (int16_t)(i32_dataBuff[u16_counterAC * FS_AEC + u16_i] >> 8);
    }

    // Convert 24-bit speaker data to 16-bit PCM for echo cancellation
    for (int u16_i = 0; u16_i < FS_AEC; ++u16_i) {
      pAudio_out_8K[u16_i] = (int16_t)(u32_Buff_Output_Speaker[u16_counterAC * FS_AEC + u16_i] >> 8);
    }

    // Run acoustic echo cancellation (AEC) processing
    if (AcousticEC_Data_Input(&PCM_BufferAC[0], pAudio_out_8K, &EchoOut[0], (AcousticEC_Handler_t *)&EchoHandlerInstance)) {
      if (!AcousticEC_Process((AcousticEC_Handler_t *)&EchoHandlerInstance)) {
        // Successfully processed: convert back to 24-bit format for SAI TX
        for (int u16_i = 0; u16_i < FS_AEC; ++u16_i) {
          i32_dataTemEco[u16_counterAC * FS_AEC + u16_i] = (int32_t)EchoOut[u16_i] << 8;
        }
      } else {
        // This block should not be reached under normal conditions
        Error_Handler();
      }
    } else {
      // If AEC input fails, pass through the audio after restoring to 24-bit format
      for (int u16_i = 0; u16_i < FS_AEC; ++u16_i) {
        i32_dataTemEco[u16_counterAC * FS_AEC + u16_i] = (int32_t)EchoOut[u16_i] << 8;
      }
    }
  }

  // Send the processed 320-byte buffer to the speaker via SAI DMA
  if (!FIFO_addToBuffer(&s_SpeakerQueue, (uint32_t *)i32_dataTemEco)) {
    // Handle buffer overflow
    Error_Handler();
  }

  // Transmit the same MIC data over CAN
  memcpy(_u32_dataBuffCAN, i32_dataBuff, (_u16_audioSize) * sizeof(int32_t));

#else

 

 

 

 

1 REPLY 1
Roger SHIVELY
ST Employee

Hello @eduarm 

This post has been escalated to the ST Online Support Team for additional assistance.  We'll contact you directly.

Regards,

Roger