没有合适的资源?快使用搜索试试~ 我知道了~
首页Android audio知识总结.pdf
资源详情
资源评论
资源推荐

音视频学习
Android音频框架
l AudioTrack:负责回放数据的输出,属Android 应用框架 API 类
l AudioRecord:负责录音数据的采集,属Android 应用框架 API 类
l AudioSystem: 负责音频事务的综合管理,属 Android 应用框架 API 类
l AudioPolicyService:音频策略的制定者,负责音频设备切换的策略抉择、音量调节策略等(决定
选择哪个设备输出,接上耳机用耳机,接上蓝牙设备用蓝牙;是策略的制定者,比如什么时候打开音
频接口设备、某种Stream类型的音频对应什么设备等等。)
l AudioFlinger:音频策略的执行者,负责输入输出流设备的管理及音频流数据的处理传输(具体如

何与音频设备通信,如何维护现有系统中的音频设备,以及多个音频流的混音如何处理等等)
| Audio HAL:音频硬件抽象层,负责与音频硬件设备的交互,由 AudioFlinger 直接调用。
MultiMedia 负责音视频的编解码,
MultiMedia
将
解
码
后
的
数据
通过
AudioTrack
输
出
,
而
AudioRecord
采集
的
录
音
数据
交
由
MultiMedia
进
行
编码
。
AudioTrack(仅仅能播放PCM音频流)
**AudioTrack是管理和播放单一音频资源的类。AudioTrack仅仅能播放已经解码的PCM流,用于
PCM音频流的回放。
**
1、MediaPlayer、AudioTrack的区别:
都可以播放声音,MediaPlayer可以播放多种格式的音源,如 mp3、flac、wma、ogg、wav 等,
而 AudioTrack 只能播放解码后的 PCM 数据流(由MultiMedia进行解码)。
MediaPlayer实现原理:MediaPlayer 在 Native 层会创建对应的音频解码器和一个 AudioTrack,解
码后的数据交由 AudioTrack 输出
总结:MediaPlayer 的应用场景更广,一般情况下使用它也更方便;只有一些对声音时延要求非
常苛刻的应用场景才需要用到 AudioTrack。
AudioTrack两种传输模式
AudioTrack音频流的类型
调节一个类型的音频流音量,不会影响到其他类型的音频流
根据流类型选择合适的输出设备(AudioPolicyService负责决策输出到哪个设备,
AudioFlinger来处理具体的输出事宜);比如插着有线耳机期间,音乐声(STREAM_MUSIC)
只会输出到有线耳机,而铃声(STREAM_RING)会同时输出到有线耳机和外放
STREAM参数对AudioTrack来说,它的含义就是告诉系统,我现在想使用的是哪种类型的声
音,这样系统就可以对应管理他们了
AudioTrack Native相关
AudioTrack Native API四种数据传输模式
AudioTrack Native API音频流类型

AudioTrack Native API 输出标识
AudioTrack实现PCM音频播放
AudioTrack实现PCM音频播放五步走
Ø 配置基本参数
Ø 获取最小缓冲区大小
Ø 创建AudioTrack对象
Ø 获取PCM文件,转成DataInputStream
Ø 开启/停止播放
配置基本参数
1、StreamType音频流类型
AudioManager.STREAM_MUSIC:用于音乐播放的音频流。
AudioManager.STREAM_SYSTEM:用于系统声音的音频流。
AudioManager.STREAM_RING:用于电话铃声的音频流。
AudioManager.STREAM_VOICE_CALL:用于电话通话的音频流。
AudioManager.STREAM_ALARM:用于警报的音频流。
AudioManager.STREAM_NOTIFICATION:用于通知的音频流。
AudioManager.STREAM_BLUETOOTH_SCO:用于连接到蓝牙电话时的手机音频流。
AudioManager.STREAM_SYSTEM_ENFORCED:在某些国家实施的系统声音的音频流。
AudioManager.STREAM_DTMF:DTMF音调的音频流。
AudioManager.STREAM_TTS:文本到语音转换(TTS)的音频流。
2、MODE模式(static和stream两种)
· AudioTrack.MODE_STREAM
Ø STREAM的意思是由用户在应用程序通过write方式把数据一次一次得写到AudioTrack
中。这个和我们在socket中发送数据一样,应用层从某个地方获取数据,例如通过编解
码得到PCM数据,然后write到AudioTrack。这种方式的坏处就是总是在JAVA层和Native
层交互,效率损失较大。
· AudioTrack.MODE_STATIC
Ø STATIC就是数据一次性交付给接收方。好处是简单高效,只需要进行一次操作就完成
了数据的传递;缺点当然也很明显,对于数据量较大的音频回放,显然它是无法胜任
的,因而通常只用于播放铃声、系统提醒等对内存小的操作
3、采样率:mSampleRateInHz
采样率 (MediaRecoder的采样率通常是8000Hz AAC的通常是44100Hz。设置采样率为

44100,目前为常用的采样率,官方文档表示这个值可以兼容所有的设置)
4、通道数目:mChannelConfig
首先得出声道数,目前最多只支持双声道。
5、音频量化位数:mAudioFormat(只支持8Bit和16bit两种。)
获取最小缓冲区大小
`frameworks/base/core/jni/android_media_AudioTrack.cpp
static jint android_media_AudioTrack_get_min_buff_size(JNIEnv*env, jobject thiz,
jint sampleRateInHertz,jint nbChannels, jint audioFormat) {
int frameCount = 0;
if(AudioTrack::**getMinFrameCount**(&frameCount,
AUDIO_STREAM_DEFAULT,sampleRateInHertz) != NO_ERROR) {
return -1;
}
return frameCount * nbChannels * (audioFormat ==javaAudioTrackFields.PCM16 ? 2 : 1);
}`
**
getMinFrameCount,这个函数用于确定至少需要多少Frame才能保证音频正常播放。
android_media_AudioTrack_get_min_buff_size中最后采用的计算公式就是:
至少需要多少帧
每
帧
数据
量
= frameCount * nbChannels * (audioFormat
==javaAudioTrackFields.PCM16 ? 2 : 1);
公
式
中
frameCount
就
是
需
要
的
帧
数
,
每
一
帧
的
数据
量
又
等
于
:
Channel
数
每个Channel数据量= nbChannels* (audioFormat ==javaAudioTrackFields.PCM16
? 2 : 1)层层返回getMinBufferSize就得到了保障AudioTrack正常工作的最小缓冲区大小
了。
创建AudioTrack对象

调用AudioTrack构造方法时,调用它的重载方法
`public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int
audioFormat,
int bufferSizeInBytes, int mode)throws IllegalArgumentException {
this(streamType, sampleRateInHz, channelConfig, audioFormat,
bufferSizeInBytes, mode, AudioManager.AUDIO_SESSION_ID_GENERATE);}`
重载方法中主要调用了native_setup()方法,native_setup来创建一个本地AudioTrack对
象,创建一个Storage对象,从这个Storage猜测这可能是存储音频数据的地方
我们只保留两种内存模式(STATIC和STREAM)有差异的地方,入参中的倒数第三个是
lpJniStorage->mMemBase,而STREAM类型时为null(0)。
获取PCM文件,转成DataInputStream
开始/停止播放
剩余33页未读,继续阅读















安全验证
文档复制为VIP权益,开通VIP直接复制

评论0