前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux下音频设备的操作

Linux下音频设备的操作

作者头像
程序手艺人
发布2019-02-21 17:43:30
3.4K0
发布2019-02-21 17:43:30
举报
文章被收录于专栏:程序手艺人程序手艺人

在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中,主要有以下的几种设备文件:??

代码语言:javascript
复制
/********************************************************************************
**          音频设备的操作-->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音频设备的操作

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

?? 放音程序:

代码语言:javascript
复制
/********************************************************************************
**          音频设备的操作-->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;
}

?? 录音程序:

代码语言:javascript
复制
#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;
}
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2014年10月08日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com