Chinaunix首页 | 论坛 | 博客
  • 博客访问: 259183
  • 博文数量: 56
  • 博客积分: 1264
  • 博客等级: 中尉
  • 技术积分: 491
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-19 15:16
文章分类

全部博文(56)

文章存档

2012年(10)

2011年(46)

分类: LINUX

2011-08-07 17:35:08

2. 对声卡编程
  
只要我们不是进行诸如驱动设备开发之类的工作,对声卡的编程和上面对扬声器的编程没有什么本质的区别。当你试图来编 写诸如CD播放器、MP3播放器之类的复杂的程序时,你的工作是取获得与CDROM控制、MP3解码之类的信息,而读写系统设备的这一步在Linux下超 互想象的简单。例如,Linux下最简单的播放wav的程序只有一行:cp $< >/dev/audio。将它写成一个shell文件,同样是一个程序(shell 编程)。
  
我们首先需要知道一台机器上是否 有声卡,一个检查的办法是检查文件/dev/sndstat文件,如果打开此文件错误,并且错误号是ENODEV,则说明此机器没有安装声卡。除此之外, 试着去打开文件/dev/dsp也可以来检查是否安装了声卡。
  
Linux下和声卡相关的文件有许多,如采集数字样本的/dev /dsp文件,针对混音器的/dev/mixer文件以及用于音序器的/dev /sequencer等。文件/dev/audio是一个基于兼容性考虑的声音设备文件,它实际是到上述数字设备的一个映射,它最大的特色或许是对诸如 wav这类文件格式的直接支持。我们下面的例子即使用了此设备文件实现了一个简单的录音机:我们从声卡设备(当然要用麦克风)读取音频数据,并将它存放到 文件test.wav中去。要播放这个wav文件,只要如前面所述,使用命令cp test.wav >/dev/audio即可,当然你也可以用Linux下其他的多媒体软件来播放这个文件。
下面即是完整的程序清单:

/* 此文件中定义了下面所有形如SND_的变量*/
#include
#include
#include
#include
#include

main( )
{
/* id:读取音频文件描述符;fd:写入的文件描述符。i,j为临时变量*/
int id,fd,i,j;
/* 存储音频数据的缓冲区,可以调整*/
char testbuf[4096];
/* 打开声卡设备,失败则退出*/
if ( ( id = open ( "/dev/audio", O_RDWR ) ) < 0 ) {
fprintf (stderr, " Can?t open sound device!\n");
exit ( -1 ) ;
}
/* 打开输出文件,失败则退出*/
if ( ( fd = open ("test.wav",O_RDWR))<0){
fprintf ( stderr, " Can?t open output file!\n");
exit (-1 );
}
/* 设置适当的参数,使得声音设备工作正常*/
/* 详细情况请参考Linux关于声卡编程的文档*/
i=0;
ioctl (id,SNDCTL_DSP_RESET,(char *)&i) ;
ioctl (id,SNDCTL_DSP_SYNC,(char *)&i);
i=1;
ioctl (id,SNDCTL_DSP_NONBLOCK,(char *)&i);
i=8000;
ioctl (id,SNDCTL_DSP_SPEED,(char *)&i);
i=1;
ioctl (id,SNDCTL_DSP_CHANNELS,(char *)&i);
i=8;
ioctl (id,SNDCTL_DSP_SETFMT,(char *)&i);
i=3;
ioctl (id,SNDCTL_DSP_SETTRIGGER,(char *)&i);
i=3;
ioctl (id,SNDCTL_DSP_SETFRAGMENT,(char *)&i);
i=1;
ioctl (id,SNDCTL_DSP_PROFILE,(char *)&i);
/* 读取一定数量的音频数据,并将之写到输出文件中去*/
for ( j=0; j<10;){
i=read(id,testbuf,4096);
if(i>0){
write(fd,filebuf,i);
j++;
}
}
/* 关闭输入、输出文件*/
close(fd);
close(id);
}


#include
#include
#include
#include
#include

main()
{
  int id,fd,i,j;
  char testbuf[4096];

  id=open("/dev/audio",O_RDWR);
  fd=open("test.wav",O_RDWR);
  if(id<0||fd<0){
   printf("error in open the device!\n");
   printf("id %d\t dsp%d\t seq%d\n",id,dsp,seq);
   exit(-1);
  }

   post=0;

        ioctl(id,SNDCTL_DSP_RESET,(char *)&i);
        ioctl(id,SNDCTL_DSP_SYNC,(char *)&i);
        i=1;
        ioctl(id,SNDCTL_DSP_NONBLOCK,(char *)&i);
        i=8000;
        ioctl(id,SNDCTL_DSP_SPEED,(char *)&i);
        i=1;
        ioctl(id,SNDCTL_DSP_CHANNELS,(char *)&i);
        i=8;
        ioctl(id,SNDCTL_DSP_SETFMT,(char *)&i);
        i=3;
        ioctl(id,SNDCTL_DSP_SETTRIGGER,(char *)&i);
        i=3;
        ioctl(id,SNDCTL_DSP_SETFRAGMENT,(char *)&i);
        i=1;
        ioctl(id,SNDCTL_DSP_PROFILE,(char *)&i);
        for(j=0;j<10;){
                i=read(id,testbuf,4096);
                if(i>0){
                write(fd,filebuf,i);
                j++;
                }
        }
        close(fd);
        close(id);
}

  该程序只是简单地录一小段纯音频数据存储在test.wav中,用命令
cat test.wav >/dev/audio 就可以播放出来
一个不成功的案例:::::
lame_global_flags   *gf;
 
  int   lame_encoder(FILE*   OutFileID,   void     *WAVBuffer,   long   WAVBufferSize)
  {
          unsigned   char   mp3buffer[LAME_MAXMP3BUFFER];
          int           imp3;
          int           frames;
          if   (WAVBufferSize   <=   0)
  return   -1;
          void         *tmpBuf   =   malloc(WAVBufferSize);
          memcpy(tmpBuf,   WAVBuffer,   WAVBufferSize);
  //   encode   until   we   hit   eof  
          //   read   in   'iread'   samples  
          if   (gf   ==   NULL)
  return   -1;
          frames   =   lame_get_frameNum(gf);
 
  //   encode  
          imp3   =   lame_encode_buffer(gf,   WAVBuffer,   WAVBuffer,   WAVBufferSize,
                                                                              mp3buffer,   sizeof(mp3buffer));
          free(tmpBuf);
                  //   was   our   output   buffer   big   enough?  
                  if   (imp3   <   0)   {
                          if   (imp3   ==   -1)
                                  fprintf(stderr,   "mp3   buffer   is   not   big   enough...   \n");
                          else
                                  fprintf(stderr,   "mp3   internal   error:     error   code=%i\n",   imp3);
                          return   1;
                  }
 
                  if   (fwrite(   mp3buffer,   imp3,   1,   OutFileID)   !=   imp3){
                          fprintf(stderr,   "Error   writing   mp3   output   \n");
                          return   1;
                  }
 
 
 
 
          return   0;
  }
 
 
  int
  InitMP3Convert(void)
  {
       
          //   support   for   "nogap"   encoding   of   up   to   200   .wav   files//
  #define   MAX_NOGAP   200
 
          if   (NULL   ==   (gf   =   lame_init()))   {
                  fprintf(stderr,   "fatal   error   during   initialization\n");
                  return   1;
          }
       
          lame_set_num_channels(gf,2);
          lame_set_in_samplerate(gf,44100);
          lame_set_brate(gf,128);
          lame_set_mode(gf,1);
          lame_set_quality(gf,2);
  lame_init_params(   gf);  
 
        return   0;
  }
 
  void   FinishConvert(FILE   *fid)
  {
  lame_mp3_tags_fid(gf,fid);
  }      
  void   DeinitMP3Convert()
  {
          lame_close(gf);
  }
 
  数据是从WAV文件获得或是从麦克风获得的。但是在压缩成mp3以后,除了很多杂音,其余什么都没有
阅读(1808) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~