主题 : arm linux 语音采集和播放程序 Input/output error 问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 40081
精华: 0
发帖: 1
金钱: 5 两
威望: 1 点
贡献值: 0 点
综合积分: 2 分
注册时间: 2011-03-15
最后登录: 2017-09-13
楼主  发表于: 2011-05-11 15:23

 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,&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");
  }
*/
 }
}

不知有没有遇到相似问题的交流下?
级别: 新手上路
UID: 48584
精华: 0
发帖: 40
金钱: 210 两
威望: 42 点
贡献值: 0 点
综合积分: 80 分
注册时间: 2011-06-02
最后登录: 2011-12-25
1楼  发表于: 2011-08-13 16:42
不支持读写打开
级别: 侠客
UID: 16892
精华: 0
发帖: 58
金钱: 290 两
威望: 58 点
贡献值: 0 点
综合积分: 116 分
注册时间: 2010-03-23
最后登录: 2017-02-11
2楼  发表于: 2012-11-01 17:14
引用第1楼12555于2011-08-13 16:42发表的  :
不支持读写打开


是驱动的原因?还是硬件的原因?如果开发网络电话的话需要换芯片?还是要修改驱动?谢谢!
级别: 新手上路
UID: 107168
精华: 0
发帖: 8
金钱: 40 两
威望: 8 点
贡献值: 0 点
综合积分: 16 分
注册时间: 2014-08-16
最后登录: 2018-08-22
3楼  发表于: 2014-12-04 22:17

 回 2楼(ke123456le) 的帖子

话说你解决了么,看了好些帖子,好像都没人说怎么解决这个问题