Linux下音频设备的操作
1 OSS
·
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; }
更多推荐
已为社区贡献4条内容
所有评论(0)