#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <libusb-1.0/libusb.h>
#include <sys/time.h>
#define VID 0x046d
#define PID 0x0826
#define ISOENDPOINT 0x86
#define TIMEOUT 0
#define INTERFACE 1
#define ALTSETTING 4
#define PACKETLEN 96
#define PACKETNUM 10
static int aborted = 0;
libusb_device_handle *handle;
static FILE *outfile;
int r;
unsigned char oldbuffer[PACKETLEN*PACKETNUM];
static int sampleCount=0;
void write_wav_header(FILE *fp)
{
char ChunkRiff[] = {'R','I','F', 'F' };
char ChunkType[] = { 'W', 'A', 'V', 'E' };
char ChunkFmt[] = { 'f', 'm', 't', ' ' };
char ChunkData[] = { 'd', 'a', 't', 'a' };
short shPad = 1;
int nFormatChunkLength = 0x10;
int nLength = 0;
short shBytesPerSample = 2;
short Channels=1;
short BitsPerSample=16;
int SamplesPerSecond=48000;
int AverageBytesPerSecond=2*SamplesPerSecond;
fwrite(ChunkRiff,4,1,fp);
fwrite(&nLength,4,1,fp);
fwrite(ChunkType,4,1,fp);
fwrite(ChunkFmt,4,1,fp);
fwrite(&nFormatChunkLength,4,1,fp);
fwrite(&shPad,2,1,fp);
fwrite(&Channels,2,1,fp);
fwrite(&SamplesPerSecond,4,1,fp);
fwrite(&AverageBytesPerSecond,4,1,fp);
fwrite(&shBytesPerSample,2,1,fp);
fwrite(&BitsPerSample,2,1,fp);
fwrite(ChunkData,4,1,fp);
fwrite(&nLength,4,1,fp);
}
void write_wav_length(FILE *fp)
{
fseek(fp,40,SEEK_SET);
fwrite(&sampleCount,4,1,fp);
sampleCount+=36;
fseek(fp,4,SEEK_SET);
fwrite(&sampleCount,4,1,fp);
}
void start_stream()
{
unsigned char data[]={0x80,0xbb,0x00};
r=libusb_control_transfer(handle,0x22,0x01,0x0100,0x0086,data,0x0003,0);
}
void stop_stream()
{
}
static void sighandler(int signum)
{
printf("got signal %d\n", signum);
aborted = 1;
}
static void capture_callback(struct libusb_transfer *transfer)
{
int i;
struct libusb_iso_packet_descriptor *desc ;
if(0==memcmp(oldbuffer,transfer->buffer,PACKETNUM*PACKETLEN))
{
printf("same frame.\n");
}
else
{
memcpy(oldbuffer,transfer->buffer,PACKETNUM*PACKETLEN);
}
fwrite(transfer->buffer, PACKETLEN*PACKETNUM, 1, outfile);
sampleCount+=480;
printf("%d\n",sampleCount);
if (!aborted)
libusb_submit_transfer(transfer);
}
static struct libusb_transfer *alloc_capture_transfer(void)
{
int i;
struct libusb_transfer *transfer = libusb_alloc_transfer(PACKETNUM);
unsigned char *buf=malloc(PACKETLEN*PACKETNUM);
if (!transfer&&!buf)
perror("transfer alloc failure");
libusb_fill_iso_transfer(transfer,handle,ISOENDPOINT,buf,PACKETNUM*PACKETLEN,PACKETNUM,capture_callback,NULL,0);
libusb_set_iso_packet_lengths(transfer,PACKETLEN);
return transfer;
}
static void do_capture(void)
{
struct libusb_transfer *transfer[5];
int i=0;
r=libusb_set_interface_alt_setting(handle,INTERFACE,ALTSETTING);
start_stream();
for(i=0;i<5;++i)
{
transfer[i] = alloc_capture_transfer();
}
for(i=0;i<5;++i)
{
r=libusb_submit_transfer(transfer[i]);
}
while (!aborted)
{
if (libusb_handle_events(NULL) < 0)
{
break;
}
}
for(i=0;i<5;++i)
{
libusb_free_transfer(transfer[i]);
}
stop_stream();
libusb_set_interface_alt_setting(handle,INTERFACE,0);
}
int main(int argc, char *argv[])
{
struct timeval tstart,tend;
libusb_init(NULL);
// libusb_set_debug(NULL,4);
handle = libusb_open_device_with_vid_pid(NULL,VID,PID);
if (handle)
{
printf("Opened device: %x\n", handle);
}
libusb_detach_kernel_driver(handle,0);
libusb_detach_kernel_driver(handle,1);
libusb_detach_kernel_driver(handle,2);
libusb_detach_kernel_driver(handle,3);
libusb_detach_kernel_driver(handle,4);
r= libusb_set_auto_detach_kernel_driver(handle,1);
switch(r)
{
case LIBUSB_SUCCESS:printf("set auto detach kernel driver success\n");break;
default: printf("error\n");break;
}
r=libusb_claim_interface(handle,INTERFACE);
switch(r)
{
case LIBUSB_SUCCESS:printf("claim interface success\n");break;
default: printf("error\n");break;
}
struct sigaction sigact;
sigact.sa_handler = sighandler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGINT, &sigact, NULL);
sigaction(SIGTERM, &sigact, NULL);
sigaction(SIGQUIT, &sigact, NULL);
outfile = fopen("test.wav", "wb");
write_wav_header(outfile);
gettimeofday(&tstart,NULL);
do_capture();
gettimeofday(&tend,NULL);
printf("record: %d seconds\n",(int)(tend.tv_sec-tstart.tv_sec));
libusb_release_interface(handle,INTERFACE);
perror("release interface.\n");
write_wav_length(outfile);
fclose(outfile);
libusb_close(handle);
libusb_exit(NULL);
return 0;
}
评论6
最新资源