diff --git a/Engine/source/sfx/media/sfxSndStream.cpp b/Engine/source/sfx/media/sfxSndStream.cpp index eee6d5d69..86c7e20ab 100644 --- a/Engine/source/sfx/media/sfxSndStream.cpp +++ b/Engine/source/sfx/media/sfxSndStream.cpp @@ -33,11 +33,11 @@ bool SFXSndStream::_readHeader() dMemset(&sfinfo, 0, sizeof(SF_INFO)); - vio.get_filelen = sndFileLen; - vio.seek = sndSeek; - vio.read = sndRead; - vio.write = sndWrite; - vio.tell = sndTell; + vio.get_filelen = sndFileLen; + vio.seek = sndSeek; + vio.read = sndRead; + vio.write = sndWrite; + vio.tell = sndTell; vio_data.length = 0; vio_data.offset = 0; @@ -85,6 +85,7 @@ void SFXSndStream::_close() return; sf_close(sndFile); + sndFile = NULL; } SFXSndStream* SFXSndStream::create(Stream* stream) @@ -99,18 +100,40 @@ SFXSndStream* SFXSndStream::create(Stream* stream) void SFXSndStream::reset() { + if (!sndFile) + return; vio_data.offset = 0; + sf_seek(sndFile, 0, SEEK_SET); } U32 SFXSndStream::read(U8* buffer, U32 length) { if (!sndFile) { - Con::errorf("SFXSndStream - read: Called on uninitialized stream."); + Con::errorf("SFXSndStream - read: Called on uninitialized or closed stream."); + return 0; + } + + if (!buffer) + { + Con::errorf("SFXSndStream - read: NULL buffer passed."); + return 0; + } + + const U32 bytesPerSample = mFormat.getBytesPerSample(); + if (bytesPerSample == 0) + { + Con::errorf("SFXSndStream - read: bytesPerSample is zero, format not initialized?"); + return 0; + } + + U32 framesToRead = length / bytesPerSample; + if (framesToRead == 0) + { + Con::errorf("SFXSndStream - read: length %d too small for bytesPerSample %d", length, bytesPerSample); return 0; } - U32 framesToRead = length / mFormat.getBytesPerSample(); U32 framesRead = 0; switch (sfinfo.format & SF_FORMAT_SUBMASK) @@ -136,13 +159,13 @@ U32 SFXSndStream::read(U8* buffer, U32 length) Con::errorf("SFXSndStream - read: %s", sf_strerror(sndFile)); } - // (convert to frames) - number of frames available < MAX_BUFFER? reset - if (((getPosition() / mFormat.getBytesPerSample()) - sfinfo.frames) < MAX_BUFFER) + sf_count_t currentFrame = sf_seek(sndFile, 0, SEEK_CUR); + if (currentFrame >= sfinfo.frames - (sf_count_t)MAX_BUFFER) { - // reset stream - setPosition(0); + sf_seek(sndFile, 0, SEEK_SET); + vio_data.offset = 0; } - + return framesRead * mFormat.getBytesPerSample(); } @@ -221,4 +244,3 @@ sf_count_t SFXSndStream::sndFileLen(void* user_data) return vf->length; } - diff --git a/Engine/source/sfx/sfxProfile.cpp b/Engine/source/sfx/sfxProfile.cpp index 2af2cb6e2..017e37e98 100644 --- a/Engine/source/sfx/sfxProfile.cpp +++ b/Engine/source/sfx/sfxProfile.cpp @@ -275,21 +275,41 @@ void SFXProfile::_onResourceChanged( const Torque::Path& path ) bool SFXProfile::_preloadBuffer() { - AssertFatal( !mDescription->mIsStreaming, "SFXProfile::_preloadBuffer() - must not be called for streaming profiles" ); + AssertFatal(!mDescription->mIsStreaming, "SFXProfile::_preloadBuffer() - must not be called for streaming profiles"); + if (!SFX) + return false; + + if (mFilename == StringTable->EmptyString()) + { + Con::errorf("SFXProfile::_preloadBuffer(%s) - no filename set", getName()); + return false; + } + +#ifdef TORQUE_DEBUG + Con::printf("SFXProfile::_preloadBuffer(%s) - attempting to preload '%s'", getName(), mFilename); +#endif mBuffer = _createBuffer(); - return ( !mBuffer.isNull() ); + if (mBuffer.isNull()) + { + Con::errorf("SFXProfile::_preloadBuffer(%s) - _createBuffer() returned null for '%s'", getName(), mFilename); + return false; + } + + return true; } //----------------------------------------------------------------------------- Resource& SFXProfile::getResource() { - if (!mResource && SFXResource::exists(mFilename)) - mResource = SFXResource::load(mFilename); - else - mResource = NULL; - + if (!mResource) + { + if (SFXResource::exists(mFilename)) + mResource = SFXResource::load(mFilename); + else + Con::errorf("SFXProfile::getResource(%s) - file does not exist: '%s'", getName(), mFilename); + } return mResource; } @@ -317,49 +337,44 @@ SFXBuffer* SFXProfile::getBuffer() SFXBuffer* SFXProfile::_createBuffer() { - SFXBuffer* buffer = 0; - - // Try to create through SFXDevie. - - if( mFilename != StringTable->EmptyString() && SFX ) - { - buffer = SFX->_createBuffer( mFilename, mDescription ); - if( buffer ) - { - #ifdef TORQUE_DEBUG - const SFXFormat& format = buffer->getFormat(); - Con::printf( "%s SFX: %s (%i channels, %i kHz, %.02f sec, %i kb)", - mDescription->mIsStreaming ? "Streaming" : "Loaded", mFilename, - format.getChannels(), - format.getSamplesPerSecond() / 1000, - F32( buffer->getDuration() ) / 1000.0f, - format.getDataLength( buffer->getDuration() ) / 1024 ); - #endif - } - } - - // If that failed, load through SFXResource. - - if( !buffer ) - { - Resource< SFXResource >& resource = getResource(); - if( resource != NULL && SFX ) - { - #ifdef TORQUE_DEBUG - const SFXFormat& format = resource->getFormat(); - Con::printf( "%s SFX: %s (%i channels, %i kHz, %.02f sec, %i kb)", - mDescription->mIsStreaming ? "Streaming" : "Loading", resource->getFileName().c_str(), - format.getChannels(), - format.getSamplesPerSecond(), - F32( resource->getDuration() ) / 1000.0f, - format.getDataLength( resource->getDuration() ) / 1024 ); - #endif + SFXBuffer* buffer = NULL; - ThreadSafeRef< SFXStream > sfxStream = resource->openStream(); - buffer = SFX->_createBuffer( sfxStream, mDescription ); - } + if (mFilename == StringTable->EmptyString()) + { + Con::errorf("SFXProfile::_createBuffer(%s) - mFilename is empty!", getName()); + return NULL; } + if (!SFX) + { + Con::errorf("SFXProfile::_createBuffer(%s) - No SFX system available!", getName()); + return NULL; + } + + if (!SFXResource::exists(mFilename)) + { + Con::errorf("SFXProfile::_createBuffer(%s) - SFXResource::exists() returned false for '%s'", getName(), mFilename); + return NULL; + } + + Resource< SFXResource >& resource = getResource(); + if (resource == NULL) + { + Con::errorf("SFXProfile::_createBuffer(%s) - getResource() returned NULL for '%s'", getName(), mFilename); + return NULL; + } + + ThreadSafeRef< SFXStream > sfxStream = resource->openStream(); + if (!sfxStream) + { + Con::errorf("SFXProfile::_createBuffer(%s) - openStream() returned NULL for '%s'", getName(), mFilename); + return NULL; + } + + buffer = SFX->_createBuffer(sfxStream, mDescription); + if (!buffer) + Con::errorf("SFXProfile::_createBuffer(%s) - Device _createBuffer from stream also failed for '%s'", getName(), mFilename); + return buffer; } diff --git a/Engine/source/sfx/sfxResource.cpp b/Engine/source/sfx/sfxResource.cpp index fa03a9a58..6f03867aa 100644 --- a/Engine/source/sfx/sfxResource.cpp +++ b/Engine/source/sfx/sfxResource.cpp @@ -79,5 +79,9 @@ bool SFXResource::exists( String filename ) ThreadSafeRef SFXResource::openStream() { - return mStream; + // Open a fresh independent stream from the file each time + ThreadSafeRef freshStream = SFXFileStream::create(mFileName); + if (!freshStream) + Con::errorf("SFXResource::openStream() - failed to reopen '%s'", mFileName.c_str()); + return freshStream; }