免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2930 | 回复: 1
打印 上一主题 下一主题

arm linux 语音采集和播放程序 Input/output error 问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-05-11 15:32 |只看该作者 |倒序浏览
在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,&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");
  }
*/
}
}

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

论坛徽章:
0
2 [报告]
发表于 2011-05-12 08:44 |只看该作者
没人回复。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP