forked from MoonsideGames/FAudioGMS
initial voice refactor
parent
7894eae234
commit
d3d9d4fe3f
229
src/FAudioGMS.c
229
src/FAudioGMS.c
|
@ -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,46 +1532,44 @@ static FAudioEffectChain* FAudioGMS_INTERNAL_CreateFAudioEffectChain(FAudioGMS_E
|
||||||
return fAudioEffectChain;
|
return fAudioEffectChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain)
|
static void FAudioGMS_INTERNAL_SetEffectChain(FAudioGMS_Voice* voice, FAudioGMS_EffectChain* effectChain, float effectGain)
|
||||||
{
|
{
|
||||||
RETURN_ON_NULL_DEVICE()
|
|
||||||
FAudioGMS_SoundInstance *instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
|
|
||||||
FAudioGMS_EffectChain *effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID);
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
if (instance != NULL && effectChain != NULL)
|
if (voice->effectChainAttached)
|
||||||
{
|
|
||||||
if (instance->effectChainAttached)
|
|
||||||
{
|
{
|
||||||
/* This frees the effect chain on the voice */
|
/* This frees the effect chain on the voice */
|
||||||
FAudioVoice_SetEffectChain(instance->handle, NULL);
|
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);
|
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(
|
FAudio_CreateSubmixVoice(
|
||||||
device->handle,
|
device->handle,
|
||||||
&instance->effectVoice,
|
&voice->effectVoice,
|
||||||
1, /* FIXME: is this correct? */
|
1, /* FIXME: is this correct? */
|
||||||
device->deviceDetails.OutputFormat.Format.nSamplesPerSec,
|
device->deviceDetails.OutputFormat.Format.nSamplesPerSec,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
NULL,
|
&voice->effectSends,
|
||||||
fAudioEffectChain);
|
fAudioEffectChain);
|
||||||
|
|
||||||
instance->effectSends.SendCount = 2;
|
/* Copy the effect params */
|
||||||
instance->effectSends.pSends = SDL_malloc(2 * sizeof(FAudioSendDescriptor));
|
|
||||||
|
|
||||||
instance->effectSends.pSends[0].Flags = 0;
|
|
||||||
instance->effectSends.pSends[0].pOutputVoice = device->masteringVoice;
|
|
||||||
instance->effectSends.pSends[1].Flags = 0;
|
|
||||||
instance->effectSends.pSends[1].pOutputVoice = instance->effectVoice;
|
|
||||||
|
|
||||||
instance->effectChainAttached = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < effectChain->effectCount; i += 1)
|
for (i = 0; i < effectChain->effectCount; i += 1)
|
||||||
{
|
{
|
||||||
uint32_t parametersSize;
|
uint32_t parametersSize;
|
||||||
void *parameters;
|
void* parameters;
|
||||||
|
|
||||||
switch (effectChain->effectTypes[i])
|
switch (effectChain->effectTypes[i])
|
||||||
{
|
{
|
||||||
|
@ -1539,26 +1583,65 @@ void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effec
|
||||||
}
|
}
|
||||||
|
|
||||||
FAudioVoice_SetEffectParameters(
|
FAudioVoice_SetEffectParameters(
|
||||||
instance->effectVoice,
|
voice->effectVoice,
|
||||||
i,
|
i,
|
||||||
parameters,
|
parameters,
|
||||||
parametersSize,
|
parametersSize,
|
||||||
0);
|
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(
|
FAudioVoice_SetOutputVoices(
|
||||||
instance->handle,
|
voice->handle,
|
||||||
&instance->effectSends);
|
&voice->effectSends);
|
||||||
|
|
||||||
FAudioGMS_INTERNAL_SoundInstance_SetEffectGain(instance, effectGain);
|
FAudioGMS_INTERNAL_Voice_SetEffectGain(voice, effectGain);
|
||||||
|
|
||||||
/* all the effect parameters are copied to the voice so we free here */
|
/* All the effect parameters are copied to the voice so we free here */
|
||||||
for (i = 0; i < effectChain->effectCount; i += 1)
|
for (i = 0; i < effectChain->effectCount; i += 1)
|
||||||
{
|
{
|
||||||
FAPOBase_Release((FAPOBase*)fAudioEffectChain->pEffectDescriptors[i].pEffect);
|
FAPOBase_Release((FAPOBase*)fAudioEffectChain->pEffectDescriptors[i].pEffect);
|
||||||
}
|
}
|
||||||
SDL_free(fAudioEffectChain->pEffectDescriptors);
|
SDL_free(fAudioEffectChain->pEffectDescriptors);
|
||||||
SDL_free(fAudioEffectChain);
|
SDL_free(fAudioEffectChain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain)
|
||||||
|
{
|
||||||
|
RETURN_ON_NULL_DEVICE()
|
||||||
|
FAudioGMS_SoundInstance *instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
|
||||||
|
FAudioGMS_EffectChain *effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID);
|
||||||
|
|
||||||
|
if (instance != NULL && effectChain != NULL)
|
||||||
|
{
|
||||||
|
FAudioGMS_INTERNAL_SetEffectChain(&instance->voice, effectChain, effectGain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_SetMasteringEffectChain(double effectChainID, double effectGain)
|
||||||
|
{
|
||||||
|
RETURN_ON_NULL_DEVICE()
|
||||||
|
FAudioGMS_EffectChain* effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID);
|
||||||
|
|
||||||
|
if (effectChain != NULL)
|
||||||
|
{
|
||||||
|
FAudioGMS_INTERNAL_SetEffectChain(&device->fauxMasteringVoice, effectChain, effectGain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_SetMasteringEffectGain(double effectGain)
|
||||||
|
{
|
||||||
|
RETURN_ON_NULL_DEVICE()
|
||||||
|
if (device->fauxMasteringVoice.effectChainAttached)
|
||||||
|
{
|
||||||
|
FAudioGMS_INTERNAL_Voice_SetEffectGain(&device->fauxMasteringVoice, effectGain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue