当前位置:操作系统 > 安卓/Android >>

Android Audio代码分析11 - AudioStreamOutALSA::write函数

在看音频数据是怎么写的时候,在MixerThread的threadloop函数中,有以下代码完成了往硬件写数据:
int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);


mOutput来历:
函数AudioFlinger::openOutput中创建了一个MixerThread对象,并将前面调用mAudioHardware->openOutputStream得到的output作为参数传入。
MixerThread继承自PlaybackThread,在PlaybackThread的构造函数中将传入的output赋值给了mOutput。


函数AudioFlinger::openOutput以前已经打过交道。mAudioHardware其实是一个AudioHardwareALSA对象。
调用mAudioHardware->openOutputStream得到的其实是一个AudioStreamOutALSA对象。


所以,mOutput->write,其实就是函数AudioStreamOutALSA::write。


*****************************************源码*************************************************
ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes)
{
    AutoMutex lock(mLock);


    if (!mPowerLock) {
        acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock");
        mPowerLock = true;
    }


    acoustic_device_t *aDev = acoustics();


    // For output, we will pass the data on to the acoustics module, but the actual
    // data is expected to be sent to the audio device directly as well.
    if (aDev && aDev->write)
        aDev->write(aDev, buffer, bytes);


    snd_pcm_sframes_t n;
    size_t            sent = 0;
    status_t          err;


    do {
        if (mHandle->mmap)
            n = snd_pcm_mmap_writei(mHandle->handle,
                               (char *)buffer + sent,
                               snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent));
else
            n = snd_pcm_writei(mHandle->handle,
                               (char *)buffer + sent,
                               snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent));
        if (n == -EBADFD) {
            // Somehow the stream is in a bad state. The driver probably
            // has a bug and snd_pcm_recover() doesn't seem to handle this.
            mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode);


            if (aDev && aDev->recover) aDev->recover(aDev, n);
        }
        else if (n < 0) {
            if (mHandle->handle) {
LOGW("underrun and do recovery.....");
                // snd_pcm_recover() will return 0 if successful in recovering from
                // an error, or -errno if the error was unrecoverable.
                n = snd_pcm_recover(mHandle->handle, n, 1);


                if (aDev && aDev->recover) aDev->recover(aDev, n);


                if (n) return static_cast<ssize_t>(n);
            }
        }
        else {
            mFrameCount += n;
            sent += static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle->handle, n));
        }


    } while (mHandle->handle && sent < bytes);


    return sent;
}
**********************************************************************************************
源码路径:
hardware\alsa_sound\AudioStreamOutALSA.cpp


#######################说明################################
ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes)
{
    AutoMutex lock(mLock);


    if (!mPowerLock) {
        acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock");
        mPowerLock = true;
    }


// 看看acoustics是个什么东东
    acoustic_device_t *aDev = acoustics();
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
acoustic_device_t *ALSAStreamOps::acoustics()
{
    return mParent->mAcousticDevice;
}
ALSAStreamOps是AudioStreamOutALSA的父类。
mParent是在ALSAStreamOps的构造函数中赋值的。
AudioStreamOutALSA对象是在AudioHardwareALSA::openOutputStream中创建。
out = new AudioStreamOutALSA(this, &(*it));
在ALSAStreamOps的构造函数中,将传入的this赋值给了mParent。
mAcousticDevice其实是AudioHardwareALSA的成员变量。其赋值在AudioHardwareALSA的构造函数中完成:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    err = hw_get_module(ACOUSTICS_HARDWARE_MODULE_ID,
            (hw_module_t const**)&module);


    if (err == 0) {
        hw_device_t* device;
        err = module->methods->open(module, ACOUSTICS_HARDWARE_NAME, &device);
        if (err == 0)
            mAcousticDevice = (acoustic_device_t *)device;
        else
            LOGE("Acoustics Module not found.");
    }
----------------------------------------------------------------
----------------------------------------------------------------


  &

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,