initial spatial audio implementation
parent
b6715102ad
commit
4fceb026da
317
src/FAudioGMS.c
317
src/FAudioGMS.c
|
@ -121,6 +121,10 @@ typedef struct FAudioGMS_SoundInstance
|
||||||
uint8_t isStatic;
|
uint8_t isStatic;
|
||||||
uint8_t destroyOnFinish;
|
uint8_t destroyOnFinish;
|
||||||
|
|
||||||
|
uint8_t is3D;
|
||||||
|
F3DAUDIO_EMITTER* emitter; /* must not be NULL if is3D */
|
||||||
|
float stereoAzimuth[2];
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
FAudioGMS_StaticSound *staticSound;
|
FAudioGMS_StaticSound *staticSound;
|
||||||
|
@ -128,12 +132,20 @@ typedef struct FAudioGMS_SoundInstance
|
||||||
} parent;
|
} parent;
|
||||||
} FAudioGMS_SoundInstance;
|
} FAudioGMS_SoundInstance;
|
||||||
|
|
||||||
|
static const float DOPPLER_SCALE = 1.0f;
|
||||||
|
static const float CURVE_DISTANCE_SCALER = 1.0f;
|
||||||
|
|
||||||
typedef struct FAudioGMS_Device
|
typedef struct FAudioGMS_Device
|
||||||
{
|
{
|
||||||
FAudio* handle;
|
FAudio* handle;
|
||||||
|
F3DAUDIO_HANDLE handle3D;
|
||||||
|
|
||||||
FAudioDeviceDetails deviceDetails;
|
FAudioDeviceDetails deviceDetails;
|
||||||
FAudioMasteringVoice *masteringVoice;
|
FAudioMasteringVoice *masteringVoice;
|
||||||
|
|
||||||
|
F3DAUDIO_LISTENER listener;
|
||||||
|
float speedOfSound;
|
||||||
|
|
||||||
FAudioGMS_StaticSound **staticSounds;
|
FAudioGMS_StaticSound **staticSounds;
|
||||||
uint32_t staticSoundCount;
|
uint32_t staticSoundCount;
|
||||||
IdStack staticSoundIndexStack;
|
IdStack staticSoundIndexStack;
|
||||||
|
@ -145,7 +157,33 @@ typedef struct FAudioGMS_Device
|
||||||
|
|
||||||
static FAudioGMS_Device* device = NULL;
|
static FAudioGMS_Device* device = NULL;
|
||||||
|
|
||||||
void FAudioGMS_Init()
|
static inline FAudioGMS_StaticSound* FAudioGMS_INTERNAL_LookupStaticSound(uint32_t id)
|
||||||
|
{
|
||||||
|
if (id >= 0 && id < device->staticSoundCount)
|
||||||
|
{
|
||||||
|
return device->staticSounds[id];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log("Invalid StaticSound ID!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_LookupSoundInstance(uint32_t id)
|
||||||
|
{
|
||||||
|
if (id >= 0 && id < device->soundInstanceCount)
|
||||||
|
{
|
||||||
|
return device->soundInstances[id];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log("Invalid SoundInstance ID!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_Init(double speedOfSound)
|
||||||
{
|
{
|
||||||
device = SDL_malloc(sizeof(FAudioGMS_Device));
|
device = SDL_malloc(sizeof(FAudioGMS_Device));
|
||||||
|
|
||||||
|
@ -218,6 +256,28 @@ void FAudioGMS_Init()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device->speedOfSound = speedOfSound;
|
||||||
|
|
||||||
|
F3DAudioInitialize(
|
||||||
|
device->deviceDetails.OutputFormat.dwChannelMask,
|
||||||
|
device->speedOfSound,
|
||||||
|
device->handle3D
|
||||||
|
);
|
||||||
|
|
||||||
|
device->listener.OrientFront.x = 0;
|
||||||
|
device->listener.OrientFront.y = 0;
|
||||||
|
device->listener.OrientFront.z = -1;
|
||||||
|
device->listener.OrientTop.x = 0;
|
||||||
|
device->listener.OrientTop.y = 1;
|
||||||
|
device->listener.OrientTop.z = 0;
|
||||||
|
device->listener.Position.x = 0;
|
||||||
|
device->listener.Position.y = 0;
|
||||||
|
device->listener.Position.z = 0;
|
||||||
|
device->listener.Velocity.x = 0;
|
||||||
|
device->listener.Velocity.y = 0;
|
||||||
|
device->listener.Velocity.z = 0;
|
||||||
|
device->listener.pCone = NULL;
|
||||||
|
|
||||||
device->staticSounds = NULL;
|
device->staticSounds = NULL;
|
||||||
device->staticSoundCount = 0;
|
device->staticSoundCount = 0;
|
||||||
IdStack_Init(&device->staticSoundIndexStack);
|
IdStack_Init(&device->staticSoundIndexStack);
|
||||||
|
@ -240,6 +300,10 @@ static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* in
|
||||||
FAudioSourceVoice_Stop(instance->handle, 0, 0);
|
FAudioSourceVoice_Stop(instance->handle, 0, 0);
|
||||||
FAudioSourceVoice_FlushSourceBuffers(instance->handle);
|
FAudioSourceVoice_FlushSourceBuffers(instance->handle);
|
||||||
FAudioVoice_DestroyVoice(instance->handle);
|
FAudioVoice_DestroyVoice(instance->handle);
|
||||||
|
if (instance->is3D)
|
||||||
|
{
|
||||||
|
SDL_free(instance->emitter);
|
||||||
|
}
|
||||||
SDL_free(instance->dspSettings.pMatrixCoefficients);
|
SDL_free(instance->dspSettings.pMatrixCoefficients);
|
||||||
SDL_free(instance);
|
SDL_free(instance);
|
||||||
}
|
}
|
||||||
|
@ -247,12 +311,17 @@ static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* in
|
||||||
|
|
||||||
void FAudioGMS_SoundInstance_Destroy(double id)
|
void FAudioGMS_SoundInstance_Destroy(double id)
|
||||||
{
|
{
|
||||||
FAudioGMS_INTERNAL_SoundInstance_Destroy(device->soundInstances[(uint32_t)id]);
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id);
|
||||||
|
|
||||||
|
if (instance != NULL)
|
||||||
|
{
|
||||||
|
FAudioGMS_INTERNAL_SoundInstance_Destroy(instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FAudioGMS_SoundInstance_DestroyWhenFinished(double id)
|
void FAudioGMS_SoundInstance_DestroyWhenFinished(double id)
|
||||||
{
|
{
|
||||||
FAudioGMS_SoundInstance *instance = device->soundInstances[(uint32_t)id];
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id);
|
||||||
|
|
||||||
if (instance != NULL)
|
if (instance != NULL)
|
||||||
{
|
{
|
||||||
|
@ -273,31 +342,14 @@ static void FAudioGMS_INTERNAL_StaticSound_Destroy(FAudioGMS_StaticSound* sound)
|
||||||
}
|
}
|
||||||
|
|
||||||
void FAudioGMS_StaticSound_Destroy(double id)
|
void FAudioGMS_StaticSound_Destroy(double id)
|
||||||
|
{
|
||||||
|
if (id >= 0 && id < device->staticSoundCount)
|
||||||
{
|
{
|
||||||
FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[(uint32_t)id]);
|
FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[(uint32_t)id]);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
void FAudioGMS_Update()
|
|
||||||
{
|
{
|
||||||
uint32_t i;
|
Log("Invalid ID for destroy!");
|
||||||
|
|
||||||
for (i = 0; i < device->soundInstanceCount; i += 1)
|
|
||||||
{
|
|
||||||
FAudioGMS_SoundInstance* instance = device->soundInstances[i];
|
|
||||||
|
|
||||||
if (instance != NULL)
|
|
||||||
{
|
|
||||||
if (instance->destroyOnFinish)
|
|
||||||
{
|
|
||||||
FAudioVoiceState state;
|
|
||||||
FAudioSourceVoice_GetState(instance->handle, &state, FAUDIO_VOICE_NOSAMPLESPLAYED);
|
|
||||||
|
|
||||||
if (state.BuffersQueued == 0)
|
|
||||||
{
|
|
||||||
FAudioGMS_INTERNAL_SoundInstance_Destroy(instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +427,7 @@ double FAudioGMS_StaticSound_LoadWAV(char *filePath)
|
||||||
sound->buffer.LoopBegin = 0;
|
sound->buffer.LoopBegin = 0;
|
||||||
sound->buffer.LoopCount = 0;
|
sound->buffer.LoopCount = 0;
|
||||||
sound->buffer.LoopLength = 0;
|
sound->buffer.LoopLength = 0;
|
||||||
sound->buffer.pAudioData = pSampleData;
|
sound->buffer.pAudioData = (uint8_t*) pSampleData;
|
||||||
sound->buffer.pContext = NULL;
|
sound->buffer.pContext = NULL;
|
||||||
sound->buffer.PlayBegin = 0;
|
sound->buffer.PlayBegin = 0;
|
||||||
sound->buffer.PlayLength = 0;
|
sound->buffer.PlayLength = 0;
|
||||||
|
@ -563,25 +615,67 @@ static void FAudioGMS_INTERNAL_SoundInstance_SetPan(FAudioGMS_SoundInstance* ins
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FAudioGMS_INTERNAL_SoundInstance_SetPitch(FAudioGMS_SoundInstance* instance, float pitch)
|
static void FAudioGMS_INTERNAL_SoundInstance_UpdatePitch(FAudioGMS_SoundInstance* instance)
|
||||||
{
|
{
|
||||||
instance->pitch = pitch;
|
float doppler = 1.0f;
|
||||||
|
|
||||||
pitch -= 1.0; /* default pitch is 1.0 as per GM standard */
|
if (!instance->is3D || DOPPLER_SCALE == 0.0f)
|
||||||
pitch = SDL_max(-1.0, SDL_min(1.0, pitch));
|
{
|
||||||
|
doppler = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doppler = instance->dspSettings.DopplerFactor * DOPPLER_SCALE;
|
||||||
|
}
|
||||||
|
|
||||||
FAudioSourceVoice_SetFrequencyRatio(
|
FAudioSourceVoice_SetFrequencyRatio(
|
||||||
instance->handle,
|
instance->handle,
|
||||||
SDL_powf(2.0f, pitch),
|
SDL_powf(2.0f, instance->pitch - 1) * doppler, /* FAudio expects pitch range to be -1.0 to 1.0 while GM uses 0.0 to 2.0 so we adjust here */
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void FAudioGMS_INTERNAL_SoundInstance_SetPitch(FAudioGMS_SoundInstance* instance, float pitch)
|
||||||
|
{
|
||||||
|
pitch = SDL_max(0.0, SDL_min(2.0, pitch));
|
||||||
|
instance->pitch = pitch;
|
||||||
|
FAudioGMS_INTERNAL_SoundInstance_UpdatePitch(instance);
|
||||||
|
}
|
||||||
|
|
||||||
static void FAudioGMS_INTERNAL_SoundInstance_SetVolume(FAudioGMS_SoundInstance* instance, float volume)
|
static void FAudioGMS_INTERNAL_SoundInstance_SetVolume(FAudioGMS_SoundInstance* instance, float volume)
|
||||||
{
|
{
|
||||||
FAudioVoice_SetVolume(instance->handle, volume, 0);
|
FAudioVoice_SetVolume(instance->handle, volume, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void FAudioGMS_INTERNAL_Apply3D(FAudioGMS_SoundInstance* instance)
|
||||||
|
{
|
||||||
|
F3DAUDIO_EMITTER* emitter = instance->emitter;
|
||||||
|
|
||||||
|
if (emitter == NULL)
|
||||||
|
{
|
||||||
|
Log("Sound instance does not have 3D data! Did you forget to initialize?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
F3DAudioCalculate(
|
||||||
|
device->handle3D,
|
||||||
|
&device->listener,
|
||||||
|
emitter,
|
||||||
|
F3DAUDIO_CALCULATE_MATRIX | F3DAUDIO_CALCULATE_DOPPLER,
|
||||||
|
&instance->dspSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
FAudioGMS_INTERNAL_SoundInstance_UpdatePitch(instance);
|
||||||
|
FAudioVoice_SetOutputMatrix(
|
||||||
|
instance->handle,
|
||||||
|
device->masteringVoice,
|
||||||
|
instance->dspSettings.SrcChannelCount,
|
||||||
|
instance->dspSettings.DstChannelCount,
|
||||||
|
instance->dspSettings.pMatrixCoefficients,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(
|
static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(
|
||||||
FAudioGMS_StaticSound *staticSound,
|
FAudioGMS_StaticSound *staticSound,
|
||||||
double pan,
|
double pan,
|
||||||
|
@ -646,6 +740,11 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStati
|
||||||
|
|
||||||
instance->soundState = SoundState_Stopped;
|
instance->soundState = SoundState_Stopped;
|
||||||
|
|
||||||
|
instance->is3D = 0;
|
||||||
|
instance->emitter = NULL;
|
||||||
|
instance->stereoAzimuth[0] = 0.0f;
|
||||||
|
instance->stereoAzimuth[1] = 0.0f;
|
||||||
|
|
||||||
if (device->soundInstanceIndexStack.count > 0)
|
if (device->soundInstanceIndexStack.count > 0)
|
||||||
{
|
{
|
||||||
instance->id = IdStack_Pop(&device->soundInstanceIndexStack);
|
instance->id = IdStack_Pop(&device->soundInstanceIndexStack);
|
||||||
|
@ -663,6 +762,47 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStati
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void FAudioGMS_INTERNAL_StaticSound_AddEmitter(FAudioGMS_SoundInstance* instance, float x, float y, float z)
|
||||||
|
{
|
||||||
|
instance->is3D = 1;
|
||||||
|
|
||||||
|
instance->emitter = SDL_malloc(sizeof(F3DAUDIO_EMITTER));
|
||||||
|
|
||||||
|
/* defaults based on XNA behavior */
|
||||||
|
instance->emitter->pCone = NULL;
|
||||||
|
instance->emitter->ChannelRadius = 1.0f;
|
||||||
|
instance->emitter->pChannelAzimuths = instance->stereoAzimuth;
|
||||||
|
instance->emitter->pVolumeCurve = NULL;
|
||||||
|
instance->emitter->pLFECurve = NULL;
|
||||||
|
instance->emitter->pLPFDirectCurve = NULL;
|
||||||
|
instance->emitter->pLPFReverbCurve = NULL;
|
||||||
|
instance->emitter->pReverbCurve = NULL;
|
||||||
|
instance->emitter->InnerRadius = 0;
|
||||||
|
instance->emitter->InnerRadiusAngle = 0;
|
||||||
|
|
||||||
|
instance->emitter->ChannelCount = instance->dspSettings.SrcChannelCount;
|
||||||
|
instance->emitter->CurveDistanceScaler = CURVE_DISTANCE_SCALER;
|
||||||
|
instance->emitter->DopplerScaler = 1.0f;
|
||||||
|
|
||||||
|
instance->emitter->Position.x = x;
|
||||||
|
instance->emitter->Position.y = y;
|
||||||
|
instance->emitter->Position.z = z;
|
||||||
|
|
||||||
|
instance->emitter->Velocity.x = 0;
|
||||||
|
instance->emitter->Velocity.y = 0;
|
||||||
|
instance->emitter->Velocity.z = 0;
|
||||||
|
|
||||||
|
instance->emitter->OrientTop.x = 0;
|
||||||
|
instance->emitter->OrientTop.y = 1;
|
||||||
|
instance->emitter->OrientTop.z = 0;
|
||||||
|
|
||||||
|
instance->emitter->OrientFront.x = 0;
|
||||||
|
instance->emitter->OrientFront.y = 0;
|
||||||
|
instance->emitter->OrientFront.z = 1;
|
||||||
|
|
||||||
|
FAudioGMS_INTERNAL_Apply3D(instance);
|
||||||
|
}
|
||||||
|
|
||||||
static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* instance)
|
static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* instance)
|
||||||
{
|
{
|
||||||
if (instance->isStatic)
|
if (instance->isStatic)
|
||||||
|
@ -693,7 +833,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* insta
|
||||||
|
|
||||||
void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double pitch, double volume, double reverb)
|
void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double pitch, double volume, double reverb)
|
||||||
{
|
{
|
||||||
FAudioGMS_StaticSound* staticSound = device->staticSounds[(uint32_t)staticSoundID];
|
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
||||||
|
|
||||||
if (staticSound != NULL)
|
if (staticSound != NULL)
|
||||||
{
|
{
|
||||||
|
@ -707,9 +847,26 @@ void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double reverb)
|
||||||
|
{
|
||||||
|
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
||||||
|
|
||||||
|
if (staticSound != NULL)
|
||||||
|
{
|
||||||
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound, 0, pitch, volume, reverb);
|
||||||
|
instance->destroyOnFinish = 1;
|
||||||
|
FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z);
|
||||||
|
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log("StaticSound_PlayOneOffSpatial: Invalid static sound ID! Did you destroy this sound?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch, double volume, double reverb, double loop)
|
double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch, double volume, double reverb, double loop)
|
||||||
{
|
{
|
||||||
FAudioGMS_StaticSound* staticSound = device->staticSounds[(uint32_t)staticSoundID];
|
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
||||||
|
|
||||||
if (staticSound != NULL)
|
if (staticSound != NULL)
|
||||||
{
|
{
|
||||||
|
@ -725,9 +882,28 @@ double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double reverb, double loop)
|
||||||
|
{
|
||||||
|
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
||||||
|
|
||||||
|
if (staticSound != NULL)
|
||||||
|
{
|
||||||
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound, 0, pitch, volume, reverb);
|
||||||
|
instance->loop = (uint8_t)loop;
|
||||||
|
FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z);
|
||||||
|
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
|
||||||
|
return (double)instance->id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log("StaticSound_PlaySpatial: Invalid static sound ID! Did you destroy this sound?");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FAudioGMS_SoundInstance_Play(double id)
|
void FAudioGMS_SoundInstance_Play(double id)
|
||||||
{
|
{
|
||||||
FAudioGMS_SoundInstance *instance = device->soundInstances[(uint32_t)id];
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id);
|
||||||
|
|
||||||
if (instance != NULL)
|
if (instance != NULL)
|
||||||
{
|
{
|
||||||
|
@ -737,7 +913,7 @@ void FAudioGMS_SoundInstance_Play(double id)
|
||||||
|
|
||||||
void FAudioGMS_SoundInstance_Pause(double id)
|
void FAudioGMS_SoundInstance_Pause(double id)
|
||||||
{
|
{
|
||||||
FAudioGMS_SoundInstance* instance = device->soundInstances[(uint32_t)id];
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id);
|
||||||
|
|
||||||
if (instance != NULL)
|
if (instance != NULL)
|
||||||
{
|
{
|
||||||
|
@ -758,7 +934,7 @@ void FAudioGMS_SoundInstance_Pause(double id)
|
||||||
|
|
||||||
void FAudioGMS_SoundInstance_Stop(double id)
|
void FAudioGMS_SoundInstance_Stop(double id)
|
||||||
{
|
{
|
||||||
FAudioGMS_SoundInstance* instance = device->soundInstances[(uint32_t)id];
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id);
|
||||||
|
|
||||||
if (instance != NULL)
|
if (instance != NULL)
|
||||||
{
|
{
|
||||||
|
@ -773,19 +949,82 @@ void FAudioGMS_SoundInstance_Stop(double id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z)
|
||||||
|
{
|
||||||
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
|
||||||
|
|
||||||
|
if (instance != NULL)
|
||||||
|
{
|
||||||
|
if (!instance->is3D)
|
||||||
|
{
|
||||||
|
Log("Not a 3D sound!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->emitter->Velocity.x = x - instance->emitter->Position.x;
|
||||||
|
instance->emitter->Velocity.y = y - instance->emitter->Position.y;
|
||||||
|
instance->emitter->Velocity.z = z - instance->emitter->Position.z;
|
||||||
|
|
||||||
|
instance->emitter->Position.x = x;
|
||||||
|
instance->emitter->Position.y = y;
|
||||||
|
instance->emitter->Position.z = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_SetListenerPosition(double x, double y, double z)
|
||||||
|
{
|
||||||
|
device->listener.Velocity.x = x - device->listener.Position.x;
|
||||||
|
device->listener.Velocity.y = y - device->listener.Position.y;
|
||||||
|
device->listener.Velocity.z = z - device->listener.Position.z;
|
||||||
|
|
||||||
|
device->listener.Position.x = x;
|
||||||
|
device->listener.Position.y = y;
|
||||||
|
device->listener.Position.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_Update()
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < device->soundInstanceCount; i += 1)
|
||||||
|
{
|
||||||
|
FAudioGMS_SoundInstance* instance = device->soundInstances[i];
|
||||||
|
|
||||||
|
if (instance != NULL)
|
||||||
|
{
|
||||||
|
if (instance->is3D)
|
||||||
|
{
|
||||||
|
FAudioGMS_INTERNAL_Apply3D(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance->destroyOnFinish)
|
||||||
|
{
|
||||||
|
FAudioVoiceState state;
|
||||||
|
FAudioSourceVoice_GetState(instance->handle, &state, FAUDIO_VOICE_NOSAMPLESPLAYED);
|
||||||
|
|
||||||
|
if (state.BuffersQueued == 0)
|
||||||
|
{
|
||||||
|
FAudioGMS_INTERNAL_SoundInstance_Destroy(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FAudioGMS_Destroy()
|
void FAudioGMS_Destroy()
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
for (i = 0; i < device->staticSoundCount; i += 1)
|
|
||||||
{
|
|
||||||
FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < device->soundInstanceCount; i += 1)
|
for (i = 0; i < device->soundInstanceCount; i += 1)
|
||||||
{
|
{
|
||||||
FAudioGMS_INTERNAL_SoundInstance_Destroy(device->soundInstances[i]);
|
FAudioGMS_INTERNAL_SoundInstance_Destroy(device->soundInstances[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < device->staticSoundCount; i += 1)
|
||||||
|
{
|
||||||
|
FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[i]);
|
||||||
|
}
|
||||||
|
|
||||||
FAudio_Release(device->handle);
|
FAudio_Release(device->handle);
|
||||||
SDL_free(device);
|
SDL_free(device);
|
||||||
device = NULL;
|
device = NULL;
|
||||||
|
|
|
@ -39,20 +39,25 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
FAUDIOGMSAPI void FAudioGMS_Init();
|
FAUDIOGMSAPI void FAudioGMS_Init(double speedOfSound); /* recommend about 1500? for 2D game */
|
||||||
FAUDIOGMSAPI void FAudioGMS_Update();
|
|
||||||
|
|
||||||
FAUDIOGMSAPI double FAudioGMS_StaticSound_LoadWAV(char *filePath); /* returns a static sound ID */
|
FAUDIOGMSAPI double FAudioGMS_StaticSound_LoadWAV(char *filePath); /* returns a static sound ID */
|
||||||
FAUDIOGMSAPI void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double pitch, double volume, double reverb); /* automatically frees itself when done! */
|
FAUDIOGMSAPI void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double pitch, double volume, double reverb); /* automatically frees itself when done! */
|
||||||
|
FAUDIOGMSAPI void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double reverb); /* automatically frees itself when done! */
|
||||||
FAUDIOGMSAPI double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch, double volume, double reverb, double loop); /* returns a sound instance ID. must be freed! */
|
FAUDIOGMSAPI double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch, double volume, double reverb, double loop); /* returns a sound instance ID. must be freed! */
|
||||||
|
FAUDIOGMSAPI double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double reverb, double loop); /* returns a sound instance ID. must be freed! */
|
||||||
|
FAUDIOGMSAPI void FAudioGMS_StaticSound_Destroy(double id);
|
||||||
|
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Play(double id);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Play(double id);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Pause(double id);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Pause(double id);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Stop(double id);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Stop(double id);
|
||||||
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Destroy(double id);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Destroy(double id);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double id);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double id);
|
||||||
FAUDIOGMSAPI void FAudioGMS_StaticSound_Destroy(double id);
|
|
||||||
|
FAUDIOGMSAPI void FAudioGMS_SetListenerPosition(double x, double y, double z);
|
||||||
|
|
||||||
|
FAUDIOGMSAPI void FAudioGMS_Update();
|
||||||
FAUDIOGMSAPI void FAudioGMS_Destroy();
|
FAUDIOGMSAPI void FAudioGMS_Destroy();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Reference in New Issue