bool TimerManager::AsyncRemoveTimer(uint64_t id) { assert(!IsStoped()); MutexLocker locker(&m_mutex); return AsyncRemoveTimerNoLock(id); }
void SLSound::Stop() { if (IsStoped()) return ; safe_delete(i_thread); (*mBQPlayI)->SetPlayState(mBQPlayI, SL_PLAYSTATE_STOPPED); (*mBQObjectI)->Destroy(mBQObjectI); mBQObjectI = NULL; mBQPlayI = NULL; mBQBufferQueueI = NULL; mBQEffectSendI = NULL; mVolumeI = NULL; mBuffer.Clear(); mBufferQueue.Clear(); mPosition = Float3(0, 0, 0); mVolume = 1; mAttenStart = mAttenEnd = 0; mInvAttenDist = 1; mAudio = NULL; mCategory = 0; mFlags = 0; mFadeMode = 0; mFadeTime = SL_FADETIME; }
void SLSound::Resume() { if (IsStoped() || !IsPaused()) return ; (*mBQPlayI)->SetPlayState(mBQPlayI, SL_PLAYSTATE_PLAYING); }
void SLSound::Pause() { if (IsStoped() || IsPaused()) return ; (*mBQPlayI)->SetPlayState(mBQPlayI, SL_PLAYSTATE_PAUSED); }
bool SLSound::IsPaused() { d_assert (!IsStoped()); SLuint32 state = 0; (*mBQPlayI)->GetPlayState(mBQPlayI, &state); return state == SL_PLAYSTATE_PAUSED; }
void TimerManager::Stop() { if (!IsStoped()) { { MutexLocker locker(&m_mutex); BaseThread::SendStopRequest(); m_cond.Signal(); } BaseThread::Join(); Clear(); } }
bool TimerManager::EnableTimer(uint64_t id) { assert(!IsStoped()); MutexLocker locker(&m_mutex); TimerEntry* entry = FindEntry(id); if (entry) { entry->is_enabled = true; SetNextTimeout(id, entry->interval, entry->revision); return true; } return false; }
bool TimerManager::DisableTimer(uint64_t id) { assert(!IsStoped()); MutexLocker locker(&m_mutex); TimerEntry* entry = FindEntry(id); if (entry) { entry->is_enabled = false; entry->revision++; return true; } return false; }
uint64_t TimerManager::AddTimer(int64_t interval, bool is_period, CallbackClosure* closure) { assert(interval >= 0); assert(!IsStoped()); MutexLocker locker(&m_mutex); uint64_t id = NewTimerId(); TimerEntry& timer = m_timers[id]; timer.interval = interval; timer.is_period = is_period; timer.closure = closure; timer.is_enabled = true; SetNextTimeout(id, interval, 0); return id; }
bool TimerManager::ModifyTimer(uint64_t id, int64_t interval, CallbackClosure* closure) { assert(!IsStoped()); MutexLocker locker(&m_mutex); TimerEntry* entry = FindEntry(id); if (entry) { entry->interval = interval; if (entry->closure != closure) { delete entry->closure; // release the old closure entry->closure = closure; } entry->revision++; if (entry->is_enabled) { SetNextTimeout(id, interval, entry->revision); } return true; } return false; }
bool TimerManager::RemoveTimer(uint64_t id) { assert(!IsStoped()); // 0 is an invalid id if (id == 0) { return false; } if (ThisThread::GetId() == GetId()) { // in the same thread, can call AsyncRemoveTimer return AsyncRemoveTimer(id); } while (true) { { MutexLocker locker(&m_mutex); if (id != m_running_timer) { return AsyncRemoveTimerNoLock(id); } } ThisThread::Sleep(1); } }
bool SLSound::Play(IAudioPtr ado, int category, int flags) { d_assert (IsStoped() && ado != NULL); // configure audio source #ifdef M_PLATFORM_ANDROID SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, NUM_BUFFER }; #else SLDataLocator_BufferQueue loc_bufq = { SL_DATALOCATOR_BUFFERQUEUE, NUM_BUFFER }; #endif SLDataFormat_PCM format_pcm; format_pcm.formatType = SL_DATAFORMAT_PCM; format_pcm.numChannels = ado->i_channels; format_pcm.samplesPerSec = ado->i_sample_rate * 1000; format_pcm.bitsPerSample = ado->i_sample_size * 8; format_pcm.containerSize = ado->i_sample_size * 8; if(ado->i_channels == 2 ) format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; else format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER; format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; SLDataSource audioSrc = {&loc_bufq, &format_pcm}; // configure audio sink SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, gOutputMixObject}; SLDataSink audioSnk = {&loc_outmix, NULL}; // create audio player const SLInterfaceID ids[3] = { SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND, SL_IID_VOLUME}; const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; SLresult result = (*gEngineEngine)->CreateAudioPlayer(gEngineEngine, &mBQObjectI, &audioSrc, &audioSnk, 3, ids, req); if (result != SL_RESULT_SUCCESS) return false; mAudio = ado; mCategory = category; mFlags = flags; mVolume = 1; mVolumeAbs = 1; if (ado->i_channels == 1) { mBufferSize = ado->i_sample_rate / 2; mBufferSize -= mBufferSize % 2; } else { mBufferSize = ado->i_sample_rate; mBufferSize -= mBufferSize % 4; } mBuffer.Resize(NUM_BUFFER * mBufferSize); for (int i = 0; i < NUM_BUFFER; ++i) { mBufferFlag[i] = 0; } (*mBQObjectI)->Realize(mBQObjectI, SL_BOOLEAN_FALSE); (*mBQObjectI)->GetInterface(mBQObjectI, SL_IID_PLAY, &mBQPlayI); (*mBQObjectI)->GetInterface(mBQObjectI, SL_IID_BUFFERQUEUE, &mBQBufferQueueI); (*mBQObjectI)->GetInterface(mBQObjectI, SL_IID_EFFECTSEND, &mBQEffectSendI); (*mBQObjectI)->GetInterface(mBQObjectI, SL_IID_VOLUME, &mVolumeI); Track(); (*mBQPlayI)->SetPositionUpdatePeriod(mBQPlayI, (SLmillisecond)(ado->i_duration * 1000)); (*mBQPlayI)->SetPlayState(mBQPlayI, SL_PLAYSTATE_PLAYING); if (mFlags & AUDIO_FLAG_MULTI_THREAD) { i_thread = new SLSoundThread(this); i_thread->Start(); } mFadeMode = 0; mFadeTime = SL_FADETIME; if (mFlags & AUDIO_FLAG_FADEIN) FadeIn(); mPlayTime = 0; mPlayOffset = 0; mPlayEnd = FALSE; return true; }
bool SLSound::IsTimeOut() { d_assert (!IsStoped()); return mPlayEnd == TRUE && mBufferQueue.Size() == 0; }
void SLSound::Track() { if (IsStoped() || IsPaused() || mAudio == NULL) return ; #ifdef M_PLATFORM_ANDROID SLAndroidSimpleBufferQueueState state; #else SLBufferQueueState state; #endif (*mBQBufferQueueI)->GetState(mBQBufferQueueI, &state); int processed = mBufferQueue.Size() - state.count; if (processed > 0) { mPlayOffset += mBufferQueue[0].size; mBufferFlag[mBufferQueue[0].id] = 0; mBufferQueue.Erase(0); if (mPlayOffset >= mAudio->i_data_size && (mFlags & AUDIO_FLAG_LOOPED)) mPlayOffset -= mAudio->i_data_size; } SLmillisecond millsecond; (*mBQPlayI)->GetPosition(mBQPlayI, &millsecond); mPlayTime = millsecond / 1000.0f; int queued = mBufferQueue.Size(); while (queued++ < NUM_BUFFER) { PlayBuffer pb = {0, 0}; for (int i = 0; i < NUM_BUFFER; ++i) { if (mBufferFlag[i] == 0) { pb.id = i; break; } } int offset = pb.id * mBufferSize; int nreads = mAudio->Read(&mBuffer[offset], mBufferSize); if (nreads > 0) { #ifdef M_PLATFORM_ANDROID (*mBQBufferQueueI)->Enqueue(mBQBufferQueueI, &mBuffer[offset], nreads); #else (*mBQBufferQueueI)->Enqueue(mBQBufferQueueI, &mBuffer[offset], nreads, false); #endif pb.size = nreads; mBufferFlag[pb.id] = 1; mBufferQueue.PushBack(pb); } else if (mFlags & AUDIO_FLAG_LOOPED) { mAudio->Seek(0); } else { mPlayEnd = TRUE; break; } } }