最近在学习录放音程序的编写。 
我写了个小程序,以8000采样率录音20ms,由于设置sample size为16bits,所以每20ms从/dev/dsp录音 8000*20/1000*16/8 = 320字节。 
320个字节一录好,就立刻把这些数据写入到/dev/dsp。 
 
相当于本地自环,录音的同时放音。 
 
但是有一个问题,理论上讲,录音和放音应该几乎是同时的,即最大延时应该为20ms左右,人耳朵是听不出来的。但是现在放音比录音延迟有大概2秒左右。 
 
我又试着用cat /dev/dsp > /tmp/a.wav 
录一段声音以后cat /tmp/a.wav > /dev/dsp 
这样也是要等大概2秒左右才开始有声音。 
 
请问各位大侠,这个到底是什么原因造成的呢?音频设备初始化也不需要这么长时间啊,用madplay播放音频文件立刻就有声音了。难道音频设备给printf一样,有缓冲区的,等满了以后才会刷新缓冲区。 
 
下面是我的代码。- #include <stdio.h>
 
 - #include <stdlib.h>
 
 - #include <string.h>
 
 - #include <unistd.h>
 
 - #include <fcntl.h>
 
  
- #include <sys/types.h>
 
 - #include <sys/stat.h>
 
 - #include <sys/ioctl.h>
 
 - #include <sys/select.h>
 
 - #include <sys/time.h>
 
 - #include <sys/soundcard.h>
 
  
- #include <errno.h>
 
  
- #define REC_LENGTH 320
 
  
- #define RATE 8000   /* the sampling rate */
 
 - #define SIZE 16      /* sample size: 8 or 16 bits */
 
 - #define CHANNELS 1  /* 1 = mono 2 = stereo */
 
  
 
- /* this buffer holds the digitized audio */
 
 - //unsigned char rec_buf[TIME*RATE*SIZE*CHANNELS/8];
 
 - unsigned char rec_buf[REC_LENGTH] = {0};
 
  
- int dsp_fd;        /* sound device file descriptor */
 
 - int rd_fd;
 
 - int arg;        /* argument for ioctl calls */
 
 - int status;   /* return status of system calls */
 
  
- void init_r(void)
 
 - {
 
 -         //printf("init read\n");
 
 -         dsp_fd = open("/dev/dsp", O_RDONLY);
 
  
-         if (dsp_fd < 0)
 
 -         {
 
 -                 perror("open of /dev/dsp failed");
 
 -                 printf("error no = %d\n", errno);
 
 -                 exit(1);
 
 -         }
 
  
-         /* set sampling parameters */
 
 -         arg = SIZE;           /* sample size */
 
 -         status = ioctl(dsp_fd, SOUND_PCM_WRITE_BITS, &arg);
 
 -         if (status == -1)
 
 -                 perror("SOUND_PCM_WRITE_BITS ioctl failed");
 
 -         if (arg != SIZE)
 
 -                 perror("unable to set sample size");
 
  
-         arg = CHANNELS;  /* mono or stereo */
 
 -         status = ioctl(dsp_fd, SOUND_PCM_WRITE_CHANNELS, &arg);
 
 -         if (status == -1)
 
 -                 perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
 
 -         if (arg != CHANNELS)
 
 -                 perror("unable to set number of channels");
 
  
-         arg = RATE;           /* sampling rate */
 
 -         status = ioctl(dsp_fd, SOUND_PCM_WRITE_RATE, &arg);
 
 -         if (status == -1)
 
 -                 perror("SOUND_PCM_WRITE_WRITE ioctl failed");
 
 -         //printf("init r ok\n");
 
 - }
 
  
- void init_w(void)
 
 - {
 
 -         //printf("init write\n");
 
 -         rd_fd = open("/dev/dsp", O_WRONLY);
 
  
-         if (rd_fd < 0)
 
 -         {
 
 -                 perror("open of /dev/dsp failed");
 
 -                 printf("error no = %d\n", errno);
 
 -                 exit(1);
 
 -         }
 
  
-         /* set sampling parameters */
 
 -         arg = SIZE;           /* sample size */
 
 -         status = ioctl(rd_fd, SOUND_PCM_WRITE_BITS, &arg);
 
 -         if (status == -1)
 
 -                 perror("SOUND_PCM_WRITE_BITS ioctl failed");
 
 -         if (arg != SIZE)
 
 -                 perror("unable to set sample size");
 
  
-         arg = CHANNELS;  /* mono or stereo */
 
 -         status = ioctl(rd_fd, SOUND_PCM_WRITE_CHANNELS, &arg);
 
 -         if (status == -1)
 
 -                 perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
 
 -         if (arg != CHANNELS)
 
 -                 perror("unable to set number of channels");
 
  
-         arg = RATE;           /* sampling rate */
 
 -         status = ioctl(rd_fd, SOUND_PCM_WRITE_RATE, &arg);
 
 -         if (status == -1)
 
 -                 perror("SOUND_PCM_WRITE_WRITE ioctl failed");
 
 -         //printf("init w ok\n");
 
 - }
 
  
 
- int main(void)
 
 - {
 
 -         /*初始化DSP*/
 
 -         printf("init DSP\n");
 
 -     /*初始化读句柄*/
 
 -         init_r();
 
 -     /*初始化写句柄*/
 
 -         init_w();
 
  
-         while(1)
 
 -         {
 
 -         /*录音*/
 
 -                 status = read(dsp_fd, rec_buf, sizeof(rec_buf));
 
 -                 if (status != sizeof(rec_buf))
 
 -                         perror("read wrong number of bytes");
 
  
 
 
-                 /*放音*/
 
 -                 status = write(rd_fd, rec_buf, sizeof(rec_buf));
 
 -                 if (status != sizeof(rec_buf))
 
 -                         perror("read wrong number of bytes");
 
 -         }
 
 -     
 
 -         close(dsp_fd);
 
 -         close(rd_fd);
 
 -         return 0;
 
 - }
 
 
  复制代码 请各位大侠给点思路,谢谢了! |