|
|
//===== Copyright � 1996-2005, 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"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// External interfaces
//-----------------------------------------------------------------------------
IAudioDevice *g_pAudioDevice = 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 );
void GetAudioDevices(CUtlVector< audio_device_description_t >& deviceListOut) const;
private: struct CSoundFile { char filename[ 512 ]; CAudioSource *source; long 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.Count() ); for ( int i = 0 ; i < m_ActiveSounds.Count(); 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.Count(); i++ ) { s = &m_ActiveSounds[ i ]; Assert( s ); if ( !stricmp( s->filename, filename ) ) { long 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 ); } }
static eSubSystems_t GetDefaultAudioSubsystem() { eSubSystems_t nSubsystem = AUDIO_SUBSYSTEM_XAUDIO; #if IS_WINDOWS_PC
if (CommandLine()->CheckParm("-directsound")) { nSubsystem = AUDIO_SUBSYSTEM_DSOUND; } #endif
return nSubsystem; }
void CSoundSystem::GetAudioDevices(CUtlVector< audio_device_description_t >& deviceListOut) const { CAudioDeviceList list; eSubSystems_t nSubsystem = GetDefaultAudioSubsystem();
list.BuildDeviceList(nSubsystem);
deviceListOut = list.m_list; }
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 ); }
|