effect chain API
parent
b171dd1669
commit
5570687a66
452
src/FAudioGMS.c
452
src/FAudioGMS.c
|
@ -225,14 +225,14 @@ typedef struct FAudioGMS_SoundInstance
|
||||||
float pan;
|
float pan;
|
||||||
float pitch;
|
float pitch;
|
||||||
float volume;
|
float volume;
|
||||||
float reverb;
|
|
||||||
float lowPassFilter;
|
float lowPassFilter;
|
||||||
float highPassFilter;
|
float highPassFilter;
|
||||||
float bandPassFilter;
|
float bandPassFilter;
|
||||||
|
|
||||||
uint8_t reverbAttached;
|
uint8_t effectChainAttached;
|
||||||
FAudioSubmixVoice* reverbVoice;
|
FAudioSubmixVoice* effectVoice;
|
||||||
FAudioVoiceSends reverbSends;
|
FAudioVoiceSends effectSends;
|
||||||
|
float effectGain;
|
||||||
|
|
||||||
uint8_t adjustingVolumeOverTime;
|
uint8_t adjustingVolumeOverTime;
|
||||||
float targetVolume;
|
float targetVolume;
|
||||||
|
@ -252,6 +252,24 @@ typedef struct FAudioGMS_SoundInstance
|
||||||
} soundData;
|
} soundData;
|
||||||
} FAudioGMS_SoundInstance;
|
} FAudioGMS_SoundInstance;
|
||||||
|
|
||||||
|
typedef enum FAudioGMS_EffectType
|
||||||
|
{
|
||||||
|
EffectType_Reverb
|
||||||
|
} FAudioGMS_EffectType;
|
||||||
|
|
||||||
|
typedef union FAudioGMS_EffectParameters
|
||||||
|
{
|
||||||
|
FAudioFXReverbParameters reverbParameters;
|
||||||
|
} FAudioGMS_EffectParameters;
|
||||||
|
|
||||||
|
typedef struct FAudioGMS_EffectChain
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
FAudioEffectChain fAudioEffectChain;
|
||||||
|
FAudioGMS_EffectType *effectTypes; /* size equal to effect chain size */
|
||||||
|
union FAudioGMS_EffectParameters *effectParameters; /* size equal to effect chain size */
|
||||||
|
} FAudioGMS_EffectChain;
|
||||||
|
|
||||||
static const float SPEED_OF_SOUND = 343.5f;
|
static const float SPEED_OF_SOUND = 343.5f;
|
||||||
static const float DOPPLER_SCALE = 1.0f;
|
static const float DOPPLER_SCALE = 1.0f;
|
||||||
static const uint32_t MINIMUM_BUFFER_CHECK = 3;
|
static const uint32_t MINIMUM_BUFFER_CHECK = 3;
|
||||||
|
@ -278,6 +296,10 @@ typedef struct FAudioGMS_Device
|
||||||
uint32_t soundInstanceCount;
|
uint32_t soundInstanceCount;
|
||||||
IdStack soundInstanceIndexStack;
|
IdStack soundInstanceIndexStack;
|
||||||
|
|
||||||
|
FAudioGMS_EffectChain** effectChains;
|
||||||
|
uint32_t effectChainCount;
|
||||||
|
IdStack effectChainIndexStack;
|
||||||
|
|
||||||
float streamStagingBuffer[STREAMING_BUFFER_SIZE];
|
float streamStagingBuffer[STREAMING_BUFFER_SIZE];
|
||||||
double timestep;
|
double timestep;
|
||||||
} FAudioGMS_Device;
|
} FAudioGMS_Device;
|
||||||
|
@ -310,6 +332,19 @@ static inline FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_LookupSoundInstance(ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline FAudioGMS_EffectChain* FAudioGMS_INTERNAL_LookupEffectChain(uint32_t id)
|
||||||
|
{
|
||||||
|
if (id >= 0 && id < device->effectChainCount)
|
||||||
|
{
|
||||||
|
return device->effectChains[id];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log("Invalid EffectChain ID!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FAudioGMS_Init(double spatialDistanceScale, double timestep)
|
void FAudioGMS_Init(double spatialDistanceScale, double timestep)
|
||||||
{
|
{
|
||||||
device = SDL_malloc(sizeof(FAudioGMS_Device));
|
device = SDL_malloc(sizeof(FAudioGMS_Device));
|
||||||
|
@ -413,6 +448,10 @@ void FAudioGMS_Init(double spatialDistanceScale, double timestep)
|
||||||
device->soundInstanceCount = 0;
|
device->soundInstanceCount = 0;
|
||||||
IdStack_Init(&device->soundInstanceIndexStack);
|
IdStack_Init(&device->soundInstanceIndexStack);
|
||||||
|
|
||||||
|
device->effectChains = NULL;
|
||||||
|
device->effectChainCount = 0;
|
||||||
|
IdStack_Init(&device->effectChainIndexStack);
|
||||||
|
|
||||||
device->timestep = timestep;
|
device->timestep = timestep;
|
||||||
|
|
||||||
Log("FAudio initialized successfully!");
|
Log("FAudio initialized successfully!");
|
||||||
|
@ -521,118 +560,6 @@ double FAudioGMS_StaticSound_LoadWAV(char *filePath)
|
||||||
return (double)sound->id;
|
return (double)sound->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FAudioGMS_INTERNAL_SoundInstance_AttachReverb(FAudioGMS_SoundInstance* instance)
|
|
||||||
{
|
|
||||||
if (!instance->reverbAttached)
|
|
||||||
{
|
|
||||||
/* Init reverb */
|
|
||||||
|
|
||||||
FAPO* reverb;
|
|
||||||
FAudioCreateReverb(&reverb, 0);
|
|
||||||
|
|
||||||
FAudioEffectChain* reverbChain = SDL_malloc(sizeof(FAudioEffectChain));
|
|
||||||
|
|
||||||
reverbChain->EffectCount = 1;
|
|
||||||
reverbChain->pEffectDescriptors = SDL_malloc(sizeof(FAudioEffectDescriptor));
|
|
||||||
|
|
||||||
FAudioEffectDescriptor* reverbDescriptor = reverbChain->pEffectDescriptors;
|
|
||||||
|
|
||||||
reverbDescriptor->InitialState = 1;
|
|
||||||
reverbDescriptor->OutputChannels = device->deviceDetails.OutputFormat.Format.nChannels == 6 ? 6 : 1;
|
|
||||||
reverbDescriptor->pEffect = reverb;
|
|
||||||
|
|
||||||
FAudio_CreateSubmixVoice(
|
|
||||||
device->handle,
|
|
||||||
&instance->reverbVoice,
|
|
||||||
1, /* omnidirectional reverb */
|
|
||||||
device->deviceDetails.OutputFormat.Format.nSamplesPerSec,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
reverbChain);
|
|
||||||
|
|
||||||
FAPOBase_Release((FAPOBase*)reverb);
|
|
||||||
SDL_free(reverbChain->pEffectDescriptors);
|
|
||||||
SDL_free(reverbChain);
|
|
||||||
|
|
||||||
FAudioFXReverbParameters* reverbParams = SDL_malloc(sizeof(FAudioFXReverbParameters));
|
|
||||||
|
|
||||||
reverbParams->WetDryMix = 100.0f;
|
|
||||||
reverbParams->ReflectionsDelay = 7;
|
|
||||||
reverbParams->ReverbDelay = 11;
|
|
||||||
reverbParams->RearDelay = FAUDIOFX_REVERB_DEFAULT_REAR_DELAY;
|
|
||||||
reverbParams->PositionLeft = FAUDIOFX_REVERB_DEFAULT_POSITION;
|
|
||||||
reverbParams->PositionRight = FAUDIOFX_REVERB_DEFAULT_POSITION;
|
|
||||||
reverbParams->PositionMatrixLeft = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX;
|
|
||||||
reverbParams->PositionMatrixRight = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX;
|
|
||||||
reverbParams->EarlyDiffusion = 15;
|
|
||||||
reverbParams->LateDiffusion = 15;
|
|
||||||
reverbParams->LowEQGain = 8;
|
|
||||||
reverbParams->LowEQCutoff = 4;
|
|
||||||
reverbParams->HighEQGain = 8;
|
|
||||||
reverbParams->HighEQCutoff = 6;
|
|
||||||
reverbParams->RoomFilterFreq = 5000.0f;
|
|
||||||
reverbParams->RoomFilterMain = -10.0f;
|
|
||||||
reverbParams->RoomFilterHF = -1.0f;
|
|
||||||
reverbParams->ReflectionsGain = -26.0200005f;
|
|
||||||
reverbParams->ReverbGain = 10.0f;
|
|
||||||
reverbParams->DecayTime = 1.49000001f;
|
|
||||||
reverbParams->Density = 100.0f;
|
|
||||||
reverbParams->RoomSize = FAUDIOFX_REVERB_DEFAULT_ROOM_SIZE;
|
|
||||||
|
|
||||||
FAudioVoice_SetEffectParameters(
|
|
||||||
instance->reverbVoice,
|
|
||||||
0,
|
|
||||||
reverbParams,
|
|
||||||
sizeof(FAudioFXReverbParameters),
|
|
||||||
0);
|
|
||||||
|
|
||||||
SDL_free(reverbParams);
|
|
||||||
|
|
||||||
/* Init reverb sends */
|
|
||||||
|
|
||||||
instance->reverbSends.SendCount = 2;
|
|
||||||
instance->reverbSends.pSends = SDL_malloc(2 * sizeof(FAudioSendDescriptor));
|
|
||||||
|
|
||||||
instance->reverbSends.pSends[0].Flags = 0;
|
|
||||||
instance->reverbSends.pSends[0].pOutputVoice = device->masteringVoice;
|
|
||||||
instance->reverbSends.pSends[1].Flags = 0;
|
|
||||||
instance->reverbSends.pSends[1].pOutputVoice = instance->reverbVoice;
|
|
||||||
|
|
||||||
instance->reverbAttached = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FAudioVoice_SetOutputVoices(
|
|
||||||
instance->handle,
|
|
||||||
&instance->reverbSends);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FAudioGMS_INTERNAL_SoundInstance_SetReverb(FAudioGMS_SoundInstance *instance, float reverb)
|
|
||||||
{
|
|
||||||
if (!instance->reverbAttached)
|
|
||||||
{
|
|
||||||
FAudioGMS_INTERNAL_SoundInstance_AttachReverb(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
float* outputMatrix = instance->dspSettings.pMatrixCoefficients;
|
|
||||||
|
|
||||||
outputMatrix[0] = reverb;
|
|
||||||
if (instance->dspSettings.SrcChannelCount == 2)
|
|
||||||
{
|
|
||||||
outputMatrix[1] = reverb;
|
|
||||||
}
|
|
||||||
|
|
||||||
FAudioVoice_SetOutputMatrix(
|
|
||||||
instance->handle,
|
|
||||||
instance->reverbVoice,
|
|
||||||
instance->dspSettings.SrcChannelCount,
|
|
||||||
1,
|
|
||||||
outputMatrix,
|
|
||||||
0);
|
|
||||||
|
|
||||||
instance->reverb = reverb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FAudioGMS_INTERNAL_SoundInstance_SetLowPassFilter(FAudioGMS_SoundInstance* instance, float lowPassFilter)
|
static void FAudioGMS_INTERNAL_SoundInstance_SetLowPassFilter(FAudioGMS_SoundInstance* instance, float lowPassFilter)
|
||||||
{
|
{
|
||||||
FAudioFilterParameters p;
|
FAudioFilterParameters p;
|
||||||
|
@ -747,16 +674,11 @@ static void FAudioGMS_INTERNAL_SoundInstance_SetVolume(FAudioGMS_SoundInstance*
|
||||||
FAudioVoice_SetVolume(instance->handle, volume, 0);
|
FAudioVoice_SetVolume(instance->handle, volume, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FAudioGMS_INTERNAL_SoundInstance_SetProperties(FAudioGMS_SoundInstance* instance, double pan, double pitch, double volume, double reverb)
|
static void FAudioGMS_INTERNAL_SoundInstance_SetProperties(FAudioGMS_SoundInstance* instance, double pan, double pitch, double volume)
|
||||||
{
|
{
|
||||||
FAudioGMS_INTERNAL_SoundInstance_SetPan(instance, pan);
|
FAudioGMS_INTERNAL_SoundInstance_SetPan(instance, pan);
|
||||||
FAudioGMS_INTERNAL_SoundInstance_SetPitch(instance, pitch);
|
FAudioGMS_INTERNAL_SoundInstance_SetPitch(instance, pitch);
|
||||||
FAudioGMS_INTERNAL_SoundInstance_SetVolume(instance, volume);
|
FAudioGMS_INTERNAL_SoundInstance_SetVolume(instance, volume);
|
||||||
|
|
||||||
if (reverb > 0.0f)
|
|
||||||
{
|
|
||||||
FAudioGMS_INTERNAL_SoundInstance_SetReverb(instance, reverb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FAudioGMS_INTERNAL_Apply3D(FAudioGMS_SoundInstance* instance)
|
static void FAudioGMS_INTERNAL_Apply3D(FAudioGMS_SoundInstance* instance)
|
||||||
|
@ -831,8 +753,10 @@ 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->reverbAttached = 0;
|
instance->effectChainAttached = 0;
|
||||||
instance->reverb = 0.0f;
|
instance->effectVoice = NULL;
|
||||||
|
instance->effectGain = 0;
|
||||||
|
|
||||||
instance->lowPassFilter = 0.0f;
|
instance->lowPassFilter = 0.0f;
|
||||||
instance->highPassFilter = 0.0f;
|
instance->highPassFilter = 0.0f;
|
||||||
instance->bandPassFilter = 0.0f;
|
instance->bandPassFilter = 0.0f;
|
||||||
|
@ -1072,7 +996,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* insta
|
||||||
instance->soundState = SoundState_Playing;
|
instance->soundState = SoundState_Playing;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
||||||
|
|
||||||
|
@ -1080,7 +1004,7 @@ void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double p
|
||||||
{
|
{
|
||||||
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound);
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound);
|
||||||
instance->destroyOnFinish = 1;
|
instance->destroyOnFinish = 1;
|
||||||
FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, pan, pitch, volume, reverb);
|
FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, pan, pitch, volume);
|
||||||
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
|
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1089,7 +1013,7 @@ 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)
|
void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, double y, double z, double pitch, double volume)
|
||||||
{
|
{
|
||||||
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
||||||
|
|
||||||
|
@ -1097,7 +1021,7 @@ void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, dou
|
||||||
{
|
{
|
||||||
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound);
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound);
|
||||||
instance->destroyOnFinish = 1;
|
instance->destroyOnFinish = 1;
|
||||||
FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, 0, pitch, volume, reverb);
|
FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, 0, pitch, volume);
|
||||||
FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z);
|
FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z);
|
||||||
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
|
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
|
||||||
}
|
}
|
||||||
|
@ -1107,7 +1031,7 @@ void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, dou
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 loop)
|
||||||
{
|
{
|
||||||
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
||||||
|
|
||||||
|
@ -1115,7 +1039,7 @@ double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch
|
||||||
{
|
{
|
||||||
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound);
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound);
|
||||||
instance->loop = (uint8_t)loop;
|
instance->loop = (uint8_t)loop;
|
||||||
FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, pan, pitch, volume, reverb);
|
FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, pan, pitch, volume);
|
||||||
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
|
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
|
||||||
return (double)instance->id;
|
return (double)instance->id;
|
||||||
}
|
}
|
||||||
|
@ -1126,7 +1050,7 @@ 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)
|
double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double loop)
|
||||||
{
|
{
|
||||||
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
|
||||||
|
|
||||||
|
@ -1134,7 +1058,7 @@ double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double
|
||||||
{
|
{
|
||||||
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound);
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound);
|
||||||
instance->loop = (uint8_t)loop;
|
instance->loop = (uint8_t)loop;
|
||||||
FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, 0, pitch, volume, reverb);
|
FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, 0, pitch, volume);
|
||||||
FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z);
|
FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z);
|
||||||
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
|
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
|
||||||
return (double)instance->id;
|
return (double)instance->id;
|
||||||
|
@ -1254,16 +1178,6 @@ void FAudioGMS_SoundInstance_SetVolume(double soundInstanceID, double volume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FAudioGMS_SoundInstance_SetReverb(double soundInstanceID, double reverb)
|
|
||||||
{
|
|
||||||
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
|
|
||||||
|
|
||||||
if (instance != NULL)
|
|
||||||
{
|
|
||||||
FAudioGMS_INTERNAL_SoundInstance_SetReverb(instance, reverb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z)
|
void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z)
|
||||||
{
|
{
|
||||||
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
|
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
|
||||||
|
@ -1451,6 +1365,255 @@ void FAudioGMS_StaticSound_Destroy(double staticSoundID)
|
||||||
FAudioGMS_INTERNAL_StaticSound_Destroy(sound);
|
FAudioGMS_INTERNAL_StaticSound_Destroy(sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double FAudioGMS_EffectChain_Create()
|
||||||
|
{
|
||||||
|
FAudioGMS_EffectChain* effectChain = SDL_malloc(sizeof(FAudioGMS_EffectChain));
|
||||||
|
|
||||||
|
effectChain->fAudioEffectChain.EffectCount = 0;
|
||||||
|
effectChain->fAudioEffectChain.pEffectDescriptors = NULL;
|
||||||
|
effectChain->effectTypes = NULL;
|
||||||
|
effectChain->effectParameters = NULL;
|
||||||
|
|
||||||
|
if (device->effectChainIndexStack.count > 0)
|
||||||
|
{
|
||||||
|
effectChain->id = IdStack_Pop(&device->effectChainIndexStack);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
effectChain->id = device->effectChainCount;
|
||||||
|
|
||||||
|
device->effectChains = SDL_realloc(device->effectChains, (device->effectChainCount + 1) * sizeof(FAudioGMS_EffectChain*));
|
||||||
|
device->effectChainCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
device->effectChains[effectChain->id] = effectChain;
|
||||||
|
|
||||||
|
return effectChain->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FAudioGMS_INTERNAL_EffectChain_AddReverb(FAudioGMS_EffectChain* effectChain, FAudioFXReverbParameters *reverbParameters)
|
||||||
|
{
|
||||||
|
FAPO* reverb;
|
||||||
|
FAudioCreateReverb(&reverb, 0);
|
||||||
|
|
||||||
|
effectChain->fAudioEffectChain.EffectCount += 1;
|
||||||
|
effectChain->fAudioEffectChain.pEffectDescriptors = SDL_realloc(effectChain->fAudioEffectChain.pEffectDescriptors, effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioEffectDescriptor));
|
||||||
|
|
||||||
|
FAudioEffectDescriptor* reverbDescriptor = &effectChain->fAudioEffectChain.pEffectDescriptors[effectChain->fAudioEffectChain.EffectCount - 1];
|
||||||
|
|
||||||
|
reverbDescriptor->InitialState = 1;
|
||||||
|
reverbDescriptor->OutputChannels = device->deviceDetails.OutputFormat.Format.nChannels == 6 ? 6 : 1;
|
||||||
|
reverbDescriptor->pEffect = reverb;
|
||||||
|
|
||||||
|
effectChain->effectTypes = SDL_realloc(effectChain->effectTypes, effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioGMS_EffectType));
|
||||||
|
effectChain->effectTypes[effectChain->fAudioEffectChain.EffectCount - 1] = EffectType_Reverb;
|
||||||
|
|
||||||
|
effectChain->effectParameters = SDL_realloc(effectChain->effectParameters, effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioGMS_EffectParameters));
|
||||||
|
SDL_memcpy(&effectChain->effectParameters[effectChain->fAudioEffectChain.EffectCount - 1], reverbParameters, sizeof(FAudioFXReverbParameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_EffectChain_AddDefaultReverb(double effectChainID)
|
||||||
|
{
|
||||||
|
FAudioGMS_EffectChain *effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID);
|
||||||
|
|
||||||
|
if (effectChain != NULL)
|
||||||
|
{
|
||||||
|
FAudioFXReverbParameters reverbParams;
|
||||||
|
|
||||||
|
reverbParams.WetDryMix = 100.0f;
|
||||||
|
reverbParams.ReflectionsDelay = 7;
|
||||||
|
reverbParams.ReverbDelay = 11;
|
||||||
|
reverbParams.RearDelay = FAUDIOFX_REVERB_DEFAULT_REAR_DELAY;
|
||||||
|
reverbParams.PositionLeft = FAUDIOFX_REVERB_DEFAULT_POSITION;
|
||||||
|
reverbParams.PositionRight = FAUDIOFX_REVERB_DEFAULT_POSITION;
|
||||||
|
reverbParams.PositionMatrixLeft = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX;
|
||||||
|
reverbParams.PositionMatrixRight = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX;
|
||||||
|
reverbParams.EarlyDiffusion = 15;
|
||||||
|
reverbParams.LateDiffusion = 15;
|
||||||
|
reverbParams.LowEQGain = 8;
|
||||||
|
reverbParams.LowEQCutoff = 4;
|
||||||
|
reverbParams.HighEQGain = 8;
|
||||||
|
reverbParams.HighEQCutoff = 6;
|
||||||
|
reverbParams.RoomFilterFreq = 5000.0f;
|
||||||
|
reverbParams.RoomFilterMain = -10.0f;
|
||||||
|
reverbParams.RoomFilterHF = -1.0f;
|
||||||
|
reverbParams.ReflectionsGain = -26.0200005f;
|
||||||
|
reverbParams.ReverbGain = 10.0f;
|
||||||
|
reverbParams.DecayTime = 1.49000001f;
|
||||||
|
reverbParams.Density = 100.0f;
|
||||||
|
reverbParams.RoomSize = FAUDIOFX_REVERB_DEFAULT_ROOM_SIZE;
|
||||||
|
|
||||||
|
FAudioGMS_INTERNAL_EffectChain_AddReverb(effectChain, &reverbParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no room filter params because game maker only supports 16 arguments lmao */
|
||||||
|
void FAudioGMS_EffectChain_AddReverb(
|
||||||
|
double effectChainID,
|
||||||
|
double wetDryMix,
|
||||||
|
double reflectionsDelay,
|
||||||
|
double reverbDelay,
|
||||||
|
double earlyDiffusion,
|
||||||
|
double lateDiffusion,
|
||||||
|
double lowEQGain,
|
||||||
|
double lowEQCutoff,
|
||||||
|
double highEQGain,
|
||||||
|
double highEQCutoff,
|
||||||
|
double reflectionsGain,
|
||||||
|
double reverbGain,
|
||||||
|
double decayTime,
|
||||||
|
double density,
|
||||||
|
double roomSize
|
||||||
|
) {
|
||||||
|
FAudioGMS_EffectChain* effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID);
|
||||||
|
|
||||||
|
if (effectChain != NULL)
|
||||||
|
{
|
||||||
|
FAudioFXReverbParameters reverbParams;
|
||||||
|
|
||||||
|
reverbParams.WetDryMix = wetDryMix;
|
||||||
|
reverbParams.ReflectionsDelay = reflectionsDelay;
|
||||||
|
reverbParams.ReverbDelay = reverbDelay;
|
||||||
|
reverbParams.RearDelay = FAUDIOFX_REVERB_DEFAULT_REAR_DELAY;
|
||||||
|
reverbParams.PositionLeft = FAUDIOFX_REVERB_DEFAULT_POSITION;
|
||||||
|
reverbParams.PositionRight = FAUDIOFX_REVERB_DEFAULT_POSITION;
|
||||||
|
reverbParams.PositionMatrixLeft = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX;
|
||||||
|
reverbParams.PositionMatrixRight = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX;
|
||||||
|
reverbParams.EarlyDiffusion = earlyDiffusion;
|
||||||
|
reverbParams.LateDiffusion = lateDiffusion;
|
||||||
|
reverbParams.LowEQGain = lowEQGain;
|
||||||
|
reverbParams.LowEQCutoff = lowEQCutoff;
|
||||||
|
reverbParams.HighEQGain = highEQGain;
|
||||||
|
reverbParams.HighEQCutoff = highEQCutoff;
|
||||||
|
reverbParams.RoomFilterFreq = 5000.0f;
|
||||||
|
reverbParams.RoomFilterMain = -10.0f;
|
||||||
|
reverbParams.RoomFilterHF = -1.0f;
|
||||||
|
reverbParams.ReflectionsGain = reflectionsGain;
|
||||||
|
reverbParams.ReverbGain = reverbGain;
|
||||||
|
reverbParams.DecayTime = decayTime;
|
||||||
|
reverbParams.Density = density;
|
||||||
|
reverbParams.RoomSize = roomSize;
|
||||||
|
|
||||||
|
FAudioGMS_INTERNAL_EffectChain_AddReverb(effectChain, &reverbParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain)
|
||||||
|
{
|
||||||
|
FAudioGMS_SoundInstance *instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
|
||||||
|
FAudioGMS_EffectChain *effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID);
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if (instance != NULL && effectChain != NULL)
|
||||||
|
{
|
||||||
|
if (!instance->effectChainAttached)
|
||||||
|
{
|
||||||
|
FAudio_CreateSubmixVoice(
|
||||||
|
device->handle,
|
||||||
|
&instance->effectVoice,
|
||||||
|
1, /* FIXME: is this correct? */
|
||||||
|
device->deviceDetails.OutputFormat.Format.nSamplesPerSec,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&effectChain->fAudioEffectChain);
|
||||||
|
|
||||||
|
instance->effectSends.SendCount = 2;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FAudioVoice_SetEffectChain(
|
||||||
|
instance->effectVoice,
|
||||||
|
&effectChain->fAudioEffectChain);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < effectChain->fAudioEffectChain.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);
|
||||||
|
|
||||||
|
/* TODO: move this to a different API call */
|
||||||
|
float *outputMatrix = instance->dspSettings.pMatrixCoefficients;
|
||||||
|
|
||||||
|
outputMatrix[0] = effectGain;
|
||||||
|
if (instance->dspSettings.SrcChannelCount == 2)
|
||||||
|
{
|
||||||
|
outputMatrix[1] = effectGain;
|
||||||
|
}
|
||||||
|
|
||||||
|
FAudioVoice_SetOutputMatrix(
|
||||||
|
instance->handle,
|
||||||
|
instance->effectVoice,
|
||||||
|
instance->dspSettings.SrcChannelCount,
|
||||||
|
1,
|
||||||
|
outputMatrix,
|
||||||
|
0);
|
||||||
|
|
||||||
|
instance->effectGain = effectGain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FAudioGMS_INTERNAL_EffectChain_Destroy(FAudioGMS_EffectChain *effectChain)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
if (effectChain != NULL)
|
||||||
|
{
|
||||||
|
device->effectChains[effectChain->id] = NULL;
|
||||||
|
IdStack_Push(&device->effectChainIndexStack, effectChain->id);
|
||||||
|
|
||||||
|
for (i = 0; i < effectChain->fAudioEffectChain.EffectCount; i += 1)
|
||||||
|
{
|
||||||
|
FAPOBase_Release((FAPOBase*)effectChain->fAudioEffectChain.pEffectDescriptors[i].pEffect);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(effectChain->effectParameters);
|
||||||
|
SDL_free(effectChain->effectTypes);
|
||||||
|
SDL_free(effectChain->fAudioEffectChain.pEffectDescriptors);
|
||||||
|
SDL_free(effectChain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAudioGMS_EffectChain_Destroy(double effectChainID)
|
||||||
|
{
|
||||||
|
FAudioGMS_EffectChain *effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID);
|
||||||
|
|
||||||
|
if (effectChain != NULL)
|
||||||
|
{
|
||||||
|
FAudioGMS_INTERNAL_EffectChain_Destroy(effectChain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FAudioGMS_Update()
|
void FAudioGMS_Update()
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -1532,6 +1695,11 @@ void FAudioGMS_Destroy()
|
||||||
FAudioGMS_INTERNAL_SoundInstance_Destroy(device->soundInstances[i]);
|
FAudioGMS_INTERNAL_SoundInstance_Destroy(device->soundInstances[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < device->effectChainCount; i += 1)
|
||||||
|
{
|
||||||
|
FAudioGMS_INTERNAL_EffectChain_Destroy(device->effectChains[i]);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < device->staticSoundCount; i += 1)
|
for (i = 0; i < device->staticSoundCount; i += 1)
|
||||||
{
|
{
|
||||||
FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[i]);
|
FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[i]);
|
||||||
|
|
|
@ -42,10 +42,10 @@ extern "C" {
|
||||||
FAUDIOGMSAPI void FAudioGMS_Init(double spatialDistanceScale, double timestep);
|
FAUDIOGMSAPI void FAudioGMS_Init(double spatialDistanceScale, double timestep);
|
||||||
|
|
||||||
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); /* 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 void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, double y, double z, double pitch, double volume); /* 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 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 double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double loop); /* returns a sound instance ID. must be freed! */
|
||||||
FAUDIOGMSAPI void FAudioGMS_StaticSound_Destroy(double staticSoundID);
|
FAUDIOGMSAPI void FAudioGMS_StaticSound_Destroy(double staticSoundID);
|
||||||
|
|
||||||
FAUDIOGMSAPI double FAudioGMS_StreamingSound_LoadOGG(char* filepath); /* returns a sound instance */
|
FAUDIOGMSAPI double FAudioGMS_StreamingSound_LoadOGG(char* filepath); /* returns a sound instance */
|
||||||
|
@ -58,7 +58,6 @@ FAUDIOGMSAPI void FAudioGMS_SoundInstance_StopImmediate(double soundInstanceID);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetPan(double soundInstanceID, double pan);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetPan(double soundInstanceID, double pan);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetPitch(double soundInstanceID, double pitch);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetPitch(double soundInstanceID, double pitch);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetVolume(double soundInstanceID, double volume);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetVolume(double soundInstanceID, double volume);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetReverb(double soundInstanceID, double reverb);
|
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetTrackPosition(double soundInstanceID, double trackPositionInSeconds);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetTrackPosition(double soundInstanceID, double trackPositionInSeconds);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetVolumeOverTime(double soundInstanceID, double volume, double milliseconds);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetVolumeOverTime(double soundInstanceID, double volume, double milliseconds);
|
||||||
|
@ -73,6 +72,29 @@ FAUDIOGMSAPI double FAudioGMS_SoundInstance_GetTrackLengthInSeconds(double sound
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Destroy(double soundInstanceID);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Destroy(double soundInstanceID);
|
||||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double soundInstanceID);
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double soundInstanceID);
|
||||||
|
|
||||||
|
FAUDIOGMSAPI double FAudioGMS_EffectChain_Create();
|
||||||
|
FAUDIOGMSAPI void FAudioGMS_EffectChain_AddDefaultReverb(double effectChainID);
|
||||||
|
FAUDIOGMSAPI void FAudioGMS_EffectChain_AddReverb(
|
||||||
|
double effectChainID,
|
||||||
|
double wetDryMix,
|
||||||
|
double reflectionsDelay,
|
||||||
|
double reverbDelay,
|
||||||
|
double earlyDiffusion,
|
||||||
|
double lateDiffusion,
|
||||||
|
double lowEQGain,
|
||||||
|
double lowEQCutoff,
|
||||||
|
double highEQGain,
|
||||||
|
double highEQCutoff,
|
||||||
|
double reflectionsGain,
|
||||||
|
double reverbGain,
|
||||||
|
double decayTime,
|
||||||
|
double density,
|
||||||
|
double roomSize
|
||||||
|
);
|
||||||
|
FAUDIOGMSAPI void FAudioGMS_EffectChain_Destroy(double effectChainID);
|
||||||
|
|
||||||
|
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, 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_StopAll();
|
FAUDIOGMSAPI void FAudioGMS_StopAll();
|
||||||
|
|
Loading…
Reference in New Issue