Linux声卡录音程序之——wav

代码参考自:http://hi.baidu.com/qshlzh/item/fa99a02fbfd4b44f469962f5


#include <sys/soundcard.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>

struct fhead
{
 
  unsigned char a[4];//四个字节存放'R','I','F','F'
  long int b;              //整个文件的长度-8;每个Chunk的size字段,都是表示除了本Chunk的ID和SIZE字段外的长度;
  unsigned char c[4];//四个字节存放'W','A','V','E'

 
  unsigned char d[4];//四个字节存放'f','m','t',''
  long int e;            //16后没有附加消息,18后有附加消息;一般为16,其他格式转来的话为18
  short int f;            //编码方式,一般为0x0001;
  short int g;            //声道数目,1单声道,2双声道;
  long int h;              //采样频率;
  long int i;              //每秒所需字节数;
  short int j;            //每个采样需要多少字节,若声道是双,则两个一起考虑;
  short int k;            //即量化位数

 
  unsigned char p[4];//四个字节存放'd','a','t','a'
  long int q;              //语音数据部分长度,不包括文件头的任何部分
} wavehead;//定义WAVE文件的文件头结构体

#define LENGTH        //录音时间,秒
#define RATE      44100 //采样频率
#define SIZE      16    //量化位数
#define CHANNELS 2    //声道数目
#define RSIZE      8192      //buf的大小,

int main()
{
 
  wavehead.a[0]='R';
  wavehead.a[1]='I';
  wavehead.a[2]='F';
  wavehead.a[3]='F';
  wavehead.b=LENGTH*RATE*CHANNELS*SIZE/8-8;
  wavehead.c[0]='W';
  wavehead.c[1]='A';
  wavehead.c[2]='V';
  wavehead.c[3]='E';
  wavehead.d[0]='f';
  wavehead.d[1]='m';
  wavehead.d[2]='t';
  wavehead.d[3]=' ';
  wavehead.e=16;
  wavehead.f=1;
  wavehead.g=CHANNELS;
  wavehead.h=RATE;
  wavehead.i=RATE*CHANNELS*SIZE/8;
  wavehead.j=CHANNELS*SIZE/8;
  wavehead.k=SIZE;
  wavehead.p[0]='d';
  wavehead.p[1]='a';
  wavehead.p[2]='t';
  wavehead.p[3]='a';
  wavehead.q=LENGTH*RATE*CHANNELS*SIZE/8;
 


  int i;
  unsigned char buf[RSIZE]; //每次循环取得RSIZE大小的容量,放入buf,然后写入文件;放音是相反。
 
  //打开声卡设备,只读方式;并对声卡进行设置
  int fd_dev_r= open("/dev/dsp", O_RDONLY,0777);
  if (fd_dev_r < 0)
  {
      perror("Cannot open /dev/dsp device");
      return 1;
  }
 
  int arg = SIZE;
  if (ioctl(fd_dev_r, SOUND_PCM_WRITE_BITS, &arg) == -1)      //设置量化位数 
  {
              perror("Cannot set SOUND_PCM_WRITE_BITS ");
              return 1;
  }
 
  arg = CHANNELS;
  if (ioctl(fd_dev_r, SOUND_PCM_WRITE_CHANNELS, &arg) == -1)    //设置声道数
  {
              perror("Cannot set SOUND_PCM_WRITE_CHANNELS");
              return 1;
  }
  arg = RATE;
  if (ioctl(fd_dev_r, SOUND_PCM_WRITE_RATE, &arg) == -1)          //设置采样率
  {
              perror("Cannot set SOUND_PCM_WRITE_WRITE");
              return 1;
  }
 
  //打开声卡设备,只写方式;并对声卡进行设置
  int fd_dev_w = open("/dev/dsp", O_WRONLY,0777);
  if (fd_dev_w < 0)
  {
              perror("Cannot open /dev/dsp device");
              return 1;
  }
  arg = SIZE;
  if (ioctl(fd_dev_w, SOUND_PCM_WRITE_BITS, &arg) == -1)          //设置量化位数
  {
            perror("Cannot set SOUND_PCM_WRITE_BITS ");
            return 1;
  }
  arg = CHANNELS;         
  if (ioctl(fd_dev_w, SOUND_PCM_WRITE_CHANNELS, &arg) == -1)    //设置声道数
  {
              perror("Cannot set SOUND_PCM_WRITE_CHANNELS");
              return 1;
  }
  arg = RATE;           
  if (ioctl(fd_dev_w, SOUND_PCM_WRITE_RATE, &arg) == -1)            //设置采样率
  {
              perror("Cannot set SOUND_PCM_WRITE_WRITE");
              return 1;
  }
 
 
  system("rm -f sound.wav");//清除已有的wav录音文件
  int fd_f;
      if(( fd_f = open("./sound.wav", O_CREAT|O_RDWR,0777))==-1)//创建一个wave格式语音文件
      {
              perror("cannot creat the sound file");
      }
      if(write(fd_f, &wavehead, sizeof(wavehead))==-1)//写入wave文件的文件头
      {
            perror("write to sound'head wrong!!");
      }
  for(i=0;i<(LENGTH*RATE*SIZE*CHANNELS/8)/RSIZE;i++)//每次从声卡获得RSIZE大小的数据,共循环了语音长度/RSIZE次
  {
 
   
      if (read(fd_dev_r, buf, sizeof(buf)) != sizeof(buf))
      {
          perror("read wrong number of bytes");
      }
      if(write(fd_f, buf, sizeof(buf))==-1)
      {
                  perror("write to sound wrong!!");
       
  }
  close(fd_dev_r);//关闭只读方式的声卡
  close(fd_f);//关闭wave文件
  printf("play your sound now??\n y OR n\n");
 
  if(getchar()=='y')
  {
      printf("Play...:\n");
      if(( fd_f = open("./sound.wav", O_RDONLY,0777))==-1)
      {
            perror("cannot creat the sound file");
      }
      lseek(fd_f,44,SEEK_SET);
      for(i=0;i<(LENGTH*RATE*SIZE*CHANNELS/8)/RSIZE;i++)
      {
       
              if (read(fd_f, buf, sizeof(buf)) != sizeof(buf))    //读语音文件
              perror("write wrong number of bytes");
                     
              if (write(fd_dev_w, buf, sizeof(buf)) != sizeof(buf)) //送声卡播放
              perror("wrote2 wrong number of bytes");
      }
      close(fd_f);
      close(fd_dev_w);
      return 0;
  }
  else
  {
      printf("bye!\n");
      return 0;
  }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值