cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L476 USB device audio class sample rate cannot set to 44100

jiangpen
Associate II
Posted on November 11, 2015 at 06:04

hi all,

 I am a newbie in STM32. Now I get an application to make STM32L476 as an USB audio device and playing music in PC will play in the speaker connected to STM32L476. I use the USB audio class(device) and windows 7 default driver.

I get the 48K sample rate running which is the defaut setting, but when I change to 44100, the media player cannot play because the USB driver at this sample rate may manfunction.

the change locate in the USB device lib:

&sharpdefine USBD_AUDIO_FREQ     44100

if I put to below, then it works.

&sharpdefine USBD_AUDIO_FREQ     48000

from the USB device lib document, it seems that is the only place, but does not work. I changed the codec sample rate accordingly, but it is USB problem.

 thanks

JP

#stm32l476
8 REPLIES 8
romanetz4
Associate II
Posted on November 12, 2015 at 17:09

Available frequencies for USB audio device are advertised to host at Type I Interface descriptor.

/* USB Speaker Audio Type III Format Interface Descriptor */

  AUDIO_FORMAT_TYPE_III_DESC_SZ,        /* bLength */

  AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */

  AUDIO_STREAMING_FORMAT_TYPE,          /* bDescriptorSubtype */

  AUDIO_FORMAT_TYPE_III,                /* bFormatType */ 

  0x02,                                 /* bNrChannels */

  0x02,                                 /* bSubFrameSize :  2 Bytes per frame (16bits) */

  16,                                   /* bBitResolution (16-bits per sample) */ 

  0x01,                                 /* bSamFreqType only one frequency supported */ 

  SAMPLE_FREQ(USBD_AUDIO_FREQ),         /* Audio sampling frequency coded on 3 bytes */

  /* 11 byte*/

Also, due to the different size of ISOC OUT frames (44 samples nine times, then 45 samples), the code in class-callback function usbd_audio_DataOut has to be modified.

This code has to get size of audio data in received frame (in samples or bytes) and move them from USB FIFO to audio ring buffer. 

What template do you use, is it HAL or SPL? Syntax slightly differs between them.

jiangpen
Associate II
Posted on November 13, 2015 at 02:24

Thanks pechenko,

I use the STM32CUBE to generate code, I believe the template is HAL.

yes, I check something about 44100 sample rate, seems it cannot be supported directly. Not sure if anything for USB audio device has been done before for this common sample rate.

thanks a lot.

romanetz4
Associate II
Posted on November 13, 2015 at 18:55

Your code needs to receive different size of OUT transactions. Basic approach is to get size of last received frame and append its data to the end of ring buffer with audio data. When remaining place in buffer is less than size of frame, divide received data into two parts, and fill buffer to the end, revert to start and write remaining data.

For synchronization between USB and audio interface ofSTM32, ST offers to drop or duplicate one sample in audio buffer, until two pointers (read and written data) move synchronously. I believe that the best way is to use explicit feedback endpoint as stated in USB Audio Class standard. There are some examples for other architectures (sdr-widget - for AVR32, Freescale USB stack - for its Kinetis family of MCU's, maybe some else exist?). I've written implementation of UAC with explicit feedback for STM32F407 on STM32F4-Discovery board. But it uses SPL and ''older'' library. I'm afraid that direct translation of this code could break your project, much of care is needed.

This code is under GPL license, because of GPL'ed sdr-widget.

________________

Attachments :

USB_STM32F4.7z : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0fu&d=%2Fa%2F0X0000000bcI%2FQS5tws5Uh2gz.hz.mrO2nagi6.BNcKgKO17fgMi_jF8&asPdf=false
jiangpen
Associate II
Posted on November 16, 2015 at 11:46

Dear pechenko,

 I tried to follow your instructions to change function.

USBD_AUDIO_DataOut

Basically, I understand the approach, that is change this function to record the actual recv size, and then put recv data into ring buffer.

But, when I tried to get the recv size, it always gets me 176.

I used ''int datalen=USBD_LL_GetRxDataSize(pdev, epnum);'' to get the rx data len which actually called ''hpcd->OUT_ep[ep_addr & 0x7F].xfer_count'', it didn't work.

If possible, could you share the change of the USBD_AUDIO_DataOut or the way get actual RX len, thanks a lot.

romanetz4
Associate II
Posted on November 16, 2015 at 17:15

Have you changed the maximum packet size for OUT endpoint to 180 bytes? I've just tested my code (for STM32F407) @1k sample rate and have seen blinking LED, showing audio packets with larger length. The sound was without glitches. You can test it with STM32F4-Discovery, just put wire from PC7 to PA15

________________

Attachments :

USB_STM32F4_44100.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0CL&d=%2Fa%2F0X0000000bcE%2FtwEwSjjOHEz.IRe_y64Zr_QOlwNUTn0dvhVp0yLXv9M&asPdf=false
jiangpen
Associate II
Posted on November 19, 2015 at 12:35

yes, that is my first try, but unsucess. After refering your code, I make the 44100 working. Thanks a lot!!!

But another problem is it just works about 1 mins, and I check the reason, that is due to my codec sample rate(44177) is slightly faster than USB's 44100. As a result, the read buffer ptr from codec will exceed the USB write ptr.  I am not pretty sure if adding a feedback end point will help, as it seems delay the USB sending only, not sure can speed up USB speed over 44100.

maybe I need find a good way to tune the codec clock to run exactly 44100, or let codec run less than 44100, but using feedback endpoint to slow down the USB sending.

romanetz4
Associate II
Posted on November 19, 2015 at 14:41

Explicit feedback endpoint is a key to the asynchronous playback. With feedback provided data, host either resamples audio data or tunes the speed of playback. Otherwise, the MCU MUST lock its I2S masterclock to USB frame rate (1 kHz - SOF rate - for Full-speed). Usual single-chip audio solutions (say, PCM2904, C-Media CM109) use a kind of PLL to lock on-chip oscillator to USB clock.

mlrogers2002
Associate II
Posted on June 13, 2016 at 14:48

Hello Roman, is this project with the explicit feedback available to share? I'd really like to get a look at it, as I want to implement a feedback endpoint for my own project.

Thanks.