2

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.

yun
  • 1,243
  • 11
  • 30

1 Answers1

2

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)

ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • Hm well I'm not using libusb so this doesn't really help... But I did follow the comments on there and set the interface's alt setting once the USB device attached itself. But the problem seems more like something with sending to the host now... Should the host (like a mac) just readily accept usb audio data? I know the host will not enable usb audio output until the host sends a set interface request stating audio data is being transmitted to the device – yun Jan 13 '17 at 21:04
  • in usb protocol the host initiates any communication. even if the device sends an interrupt it has to wait until the host polls it. so if there is a stream then the host requested it before and so it should accept it. maybe sniff the usb using wireshark or http://unix.stackexchange.com/questions/138742/how-to-dump-usb-traffic to see what happens – ralf htp Jan 13 '17 at 21:41
  • Hm that confirms some suspicions I've been having over the last day. 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". Could be I just have to set these? – yun Jan 13 '17 at 21:49
  • I'm using Audio Class 2.0. And the linux link you put is what I saw too. But I'm not sure how to get the host to enable/set the alternate setting.. – yun Jan 14 '17 at 14:23
  • http://stackoverflow.com/questions/28274535/what-is-an-alternate-setting-in-a-usb-interface normally the host driver is responsible for this. you can set the alternate setting it by sending a control transfer (to EP0). this is what the libusb function `libusb_set_interface_alt_setting` does. " *The default setting for an interface is always alternate setting zero. Alternate settings can be selected exclusively by the standard control transfer set_interface.*" http://www.linux-usb.org/USB-guide/x75.html – ralf htp Jan 14 '17 at 14:39
  • if the host does not recognize the device completely maybe something int the 'descriptor tree' is wrong meaning that a complete *Standard AudioStreaming Interface Descriptor* has something like *Class-Specific Audio Streaming Descriptor*, (*Type I format descriptor*), *Standard Endpoint Descriptor*, *Class-specific Isochronous Audio Data Endpoint Descriptor* in its substructure – ralf htp Jan 14 '17 at 14:43
  • Hm so to try to enable this audio stream I should try to send a control transfer? I'll try it on Monday... I guess I haven't tried that yet. But the device is definitely getting recognized and I'm able to change codec parameters via USB so the descriptor tree is OK – yun Jan 14 '17 at 15:01
  • 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. I'll mark this as the correct answer because you helped me the most/all the information you gave me was correct for my understanding. THanks! – yun Jan 16 '17 at 19:36