好的,这是一个非常深入的问题。我们来详细分析 AudioFlinger 如何将应用设置的音量应用到活跃的音频流上。
- 整体音量应用流程
应用设置音量 → AudioManager → AudioService → AudioSystem → AudioFlinger
↓
AudioPolicyService (音量曲线管理) → AudioFlinger (混音处理)
↓
AudioFlinger::PlaybackThread → 应用音量 + 设备音量 + 主音量
↓
AudioMixer → 音量应用 → 输出到HAL
- 详细源码调用流程
步骤1: 应用层设置音量
// 应用调用
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
// frameworks/base/media/java/android/media/AudioManager.java
public void setStreamVolume(int streamType, int index, int flags) {
// 通过Binder调用AudioService
IAudioService service = getService();
service.setStreamVolume(streamType, index, flags, getContext().getOpPackageName());
}
步骤2: AudioService处理
// frameworks/base/services/core/java/com/android/server/audio/AudioService.java
public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
// 1. 权限检查和音量范围验证
ensureValidStreamType(streamType);
index = rescaleIndex(index, streamType);
// 2. 获取对应流的音量控制器
VolumeStreamState streamState = mStreamStates[streamType];
// 3. 设置设备索引
int device = getDeviceForStream(streamType);
streamState.setIndex(index, device, callingPackage);
// 4. 通知AudioSystem
mAudioSystem.setStreamVolumeIndex(streamType, index, device);
// 5. 发送音量更新广播
sendBroadcastToAll(new Intent(AudioManager.VOLUME_CHANGED_ACTION));
}
步骤3: AudioSystem到AudioFlinger
// frameworks/av/media/libaudioclient/AudioSystem.cpp
status_t AudioSystem::setStreamVolume(audio_stream_type_t stream, float value, audio_io_handle_t output) {
// 通过Binder调用AudioFlinger
const sp& af = AudioSystem::get_audio_flinger();
return af->setStreamVolume(stream, value, output);
}
步骤4: AudioFlinger接收音量设置
// frameworks/av/services/audioflinger/AudioFlinger.cpp
status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value, audio_io_handle_t output) {
// 1. 检查权限和参数有效性
if (!isStreamValid(stream)) return BAD_VALUE;
// 2. 查找对应的播放线程
sp<PlaybackThread> thread = getPlaybackThread_l(output);
if (thread == 0) return BAD_VALUE;
// 3. 在线程中设置流音量
return thread->setStreamVolume(stream, value);
}
- PlaybackThread中的音量管理
PlaybackThread音量设置
// frameworks/av/services/audioflinger/Threads.cpp
status_t AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value) {
Mutex::Autolock _l(mLock);
// 1. 存储流音量
mStreamTypes[stream].volume = value;
// 2. 立即应用到所有活跃的Track
for (size_t i = 0; i < mActiveTracks.size(); ++i) {
sp<Track> track = mActiveTracks[i];
if (track->streamType() == stream) {
// 重新计算Track的音量
track->setFinalVolume_l();
}
}
// 3. 广播音量变化
broadcast_l();
return NO_ERROR;
}
Track音量计算
// frameworks/av/services/audioflinger/Tracks.cpp
void AudioFlinger::PlaybackThread::Track::setFinalVolume_l() {
// 1. 获取流类型音量
float streamVolume = mThread->mStreamTypes[mStreamType].volume;
// 2. 获取主音量
float masterVolume = mThread->masterVolume();
// 3. 应用音频策略音量曲线
float volumeDb = AudioSystem::linearToLog(streamVolume * mVolume[0] * mVolume[1]);
// 4. 考虑静音状态
if (mThread->isStreamMuted(mStreamType)) {
volumeDb = AUDIO_MIN_VOLUME;
}
// 5. 设置最终音量
mFinalVolume = AudioSystem::logToLinear(volumeDb) * masterVolume;
ALOGV("setFinalVolume_l: stream=%d, streamVol=%.3f, master=%.3f, final=%.3f",
mStreamType, streamVolume, masterVolume, mFinalVolume);
}
- 混音时的音量应用
MixerThread处理
// frameworks/av/services/audioflinger/Threads.cpp - MixerThread
bool AudioFlinger::MixerThread::threadLoop() {
while (!exitPending()) {
// 1. 准备混音
processConfigEvents();
// 2. 准备活跃的Tracks
prepareTracks_l(&tracks, &outputBuffer);
// 3. 执行混音
mAudioMixer->process();
// 4. 输出到HAL
threadLoop_write();
}
return false;
}
AudioMixer中的音量处理
// frameworks/av/services/audioflinger/AudioMixer.cpp
void AudioMixer::process() {
for (size_t i = 0; i < mActiveTracks.size(); ++i) {
int name = mActiveTracks[i];
track_t* track = &mTracks[name];
// 应用音量到每个Track
if (track->needsVolume) {
// 设置音量参数
uint32_t vl = uint32_t(track->volume[0] * track->mFinalVolume * 0x1000);
uint32_t vr = uint32_t(track->volume[1] * track->mFinalVolume * 0x1000);
// 调用DSP处理函数应用音量
track->hook(track, outputBuffer, numFrames);
}
}
}
- 音量曲线和策略管理
AudioPolicyService参与
// frameworks/av/services/audiopolicy/AudioPolicyService.cpp
float AudioPolicyService::getStreamVolume(audio_stream_type_t stream,
audio_devices_t device,
audio_output_flags_t flags) {
// 1. 获取音量曲线
VolumeCurve curve = getVolumeCurve(stream, device);
// 2. 应用音量曲线转换
float volumeDb = curve.mapVolume(mStreams[stream].getVolumeIndex());
// 3. 考虑安全音量限制
volumeDb = applyAllVolumes(volumeDb, stream, device);
return volumeDb;
}
音量曲线映射
// frameworks/av/services/audiopolicy/engine/VolumeCurve.cpp
float VolumeCurve::mapVolume(int index) const {
// 将音量索引转换为dB值
if (index <= mIndexMin) {
return mDbMin;
} else if (index >= mIndexMax) {
return mDbMax;
}
// 线性或分段线性插值
float fraction = float(index - mIndexMin) / float(mIndexMax - mIndexMin);
return mDbMin + fraction * (mDbMax - mDbMin);
}
- 实时音量调整机制
淡入淡出处理
// frameworks/av/services/audioflinger/Tracks.cpp
void AudioFlinger::PlaybackThread::Track::setVolume(float left, float right) {
sp thread = mThread.promote();
if (thread != 0) {
Mutex::Autolock _l(thread->mLock);
// 设置目标音量
mVolume[0] = left;
mVolume[1] = right;
// 如果需要淡入淡出
if (mFramesCount == 0) {
// 立即设置
mFinalVolume = calculateFinalVolume();
} else {
// 启动淡入淡出
startVolumeRamp();
}
}
}
void AudioFlinger::PlaybackThread::Track::startVolumeRamp() {
// 计算淡入淡出步长
uint32_t sampleRate = mSampleRate;
uint32_t rampFrames = uint32_t((mRampDuration * sampleRate) / 1000);
if (rampFrames > 0) {
mVolumeInc[0] = (mVolume[0] - mPrevVolume[0]) / rampFrames;
mVolumeInc[1] = (mVolume[1] - mPrevVolume[1]) / rampFrames;
mRampFrames = rampFrames;
}
}
- 多设备音量管理
设备特定音量
// frameworks/av/services/audioflinger/AudioFlinger.cpp
status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream,
float value, audio_io_handle_t output,
audio_devices_t device) {
// 1. 查找对应设备和输出的线程
sp thread = checkPlaybackThread_l(output);
if (thread == 0) return BAD_VALUE;
// 2. 设置设备特定的音量
if (device == AUDIO_DEVICE_NONE) {
device = thread->outDevice();
}
// 3. 存储设备音量
mStreams[stream].setVolume(device, value);
// 4. 应用到活跃流
return thread->setStreamVolume(stream, value, device);
}
-
关键设计特点
-
分层音量控制
应用音量 → 流音量 → 设备音量 → 主音量 → 最终音量
- 实时性保证
• 音量变化立即生效
• 淡入淡出避免爆音
• 锁保护确保线程安全
- 策略灵活性
• 可配置的音量曲线
• 设备特定的音量设置
• 安全音量限制
- 性能优化
• 预计算最终音量
• 向量化音量处理
• 最小化锁竞争
这个流程展示了Android音频系统如何高效、灵活地管理应用音量,确保多应用、多设备的音频混合能够正确应用各自的音量设置。