最近在学习录放音程序的编写。
我写了个小程序,以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;
- }
复制代码 请各位大侠给点思路,谢谢了! |