cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WBA55G-DK1 audio channel digital processing

flamefire
Associate II

Hello

I want to implement some filters on the two audio channels in the BLE_Audio_PBP_Sink example project.
Where in the code would you recommend that i implement these filters. Where can i without problems alter the audio streams.
Are there any documentation that explains the audio paths through out the system, with references to the code?

Kind regards Malte F. Developer

1 ACCEPTED SOLUTION

Accepted Solutions

Hello, 

 

here are some clarifications that can help.

 

-PBP Sink project is using SAI peripheral for I²S generation through the BSP,  (see stm32wba55g_discovery_audio.c)

In the header you can see that several DMA channels are reserved by this BSP : 

-GPDMA1_Channel1 for audio IN : not used at sink

-GPDMA1_Channel2 for audio OUT : used 

-GPDMA1_Channel3 for audio IN (PDM) ; not used 

 

Note that GPDMA channel 0 and 7 are for the ST Link UART (logs, etc..)

 

Keep in mind that I²S is done for stereo, then both left and right channels are link to the same DMA handler. Additionally audio buffers are in stereo with channel Left and Right interleaved 

 

You can add some processing, if CPU is not overloading, by two ways:

-Directly in CODEC_NotifyDataReady() that must be redefined (weak) and that is called after the LC3 processing

-Aligned on a DMA interrupt, when CODEC_ReceiveData() is called, but you may have to delay the signal to ensure that SAI, LC3, and application are still working on separated buffer 

 

You can find some information related to audio data path here:

https://wiki.st.com/stm32mcu/wiki/Connectivity:Bluetooth_LE_Audio_-_STM32WBA_LC3_Codec

 

Best regards,

View solution in original post

6 REPLIES 6
STTwo-32
ST Employee

Hello @flamefire 

What are the filters that you are looking to implement. The filters should be implemented on the process of audio filtration and inside the example.

Best Regards.

STTwo-32

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

flamefire
Associate II

Ideally any filter. The main reason is to implement a cross over filter, and some high and low pass filters.
Could you please reference a method or place in the example project, where i can access the audio/data buffer and apply filters?

Kind Regards Malte F.

flamefire
Associate II

@STTwo-32 
After further study of the code in the BLE_Audio_PBP_Sink project, i can see that the DMA is used on four channels in main.c. I suspect that maybe two of these channels are used for audio left and right?

DMA_HandleTypeDef handle_GPDMA1_Channel2;
DMA_HandleTypeDef handle_GPDMA1_Channel1;
DMA_HandleTypeDef handle_GPDMA1_Channel7;
DMA_HandleTypeDef handle_GPDMA1_Channel0;

 And these are used externally in many other files.

I then think that i can insert filter processing in the stm32wbaxx_it.c

like this:

/**
  * @brief This function handles GPDMA1 Channel 2 global interrupt.
  */
void GPDMA1_Channel2_IRQHandler(void)
{
  /* USER CODE BEGIN GPDMA1_Channel2_IRQn 0 */
  BSP_AUDIO_OUT_IRQHandler(0,0);

  CODEC_ManagerProcess();

  //filter processing 
  process_audio_via_dma();

  /* USER CODE END GPDMA1_Channel2_IRQn 0 */
  /* USER CODE BEGIN GPDMA1_Channel2_IRQn 1 */

  /* USER CODE END GPDMA1_Channel2_IRQn 1 */
}

But its hard to know what channel is left and right audio.
I can also see that there is a SAI driver in the STM32WBA_HAL_Driver directory. The SAI driver is not currently used in the project to my knowledge, but maybe this is a better way to handle the audio data?

Could you share some thoughts on this?

Kind regards Malte F.

Hello, 

 

here are some clarifications that can help.

 

-PBP Sink project is using SAI peripheral for I²S generation through the BSP,  (see stm32wba55g_discovery_audio.c)

In the header you can see that several DMA channels are reserved by this BSP : 

-GPDMA1_Channel1 for audio IN : not used at sink

-GPDMA1_Channel2 for audio OUT : used 

-GPDMA1_Channel3 for audio IN (PDM) ; not used 

 

Note that GPDMA channel 0 and 7 are for the ST Link UART (logs, etc..)

 

Keep in mind that I²S is done for stereo, then both left and right channels are link to the same DMA handler. Additionally audio buffers are in stereo with channel Left and Right interleaved 

 

You can add some processing, if CPU is not overloading, by two ways:

-Directly in CODEC_NotifyDataReady() that must be redefined (weak) and that is called after the LC3 processing

-Aligned on a DMA interrupt, when CODEC_ReceiveData() is called, but you may have to delay the signal to ensure that SAI, LC3, and application are still working on separated buffer 

 

You can find some information related to audio data path here:

https://wiki.st.com/stm32mcu/wiki/Connectivity:Bluetooth_LE_Audio_-_STM32WBA_LC3_Codec

 

Best regards,

Hi,

I have tried my best to follow your instructions for implementing some audio processing on the audio samples.

I am trying to access the audio samples via CODEC_NotifyDataReady inside tmap_app.c. I have tried to make a very simple loop which tries to mute the left audio channel. Assuming the data is interleaved left and right.

void CODEC_NotifyDataReady(uint16_t conn_handle, void* decoded_data)
{
  /* When only one channel is active, duplicate it for fake stereo on SAI */
  uint32_t i;
  uint16_t *pData = (uint16_t *)(decoded_data);   /* 16 bits samples */

  if(pData == (pPrevData + 1)){
    /* we start receiving two channels */
    Nb_Active_Ch = 2;
    //LOG_INFO_APP("2 Channels Active");
  }
  pPrevData = pData;

  if (Nb_Active_Ch < 2)
  {
	//LOG_INFO_APP("1 Channel Active");
    for (i = 0; i < Sink_frame_size/2; i+=2)
    {
      /* decoded_data is organized with a decimation equal to 2, so we duplicate each sample */
      pData[i+1] = pData[i];
    }
  }

  for(i = 0; i < Sink_frame_size; i+=2){  //Trying to mute left channel
	  pData[i] = 0;
  }
}

 Doing so results in the program freezing with an analog output looking like this:Output.png

Looks like one of the channels (blue signal in oscilloscope) was succesfully muted before the program froze. I can't explain why the yellow channel appears the way it does.

 

I am running the STM32Cube_FW_WBA_V1.6.0 on the STM32WBA55G-DK1. The application example running is the BLE_Audio_TMAP_Peripheral.


Any suggestions would be greatly appreciated. My audio processing does not have to happen here, i just need to know where i can safely access the raw audio samples.

Hello,

 

Note that Sink_frame_size is the total len used by the DMA (in samples), meaning it contains 2 x LC3 frames (20ms of data in the example). But we are working with half and full transfer DMA interrupt  (10ms frames), so you have to use (Sink_frame_size / 2) for your loop. 

 

Additionally, CODEC_NotifyDataReady() is called for each LC3 frame decoded, meaning there is 4 different pointers provided  (same as provided in CODEC_ReceiveData because 1 ch / CIS)

  • Left     / First half of total the buffer
  • Right  / First half
  • Left    / Second half
  • Right  / Second half 

 

Thus, you have to check that pData is on the left channel, so here is my proposal :

  if ((pData == aSnkBuff) || (pData == aSnkBuff + Sink_frame_size/2))
  {
    for(i = 0; i < Sink_frame_size/2; i+=2){  //Trying to mute left channel
      pData[i] = 0;
    }
  }

 

Best regards,