android 音频数据在AudioFlinger中的处理(出入口)

本文深入探讨了Android音频处理框架AudioFlinger的数据流程,重点关注数据的入口和出口。数据出口在AudioFlinger::PlaybackThread::threadLoop_write()中,而数据入口位于AudioMixer的混音过程,通过AudioTrack的共享内存获取。threadLoop_mix()执行混音操作,将数据从track的mMainBuffer拉入并处理,最终写入驱动。
摘要由CSDN通过智能技术生成

AudioFlinger::PlaybackThread::threadLoop()
{
         …
     if (!waitingAsyncCallback()) {
            // sleepTime == 0 means we mustwrite to audio hardware
            if (sleepTime == 0) {
                if (mBytesRemaining) {
                    ssize_tret = threadLoop_write();
                    if (ret < 0) {
                        mBytesRemaining = 0;
                    } else {
                        mBytesWritten += ret;
                        mBytesRemaining -= ret;
                    }
                } else if ((mMixerStatus ==MIXER_DRAIN_TRACK) ||
                        (mMixerStatus ==MIXER_DRAIN_ALL)) {
                    threadLoop_drain();
                }
         …
}

AudioFlinger 是android 多媒体模块Audio模块的两大服务之一。音频相关的数据必须通过它来传递到底层,所以它就会有一个音频数据的处理过程。这里主要就是分析音频数据从编码器出来之后,怎么流向驱动的。

从audoFlinger的代码中很容易发现,数据写到驱动的处理是在函数

AudioFlinger::PlaybackThread::threadLoop_write()中。这个threadLoop_write 函数在AudioFlinger::PlaybackThread::threadLoop()函数中调用,很显然audioFlinger的数据处理都会在这个线程函数中处理。那么数据的出口是这样实现


那么数据的入口在哪里呢?

通过分析,发现PlaybackThread::threadLoop() 函数主要做三件事,prepareTracks_l(), threadLoop_mix(),threadLoop_write().

prepareTracks_l() 函数主要的工作就是检查是否有track 的状态,并做相应的处理,比如track准备好了,就把它添加到队列中区,还做一些处理比如

           // XXX: these things DON'T need to be done each time
           mAudioMixer->setBufferProvider(name, track);
           mAudioMixer->enable(name); 

           mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void*)vl);
           mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void*)vr);
           mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void*)va);
           mAudioMixer->setParameter(
                name,
                AudioMixer::TRACK,
                AudioMixer::FORMAT, (void*)track->format());
            mAudioMixer->setParameter(
                name,
                AudioMixer::TRACK,
                AudioMixer::CHANNEL_MASK, (void*)track->channelMask());


设置参数到AudioMixer。这个很关键,会影响后面混音的结果和处理。

prepareTracks_l() 之后就是混音处理了,处理函数就是threadLoop_mix()。混音,顾名思义,就是将几种声音混到一起,实际上就是将同时处于active状态的track进行混音,每一路音频对应一个track实例。目前android 最多支持32路混音,在类AudioMixer中有相应的定义:  static const uint32_tMAX_NUM_TRACKS = 32;

threadLoop_write 是数据的出口,prepareTracks_l只是准备tracks,那么很显然,数据的入口也只有threadLoop_mix 了,混音必须要对数据处理,如果没有数据怎么混音,此时将数据拉进来时最好的时机,事实上也是在threadLoop_mix 的处理过程中数据进入到

AudioFlinger服务中。下面来分析threadLoop_mix。

voidAudioFlinger::MixerThread::threadLoop_mix()
{
   // obtain the presentation timestamp of the next output buffer
   int64_t pts;
   status_t status = INVALID_OPERATION;
 
   if (mNormalSink != 0) {
       status = mNormalSink->getNextWriteTimestamp(&pts);
    }else {
       status = mOutputSink->getNextWriteTimestamp(&pts);
    }
 
   if (status != NO_ERROR) {
       pts = AudioBufferProvider::kInvalidPTS;
    }
   // mix buffers...
    mAudioMixer->process(pts);
   mCurrentWriteLength = mixBufferSize;
   if ((sleepTime == 0) && (sleepTimeShift > 0)) {
       sleepTimeShift--;
    }
   sleepTime = 0;
   standbyTime = systemTime() + standbyDelay;
   //TODO: delay standby when effects have a tail
}
从函数中发现, mAudioMixe
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值