Audio Class Configuration Guidelines
In order to optimize the usage of the audio class, there are a few places to pay attention to when configuring the audio class:
- Memory segment size: parameter
size
ofMem_SegCreate()
or µC/LIB heap size:LIB_MEM_CFG_HEAP_SIZE
- µC/USB-Device general configuration for extra URBs (USB Request Block):
USBD_CFG_MAX_NBR_URB_EXTRA
- Buffers allocated to each AudioStreaming interface: field
MaxBufNbr
of structureUSBD_AUDIO_STREAM_CFG
passed as argument toUSBD_Audio_AS_IF_Cfg
The recommendations for these places are:
- Buffers allocated for each AudioStreaming interface composing your audio function are allocated either from a dedicated memory segment created with
Mem_SegCreate()
or from the heap region defined by µC/LIB. Consequently, the parametersize
ofMem_SegCreate()
or the configuration constantLIB_MEM_CFG_HEAP_SIZE
defining the heap region size must be set large enough to hold all playback and record buffers. USBD_CFG_MAX_NBR_URB_EXTRA
is used by the core layer to assign an URB to each isochronous transfer submitted to the core and that could be queued in a USB device driver. Certain USB device drivers implement a queuing mechanism allowing to queue several isochronous transfers for a given endpoint. If a USB device driver is capable of queuing transfers and in order to take advantage of audio streaming, the total number of allocated buffers for all AudioStreaming interfaces should be equal toUSBD_CFG_MAX_NBR_URB_EXTRA
. It will allow the playback and record tasks to queue each time all isochronous transfers they can. They will spend less time trying to re-submit an isochronous transfer if this one could not be queued. If the USB device driver can only accept one transfer at a time, it is not necessary that the total number of allocated buffers be equal toUSBD_CFG_MAX_NBR_URB_EXTRA
. In that case, you can specify the total number of buffers you want. The result is that playback and record tasks will attempt more often to retry isochronous transfers that cannot be queued.- The field
MaxBufNbr
of structureUSBD_AUDIO_STREAM_CFG
should be set accordingly following the two previous recommendations. Moreover,
Table - Audio Class Configuration Guidelines presents some examples according to the type of audio application.
Constant | Value | Note |
---|---|---|
Playback only application (2 channels, 16 bit resolution, 48 kHz) | ||
APP_CFG_USBD_AUDIO_PLAYBACK_NBR_BUF | 16u | Application constant that can be passed to the field MaxBufNbr of structure USBD_AUDIO_STREAM_CFG . |
USBD_CFG_MAX_NBR_URB_EXTRA | 16u | The USB device driver is able to queue isochronous transfers. |
parameter size of Mem_SegCreate() LIB_MEM_CFG_HEAP_SIZE | - | With 2 channels, 16 bit resolution, 48 kHz, each playback buffer is 192 bytes which gives a total of 192 * 20 = 3072 bytes. The memory segment or heap should be set accordingly to accommodate the 3072 bytes required. |
Record only application (1 channel, 16 bit resolution, 48 kHz) | ||
APP_CFG_USBD_AUDIO_RECORD_NBR_BUF | 16u | Application constant that can be passed to the field MaxBufNbr of structure USBD_AUDIO_STREAM_CFG . |
USBD_CFG_MAX_NBR_URB_EXTRA | 0u | The USB device driver is not able to queue isochronous transfers.
|
parameter size of Mem_SegCreate() LIB_MEM_CFG_HEAP_SIZE | - | With 1 channel, 16 bit resolution, 48 kHz, each record buffer is 96 bytes which gives a total of 96 * 16 = 1536 bytes. The memory segment or heap should be set accordingly to accommodate the 1536 bytes required. |
Playback and record application (playback: 2 channels, 16 bit resolution, 48 kHz; record: 1 channel, 16 bit resolution, 48 kHz) | ||
APP_CFG_USBD_AUDIO_PLAYBACK_NBR_BUF | 16u | Application constant that can be passed to the field MaxBufNbr of structure USBD_AUDIO_STREAM_CFG . |
APP_CFG_USBD_AUDIO_RECORD_NBR_BUF | 16u | Application constant that can be passed to the field MaxBufNbr of structure USBD_AUDIO_STREAM_CFG . |
USBD_CFG_MAX_NBR_URB_EXTRA | 32u | The USB device driver is able to queue isochronous transfers. |
parameter size of Mem_SegCreate() LIB_MEM_CFG_HEAP_SIZE | - | Each playback buffer is 192 bytes which gives a total of 192 * 16 = 3072 bytes and each record buffer is 96 bytes which gives a total of 96 * 16 = 1536 bytes. At least, 5760 bytes must be available from the memory segment or the heap for all audio buffers. More heap space can be necessary for all software resources needed by the USB device stack and other Micrium products used in your application. |
Heap Size
µC/USB-Device uses the heap to allocate some software resources such as internal buffers. The core, classes and certain drivers allocate resources on the heap. Moreover, you must take into account that other Micrium products also allocate from the heap. Thus, its size must be set accordingly.
Another recommendation relates to the configuration of the maximum number of interfaces (constant
USBD_CFG_MAX_NBR_IF
) and alternate interfaces (constant
USBD_CFG_MAX_NBR_IF_ALT
) needed for your audio function. Assuming that the audio class is the only class used, these formula can be used to determine the maximum number of interfaces and alternates interfaces for the audio class:
USBD_CFG_MAX_NBR_IF
= sum of [(1 AudioControl interface + N AudioStreaming interface)] from 1 to X times Audio Interface Collection (AIC)
USBD_CFG_MAX_NBR_IF_ALT
= sum of [(1 AudioControl interface + N AudioStreaming interface * M alternate settings)] from 1 to X times Audio Interface Collection (AIC)
where N is in the range [1, 255] and M in the range [2, 255]
When using the built-in playback or record correction, you should pay attention to the value of the MaxBufNbr
field of the structure
USBD_AUDIO_STREAM_CFG.
The size of the safe zone depends on t he number of streams buffers, set in the field MaxBufNbr
. If you allocate more buffers for a given stream, the safe zone will be larger. Since the pre-buffering threshold for a stream is always ( MaxBufNbr
/ 2), if the safe zone is large, any slight clock drift between the USB and codec clocks will be easily absorbed and the risk of reaching the under-run or overrun situation is reduced (cf. Figure - Playback Ring Buffers Queue Monitoring).
If you activate any stream correction (built-in or feedback), you should set the number of buffers, the field MaxBufNbr
, to a multiple of 6. This will optimize the stream correction processing. You can set the field MaxBufNbr
to one of these pre-defined constants:
USBD_AUDIO_STREAM_NBR_BUF_6
USBD_AUDIO_STREAM_NBR_BUF_12
USBD_AUDIO_STREAM_NBR_BUF_18
USBD_AUDIO_STREAM_NBR_BUF_24
USBD_AUDIO_STREAM_NBR_BUF_30
USBD_AUDIO_STREAM_NBR_BUF_36
USBD_AUDIO_STREAM_NBR_BUF_42
Furthermore, if you have a playback stream, you should favor the feedback correction. Indeed, the feedback correction allows a correction more progressive as the host is doing the audio samples adjustment based on the device feedback for a given stream. It makes the correction smoother and prevent the device from trying to compensate on its side a possible USB and codec clocks drifting by software that could impact the correction performance.