cancel
Showing results for 
Search instead for 
Did you mean: 

LC3 CODEC transparent mode.

NRedd.2
Senior

Hi,

I was going through the documentation in this link

It mentions that there is a transparent mode. How can I enable this in the example for PBP Source?

/* Codec Mode */ typedef uint8_t CODEC_Mode_t; #define CODEC_MODE_DEFAULT (CODEC_MODE_FLOW_CTRL) #define CODEC_MODE_FLOW_CTRL (0x01) #define CODEC_MODE_WAIT_SYNC (0x02)

These are the modes available. I do not see an option for transparent mode here.

 

Let's assume that I already have LC3 encoded data that is sent over UART/SPI/USB etc, I do not wish to decode and encode again. In this case, the transparent mode is useful. How can I enable it? Is it even possible?

 

Best regards,

Navin

8 REPLIES 8
TMANE.1
ST Employee

Hello Navin,

 

From what I understand, the sink has to know the data is LC3 encoded format and not transparent, so the coding format exposed inside the periodic advertising must remain LC3 (so no changes inside PBPAPP_SetupBASE())

 

However, you want the codec manager to bypass the LC3. The codec used by the codec manager is given through HCI commands (mainly HCI LE Setup Iso Data Path) called by the audio stack. You can change a_codec_id[0] to AUDIO_CODING_FORMAT_TRANSPARENT in the function PBPAPP_BroadcastSetupAudio(), thus CODEC_SetupIsoDataPath() will be called with transparent mode. 

 

Then you must adapt the application when calling CODEC_SendData() to provide the address of the media packet to be send. Keep in mind that the audio data rate is driven by the isochronous link and CODEC_SendData() must be called synchronously. 

 

Thanks to the clock corrector, the PLL is synchronized to the radio. So maybe it can be done by creating a periodic timer based on the PLL output (at the frame duration rate), and a kind of flow control mechanism to let the WBA drive the data rate on the bus (UART/SPI/USB).

 

Best regards,

Hello @TMANE.1 ,

 

Thank you for your response!

Ah, I see that's where the change needs to be!

While I was going through the CubeMX configuration, I saw that two timers are configured (TIM3 and TIM16). What is the use of TIM16? It seems to stabilize the System Clock. I could not figure out why it is necessary and why ARR is chosen to be 3200.

Also, I could not find the usage of TIM3 in the code. 

 

In case I choose to use RTOS, I want to run the system at max speed (100MHz), is that possible with the change in the code from CubeMX? I ask so because there are several clocks / timers that have certain hardcoded values (TIM16). 

 

NRedd2_0-1750091576021.png

 

In this function, why is the PLL_M set to 6? Since, in CubeMX, it displays the divider value as `\1` .

NRedd2_1-1750091677154.png

 

Your response really helped in understanding the code better. Yet, there are some missing pieces! 

Looking forward to hearing from you!

Best regards,

Navin

 

TMANE.1
ST Employee

Hello, 

 

You are right, TIM16 is used by the system clock manager when starting the HSE oscillator, especially after a low power period. Note that when running the PLL, stop and standby mode could not be used anymore and HSE is never stopped, so TIM16 is not required anymore. 

 

Then I agree with you that TIM3 should be free in the .ioc  since audio projects are not using it. 

 

We decided to align the strategy of the BLE_Audio_PBP_Source with other BLE Audio projects where the system is starting in low power mode (stop or standby, no PLL), and where the audio frequency (=PLL configuration) is depending on the remote device. That is why the PLL is not configured in cubeMX (but could be for PBP source), but is configured after an asynchronous event of the audio stack. 

 

Keep in mind that the closest audio compatible frequency to 100MHz is 98.304MHz (suitable for 8, 16, 24, 32 and 48kHz on the I²S) and values provided in PLL_Ready_Task() are provided for this setup. 

 

Best regards,

Hello @TMANE.1,

 

I see! I verified the clock rate, and it is around 98MHz. Initially, I assumed that the application was running at 16MHz, which would be great for encoding + streaming. But, good to know that it is almost at the maximum now with PLL boost.

 

I will soon test LC3 bypass and let you know if it works. Currently, I busy learning the architecture and making a wrapper for LC3 in Golang. 

 

Thank you for your response!

 

Best regards,

Navin

Hi, 

 

Just some clarification to my previous message : 

The PLL and HSE should not be stopped during the audio stream (no stop or standby mode) because :

-the I²S is continuously streaming audio in our project. It also brings the PLL configuration constraint (audio compatible frequencies). But I understand you may change bus... 

-the codec manager relies on a free running clock (codec_if.c) for managing audio timestamps and latencies

-the codec manager relies on this same clock for synchronizing the PLL to the LSE (=sleep clock / ISO interval at broadcast source)

 

Let's assume you don't use the internal clock synchronization mechanism but found another way to synchronize the audio rate to the LSE, I guess the point 2 could be adapted with low power .

 

Note that TIM16 is used at low power wakeup, at this time TIM16 is clocked by HSI and does not depend on the PLL configuration.

 

Best regards, 

Hi @TMANE.1,

> -the codec manager relies on a free running clock (codec_if.c) for managing audio timestamps and latencies

Since I am using an external bus, will this have any effect on these timestamps? I am also not going to use sleep mode. The device will always be on, as it is connected to a mains supply.

> Let's assume you don't use the internal clock synchronization mechanism but found another way to synchronize the audio rate to the LSE, I guess the point 2 could be adapted with low power .

What are the consequences of not syncing? Will the audio be delayed with an increasing delay over time?

 

TMANE.1
ST Employee

Hello, 

 

Timestamps are used for the generation of the trigger signal (see CODEC_RegisterTriggerClbk()). It is expected to provide data to the codec manager at this callback time (or Tcallback + n*media packet duration) to respect latencies. 

Using external bus, if not aligned on this trigger, will introduce an uncertainty on the latency. 

 

Then if the rate of CODEC_SendData() is not sync with the radio, we are out of the Bluetooth specification. Some packet will be lost, introducing audio glitches and latency changes. 

 

I recommend keeping the PLL sync with the radio and generating a master clock from the STM32WBA for your other device. 

 

Best regards,

Hi @TMANE.1,

 

Thank you for the response and the detailed explanations! It is clear now, the usage of the trigger and sync mechanism. (The library sort of makes it a black box, though!)

I will make sure to implement these while developing the product.

Best regards,

Navin