hsBool plWin32GroupedSound::LoadSound( hsBool is3D ) { if( fFailed ) return false; if( fPriority > plgAudioSys::GetPriorityCutoff() ) return false; // Don't set the failed flag, just return if( !plgAudioSys::Active() || fDSoundBuffer != nil ) return false; // Debug flag #1 if( fChannelSelect > 0 && plgAudioSys::IsDebugFlagSet( plgAudioSys::kDisableRightSelect ) ) { // Force a fail fFailed = true; return false; } // We need it to be resident to read in plSoundBuffer::ELoadReturnVal retVal = IPreLoadBuffer(true); plSoundBuffer *buffer = (plSoundBuffer *)fDataBufferKey->ObjectIsLoaded(); if(!buffer) { return plSoundBuffer::kError; } if( retVal == plSoundBuffer::kPending) // we are still reading data. { return true; } // We need it to be resident to read in if( retVal == plSoundBuffer::kError) { plString str = plString::Format("Unable to open .wav file %s", fDataBufferKey ? fDataBufferKey->GetName().c_str() : "nil"); IPrintDbgMessage( str.c_str(), true ); fFailed = true; return false; } SetProperty( kPropIs3DSound, is3D ); plWAVHeader header = buffer->GetHeader(); // Debug flag #2 if( fChannelSelect == 0 && header.fNumChannels > 1 && plgAudioSys::IsDebugFlagSet( plgAudioSys::kDisableLeftSelect ) ) { // Force a fail fFailed = true; return false; } // Calculate the maximum size for our buffer. This will be the length of the longest sound we're going to // have to play. uint16_t i; uint32_t maxSoundSize, len; for( i = 1, maxSoundSize = 0; i < fStartPositions.GetCount(); i++ ) { len = fStartPositions[ i ] - fStartPositions[ i - 1 ]; if( len > maxSoundSize ) maxSoundSize = len; } len = buffer->GetDataLength() - fStartPositions[ fStartPositions.GetCount() - 1 ]; if( len > maxSoundSize ) maxSoundSize = len; // Based on that, allocate our buffer uint32_t bufferSize = maxSoundSize - ( maxSoundSize % header.fBlockAlign ); if( header.fNumChannels > 1 && is3D ) { // We can only do a single channel of 3D sound. So copy over one (later) bufferSize /= header.fNumChannels; header.fBlockAlign /= header.fNumChannels; header.fAvgBytesPerSec /= header.fNumChannels; header.fNumChannels = 1; } fNumDestChannels = (uint8_t)(header.fNumChannels); fNumDestBytesPerSample = (uint8_t)(header.fBlockAlign); // Create our DSound buffer (or rather, the wrapper around it) fDSoundBuffer = new plDSoundBuffer( bufferSize, header, is3D, IsPropertySet( kPropLooping ), true ); if( !fDSoundBuffer->IsValid() ) { char str[256]; sprintf(str, "Can't create sound buffer for %s.wav. This could happen if the wav file is a stereo file. Stereo files are not supported on 3D sounds. If the file is not stereo then please report this error.", GetFileName()); IPrintDbgMessage( str, true ); fFailed = true; delete fDSoundBuffer; fDSoundBuffer = nil; return false; } IRefreshEAXSettings( true ); // Fill the buffer with whatever our current sound is. IFillCurrentSound( 0 ); // Logging plString str = plString::Format(" Grouped %s %s allocated (%d msec).", buffer->GetFileName() != nil ? "file" : "buffer", buffer->GetFileName() != nil ? buffer->GetFileName() : buffer->GetKey()->GetUoid().GetObjectName().c_str(), //fDSoundBuffer->IsHardwareAccelerated() ? "hardware" : "software", //fDSoundBuffer->IsStaticVoice() ? "static" : "dynamic", #ifdef PL_PROFILE_ENABLED gProfileVarStaticSndShoveTime.GetValue() ); #else 0 ); #endif IPrintDbgMessage( str.c_str() ); if( GetKey() != nil && GetKeyName().Find( "Footstep" ) >= 0 ) ; else plStatusLog::AddLineS( "audioTimes.log", "%s (%s)", str.c_str(), GetKey() ? GetKeyName().c_str() : "unkeyed" ); fTotalBytes = bufferSize; plProfile_NewMem( MemSounds, fTotalBytes ); // All done! // if( fLoadFromDiskOnDemand ) // IUnloadDataBuffer(); FreeSoundData(); return true; }
bool plWin32StaticSound::LoadSound( bool is3D ) { if (fFailed) return false; if( fPriority > plgAudioSys::GetPriorityCutoff() ) return false; // Don't set the failed flag, just return if (plgAudioSys::Active() && !fDSoundBuffer) { // Debug flag #1 if( fChannelSelect > 0 && plgAudioSys::IsDebugFlagSet( plgAudioSys::kDisableRightSelect ) ) { // Force a fail fFailed = true; return false; } // We need it to be resident to read in plSoundBuffer::ELoadReturnVal retVal = IPreLoadBuffer(true); plSoundBuffer *buffer = (plSoundBuffer *)fDataBufferKey->ObjectIsLoaded(); if(!buffer) { return plSoundBuffer::kError; } if( retVal == plSoundBuffer::kPending) // we are still reading data. { return true; } if( retVal == plSoundBuffer::kError ) { plString str = plFormat("Unable to open .wav file {}", fDataBufferKey ? fDataBufferKey->GetName() : "nil"); IPrintDbgMessage( str.c_str(), true ); fFailed = true; return false; } SetProperty( kPropIs3DSound, is3D ); plWAVHeader header = buffer->GetHeader(); // Debug flag #2 if( fChannelSelect == 0 && header.fNumChannels > 1 && plgAudioSys::IsDebugFlagSet( plgAudioSys::kDisableLeftSelect ) ) { // Force a fail fFailed = true; return false; } uint32_t bufferSize = buffer->GetDataLength(); if( header.fNumChannels > 1 && is3D ) { // We can only do a single channel of 3D sound. So copy over one (later) bufferSize /= header.fNumChannels; header.fBlockAlign /= header.fNumChannels; header.fAvgBytesPerSec /= header.fNumChannels; header.fNumChannels = 1; } bool tryStatic = true; // If we want FX, we can't use a static voice, but EAX doesn't fit under that limitation :) if( 0 ) tryStatic = false; // Create our DSound buffer (or rather, the wrapper around it) fDSoundBuffer = new plDSoundBuffer( bufferSize, header, is3D, IsPropertySet( kPropLooping ), tryStatic ); if( !fDSoundBuffer->IsValid() ) { plString str = plFormat("Can't create sound buffer for {}.wav. This could happen if the wav file is a stereo file." " Stereo files are not supported on 3D sounds. If the file is not stereo then please report this error.", GetFileName()); IPrintDbgMessage(str.c_str(), true); fFailed = true; delete fDSoundBuffer; fDSoundBuffer = nil; return false; } plProfile_BeginTiming( StaticSndShoveTime ); if(!fDSoundBuffer->FillBuffer(buffer->GetData(), buffer->GetDataLength(), &header)) { delete fDSoundBuffer; fDSoundBuffer = nil; plStatusLog::AddLineS("audio.log", "Could not play static sound, no voices left %s", GetKeyName().c_str()); return false; } plProfile_EndTiming( StaticSndShoveTime ); IRefreshEAXSettings( true ); fTotalBytes = bufferSize; plProfile_NewMem(MemSounds, fTotalBytes); // get pertinent info float length = (float)bufferSize / (float)header.fAvgBytesPerSec; SetLength(length); if( fLoadFromDiskOnDemand && !IsPropertySet( kPropLoadOnlyOnCall ) ) FreeSoundData(); return true; } return false; }
bool plWin32StreamingSound::LoadSound( bool is3D ) { if( fFailed ) return false; if( !plgAudioSys::Active() || fDSoundBuffer ) return false; if( fPriority > plgAudioSys::GetPriorityCutoff() ) return false; // Don't set the failed flag, just return // Debug flag #1 if( is3D && fChannelSelect > 0 && plgAudioSys::IsDebugFlagSet( plgAudioSys::kDisableRightSelect ) ) { // Force a fail fFailed = true; return false; } plSoundBuffer::ELoadReturnVal retVal = IPreLoadBuffer(true); if(retVal == plSoundBuffer::kPending) return true; if( retVal == plSoundBuffer::kError ) { plString str = plString::Format( "Unable to open streaming source %s", fDataBufferKey->GetName().c_str() ); IPrintDbgMessage( str.c_str(), true ); fFailed = true; return false; } SetProperty( kPropIs3DSound, is3D ); plWAVHeader header = fDataStream->GetHeader(); uint32_t bufferSize = (uint32_t)(fBufferLengthInSecs * header.fAvgBytesPerSec); // Debug flag #2 if( is3D && fChannelSelect == 0 && header.fNumChannels > 1 && plgAudioSys::IsDebugFlagSet( plgAudioSys::kDisableLeftSelect ) ) { // Force a fail fFailed = true; return false; } if( header.fNumChannels > 1 && is3D ) { // We can only do a single channel of 3D sound. So copy over one (later) bufferSize /= header.fNumChannels; header.fBlockAlign /= header.fNumChannels; header.fAvgBytesPerSec /= header.fNumChannels; header.fNumChannels = 1; } // Actually create the buffer now (always looping) fDSoundBuffer = new plDSoundBuffer( bufferSize, header, is3D, IsPropertySet(kPropLooping), false, true ); if( !fDSoundBuffer->IsValid() ) { fDataStream->Close(); delete fDataStream; fDataStream = nil; delete fDSoundBuffer; fDSoundBuffer = nil; plString str = plString::Format("Can't create sound buffer for %s.wav. This could happen if the wav file is a stereo file." " Stereo files are not supported on 3D sounds. If the file is not stereo then please report this error.", GetFileName().AsString().c_str()); IPrintDbgMessage(str.c_str(), true); fFailed = true; return false; } fTotalBytes = (uint32_t)bufferSize; plProfile_NewMem(MemSounds, fTotalBytes); plSoundBuffer *buffer = (plSoundBuffer *)fDataBufferKey->ObjectIsLoaded(); if(!buffer) return false; bool setupSource = true; if(!buffer->GetData() || fStartPos) { if(fStartPos && fStartPos <= fDataStream->NumBytesLeft()) { fDataStream->SetPosition(fStartPos); plStatusLog::AddLineS("syncaudio.log", "startpos %d", fStartPos); } // if we get here we are not starting from the beginning of the sound. We still have an audio loaded and need to pick up where we left off if(!fDSoundBuffer->SetupStreamingSource(fDataStream)) { setupSource = false; } } else { // this sound is starting from the beginning. Get the data and start it. if(!fDSoundBuffer->SetupStreamingSource(buffer->GetData(), buffer->GetAsyncLoadLength())) { setupSource = false; } } if(!setupSource) { fDataStream->Close(); delete fDataStream; fDataStream = nil; delete fDSoundBuffer; fDSoundBuffer = nil; plStatusLog::AddLineS("audio.log", "Could not play streaming sound, no voices left %s", GetKeyName().c_str()); return false; } FreeSoundData(); IRefreshEAXSettings( true ); // Debug info char str[ 256 ]; snprintf( str, arrsize(str), " Streaming %s.", fSrcFilename.AsString().c_str() ); IPrintDbgMessage( str ); plStatusLog::AddLineS( "audioTimes.log", 0xffffffff, "Streaming %4.2f secs of %s", fDataStream->GetLengthInSecs(), GetKey()->GetUoid().GetObjectName().c_str() ); // Get pertinent info SetLength( (float)fDataStream->GetLengthInSecs() ); // Set up our deswizzler, if necessary delete fDeswizzler; if( fDataStream->GetHeader().fNumChannels != header.fNumChannels ) fDeswizzler = new plSoundDeswizzler( (uint32_t)(fBufferLengthInSecs * fDataStream->GetHeader().fAvgBytesPerSec), (uint8_t)(fDataStream->GetHeader().fNumChannels), header.fBitsPerSample / 8 ); else fDeswizzler = nil; // LEAVE THE WAV FILE OPEN! (We *are* streaming, after all :) return true; }