我目前正在使用libusb(1.0.9)为我的Android应用程序支持USB麦克风(Samson Q1U)。我从设备获得数据流没有问题,但我想读取有关数据格式(位深度,采样率,通道)的信息。到目前为止,USB一直很混乱,所以请原谅我在下面使用它的尝试。问题是控制转移,我不相信它设置正确。我尝试了许多不同的传输参数组合,但都有返回错误代码-1,-7和& -9。任何帮助都会很棒。
基本上,我想得到这个描述符:
AudioStreaming Interface Descriptor:
bLength 23
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 1
bSubframeSize 2
bBitResolution 16
bSamFreqType 5 Discrete
tSamFreq[ 0] 8000
tSamFreq[ 1] 11025
tSamFreq[ 2] 22050
tSamFreq[ 3] 44100
tSamFreq[ 4] 48000
这是我的控制转移代码:
extern "C" void Java_com_example_test_LibUsb_nativeGetAudioInfo(JNIEnv *env, jobject obj){
libusb_init(NULL);
devh = libusb_open_device_with_vid_pid(NULL,VID,PID);
libusb_kernel_driver_active(devh, 0);
libusb_detach_kernel_driver(devh, 0);
libusb_claim_interface(devh, 0);
libusb_set_interface_alt_setting(devh,0,0);
uint8_t requestType = 0b1 | 0b01 | 0b00001;
uint8_t bRequest = 0x06;
uint16_t wValue = 0x24;
uint16_t wIndex = 0;
unsigned char data[23];
unsigned int timeout = 1000;
int rc = libusb_control_transfer(devh, requestType, bRequest, wValue, wIndex, data, sizeof(data), timeout);
LOGD("%d",rc);
int cnt = 0;
if(rc > 0){
char bLength = data[cnt++];
char bDescriptorType = data[cnt++];
char bDescriptorSubtype = data[cnt++];
char bFormatType = data[cnt++];
char bNrChannels = data[cnt++];
char bSubframeSize = data[cnt++];
char bBitResolution = data[cnt++];
char bSamFreqType = data[cnt++];
int rates[bSamFreqType];
LOGD("%d",bNrChannels);
LOGD("%d",bBitResolution);
for(int i = 0;i < bSamFreqType;i++){
char byte1 = data[cnt++];
char byte2 = data[cnt++];
char byte3 = data[cnt++];
rates[i] = ((byte1 & 0xFF) << 8 | (byte2 & 0xFF) << 16 | (byte3 & 0xFF) << 24);
LOGD("%d",rates[i]);
}
}
libusb_exit(NULL);
}
以下是完整的设备描述符:
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x17a0 Samson Technologies Corp.
idProduct 0x0002 Q1U dynamic microphone
bcdDevice 0.01
iManufacturer 1
iProduct 2
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 177
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 90mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 40
bInCollection 1
baInterfaceNr( 0) 1
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Microphone
bAssocTerminal 2
bNrChannels 2
wChannelConfig 0x0003
Left Front (L)
Right Front (R)
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 1
bSourceID 3
iTerminal 0
AudioControl Interface Descriptor:
bLength 10
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 3
bSourceID 1
bControlSize 1
bmaControls( 0) 0x01
Mute Control
bmaControls( 1) 0x02
Volume Control
bmaControls( 2) 0x02
Volume Control
iFeature 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 2
bDelay 1 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 23
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 1
bSubframeSize 2
bBitResolution 16
bSamFreqType 5 Discrete
tSamFreq[ 0] 8000
tSamFreq[ 1] 11025
tSamFreq[ 2] 22050
tSamFreq[ 3] 44100
tSamFreq[ 4] 48000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0064 1x 100 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x01
Sampling Frequency
bLockDelayUnits 0 Undefined
wLockDelay 0 Undefined
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 2
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 2
bDelay 1 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 23
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 2
bSubframeSize 2
bBitResolution 16
bSamFreqType 5 Discrete
tSamFreq[ 0] 8000
tSamFreq[ 1] 11025
tSamFreq[ 2] 22050
tSamFreq[ 3] 44100
tSamFreq[ 4] 48000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x00c8 1x 200 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x01
Sampling Frequency
bLockDelayUnits 0 Undefined
wLockDelay 0 Undefined
答案 0 :(得分:0)
我也在使用 libusb 库从Android上的USB麦克风录制。
我试图使用 libusb 接口来解析描述符,例如 libusb_get_config_descriptor(),但不幸的是它没有用。
我的解决方案是自己做。 在USB documentation类中使用getRawDescriptors() + UsbDeviceConnection方法:
//parse audio interface descriptors of TYPE 1 FORMAT (PCM) - get all recording settings
public static List<UsbAudioInfo> ParseUsbRawDescriptor(byte[] rawDesc)
{
//list of settings my flat custom class
List<UsbAudioInfo> list = new ArrayList<>();
final int INTERFACE = 4;
final int AUDIO = 1;
final int STREAMING = 2;
//Timber.i("Descriptor length: " + rawDesc.length);
int idVendor = ((rawDesc[9] & 0xff) << 8) | (rawDesc[8] & 0xff);
int idProduct = ((rawDesc[11] & 0xff) << 8) | (rawDesc[10] & 0xff);
int bLength = 0;
for(int i = 0; i<rawDesc.length; i+=bLength) {
bLength = rawDesc[i];
int bDescriptorType = rawDesc[i+1];
if (bDescriptorType == INTERFACE)
{
int bInterfaceNumber = rawDesc[i+2];
int bAlternateSetting = rawDesc[i+3];
int bNumEndpoints = rawDesc[i+4];
int bInterfaceClass = rawDesc[i+5];
int bInterfaceSubClass = rawDesc[i+6];
//interested only in ADUIO STREAMING interface with endpoints (support only PCM >> Type I Format Type Descriptor)
if (bInterfaceClass == AUDIO && bInterfaceSubClass == STREAMING && bNumEndpoints>0)
{
//AudioStreaming Interface Descriptor: (AS_GENERAL)
bLength += rawDesc[i+bLength];
//AudioStreaming Interface Descriptor: (FORMAT_TYPE)
int ftbLength = rawDesc[i+bLength];
//before we proceed check if IN endpoint (recording) => jump to endpoint desc
int bEndpointAddress = rawDesc[i+bLength+ftbLength + 2];
int direction = bEndpointAddress & 0x80; // 10000000b; Bit 7
//only recording
if (direction == USB_DIR_IN)
{
int epaddress = bEndpointAddress & 0xff;
int epmaxpacket = ((rawDesc[i+bLength+ftbLength+5] & 0xff) << 8) | (rawDesc[i+bLength+ftbLength+4] & 0xff);
//PCM TYPE_1 descrtiptor
//http://www.usb.org/developers/docs/devclass_docs/frmts10.pdf
int bNrChannels = rawDesc[i+bLength + 4];
int bBitResolution = rawDesc[i+bLength + 6];
int bSamFreqType = rawDesc[i+bLength + 7];
int ratesind = i+bLength + 8;
for( int s = 0; s < bSamFreqType; s++)
{
//3 byte int:
byte b1 = rawDesc[ratesind + s*3 + 0];
byte b2 = rawDesc[ratesind + s*3 + 1];
byte b3 = rawDesc[ratesind + s*3 + 2];
int rate = (b1 & 0xFF) | ((b2 & 0xFF) << 8) | ((b3 & 0x0F) << 16);
//store in my custom object
UsbAudioInfo info = new UsbAudioInfo();
info.SAMPLING_RATE = rate;
info.ALTSET_NUM = bAlternateSetting;
info.CHANNELS = bNrChannels;
info.ENDPOINT_ADDRESS = epaddress;
info.ENDPOINT_MAXPCKSIZE = epmaxpacket;
info.FORMAT = bBitResolution;
info.INTERFACE_NUM = bInterfaceNumber;
info.VID = idVendor;
info.PID = idProduct;
list.add(info);
}
}
}
}
}
return list;
}