linux下音频采集与播放问题
大家好,
本人在开发板上做了一个实时音频监听程序,主要流程如下:
1、打开dev\dsp设备,并设置参数
2、进入while(1)不断进行 采集read()和 播放 write()
目前情况:在采样率为8k的时候,声音听起来很流畅,但把采样率提到16k时,就会出现吱吱的杂音。因为采集与播放都用到了同一个设备,所以两者不能并行处理,只能串行,这样就肯定会有声音丢失,但是,个人认为丢失不多的话影响不大,采样率为8k的时候,播放没有问题就可以证明这一点,但现在的问题是为什么16k不行呢?
附上简单源码:
int i=1,rp=1;
int fd;
int bits, chns;
int status;
rate = atoi(argv[1]);
if(rate != 16000 && rate != 8000) rate = 8000;
printf("run rate: %d\n",rate);
fd = open("/dev/dsp", O_RDWR);
if (fd < 0) {
printf("open of /dev/dsp failed\n");
return -1;
}
status = ioctl(fd, SOUND_PCM_WRITE_RATE, &rate);
if (status == -1)
printf("SOUND_PCM_WRITE_WRITE ioctl failed\n");
bits = SIZE; /* sample size */
status = ioctl(fd, SNDCTL_DSP_SETFMT, &bits); //for 6446
if (status == -1)
printf("SOUND_PCM_WRITE_BITS ioctl failed\n");
if (bits != SIZE)
printf("unable to set sample size\n");
chns = CHANNELS; /* mono or stereo */
status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &chns);
if (status == -1)
printf("SOUND_PCM_WRITE_CHANNELS ioctl failed\n");
if (chns != CHANNELS)
printf("unable to set number of channels\n");
set_input_select(0);//选择mic输入
frag_size = atoi(argv[2]);
//frag_size = 320;
if(frag_size <= 0 || frag_size > 1000) frag_size = DEF_FRAGSIZE;;
ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag_size);
printf("run frag_size: %d\n",frag_size);
//int frag_num = DEF_FRAGNUM;
int frag_num = atoi(argv[3]);
if(frag_num <= 0 || frag_num > 1000) frag_num = DEF_FRAGNUM;;
ioctl(fd, 5001, &frag_num);
printf("run frag_num: %d\n",frag_num);
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGABRT, signal_handler);
int size, avail;
ioctl(fd, 5002, NULL);
int read_size = atoi(argv[2])/40;
rp = 0;
while (1) {
if(rp)
{
//printf("start record! rb:%d\n",rb);
size = read(fd, &buf[read_start], read_size);
//write(r_fd, &buf[read_start], read_size);
read_start += read_size;
read_start %= BUF_LENGTH;
rp=0;
}
else
{
size = write(fd, &buf[write_start], read_size);
//write(r_fd, rebuf1, read_size);
write_start += read_size;
write_start %= BUF_LENGTH;
rp=1;
}
}
system("date");
close(fd);
return 0;