The-Simpsons-Hit-and-Run/game/code/sound/simpsonssoundplayer.cpp

539 lines
16 KiB
C++

//=============================================================================
// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
//
// File: simpsonssoundplayer.cpp
//
// Description: Implement SimpsonsSoundPlayer class, which interacts with
// the sound renderer to play sounds, and tracks the player
// resources in use.
//
// History: 29/06/2002 + Created -- Darren
//
//=============================================================================
//========================================
// System Includes
//========================================
//========================================
// Project Includes
//========================================
#include <sound/simpsonssoundplayer.h>
#include <sound/soundmanager.h>
#include <sound/soundloader.h>
#include <sound/soundrenderercallback.h>
#include <sound/soundrenderer/soundrenderingmanager.h>
#include <sound/soundrenderer/soundresourcemanager.h>
#include <sound/soundrenderer/soundallocatedresource.h>
#include <sound/soundrenderer/playermanager.h>
#include <sound/soundrenderer/idasoundresource.h>
#include <memory/srrmemory.h>
//******************************************************************************
//
// Global Data, Local Data, Local Classes
//
//******************************************************************************
unsigned int SimpsonsSoundPlayer::s_playersCreated = 0;
unsigned int SimpsonsSoundPlayer::s_clipPlayersInUse = 0;
unsigned int SimpsonsSoundPlayer::s_streamPlayersInUse = 0;
Sound::daSoundResourceManager* SimpsonsSoundPlayer::s_resourceManager = NULL;
Sound::daSoundPlayerManager* SimpsonsSoundPlayer::s_playerManager = NULL;
SoundLoader* SimpsonsSoundPlayer::s_soundLoader = NULL;
//
// Limits on the number of players that can be playing clips/streams at once.
// Numbers are arbitrary and subject to experimentation
//
static const unsigned int s_maxActiveClipPlayersAllowed = 25;
static const unsigned int s_maxActiveStreamPlayersAllowed = 8;
//******************************************************************************
//
// Public Member Functions
//
//******************************************************************************
//==============================================================================
// SimpsonsSoundPlayer::SimpsonsSoundPlayer
//==============================================================================
// Description: Constructor.
//
// Parameters: None.
//
// Return: N/A.
//
//==============================================================================
SimpsonsSoundPlayer::SimpsonsSoundPlayer() :
m_playa( NULL ),
m_callback( NULL )
{
m_Type = Type_NonPositional;
//
// Get resource manager ptr and sound loader ptr if that hasn't been done yet
//
if( s_resourceManager == NULL )
{
s_resourceManager = Sound::daSoundRenderingManagerGet()->GetResourceManager();
}
if( s_playerManager == NULL )
{
s_playerManager = Sound::daSoundRenderingManagerGet()->GetPlayerManager();
}
if( s_soundLoader == NULL )
{
s_soundLoader = SoundManager::GetInstance()->GetSoundLoader();
}
//
// Update statistics
//
++s_playersCreated;
}
//==============================================================================
// SimpsonsSoundPlayer::~SimpsonsSoundPlayer
//==============================================================================
// Description: Destructor.
//
// Parameters: None.
//
// Return: N/A.
//
//==============================================================================
SimpsonsSoundPlayer::~SimpsonsSoundPlayer()
{
//
// Update statistics
//
--s_playersCreated;
if( m_callback != NULL )
{
m_callback->CancelGameCallbackAndRelease();
}
rAssert( m_playa == NULL );
}
//=============================================================================
// SimpsonsSoundPlayer::PlaySound
//=============================================================================
// Description: Play the sound resource with the given name
//
// Parameters: resourceName - string with name of resource to play
// callback - optional callback on playback completion
//
// Return: true if sound could be played, false otherwise
//
//=============================================================================
bool SimpsonsSoundPlayer::PlaySound( const char* resourceName,
SimpsonsSoundPlayerCallback* callback )
{
return( PlaySound( ::radMakeKey32( resourceName ), callback ) );
}
//=============================================================================
// SimpsonsSoundPlayer::PlayResource
//=============================================================================
// Description: Play the sound resource
//
// Parameters: resource - resource to play
// callback - object to notify when we're done
//
// Return: true if sound could be played, false otherwise
//
//=============================================================================
bool SimpsonsSoundPlayer::PlayResource( IDaSoundResource* resource,
SimpsonsSoundPlayerCallback* callback /* = NULL */ )
{
bool canPlay;
canPlay = QueueSound( resource, callback );
if( canPlay )
{
PlayQueuedSound();
}
return( canPlay );
}
//=============================================================================
// SimpsonsSoundPlayer::PlaySound
//=============================================================================
// Description: Comment
//
// Parameters: resourceKey - hashed value of the name of the sound resource
// to play
//
// Return: true if sound could be played, false otherwise
//
//=============================================================================
bool SimpsonsSoundPlayer::PlaySound( Sound::daResourceKey resourceKey,
SimpsonsSoundPlayerCallback* callback )
{
IDaSoundResource* resource;
bool retVal;
resource = s_resourceManager->FindResource( resourceKey );
if( resource != NULL )
{
retVal = PlayResource( resource, callback );
}
else
{
rDebugString( "Tried to play missing sound resource\n" );
retVal = false;
}
return( retVal );
}
//=============================================================================
// SimpsonsSoundPlayer::QueueSound
//=============================================================================
// Description: Queue up a sound for playback, but don't play it. Useful
// for streamed dialog
//
// Parameters: resourceName - name of sound resource to queue
// callback - playback completion callback, unused if NULL
// playUnbuffered - if streamer, don't use buffered data source
//
// Return: true if sound could be played, false otherwise
//
//=============================================================================
bool SimpsonsSoundPlayer::QueueSound( radKey32 resourceID,
SimpsonsSoundPlayerCallback* callback )
{
IDaSoundResource* resource = s_resourceManager->FindResource( resourceID );
if( resource != NULL )
{
return( QueueSound( resource, callback ) );
}
else
{
rDebugPrintf( "Couldn't play sound resource ID %d\n", resourceID );
return( false );
}
}
//=============================================================================
// SimpsonsSoundPlayer::QueueSound
//=============================================================================
// Description: Queue up a sound for playback, but don't play it. Useful
// for streamed dialog
//
// Parameters: resource - sound resource to queue
// callback - playback completion callback, unused if NULL
// playUnbuffered - if streamer, don't use buffered data source
//
// Return: true if sound could be played, false otherwise
//
//=============================================================================
bool SimpsonsSoundPlayer::QueueSound( IDaSoundResource* resource,
SimpsonsSoundPlayerCallback* callback )
{
if( m_playa != NULL )
{
rDebugString( "Dropped sound, player busy\n" );
return( false );
}
//
// Make sure we haven't maxed our limit on playback of this type of
// resource
//
if( resource->GetType() == IDaSoundResource::CLIP )
{
if( s_clipPlayersInUse < s_maxActiveClipPlayersAllowed )
{
++s_clipPlayersInUse;
}
else
{
rAssertMsg( false, "Reached maximum allowable number of clip players\n" );
return( false );
}
}
else
{
rAssert( resource->GetType() == IDaSoundResource::STREAM );
if( s_streamPlayersInUse < s_maxActiveStreamPlayersAllowed )
{
++s_streamPlayersInUse;
}
else
{
rAssertMsg( false, "Reached maximum allowable number of stream players\n" );
return( false );
}
}
s_playerManager->CaptureFreePlayer( &m_playa,
resource,
Type_Positional == m_Type );
rAssert( m_playa != NULL );
//
// Reset trim, just to be safe
//
m_playa->SetExternalTrim( 1.0f );
//
// Create a callback object and point it toward whoever wants the callback
//
if( ( callback != NULL ) && ( m_callback == NULL ) )
{
m_callback = new(GMA_TEMP) SoundRenderingPlayerCallback( *this, callback );
m_playa->RegisterSoundPlayerStateCallback( m_callback, NULL );
}
return( true );
}
//=============================================================================
// SimpsonsSoundPlayer::PlayQueuedSound
//=============================================================================
// Description: Play the sound we've queued for playback
//
// Parameters: callback - callback to trigger on playback completion, ignored
// if NULL
//
// Return: void
//
//=============================================================================
void SimpsonsSoundPlayer::PlayQueuedSound( SimpsonsSoundPlayerCallback* callback )
{
rAssert( m_playa != NULL );
//
// Play should not get stuck on pauses. If this causes problems,
// then I'll have to figure out how to make 100% sure that all
// paused streams (e.g. NIS) get unpaused in a proper fashion
//
if( m_playa->IsPaused() )
{
m_playa->UberContinue();
}
m_playa->Play();
//
// If requested, create a callback object and point it toward whoever
// wants the callback
//
if( m_callback == NULL )
{
m_callback = new(GMA_TEMP) SoundRenderingPlayerCallback( *this, callback );
m_playa->RegisterSoundPlayerStateCallback( m_callback, NULL );
}
}
//=============================================================================
// SimpsonsSoundPlayer::OnPlaybackComplete
//=============================================================================
// Description: Callback from the sound renderer callback object when the
// clip stops playback (not called for looping clips)
//
// Parameters: None
//
// Return: void
//
//=============================================================================
void SimpsonsSoundPlayer::OnPlaybackComplete()
{
dumpSoundPlayer();
}
//=============================================================================
// SimpsonsSoundPlayer::Stop
//=============================================================================
// Description: Stop playing sound.
//
// Parameters: None
//
// Return: void
//
//=============================================================================
void SimpsonsSoundPlayer::Stop()
{
if( m_playa != NULL )
{
//
// Stop() doesn't seem to play well with paused players. They tend
// to remain paused when you reuse them later.
//
if( m_playa->IsPaused() )
{
m_playa->Continue();
}
m_playa->Stop();
if( m_playa != NULL )
{
//
// The player didn't get released because we don't have
// a callback set (presumably), so we do it ourselves
//
dumpSoundPlayer();
}
rAssert( m_playa == NULL );
}
}
//=============================================================================
// SimpsonsSoundPlayer::Pause
//=============================================================================
// Description: Pause the sound player
//
// Parameters: None
//
// Return: void
//
//=============================================================================
void SimpsonsSoundPlayer::Pause()
{
if( m_playa != NULL )
{
m_playa->Pause();
}
}
//=============================================================================
// SimpsonsSoundPlayer::Continue
//=============================================================================
// Description: Unpause the sound player
//
// Parameters: None
//
// Return: void
//
//=============================================================================
void SimpsonsSoundPlayer::Continue()
{
if( m_playa != NULL )
{
m_playa->Continue();
}
}
//=============================================================================
// SimpsonsSoundPlayer::IsPaused
//=============================================================================
// Description: Indicate whether the player is paused
//
// Parameters: None
//
// Return: true if paused, false if not or player unused
//
//=============================================================================
bool SimpsonsSoundPlayer::IsPaused()
{
if( m_playa != NULL )
{
return( m_playa->IsPaused() );
}
else
{
return( false );
}
}
//=============================================================================
// SimpsonsSoundPlayer::SetPitch
//=============================================================================
// Description: Set the pitch of the currently playing clip
//
// Parameters: pitch - pitch setting to apply
//
// Return: void
//
//=============================================================================
void SimpsonsSoundPlayer::SetPitch( float pitch )
{
if( m_playa != NULL )
{
m_playa->SetPitch( pitch );
}
else
{
rDebugString( "Can't set pitch without associated player\n" );
}
}
//=============================================================================
// SimpsonsSoundPlayer::SetTrim
//=============================================================================
// Description: Set the trim of the currently playing clip
//
// Parameters: trim - trim setting to apply
//
// Return: void
//
//=============================================================================
void SimpsonsSoundPlayer::SetTrim( float trim )
{
if( m_playa != NULL )
{
m_playa->SetExternalTrim( trim );
}
else
{
rDebugString( "Can't set trim without associated player\n" );
}
}
//******************************************************************************
//
// Private Member Functions
//
//******************************************************************************
//=============================================================================
// SimpsonsSoundPlayer::dumpSoundPlayer
//=============================================================================
// Description: To be called when we're done with the sound renderer's player
//
// Parameters: None
//
// Return: void
//
//=============================================================================
void SimpsonsSoundPlayer::dumpSoundPlayer()
{
if( m_callback )
{
m_callback->CancelGameCallbackAndRelease();
m_playa->UnregisterSoundPlayerStateCallback( m_callback, NULL );
m_callback = NULL;
}
if( m_playa->GetPlayerType() == IDaSoundResource::CLIP )
{
--s_clipPlayersInUse;
}
else
{
rAssert( m_playa->GetPlayerType() != IDaSoundResource::UNKNOWN );
--s_streamPlayersInUse;
}
if( m_playa->IsCaptured() )
{
m_playa->UnCapture();
}
m_playa = NULL;
}