如何使用libusb播放音频文件(从wav文件读取的字节数)

时间:2013-11-26 08:31:54

标签: c++

如何在连接的USB耳机上使用libusb播放音频文件(从wav文件读取的字节数),我已尝试使用ISynchronous传输来执行,但调用libusb_submit_transfer()时控制传输失败,让我了解实现此方案所涉及的步骤

  • USB Headsetdetails 端点描述符01 1输出,等时,1 ms

偏移字段大小值描述

0 bLength 1 09h

1 bDescriptorType 1 05h Endpoint

2 bEndpointAddress 1 01h 1 Out

3 bmAttributes 1 09h同步,自适应,数据

1..0:传输类型...... 01等时

3..2:同步类型.... 10 ..自适应

5..4:使用类型..00 ....数据

7..6:保留00 ......

4 wMaxPacketSize 2 00C8h 200字节

6 bInterval 1 01h 1 ms

7 bRefresh 1 00h

8 bSynchAddress 1 00h


仅供参考:函数libusb_fill_control_setup()的值是根据主机和设备之间交换的数据包(使用USB分析器查看播放音乐文件时的原始数据包)来自USB分析器

设置数据包 偏移字段大小值描述

0 bmRequestType 1 22h

4..0:收件人... 00010端点

6..5:输入.01 ..... Class

7:方向0 .......主机到设备

1 bRequest 1 01h
2 wValue 2 0100h
4 wIndex 2 0001h
6 wLength 2 0003h


#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <libusb.h>

using namespace std;
libusb_device_handle *dev_handle;
unsigned char *audiobytes = NULL;
int slen = 0;
libusb_transfer_cb_fn cbTest(struct libusb_transfer *transfer);
void submit_write(int endpoint, uint8_t* data, int len, libusb_transfer_cb_fn callback);

libusb_transfer_cb_fn cbTest(struct libusb_transfer *transfer)
{
    cout << "cbTest" << endl;
}

void send_buf(uint8_t request_type, uint8_t request, uint16_t value, uint16_t index,uint8_t* data_in, uint16_t length, 
                   libusb_transfer_cb_fn callback, void* userdata)
{
    libusb_transfer* transfer = libusb_alloc_transfer(0);
    transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER;
    transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;

    uint8_t* data = (uint8_t*)(malloc(length+8));
    libusb_fill_control_setup(data, request_type, request, value, index, 0x0003);
    libusb_fill_control_transfer(transfer, dev_handle, data, callback, userdata, 0);

    int ret;
    ret = libusb_submit_transfer(transfer);
    if (ret == LIBUSB_SUCCESS)
    {
        cout << "send_buf LIBUSB_SUCCESS" << endl;
    }
    else
    {
        cout << "send_buf LIBUSB_FAILURE" << endl;
        libusb_free_transfer(transfer);
    }
}

void readfile()
{
    int i;
    int result;
    FILE *wav;
    FILE *outwav;

    wav = fopen("./test1.wav", "rb");
    outwav = fopen("./out.wav", "wb");

    fseek(wav, 0, SEEK_END);
    slen = ftell(wav);
    cout << "fwrite slen = " << slen << endl;
    rewind(wav);

    audiobytes = (unsigned char*) malloc (sizeof(char)*slen);
    if(audiobytes == NULL)
    {
        fputs("Memory error", stderr);
        exit(1);
    }

    result = fread(audiobytes, 1, slen, wav);
    if(result != slen)
    {
        fputs("Read error",stderr);
        exit(2);
    }

    fclose(wav);
    cout << "fwrite" << endl;
    fwrite(audiobytes+44, 1, slen, outwav);
    fclose(outwav);     
    return;
}

int main() 
{
    libusb_device **devs;   
    libusb_context *ctx = NULL;
    int r;
    ssize_t cnt;
    r = libusb_init(&ctx);
    if(r < 0) 
    {
        cout<<"Init Error "<<r<<endl;
        return 1;
    }
    libusb_set_debug(ctx, 3);

    cnt = libusb_get_device_list(ctx, &devs);
    if(cnt < 0) {
        cout<<"Get Device Error"<<endl;
        return 1;
    }
    cout<<cnt<<" Devices in list."<<endl;

    dev_handle = libusb_open_device_with_vid_pid(ctx, 5013, 37);//USB headset
    if(dev_handle == NULL)
        cout<<"Cannot open device"<<endl;
    else
        cout<<"Device Opened"<<endl;
    libusb_free_device_list(devs, 1);

    int byteswritten;
    if(libusb_kernel_driver_active(dev_handle, 0) == 1) 
    {
        cout<<"Kernel Driver Active"<<endl;
        if(libusb_detach_kernel_driver(dev_handle, 0) == 0)
            cout<<"Kernel Driver Detached!"<<endl;
    }
    r = libusb_claim_interface(dev_handle, 0);
    if(r < 0) 
    {
        cout<<"Cannot Claim Interface"<<endl;
        return 1;
    }
    cout<<"Claimed Interface"<<endl;    

    readfile();
    cout<<"Writing Data..."<<endl;
    send_buf(0x22, 0x01, 0x0100, 0x0001, audiobytes, slen, NULL, NULL);

    r = libusb_release_interface(dev_handle, 0);
    if(r!=0)
    {
        cout<<"Cannot Release Interface"<<endl;
        return 1;
    }
    cout<<"Released Interface"<<endl;

    libusb_close(dev_handle);
    libusb_exit(ctx);
    sleep(40);
    return 0;
}

0 个答案:

没有答案