Android 音频系统:从 AudioTrack 到 AudioFlinger

https://blog.csdn.net/zyuanyun/article/details/60890534?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162398154816780269857280%2522%252C%2522scm%2522%253A%252220140713.130102334%E2%80%A6%2522%257D&request_id=162398154816780269857280&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-4-60890534.first_rank_v2_pc_rank_v29&utm_term=AudioFlinger&spm=1018.2226.3001.4187
audiotrack和audioflinger交互 添加链接描述

3.3. AudioFlinger 服务接口
AudioFlinger 对外提供的主要的服务接口如下:

在这里插入图片描述
可以归纳出 AudioFlinger 响应的服务请求主要有:

获取硬件设备的配置信息 sampleRate、format、frameCount、latency
音量调节 setMasterVolume、setStreamVolume、setVoiceVolume
静音操作 setMasterMute、setStreamMute、setMicMute
音频模式切换 setMode Normal、Ringtone、Call、Communicatoin
音频参数设置 setParameters
输入输出流设备管理 openOutput closeOutput openInput closeInput openRecord
音频流管理 createTrack start/stop/pause

在这里插入图片描述

  1. ThreadBase:PlaybackThread 和 RecordThread 的基类
  2. RecordThread:录制线程类,由 ThreadBase 派生
  3. PlaybackThread:回放线程基类,同由 ThreadBase 派生
  4. MixerThread:混音回放线程类,由 PlaybackThread 派生,负责处理标识为
    AUDIO_OUTPUT_FLAG_PRIMARY、AUDIO_OUTPUT_FLAG_FAST、AUDIO_OUTPUT_FLAG_DEEP_BUFFER
    的音频流,MixerThread 可以把多个音轨的数据混音后再输出
  5. DirectOutputThread:直输回放线程类,由 PlaybackThread 派生,负责处理标识为
    AUDIO_OUTPUT_FLAG_DIRECT 的音频流,这种音频流数据不需要软件混音,直接输出到音频设备即可
  6. DuplicatingThread:复制回放线程类,由 MixerThread
    派生,负责复制音频流数据到其他输出设备,使用场景如主声卡设备、蓝牙耳机设备、USB 声卡设备同时输出
  7. OffloadThread:硬解回放线程类,由 DirectOutputThread 派生,负责处理标识为
    AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD 的音频流,这种音频流未经软件解码的(一般是 MP3、AAC
    等格式的数据),需要输出到硬件解码器,由硬件解码器解码成 PCM 数据

PlaybackThread 中有个极为重要的函数 threadLoop(),当 PlaybackThread 被强引用时,threadLoop() 会真正运行起来进入循环主体,处理音频流数据相关事务,threadLoop() 大致流程如下(以 MixerThread 为例):

bool AudioFlinger::PlaybackThread::threadLoop()
{
    // ......

    while (!exitPending())
    {
        // ......

        { // scope for mLock

            Mutex::Autolock _l(mLock);
       processConfigEvents_l();

            // ......

            if ((!mActiveTracks.size() && systemTime() > mStandbyTimeNs) ||
                                   isSuspended()) {
                // put audio hardware into standby after short delay
                if (shouldStandby_l()) {

                    threadLoop_standby();

                    mStandby = true;
                }

                // ......
            }
            // mMixerStatusIgnoringFastTracks is also updated internally
            mMixerStatus = prepareTracks_l(&tracksToRemove);

            // ......
        } // mLock scope ends

        // ......

        if (mBytesRemaining == 0) {
            mCurrentWriteLength = 0;
            if (mMixerStatus == MIXER_TRACKS_READY) {
                // threadLoop_mix() sets mCurrentWriteLength
                threadLoop_mix();
            }
            // ......
        }

        // ......

        if (!waitingAsyncCallback()) {
            // mSleepTimeUs == 0 means we must write to audio hardware
            if (mSleepTimeUs == 0) {
                // ......
                if (mBytesRemaining) {
                    // FIXME rewrite to reduce number of system calls
                    ret = threadLoop_write();
                    lastWriteFinished = systemTime();
                    delta = lastWriteFinished - mLastWriteTime;
                    if (ret < 0) {
                        mBytesRemaining = 0;
                    } else {
                        mBytesWritten += ret;
                        mBytesRemaining -= ret;
                        mFramesWritten += ret / mFrameSize;
                    }
                }
                // ......
            }
            // ......
        }

        // Finally let go of removed track(s), without the lock held
        // since we can't guarantee the destructors won't acquire that
        // same lock.  This will also mutate and push a new fast mixer state.
        threadLoop_removeTracks(tracksToRemove);
        tracksToRemove.clear();

        // ......
    }

    threadLoop_exit();

    if (!mStandby) {
        threadLoop_standby();
        mStandby = true;
    }

    // ......
    return false;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值