0
0

So I’ve been trying to convert our sound engine to use 3D and attenuate as you move around. If I manually move the listener, it seems to work, but if I try attaching it to our player and move around, it doesn’t work, even though when I debug the values they are sufficiently large that the sounds should have stopped playing by then.

Any advice would be appreciated!

[code:3tg614y1]

include "SoundManager.h"

include <assert.h>

include <string>

include "Engine.h"

SoundManager* SoundManager::m_pSoundManager = NULL;
extern float currentRadius;

SoundManager* SoundManager::Instance(void)
{
if(m_pSoundManager)
return m_pSoundManager;
else
{
m_pSoundManager = new SoundManager();
return m_pSoundManager;
}

ifdef _DEBUG

printf("Creating SoundManager Instance\n");

endif

}

void SoundManager::Destroy(void)
{
if(m_pSoundManager)
{
delete m_pSoundManager;
m_pSoundManager = NULL;
}

ifdef _DEBUG

printf("Destroying SoundManager\n");

endif

}

// Constructor
SoundManager::SoundManager() : ISystem()
{

ifdef _DEBUG

printf("Initializing Sound Manager\n");

endif

PreviouslyMuted = false;

fmod_systemInstance = 0;
pitchsound = 0;
pitchchannel = 0;
channel = 0;
channel2 = 0;
sound = 0;
sound2 = 0;
Shot = 0;

SFX_1 = 0;
SFX_2 = 0;
SFX_3 = 0;
SFX_4 = 0;
SFX_5 = 0;

/*
Create a System object and initialize.
*/
result = FMOD_System_Create(&fmod_systemInstance);
ERRCHECK(result);

result = FMOD_System_GetVersion(fmod_systemInstance, &version);
ERRCHECK(result);

if (version < FMOD_VERSION)
{
#ifdef _DEBUG
printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION);

endif

return;

}

// Set volume to on initially
muted = false;

/*
System initialization
*/

result = FMOD_System_SetOutput(fmod_systemInstance, FMOD_OUTPUTTYPE_DSOUND);
ERRCHECK(result);

result = FMOD_System_Init(fmod_systemInstance, 32, FMOD_INIT_NORMAL, NULL);
ERRCHECK(result);

// initialize our playerEar
playerEar = new FMOD_VECTOR;

playerEar->x = 0;
playerEar->y = 0;
playerEar->z = 0;

printf("PlayerEar: %d, %d, %d", playerEar->x, playerEar->y, playerEar->z);

tmpLocation = new FMOD_VECTOR;
tmpLocation->x = 0;
tmpLocation->y = 0;
tmpLocation->z = 0;

initLocation = new FMOD_VECTOR;
initLocation->x = 0;
initLocation->y = 0;
initLocation->z = 0;

FMOD_Channel_Set3DAttributes(channel, initLocation, 0);
FMOD_Channel_Set3DAttributes(channel2, initLocation, 0);
FMOD_Channel_Set3DAttributes(SFXchan1, initLocation, 0);
FMOD_Channel_Set3DAttributes(SFXchan2, initLocation, 0);
FMOD_Channel_Set3DAttributes(SFXchan3, initLocation, 0);

}

SoundManager::~SoundManager()
{
result = FMOD_Sound_Release(pitchsound);
ERRCHECK(result);

delete initLocation;

// Take out the trash
result = FMOD_Sound_Release(sound);
ERRCHECK(result);
result = FMOD_System_Close(fmod_systemInstance);
ERRCHECK(result);
result = FMOD_System_Release(fmod_systemInstance);
ERRCHECK(result);

}

void SoundManager::ERRCHECK(FMOD_RESULT result)
{
if (result != FMOD_OK)
{
OutputDebugString(FMOD_ErrorString(result));
assert(result);
}
}

void SoundManager::MusicPlay(const std::string & str)
{
if (muted)
return;

std::string loc = "Sound\";
std::string result2;
result2 += loc;
result2 += str;

result = FMOD_System_CreateStream(fmod_systemInstance,result2.c_str(), FMOD_HARDWARE | FMOD_LOOP_OFF | FMOD_3D, 0, &sound2);
ERRCHECK(result);

result = FMOD_System_PlaySound(fmod_systemInstance, FMOD_CHANNEL_FREE, sound2, 0, &channel2);
ERRCHECK(result);

FMOD_Channel_SetVolume(channel, 0.2f);
FMOD_Channel_SetVolume(channel2, 0.2f);

}

void SoundManager::SFXPlay(const std::string & str)
{
if (muted)
return;

std::string loc = "Sound\";
std::string result2;
result2 += loc;
result2 += str;

result  = FMOD_System_CreateSound(fmod_systemInstance, result2.c_str(), FMOD_HARDWARE| FMOD_LOOP_OFF | FMOD_3D, 0, &amp;SFX_1);
ERRCHECK(result);

result = FMOD_System_PlaySound(fmod_systemInstance, FMOD_CHANNEL_FREE, SFX_1, 0, &amp;SFXchan1);
ERRCHECK(result);

FMOD_Sound_Set3DMinMaxDistance(SFX_1, 1.0f, 10.0f);
FMOD_Sound_Set3DMinMaxDistance(SFX_2, 1.0f, 10.0f);

}

void SoundManager::SFXStop()
{
result = FMOD_Sound_Release(SFX_1);
ERRCHECK(result);

result = FMOD_Sound_Release(SFX_2);
ERRCHECK(result);

result = FMOD_Sound_Release(SFX_3);
ERRCHECK(result);

result = FMOD_Sound_Release(SFX_4);
ERRCHECK(result);

result = FMOD_Sound_Release(SFX_5);
ERRCHECK(result);
}

void SoundManager::Update(float frameTime)
{
if (muted)
return;

// Update ears — here, where our player is, hence what he will hear
result = FMOD_System_Set3DListenerAttributes(fmod_systemInstance, 0, playerEar, 0, 0, 0);

FMOD_System_Update(fmod_systemInstance);

if (channel)
{
unsigned int ms;
unsigned int lenms;
int playing;
int paused;

result = FMOD_Channel_IsPlaying(channel, &amp;playing);
if ((result != FMOD_OK) &amp;&amp; (result != FMOD_ERR_INVALID_HANDLE) &amp;&amp; (result != FMOD_ERR_CHANNEL_STOLEN))
{
  ERRCHECK(result);
}

result = FMOD_Channel_GetPaused(channel, &amp;paused);
if ((result != FMOD_OK) &amp;&amp; (result != FMOD_ERR_INVALID_HANDLE) &amp;&amp; (result != FMOD_ERR_CHANNEL_STOLEN))
{
  ERRCHECK(result);
}

result = FMOD_Channel_GetPosition(channel, &amp;ms, FMOD_TIMEUNIT_MS);
if ((result != FMOD_OK) &amp;&amp; (result != FMOD_ERR_INVALID_HANDLE) &amp;&amp; (result != FMOD_ERR_CHANNEL_STOLEN))
{
  ERRCHECK(result);
}

result = FMOD_Sound_GetLength(sound, &amp;lenms, FMOD_TIMEUNIT_MS);
if ((result != FMOD_OK) &amp;&amp; (result != FMOD_ERR_INVALID_HANDLE) &amp;&amp; (result != FMOD_ERR_CHANNEL_STOLEN))
{
  ERRCHECK(result);
}

}

}

}
[/code:3tg614y1]

Then in our messaging system, whenever we move, the following is called to update the playerEar listener:

[code:3tg614y1]

    playerEar-&gt;x = objMessage-&gt;playerPosition[0];
    playerEar-&gt;y = objMessage-&gt;playerPosition[1];
    playerEar-&gt;z = objMessage-&gt;playerPosition[2];

[/code:3tg614y1]

  • You must to post comments
0
0

Your last 3 vetors ar null…

FMOD_RESULT System::set3DListenerAttributes(
int listener,
const FMOD_VECTOR * pos,
const FMOD_VECTOR * vel,
const FMOD_VECTOR * forward,
const FMOD_VECTOR * up
);

FMOD_VECTOR vel = {0,0,0}; //no speed, no doppler
FMOD_VECTOR forward = {1,0,0}; //facing right, set to your player facing vector

FMOD_VECTOR up = {0,0,1}; //Top of the head points up, again, set to the top of the head vector of your player

result = FMOD_System_Set3DListenerAttributes(fmod_systemInstance, 0, playerEar, &vel, &forward, &up);

… -1 or 1, depends which way is up in your game, the values here are just to debug. calculate the proper vectors.

[quote:aga8qgu6]
You can specify 0 or NULL to not update the forwards orientation of the listener.
[/quote:aga8qgu6]

From the doc. I think this is misleading. I’m pretty sure if no vetors where set initially, the function will be in a bad state. So passing null may not do it. I always pass vectors

  • You must to post comments
0
0

Hi neville, welcome to the FMOD forums!

I can see a few issues with the code you posted.

[code:7tws5htu] FMOD_Channel_Set3DAttributes(channel, initLocation, 0);
FMOD_Channel_Set3DAttributes(channel2, initLocation, 0);
FMOD_Channel_Set3DAttributes(SFXchan1, initLocation, 0);
FMOD_Channel_Set3DAttributes(SFXchan2, initLocation, 0);
FMOD_Channel_Set3DAttributes(SFXchan3, initLocation, 0); [/code:7tws5htu]
Every FMOD function returns an FMOD_RESULT, it is extremely important to ERRCHECK after [b:7tws5htu]every[/b:7tws5htu] FMOD function call. I can guarantee all of these will be returning FMOD_ERR_INVALIDHANDLE error. You have to call System::playSound to get a valid FMOD::Channel handle, then you can then set the 3D position of that channel. I think this is the main cause of your problem.

[code:7tws5htu]void SoundManager::SFXPlay(const std::string & str)
{
if (muted)
return;

std::string loc = "Sound\";
std::string result2;
result2 += loc;
result2 += str;

result  = FMOD_System_CreateSound(fmod_systemInstance, result2.c_str(), FMOD_HARDWARE| FMOD_LOOP_OFF | FMOD_3D, 0, &amp;SFX_1);
ERRCHECK(result);

result = FMOD_System_PlaySound(fmod_systemInstance, FMOD_CHANNEL_FREE, SFX_1, 0, &amp;SFXchan1);
ERRCHECK(result);

FMOD_Sound_Set3DMinMaxDistance(SFX_1, 1.0f, 10.0f);
FMOD_Sound_Set3DMinMaxDistance(SFX_2, 1.0f, 10.0f);

} [/code:7tws5htu]
Here you are creating a new FMOD::Sound object every time you play a sound effect, you don’t need to when it’s a sample (not a stream). When you create a FMOD::Sound as a sample it only needs to be loaded once. You can play that sound many times without calling createSound again. Also, you should set the properties (like 3DMinMaxDistance) on the FMOD::Sound before calling playSound.

The following are more best-practices type things rather than actual errors.

[code:7tws5htu] result = FMOD_System_CreateStream(fmod_systemInstance,result2.c_str(), FMOD_HARDWARE | FMOD_LOOP_OFF | FMOD_3D, 0, &sound2); [/code:7tws5htu]
We recommend using software mixing on PC. It will be more consistent across platforms and supports more features of the API.

[code:7tws5htu]#ifdef _DEBUG
printf("Creating SoundManager Instance\n");

endif [/code:7tws5htu]

Although it’s not relevant to your problem this code will never hit.

[code:7tws5htu] result = FMOD_System_SetOutput(fmod_systemInstance, FMOD_OUTPUTTYPE_DSOUND);
ERRCHECK(result); [/code:7tws5htu]
FMOD will automatically detect which output type to use on each platform. We reccomend WASAPI on vista/win7.

  • You must to post comments
0
0

Hiya.
Thanks for the help!
The "fix" seemed to be just playing the sounds with SOFTWARE instead of HARDWARE.

I moved things around to fix some of the other issues you pointed out.
Namely, I now initialize the sounds in the sound manager constructor, so that I can play them on demand.

Then I reworked the SFX Play function to set the 3D Min Max distance, then play the sound, then set the 3D attributes… at least in theory.

It works initially (I.e. everything seems to set up okay when I step through it).

But when I actually try to call SFXPlay later to play a sound, I get an error: FMOD_ERR_NOTREADY. The documentation told me nothing other than the sound isn’t ready…

[code:34yp52hr]
SoundManager::SoundManager() : ISystem()
{

ifdef _DEBUG

printf("Initializing Sound Manager\n");

endif

PreviouslyMuted = false;

fmod_systemInstance = 0;
pitchsound = 0;
pitchchannel = 0;
channel = 0;
channel2 = 0;
sound = 0;
sound2 = 0;
Shot = 0;

/*
Create a System object and initialize.
*/
result = FMOD_System_Create(&fmod_systemInstance);
ERRCHECK(result);

result = FMOD_System_GetVersion(fmod_systemInstance, &version);
ERRCHECK(result);

if (version < FMOD_VERSION)
{
#ifdef _DEBUG
printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION);

endif

return;

}

// Set volume to on initially
muted = false;

/*
System initialization
*/

result = FMOD_System_SetOutput(fmod_systemInstance, FMOD_OUTPUTTYPE_DSOUND);
ERRCHECK(result);

result = FMOD_System_Init(fmod_systemInstance, 100, FMOD_INIT_NORMAL, NULL);
ERRCHECK(result);

// initialize our playerEar
playerEar = new FMOD_VECTOR;

playerEar->x = 0;
playerEar->y = 0;
playerEar->z = 0;

printf("PlayerEar: %d, %d, %d", playerEar->x, playerEar->y, playerEar->z);

tmpLocation = new FMOD_VECTOR;
tmpLocation->x = 0;
tmpLocation->y = 0;
tmpLocation->z = 0;

initLocation = new FMOD_VECTOR;
initLocation->x = 0;
initLocation->y = 0;
initLocation->z = 0;

// Load our sounds
result = FMOD_System_CreateSound(fmod_systemInstance, "Sound\tutorial_voice\room01_part01_welcome.mp3", FMOD_SOFTWARE | FMOD_LOOP_OFF | FMOD_3D, 0, &SFX_1);
ERRCHECK(result);

result = FMOD_System_CreateSound(fmod_systemInstance, "Sound\tutorial_voice\room01_part02_good.mp3", FMOD_SOFTWARE | FMOD_LOOP_OFF | FMOD_3D, 0, &SFX_2);
ERRCHECK(result);

result = FMOD_System_CreateSound(fmod_systemInstance, "Sound\tutorial_voice\room01_part03_excellent.mp3", FMOD_SOFTWARE | FMOD_LOOP_OFF | FMOD_3D, 0, &SFX_3);
ERRCHECK(result);

result = FMOD_System_CreateSound(fmod_systemInstance, "Sound\SFX\shot_05.mp3", FMOD_SOFTWARE | FMOD_LOOP_OFF | FMOD_3D, 0, &SFX_4);
ERRCHECK(result);

// This DOES play if uncommented!
// result = FMOD_System_PlaySound(fmod_systemInstance, FMOD_CHANNEL_FREE, SFX_1, 0, &channel);
//ERRCHECK(result);

}

void SoundManager::SFXPlay(FMOD_SOUND* current, FMOD_VECTOR* location, float minDist, float maxDist)
{
if (muted)
return;

// set the params for where it should play

FMOD_Sound_Set3DMinMaxDistance(current, minDist, maxDist);

// play our current sound
result = FMOD_System_PlaySound(fmod_systemInstance, FMOD_CHANNEL_FREE, current, 0, &channel);
ERRCHECK(result);

FMOD_Channel_Set3DAttributes(channel, location, 0);

}

[/code:34yp52hr]

  • You must to post comments
0
0

Any ideas?

  • You must to post comments
Showing 4 results
Your Answer

Please first to submit.