void AudioFlinger::MixerThread::threadLoop_mix()
{
// obtain the presentation timestamp of the next output buffer
int64_t pts;
status_t status = INVALID_OPERATION;
//判断使用的输出端口,正常情况下使用mNormalSink进行输出
//该输出端口动态选择Monopip(FastMix)或者AudioStreamOutSink(Hal)
if (mNormalSink != 0) {
status = mNormalSink->getNextWriteTimestamp(&pts);
} else {
status = mOutputSink->getNextWriteTimestamp(&pts);
}
if (status != NO_ERROR) {
pts = AudioBufferProvider::kInvalidPTS;
}
// mix buffers...
//根据parameter来调用不同的处理函数
mAudioMixer->process(pts);
mCurrentWriteLength = mixBufferSize;
// increase sleep time progressively when application underrun condition clears.
// Only increase sleep time if the mixer is ready for two consecutive times to avoid
// that a steady state of alternating ready/not ready conditions keeps the sleep time
// such that we would underrun the audio HAL.
if ((sleepTime == 0) && (sleepTimeShift > 0)) {
sleepTimeShift--;
}
sleepTime = 0;
standbyTime = systemTime() + standbyDelay;
//TODO: delay standby when effects have a tail
}
void AudioMixer::process(int64_t pts){
mState.hook(&mState, pts);
}
status_t AudioStreamOutSink::getNextWriteTimestamp(int64_t *timestamp) {
ALOG_ASSERT(timestamp != NULL);
if (NULL == mStream)
return INVALID_OPERATION;
if (NULL == mStream->get_next_write_timestamp)
return INVALID_OPERATION;
return mStream->get_next_write_timestamp(mStream, timestamp);
}
// no-op case
void AudioMixer::process__nop(state_t* state, int64_t pts)
{
uint32_t e0 = state->enabledTracks;
size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
while (e0) {
// process by group of tracks with same output buffer to
// avoid multiple memset() on same buffer
uint32_t e1 = e0, e2 = e0;
int i = 31 - __builtin_clz(e1);
{
track_t& t1 = state->tracks[i];
e2 &= ~(1<<i);
while (e2) {
i = 31 - __builtin_clz(e2);
e2 &= ~(1<<i);
track_t& t2 = state->tracks[i];
if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
e1 &= ~(1<<i);
}
}
e0 &= ~(e1);
memset(t1.mainBuffer, 0, bufSize);
}
while (e1) {
i = 31 - __builtin_clz(e1);
e1 &= ~(1<<i);
{
track_t& t3 = state->tracks[i];
size_t outFrames = state->frameCount;
while (outFrames) {
t3.buffer.frameCount = outFrames;
int64_t outputPTS = calculateOutputPTS(
t3, pts, state->frameCount - outFrames);
t3.bufferProvider->getNextBuffer(&t3.buffer, outputPTS);
if (t3.buffer.raw == NULL) break;
outFrames -= t3.buffer.frameCount;
t3.bufferProvider->releaseBuffer(&t3.buffer);
}
}
}
}
}
void AudioMixer::process__validate(state_t* state, int64_t pts)
{
ALOGW_IF(!state->needsChanged,
"in process__validate() but nothing's invalid");
uint32_t changed = state->needsChanged;
state->needsChanged = 0; // clear the validation flag
// recompute which tracks are enabled / disabled
uint32_t enabled = 0;
uint32_t disabled = 0;
while (changed) {
const int i = 31 - __builtin_clz(changed);
const uint32_t mas
Audio笔记之MixerThread::threadLoop_mix
最新推荐文章于 2022-04-27 21:07:07 发布
本文详细介绍了Android AudioFlinger中的MixerThread如何进行音频混合处理,包括获取输出缓冲区的时间戳、根据条件调用不同处理函数以及混合音频缓冲区的过程。通过对AudioMixer的process方法和相关辅助方法的分析,揭示了Android系统内部音频处理的机制。
摘要由CSDN通过智能技术生成