音频系统的播放接口由AudioTrack提供,每一个音频都会对应一个AudioTrack实例,它会通过iBinder来远程调用AudioFlinger的createTrack函数.AudioFlinger 会根据传入的frameCOunt参数申请一块内存,AudioTrack可以通过IaudioTrack接口的getCblk()函数获得指向该内存的Imemory接口,然后AudioTrack通过该Imemeory接口的pointer()函数获得指向该内存快的指针,这块内存的开始部分是audio_track_cblk_t结构,紧接着是大小为feameSize的buffer内存.
代码路径位于frameworks/base/media/libmedia/AudioTrack.cpp
status_t AudioTrack::set(
int streamType,
uint32_t sampleRate,
int format,
int channelMask,
int frameCount,
uint32_t flags,
callback_t cbf,
void* user,
int notificationFrames,
const sp<IMemory>& sharedBuffer,
bool threadCanCallJava,
int sessionId)
{
LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
AutoMutex lock(mLock);
if (mAudioTrack != 0) {
LOGE("Track already in use");
return INVALID_OPERATION;
}
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/* create the IAudioTrack */
status_t status = createTrack_l(streamType,
sampleRate,
(uint32_t)format,
(uint32_t)channelMask,
frameCount,
flags,
sharedBuffer,
output,
true);
if (status != NO_ERROR) {
return status;
}
if (cbf != 0) {
mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
if (mAudioTrackThread == 0) {
LOGE("Could not create callback thread");
return NO_INIT;
}
}
。。。。。。。。。。。。。。。。。。。
AudioSystem::acquireAudioSessionId(mSessionId);
mRestoreStatus = NO_ERROR;
return NO_ERROR;
}
status_t AudioTrack::createTrack_l(
int streamType,
uint32_t sampleRate,
uint32_t format,
uint32_t channelMask,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
bool enforceFrameCount)
{
status_t status;
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
if (audioFlinger == 0) {
LOGE("Could not get audioflinger");
return NO_INIT;
}
int afSampleRate;
if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
return NO_INIT;
}
int afFrameCount;
if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
return NO_INIT;
}
uint32_t afLatency;
if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) {
return NO_INIT;
}
mNotificationFramesAct = mNotificationFramesReq;
if (!audio_is_linear_pcm(format)) {
if (sharedBuffer != 0) {
frameCount = sharedBuffer->size();
}
} else {
// Ensure that buffer depth covers at least audio hardware latency
uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
if (minBufCount < 2) minBufCount = 2;
int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;
if (sharedBuffer == 0) {
if (frameCount == 0) {
frameCount = minFrameCount;
}
if (mNotificationFramesAct == 0) {
mNotificationFramesAct = frameCount/2;
}
// Make sure that application is notified with sufficient margin
// before underrun
if (mNotificationFramesAct > (uint32_t)frameCount/2) {
mNotificationFramesAct = frameCount/2;
}
if (frameCount < minFrameCount) {
if (enforceFrameCount) {
LOGE("Invalid buffer size: minFrameCount %d, frameCount %d", minFrameCount, frameCount);
return BAD_VALUE;
} else {
frameCount = minFrameCount;
}
}
} else {
// Ensure that buffer alignment matches channelcount
int channelCount = popcount(channelMask);
if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) {
LOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount);
return BAD_VALUE;
}
frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t);
}
}
sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
streamType,
sampleRate,
format,
channelMask,
frameCount,
((uint16_t)flags) << 16,
sharedBuffer,
output,
&mSessionId,
&status);
if (track == 0) {
LOGE("AudioFlinger could not create track, status: %d", status);
return status;
}
sp<IMemory> cblk = track->getCblk();
if (cblk == 0) {
LOGE("Could not get control block");
return NO_INIT;
}
mAudioTrack.clear();
mAudioTrack = track;
mCblkMemory.clear();
mCblkMemory = cblk;
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags);
if (sharedBuffer == 0) {
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
} else {
mCblk->buffers = sharedBuffer->pointer();
// Force buffer full condition as data is already present in shared memory
mCblk->stepUser(mCblk->frameCount);
}
mCblk->volumeLR = (uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000);
mCblk->sendLevel = uint16_t(mSendLevel * 0x1000);
mAudioTrack->attachAuxEffect(mAuxEffectId);
mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
mRemainingFrames = mNotificationFramesAct;
mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate;
return NO_ERROR;
}
/**
*createTrack_l
*/
status_t AudioTrack::createTrack_l(
int streamType,
uint32_t sampleRate,
uint32_t format,
uint32_t channelMask,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
bool enforceFrameCount)
{
status_t status;
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
if (audioFlinger == 0) {
LOGE("Could not get audioflinger");
return NO_INIT;
}
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
streamType,
sampleRate,
format,
channelMask,
frameCount,//通过这个参数来申请一块内存
((uint16_t)flags) << 16,
sharedBuffer,
output,
&mSessionId,
&status);
if (track == 0) {
LOGE("AudioFlinger could not create track, status: %d", status);
return status;
}
/*获取IMemeory 接口*/
sp<IMemory> cblk = track->getCblk();
if (cblk == 0) {
LOGE("Could not get control block");
return NO_INIT;
}
mAudioTrack.clear();
mAudioTrack = track;
mCblkMemory.clear();
mCblkMemory = cblk;
/*通过pointer指针来指向该内存块*/
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags);
if (sharedBuffer == 0) {//给buffer起始地址赋值
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);/*内存的其实部分让frameSize 的buffer内存也指向这里*/
} else {
mCblk->buffers = sharedBuffer->pointer();
// Force buffer full condition as data is already present in shared memory
mCblk->stepUser(mCblk->frameCount);
}
mCblk->volumeLR = (uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000);
mCblk->sendLevel = uint16_t(mSendLevel * 0x1000);
mAudioTrack->attachAuxEffect(mAuxEffectId);
mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
mRemainingFrames = mNotificationFramesAct;
mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate;
return NO_ERROR;
}
在上面的函数中通过AudioSystem:: AudioSystem::get_audio_flinger()函数可以获得IAudioFlinger的实例,再通过该实例调用createTrack申请内存,初始化buffer等,