AudioFlinger分析(5)

2020-02-20 14:13

standbyTime = systemTime() + kStandbyTimeInNsecs; }

有数据要写到硬件中,肯定不能sleep了呀 if (sleepTime == 0) {

//把缓存的数据写到outPut中。这个mOutput是AudioStreamOut //由Audio HAL的那个对象创建得到。等我们以后分析再说

int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize); mStandby = false; } else {

usleep(sleepTime);//如果没有数据,那就休息吧.. } 3. MixerThread核心

到这里,大家是不是有种焕然一新的感觉?恩,对了,AF的工作就是如此的精密,每个部分都配合得丝丝入扣。不过对于我们看代码的人来说,实在搞不懂这么做的好处----哈哈 有点扯远了。

MixerThread的线程循环中,最重要的两个函数: prepare_l和mAudioMixer->process,我们一一来看看。

uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp >& activeTracks, Vector< sp > *tracksToRemove) {

uint32_t mixerStatus = MIXER_IDLE;

//得到活跃track个数,这里假设就是我们创建的那个AT吧,那么count=1 size_t count = activeTracks.size();

float masterVolume = mMasterVolume; bool masterMute = mMasterMute; for (size_t i=0 ; i

sp t = activeTracks[i].promote(); Track* const track = t.get();

//得到placement new分配的那个跨进程共享的对象 audio_track_cblk_t* cblk = track->cblk(); //设置混音器,当前活跃的track。

mAudioMixer->setActiveTrack(track->name());

if (cblk->framesReady() && (track->isReady() || track->isStopped()) && !track->isPaused() && !track->isTerminated()) {

// compute volume for this track //AT已经write数据了。所以肯定会进到这来。 int16_t left, right;

if (track->isMuted() || masterMute || track->isPausing() || mStreamTypes[track->type()].mute) { left = right = 0; if (track->isPausing()) { track->setPaused(); }

//AT设置的音量假设不为零,我们需要聆听声音! //所以走else流程 } else {

// read original volumes with volume control

float typeVolume = mStreamTypes[track->type()].volume; float v = masterVolume * typeVolume; float v_clamped = v * cblk->volume[0]; if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN; left = int16_t(v_clamped); v_clamped = v * cblk->volume[1];

if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN; right = int16_t(v_clamped); //计算音量 }

//注意,这里对混音器设置了数据提供来源,是一个track,还记得我们前面说的吗?Track从

AudioBufferProvider派生

mAudioMixer->setBufferProvider(track); mAudioMixer->enable(AudioMixer::MIXING);

int param = AudioMixer::VOLUME; //为这个track设置左右音量等

mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left); mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right); mAudioMixer->setParameter( AudioMixer::TRACK,

AudioMixer::FORMAT, track->format()); mAudioMixer->setParameter( AudioMixer::TRACK,

AudioMixer::CHANNEL_COUNT, track->channelCount()); mAudioMixer->setParameter( AudioMixer::RESAMPLE, AudioMixer::SAMPLE_RATE, int(cblk->sampleRate)); } else {

if (track->isStopped()) { track->reset(); }

//如果这个track已经停止了,那么把它加到需要移除的track队列tracksToRemove中去

//同时停止它在AudioMixer中的混音

if (track->isTerminated() || track->isStopped() || track->isPaused()) {

tracksToRemove->add(track);

mAudioMixer->disable(AudioMixer::MIXING); } else {

mAudioMixer->disable(AudioMixer::MIXING); } } }

// remove all the tracks that need to be... count = tracksToRemove->size();

return mixerStatus; }

看明白了吗?prepare_l的功能是什么?根据当前活跃的track队列,来为混音器设置信息。可想而知,一个track必然在混音器中有一个对应的东西。我们待会分析AudioMixer的时候再详述。 为混音器准备好后,下面调用它的process函数 void AudioMixer::process(void* output) {

mState.hook(&mState, output);//hook?难道是钩子函数? }

晕乎,就这么简单的函数???

CTRL+左键,hook是一个函数指针啊,在哪里赋值的?具体实现函数又是哪个? 没办法了,只能分析AudioMixer类了。 4. AudioMixer

AudioMixer实现在framework/base/libs/audioflinger/AudioMixer.cpp中 AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate) : mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate) {

mState.enabledTracks= 0; mState.needsChanged = 0; mState.frameCount = frameCount; mState.outputTemp = 0; mState.resampleTemp = 0;

mState.hook = process__nop;//process__nop,是该类的静态函数 track_t* t = mState.tracks; //支持32路混音。牛死了 for (int i=0 ; i<32 ; i++) { t->needs = 0;

t->volume[0] = UNITY_GAIN; t->volume[1] = UNITY_GAIN; t->volumeInc[0] = 0; t->volumeInc[1] = 0; t->channelCount = 2; t->enabled = 0; t->format = 16;

t->buffer.raw = 0; t->bufferProvider = 0; t->hook = 0; t->resampler = 0;

t->sampleRate = mSampleRate; t->in = 0; t++; } }

//其中,mState是在AudioMixer.h中定义的一个数据结构

//注意,source insight没办法解析这个mState,因为....见下面的注释。 struct state_t {

uint32_t enabledTracks; uint32_t needsChanged; size_t frameCount; mix_t hook; int32_t *outputTemp; int32_t *resampleTemp; int32_t reserved[2];

track_t tracks[32];// __attribute__((aligned(32)));《--把这里注释掉

//否则source insight会解析不了这个state_t类型 };

int mActiveTrack;

uint32_t mTrackNames;//names?搞得像字符串,实际是一个int const uint32_t mSampleRate;

state_t mState

好了,没什么吗。hook对应的可选函数实现有: process__validate process__nop

process__genericNoResampling


AudioFlinger分析(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:华理工 宏观经济学 - 201606 - 模拟卷2

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: