Linux Audio Stack & ALSA
来源:互联网 发布:淘宝客网址 编辑:程序博客网 时间:2024/06/06 12:56
目录(?)[-]
- Linux Audio Stack
- oss
- ALSA
- PulseAudio
- ALSA Project
- ALSA体系结构
- 环境搭建
- 测试
- ALSA混音
- ALSA编程
Linux Audio Stack
oss
- OSS借用了UNIX里”一切都是文件”的概念,。
把声卡模拟成一个/dev/dsp设备, 多块声卡就是dsp0, dsp1… - 要播放声音?打开dsp设备.往里面write数据就可以了.
- 设置比特率?用ioctl设置即可.
- 最简单的接口, 也是最没用的接口.因为应用程序完全没法对声音的播放进行控制.
- OSS是个阻塞的接口, write后, 要声音播放完毕才返回.
显然很糟糕, 因为在write和下一次write的微小时间间隔内, 声音出现了不连续.解决办法就是使用异步的write. write完了, 用ioctl轮询, 看还剩下多少数据.注意, 是轮询.轮询到还剩下不到1ms就播放玩了, 马上再write一个buffer过去.这就是OSS接口下的播放.
ALSA
- 当然OSS这个声音接口实在是太简单了, 于是他们搞了一个ALSA接口.ALSA先进了一些, 有了PLL接口.除了可以向声卡发送数据,
还可以为数据附带时钟信息.注意, 可以为数据附带时钟信息.意味着你可以不用精确的等待到一个时间再送出数据,
而是指定一块数据在指定的时间播放.还可以设定播放到某个byte的时候, 产生时钟信号通知程序, 好让程序能继续准备下一块buffer继续播放.然后asla又提供了一个高级的接口, libasound.so, libasound.so可以读取
/etc/asound.conf
、/usr/share/alsa/alsa.conf
、~/.asound.conf
配置文件, 还可以加载各种插件, 插件又可以通过配置文件配置.相当的高级.可以说, alsa是为专业的音频应用准备的.不论是OSS还是ALSA, 在民用声卡上都有一个致命的缺点:他们不支持混音.OSS和ALSA都只是声卡的接口.如果声卡本身不支持硬件混音,
那么程序就只能独占声卡.表现为只能有一个程序出声.好在alsa有一个补救措施, 那就是libasound.so.alsa不推荐直接使用alsa的内核接口编程,而是使用libasound.so的接口.如果使用了libasound.so的接口, 用户可以配置一个叫”dmix”的插件.然后把dmix模拟出来的声卡作为默认声卡.大家都输出到dmix, dmix再收集多个程序的声音, 一起混音然后输出给硬件.
这个问题看似解决了.实际上没有解决.受限于alsa的接口, dmix的实现质量相当的糟糕.首先, dmix为了混音, 强制重采样.重采样导致了音质的劣化.
其次, dmix没有C/S结构.通过共享内存协作完成混音和共享声卡, 一个程序的dmix出问题, 会导致所有正在发声的程序崩溃.ALSA的另一个缺点, 在使用了多个声卡后(蓝牙和HDMI普及了啊), 也开始暴露.那就是不能动态切换输出声卡.
我希望我带上蓝牙耳机后, 声音能从扬声器直接转移到耳机里播放.但是ALSA的先天缺陷导致无法实现这个功能.
播放器必须重新打开蓝牙声卡.也就是说, 把切换输出的责任全部交给播放器实现.播放器可以实现,
问题是所有的播放器都必须实现.另一个问题是, 用户必须到各个播放器下依次调节.非常麻烦.
PulseAudio
为了解决ALSA固有缺陷的目的, PulseAudio又出现了.
PulseAudio解决办法也是提供一个混音服务.混音服务后台执行, 独占声卡的访问权限.其他程序要播放声音的,
都需要将声音数据交给pulseaudio.由pulseaudio执行混音.那么, 重采样问题怎么解决呢?
pulseaudio提供了一个动态采样率模式.简单说明一下工作原理- A程序播放44100hz的声音, 提交给pulseaudio
- pulseaudio查询到声卡支持44100hz采样率播放, 直接输出
- A程序接着播放48000hz声音, 提交给pulseaudio
- pulseaudio查询到声卡是否支持48000hz采样率播放, 不支持则重采样到44100后输出.
如果声卡支持, 则直接输出.那么, 现在支持, 好, 设定声卡为48000模式, 然后直接输出. - A程序播放48000声音的同时, B程序开始播放44100的声音.
- pulseaudio将B程序的声音重采样到48000, 然后混音输出.
- A程序退出, B程序继续播放44100的声音
- pulseaudio将B程序的声音重采样到48000, 然后混音输出.
- B程序暂停或停止播放, 然后重新或继续播放44100的声音
- pulseaudio将设定声卡为44100模式, 然后直接输出.
- A程序又播放48000声音
- pulseaudio将A程序的声音重采样到44100, 然后混音输出.
- 用户切换到蓝牙耳机.只支持32000hz采样率.
- pulseaudio将A程序的48000hz重采样到32000hz, B的44100重采样到32000hz, 混音后输出给蓝牙耳机.
同样是系统混音, pulseaudio支持动态采样率调节.依据当前声卡支持的采样率和当前程序提交的数据,
动态修改内部混音的采样率.尽量减小不必要的重采样过程顺便提一下:google的Android不使用pulseaudio, 自己搞了个AudioFlinger,
不支持动态采样率, 还是会强制重采样到44100hz.
ALSA Project
ALSA 高级Linux音频架构
ALSA体系结构
- alsa-lib
- Control Interface (/dev/snd/controlCX)控制接口:提供管理声卡注册和请求可用设备的通用功能
- PCM Interface (/dev/snd/pcmCXDX) PCM接口:管理数字音频回放(playback)和录音(capture)的接口。它是开发数字音频程序最常用到的接口。
- Raw MIDI Interface (/dev/snd/midiCXDX) Raw MIDI接口:支持MIDI(Musical Instrument Digital Interface),标准的电子乐器。这些API提供对声卡上MIDI总线的访问。这个原始接口基于MIDI事件工作,由程序员负责管理协议以及时间处理。
- Timer Interface (/dev/snd/timer) 定时器(Timer)接口:为同步音频事件提供对声卡上时间处理硬件的访问。
- Sequencer Interface (/dev/snd/seq)时序器(Sequencer)接口
- Mixer Interface (/dev/snd/mixerCXDX) 混音器(Mixer)接口
- alsa-utils 一些常用有用的工具
- amixer:可以配置底层提供的alsa接口。
amixer contents
可以查看所有的控制接口和当前值amixer controls
可以列出所有的接口amixer cget (接口名)
可以获取指定接口值amixer cset (接口名)
可以设置指定接口值
- aplay/arecord 用于放音和录音的应用
- alsactl: 用于保存alsa配置
- alsamixer: alsamixer程序是amixer的ncurses的版本。
- aconnect, aseqnet 是进行MIDI连接和查看连接端口列表。
- amixer:可以配置底层提供的alsa接口。
- alsa-plugins
- alsa-tools
- …
环境搭建
kernel基于mozart linux-3.0.8 [speaker-master, commit id:8334430651460305e884496d9356b8b6f132ebaa]
板子使用 SP_M150_V2.0
- Sound card support
- [*] Advanced Linux Sound Architecture —>
- [*] ALSA for SoC audio support —>
- [*] ASoC support for Ingenic —>
- jz board type select —>
- soc 4775 codec type select (Audio support for wattle with internal codec) = Audio support for wattle with internal codec
- [*] Support DMIC for record
- [*] JZ audio dma clear auto dirty memor
- [*] JZ audio dma cyclic dma with hrtimer callback mode
- [] Open Sound System (DEPRECATED) —>
- [*] Advanced Linux Sound Architecture —>
测试
- 先使用amixer contents查看接口, 并用amixer cset 设置对应的值
- 使用aplay播放wav音频, 只支持wav格式
- 使用arecord 录音
ALSA混音
Alsa本身也提供混音的plugin,dmix.
应用程序不需要修改,添加配置dmix的/etc/asound.conf配置文件即可
效果是可以有多个应用同时放音
结构如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
ALSA编程
内核Alsa代码进行改动时会影响到应用程序的代码编写
ALSA放音
详细实例见:mozart_sdk/sources/application/molib_src/trunk/file-manager/player/mp3_utils.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
ALSA录音
详细实例见:mozart_sdk/sources/application/molib_src/trunk/utils/librecord/alsa/record.c
ALSA配置参数
有关调节音量,设置静音,详细实例见:/mozart_sdk/sources/application/molib_src/trunk/utils/volume/volume_alsa.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
参考
- ALSA project homepage
- ALSA project - the C library reference
- linux 3.0下混音播放解决方案 blog
- 系统混音的动态采样率 blog
- Linux声音系统 blog
- stackedit
- Linux Audio Stack & ALSA
- Linux Audio Stack & ALSA
- Linux Audio Stack & ALSA
- [Audio] Linux ALSA Mixer
- android audio/linux alsa音频-框架
- Audio codec linux driver 之 ALSA 架构的 DAPM 学习
- linux audio(alsa) 驱动注册的简明流程.
- linux audio(alsa) 驱动注册的简明流程.
- Audio codec linux driver 之 ALSA 架构的 DAPM 学习
- android audio/linux alsa音频-应用与驱动的接口
- Linux Audio ALSA Technical specification(Linux 音频ALSA技术说明)
- Alsa-Audio 二
- ALSA Audio API手册
- ALSA audio 术语
- Bluetooth stack, ALSA and Skype in Linux system
- Alsa SoC Audio(part 1)
- Alsa SoC Audio(part 2)
- ALSA Audio API 使用指南(中英版)
- URL中“#” “?” &“”号的作用
- android EditText 屏蔽长按弹出剪切 复制 全选菜单 的解决办法
- Hadoop学习笔记(4)
- webpack资源
- video的切换和相关操作
- Linux Audio Stack & ALSA
- Java中的静态块中的局部变量以及静态变量,以及静态变量声明与静态块的执行顺序
- 技术-CentOS中配置Java环境
- win10 mysql-5.6.35-winx64免安装版配置
- 安卓Android实现摄像头对焦的三种方法
- 【获奖公布】2017 CSDN博客专栏评选
- Html5的局:WebGL的纹理格式的转换
- oracle入门很简单:一、oracle数据库的安装
- JSP获得当前页面名称后判断是否显示页面元素的方法