USB Microphone Library Overview

Description

The USB microphone API set encapsulates all the pieces that control access to the UAC stack, including the attachment and removal of UAC devices. It manages the state of the driver chain, performs data and sample rate conversion, and matches the sampling frequency used in the audio subsystem (AX) of 32kHz exactly.

To keep data copies to a minimum, the API is designed around a shared ring buffer architecture. APIs exist to query the amount of available samples and to set the number of samples consumed by the audio system. That way, the finite state machine in the microphone driver can properly manage itself as the data source of the ring buffer.

The memory used for the ring buffer is provided by a hierarchically higher level process, the application. If that application wishes to perform DMA directly from that shared ring buffer then it is the application's responsibility to manage buffer alignment and memory coherency. This library requires a minimum alignment of 4 bytes.

All the memory necessary to open a UAC device instance comes from the application. Upon attachment of a UAC device, the application can query the memory resources necessary to open that UAC device instance. The API set is designed that the query returns the minimum memory resources required. An application can provide more than the minimum when indicated by the flags that are part of the memory resource definition.

It is the application's responsibility to check the fill level of the shared ring buffer before drawing from it. PCM data arrive in bursts defined by the isochronous scheduling interval of the device. The UAC microphone driver matches the average incoming data rate to the 32kHz audio sample clock used in the AX subsystem. If necessary it will also perform sample rate conversion to 32kHz. All endian-ness related conversions are performed in the library as well.

In the event that the application does not draw audio samples as quickly as they arrive, then the microphone driver will overwrite the oldest data. That assures that after the drawing of PCM samples matches the incoming rate, only a single skip occurred.

In the event that the application draws data faster than they arrive, which can be either by design, e.g., simple pitch shifting schemes, or due to link loss with the GamePad (DRC). In those cases an application will read old data that are left in the ring buffer. To avoid this condition an application must query the amount of available data prior to using them for playback.

A UAC device can be removed at any time. Although the application will receive notification of that event, it is not strictly synchronized with the flow of data. It is necessary that an application queries the amount of available data before playback.

Up to two microphones are supported by this library at the same time. This constraint is by design.

It is preferred to use the USB microphone library in applications that only wish to perform USB input streaming from devices such as microphones. This library will support most microphones on headsets as well. Applications that will perform both input and output streaming with UAC devices need to use the UAC library instead.

Usage Model

The driver is intended to be initialized once by calling USBMICInit. At that time a callback function is provided to the UAC driver stack that will notify the application of events such as attachment and detachment of UAC devices. In that callback, additional context specific information is returned to the application. The device instance handle is one of those data items that is created by the UAC stack every time a UAC device is attached.

After an application has initialized the UAC stack, it will receive notifications of events via its callback function. For UAC devices that were discovered at boot up an attach event will be generated as soon as the UAC stack is initialized.

The UAC API USBMICOpenQuery is now deprecated and need no longer be called prior to calling USBMICOpen. Memory allocations for the UAC driver stack are performed in the UAC library. However, an application allocated ring buffer is still required to open the device.

Among the data that accompany a device connection event is an instance handle for the device that has just been connected. This handle is necessary for most USB MIC API calls. It is only valid until a disconnect event is sent by the UAC library.

The necessary steps to start receiving PCM data from the attached microphone start with calling USBMICOpen. Successfully opening the UAC device will prepare the entire UAC stack to start streaming audio samples, but does not start the streaming itself. This is performed by calling USBMICStart and will continue until USBMICStop is called, the UAC device is disconnected, a process switch occurs, or the system is powered down.

After streaming is started the application needs to call USBMICGetStatus to get the number of PCM samples that are ready in the shared ring buffer. After a sufficient number of samples is in the buffer, the application is free to consume them as it sees fit. To keep the buffer state in the microphone driver coherent, the application must inform the driver of the number of samples it has consumed from the shared ring buffer by calling USBMICSetDataConsumed.

Since the ring buffer fill matches the nominal 32kHz sample rate of the AX system exactly, it is permissible to derive all microphone playback timing from the AX system generated interrupts. However, the application is encouraged to check that the number of samples available in the buffer is sufficient for the number of samples scheduled for consumption.

Before any link loss with the UAC device indication can be given, microphone audio samples will drop out. This is because the streaming of data and attachment and detachment of devices is not strictly synchronized.

As long as a given UAC device stays attached, streaming can be started and stopped as often as the application sees fit.

After streaming is stopped, a given UAC device can be closed with USBMICClose. Like the start and stop case, a UAC device can be reopened and closed with the same resource set as long as the given device stays attached.

All memory resource and ring buffer provided at USBMICOpen time must stay in place until USBMICClose has returned or a detach event has been received.

Upon arrival of the detach event in the UAC stack, the library will forcibly stop streaming and close the detached device instance. An appropriate notification is given to the application. The application does not need to call USBMICStop and USBMICClose when a detach event is received.

The UAC microphone gain is programmable. The functions USBMICSetState and USBMICGetState are used for that purpose. The sequence of steps is as follows:

The above steps need to be performed only once following the attachment of the UAC device. The following steps need to be performed every time a new gain level is to be programmed:

Process Switch Handling

In order release the foreground processing in an orderly manner, an application needs to leave the UAC driver stack in a quiescent state. This is performed by stopping any streaming, and closing the respective device for all microphones. Then USBMICUninit needs to be called to finish the shutdown of the UAC subsystem. Process switching related details are covered elsewhere.

In the event that an application does not perform the steps outlined above, the UAC library will perform them when it receives the message indicating release of foreground. The library will receive notification after the application.

When foreground status is reacquired, the UAC library is in the same state as if it had never been initialized. All the steps to initialize the UAC library need to be performed again and attach notifications for attached microphones will be sent again.

See Also

USBMICInit
USBMICUninit
USBMICOpenQuery
USBMICOpen
USBMICClose
USBMICStart
USBMICStop
USBMICGetStatus
USBMICSetDataConsumed
USBMICGetState
USBMICSetState
Error Codes

Revision History

2013/05/08 Automated cleanup pass.
2012/08/03 Cleanup Pass
2012/06/22 Update for SDK 2.06
2012/01/05 Initial version.


CONFIDENTIAL