more API goodies

mastering_effects
cosmonaut 2021-10-26 16:47:53 -07:00
parent bb9b1fef65
commit 0f9bcbc36f
2 changed files with 226 additions and 32 deletions

View File

@ -203,6 +203,7 @@ typedef struct FAudioGMS_StaticSound
uint32_t samplesPerSecond; uint32_t samplesPerSecond;
uint32_t loopStart; uint32_t loopStart;
uint32_t loopLength; uint32_t loopLength;
uint32_t lengthInSeconds;
} FAudioGMS_StaticSound; } FAudioGMS_StaticSound;
typedef struct FAudioGMS_StreamingSound typedef struct FAudioGMS_StreamingSound
@ -233,6 +234,10 @@ typedef struct FAudioGMS_SoundInstance
FAudioSubmixVoice* reverbVoice; FAudioSubmixVoice* reverbVoice;
FAudioVoiceSends reverbSends; FAudioVoiceSends reverbSends;
uint8_t adjustingVolumeOverTime;
float targetVolume;
float volumeDelta;
uint8_t isStatic; uint8_t isStatic;
uint8_t destroyOnFinish; uint8_t destroyOnFinish;
@ -274,6 +279,7 @@ typedef struct FAudioGMS_Device
IdStack soundInstanceIndexStack; IdStack soundInstanceIndexStack;
float streamStagingBuffer[STREAMING_BUFFER_SIZE]; float streamStagingBuffer[STREAMING_BUFFER_SIZE];
double timestep;
} FAudioGMS_Device; } FAudioGMS_Device;
static FAudioGMS_Device* device = NULL; static FAudioGMS_Device* device = NULL;
@ -304,7 +310,7 @@ static inline FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_LookupSoundInstance(ui
} }
} }
void FAudioGMS_Init(double spatialDistanceScale) void FAudioGMS_Init(double spatialDistanceScale, double timestep)
{ {
device = SDL_malloc(sizeof(FAudioGMS_Device)); device = SDL_malloc(sizeof(FAudioGMS_Device));
@ -407,6 +413,8 @@ void FAudioGMS_Init(double spatialDistanceScale)
device->soundInstanceCount = 0; device->soundInstanceCount = 0;
IdStack_Init(&device->soundInstanceIndexStack); IdStack_Init(&device->soundInstanceIndexStack);
device->timestep = timestep;
Log("FAudio initialized successfully!"); Log("FAudio initialized successfully!");
printf("Device: %ls", device->deviceDetails.DisplayName); printf("Device: %ls", device->deviceDetails.DisplayName);
fflush(stdout); fflush(stdout);
@ -494,6 +502,8 @@ double FAudioGMS_StaticSound_LoadWAV(char *filePath)
sound->loopStart = 0; sound->loopStart = 0;
sound->loopLength = 0; sound->loopLength = 0;
sound->lengthInSeconds = frameCount / sound->samplesPerSecond;
if (device->staticSoundIndexStack.count > 0) if (device->staticSoundIndexStack.count > 0)
{ {
sound->id = IdStack_Pop(&device->staticSoundIndexStack); sound->id = IdStack_Pop(&device->staticSoundIndexStack);
@ -802,6 +812,10 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_Init(
instance->soundState = SoundState_Stopped; instance->soundState = SoundState_Stopped;
instance->adjustingVolumeOverTime = 0;
instance->volumeDelta = 0;
instance->targetVolume = 1;
instance->is3D = 0; instance->is3D = 0;
instance->emitter = NULL; instance->emitter = NULL;
instance->stereoAzimuth[0] = 0.0f; instance->stereoAzimuth[0] = 0.0f;
@ -1102,19 +1116,20 @@ double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double
} }
} }
void FAudioGMS_SoundInstance_Play(double id) void FAudioGMS_SoundInstance_Play(double soundInstanceID, double loop)
{ {
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL) if (instance != NULL)
{ {
instance->loop = (uint8_t) loop;
FAudioGMS_INTERNAL_SoundInstance_Play(instance); FAudioGMS_INTERNAL_SoundInstance_Play(instance);
} }
} }
void FAudioGMS_SoundInstance_Pause(double id) void FAudioGMS_SoundInstance_Pause(double soundInstanceID)
{ {
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL) if (instance != NULL)
{ {
@ -1147,9 +1162,9 @@ static void FAudioGMS_INTERNAL_SoundInstance_Stop(FAudioGMS_SoundInstance* insta
} }
} }
void FAudioGMS_SoundInstance_Stop(double id) void FAudioGMS_SoundInstance_Stop(double soundInstanceID)
{ {
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
FAudioGMS_INTERNAL_SoundInstance_Stop(instance); FAudioGMS_INTERNAL_SoundInstance_Stop(instance);
} }
@ -1173,12 +1188,52 @@ static void FAudioGMS_INTERNAL_SoundInstance_StopImmediate(FAudioGMS_SoundInstan
} }
} }
void FAudioGMS_SoundInstance_StopImmediate(double id) void FAudioGMS_SoundInstance_StopImmediate(double soundInstanceID)
{ {
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
FAudioGMS_INTERNAL_SoundInstance_StopImmediate(instance); FAudioGMS_INTERNAL_SoundInstance_StopImmediate(instance);
} }
void FAudioGMS_SoundInstance_SetPan(double soundInstanceID, double pan)
{
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL)
{
FAudioGMS_INTERNAL_SoundInstance_SetPan(instance, pan);
}
}
void FAudioGMS_SoundInstance_SetPitch(double soundInstanceID, double pitch)
{
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL)
{
FAudioGMS_INTERNAL_SoundInstance_SetPitch(instance, pitch);
}
}
void FAudioGMS_SoundInstance_SetVolume(double soundInstanceID, double volume)
{
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL)
{
FAudioGMS_INTERNAL_SoundInstance_SetVolume(instance, 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);
@ -1201,6 +1256,100 @@ void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, dou
} }
} }
void FAudioGMS_SoundInstance_SetTrackPosition(double soundInstanceID, double trackPositionInSeconds)
{
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL)
{
uint32_t sampleFrame = instance->soundData.staticSound->samplesPerSecond * trackPositionInSeconds;
FAudioGMS_SoundState currentState = instance->soundState;
if (currentState == SoundState_Playing)
{
FAudioGMS_INTERNAL_SoundInstance_StopImmediate(instance);
}
if (instance->isStatic)
{
instance->soundData.staticSound->buffer.PlayBegin = instance->soundData.staticSound->samplesPerSecond * trackPositionInSeconds;
}
else
{
stb_vorbis_seek(instance->soundData.streamingSound.fileHandle, sampleFrame);
}
if (currentState == SoundState_Playing)
{
FAudioGMS_INTERNAL_SoundInstance_Play(instance);
}
}
}
void FAudioGMS_SoundInstance_SetVolumeOverTime(double soundInstanceID, double volume, double milliseconds)
{
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);\
if (instance != NULL)
{
instance->adjustingVolumeOverTime = 1;
instance->targetVolume = volume;
instance->volumeDelta = (volume - instance->volume) / (milliseconds / device->timestep);
}
}
double FAudioGMS_SoundInstance_GetPitch(double soundInstanceID)
{
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL)
{
return instance->pitch;
}
else
{
Log("Invalid sound instance!");
return -1;
}
}
double FAudioGMS_SoundInstance_GetVolume(double soundInstanceID)
{
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL)
{
return instance->volume;
}
else
{
Log("Invalid sound instance!");
return -1;
}
}
double FAudioGMS_SoundInstance_GetTrackLengthInSeconds(double soundInstanceID)
{
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL)
{
if (instance->isStatic)
{
return instance->soundData.staticSound->lengthInSeconds;
}
else
{
return stb_vorbis_stream_length_in_seconds(instance->soundData.streamingSound.fileHandle);
}
}
else
{
Log("Invalid sound instance!");
return -1;
}
}
void FAudioGMS_SetListenerPosition(double x, double y, double z) void FAudioGMS_SetListenerPosition(double x, double y, double z)
{ {
device->listener.Velocity.x = x - device->listener.Position.x; device->listener.Velocity.x = x - device->listener.Position.x;
@ -1234,9 +1383,9 @@ static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* in
} }
} }
void FAudioGMS_SoundInstance_Destroy(double id) void FAudioGMS_SoundInstance_Destroy(double soundInstanceID)
{ {
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL) if (instance != NULL)
{ {
@ -1244,9 +1393,9 @@ void FAudioGMS_SoundInstance_Destroy(double id)
} }
} }
void FAudioGMS_SoundInstance_DestroyWhenFinished(double id) void FAudioGMS_SoundInstance_DestroyWhenFinished(double soundInstanceID)
{ {
FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
if (instance != NULL) if (instance != NULL)
{ {
@ -1266,16 +1415,10 @@ static void FAudioGMS_INTERNAL_StaticSound_Destroy(FAudioGMS_StaticSound* sound)
} }
} }
void FAudioGMS_StaticSound_Destroy(double id) void FAudioGMS_StaticSound_Destroy(double staticSoundID)
{ {
if (id >= 0 && id < device->staticSoundCount) FAudioGMS_StaticSound *sound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID);
{ FAudioGMS_INTERNAL_StaticSound_Destroy(sound);
FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[(uint32_t)id]);
}
else
{
Log("Invalid ID for destroy!");
}
} }
void FAudioGMS_Update() void FAudioGMS_Update()
@ -1293,6 +1436,33 @@ void FAudioGMS_Update()
FAudioGMS_INTERNAL_Apply3D(instance); FAudioGMS_INTERNAL_Apply3D(instance);
} }
if (instance->adjustingVolumeOverTime)
{
float volume = instance->volume + instance->volumeDelta;
if (instance->volumeDelta > 0)
{
if (volume >= instance->targetVolume)
{
volume = instance->targetVolume;
instance->adjustingVolumeOverTime = 0;
}
}
else if (instance->volumeDelta < 0)
{
if (volume <= instance->targetVolume)
{
volume = instance->targetVolume;
instance->adjustingVolumeOverTime = 0;
}
}
else
{
instance->adjustingVolumeOverTime = 0;
}
FAudioGMS_INTERNAL_SoundInstance_SetVolume(instance, volume);
}
/* Update streaming instance */ /* Update streaming instance */
if (!instance->isStatic && instance->soundState == SoundState_Playing) if (!instance->isStatic && instance->soundState == SoundState_Playing)
{ {
@ -1313,9 +1483,19 @@ void FAudioGMS_Update()
} }
} }
void FAudioGMS_StopAll()
{
uint32_t i;
for (i = 0; i < device->soundInstanceCount; i += 1)
{
FAudioGMS_INTERNAL_SoundInstance_StopImmediate(device->soundInstances[i]);
}
}
void FAudioGMS_Destroy() void FAudioGMS_Destroy()
{ {
uint32_t i = 0; uint32_t i;
for (i = 0; i < device->soundInstanceCount; i += 1) for (i = 0; i < device->soundInstanceCount; i += 1)
{ {

View File

@ -39,27 +39,41 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
FAUDIOGMSAPI void FAudioGMS_Init(double spatialDistanceScale); /* recommend about 50 for a 2D game, 1 for a 3D game */ 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, 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 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 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_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 */
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Play(double id); FAUDIOGMSAPI void FAudioGMS_SoundInstance_Play(double soundInstanceID, double loop);
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Pause(double id); FAUDIOGMSAPI void FAudioGMS_SoundInstance_Pause(double soundInstanceID);
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Stop(double id); FAUDIOGMSAPI void FAudioGMS_SoundInstance_Stop(double soundInstanceID);
FAUDIOGMSAPI void FAudioGMS_SoundInstance_StopImmediate(double id); FAUDIOGMSAPI void FAudioGMS_SoundInstance_StopImmediate(double soundInstanceID);
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetPan(double soundInstanceID, double pan);
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetPitch(double soundInstanceID, double pitch);
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_Destroy(double id); FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetTrackPosition(double soundInstanceID, double trackPositionInSeconds);
FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double id); FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetVolumeOverTime(double soundInstanceID, double volume, double milliseconds);
FAUDIOGMSAPI double FAudioGMS_SoundInstance_GetPitch(double soundInstanceID);
FAUDIOGMSAPI double FAudioGMS_SoundInstance_GetVolume(double soundInstanceID);
FAUDIOGMSAPI double FAudioGMS_SoundInstance_GetTrackLengthInSeconds(double soundInstanceID);
FAUDIOGMSAPI void FAudioGMS_SoundInstance_Destroy(double soundInstanceID);
FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double soundInstanceID);
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_Update(); FAUDIOGMSAPI void FAudioGMS_Update();
FAUDIOGMSAPI void FAudioGMS_Destroy(); FAUDIOGMSAPI void FAudioGMS_Destroy();