arm linux 语音采集和播放程序 Input/output error 问题

发布于 2022-10-15 07:16:48 字数 5794 浏览 18 评论 0

在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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

终止放荡 2022-10-22 07:16:48

没人回复。。。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文