Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents
maxLevel3
minLevel2
indent20px

...

A playback stream carries audio data over an isochronous OUT endpoint. There is a one-to-one relation between an isochronous OUT endpoint, an AudioStreaming interface and a Terminal. 101482827Figure - Playback Stream Dataflow presents the audio data flow implemented inside the Audio Processing module. The playback path relies on a ring buffer queue to synchronize the playback task, the core task and the codec ISR.

...

The record data path takes care of the data rate adjustment. This is required for certain sampling frequencies that do not produce an integer number of audio samples per ms. Partial audio samples are not possible. For those sampling frequencies, the Table - Data Rate Adjustment gives the required adjustment. The data rate adjustment is implemented in the isochronous IN transfer completion callback   USBD_Audio_RecordIsocCmpl().

...

The built-in playback stream correction is active only when the constant USBD_AUDIO_CFG_PLAYBACK_CORR_EN is set to DEF_ENABLED. As explained in section Playback Stream, the stream correction is evaluated before the playback task provides a ready buffer to the audio peripheral driver. The evaluation relies on monitoring the playback ring buffer queue. Two thresholds are defined: a lower limit and an upper limit as shown in Figure - Playback Ring Buffers Queue Monitoring. The figure shows the four indexes used in the ring buffer queue. A buffer difference is computed between the indexes ProducerEnd and ConsumerEnd. For the playback path, ProducerEnd  is linked to the USB transfer completion while  ConsumerEnd  is linked to the audio transfer completion. The buffer difference represent a circular distance between two indexes. If the distance is less than the lower limit, you have an underrun situation, that is the USB side does not produce fast enough the audio samples consumed by the codec. Conversely, if the distance is greater than the upper limit, this is an overrun situation, that is the USB side produces faster then the the codec can consume audio data. To keep the codec and USB in sync, a simple algorithm is used to add an audio sample in case of underrun and to remove a sample frame in case of overrun.  

...

Panel
borderWidth0
titleFigure - Playback Ring Buffers Queue Monitoring


Figure - Adding a Sample in Case of Underrun illustrates the algorithm to add an audio sample in case of underrun situation. 

...

Warning

This stream correction is convenient for low-cost audio design. It will give good results as long as the incoming USB audio sampling frequency is very close to the DAC input clock frequency. However, if the difference between the two frequencies is important, this will add audio distortion.

Figure - Removing a Sample in Case of Overrun illustrates the algorithm to remove an audio sample in case of overrun situation. 

...

The playback stream correction offers the possibility to apply your own correction algorithm. If an underrun or overrun situation is detected, an application callback is called. Listing - Example of Playback Correction Callback Provided by the Application shows an example of playback correction callback prototype and definition provided by the application. 

...

Panel
bgColor#f0f0f0

(1) Prototype of your playback correction callback.

(2) Upon configuration of an AudioStreaming interface with the function USBD_Audio_AS_IF_Cfg , the callback function name is passed to the function. You have the possibility to define a different correction callback for each playback AudioStreaming interface composing your audio topology.

(3) Definition of your playback correction callback. Once the playback is open by the host and the built-in playback correction is enabled (USBD_AUDIO_CFG_PLAYBACK_CORR_EN set to DEF_ENABLED), if an overrun or underrun situation is detected by the Audio Processing module, your callback will be called. You will have access to the structure USBD_AUDIO_AS_ALT_CFG associated to this playback stream through the pointer p_as_alt_cfg. Among the fields, you may be interested in:

  • TerminalID: ID of terminal associated to the playback stream.
  • NbrCh: Number of channels supported by the stream.
  • SubframeSize: Number of bytes occupied by one audio sample.
  • BitRes: Effectively used bits in an audio sample.

Beside the AudioStreaming alternate setting configuration structure, you will know the situation type (underrun or overrun via underrun_flag), the current buffer length (buf_len_cur) and the total buffer length ( buf_len_total ). Then you can apply your own correction algorithm to the buffer referenced by p_buf. If some samples are removed or added to the buffer, you will have to return to the Audio Processing module the adjusted buffer length. Note that you can add or remove only one sample at a time. You can also specify an error code if something went wrong while applying your correction.

...

There is also a built-in record stream correction active only when the constant USBD_AUDIO_CFG_RECORD_CORR_EN is set to DEF_ENABLED. As explained in the section Record Stream, when an isochronous IN transfer completes by calling the callback function  USBD_Audio_RecordIsocCmpl() , the stream correction is evaluated. The evaluation relies on monitoring the record ring buffer queue. Two thresholds are defined: a lower limit and an upper limit based on the same principle as shown in 101482827 Figure - Playback Ring Buffers Queue Monitoring. For the record path, ProducerEnd  is linked to the audio transfer completion while  ConsumerEnd  is linked to the USB transfer completion. This is the opposite of the playback. Moreover, the ring buffer queue scheme is common to the  playback and record streams. And within the audio class, the definition of overrun and  underrun situation is "USB-centric". 

...

The feedback value evaluation relies on monitoring the playback ring buffer queue. Based on the same principle as the playback built-in correction, the buffer difference between the indexes ProducerEnd  and  ConsumerEnd is computed and gives the reflect at which the USB and codec clocks operate.  The feedback monitoring starts only when the playback stream priming is done, that is when the audio class calls the audio peripheral driver function  USBD_Audio_DrvStreamStart . Once the feedback monitoring has started, the underrun or overrun situation requiring a feedback value to be sent to the host is evaluated using the method shown in Table - Feedback Monitoring

Anchor
Table - Feedback Monitoring
Table - Feedback Monitoring

...