[audio] AudioTrack (六) 共享内存使用分析

环形缓冲区,[ audio_track_cblk_t ] [ FIFO ] 如何读取和写入

环形缓冲区:初始 R = 0,W = 0,buf 长度为 LEN

写入一个数据:w = W % LEN;buf[w] = data;W++;等价于 w = W & (LEN -1)

读取一个数据:r = R % LEN;buf[r] = data;R++;等价于 r = R & (LEN -1)

判断 满:W - R == LEN

判断 空:W == R


接上文

https://blog.csdn.net/we1less/article/details/156458655?spm=1001.2014.3001.5502

av/media/libaudioclient/AudioTrack.cpp createTrack_l

**STATIC:**StaticAudioTrackClientProxy

**STREAM:**AudioTrackClientProxy

cblk, buffers, mFrameCount, mFrameSize

cpp 复制代码
status_t AudioTrack::createTrack_l()
{
    status_t status;
 
    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
    
    // 使用返回的 response 解析出 Cblk
    status = audioFlinger->createTrack(aidlInput.value(), response);
    
    output.audioTrack->getCblk(&sfr);
 
    audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
    
    mCblk = cblk;
 
    void* buffers;
    if (mSharedBuffer == 0) {
        
        // STREAM 模式下音频数据 buffers 就是 + 1
        buffers = cblk + 1;
    } else {
        // STATIC 模式下音频数据 buffers 就是传进来的 buffer
        buffers = mSharedBuffer->unsecurePointer();
 
        }
    }

    if (mSharedBuffer == 0) {
        mStaticProxy.clear();
        
        //stream
        mProxy = new AudioTrackClientProxy(cblk, buffers, mFrameCount, mFrameSize);
    } else {

        //static
        mStaticProxy = new StaticAudioTrackClientProxy(cblk, buffers, mFrameCount, mFrameSize);
        mProxy = mStaticProxy;
    }
    
 
    return logIfErrorAndReturnStatus(status, "");
}

app 调用 streamTrack.write(buffer, 0, len)

base/media/java/android/media/AudioTrack.java

native_write_byte

java 复制代码
public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
        @WriteMode int writeMode) {


    final int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat,
            writeMode == WRITE_BLOCKING);


    return ret;
}

base/core/jni/android_media_AudioTrack.cpp android_media_AudioTrack_writeArray

STATIC 模式下直接使用的memcpy

cpp 复制代码
template <typename T>
static jint android_media_AudioTrack_writeArray(JNIEnv *env, jobject thiz,
                                                T javaAudioData,
                                                jint offsetInSamples, jint sizeInSamples,
                                                jint javaAudioFormat,
                                                jboolean isWriteBlocking) {
    //ALOGV("android_media_AudioTrack_writeArray(offset=%d, sizeInSamples=%d) called",
    //        offsetInSamples, sizeInSamples);
    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);


    jint samplesWritten = writeToTrack(lpTrack, javaAudioFormat, cAudioData,
            offsetInSamples, sizeInSamples, isWriteBlocking == JNI_TRUE /* blocking */);

    return samplesWritten;
}


template <typename T>
static jint writeToTrack(const sp<AudioTrack>& track, jint audioFormat, const T *data,
                         jint offsetInSamples, jint sizeInSamples, bool blocking) {

    ssize_t written = 0;

    size_t sizeInBytes = sizeInSamples * sizeof(T);
    if (track->sharedBuffer() == 0) {

        written = track->write(data + offsetInSamples, sizeInBytes, blocking);

        if (written == (ssize_t) WOULD_BLOCK) {
            written = 0;
        }
    } else {
        
        // STATIC 模式下直接使用的memcpy

        if ((size_t)sizeInBytes > track->sharedBuffer()->size()) {
            sizeInBytes = track->sharedBuffer()->size();
        }

        memcpy(track->sharedBuffer()->unsecurePointer(), data + offsetInSamples, sizeInBytes);

        written = sizeInBytes;
    }

    if (written >= 0) {
        return written / sizeof(T);
    }

    return interpretWriteSizeError(written);
}

audioflinger

av/services/audioflinger/Threads.cpp createTrack_l

相关推荐
天若有情6739 分钟前
逆向玩家狂喜!用C++野生写法一键破解线性加密(不规范但巨好用)
开发语言·c++·算法
XiYang-DING9 分钟前
JavaScript
开发语言·javascript·ecmascript
咸鱼翻身小阿橙12 分钟前
Qt QML调用C++注册类
java·c++·qt
skywalk816314 分钟前
代码高尔夫(Code Golf)是一种以“用最少的字符数实现特定功能”为核心目标的编程挑战或风格。
开发语言
xyq202418 分钟前
MySQL 安装配置
开发语言
逸Y 仙X23 分钟前
文章二十一:ElasticSearch 词项查询与调度查询实战
java·大数据·数据库·elasticsearch·搜索引擎
Bechamz23 分钟前
大数据开发学习Day25
java·大数据·学习
鸽子一号24 分钟前
c#Modbus通信
开发语言·c#
念何架构之路39 分钟前
Go Socket编程
开发语言·后端·golang
feifeigo1231 小时前
基于无迹变换的电网概率潮流分析 MATLAB 实现
开发语言·算法·matlab