Android Audio - 音频子系统框架简析

关键的类对象

AudioSystem
    AudioFlinger
    AudioPolicy
    
AudioStreamIn
AudioResampler

Threads
    RecordThread
    MixerThread
    PlaybackThread
    
TrackBase
    RecordTrack
    Track (playback track)
        TimedTrack
        OutputTrack

mRecord = new AudioRecord() 时

set
    openRecord
        AudioSystem::getInput
            // 只有 openInput 才回去创建新的 RecordThread.
            // 这里做了处理, 当本次录音的 Profile 文件与已经打开的 
            // mInput Profile 一样的话, 表示希望打开同一设备. 仅返回 audio_io_handle_t 即可.           
            mpClientInterface->openInput
                AudioFlinger::openInput
                    // 创建一个新的 audio_io_handle_t 号码.
                    audio_io_handle_t id = nextUniqueId();
                    
                    // 建立与 so 库的连接, 注意: 此时还没有 open 底层驱动.
                    inHwHal->open_input_stream(inHwHal, id, *pDevices, &config, &inStream);
                        ladev->hwif->openInputStream
                            // 创建 speex_resampler_init 重采样器.
                            new AudioHardware::DownSampler 
                            
                    // 创建一个 RecordThread 录音线程
                    thread = new RecordThread();
                    
                    // 将 audio_io_handle_t 绑定 RecordThread.
                    mRecordThreads.add(id, thread);
                    
        record = audioFlinger->openRecord
            // 从 mRecordThreads 里面根据 input(id) 获取一个 RecordThread.
            thread = checkRecordThread_l(input);
            // 创建一个 RecordTrack. 
            recordTrack = thread->createRecordTrack_l();
                new RecordTrack()
                
            // 将 recordTrack 绑定 RecordHandle 
            recordHandle = new RecordHandle(recordTrack);
            return recordHandle;
            
        mAudioRecord = record;

mRecord.start() 时

start
    mAudioRecord->start(event, triggerSession);
        RecordHandle->start()
            RecordThread::start(recordTrack)
                // 在此处加入 mActiveTracks 数组
                mActiveTracks.add(recordTrack); 
                
                // 置位 recordTrack != TrackBase::IDLE 状态.
                recordTrack->mState = TrackBase::STARTING_2;
                
                // 释放 RecordThread::threadLoop() 的锁.
                mWaitWorkCV.broadcast();

mRecord.read() 时

待填充

mRecord.stop() 时

// 停止只是将 recordTrack = TrackBase::PAUSING 的状态
// 不在 memcpy 底层获得到的 buffer 而已.
stop 
    mRecordTrack->stop();
        AudioSystem::stopInput(recordThread->id());

mRecord 对象被释放时

// 当 RecordHandle 析构时, 也就是持有它的 AudioRecord 对象析构时才调用.
~RecordHandle
    RecordTrack::destroy
        AudioSystem::releaseInput
            mpClientInterface->closeInput 
                AudioFlinger::closeInput
                    thread = checkRecordThread_l(input);
                    mRecordThreads.removeItem(input);
                    in->hwDev()->close_input_stream(in->hwDev(), in->stream);
    
        recordThread->destroyTrack_l
            // 仅仅是指移除了在 mTracks 里面的 recordTrack. 没有移除 mActiveTracks 里面的 recordTrack.
            mTracks.remove(track);

待整理流程

// 从 APP 录音角度分析
AudioRecord.java  
    create/set(设备(BT, DEFUALT), 通道数, 采样速率, 数据深度)
    start
    
AudioRecord.cpp
    1. set: new AudioRecordThread  读 RecordTrack. 
    2. openRecord_l: 
            // 用于标志从哪个声卡c / p设备获取.
            audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat, 
                                AudioPolicy->openInput -> 调用到了 AudioFlinger -> openInput()
                                
            audioFlinger->openRecord
                thread->createRecordTrack_l
                
    3. start 
            RecordHandle->start
                mRecordTrack->start
                    recordThread->start
                 
AudioFlinger // 
    openInput()
        AudioStreamIn *input = stream_in.
        new RecordThread
        
    Threads  // 线程            
        RecordThreads    // 录音线程(单例), 在第一次被 sp -> run() -> 由于录音状态是 PAUSING. 休眠.
            createRecordTrack_l
                RecordTrack.     app 读 buffer.  采集.
                
            start            
                AudioSystem::startInput(mId);
                    mpClientInterface->setParameters(input, param.toString());
                    
                mActiveTrack->RESUMING
               
              
            if (mActiveTrack == RESUMING) 
                threadLoop往下走了.
                1. 读一次.
                
                2. mInput->stream->read(mInput->stream, readInto, mBufferSize);
                
AudioPolicy //向下管理so库. 向上提供 Read / Write / set 接口.

AudioHAL    // ALSA PCM_XXX 操作声卡
    set
    
    read
        open_l -> pcm_open().
        pcm_read()
            Dev // 驱动


// 从系统启动角度
libmeida.so 
init.rc media
AudioFlinger 首先启动.
     1. 初始化 so 库列表. 
         mAudioHwDevs = dopen(xxx.so).

AudioPolicy 
     getProfile 解析 audio_policy.xml 
         mAudioHwDevs

与之相关

Android Audio - 支持多应用同时录音_Android4.4修改方法
Android Audio - 支持多应用同时录音_Android5.1 & Android6.0 修改方法
Android Audio - 支持多应用同时录音_Android8.1修改方法

发布了53 篇原创文章 · 获赞 19 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_33443989/article/details/103703004