cgl28 发表于 2011-05-11 15:32

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_NUM160

/* 用于保存数字音频数据的内存缓冲区 */
unsigned char *pbuf = new unsigned char;
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,&currentsamplingrate);
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,&currentsamplingrate);
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");
}
*/
}
}

不知有没有遇到相似问题的交流下?

cgl28 发表于 2011-05-12 08:44

没人回复。。。
页: [1]
查看完整版本: arm linux 语音采集和播放程序 Input/output error 问题