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 ,