如何在连接的USB耳机上使用libusb播放音频文件(从wav文件读取的字节数),我已尝试使用ISynchronous传输来执行,但调用libusb_submit_transfer()时控制传输失败,让我了解实现此方案所涉及的步骤
偏移字段大小值描述
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;
}