【问题标题】:libusb - How to select an alternate setting of a usb-soundcard for stereo recording?libusb - 如何为立体声录音选择 USB 声卡的备用设置?
【发布时间】:2016-05-04 12:23:44
【问题描述】:

我有一个 USB 声卡,它具有以下设置并允许使用 48000hz 2 通道 16 位进行立体声录制,所以我正在尝试这样设置:

UsbConfiguration[mId=1,mName=null, mAttributes=160, mMaxPower=50, 
    mInterfaces=[                                                                
        UsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=1,mSubclass=1,mProtocol=0,
            mEndpoints=[]
        UsbInterface[mId=1,mAlternateSetting=0,mName=null,mClass=1,mSubclass=2,mProtocol=0,
            mEndpoints=[]
        UsbInterface[mId=1,mAlternateSetting=1,mName=null,mClass=1,mSubclass=2,mProtocol=0,
            mEndpoints=[UsbEndpoint[mAddress=4,mAttributes=9,mMaxPacketSize=384,mInterval=1]]
        UsbInterface[mId=1,mAlternateSetting=2,mName=null,mClass=1,mSubclass=2,mProtocol=0,
            mEndpoints=[UsbEndpoint[mAddress=4,mAttributes=9,mMaxPacketSize=576,mInterval=1]]
        UsbInterface[mId=1,mAlternateSetting=3,mName=null,mClass=1,mSubclass=2,mProtocol=0,
            mEndpoints=[UsbEndpoint[mAddress=4,mAttributes=9,mMaxPacketSize=192,mInterval=1]]
        UsbInterface[mId=2,mAlternateSetting=0,mName=null,mClass=1,mSubclass=2,mProtocol=0,
            mEndpoints=[]
        UsbInterface[mId=2,mAlternateSetting=1,mName=null,mClass=1,mSubclass=2,mProtocol=0,
            mEndpoints=[UsbEndpoint[mAddress=138,mAttributes=5,mMaxPacketSize=196,mInterval=1]]
        UsbInterface[mId=2,mAlternateSetting=2,mName=null,mClass=1,mSubclass=2,mProtocol=0,
            mEndpoints=[UsbEndpoint[mAddress=138,mAttributes=5,mMaxPacketSize=294,mInterval=1]]
        UsbInterface[mId=2,mAlternateSetting=3,mName=null,mClass=1,mSubclass=2,mProtocol=0,
            mEndpoints=[UsbEndpoint[mAddress=138,mAttributes=5,mMaxPacketSize=388,mInterval=1]]
        UsbInterface[mId=2,mAlternateSetting=4,mName=null,mClass=1,mSubclass=2,mProtocol=0,
            mEndpoints=[UsbEndpoint[mAddress=138,mAttributes=5,mMaxPacketSize=582,mInterval=1]]
        UsbInterface[mId=3,mAlternateSetting=0,mName=null,mClass=3,mSubclass=0,mProtocol=0,
            mEndpoints=[UsbEndpoint[mAddress=130,mAttributes=3,mMaxPacketSize=16,mInterval=16]
    ]
]

我正在尝试选择传入接口并将其与立体声输入的备用设置一起使用,并对立体声输出接口执行相同的操作。 对于输入,我尝试使用以下代码在本地进行:

int AndroidUSBAudioIO_start(int sampleRate, int bufferSize, void *callback, void *clientData) {
    int rc = -1;

    if (androidUSBAudioIO == NULL) {
        androidUSBAudioIO = (AndroidUSBAudioIOInternals *) malloc(sizeof(AndroidUSBAudioIOInternals));
    }
    androidUSBAudioIO->samplerate = sampleRate;
    androidUSBAudioIO->buffersize = bufferSize;
    androidUSBAudioIO->callback = (audioUSBProcessingCallback *) callback;
    androidUSBAudioIO->clientData = clientData;
    androidUSBAudioIO->maruStream = 0;
    androidUSBAudioIO->isSetup = 0;
    androidUSBAudioIO->isPlaying = 0;

    rc = libusb_init(NULL);
    if (rc < 0) {          
    }

    androidUSBAudioIO->deviceHandle = libusb_open_device_with_vid_pid(NULL, VID, PID);
    if (!androidUSBAudioIO->deviceHandle) {
        rc = -1;
        goto out;
    }
    rc = libusb_reset_device(androidUSBAudioIO->deviceHandle);
    if (rc < 0) {
        goto out;
    }
    rc = libusb_set_configuration(androidUSBAudioIO->deviceHandle, 1);
    if (rc < 0) {
    }
    rc = libusb_kernel_driver_active(androidUSBAudioIO->deviceHandle, IFACE_NUM);
    if (rc == 1) {
        rc = libusb_detach_kernel_driver(androidUSBAudioIO->deviceHandle, IFACE_NUM);
        if (rc < 0) {
            goto out;
        }
    }
    rc = libusb_claim_interface(androidUSBAudioIO->deviceHandle, IFACE_NUM);
    if (rc < 0) {
        goto out;
    }

    rc = libusb_set_interface_alt_setting(androidUSBAudioIO->deviceHandle, 1, 2);
    if (rc < 0) {
        printf("libusb_claim_interface: %s.\n", libusb_error_name(rc));
        goto out;
    }
    ...

设置备用界面时出现以下错误:

Fatal signal 11 (SIGSEGV) at 0x0000001d (code=1), thread 10303

并且在获得使用设备的权限后还尝试使用以下代码从 java 中执行此操作:

UsbDeviceConnection mUsbDevConn = mUsbManager.openDevice(mAudioDevice);
int mReqType = 0x01; //
int mRequest = 0x0B; // SET_INTERFACE USB SPEC CONSTANT
int mValue = 0x02; // alt settings
int mIndex = 0x01; // interface nr
byte[] mBuffer = null;
int mLength = 0;
int mTimout = 1000;
mUsbDevConn.controlTransfer(UsbConstants.USB_DIR_OUT | mReqType, mRequest, mValue, mIndex, mBuffer, mLength, mTimout);

我收到以下错误:

Error (status 6: **UNKNOWN**)

我错过了什么?

【问题讨论】:

    标签: android audio java-native-interface usb libusb


    【解决方案1】:

    我认为 libusb_set_interface_alt_setting 调用本身导致 SIGSEGV 是非常不寻常的。我希望之前的调用会导致这种情况,或者 SIGSEGV 是调用的间接影响。也就是说,此调用更改了备用设置,这有效地开始了音频数据的传输。如果缓冲区、其他数据结构或回调未正确设置,则可能会导致 SIGSEGV。

    在您的情况下,我会在代码中添加更多调试消息,包括在库和您的回调中,以尝试缩小崩溃前的最后一件事。

    如果代码适用于“单声道”设备,请查看在迁移到“立体声”时发生了什么变化。也许数据包大小(缓冲区)需要更大。

    就 Java 版本而言,错误 6 可能与您在尝试更改备用设置之前似乎没有分离任何内核驱动程序或声明接口这一事实有关。

    过去我发现有必要从每个接口(包括 HID 接口)中分离内核驱动程序,以在启动音频之前释放分配的总线带宽。

    最后,如果免费版的 usbEffects (Android App) 可以在这个设备上运行,你可以通过 Wi-Fi 将 adb 连接到手机并在连接的设备上运行该应用程序以查看调试消息,该消息将告诉 requestType ,请求等参数对于此硬件是正确的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-08
      • 1970-01-01
      • 2011-06-21
      • 1970-01-01
      相关资源
      最近更新 更多