initial voice refactor

main
cosmonaut 2021-11-01 12:08:36 -07:00
parent 9f4f2a50c4
commit 5a7f98944c
2 changed files with 198 additions and 108 deletions

View File

@ -149,6 +149,17 @@ typedef enum FAudioGMS_SoundState
SoundState_Stopped SoundState_Stopped
} FAudioGMS_SoundState; } FAudioGMS_SoundState;
typedef struct FAudioGMS_Voice
{
FAudioVoice* handle;
FAudioVoiceSends sends;
uint8_t effectChainAttached;
FAudioSubmixVoice* effectVoice;
FAudioVoiceSends effectSends;
float effectGain;
} FAudioGMS_Voice;
typedef struct FAudioGMS_StaticSound typedef struct FAudioGMS_StaticSound
{ {
uint32_t id; uint32_t id;
@ -171,7 +182,7 @@ typedef struct FAudioGMS_StreamingSound
typedef struct FAudioGMS_SoundInstance typedef struct FAudioGMS_SoundInstance
{ {
uint32_t id; uint32_t id;
FAudioSourceVoice *handle; FAudioGMS_Voice voice;
FAudioWaveFormatEx format; FAudioWaveFormatEx format;
uint8_t loop; /* bool */ uint8_t loop; /* bool */
FAudioGMS_SoundState soundState; FAudioGMS_SoundState soundState;
@ -184,11 +195,6 @@ typedef struct FAudioGMS_SoundInstance
float highPassFilter; float highPassFilter;
float bandPassFilter; float bandPassFilter;
uint8_t effectChainAttached;
FAudioSubmixVoice* effectVoice;
FAudioVoiceSends effectSends;
float effectGain;
uint8_t adjustingVolumeOverTime; uint8_t adjustingVolumeOverTime;
float targetVolume; float targetVolume;
float volumeDelta; float volumeDelta;
@ -238,6 +244,8 @@ typedef struct FAudioGMS_Device
FAudioDeviceDetails deviceDetails; FAudioDeviceDetails deviceDetails;
FAudioMasteringVoice *masteringVoice; FAudioMasteringVoice *masteringVoice;
FAudioGMS_Voice fauxMasteringVoice;
F3DAUDIO_LISTENER listener; F3DAUDIO_LISTENER listener;
float spatialDistanceScale; float spatialDistanceScale;
@ -386,6 +394,36 @@ void FAudioGMS_Init(double spatialDistanceScale, double timestep)
return; return;
} }
device->fauxMasteringVoice.sends.SendCount = 1;
device->fauxMasteringVoice.sends.pSends = SDL_malloc(sizeof(FAudioSendDescriptor));
device->fauxMasteringVoice.sends.pSends[0].Flags = 0;
device->fauxMasteringVoice.sends.pSends[0].pOutputVoice = device->masteringVoice;
if (FAudio_CreateSubmixVoice(
device->handle,
&device->fauxMasteringVoice.handle,
FAUDIO_DEFAULT_CHANNELS,
FAUDIO_DEFAULT_SAMPLERATE,
0,
i,
&device->fauxMasteringVoice.sends,
NULL
) != 0)
{
Log("Failed to create faux mastering voice! Bailing!");
FAudioVoice_DestroyVoice(device->masteringVoice);
FAudio_Release(device->handle);
SDL_free(device);
device = NULL;
return;
}
device->fauxMasteringVoice.effectChainAttached = 0;
device->fauxMasteringVoice.effectGain = 0;
device->fauxMasteringVoice.effectVoice = NULL;
device->fauxMasteringVoice.effectSends.SendCount = 0;
device->fauxMasteringVoice.effectSends.pSends = NULL;
device->spatialDistanceScale = spatialDistanceScale; device->spatialDistanceScale = spatialDistanceScale;
F3DAudioInitialize( F3DAudioInitialize(
@ -543,8 +581,8 @@ static void FAudioGMS_INTERNAL_SoundInstance_SetPan(FAudioGMS_SoundInstance* ins
SetPanMatrixCoefficients(instance); SetPanMatrixCoefficients(instance);
FAudioVoice_SetOutputMatrix( FAudioVoice_SetOutputMatrix(
instance->handle, instance->voice.handle,
device->masteringVoice, device->fauxMasteringVoice.handle,
instance->dspSettings.SrcChannelCount, instance->dspSettings.SrcChannelCount,
instance->dspSettings.DstChannelCount, instance->dspSettings.DstChannelCount,
instance->dspSettings.pMatrixCoefficients, instance->dspSettings.pMatrixCoefficients,
@ -566,7 +604,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_UpdatePitch(FAudioGMS_SoundInstance
} }
FAudioSourceVoice_SetFrequencyRatio( FAudioSourceVoice_SetFrequencyRatio(
instance->handle, instance->voice.handle,
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 */ 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
); );
@ -582,7 +620,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_SetPitch(FAudioGMS_SoundInstance* i
static void FAudioGMS_INTERNAL_SoundInstance_SetVolume(FAudioGMS_SoundInstance* instance, float volume) static void FAudioGMS_INTERNAL_SoundInstance_SetVolume(FAudioGMS_SoundInstance* instance, float volume)
{ {
instance->volume = volume; instance->volume = volume;
FAudioVoice_SetVolume(instance->handle, volume, 0); FAudioVoice_SetVolume(instance->voice.handle, volume, 0);
} }
static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_Init( static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_Init(
@ -592,7 +630,7 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_Init(
) { ) {
FAudioGMS_SoundInstance* instance = SDL_malloc(sizeof(FAudioGMS_SoundInstance)); FAudioGMS_SoundInstance* instance = SDL_malloc(sizeof(FAudioGMS_SoundInstance));
instance->handle = NULL; instance->voice.handle = NULL;
instance->isStatic = isStatic; instance->isStatic = isStatic;
instance->loop = 0; instance->loop = 0;
@ -606,17 +644,22 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_Init(
instance->format.nSamplesPerSec = samplesPerSecond; instance->format.nSamplesPerSec = samplesPerSecond;
instance->format.nAvgBytesPerSec = instance->format.nBlockAlign * samplesPerSecond; instance->format.nAvgBytesPerSec = instance->format.nBlockAlign * samplesPerSecond;
instance->voice.sends.SendCount = 1;
instance->voice.sends.pSends = SDL_malloc(sizeof(FAudioSendDescriptor));
instance->voice.sends.pSends[0].Flags = 0;
instance->voice.sends.pSends[0].pOutputVoice = device->fauxMasteringVoice.handle;
FAudio_CreateSourceVoice( FAudio_CreateSourceVoice(
device->handle, device->handle,
&instance->handle, &instance->voice.handle,
&instance->format, &instance->format,
FAUDIO_VOICE_USEFILTER, FAUDIO_VOICE_USEFILTER,
FAUDIO_DEFAULT_FREQ_RATIO, FAUDIO_DEFAULT_FREQ_RATIO,
isStatic ? NULL : &device->voiceCallbacks, isStatic ? NULL : &device->voiceCallbacks,
NULL, &instance->voice.sends,
NULL); NULL);
if (instance->handle == NULL) if (instance->voice.handle == NULL)
{ {
Log("SoundInstance failed to initialize!"); Log("SoundInstance failed to initialize!");
SDL_free(instance); SDL_free(instance);
@ -631,9 +674,9 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_Init(
instance->dspSettings.pMatrixCoefficients = SDL_malloc(memsize); instance->dspSettings.pMatrixCoefficients = SDL_malloc(memsize);
SDL_memset(instance->dspSettings.pMatrixCoefficients, 0, memsize); SDL_memset(instance->dspSettings.pMatrixCoefficients, 0, memsize);
instance->effectChainAttached = 0; instance->voice.effectChainAttached = 0;
instance->effectVoice = NULL; instance->voice.effectVoice = NULL;
instance->effectGain = 0; instance->voice.effectGain = 0;
instance->lowPassFilter = 0.0f; instance->lowPassFilter = 0.0f;
instance->highPassFilter = 0.0f; instance->highPassFilter = 0.0f;
@ -710,7 +753,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_SetLowPassFilter(FAudioGMS_SoundIns
p.Frequency = SDL_max(0.0, SDL_min(1.0, lowPassFilter)); p.Frequency = SDL_max(0.0, SDL_min(1.0, lowPassFilter));
p.OneOverQ = 1.0f / Q; p.OneOverQ = 1.0f / Q;
FAudioVoice_SetFilterParameters(instance->handle, &p, 0); FAudioVoice_SetFilterParameters(instance->voice.handle, &p, 0);
instance->lowPassFilter = lowPassFilter; instance->lowPassFilter = lowPassFilter;
} }
@ -732,7 +775,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_SetHighPassFilter(FAudioGMS_SoundIn
p.Frequency = SDL_max(0.0, SDL_min(1.0, highPassFilter)); p.Frequency = SDL_max(0.0, SDL_min(1.0, highPassFilter));
p.OneOverQ = 1.0f / Q; p.OneOverQ = 1.0f / Q;
FAudioVoice_SetFilterParameters(instance->handle, &p, 0); FAudioVoice_SetFilterParameters(instance->voice.handle, &p, 0);
instance->highPassFilter = highPassFilter; instance->highPassFilter = highPassFilter;
} }
@ -754,7 +797,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_SetBandPassFilter(FAudioGMS_SoundIn
p.Frequency = SDL_max(0.0, SDL_min(1.0, bandPassFilter)); p.Frequency = SDL_max(0.0, SDL_min(1.0, bandPassFilter));
p.OneOverQ = 1.0f / Q; p.OneOverQ = 1.0f / Q;
FAudioVoice_SetFilterParameters(instance->handle, &p, 0); FAudioVoice_SetFilterParameters(instance->voice.handle, &p, 0);
instance->bandPassFilter = bandPassFilter; instance->bandPassFilter = bandPassFilter;
} }
@ -789,8 +832,8 @@ static void FAudioGMS_INTERNAL_Apply3D(FAudioGMS_SoundInstance* instance)
FAudioGMS_INTERNAL_SoundInstance_UpdatePitch(instance); FAudioGMS_INTERNAL_SoundInstance_UpdatePitch(instance);
FAudioVoice_SetOutputMatrix( FAudioVoice_SetOutputMatrix(
instance->handle, instance->voice.handle,
device->masteringVoice, device->fauxMasteringVoice.handle,
instance->dspSettings.SrcChannelCount, instance->dspSettings.SrcChannelCount,
instance->dspSettings.DstChannelCount, instance->dspSettings.DstChannelCount,
instance->dspSettings.pMatrixCoefficients, instance->dspSettings.pMatrixCoefficients,
@ -832,7 +875,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_AddBuffer(FAudioGMS_SoundInstance*
buffer.LoopLength = 0; buffer.LoopLength = 0;
buffer.pContext = instance; /* context for OnBufferEnd callback */ buffer.pContext = instance; /* context for OnBufferEnd callback */
FAudioSourceVoice_SubmitSourceBuffer(instance->handle, &buffer, NULL); FAudioSourceVoice_SubmitSourceBuffer(instance->voice.handle, &buffer, NULL);
/* We have reached the end of the file! */ /* We have reached the end of the file! */
/* FIXME: maybe move this to a OnStreamEnd callback? */ /* FIXME: maybe move this to a OnStreamEnd callback? */
@ -943,10 +986,10 @@ static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* insta
instance->soundData.staticSound->buffer.LoopLength = 0; instance->soundData.staticSound->buffer.LoopLength = 0;
} }
FAudioSourceVoice_SubmitSourceBuffer(instance->handle, &instance->soundData.staticSound->buffer, NULL); FAudioSourceVoice_SubmitSourceBuffer(instance->voice.handle, &instance->soundData.staticSound->buffer, NULL);
} }
FAudioSourceVoice_Start(instance->handle, 0, 0); FAudioSourceVoice_Start(instance->voice.handle, 0, 0);
instance->soundState = SoundState_Playing; instance->soundState = SoundState_Playing;
} }
@ -968,7 +1011,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_Pause(FAudioGMS_SoundInstance* inst
{ {
if (instance->soundState == SoundState_Playing) if (instance->soundState == SoundState_Playing)
{ {
FAudioSourceVoice_Stop(instance->handle, 0, 0); /* this actually just pauses lol */ FAudioSourceVoice_Stop(instance->voice.handle, 0, 0); /* this actually just pauses lol */
instance->soundState = SoundState_Paused; instance->soundState = SoundState_Paused;
} }
} }
@ -991,8 +1034,8 @@ static void FAudioGMS_INTERNAL_SoundInstance_Stop(FAudioGMS_SoundInstance* insta
{ {
instance->soundState = SoundState_Stopped; /* set this before so flush buffers doesn't trigger buffer add callback */ instance->soundState = SoundState_Stopped; /* set this before so flush buffers doesn't trigger buffer add callback */
FAudioSourceVoice_Stop(instance->handle, 0, 0); FAudioSourceVoice_Stop(instance->voice.handle, 0, 0);
FAudioSourceVoice_FlushSourceBuffers(instance->handle); FAudioSourceVoice_FlushSourceBuffers(instance->voice.handle);
if (!instance->isStatic) if (!instance->isStatic)
{ {
@ -1101,8 +1144,8 @@ void FAudioGMS_SoundInstance_SetTrackPositionInSeconds(double soundInstanceID, d
FAudioGMS_SoundState currentState = instance->soundState; FAudioGMS_SoundState currentState = instance->soundState;
if (currentState == SoundState_Playing) if (currentState == SoundState_Playing)
{ {
FAudioSourceVoice_Stop(instance->handle, 0, 0); FAudioSourceVoice_Stop(instance->voice.handle, 0, 0);
FAudioSourceVoice_FlushSourceBuffers(instance->handle); FAudioSourceVoice_FlushSourceBuffers(instance->voice.handle);
} }
if (instance->isStatic) if (instance->isStatic)
@ -1197,7 +1240,7 @@ double FAudioGMS_SoundInstance_GetTrackPositionInSeconds(double soundInstanceID)
if (instance != NULL) if (instance != NULL)
{ {
uint32_t sampleFrame = instance->handle->src.curBufferOffset / sizeof(float); uint32_t sampleFrame = instance->voice.handle->src.curBufferOffset / sizeof(float);
return sampleFrame / instance->format.nSamplesPerSec; return sampleFrame / instance->format.nSamplesPerSec;
} }
else else
@ -1231,13 +1274,14 @@ static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* in
IdStack_Push(&device->soundInstanceIndexStack, instance->id); IdStack_Push(&device->soundInstanceIndexStack, instance->id);
FAudioGMS_INTERNAL_SoundInstance_Stop(instance); FAudioGMS_INTERNAL_SoundInstance_Stop(instance);
if (instance->effectChainAttached) if (instance->voice.effectChainAttached)
{ {
FAudioVoice_DestroyVoice(instance->effectVoice); FAudioVoice_DestroyVoice(instance->voice.effectVoice);
SDL_free(instance->effectSends.pSends); SDL_free(instance->voice.effectSends.pSends);
} }
FAudioVoice_DestroyVoice(instance->handle); SDL_free(instance->voice.sends.pSends);
FAudioVoice_DestroyVoice(instance->voice.handle);
if (!instance->isStatic) if (!instance->isStatic)
{ {
@ -1419,27 +1463,29 @@ void FAudioGMS_EffectChain_AddReverb(
} }
} }
static void FAudioGMS_INTERNAL_SoundInstance_SetEffectGain(FAudioGMS_SoundInstance *instance, float effectGain) static void FAudioGMS_INTERNAL_Voice_SetEffectGain(FAudioGMS_Voice *voice, float effectGain)
{ {
if (instance->effectChainAttached) if (voice->effectChainAttached)
{ {
float* outputMatrix = instance->dspSettings.pMatrixCoefficients; float* outputMatrix = SDL_stack_alloc(float, voice->effectSends.SendCount);
outputMatrix[0] = effectGain; outputMatrix[0] = effectGain;
if (instance->dspSettings.SrcChannelCount == 2) if (voice->effectSends.SendCount == 2)
{ {
outputMatrix[1] = effectGain; outputMatrix[1] = effectGain;
} }
FAudioVoice_SetOutputMatrix( FAudioVoice_SetOutputMatrix(
instance->handle, voice->handle,
instance->effectVoice, voice->effectVoice,
instance->dspSettings.SrcChannelCount, voice->effectSends.SendCount,
1, 1,
outputMatrix, outputMatrix,
0); 0);
instance->effectGain = effectGain; voice->effectGain = effectGain;
SDL_stack_free(outputMatrix);
} }
} }
@ -1450,7 +1496,7 @@ void FAudioGMS_SoundInstance_SetEffectGain(double soundInstanceID, double effect
if (instance != NULL) if (instance != NULL)
{ {
FAudioGMS_INTERNAL_SoundInstance_SetEffectGain(instance, effectGain); FAudioGMS_INTERNAL_Voice_SetEffectGain(&instance->voice, effectGain);
} }
} }
@ -1486,79 +1532,116 @@ static FAudioEffectChain* FAudioGMS_INTERNAL_CreateFAudioEffectChain(FAudioGMS_E
return fAudioEffectChain; return fAudioEffectChain;
} }
static void FAudioGMS_INTERNAL_SetEffectChain(FAudioGMS_Voice* voice, FAudioGMS_EffectChain* effectChain, float effectGain)
{
uint32_t i;
if (voice->effectChainAttached)
{
/* This frees the effect chain on the voice */
FAudioVoice_SetEffectChain(voice->effectVoice, NULL);
SDL_free(voice->effectSends.pSends);
}
else
{
voice->sends.pSends = SDL_realloc(voice->sends.pSends, 2 * sizeof(FAudioSendDescriptor));
}
FAudioEffectChain* fAudioEffectChain = FAudioGMS_INTERNAL_CreateFAudioEffectChain(effectChain);
voice->effectSends.SendCount = 1;
voice->effectSends.pSends = SDL_malloc(sizeof(FAudioSendDescriptor));
voice->effectSends.pSends[0].Flags = 0;
voice->effectSends.pSends[0].pOutputVoice = device->fauxMasteringVoice.handle;
FAudio_CreateSubmixVoice(
device->handle,
&voice->effectVoice,
1, /* FIXME: is this correct? */
device->deviceDetails.OutputFormat.Format.nSamplesPerSec,
0,
0,
&voice->effectSends,
fAudioEffectChain);
/* Copy the effect params */
for (i = 0; i < effectChain->effectCount; i += 1)
{
uint32_t parametersSize;
void* parameters;
switch (effectChain->effectTypes[i])
{
case EffectType_Reverb:
parametersSize = sizeof(FAudioFXReverbParameters);
parameters = &effectChain->effectParameters[i].reverbParameters;
break;
default:
Log("Unknown effect type! Something is very wrong!");
}
FAudioVoice_SetEffectParameters(
voice->effectVoice,
i,
parameters,
parametersSize,
0);
}
/* Set the instance voice to go through both faux mastering and effect voice for wet/dry */
voice->sends.pSends[0].Flags = 0;
voice->sends.pSends[0].pOutputVoice = device->fauxMasteringVoice.handle;
voice->sends.pSends[1].Flags = 0;
voice->sends.pSends[1].pOutputVoice = voice->effectVoice;
voice->effectChainAttached = 1;
FAudioVoice_SetOutputVoices(
voice->handle,
&voice->effectSends);
FAudioGMS_INTERNAL_Voice_SetEffectGain(voice, effectGain);
/* All the effect parameters are copied to the voice so we free here */
for (i = 0; i < effectChain->effectCount; i += 1)
{
FAPOBase_Release((FAPOBase*)fAudioEffectChain->pEffectDescriptors[i].pEffect);
}
SDL_free(fAudioEffectChain->pEffectDescriptors);
SDL_free(fAudioEffectChain);
}
void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain) void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain)
{ {
RETURN_ON_NULL_DEVICE() RETURN_ON_NULL_DEVICE()
FAudioGMS_SoundInstance *instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID); FAudioGMS_SoundInstance *instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
FAudioGMS_EffectChain *effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID); FAudioGMS_EffectChain *effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID);
uint32_t i;
if (instance != NULL && effectChain != NULL) if (instance != NULL && effectChain != NULL)
{ {
if (instance->effectChainAttached) FAudioGMS_INTERNAL_SetEffectChain(&instance->voice, effectChain, effectGain);
{ }
/* This frees the effect chain on the voice */ }
FAudioVoice_SetEffectChain(instance->handle, NULL);
}
FAudioEffectChain* fAudioEffectChain = FAudioGMS_INTERNAL_CreateFAudioEffectChain(effectChain); void FAudioGMS_SetMasteringEffectChain(double effectChainID, double effectGain)
FAudio_CreateSubmixVoice( {
device->handle, RETURN_ON_NULL_DEVICE()
&instance->effectVoice, FAudioGMS_EffectChain* effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID);
1, /* FIXME: is this correct? */
device->deviceDetails.OutputFormat.Format.nSamplesPerSec, if (effectChain != NULL)
0, {
0, FAudioGMS_INTERNAL_SetEffectChain(&device->fauxMasteringVoice, effectChain, effectGain);
NULL, }
fAudioEffectChain); }
instance->effectSends.SendCount = 2; void FAudioGMS_SetMasteringEffectGain(double effectGain)
instance->effectSends.pSends = SDL_malloc(2 * sizeof(FAudioSendDescriptor)); {
RETURN_ON_NULL_DEVICE()
instance->effectSends.pSends[0].Flags = 0; if (device->fauxMasteringVoice.effectChainAttached)
instance->effectSends.pSends[0].pOutputVoice = device->masteringVoice; {
instance->effectSends.pSends[1].Flags = 0; FAudioGMS_INTERNAL_Voice_SetEffectGain(&device->fauxMasteringVoice, effectGain);
instance->effectSends.pSends[1].pOutputVoice = instance->effectVoice;
instance->effectChainAttached = 1;
for (i = 0; i < effectChain->effectCount; i += 1)
{
uint32_t parametersSize;
void *parameters;
switch (effectChain->effectTypes[i])
{
case EffectType_Reverb:
parametersSize = sizeof(FAudioFXReverbParameters);
parameters = &effectChain->effectParameters[i].reverbParameters;
break;
default:
Log("Unknown effect type! Something is very wrong!");
}
FAudioVoice_SetEffectParameters(
instance->effectVoice,
i,
parameters,
parametersSize,
0);
}
FAudioVoice_SetOutputVoices(
instance->handle,
&instance->effectSends);
FAudioGMS_INTERNAL_SoundInstance_SetEffectGain(instance, effectGain);
/* all the effect parameters are copied to the voice so we free here */
for (i = 0; i < effectChain->effectCount; i += 1)
{
FAPOBase_Release((FAPOBase*)fAudioEffectChain->pEffectDescriptors[i].pEffect);
}
SDL_free(fAudioEffectChain->pEffectDescriptors);
SDL_free(fAudioEffectChain);
} }
} }
@ -1632,7 +1715,7 @@ void FAudioGMS_Update()
if (instance->destroyOnFinish) if (instance->destroyOnFinish)
{ {
FAudioVoiceState state; FAudioVoiceState state;
FAudioSourceVoice_GetState(instance->handle, &state, FAUDIO_VOICE_NOSAMPLESPLAYED); FAudioSourceVoice_GetState(instance->voice.handle, &state, FAUDIO_VOICE_NOSAMPLESPLAYED);
if (state.BuffersQueued == 0) if (state.BuffersQueued == 0)
{ {
@ -1706,6 +1789,10 @@ void FAudioGMS_Destroy()
FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[i]); FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[i]);
} }
/* FIXME: FAudioGMS_Voice_Destroy call */
FAudioVoice_DestroyVoice(device->fauxMasteringVoice.handle);
SDL_free(device->fauxMasteringVoice.sends.pSends);
FAudio_Release(device->handle); FAudio_Release(device->handle);
SDL_free(device); SDL_free(device);
device = NULL; device = NULL;

View File

@ -98,6 +98,9 @@ FAUDIOGMSAPI void FAudioGMS_EffectChain_Destroy(double effectChainID);
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain); FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain);
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetEffectGain(double soundInstanceID, double effectGain); FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetEffectGain(double soundInstanceID, double effectGain);
FAUDIOGMSAPI void FAudioGMS_SetMasteringEffectChain(double effectChainID, double effectGain);
FAUDIOGMSAPI void FAudioGMS_SetMasteringEffectGain(double effectGain);
FAUDIOGMSAPI void FAudioGMS_SetListenerPosition(double x, double y, double z); FAUDIOGMSAPI void FAudioGMS_SetListenerPosition(double x, double y, double z);
FAUDIOGMSAPI void FAudioGMS_SetListenerVelocity(double xVelocity, double yVelocity, double zVelocity); FAUDIOGMSAPI void FAudioGMS_SetListenerVelocity(double xVelocity, double yVelocity, double zVelocity);