Linux下音频设备的操作

 
    在Linux中,先后出现了音频设备的两种框架OSS和ALSA

1 OSS(Open Sound System)是unix平台上一个统一的音频接口。

一、基础知识
     数字音频设备(有时也称codec,PCM,DSP,ADC/DAC设备):播放或录制数字化的声音。它的指标主要有:采样速率(电话为8K,DVD为96K)、channel数目(单声道,立体声)、采样分辨率(8-bit,16-bit)。
mixer(混频器):用来控制多个输入、输出的音量,也控制输入(microphone,line-in,CD)之间的切换。
synthesizer(合成器):通过一些预先定义好的波形来合成声音,有时用在游戏中声音效果的产生。
MIDI 接口:MIDI接口是为了连接舞台上的synthesizer、键盘、道具、灯光控制器的一种串行接口。
在Unix系统中,所有的设备都被统一成文件,通过对文件的访问方式(首先open,然后read/write,同时可以使用ioctl读取/设置参数,最后close)来访问设备。在OSS中,主要有以下的几种设备文件:  

 
/********************************************************************************
**          音频设备的操作-->OSS
**
**----------FIleInof------------------------------------------------------------
** 文件信息:
** 创建日期:2014-10-8
** 修改日期:
** 文件信息:有bug
********************************************************************************/
#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#include
       
       
         #include 
        
          #include 
         
           #include 
          
            #include 
           
             int main(int argc,char **argv) { int rate = 88200; //立体声 int bit = 16; if(argc < 2){ printf("input : ./app music\n"); exit(1); } int fd = open("/dev/dsp",O_RDWR); if(fd < 0){ perror("open error\n"); exit(1); } int io_1 = ioctl(fd,SOUND_PCM_WRITE_BITS,&bit); if(io_1 < 0){ perror("ioctl_1 error!\n"); exit(1); } int io_2 = ioctl(fd,SOUND_PCM_WRITE_RATE,&rate); if(io_2 < 0){ perror("ioctl_2 error!\n"); exit(1); } /*打开音乐文件*/ int fp = open(argv[1],O_RDWR); if(fp < 0){ perror("open fp error!\n"); exit(1); } /*求文件的大小*/ struct stat music_buf; int ft = fstat(fd,&music_buf); if(ft < 0){ perror("fstat error!\n"); exit(1); } int len = music_buf.st_size; char *buf = (char *)malloc(sizeof(char)*len); memset(buf,0,len); /*读文件到buf中*/ int rd = read(fp,buf,len); if(rd < 0){ perror("read error!\n"); exit(1); } int wr = write(fd,buf,len); if(wr < 0){ perror("write error!\n"); exit(1); } free(buf); buf = NULL; close(fd); close(fp); return 0; } 
            
           
          
         
       
      
      
     
     
    
    
   
   

2 alsa音频设备的操作

    编程的一般步骤:设置参数到设备中--->音源处理--->写入设备

   放音程序:

   
/********************************************************************************
**          音频设备的操作-->alsa
**
**----------FIleInof------------------------------------------------------------
** 文件信息:
** 创建日期:2014-10-8
** 修改日期:
** 文件信息:放音的操作
********************************************************************************/
#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#include
       
       
         #include 
        
          #include 
         
           #include 
          
            #include 
           
             int main(int argc,char **argv) { if(argc < 2){ printf("input :./app music"); exit(1); } snd_pcm_hw_params_t *myparams; snd_pcm_t *mydevice; snd_pcm_uframes_t frame = 200; int fd = snd_pcm_open(&mydevice,"default",0,0); if(fd < 0){ perror("open error!\n"); exit(1); } /*分配空间*/ snd_pcm_hw_params_malloc(&myparams); /*初始化*/ int init = snd_pcm_hw_params_any(mydevice,myparams); if(init < 0){ perror("any error!\n"); exit(1); } //设置位宽 snd_pcm_hw_params_set_format(mydevice,myparams,SND_PCM_FORMAT_S16_LE); //设置声道 snd_pcm_hw_params_set_channels(mydevice, myparams, 2); //2代表立体声 //设置采样率 int rate = 44100; int dir; snd_pcm_hw_params_set_rate_near(mydevice,myparams,&rate,&dir); //设置交互模式 snd_pcm_hw_params_set_access(mydevice,myparams,SND_PCM_ACCESS_MMAP_INTERLEAVED); //设置采样周期 snd_pcm_hw_params_set_period_size_near(mydevice,myparams,&frame, &dir); snd_pcm_hw_params_get_period_size(myparams,&frame, &dir); //设置参数 snd_pcm_hw_params(mydevice,myparams); int fp = open(argv[1],O_RDWR); if(fp < 0){ perror("open error!\n"); exit(1); } int len = lseek(fp,0,SEEK_END); if(len < 0){ perror("lseek error!\n"); exit(1); } lseek(fp,0,SEEK_SET); char *music = (char *)malloc(sizeof(char) *len); /*读取数据*/ int rd = read(fp,music,len); if(rd < 0){ perror("read error!\n"); exit(1); } /*写入设备*/ snd_pcm_writei(mydevice,music,len); snd_pcm_hw_params_free(myparams); free(music); music = NULL; snd_pcm_close(mydevice); close(fd); return 0; } 
            
           
          
         
       
      
      
     
     
    
    
   
   

   录音程序:
  
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
        
        
#include 
        
        
          #include 
         
           #include 
          
            #include 
           
             int main(int argc,char**argv) { if(argc < 2){ printf("please input :./app music\n"); exit(1); } snd_pcm_hw_params_t *myparams; snd_pcm_t *mydevice; snd_pcm_uframes_t frame = 200; int fd = snd_pcm_open(&mydevice,"default",1,0); if(fd < 0){ perror("open \n"); exit(1); } snd_pcm_hw_params_malloc(&myparams); int init = snd_pcm_hw_params_any(mydevice, myparams); if(init < 0){ perror("init\n"); exit(1); } //设置位宽 snd_pcm_hw_params_set_format(mydevice, myparams, SND_PCM_FORMAT_S16); //设置声道 snd_pcm_hw_params_set_channels(mydevice, myparams,2); //设置采样率 int rate = 44100; int dir ; snd_pcm_hw_params_set_rate_near(mydevice, myparams, &rate, &dir); //设置交互模式 snd_pcm_hw_params_set_access(mydevice, myparams, SND_PCM_ACCESS_MMAP_INTERLEAVED); //获取周期 snd_pcm_hw_params_set_period_size_near(mydevice, myparams, &frame, &dir); snd_pcm_hw_params_get_period_size(myparams, &frame, &dir); //设置参数 snd_pcm_hw_params(mydevice, myparams); int fp = open(argv[1],O_RDWR); if(fp < 0){ perror("open music\n"); exit(1); } int len = 10*44100*2*16/8; char *music = (char *)malloc(sizeof(char )*len); int l = 0; int i = 0; while(l < len){ snd_pcm_readi(mydevice, music + i*4*frame, frame); l = i*4*frame + 4*frame; i++; } int rd = write(fp,music,len); if(rd < 0){ perror("read\n"); exit(1); } snd_pcm_hw_params_free(myparams); free(music); close(fp); snd_pcm_close(mydevice); return 0; } 
            
           
          
        
       
       
      
      
     
     
    
    





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序手艺人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值