AudioFlinger音频dump方法

一、概述

采用Android TEE方案,支持dump AudioFlinger中各个链路中的音频数据。

支持DUMP的音频数据如下:

"aftee_Date_ThreadId_C_reason.wav"  // RecordThread (从hal层取到的数据)

"aftee_Date_ThreadId_M_reason.wav" //MixerThread (NormalMixer后的数据)

"aftee_Date_ThreadId_F_reason.wav" // MixerThread (FastMixer后的数据)

"aftee_Date_ThreadId_TrackId_R_reason.wav" // RecordTrack(送给AudioRecord的数据)

"aftee_Date_ThreadId_TrackId_TrackName_T_reason.wav" // PlaybackTrack (AudioTrack写下来的数据)

二、准备工作

2.1 编译时设置

  • 修改frameworks/av/services/audioflinger/Configuration.h,对 #define TEE_SINK 取消注释
  • 重新编译 libaudioflinger.so
  • 将 64与32位的 libaudioflinger.so 推送或同步到设备的 /system/lib

Android 9 也要编译 audioserver 推进车机

2.2 运行时设置

  • 开启debug开关

getprop | grep ro.debuggable

确认输出是:[ro.debuggable]: [1]

  • 创建文件目录

ls -ld /data/misc/audioserver,

确认输出是:drwx------ audioserver audioserver ... audioserver

如果目录不存在,请按如下方式创建:

mkdir /data/misc/audioserver

chown audioserver:audioserver/data/misc/audioserver

  • 修改配置文件

echo af.tee=# > /data/local.prop

af.tee 的值是一个 0 到 7 之间的数字,表示几个位的总和(每个功能一个位)

1 = 输入

2 = FastMixer 输出

4 = 各音轨的 AudioRecord 和 AudioTrack

chmod 644 /data/local.prop

  • 重启系统

三.测试和获取数据

  1. 播放音频
  2. dumpsys media.audio_flinger
  3. 在 dumpsys 输出中查找如下行:

    tee copied to /data/misc/audioserver/20131010101147_2.wav

    这是一个 PCM .wav 文件

  4. adb pull  /data/misc/audioserver/*.wav 文件

四、截取位置代码分析

T 及 R 录音文件的截取位置:

// frameworks/av/services/audioflinger/Tracks.cpp

// AudioBufferProvider interface  
// getNextBuffer() = 0;
// This implementation of releaseBuffer() is used by Track and RecordTrack
void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
{
#ifdef TEE_SINK
     mTee.write(buffer->raw, buffer->frameCount);
#endif

F录音文件的截取位置:

//frameworks/av/services/audioflinger/FastMixer.cpp

void FastMixer::onWork()
{
...
// if non-NULL, then duplicate write() to this non-blocking sink
#ifdef TEE_SINK
        mTee.write(buffer, frameCount);
#endif
// FIXME write() is non-blocking and lock-free for a properly implemented NBAIO sink,
// but this code should be modified to handle both non-blocking and blocking sinks
        dumpState->mWriteSequence++;
        ATRACE_BEGIN("write");
        ssize_t framesWritten = mOutputSink->write(buffer, frameCount);
        ATRACE_END();
...
}

M录音文件的截取位置:

// frameworks/av/services/audioflinger/Threads.cpp

// shared by MIXER and DIRECT, overridden by DUPLICATING
ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
{
    LOG_HIST_TS();
    mInWrite = true;
    ssize_t bytesWritten;
    const size_t offset = mCurrentWriteLength - mBytesRemaining;

    // If an NBAIO sink is present, use it to write the normal mixer's submix
    if (mNormalSink != 0) {

        const size_t count = mBytesRemaining / mFrameSize;

        ATRACE_BEGIN("write");
        // update the setpoint when AudioFlinger::mScreenState changes
        uint32_t screenState = AudioFlinger::mScreenState;
        if (screenState != mScreenState) {
            mScreenState = screenState;
            MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
            if (pipe != NULL) {
                pipe->setAvgFrames((mScreenState & 1) ?
                        (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
            }
        }
        ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count);
        ATRACE_END();
        if (framesWritten > 0) {
            bytesWritten = framesWritten * mFrameSize;
#ifdef TEE_SINK
            mTee.write((char *)mSinkBuffer + offset, framesWritten);
#endif
        } else {
            bytesWritten = framesWritten;
        }

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mongo-Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值