/ / USB Control Transfer для отримання AudioStreaming Descriptor з libusb - android, c, android-ndk, usb, libusb

Передача USB через управління, щоб отримати Deskriptor аудіостримування з libusb - android, c, android-ndk, usb, libusb

Зараз я працюю над мікрофоном USB (SamsonQ1U) підтримка мого додатка для Android за допомогою libusb (1.0.9). Я отримав потокове передавання даних з пристрою, який не працює, але я хотів би прочитати інформацію про формат даних (глибина бітів, частота дискретизації, канали). Поки що 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 для відповіді № 1

Я також використовую libusb бібліотека для запису з USB-мікрофона на Android.

Я намагався використати libusb інтерфейс для аналізу дескрипторів, наприклад libusb_get_config_descriptor () але, на жаль, це не спрацювало.

Моє рішення було зробити це самостійно. Використовуючи Документація USB + 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;
}