void SoundSource::PlayLockless(const SharedPtr<SoundStream>& stream) { // Reset the time position in any case timePosition_ = 0.0f; if (stream) { // Setup the stream buffer unsigned sampleSize = stream->GetSampleSize(); unsigned streamBufferSize = sampleSize * stream->GetIntFrequency() * STREAM_BUFFER_LENGTH / 1000; streamBuffer_ = new Sound(context_); streamBuffer_->SetSize(streamBufferSize); streamBuffer_->SetFormat(stream->GetIntFrequency(), stream->IsSixteenBit(), stream->IsStereo()); streamBuffer_->SetLooped(true); soundStream_ = stream; unusedStreamSize_ = 0; position_ = streamBuffer_->GetStart(); fractPosition_ = 0; sendFinishedEvent_ = true; return; } // If stream pointer is null, stop playback StopLockless(); }
void SoundSource::Update(float timeStep) { if (!audio_ || !IsEnabledEffective()) return; // If there is no actual audio output, perform fake mixing into a nonexistent buffer to check stopping/looping if (!audio_->IsInitialized()) MixNull(timeStep); // Free the stream if playback has stopped if (soundStream_ && !position_) StopLockless(); bool playing = IsPlaying(); if (!playing && sendFinishedEvent_) { sendFinishedEvent_ = false; // Make a weak pointer to self to check for destruction during event handling WeakPtr<SoundSource> self(this); soundFinished(node_,this,sound_); //TODO: verify same semantics as original : node_->SendEvent(E_SOUNDFINISHED, eventData); if (self.Expired()) return; DoAutoRemove(autoRemove_); } }
void SoundSource::Stop() { if (!audio_) return; // If sound source is currently playing, have to lock the audio mutex if (position_) { MutexLock lock(audio_->GetMutex()); StopLockless(); } else StopLockless(); MarkNetworkUpdate(); }
void SoundSource::PlayLockless(Sound* sound) { // Reset the time position in any case timePosition_ = 0.0f; if (sound) { if (!sound->IsCompressed()) { // Uncompressed sound start signed char* start = sound->GetStart(); if (start) { // Free existing stream & stream buffer if any soundStream_.Reset(); streamBuffer_.Reset(); sound_ = sound; position_ = start; fractPosition_ = 0; return; } } else { // Compressed sound start PlayLockless(sound->GetDecoderStream()); sound_ = sound; return; } } // If sound pointer is null or if sound has no data, stop playback StopLockless(); sound_.Reset(); }
void SoundSource::Update(float timeStep) { if (!audio_ || !IsEnabledEffective()) return; // If there is no actual audio output, perform fake mixing into a nonexistent buffer to check stopping/looping if (!audio_->IsInitialized()) MixNull(timeStep); // Free the stream if playback has stopped if (soundStream_ && !position_) StopLockless(); // Check for autoremove if (autoRemove_) { if (!IsPlaying()) { autoRemoveTimer_ += timeStep; if (autoRemoveTimer_ > AUTOREMOVE_DELAY) { Remove(); // Note: this object is now deleted, so only returning immediately is safe return; } } else autoRemoveTimer_ = 0.0f; } }
void SoundSource::Stop() { if (!audio_) return; // If sound source is currently playing, have to lock the audio mutex if (position_) { MutexLock lock(audio_->GetMutex()); StopLockless(); } // Free the compressed sound decoder now if any FreeDecoder(); MarkNetworkUpdate(); }