BLE audio stream quality

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
DaCh_1995281
Level 3
Level 3
First solution authored 10 sign-ins 10 questions asked

I currently have a PSoC 6 streaming audio to another PSoC 6 but I am having some issues with the quality of the audio being played back. The audio can be heard well enough to understand speech but the quality is not as good as I would like it to be.

There is also a constant noise that I can hear that occurs less frequently when I use a larger buffer for the audio, so I believe the noise is from the DMA or I2S being turned on/off but haven't been able to fix it.

I am using a pair of PSoC 6 BLE Pioneer Kits each with a TFT Display Shield for my setup.

I have attached my workspace for reference.

Any help would be appreciated.

1 Solution

Hello Daniel,

I am yet to get sometime to test this project. But I notice you have two DMA's DMA_PlayLeft and PlayRight?? Why do you have them? Since I2S is serial interface, you should store the data in a single buffer (for both Right and left channel, properly interleaved) and transfer to the I2S TX FIFO. From the DMA configuration, it looks like you are triggering PlayRight after you do a PlayLeft element transfer, this will trigger another write to the TX FIFO while there is a write to the TX from PlayLeft - the bytes might get a bit mixed up. I think your intention is to transfer the same byte to both left and right?? In that case, please try the below -

1. Use only one DMA or I2S Tx

2. Have 2 element X-Loop - do not increment neither source nor destination address

3. Have the 'n' (or 240 as seen in your config) as Y-Loop count. Use '1' element as source increment for Y-Loop.

This could solve your issue, if that is what is causing the issue

Please try this and let me know, before i try it in a kit here and sorry for a delay in response, been away a bit

Regards,

Meenakshi Sundaram R

View solution in original post

7 Replies
Yugandhar
Moderator
Moderator
Moderator
500 solutions authored 1000 replies posted 5 likes given

Hello,

Apologies for the delay.

Could you please let us know the steps to replicate.

Thanks,

P Yugandhar.

0 Likes

1) In the CY_BLE_EVT_STACK_ON case of the AppCallback function in host_main.c (should be the first event), uncomment the call to Cy_BLE_GAPP_StartAdvertisement(CY_BLE_ADVERTISING_FAST, CY_BLE_PERIPHERAL_CONFIGURATION_0_INDEX) for the peripheral device and uncomment the call to Cy_BLE_GAPC_StartScan(CY_BLE_SCANNING_FAST, 0u) for the client device.

2) The client and peripheral should automatically connect. The LED will turn blue on both, briefly flash cyan, then go back to blue.

3) Press and hold SW2 on the client and you should be able to hear what the mic picks up though the jack on the peripheral if you have headphones connected.

Note that you may need to press the reset button to make it work. When I plug in the devices all I hear is the constant noise i mentioned before. If I press the reset button, The noise is much quieter and I can hear the audio from the mic, though the quality isn't the best.

Also the client will not connect to a previously connected device, it needs to be reset to connect to the same device again. This isn't really an issue, just something I haven't gotten around to fixing/implementing.

Hope this helps.

0 Likes

Hello Daniel,

I am yet to get sometime to test this project. But I notice you have two DMA's DMA_PlayLeft and PlayRight?? Why do you have them? Since I2S is serial interface, you should store the data in a single buffer (for both Right and left channel, properly interleaved) and transfer to the I2S TX FIFO. From the DMA configuration, it looks like you are triggering PlayRight after you do a PlayLeft element transfer, this will trigger another write to the TX FIFO while there is a write to the TX from PlayLeft - the bytes might get a bit mixed up. I think your intention is to transfer the same byte to both left and right?? In that case, please try the below -

1. Use only one DMA or I2S Tx

2. Have 2 element X-Loop - do not increment neither source nor destination address

3. Have the 'n' (or 240 as seen in your config) as Y-Loop count. Use '1' element as source increment for Y-Loop.

This could solve your issue, if that is what is causing the issue

Please try this and let me know, before i try it in a kit here and sorry for a delay in response, been away a bit

Regards,

Meenakshi Sundaram R

lock attach
Attachments are accessible only for community members.

Hi Meenakshi,

I tried your suggestions and the quality has improved from before and the noise isn't really there anymore.

However it still doesn't sound quite right. The playback speed on the receiving side is fine but the pitch of the audio sounds off. For example, when I speak into the mic, it doesn't quite sound like my voice.

I have attached an updated version of my project.

Thanks,

Daniel

0 Likes

EDIT: I think I mistook the 3rd divisor as is since it is '+1' divisor in PDM, the data rate should be 8 ksps for PDM too. In that case, I think you can try Rodolfo's suggestion. I will try the project and see where the issue lies

One other suggestion, I see that the PDM sample rate is around 16 ksps but I2S output frame rate is only 8 ksps. This is like stretching the 16 ksps data to a 8 ksps output. Definitely will sound like you are playing the audio slower (1 s audio over 2 s)

So may be try either increasing the I2S frame rate to 16 ksps (if your firmware can handle that rate) or reduce the PDM sample rate to 8 ksps and see if that helps.

Regards,

Meenakshi Sundaram R

0 Likes

I tried following Rodolfo's suggestion but haven't been able to improve the quality of the audio.

Also I am hearing a slight echo in the playback.

Would you have any other suggestions that might help?

0 Likes
RodolfoGL
Employee
Employee
250 solutions authored 250 sign-ins 5 comments on KBA

Try to setup the Channel Length to 32 bits (instead of 16 bits).

In codec.c, change the data alignment. You can try:

ret = Codec_SendData(CODEC_REG_MODE_CTRL1, CODEC_MODE_CTRL1_DIF_32M_32M);

If doesn't get better, try different configurations of alignment, but keep the Channel Length to 32 bits. Note that you need to change the clock divider to keep the sample rate around 8 ksps.