|
|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
|
|
//
|
|
|
|
// Purpose: DLL interface for low-level sound utilities
|
|
|
|
//
|
|
|
|
//===========================================================================//
|
|
|
|
|
|
|
|
#include "soundsystem/isoundsystem.h"
|
|
|
|
#include "filesystem.h"
|
|
|
|
#include "tier1/strtools.h"
|
|
|
|
#include "tier1/convar.h"
|
|
|
|
#include "mathlib/mathlib.h"
|
|
|
|
#include "soundsystem/snd_device.h"
|
|
|
|
#include "datacache/idatacache.h"
|
|
|
|
#include "soundchars.h"
|
|
|
|
#include "tier1/utldict.h"
|
|
|
|
#include "snd_wave_source.h"
|
|
|
|
#include "snd_dev_wave.h"
|
|
|
|
#include "tier2/tier2.h"
|
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// External interfaces
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
IAudioDevice *g_pAudioDevice = NULL;
|
|
|
|
ISoundSystem *g_pSoundSystem = NULL;
|
|
|
|
IDataCache *g_pDataCache = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Globals
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
int g_nSoundFrameCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: DLL interface for low-level sound utilities
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class CSoundSystem : public CTier2AppSystem< ISoundSystem >
|
|
|
|
{
|
|
|
|
typedef CTier2AppSystem< ISoundSystem > BaseClass;
|
|
|
|
|
|
|
|
public:
|
|
|
|
// Inherited from IAppSystem
|
|
|
|
virtual bool Connect( CreateInterfaceFn factory );
|
|
|
|
virtual void Disconnect();
|
|
|
|
virtual void *QueryInterface( const char *pInterfaceName );
|
|
|
|
virtual InitReturnVal_t Init();
|
|
|
|
virtual void Shutdown();
|
|
|
|
|
|
|
|
void Update( float dt );
|
|
|
|
void Flush( void );
|
|
|
|
|
|
|
|
CAudioSource *FindOrAddSound( const char *filename );
|
|
|
|
CAudioSource *LoadSound( const char *wavfile );
|
|
|
|
void PlaySound( CAudioSource *source, float volume, CAudioMixer **ppMixer );
|
|
|
|
|
|
|
|
bool IsSoundPlaying( CAudioMixer *pMixer );
|
|
|
|
CAudioMixer *FindMixer( CAudioSource *source );
|
|
|
|
|
|
|
|
void StopAll( void );
|
|
|
|
void StopSound( CAudioMixer *mixer );
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct CSoundFile
|
|
|
|
{
|
|
|
|
char filename[ 512 ];
|
|
|
|
CAudioSource *source;
|
|
|
|
time_t filetime;
|
|
|
|
};
|
|
|
|
|
|
|
|
IAudioDevice *m_pAudioDevice;
|
|
|
|
float m_flElapsedTime;
|
|
|
|
CUtlVector < CSoundFile > m_ActiveSounds;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Singleton interface
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
static CSoundSystem s_SoundSystem;
|
|
|
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CSoundSystem, ISoundSystem, SOUNDSYSTEM_INTERFACE_VERSION, s_SoundSystem );
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Connect, disconnect
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool CSoundSystem::Connect( CreateInterfaceFn factory )
|
|
|
|
{
|
|
|
|
if ( !BaseClass::Connect( factory ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
g_pDataCache = (IDataCache*)factory( DATACACHE_INTERFACE_VERSION, NULL );
|
|
|
|
g_pSoundSystem = this;
|
|
|
|
return (g_pFullFileSystem != NULL) && (g_pDataCache != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSoundSystem::Disconnect()
|
|
|
|
{
|
|
|
|
g_pSoundSystem = NULL;
|
|
|
|
g_pDataCache = NULL;
|
|
|
|
BaseClass::Disconnect();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Query interface
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void *CSoundSystem::QueryInterface( const char *pInterfaceName )
|
|
|
|
{
|
|
|
|
if (!Q_strncmp( pInterfaceName, SOUNDSYSTEM_INTERFACE_VERSION, Q_strlen(SOUNDSYSTEM_INTERFACE_VERSION) + 1))
|
|
|
|
return (ISoundSystem*)this;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Init, shutdown
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
InitReturnVal_t CSoundSystem::Init()
|
|
|
|
{
|
|
|
|
InitReturnVal_t nRetVal = BaseClass::Init();
|
|
|
|
if ( nRetVal != INIT_OK )
|
|
|
|
return nRetVal;
|
|
|
|
|
|
|
|
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
|
|
|
|
m_flElapsedTime = 0.0f;
|
|
|
|
m_pAudioDevice = Audio_CreateWaveDevice();
|
|
|
|
if ( !m_pAudioDevice->Init() )
|
|
|
|
return INIT_FAILED;
|
|
|
|
|
|
|
|
return INIT_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSoundSystem::Shutdown()
|
|
|
|
{
|
|
|
|
Msg( "Removing %i sounds\n", m_ActiveSounds.Size() );
|
|
|
|
for ( int i = 0 ; i < m_ActiveSounds.Size(); i++ )
|
|
|
|
{
|
|
|
|
CSoundFile *p = &m_ActiveSounds[ i ];
|
|
|
|
Msg( "Removing sound: %s\n", p->filename );
|
|
|
|
delete p->source;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_ActiveSounds.RemoveAll();
|
|
|
|
|
|
|
|
if ( m_pAudioDevice )
|
|
|
|
{
|
|
|
|
m_pAudioDevice->Shutdown();
|
|
|
|
delete m_pAudioDevice;
|
|
|
|
}
|
|
|
|
|
|
|
|
BaseClass::Shutdown();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CAudioSource *CSoundSystem::FindOrAddSound( const char *filename )
|
|
|
|
{
|
|
|
|
CSoundFile *s;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
for ( i = 0; i < m_ActiveSounds.Size(); i++ )
|
|
|
|
{
|
|
|
|
s = &m_ActiveSounds[ i ];
|
|
|
|
Assert( s );
|
|
|
|
if ( !stricmp( s->filename, filename ) )
|
|
|
|
{
|
|
|
|
time_t filetime = g_pFullFileSystem->GetFileTime( filename );
|
|
|
|
if ( filetime != s->filetime )
|
|
|
|
{
|
|
|
|
Msg( "Reloading sound %s\n", filename );
|
|
|
|
delete s->source;
|
|
|
|
s->source = LoadSound( filename );
|
|
|
|
s->filetime = filetime;
|
|
|
|
}
|
|
|
|
return s->source;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
i = m_ActiveSounds.AddToTail();
|
|
|
|
s = &m_ActiveSounds[ i ];
|
|
|
|
strcpy( s->filename, filename );
|
|
|
|
s->source = LoadSound( filename );
|
|
|
|
s->filetime = g_pFullFileSystem->GetFileTime( filename );
|
|
|
|
|
|
|
|
return s->source;
|
|
|
|
}
|
|
|
|
|
|
|
|
CAudioSource *CSoundSystem::LoadSound( const char *wavfile )
|
|
|
|
{
|
|
|
|
if ( !m_pAudioDevice )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
CAudioSource *wave = AudioSource_Create( wavfile );
|
|
|
|
return wave;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSoundSystem::PlaySound( CAudioSource *source, float volume, CAudioMixer **ppMixer )
|
|
|
|
{
|
|
|
|
if ( ppMixer )
|
|
|
|
{
|
|
|
|
*ppMixer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_pAudioDevice )
|
|
|
|
{
|
|
|
|
CAudioMixer *mixer = source->CreateMixer();
|
|
|
|
if ( ppMixer )
|
|
|
|
{
|
|
|
|
*ppMixer = mixer;
|
|
|
|
}
|
|
|
|
mixer->SetVolume( volume );
|
|
|
|
m_pAudioDevice->AddSource( mixer );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSoundSystem::Update( float dt )
|
|
|
|
{
|
|
|
|
// closecaptionmanager->PreProcess( g_nSoundFrameCount );
|
|
|
|
|
|
|
|
if ( m_pAudioDevice )
|
|
|
|
{
|
|
|
|
m_pAudioDevice->Update( m_flElapsedTime );
|
|
|
|
}
|
|
|
|
|
|
|
|
// closecaptionmanager->PostProcess( g_nSoundFrameCount, dt );
|
|
|
|
|
|
|
|
m_flElapsedTime += dt;
|
|
|
|
g_nSoundFrameCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSoundSystem::Flush( void )
|
|
|
|
{
|
|
|
|
if ( m_pAudioDevice )
|
|
|
|
{
|
|
|
|
m_pAudioDevice->Flush();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSoundSystem::StopAll( void )
|
|
|
|
{
|
|
|
|
if ( m_pAudioDevice )
|
|
|
|
{
|
|
|
|
m_pAudioDevice->StopSounds();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSoundSystem::StopSound( CAudioMixer *mixer )
|
|
|
|
{
|
|
|
|
int idx = m_pAudioDevice->FindSourceIndex( mixer );
|
|
|
|
if ( idx != -1 )
|
|
|
|
{
|
|
|
|
m_pAudioDevice->FreeChannel( idx );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CSoundSystem::IsSoundPlaying( CAudioMixer *pMixer )
|
|
|
|
{
|
|
|
|
if ( !m_pAudioDevice || !pMixer )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
//
|
|
|
|
int index = m_pAudioDevice->FindSourceIndex( pMixer );
|
|
|
|
if ( index != -1 )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
CAudioMixer *CSoundSystem::FindMixer( CAudioSource *source )
|
|
|
|
{
|
|
|
|
if ( !m_pAudioDevice )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return m_pAudioDevice->GetMixerForSource( source );
|
|
|
|
}
|