diff --git a/src/i_sound.h b/src/i_sound.h index 7a5b826d2..60d82f62f 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -18,6 +18,14 @@ #include "sounds.h" #include "command.h" +#ifdef HAVE_OPENAL +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/alext.h" +#include "AL/efx.h" +#include "AL/efx-presets.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -37,6 +45,36 @@ typedef enum { MU_MID_EX, // Non-native MIDI } musictype_t; +typedef enum +{ + EFFECT_NONE = 0, + EFFECT_REVERB, + EFFECT_DISTORTION, +} effecttypes_t; + +typedef struct +{ + // flags for effects +#ifdef HAVE_OPENAL + ALuint effect; + ALuint slot; +#endif + UINT32 type; + float var1; + float var2; + float var3; + float var4; + float var5; + float var6; + float var7; + float var8; + float var9; + float var10; + float var11; + float var12; + float var13; +} efx_t; + /** \brief Sound subsystem runing and waiting */ extern UINT8 sound_started; @@ -83,7 +121,7 @@ void I_ShutdownSound(void); \return sfx handle */ -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel); +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel, efx_t *efx); /** \brief Stops a sound channel. @@ -105,6 +143,8 @@ void I_UpdateSound(void); */ boolean I_SoundIsPlaying(INT32 handle); + + /** \brief Updates the sfx handle \param handle sfx handle @@ -114,7 +154,7 @@ boolean I_SoundIsPlaying(INT32 handle); \return void */ -void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch); +void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch, efx_t *efx); /** \brief The I_SetSfxVolume function @@ -246,6 +286,9 @@ boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void)); boolean I_FadeOutStopSong(UINT32 ms); boolean I_FadeInPlaySong(UINT32 ms, boolean looping); +efx_t *I_CreateEFX(efx_t *efx); +void I_DeleteEFX(efx_t *efx); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/p_enemy.c b/src/p_enemy.c index 22b41afbe..59ffab2d3 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -15,6 +15,7 @@ #include "dehacked.h" #include "doomdef.h" #include "g_game.h" +#include "i_sound.h" #include "p_local.h" #include "p_setup.h" #include "r_main.h" @@ -3233,11 +3234,23 @@ void A_AttractChase(void *thing) actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true); actor->target->player->ringtime += K_GetKartRingPower(actor->target->player, true); +//#define EFXTEST +#ifdef EFXTEST + efx_t efx; + S_InitEFXArray(&efx); + efx.type = EFFECT_REVERB; + S_StartSoundAtVolumeEx(actor->target, sfx_s1b5, actor->target->player->ringvolume, &efx); +#else S_StartSoundAtVolume(actor->target, sfx_s1b5, actor->target->player->ringvolume); +#endif if (actor->target->player->rings <= 10) { +#ifdef EFXTEST + S_StartSoundAtVolumeEx(actor->target, sfx_ringlw, 255 - actor->target->player->rings*10, &efx); +#else S_StartSoundAtVolume(actor->target, sfx_ringlw, 255 - actor->target->player->rings*10); +#endif } if (actor->target->player->ringboost > (4*TICRATE + TICRATE/2)) diff --git a/src/s_sound.c b/src/s_sound.c index 79cda0d74..6c518c1ea 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -317,6 +317,7 @@ static void SetChannelsNum(void) { channels[i].sfxinfo = 0; channels[i].origin = NULL; + channels[i].efx = NULL; } S_ResetCaptions(); @@ -525,7 +526,7 @@ static INT32 S_ScaleVolumeWithSplitscreen(INT32 volume) ) / FRACUNIT; } -void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) +void S_StartSoundAtVolumeEx(const void *origin_p, sfxenum_t sfx_id, INT32 volume, efx_t *efx) { const mobj_t *origin = (const mobj_t *)origin_p; const sfxenum_t actual_id = sfx_id; @@ -730,7 +731,17 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) channels[cnum].sfxinfo = sfx; channels[cnum].origin = origin; channels[cnum].volume = initial_volume; - channels[cnum].handle = I_StartSound(sfx_id, S_GetSoundVolume(sfx, volume), sep, pitch, priority, cnum); + + if (efx != NULL && efx->type != EFFECT_NONE) + { + channels[cnum].efx = I_CreateEFX(efx); + } + else + { + channels[cnum].efx = NULL; + } + + channels[cnum].handle = I_StartSound(sfx_id, S_GetSoundVolume(sfx, volume), sep, pitch, priority, cnum, channels[cnum].efx); } } @@ -951,7 +962,7 @@ notinlevel: } if (audible) - I_UpdateSoundParams(c->handle, S_GetSoundVolume(c->sfxinfo, volume), sep, pitch); + I_UpdateSoundParams(c->handle, S_GetSoundVolume(c->sfxinfo, volume), sep, pitch, c->efx); else S_StopChannel(cnum); } @@ -1021,6 +1032,8 @@ static void S_StopChannel(INT32 cnum) } c->origin = NULL; + I_DeleteEFX(c->efx); + c->efx = NULL; } // @@ -2943,3 +2956,15 @@ void ModFilter_OnChange(void) openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value); } #endif + +void S_InitEFXArray(efx_t *efx) +{ + if (efx == NULL) + return; + + efx->type = EFFECT_NONE; + efx->var1 = efx->var2 = efx->var3 = -255; + efx->var4 = efx->var5 = efx->var6 = -255; + efx->var7 = efx->var8 = efx->var9 = -255; + efx->var10 = efx->var11 = efx->var12 = efx->var13 = -255; +} diff --git a/src/s_sound.h b/src/s_sound.h index c038e5375..2f471a19a 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -88,6 +88,8 @@ struct channel_t // handle of the sound being played INT32 handle; + // EFX + efx_t *efx; }; struct caption_t { @@ -139,7 +141,8 @@ boolean S_SoundDisabled(void); void S_StartSound(const void *origin, sfxenum_t sound_id); // Will start a sound at a given volume. -void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume); +void S_StartSoundAtVolumeEx(const void *origin_p, sfxenum_t sfx_id, INT32 volume, efx_t *efx); +#define S_StartSoundAtVolume(origin, sound_id, volume) S_StartSoundAtVolumeEx(origin, sound_id, volume, NULL) // Stop sound for thing at void S_StopSound(void *origin); @@ -345,6 +348,8 @@ void S_StartSoundName(void *mo, const char *soundname); void S_StopSoundByID(void *origin, sfxenum_t sfx_id); void S_StopSoundByNum(sfxenum_t sfxnum); +void S_InitEFXArray(efx_t *efx); + #ifndef HW3SOUND #define S_StartAttackSound S_StartSound #define S_StartScreamSound S_StartSound diff --git a/src/sdl/al_sound.c b/src/sdl/al_sound.c index 2bd57b89e..e71388abc 100644 --- a/src/sdl/al_sound.c +++ b/src/sdl/al_sound.c @@ -391,14 +391,6 @@ void I_StartupSound(void) LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv); #undef LOAD_PROC - // Start EFX - // TODO: Discuss and see if we even want EFX flags for sounds and implement system if so. - //alGenEffects(1, &audio.effect); - //TRY(alEffecti, audio.effect, AL_EFFECT_TYPE, AL_EFFECT_DISTORTION); - //TRY(alEffectf, audio.effect, AL_DISTORTION_EDGE, AL_DISTORTION_MAX_EDGE); - //alGenAuxiliaryEffectSlots(1, &audio.effectslot); - //alAuxiliaryEffectSloti(audio.effectslot, AL_EFFECTSLOT_EFFECT, audio.effect); - audio.music = INVALID_HANDLE; audio.bufferindex = 0; @@ -984,7 +976,7 @@ void I_FreeSfx(sfxinfo_t *sfx) sfx->lumpnum = LUMPERROR; } -void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch) +void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch, efx_t *efx) { if (handle == INVALID_HANDLE) return; @@ -1003,9 +995,14 @@ void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch) pan = pan * 0.5f; // 0.5 = sin(30') for a +/- 30 degree arc TRY(alSourcei, source, AL_SOURCE_RELATIVE, AL_TRUE); TRY(alSource3f, source, AL_POSITION, pan, 0, -sqrtf(1.0f - pan*pan)); + + if (efx != NULL && TRY(alIsEffect, efx->effect) && TRY(alIsAuxiliaryEffectSlot, efx->slot)) + { + TRY(alSource3i, source, AL_AUXILIARY_SEND_FILTER, efx->slot, 0, AL_FILTER_NULL); + } } -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel, efx_t *efx) { ALuint source; if (!TRY(alGenSources, 1, &source)) @@ -1023,7 +1020,7 @@ INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priori return INVALID_HANDLE; } - I_UpdateSoundParams(source, vol, sep, pitch); + I_UpdateSoundParams(source, vol, sep, pitch, efx); if (!TRY(alSourcePlay, source)) { @@ -1898,4 +1895,100 @@ boolean I_FadeInPlaySong(UINT32 ms, boolean looping) return false; } +efx_t *I_CreateEFX(efx_t *efx) +{ + LOCKAUDIO; + + efx_t *efxc = Z_Calloc(sizeof(efx_t), PU_STATIC, NULL); + + if (efxc == NULL) + I_Error("OpenAL: Ran out of memory generating EFX.\n"); + + if (efx != NULL) + memcpy(efxc, efx, sizeof(efx_t)); + + // Init effects and slots. + TRY(alGenEffects, 1, &efxc->effect); + TRY(alGenAuxiliaryEffectSlots, 1, &efxc->slot); + + if (TRY(alIsEffect, efxc->effect) && TRY(alIsAuxiliaryEffectSlot, efxc->slot)) + { + switch (efxc->type) + { + case EFFECT_REVERB: + TRY(alEffecti, efxc->effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); + + if (efxc->var1 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_DENSITY, efxc->var1); + if (efxc->var2 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_DIFFUSION, efxc->var2); + if (efxc->var3 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_GAIN, efxc->var3); + if (efxc->var4 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_GAINHF, efxc->var4); + if (efxc->var5 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_DECAY_TIME, efxc->var5); + if (efxc->var6 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_DECAY_HFRATIO, efxc->var6); + if (efxc->var7 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_REFLECTIONS_GAIN, efxc->var7); + if (efxc->var8 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_REFLECTIONS_DELAY, efxc->var8); + if (efxc->var9 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_LATE_REVERB_GAIN, efxc->var9); + if (efxc->var10 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_LATE_REVERB_DELAY, efxc->var10); + if (efxc->var11 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_AIR_ABSORPTION_GAINHF, efxc->var11); + if (efxc->var12 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, efxc->var12); + if (efxc->var13 != -255) + TRY(alEffectf, efxc->effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, efxc->var13); + + break; + case EFFECT_DISTORTION: + TRY(alEffecti, efxc->effect, AL_EFFECT_TYPE, AL_EFFECT_DISTORTION); + + if (efxc->var1 != -255) + TRY(alEffectf, efxc->effect, AL_DISTORTION_EDGE, efxc->var1); + if (efxc->var2 != -255) + TRY(alEffectf, efxc->effect, AL_DISTORTION_GAIN, efxc->var2); + if (efxc->var3 != -255) + TRY(alEffectf, efxc->effect, AL_DISTORTION_LOWPASS_CUTOFF, efxc->var3); + if (efxc->var4 != -255) + TRY(alEffectf, efxc->effect, AL_DISTORTION_EQCENTER, efxc->var4); + if (efxc->var5 != -255) + TRY(alEffectf, efxc->effect, AL_DISTORTION_EQBANDWIDTH, efxc->var5); + break; + } + + TRY(alAuxiliaryEffectSloti, efxc->slot, AL_EFFECTSLOT_EFFECT, efxc->effect); + return efxc; + } + + Z_Free(efxc); + + return NULL; +} + +void I_DeleteEFX(efx_t *efx) +{ + LOCKAUDIO; + + if (efx == NULL) + return; + + if (TRY(alIsEffect, efx->effect)) + { + TRY(alDeleteEffects, 1, &efx->effect); + } + + if (TRY(alIsAuxiliaryEffectSlot, efx->slot)) + { + TRY(alDeleteAuxiliaryEffectSlots, 1, &efx->slot); + } + + Z_Free(efx); +} + #endif // defined(HAVE_OPENAL)