Linux下OSS音频录制和播放
2015-05-20 15:38
197 查看
OSS(Open Sound System,开放声音系统),是unix或类unix环境中的音频接口,是一种音频驱动结构。
OSS标准中包括两个基本的音频设备:mixer(混音器)和dsp(数字信号处理器)。
混音器对应的应用程序操作接口/dev/mixer。
dsp对应的应用程序操作接口/dev/dsp或/dev/audio
虽然多数硬件都能够支持此音频驱动,但OSS十多年没有更新和大的修动,Linux系统中又出现一种新的音频架构(ALSA Advanced Linux Sound Architecture)。
===================================================
数据音频基础知识
数字音频设备:播放或录制数字化的声音,它的指标主要有:
采样速率 :每秒钟的采样点个数。有8KHz,44.8KHz,48KHz等等。采样频率越高,描述的声波频率就越高。
采样分辨率:即量化精度,对模拟信号转数字信号量化值。有8bit和16bit,一般使用16bit小端模式。精度超高,声音数字化越逼真。
channel数 :分为单通道1和立体声2。
mixer(混频器):用来控制多个输入、输出的音量,也控制输入(microphone,line-in,CD)之间的切换。
synthesizer(合成器):通过一些预先定义好的波形来合成声音,有时用在游戏中声音效果的产生。
MIDI 接口:MIDI接口是为了连接舞台上的synthesizer、键盘、道具、灯光控制器的一种串行接口。
原始(未编码)音频数据的大小计算:
公式:采样频率*采样分辨率*通道数 / 8 = 每秒音频数据
常用的音频压缩编码有G711,G729, MEPG-layer3。
常用的音频封装格式有MP3、WMA、MP4等等。
========================================
如果通过编程的方式来使用这些设备,那么unix平台通过文件系统提供了统一的访问接口。
程序员可以通过文件的操作函数直接控制这些设备,这些操作函数包括:open、close、read、write、ioctl等。
下面我们就分别讨论打开音频设备、放音、录音和参数调整。
音频编程的流程:
1.打开音频设备 (对于有些设备 存放于/dev/sound/下)
open_mode有三种选择:O_RDONLY,O_WRONLY和O_RDWR,分别表示只读、只写和读写。
OSS建议尽量使用只读或只写,只有在全双工的情况下(即录音和放音同时)才使用读写模式。
2.设定音频参数
采样取值及请求宏(request):
采样频率:请求宏:SNDCTL_DSP_SPEED 值:48000
量化位数:请求宏:SNDCTL_DSP_SETFMT 值:AFMT_S16_LE
通道数 : 请求宏:SNDCTL_DSP_CHANNELS 值:单通道1,立体声2
3.采集音频数据or 播放音频数据
采集数据并存放到文件当中
读取文件并播放数据
4.关闭音频设备
======================源码(录音5秒播放5秒)===========================
============================播放一个WAV格式的音频文件===========================
OSS标准中包括两个基本的音频设备:mixer(混音器)和dsp(数字信号处理器)。
混音器对应的应用程序操作接口/dev/mixer。
dsp对应的应用程序操作接口/dev/dsp或/dev/audio
虽然多数硬件都能够支持此音频驱动,但OSS十多年没有更新和大的修动,Linux系统中又出现一种新的音频架构(ALSA Advanced Linux Sound Architecture)。
===================================================
数据音频基础知识
数字音频设备:播放或录制数字化的声音,它的指标主要有:
采样速率 :每秒钟的采样点个数。有8KHz,44.8KHz,48KHz等等。采样频率越高,描述的声波频率就越高。
采样分辨率:即量化精度,对模拟信号转数字信号量化值。有8bit和16bit,一般使用16bit小端模式。精度超高,声音数字化越逼真。
channel数 :分为单通道1和立体声2。
mixer(混频器):用来控制多个输入、输出的音量,也控制输入(microphone,line-in,CD)之间的切换。
synthesizer(合成器):通过一些预先定义好的波形来合成声音,有时用在游戏中声音效果的产生。
MIDI 接口:MIDI接口是为了连接舞台上的synthesizer、键盘、道具、灯光控制器的一种串行接口。
原始(未编码)音频数据的大小计算:
公式:采样频率*采样分辨率*通道数 / 8 = 每秒音频数据
常用的音频压缩编码有G711,G729, MEPG-layer3。
常用的音频封装格式有MP3、WMA、MP4等等。
========================================
如果通过编程的方式来使用这些设备,那么unix平台通过文件系统提供了统一的访问接口。
程序员可以通过文件的操作函数直接控制这些设备,这些操作函数包括:open、close、read、write、ioctl等。
下面我们就分别讨论打开音频设备、放音、录音和参数调整。
音频编程的流程:
1.打开音频设备 (对于有些设备 存放于/dev/sound/下)
open_mode有三种选择:O_RDONLY,O_WRONLY和O_RDWR,分别表示只读、只写和读写。
OSS建议尽量使用只读或只写,只有在全双工的情况下(即录音和放音同时)才使用读写模式。
if ((audio_fd = open(AUDIO_DEV, O_RDONLY, 0)) == -1) { perror(AUDIO_DEV); <span style="white-space:pre"> </span>exit(1); }
2.设定音频参数
采样取值及请求宏(request):
采样频率:请求宏:SNDCTL_DSP_SPEED 值:48000
量化位数:请求宏:SNDCTL_DSP_SETFMT 值:AFMT_S16_LE
通道数 : 请求宏:SNDCTL_DSP_CHANNELS 值:单通道1,立体声2
void set_param(int fd) { int param; printf("set params!\n"); //---------------------------------- param = 48000; ioctl(fd,SNDCTL_DSP_SPEED,¶m); param = AFMT_S16_LE; ioctl(fd,SNDCTL_DSP_SETFMT,¶m); param = 2; ioctl(fd,SNDCTL_DSP_CHANNELS,¶m); }
3.采集音频数据or 播放音频数据
采集数据并存放到文件当中
if ((len = read(audio_fd,audio_buffer,AUDIO_BUF)) == -1) { perror("audio read"); exit(1); }
int filefd = open("a.wav",O_CREAT|O_WRONLY|O_APPEND|O_TRUNC,0666); len=0; if ((len = write(filefd,audio_buffer,AUDIO_BUF)) == -1) { perror("audio store"); exit(1); } close(filefd);
读取文件并播放数据
int filefd = open("a.wav",O_RDONLY); if ((len = read(filefd,audio_buffer,AUDIO_BUF)) == -1) { perror("audio read"); exit(1); } close(filefd); if ((audio_fd = open(AUDIO_DEV, O_WRONLY, 0)) == -1) { perror(AUDIO_DEV); exit(1); } set_param(audio_fd); len=0; if ((len = write(audio_fd,audio_buffer,AUDIO_BUF)) == -1) { perror("audio write"); exit(1); } printf("play ended!\n"); close(audio_fd);
4.关闭音频设备
======================源码(录音5秒播放5秒)===========================
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/ioctl.h>
#include<fcntl.h>
#include<linux/soundcard.h>
#define AUDIO_DEV "/dev/dsp"
#define AUDIO_BUF 48000*2*2*5//sampling,16bit,2channels ,2second
char audio_buffer[AUDIO_BUF];
void set_param(int fd) { int param; printf("set params!\n"); //---------------------------------- param = 48000; ioctl(fd,SNDCTL_DSP_SPEED,¶m); param = AFMT_S16_LE; ioctl(fd,SNDCTL_DSP_SETFMT,¶m); param = 2; ioctl(fd,SNDCTL_DSP_CHANNELS,¶m); }
void record()
{
int len=0;
int audio_fd;
if ((audio_fd = open(AUDIO_DEV, O_RDONLY, 0)) == -1)
{
perror(AUDIO_DEV);
exit(1);
}
set_param(audio_fd);
//creat a tmp file to store datas
usleep(500000);
printf("begin to record...\n");
if ((len = read(audio_fd,audio_buffer,AUDIO_BUF)) == -1) { perror("audio read"); exit(1); }
close(audio_fd);
int filefd = open("a.wav",O_CREAT|O_WRONLY|O_APPEND|O_TRUNC,0666); len=0; if ((len = write(filefd,audio_buffer,AUDIO_BUF)) == -1) { perror("audio store"); exit(1); } close(filefd);
printf("record ended!\n");
}
void play()
{
int len=0;
int audio_fd;
printf("voice play...\n");
int filefd = open("a.wav",O_RDONLY); if ((len = read(filefd,audio_buffer,AUDIO_BUF)) == -1) { perror("audio read"); exit(1); } close(filefd); if ((audio_fd = open(AUDIO_DEV, O_WRONLY, 0)) == -1) { perror(AUDIO_DEV); exit(1); } set_param(audio_fd); len=0; if ((len = write(audio_fd,audio_buffer,AUDIO_BUF)) == -1) { perror("audio write"); exit(1); } printf("play ended!\n"); close(audio_fd);
}
int main()
{
//open_mode :O_RDONLY,O_WRONLY,O_RDWR
printf("open %s!\n",AUDIO_DEV);
record();
//--------------------------------------
sleep(1);
play();
return 0;
}
============================播放一个WAV格式的音频文件===========================
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/ioctl.h>
#include<fcntl.h>
#include<linux/soundcard.h>
#define AUDIO_DEV "/dev/dsp"
#define AUDIO_BUF 48000*2*2*2//sampling,16bit,2channels ,2second
char audio_buffer[AUDIO_BUF];
void set_param(int fd) { int param; printf("set params!\n"); //---------------------------------- param = 48000; ioctl(fd,SNDCTL_DSP_SPEED,¶m); param = AFMT_S16_LE; ioctl(fd,SNDCTL_DSP_SETFMT,¶m); param = 2; ioctl(fd,SNDCTL_DSP_CHANNELS,¶m); }
void play(char *file)
{
int len=0;
int audio_fd;
printf("voice play...\n");
if ((audio_fd = open(AUDIO_DEV, O_WRONLY, 0)) == -1)
{
perror(AUDIO_DEV);
exit(1);
}
set_param(audio_fd);
int filefd = open(file,O_RDONLY);
if(filefd<0)
{
perror("open snd file ");
}
while((len = read(filefd,audio_buffer,AUDIO_BUF))>0)
{
//len=0;
if ((len = write(audio_fd,audio_buffer,AUDIO_BUF)) == -1)
{
perror("audio write");
exit(1);
}
}
printf("play ended!\n");
close(filefd);
close(audio_fd);
}
int main(int argc,char *argv[])
{
//open_mode :O_RDONLY,O_WRONLY,O_RDWR
printf("open %s!\n",AUDIO_DEV);
play(argv[1]);
return 0;
}
相关文章推荐
- linux 下音频的录制与播放测试例子
- 使用Audio Queue Services 播放和录制音频
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- HTML5+规范:audio(音频的录制和播放功能)
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- C++切换windows默认音频设备 (播放或录制)
- 音频的录制方式-AudioRecord,MediaRecorder的使用及播放
- Linux音频编程--使用ALSA库播放wav文件
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- 使用Audio Queue Services 播放和录制音频
- 使用AudioRecoder录制,AudioTrack播放PCM音频数据
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- Tlog:录制/播放终端 IO 和会话的工具 | Linux 中国
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- Android播放器MediaPlayer与MediaRecorder:录制音频并播放
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- ALSA音频录制与播放
- iOS audio queue 播放和录制音频
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- 整理下OSS方面的资料,免得到处找,linux音频编程,open sound system .