Fmod manager.cpp

From Valve Developer Community
Jump to: navigation, search
#include "cbase.h"
#include "fmod_manager.h"

using namespace FMOD;

System			*pSystem;
Sound			*pSound;
SoundGroup		*pSoundGroup;
Channel			*pChannel;
ChannelGroup	*pChannelGroup;
FMOD_RESULT		result;

CFMODManager gFMODMng;
CFMODManager* FMODManager()
{
	return &gFMODMng;
}

CFMODManager::CFMODManager()
{
	m_fFadeDelay = 0.0;
	newSoundFileToTransitionTo = "NULL";
	currentSound = "NULL";
	m_bShouldTransition = false;
	m_bFadeIn = false;
	m_bFadeOut = false;
}

CFMODManager::~CFMODManager()
{
	m_fFadeDelay = 0.0;
	newSoundFileToTransitionTo = "NULL";
	currentSound = "NULL";
	m_bShouldTransition = false;
	m_bFadeIn = false;
	m_bFadeOut = false;
}

// Starts FMOD
void CFMODManager::InitFMOD( void )
{
	result = System_Create( &pSystem ); // Create the main system object.

	if (result != FMOD_OK)
		Warning("FMOD ERROR: System creation failed!\n");
	else
		DevMsg("FMOD system successfully created.\n");

	result = pSystem->init(100, FMOD_INIT_NORMAL, 0);   // Initialize FMOD system.

	if (result != FMOD_OK)
		Warning("FMOD ERROR: Failed to initialize properly!\n");
	else
		DevMsg("FMOD initialized successfully.\n");
}

// Stops FMOD
void CFMODManager::ExitFMOD( void )
{
	result = pSystem->release();

	if (result != FMOD_OK)
		Warning("FMOD ERROR: System did not terminate properly!\n");
	else
		DevMsg("FMOD system terminated successfully.\n");
}

// Returns the full path of a specified sound file in the /sounds folder
const char* CFMODManager::GetFullPathToSound( const char* pathToFileFromModFolder )
{
	char* resultpath = new char[512];

	Q_snprintf( resultpath, 512, "%s/sound/%s", engine->GetGameDirectory(), pathToFileFromModFolder );

	// convert backwards slashes to forward slashes
	for ( int i = 0; i < 512; i++ )
	{
		if( resultpath[i] == '\\' ) 
			resultpath[i] = '/';
	}

	return resultpath;
}

// Returns the name of the current ambient sound being played
// If there is an error getting the name of the ambient sound or if no ambient sound is currently being played, returns "NULL"
const char* CFMODManager::GetCurrentSoundName( void )
{
	return currentSound;
}

// Handles all fade-related sound stuffs
// Called every frame when the client is in-game
void CFMODManager::FadeThink( void )
{
	if ( m_bFadeOut )
	{
		if ( gpGlobals->curtime >= m_fFadeDelay )
		{
			float tempvol;
			pChannel->getVolume( &tempvol );

			if ( tempvol > 0.0 )
			{
				pChannel->setVolume( tempvol - 0.05 );
				m_fFadeDelay = gpGlobals->curtime + 0.1;
			}
			else
			{
				pChannel->setVolume( 0.0 );
				m_bFadeOut = false;
				m_fFadeDelay = 0.0;
			}
		}
	}
	else if ( m_bShouldTransition )
	{
		result = pSystem->createStream( GetFullPathToSound( newSoundFileToTransitionTo ), FMOD_DEFAULT, 0, &pSound );

		if (result != FMOD_OK)
		{
			Warning("FMOD: Failed to create stream of sound '%s' ! (ERROR NUMBER: %i)\n", newSoundFileToTransitionTo, result);
			newSoundFileToTransitionTo = "NULL";
			m_bShouldTransition = false;
			return;
		}

		result = pSystem->playSound( FMOD_CHANNEL_REUSE, pSound, false, &pChannel);

		if (result != FMOD_OK)
		{
			Warning("FMOD: Failed to play sound '%s' ! (ERROR NUMBER: %i)\n", newSoundFileToTransitionTo, result);
			newSoundFileToTransitionTo = "NULL";
			m_bShouldTransition = false;
			return;
		}

		currentSound = newSoundFileToTransitionTo;
		newSoundFileToTransitionTo = "NULL";
		m_bShouldTransition = false;
	}
	else if ( m_bFadeIn )
	{
		if ( gpGlobals->curtime >= m_fFadeDelay )
		{
			float tempvol;
			pChannel->getVolume( &tempvol );

			if ( tempvol < 1.0 )
			{
				pChannel->setVolume( tempvol + 0.05 );
				m_fFadeDelay = gpGlobals->curtime + 0.1;
			}
			else
			{
				pChannel->setVolume( 1.0 );
				m_bFadeIn = false;
				m_fFadeDelay = 0.0;
			}
		}
	}
}

// Compares specified ambient sound with the current ambient sound being played
// Returns true if they match, false if they do not or if no sound is being played
bool CFMODManager::IsSoundPlaying( const char* pathToFileFromSoundsFolder )
{
	const char* currentSoundPlaying = GetCurrentSoundName();

	return strcmp(currentSoundPlaying, pathToFileFromSoundsFolder) == 0;
}

// Abruptly starts playing a specified ambient sound
// In most cases, we'll want to use TransitionAmbientSounds instead
void CFMODManager::PlayAmbientSound( const char* pathToFileFromSoundsFolder, bool fadeIn )
{
	result = pSystem->createStream( GetFullPathToSound( pathToFileFromSoundsFolder ), FMOD_DEFAULT, 0, &pSound );

	if (result != FMOD_OK)
	{
		Warning("FMOD: Failed to create stream of sound '%s' ! (ERROR NUMBER: %i)\n", pathToFileFromSoundsFolder, result);
		return;
	}

	result = pSystem->playSound( FMOD_CHANNEL_REUSE, pSound, false, &pChannel);

	if (result != FMOD_OK)
	{
		Warning("FMOD: Failed to play sound '%s' ! (ERROR NUMBER: %i)\n", pathToFileFromSoundsFolder, result);
		return;
	}

	if ( fadeIn )
	{
		pChannel->setVolume( 0.0 );
		m_bFadeIn = true;
	}

	currentSound = pathToFileFromSoundsFolder;
}

// Abruptly stops playing all ambient sounds
void CFMODManager::StopAmbientSound( bool fadeOut )
{
	if ( fadeOut )
	{
		pChannel->setVolume( 1.0 );
		m_bFadeOut = true;
	}
	else
	{
		pChannel->setVolume( 0.0 );
	}

	currentSound = "NULL";
}

// Transitions between two ambient sounds if necessary
// If a sound isn't already playing when this is called, don't worry about it
void CFMODManager::TransitionAmbientSounds( const char* pathToFileFromSoundsFolder )
{
	pChannel->setVolume( 1.0 );
	newSoundFileToTransitionTo = pathToFileFromSoundsFolder;

	m_bFadeOut = true;
	m_bShouldTransition = true;
	m_bFadeIn = true;
}

See also