Enabling a USB Audio Class 2.0 Audio Input Stream

1.9k views Asked by At

I've been trying to set up a USB Audio Input Stream on my microcontroller device. I know that each USB Audio stream has two alternate settings; Alternate setting 0 is where no stream is available; Alternate setting 1 is when there is a stream available.

I've already set up USB Audio Output so I know the stream descriptors work fine. Obviously, the microcontroller calls a USB interrupt to activate the output when the host tells it when audio is coming through (tells microcontroller to enable alternate setting 1...). However, now I'm confused how to enable the USB Audio input side. I'm confused because obviously the host doesn't tell the microcontroller that input is coming through... rather the device tells the host it's sending data through.

If anyone could give me insight how I would properly enable the input stream properly that would be wonderful. I'm wondering if I should just hard enable the endpoint and just send data that way? I can give more code to if need be but I guess this is more of a thinking type/algorithmic approach of question.

Here is my descriptor of the stream's alternate settings:

.iface_alt0.bLength                  = sizeof(usb_iface_desc_t)
.iface_alt0.bDescriptorType          = USB_DT_INTERFACE
.iface_alt0.bInterfaceNumber         = UDI_AUDIO_IFACE_DATA_IN_NUMBER
.iface_alt0.bAlternateSetting        = 0
.iface_alt0.bNumEndpoints            = 0
.iface_alt0.bInterfaceClass          = AUDIO_IFACE_CLASS
.iface_alt0.bInterfaceSubClass       = AUDIO_IFACE_SUBCLASS_STREAMING
.iface_alt0.bInterfaceProtocol       = AUDIO_IFACE_IP_VERSION_02_00
.iface_alt0.iInterface               = 0
.iface_alt1.bLength                  = sizeof(usb_iface_desc_t)
.iface_alt1.bDescriptorType          = USB_DT_INTERFACE
.iface_alt1.bInterfaceNumber         = UDI_AUDIO_IFACE_DATA_IN_NUMBER
.iface_alt1.bAlternateSetting        = 1
.iface_alt1.bNumEndpoints            = UDI_AUDIO_IN_NB_ENDPOINTS
.iface_alt1.bInterfaceClass          = AUDIO_IFACE_CLASS
.iface_alt1.bInterfaceSubClass       = AUDIO_IFACE_SUBCLASS_STREAMING
.iface_alt1.bInterfaceProtocol       = AUDIO_IFACE_IP_VERSION_02_00
.iface_alt1.iInterface               = 0

Thanks!

EDIT - Just read this source:

"When this configuration is enabled, the first two interface descriptors with bAlternativeSettings equal to zero is used. However during operation the host can send a SetInterface request directed to that of Interface one with a alternative setting of one to enable the other interface descriptor." - USB in a Nutshell

Revised Question: How do I send a SetInterface Request to enable the USB device accept an input stream?

new update - Is there a way I can set the alternate setting active through the descriptors? I was reading this about the stream descriptor -> "The bmControls field contains a set of bit pairs, indicating which Controls are present and what their capabilities are." "D1..0 Active Alternate Setting Control", "D3..2 Valid Alternate Setting Control".

resolved sort of -
So it looks like I just had to open up an audio app on my host device to enable the alternate setting... I didn't know that was the case.

1

There are 1 answers

8
ralf htp On BEST ANSWER

int libusb_set_interface_alt_setting (libusb_device_handle * dev, int interface_number, int alternate_setting)

http://libusb.org/static/api-1.0/group__dev.html#ga3047fea29830a56524388fd423068b53

in general the fields in a descriptor are like pointers to memory locations. if the mapping is faulty the device will not work.as the host has a certain mapping in its driver the device has to obey this mapping

in http://www.usb.org/developers/docs/devclass_docs/audio10.pdf on page 117 is said that there is a top-level Standard AudioControl descriptor and lower-level Class-Specific Audio Control Descriptors.

Beside the AudioStreaming descriptor you have to set other descriptors also correctly. In the example in http://www.usb.org/developers/docs/devclass_docs/audio10.pdf page 126 has to be set Standard Audio Streaming Interface Descriptor, Class-Specific Audio Streaming Descriptor, Type I format descriptor, Standard Endpoint Descriptor, Class-specific Isochronous Audio Data Endpoint Descriptor

i do not know what class your device implements, maybe you should set all these descriptors then it will possibly work i can not find a bmControl field in the AudioStreaming descriptor.

Normally alternate settings are used to switch between the endpoints or the AudioStreaming Interfaces, see the Class-specific Interface Descriptor on page 117

in http://www.usb.org/developers/docs/devclass_docs/audio10.pdf from page 58-64 are all audio streaming relevant descriptors

in the linux USB audio driver there is a bmControl field:

/* 22  * bmControl field decoders
 23  *
 24  * From the USB Audio spec v2.0:
 25  *
 26  *   bmaControls() is a (ch+1)-element array of 4-byte bitmaps,
 27  *   each containing a set of bit pairs. **If a Control is present,
 28  *   it must be Host readable.** If a certain Control is not
 29  *   present then the bit pair must be set to 0b00.
 30  *   If a Control is present but read-only, the bit pair must be
 31  *   set to 0b01. If a Control is also Host programmable, the bit
 32  *   pair must be set to 0b11. The value 0b10 is not allowed.
 33  *
 34  */

http://lxr.free-electrons.com/source/include/linux/usb/audio-v2.h

(http://www.usb.org/developers/docs/devclass_docs/audio10.pdf on page 36)