Android Audio - 音频子系统框架简析
关键的类对象
AudioSystem
AudioFlinger
AudioPolicy
AudioStreamIn
AudioResampler
Threads
RecordThread
MixerThread
PlaybackThread
TrackBase
RecordTrack
Track (playback track)
TimedTrack
OutputTrack
mRecord = new AudioRecord() 时
set
openRecord
AudioSystem::getInput
// 只有 openInput 才回去创建新的 RecordThread.
// 这里做了处理, 当本次录音的 Profile 文件与已经打开的
// mInput Profile 一样的话, 表示希望打开同一设备. 仅返回 audio_io_handle_t 即可.
mpClientInterface->openInput
AudioFlinger::openInput
// 创建一个新的 audio_io_handle_t 号码.
audio_io_handle_t id = nextUniqueId();
// 建立与 so 库的连接, 注意: 此时还没有 open 底层驱动.
inHwHal->open_input_stream(inHwHal, id, *pDevices, &config, &inStream);
ladev->hwif->openInputStream
// 创建 speex_resampler_init 重采样器.
new AudioHardware::DownSampler
// 创建一个 RecordThread 录音线程
thread = new RecordThread();
// 将 audio_io_handle_t 绑定 RecordThread.
mRecordThreads.add(id, thread);
record = audioFlinger->openRecord
// 从 mRecordThreads 里面根据 input(id) 获取一个 RecordThread.
thread = checkRecordThread_l(input);
// 创建一个 RecordTrack.
recordTrack = thread->createRecordTrack_l();
new RecordTrack()
// 将 recordTrack 绑定 RecordHandle
recordHandle = new RecordHandle(recordTrack);
return recordHandle;
mAudioRecord = record;
mRecord.start() 时
start
mAudioRecord->start(event, triggerSession);
RecordHandle->start()
RecordThread::start(recordTrack)
// 在此处加入 mActiveTracks 数组
mActiveTracks.add(recordTrack);
// 置位 recordTrack != TrackBase::IDLE 状态.
recordTrack->mState = TrackBase::STARTING_2;
// 释放 RecordThread::threadLoop() 的锁.
mWaitWorkCV.broadcast();
mRecord.read() 时
待填充
mRecord.stop() 时
// 停止只是将 recordTrack = TrackBase::PAUSING 的状态
// 不在 memcpy 底层获得到的 buffer 而已.
stop
mRecordTrack->stop();
AudioSystem::stopInput(recordThread->id());
mRecord 对象被释放时
// 当 RecordHandle 析构时, 也就是持有它的 AudioRecord 对象析构时才调用.
~RecordHandle
RecordTrack::destroy
AudioSystem::releaseInput
mpClientInterface->closeInput
AudioFlinger::closeInput
thread = checkRecordThread_l(input);
mRecordThreads.removeItem(input);
in->hwDev()->close_input_stream(in->hwDev(), in->stream);
recordThread->destroyTrack_l
// 仅仅是指移除了在 mTracks 里面的 recordTrack. 没有移除 mActiveTracks 里面的 recordTrack.
mTracks.remove(track);
待整理流程
// 从 APP 录音角度分析
AudioRecord.java
create/set(设备(BT, DEFUALT), 通道数, 采样速率, 数据深度)
start
AudioRecord.cpp
1. set: new AudioRecordThread 读 RecordTrack.
2. openRecord_l:
// 用于标志从哪个声卡c / p设备获取.
audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat,
AudioPolicy->openInput -> 调用到了 AudioFlinger -> openInput()
audioFlinger->openRecord
thread->createRecordTrack_l
3. start
RecordHandle->start
mRecordTrack->start
recordThread->start
AudioFlinger //
openInput()
AudioStreamIn *input = stream_in.
new RecordThread
Threads // 线程
RecordThreads // 录音线程(单例), 在第一次被 sp -> run() -> 由于录音状态是 PAUSING. 休眠.
createRecordTrack_l
RecordTrack. app 读 buffer. 采集.
start
AudioSystem::startInput(mId);
mpClientInterface->setParameters(input, param.toString());
mActiveTrack->RESUMING
if (mActiveTrack == RESUMING)
threadLoop往下走了.
1. 读一次.
2. mInput->stream->read(mInput->stream, readInto, mBufferSize);
AudioPolicy //向下管理so库. 向上提供 Read / Write / set 接口.
AudioHAL // ALSA PCM_XXX 操作声卡
set
read
open_l -> pcm_open().
pcm_read()
Dev // 驱动
// 从系统启动角度
libmeida.so
init.rc media
AudioFlinger 首先启动.
1. 初始化 so 库列表.
mAudioHwDevs = dopen(xxx.so).
AudioPolicy
getProfile 解析 audio_policy.xml
mAudioHwDevs
与之相关
Android Audio - 支持多应用同时录音_Android4.4修改方法
Android Audio - 支持多应用同时录音_Android5.1 & Android6.0 修改方法
Android Audio - 支持多应用同时录音_Android8.1修改方法