public void play()
throws IllegalStateException {
if (mState != STATE_INITIALIZED) {
throw new IllegalStateException("play() called on uninitialized AudioTrack.");
}
synchronized(mPlayStateLock) {
native_start();
mPlayState = PLAYSTATE_PLAYING;
}
}
static void
android_media_AudioTrack_start(JNIEnv *env, jobject thiz)
{
sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for start()");
return;
}
lpTrack->start();
}
status_t AudioTrack::start()
{
AutoMutex lock(mLock);
if (mState == STATE_ACTIVE) {
return INVALID_OPERATION;
}
mInUnderrun = true;
State previousState = mState;
if (previousState == STATE_PAUSED_STOPPING) {
mState = STATE_STOPPING;
} else {
mState = STATE_ACTIVE;
}
if (previousState == STATE_STOPPED || previousState == STATE_FLUSHED) {
// reset current position as seen by client to 0
mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition());
// force refresh of remaining frames by processAudioBuffer() as last
// write before stop could be partial.
mRefreshRemaining = true;
}
mNewPosition = mProxy->getPosition() + mUpdatePeriod;
int32_t flags = android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags);
sp<AudioTrackThread> t = mAudioTrackThread;
if (t != 0) {
if (previousState == STATE_STOPPING) {
mProxy->interrupt();
} else {
t->resume();
}
} else {
mPreviousPriority = getpriority(PRIO_PROCESS, 0);
get_sched_policy(0, &mPreviousSchedulingGroup);
androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
}
status_t status = NO_ERROR;
if (!(flags & CBLK_INVALID)) {
status = mAudioTrack->start();
if (status == DEAD_OBJECT) {
flags |= CBLK_INVALID;
}
}
if (flags & CBLK_INVALID) {
status = restoreTrack_l("start");
}
if (status != NO_ERROR) {
ALOGE("start() status %d", status);
mState = previousState;
if (t != 0) {
if (previousState != STATE_STOPPING) {
t->pause();
}
} else {
setpriority(PRIO_PROCESS, 0, mPreviousPriority);
set_sched_policy(0, mPreviousSchedulingGroup);
}
}
return status;
}
status_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event,
int triggerSession)
{
status_t status = NO_ERROR;
ALOGV("start(%d), calling pid %d session %d",
Audio笔记之AudioTrack::play
最新推荐文章于 2024-05-07 08:56:33 发布
本文详细解析了Android中的AudioTrack类如何进行音频播放。通过分析`play()`方法,展示了从初始化检查、调用本地接口启动、状态转换到实际音频数据处理的流程。此外,还涉及到线程同步、权限管理以及与AudioPolicyManager的交互。
摘要由CSDN通过智能技术生成