bool Source::update() { if (!valid) return false; if (type == TYPE_STATIC) { // Looping mode could have changed. alSourcei(source, AL_LOOPING, isLooping() ? AL_TRUE : AL_FALSE); return !isStopped(); } else if (type == TYPE_STREAM && (isLooping() || !isFinished())) { // Number of processed buffers. ALint processed = 0; alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); while (processed--) { ALuint buffer; float curOffsetSamples, curOffsetSecs; alGetSourcef(source, AL_SAMPLE_OFFSET, &curOffsetSamples); int freq = decoder->getSampleRate(); curOffsetSecs = curOffsetSamples / freq; // Get a free buffer. alSourceUnqueueBuffers(source, 1, &buffer); float newOffsetSamples, newOffsetSecs; alGetSourcef(source, AL_SAMPLE_OFFSET, &newOffsetSamples); newOffsetSecs = newOffsetSamples / freq; offsetSamples += (curOffsetSamples - newOffsetSamples); offsetSeconds += (curOffsetSecs - newOffsetSecs); // FIXME: We should put freed buffers into a list that we later // consume here, so we can keep track of all free buffers even if we // tried to stream data to one but the decoder didn't have data for it. if (streamAtomic(buffer, decoder.get()) > 0) alSourceQueueBuffers(source, 1, &buffer); } return true; } return false; }
//============================================================================== bool AudioFilePlayer::setSourceWithReader (AudioFormatReader* reader) { bool shouldBeLooping = isLooping(); audioTransportSource->setSource (nullptr); if (reader != nullptr) { // we SHOULD let the AudioFormatReaderSource delete the reader for us.. audioFormatReaderSource = new AudioFormatReaderSource (reader, true); audioTransportSource->setSource (audioFormatReaderSource, 32768, &bufferingTimeSliceThread); if (shouldBeLooping) audioFormatReaderSource->setLooping (true); // let our listeners know that we have loaded a new file audioTransportSource->sendChangeMessage(); listeners.call (&Listener::fileChanged, this); return true; } audioTransportSource->sendChangeMessage(); listeners.call (&Listener::fileChanged, this); return false; }
bool BufferingAudioSource::waitForNextAudioBlockReady (const AudioSourceChannelInfo& info, const uint32 timeout) { if (!source || source->getTotalLength() <= 0) return false; if (nextPlayPos + info.numSamples < 0) return true; if (! isLooping() && nextPlayPos > getTotalLength()) return true; const uint32 endTime = Time::getMillisecondCounter() + timeout; uint32 now = Time::getMillisecondCounter(); while (now < endTime) { { const ScopedLock sl (bufferStartPosLock); const int validStart = static_cast<int> (jlimit (bufferValidStart, bufferValidEnd, nextPlayPos) - nextPlayPos); const int validEnd = static_cast<int> (jlimit (bufferValidStart, bufferValidEnd, nextPlayPos + info.numSamples) - nextPlayPos); if (validStart <= 0 && validStart < validEnd && validEnd >= info.numSamples) return true; } if (! bufferReadyEvent.wait (static_cast<int> (endTime - now))) return false; now = Time::getMillisecondCounter(); } return false; }
bool CirclePath::update(float deltaTime, const GeneralEntitySP& entity, bool updateRotation) { float elapsedAngle= updateTransform(); if (!isLooping() && elapsedAngle >= 360.0f) { setPosition(startPosition); if (updateRotation) { setRotation(baseRotation); } return true; } setPosition(transform * startPosition); if (updateRotation) { setRotation(baseRotation); } return false; }
void SFXSound::_updateStatus() { // If we have a voice, use its status. if( mVoice ) { SFXStatus voiceStatus = mVoice->getStatus(); // Filter out SFXStatusBlocked. if( voiceStatus == SFXStatusBlocked ) _setStatus( SFXStatusPlaying ); else _setStatus( voiceStatus ); return; } // If we're not in a playing state or we're a looping // sound then we don't need to calculate the status. if( isLooping() || mStatus != SFXStatusPlaying ) return; // If we're playing and don't have a voice we // need to decide if the sound is done playing // to ensure proper virtualization of the sound. if( mPlayTimer.getPosition() > mDuration ) { _stop(); _setStatus( SFXStatusStopped ); } }
Int64 DShowAudioSource::readFrames(float* data, UInt32 numChannels, UInt32 numFrames) { memset(data, 0, sizeof(float) * numChannels * numFrames); // Check if we are done decoding... long evCode; mpMediaControl->Run(); HRESULT hr = mpMediaEvent->WaitForCompletion(0, &evCode); if(evCode == EC_COMPLETE) { mEOF = true; } RScopedLock l(&mLock); Int64 framesRead = numFrames; if(mBuffer.size() > 0) { if(mBuffer.size() / mpWaveFormatEx->nChannels < framesRead) { framesRead = mBuffer.size() / mpWaveFormatEx->nChannels; } for(UInt32 j = 0; j < numChannels; ++j) { float *in = NULL; if(mpWaveFormatEx->nChannels == 1) in = &mBuffer[0]; else in = &mBuffer[j]; for(UInt32 i = 0; i < framesRead; ++i) { *(data++) = *in; in += mpWaveFormatEx->nChannels; } } mBuffer.erase(mBuffer.begin(), mBuffer.begin()+(framesRead * mpWaveFormatEx->nChannels)); } mCurrentPosition += framesRead; // Check if we need to decode more data if(mBuffer.size() < numFrames * mpWaveFormatEx->nChannels * 2) { if(mEOF && isLooping()) { setDecoderPosition(0); } } if(mEOF && framesRead == 0) { return -1; } return framesRead; }
void RivenVideo::playBlocking(int32 endTime) { _vm->_cursor->hideCursor(); if (!_playing) { play(); } // Sanity check if (isLooping()) error("Called playBlocking() on a looping video"); bool playTillEnd; if (endTime == -1) { playTillEnd = true; } else { playTillEnd = false; _video->setEndTime(Audio::Timestamp(0, endTime, 600)); } if (playTillEnd) { enable(); } bool continuePlaying = true; while (!endOfVideo() && !_vm->hasGameEnded() && continuePlaying) { // Draw a frame _vm->doFrame(); // Handle skipping if (playTillEnd && _vm->getStack()->keyGetAction() == kKeyActionSkip) { continuePlaying = false; // Seek to the last frame _video->seek(_video->getDuration().addMsecs(-1)); _vm->getStack()->mouseForceUp(); _vm->getStack()->keyResetAction(); } } if (playTillEnd) { disable(); stop(); } // Execute the stored opcode uint16 storedOpcodeMovieSlot = _vm->_scriptMan->getStoredMovieOpcodeSlot(); uint32 storedOpcodeTime = _vm->_scriptMan->getStoredMovieOpcodeTime(); if (_slot == storedOpcodeMovieSlot && getTime() >= storedOpcodeTime) { // CHECKME: Suspicious use of time units _vm->_scriptMan->runStoredMovieOpcode(); } _vm->_cursor->showCursor(); }
// Loads the animation using data from a JSON structure void Animation::deserialize(Json::Value &configData) { std::string frame = DataManager::getString(configData, "frame", getFrameName()); std::string extension = DataManager::getString(configData, "ext", getFrameExtension()); int count = DataManager::getInt (configData, "frames", getFrameCount()); float delay = DataManager::getFloat (configData, "delay", getFrameDelay()); init(frame, extension, count, delay); setName (DataManager::getString (configData, "name", getName())); setLooping (DataManager::getBool (configData, "loop", isLooping())); allowEventGeneration(DataManager::getBool (configData, "alert", isGeneratingEvents())); }
bool SoundEmitter::isFinished() { if (isLooping()) { return false; } if (isActive()) { return getState() == SD_STOPPED_STATE; } if (getState() == SD_STOPPED_STATE) { return true; } // roughly check, in the case the clip do not plays (is not active) return (m_internData.playTimestamp + m_playCheckDifference + static_cast<uint32_t>(getDuration())) <= TimeManager::instance()->getTime(); }
void Fmod4SoundStitching::load() throw (RuntimeException) { FMOD_CREATESOUNDEXINFO exinfo; FMOD_MODE mode = FMOD_OPENUSER; if (is3d()) { mode |= FMOD_3D; } else { mode |= FMOD_2D; } if (isLooping()) { mode |= FMOD_LOOP_NORMAL; } else { mode |= FMOD_LOOP_OFF; } memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); exinfo.defaultfrequency = 44100; exinfo.numsubsounds = getNumSlots(); exinfo.numchannels = is3d() ? 1 : 2; exinfo.format = FMOD_SOUND_FORMAT_PCM16; FMOD_RESULT res = mDriver->_getFmodSystem()->createStream( getSoundResource()->getName().c_str(), mode, &exinfo, &mSound); CHECK_FMOD4_ERRORS(res); int *sentence = new int[getNumSlots()]; for(unsigned int i = 0; i < getNumSlots(); i++) { sentence[i] = i; } res = mSound->setSubSoundSentence(sentence, getNumSlots()); CHECK_FMOD4_ERRORS(res); }
void Source::reset() { alSourcefv(source, AL_POSITION, position); alSourcefv(source, AL_VELOCITY, velocity); alSourcefv(source, AL_DIRECTION, direction); alSourcef(source, AL_PITCH, pitch); alSourcef(source, AL_GAIN, volume); alSourcef(source, AL_MIN_GAIN, minVolume); alSourcef(source, AL_MAX_GAIN, maxVolume); alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance); alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor); alSourcef(source, AL_MAX_DISTANCE, maxDistance); alSourcei(source, AL_LOOPING, (type == TYPE_STATIC) && isLooping() ? AL_TRUE : AL_FALSE); alSourcei(source, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE); alSourcei(source, AL_CONE_INNER_ANGLE, cone.innerAngle); alSourcei(source, AL_CONE_OUTER_ANGLE, cone.outerAngle); alSourcef(source, AL_CONE_OUTER_GAIN, cone.outerVolume); }
AudioFileBufferStatus AudioFile::nextFrame(float **frame) { if (_pimpl->readIndex >= _pimpl->bufferSize) return AudioFileBufferStatusOutOfBounds; *frame = &((_pimpl->bufs[_pimpl->currentBufIndex])[_pimpl->readIndex]); _pimpl->readIndex += _pimpl->sfInfo.channels; _pimpl->samplesRead += _pimpl->sfInfo.channels; if (_pimpl->readIndex >= _pimpl->bufferSize) { if (_pimpl->currentBufIndex == 0) { _pimpl->currentBufIndex = 1; } else { _pimpl->currentBufIndex = 0; } _pimpl->readIndex = 0; if (_pimpl->needsBuffer && !_pimpl->isBuffering) { _pimpl->isBuffering = true; AUtilDispatchThread(file_buffer_worker, _pimpl); } } if (_pimpl->samplesRead >= totalSize()) { if (isLooping()) { _pimpl->samplesRead = 0; } else { BDLog(kAudioFileLoggerPrefix, "Done reading"); return AudioFileBufferStatusDoneReading; } } return AudioFileBufferStatusOK; }
bool BufferingAudioSource::waitForNextAudioBlockReady (const AudioSourceChannelInfo& info, const uint32 timeout) { if (!source || source->getTotalLength() <= 0) return false; if (nextPlayPos + info.numSamples < 0) return true; if (! isLooping() && nextPlayPos > getTotalLength()) return true; uint32 now = Time::getMillisecondCounter(); const uint32 startTime = now; uint32 elapsed = (now >= startTime ? now - startTime : (std::numeric_limits<uint32>::max() - startTime) + now); while (elapsed <= timeout) { { const ScopedLock sl (bufferStartPosLock); const int validStart = static_cast<int> (jlimit (bufferValidStart, bufferValidEnd, nextPlayPos) - nextPlayPos); const int validEnd = static_cast<int> (jlimit (bufferValidStart, bufferValidEnd, nextPlayPos + info.numSamples) - nextPlayPos); if (validStart <= 0 && validStart < validEnd && validEnd >= info.numSamples) return true; } if (elapsed < timeout && (! bufferReadyEvent.wait (static_cast<int> (timeout - elapsed)))) return false; now = Time::getMillisecondCounter(); elapsed = (now >= startTime ? now - startTime : (std::numeric_limits<uint32>::max() - startTime) + now); } return false; }
void Kaboodle::Player::tickerTimeout(void) { if(engine->state() == Stop) { if ( uncompleted ) { stop(); if( isLooping() ) { play(); } else { uncompleted = false; emit completed(); } } if(embedded) { widget->embed(Arts::PlayObject::null()); embedded = false; } } else if(engine->state() != Stop && engine->state() != Empty) { if(!embedded) { widget->embed(engine->playObject()); embedded = true; } emit timeout(); if(extension) emit setStatusBarText(i18n("Playing %1 - %2") .arg(current.prettyURL()) .arg(positionString() + "/" + lengthString())); } updateTitle(); }
/** * @author JoSch * @date 08-03-2008 * @version 1.0 */ void Fmod4SoundStitching::putSoundIntoSlot(unsigned int slot, CeGuiString label) { if (isValid()) { FMOD_MODE mode = FMOD_DEFAULT; if (is3d()) { mode |= FMOD_3D; } else { mode |= FMOD_2D; } if (isLooping()) { mode |= FMOD_LOOP_NORMAL; } else { mode |= FMOD_LOOP_OFF; } FMOD::Sound *sound; FMOD_RESULT result = mDriver->_getFmodSystem()->createStream( mSoundCache[label]->getName().c_str(), mode, NULL, &sound); CHECK_FMOD4_ERRORS(result); if (mSoundSlots[slot] != NULL) { mSoundSlots[slot]->release(); } mSoundSlots[slot] = sound; result = sound->setSubSound(slot, sound); CHECK_FMOD4_ERRORS(result); } }
void SFXSound::_play() { Parent::_play(); if( mVoice ) mVoice->play( isLooping() ); else { // To ensure the fastest possible reaction // to this playback let the system reassign // voices immediately. SFX->_assignVoice( this ); // If we did not get assigned a voice, we'll be // running virtualized. #ifdef DEBUG_SPEW if( !mVoice ) Platform::outputDebugString( "[SFXSound] virtualizing playback of source '%i'", getId() ); #endif } }
int Source::streamAtomic(ALuint buffer, love::sound::Decoder *d) { // Get more sound data. int decoded = std::max(d->decode(), 0); // OpenAL implementations are allowed to ignore 0-size alBufferData calls. if (decoded > 0) { int fmt = getFormat(d->getChannels(), d->getBitDepth()); if (fmt != 0) alBufferData(buffer, fmt, d->getBuffer(), decoded, d->getSampleRate()); else decoded = 0; } if (decoder->isFinished() && isLooping()) { int queued, processed; alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); if (queued > processed) toLoop = queued-processed; else toLoop = MAX_BUFFERS-processed; d->rewind(); } if (toLoop > 0) { if (--toLoop == 0) { offsetSamples = 0; offsetSeconds = 0; } } return decoded; }
//////////////////////////////////////////////////////////////////////////////// // virtual bool LLMediaImplQuickTime::updateMedia() { if ( ! mMovieHandle ) return false; if ( ! mMovieController ) return false; if ( ! mGWorldHandle ) return false; // service QuickTime MoviesTask( mMovieHandle, 0 ); MCIdle( mMovieController ); // update state machine (deals with transport controls for example) processState(); // special code for looping - need to rewind at the end of the movie if ( isLooping() ) { // QT call to see if we are at the end - can't do with controller if ( IsMovieDone( mMovieHandle ) ) { // go back to start rewind(); // kick off new play MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate( mMovieHandle ) ); // set the volume MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); } } return true; }
/** * @author JoSch * @date 07-12-2005 */ void Fmod3SoundSample::load() throw (RuntimeException) { getSoundResource()->load(); DataStreamPtr stream = getSoundResource()->getDataStream(); stream->seek(0); int len = stream->size(); char *data = new char[len]; stream->read(data, len); unsigned int mode = FSOUND_LOADMEMORY; if (is3d()) { mode |= FSOUND_HW3D | FSOUND_FORCEMONO; } else { mode |= FSOUND_HW2D; } if (isLooping()) { mode |= FSOUND_LOOP_NORMAL; } else { mode |= FSOUND_LOOP_OFF; } mSample = FSOUND_Sample_Load(FSOUND_FREE, data, mode, 0, len); if (mSample == 0 && !is3d() ) { mode |= FSOUND_FORCEMONO; mSample = FSOUND_Sample_Load(FSOUND_FREE, data, mode, 0, len); } delete[] data; if( mSample == NULL ) { int err = FSOUND_GetError(); Throw( RuntimeException, "Fmod Error:" + Ogre::StringConverter::toString(err) + " while loading " + getName() ); } }
bool BufferingAudioSource::readNextBufferChunk() { int64 newBVS, newBVE, sectionToReadStart, sectionToReadEnd; { const ScopedLock sl (bufferStartPosLock); if (wasSourceLooping != isLooping()) { wasSourceLooping = isLooping(); bufferValidStart = 0; bufferValidEnd = 0; } newBVS = jmax ((int64) 0, nextPlayPos); newBVE = newBVS + buffer.getNumSamples() - 4; sectionToReadStart = 0; sectionToReadEnd = 0; const int maxChunkSize = 2048; if (newBVS < bufferValidStart || newBVS >= bufferValidEnd) { newBVE = jmin (newBVE, newBVS + maxChunkSize); sectionToReadStart = newBVS; sectionToReadEnd = newBVE; bufferValidStart = 0; bufferValidEnd = 0; } else if (std::abs ((int) (newBVS - bufferValidStart)) > 512 || std::abs ((int) (newBVE - bufferValidEnd)) > 512) { newBVE = jmin (newBVE, bufferValidEnd + maxChunkSize); sectionToReadStart = bufferValidEnd; sectionToReadEnd = newBVE; bufferValidStart = newBVS; bufferValidEnd = jmin (bufferValidEnd, newBVE); } } if (sectionToReadStart == sectionToReadEnd) return false; jassert (buffer.getNumSamples() > 0); const int bufferIndexStart = (int) (sectionToReadStart % buffer.getNumSamples()); const int bufferIndexEnd = (int) (sectionToReadEnd % buffer.getNumSamples()); if (bufferIndexStart < bufferIndexEnd) { readBufferSection (sectionToReadStart, (int) (sectionToReadEnd - sectionToReadStart), bufferIndexStart); } else { const int initialSize = buffer.getNumSamples() - bufferIndexStart; readBufferSection (sectionToReadStart, initialSize, bufferIndexStart); readBufferSection (sectionToReadStart + initialSize, (int) (sectionToReadEnd - sectionToReadStart) - initialSize, 0); } { const ScopedLock sl2 (bufferStartPosLock); bufferValidStart = newBVS; bufferValidEnd = newBVE; } bufferReadyEvent.signal(); return true; }
void Kaboodle::Player::loop(void) { setLooping(!isLooping()); }
bool Source::isFinished() const { return type == TYPE_STATIC ? isStopped() : (isStopped() && !isLooping() && decoder->isFinished()); }
bool SFXSound::_allocVoice( SFXDevice* device ) { // We shouldn't have any existing voice! AssertFatal( !mVoice, "SFXSound::_allocVoice() - Already had a voice!" ); // Must not assign voice to source that isn't playing. AssertFatal( getLastStatus() == SFXStatusPlaying, "SFXSound::_allocVoice() - Source is not playing!" ); // The buffer can be lost when the device is reset // or changed, so initialize it if we have to. If // that fails then we cannot create the voice. if( mBuffer.isNull() ) { SFXProfile* profile = getProfile(); if( profile != NULL ) { SFXBuffer* buffer = profile->getBuffer(); if( buffer ) _setBuffer( buffer ); } if( mBuffer.isNull() ) return false; } // Ask the device for a voice based on this buffer. mVoice = device->createVoice( is3d(), mBuffer ); if( !mVoice ) return false; // Set initial properties. mVoice->setVolume( mPreAttenuatedVolume ); mVoice->setPitch( mEffectivePitch ); mVoice->setPriority( mEffectivePriority ); if( mDescription->mRolloffFactor != -1.f ) mVoice->setRolloffFactor( mDescription->mRolloffFactor ); // Set 3D parameters. if( is3d() ) { // Scatter the position, if requested. Do this only once so // we don't change position when resuming from virtualized // playback. if( !mTransformScattered ) _scatterTransform(); // Set the 3D attributes. setTransform( mTransform ); setVelocity( mVelocity ); _setMinMaxDistance( mMinDistance, mMaxDistance ); _setCone( mConeInsideAngle, mConeOutsideAngle, mConeOutsideVolume ); } // Set reverb, if enabled. if( mDescription->mUseReverb ) mVoice->setReverb( mDescription->mReverb ); // Update the duration... it shouldn't have changed, but // its probably better that we're accurate if it did. mDuration = mBuffer->getDuration(); // If virtualized playback has been started, we transfer its position to the // voice and stop virtualization. const U32 playTime = mPlayTimer.getPosition(); if( playTime > 0 ) { const U32 pos = mBuffer->getFormat().getSampleCount( playTime ); mVoice->setPosition( pos); } mVoice->play( isLooping() ); #ifdef DEBUG_SPEW Platform::outputDebugString( "[SFXSound] allocated voice for source '%i' (pos=%i, 3d=%i, vol=%f)", getId(), playTime, is3d(), mPreAttenuatedVolume ); #endif return true; }
Real SplineTimeBase::infinityMap(Real t) const { if(isLooping()) return beginTime() + Mod(t-beginTime(), length()); else return Min(t,endTime()); }