arm linux 语音采集和播放程序 Input/output error 问题
在arm9 linux 系统下,写简单的 语音采集和播放程序 遇到问题:
步骤
1.将/dev/dsp 以O_RDWR 和 同步方式打开,设置采样频率8000,双通道,16位
2.在循环中read 160字节,接着write刚读到的160字节。
问题
这段代码在Linux - pc上,编译运行是正常的,但是在arm上,刚开始几个周期是正确的,后来read就返回错误 错误码为5 - Input/output error。
不知道是什么原因?
如果在write之后,写上ioctl(f,SNDCTL_DSP_SYNC,NULL),程序正常,不过每个读写时间会很长。
代码
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>
#include <errno.h>
#include<time.h>
#include <string.h>
#include <errno.h>
#define LENGTH 5 /* 存储秒数 */
#define RATE 8000 /* 采样频率 */
#define SIZE 16 /* 量化位数 */
#define CHANNELS 2 /* 声道数目 */
#define READ_WRITE_NUM 160
/* 用于保存数字音频数据的内存缓冲区 */
unsigned char *pbuf = new unsigned char[READ_WRITE_NUM];
int main()
{
int f, val;
int flags;
int status;
int currentsamplingrate;
f = open("/dev/dsp", O_RDWR | O_NONBLOCK);
if (f < 0)
{
printf("open error code read = %d\n", errno);
return -1;
}
// Now that we've opened the file, we can set the blocking
// mode again
flags = fcntl(f,F_GETFL);
if (flags < 0)
{
printf("get open file param error\n");
return -1;
}
flags &= ~O_NONBLOCK; // disable non-blocking flags
if (fcntl(f,F_SETFL,flags) < 0)
{
printf("set open file param error\n");
return -1;
}
// set internal dma block size and number of fragments
val = 7 | (128<<16);//flagment = 128 number = 128
// val = 7 | (4<<16);//flagment = 128 number = 128
if (ioctl(f,SNDCTL_DSP_SETFRAGMENT,&val) < 0)
{
printf("set buffer flagment error\n");
return -1;
}
else
{
printf("set buffer flagment = %d\n", val);
}
// reset sound device
if (ioctl(f,SNDCTL_DSP_SYNC,NULL) < 0)
{
printf("reset sound device error\n");
return -1;
}
// set to stereo
val = 1;
if (ioctl(f,SNDCTL_DSP_STEREO,&val) < 0)
{
printf("set to stereo error\n");
return -1;
}
else
{
printf("set to stereo = %d\n", val);
}
// set to sixteen bit samples
val = 16;
if(ioctl(f,SNDCTL_DSP_SAMPLESIZE,&val) < 0)
{
printf("set to sixteen bit samples error\n");
return -1;
}
else
{
printf("set to sixteen bit samples = %d\n", val);
}
// set sampling rate
currentsamplingrate = 8000;
int ret = ioctl(f,SNDCTL_DSP_SPEED,¤tsamplingrate);
if (ret < 0)
{
printf("set sampling rate error\n");
return -1;
}
else
{
printf("set sampling rate = %d\n", currentsamplingrate);
}
ioctl(f,SOUND_PCM_READ_RATE,¤tsamplingrate);
printf("set read rate = %d\n", currentsamplingrate);
// set sample encoding to little endian and signed
val = AFMT_S16_LE;
if (ioctl(f,SNDCTL_DSP_SETFMT,&val) < 0)
{
printf("set sample encoding to little endian and signed error\n");
return -1;
}
else
{
printf("set sample encoding to little endian and signed = %d\n", val);
}
/* 循环,直到按下Control-C */
memset(pbuf, 0xcf, READ_WRITE_NUM);
while (1)
{
//read
printf("read begin:\n");
status = read(f, pbuf, READ_WRITE_NUM);
if (status != READ_WRITE_NUM)
{
printf("read wrong number of bytes\n");
if(status == -1)
{
printf("read errno = %d\n", errno);
}
}
printf("read end:\n");
//write
printf("write begin:\n");
status = write(f, pbuf, READ_WRITE_NUM);
if (status != READ_WRITE_NUM)
{
printf("write wrong number of bytes\n");
if(status == -1)
{
printf("write eeror = %d\n", errno);
}
}
printf("write end:\n");
/* if (ioctl(f,SNDCTL_DSP_SYNC,NULL) < 0)
{
printf("reset sound device error\n");
}
*/
}
}
不知有没有遇到相似问题的交流下?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没人回复。。。