diff --git a/src/deh_soc.c b/src/deh_soc.c index 29e567d4e..7936ce78d 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -804,6 +804,454 @@ static mapheader_lighting_t *usemaplighting(INT32 mapnum, const char *word) } } +static void processvector(char *word2, f_vector3_t *vec, SINT8 num) +{ + char *tmp = strtok(word2,","); + float vector[num]; + int i = 0; + + do { + if (i >= num) + break; + vector[i++] = atof(tmp); + } while ((tmp = strtok(NULL, ",")) != NULL); + + vec->x = vector[0]; + vec->y = vector[1]; + vec->z = vector[2]; +} + +// Handle parsing globalefx info +static void globalmapefxparameters(INT32 mapnum, INT32 i, char *word, char *word2) +{ + // Take off GLOBALEFX_ + word += 10; + + // Check and take off effect name + if (fastncmp(word, "EAXREVERB_", 10)) + { + word += 10; + + if (fastcmp(word, "DENSITY")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.density = atof(word2); + } + else if (fastcmp(word, "DIFFUSION")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.diffusion = atof(word2); + } + else if (fastcmp(word, "GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.gain = atof(word2); + } + else if (fastcmp(word, "GAINHF")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.gainhf = atof(word2); + } + else if (fastcmp(word, "GAINLF")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.gainlf = atof(word2); + } + else if (fastcmp(word, "DECAY_TIME")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.decay_time = atof(word2); + } + else if (fastcmp(word, "DECAY_HFRATIO")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.decay_hfratio = atof(word2); + } + else if (fastcmp(word, "DECAY_LFRATIO")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.decay_lfratio = atof(word2); + } + else if (fastcmp(word, "REFLECTIONS_GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.reflections_gain = atof(word2); + } + else if (fastcmp(word, "REFLECTIONS_DELAY")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.reflections_delay = atof(word2); + } + else if (fastcmp(word, "REFLECTIONS_PAN")) + { + processvector(word2, &mapheaderinfo[mapnum]->globalEFX->eaxreverb.reflections_pan, 3); + } + else if (fastcmp(word, "LATE_REVERB_GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.late_reverb_gain = atof(word2); + } + else if (fastcmp(word, "LATE_REVERB_DELAY")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.late_reverb_gain = atof(word2); + } + else if (fastcmp(word, "LATE_REVERB_PAN")) + { + processvector(word2, &mapheaderinfo[mapnum]->globalEFX->eaxreverb.late_reverb_pan, 3); + } + else if (fastcmp(word, "ECHO_TIME")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.echo_time = atof(word2); + } + else if (fastcmp(word, "ECHO_DEPTH")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.echo_depth = atof(word2); + } + else if (fastcmp(word, "MODULATION_TIME")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.modulation_time = atof(word2); + } + else if (fastcmp(word, "MODULATION_DEPTH")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.modulation_depth = atof(word2); + } + else if (fastcmp(word, "AIR_ABSORPTION_GAINHF")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.air_absorption_gainhf = atof(word2); + } + else if (fastcmp(word, "HFREFERENCE")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.hfreference = atof(word2); + } + else if (fastcmp(word, "LFREFERENCE")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.lfreference = atof(word2); + } + else if (fastcmp(word, "ROOM_ROLLOFF_FACTOR")) + { + mapheaderinfo[mapnum]->globalEFX->eaxreverb.room_rolloff_factor = atof(word2); + } + else if (fastcmp(word, "DECAY_HFLIMIT")) + { + if (i || word2[0] == 'T' || word2[0] == 'O') + mapheaderinfo[mapnum]->globalEFX->eaxreverb.decay_hflimit = 1; + else + mapheaderinfo[mapnum]->globalEFX->eaxreverb.decay_hflimit = 0; + } + } + else if (fastncmp(word, "REVERB_", 7)) + { + word += 7; + + if (fastcmp(word, "DENSITY")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.density = atof(word2); + } + else if (fastcmp(word, "DIFFUSION")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.diffusion = atof(word2); + } + else if (fastcmp(word, "GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.gain = atof(word2); + } + else if (fastcmp(word, "GAINHF")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.gainhf = atof(word2); + } + else if (fastcmp(word, "DECAY_TIME")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.decay_time = atof(word2); + } + else if (fastcmp(word, "DECAY_HFRATIO")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.decay_hfratio = atof(word2); + } + else if (fastcmp(word, "REFLECTIONS_GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.reflections_gain = atof(word2); + } + else if (fastcmp(word, "REFLECTIONS_DELAY")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.reflections_delay = atof(word2); + } + else if (fastcmp(word, "LATE_REVERB_GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.late_reverb_gain = atof(word2); + } + else if (fastcmp(word, "LATE_REVERB_DELAY")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.late_reverb_delay = atof(word2); + } + else if (fastcmp(word, "AIR_ABSORPTION_GAINHF")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.air_absorption_gainhf = atof(word2); + } + else if (fastcmp(word, "ROOM_ROLLOFF_FACTOR")) + { + mapheaderinfo[mapnum]->globalEFX->reverb.room_rolloff_factor = atof(word2); + } + else if (fastcmp(word, "DECAY_HFLIMIT")) + { + if (i || word2[0] == 'T' || word2[0] == 'O') + mapheaderinfo[mapnum]->globalEFX->reverb.decay_hflimit = 1; + else + mapheaderinfo[mapnum]->globalEFX->reverb.decay_hflimit = 0; + } + } + else if (fastncmp(word, "CHORUS_", 7)) + { + word += 7; + + if (fastcmp(word, "WAVEFORM")) + { + mapheaderinfo[mapnum]->globalEFX->chorus.waveform = get_number(word2); + } + else if (fastcmp(word, "PHASE")) + { + mapheaderinfo[mapnum]->globalEFX->chorus.phase = i; + } + else if (fastcmp(word, "RATE")) + { + mapheaderinfo[mapnum]->globalEFX->chorus.rate = atof(word2); + } + else if (fastcmp(word, "DEPTH")) + { + mapheaderinfo[mapnum]->globalEFX->chorus.depth = atof(word2); + } + else if (fastcmp(word, "FEEDBACK")) + { + mapheaderinfo[mapnum]->globalEFX->chorus.feedback = atof(word2); + } + else if (fastcmp(word, "DELAY")) + { + mapheaderinfo[mapnum]->globalEFX->chorus.delay = atof(word2); + } + } + else if (fastncmp(word, "DISTORTION_", 11)) + { + word += 11; + + if (fastcmp(word, "EDGE")) + { + mapheaderinfo[mapnum]->globalEFX->distortion.edge = atof(word2); + } + else if (fastcmp(word, "GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->distortion.gain = atof(word2); + } + else if (fastcmp(word, "LOWPASS_CUTOFF")) + { + mapheaderinfo[mapnum]->globalEFX->distortion.lowpass_cutoff = atof(word2); + } + else if (fastcmp(word, "EQCENTER")) + { + mapheaderinfo[mapnum]->globalEFX->distortion.eqcenter = atof(word2); + } + else if (fastcmp(word, "EQBANDWIDTH")) + { + mapheaderinfo[mapnum]->globalEFX->distortion.eqbandwidth = atof(word2); + } + } + else if (fastncmp(word, "ECHO_", 5)) + { + word += 5; + + if (fastcmp(word, "DELAY")) + { + mapheaderinfo[mapnum]->globalEFX->echo.delay = atof(word2); + } + else if (fastcmp(word, "LRDELAY")) + { + mapheaderinfo[mapnum]->globalEFX->echo.lrdelay = atof(word2); + } + else if (fastcmp(word, "DAMPING")) + { + mapheaderinfo[mapnum]->globalEFX->echo.damping = atof(word2); + } + else if (fastcmp(word, "FEEDBACK")) + { + mapheaderinfo[mapnum]->globalEFX->echo.feedback = atof(word2); + } + else if (fastcmp(word, "SPREAD")) + { + mapheaderinfo[mapnum]->globalEFX->echo.spread = atof(word2); + } + } + else if (fastncmp(word, "FLANGER_", 8)) + { + word += 8; + + if (fastcmp(word, "WAVEFORM")) + { + mapheaderinfo[mapnum]->globalEFX->flanger.waveform = get_number(word2); + } + else if (fastcmp(word, "PHASE")) + { + mapheaderinfo[mapnum]->globalEFX->flanger.phase = i; + } + else if (fastcmp(word, "RATE")) + { + mapheaderinfo[mapnum]->globalEFX->flanger.rate = atof(word2); + } + else if (fastcmp(word, "DEPTH")) + { + mapheaderinfo[mapnum]->globalEFX->flanger.depth = atof(word2); + } + else if (fastcmp(word, "FEEDBACK")) + { + mapheaderinfo[mapnum]->globalEFX->flanger.feedback = atof(word2); + } + else if (fastcmp(word, "DELAY")) + { + mapheaderinfo[mapnum]->globalEFX->flanger.delay = atof(word2); + } + } + else if (fastncmp(word, "FREQSHIFT_", 10)) + { + word += 10; + + if (fastcmp(word, "FREQUENCY")) + { + mapheaderinfo[mapnum]->globalEFX->freqshift.frequency = atof(word2); + } + else if (fastcmp(word, "LEFT_DIRECTION")) + { + mapheaderinfo[mapnum]->globalEFX->freqshift.left_direction = get_number(word2); + } + else if (fastcmp(word, "RIGHT_DIRECTION")) + { + mapheaderinfo[mapnum]->globalEFX->freqshift.right_direction = get_number(word2); + } + } + else if (fastncmp(word, "VOCALMORPH_", 11)) + { + word += 11; + + if (fastcmp(word, "PHONEMEA")) + { + mapheaderinfo[mapnum]->globalEFX->vocal_morpher.phonemea = i; + } + else if (fastcmp(word, "PHONEMEB")) + { + mapheaderinfo[mapnum]->globalEFX->vocal_morpher.phonemeb = i; + } + else if (fastcmp(word, "PHONEMEA_COARSE_TUNING")) + { + mapheaderinfo[mapnum]->globalEFX->vocal_morpher.phonemea_coarse_tuning = i; + } + else if (fastcmp(word, "PHONEMEB_COARSE_TUNING")) + { + mapheaderinfo[mapnum]->globalEFX->vocal_morpher.phonemeb_coarse_tuning = i; + } + else if (fastcmp(word, "WAVEFORM")) + { + mapheaderinfo[mapnum]->globalEFX->vocal_morpher.waveform = get_number(word2); + } + else if (fastcmp(word, "RATE")) + { + mapheaderinfo[mapnum]->globalEFX->vocal_morpher.rate = atof(word2); + } + } + else if (fastncmp(word, "PITCHSHIFT_", 11)) + { + word += 11; + + if (fastcmp(word, "COARSE_TUNE")) + { + mapheaderinfo[mapnum]->globalEFX->pitchshift.coarse_tune = i; + } + else if (fastcmp(word, "FINE_TUNE")) + { + mapheaderinfo[mapnum]->globalEFX->pitchshift.fine_tune = i; + } + } + else if (fastncmp(word, "RINGMOD_", 8)) + { + word += 8; + + if (fastcmp(word, "FREQUENCY")) + { + mapheaderinfo[mapnum]->globalEFX->ringmod.frequency = atof(word2); + } + else if (fastcmp(word, "HIGHPASS_CUTOFF")) + { + mapheaderinfo[mapnum]->globalEFX->ringmod.highpass_cutoff = atof(word2); + } + else if (fastcmp(word, "WAVEFORM")) + { + mapheaderinfo[mapnum]->globalEFX->ringmod.waveform = get_number(word2); + } + } + else if (fastncmp(word, "AUTOWAH_", 8)) + { + word += 8; + + if (fastcmp(word, "ATTACK_TIME")) + { + mapheaderinfo[mapnum]->globalEFX->autowah.attack_time = atof(word2); + } + else if (fastcmp(word, "RELEASE_TIME")) + { + mapheaderinfo[mapnum]->globalEFX->autowah.release_time = atof(word2); + } + else if (fastcmp(word, "RESONANCE")) + { + mapheaderinfo[mapnum]->globalEFX->autowah.resonance = atof(word2); + } + else if (fastcmp(word, "PEAK_GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->autowah.peak_gain = atof(word2); + } + } + else if (fastncmp(word, "COMPRESSOR_", 11)) + { + word += 11; + + if (fastcmp(word, "ONOFF")) + { + if (i || word2[0] == 'T' || word2[0] == 'O') + mapheaderinfo[mapnum]->globalEFX->compressor.onoff = 1; + else + mapheaderinfo[mapnum]->globalEFX->compressor.onoff = 0; + } + } + else if (fastncmp(word, "EQ_", 3)) + { + word += 3; + + if (fastcmp(word, "LOW_GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->eq.low_gain = atof(word2); + } + else if (fastcmp(word, "LOW_CUTOFF")) + { + mapheaderinfo[mapnum]->globalEFX->eq.low_cutoff = atof(word2); + } + else if (fastcmp(word, "MID1_GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->eq.mid1_gain = atof(word2); + } + else if (fastcmp(word, "MID1_CENTER")) + { + mapheaderinfo[mapnum]->globalEFX->eq.mid1_center = atof(word2); + } + else if (fastcmp(word, "MID1_WIDTH")) + { + mapheaderinfo[mapnum]->globalEFX->eq.mid1_width = atof(word2); + } + else if (fastcmp(word, "MID2_GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->eq.mid2_gain = atof(word2); + } + else if (fastcmp(word, "MID2_CENTER")) + { + mapheaderinfo[mapnum]->globalEFX->eq.mid2_center = atof(word2); + } + else if (fastcmp(word, "MID2_WIDTH")) + { + mapheaderinfo[mapnum]->globalEFX->eq.mid2_width = atof(word2); + } + else if (fastcmp(word, "HIGH_GAIN")) + { + mapheaderinfo[mapnum]->globalEFX->eq.high_gain = atof(word2); + } + else if (fastcmp(word, "HIGH_CUTOFF")) + { + mapheaderinfo[mapnum]->globalEFX->eq.high_cutoff = atof(word2); + } + } +} + void readlevelheader(MYFILE *f, char * name) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -1275,72 +1723,10 @@ void readlevelheader(MYFILE *f, char * name) { mapheaderinfo[num]->globalEFX->type = get_number(word2); } - else if (fastcmp(word, "GLOBALEFXVAR1")) + else if (fastncmp("GLOBALEFX_",word,10)) { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var1 = flonum ? flonum : get_number(word2); + globalmapefxparameters(num, i, word, word2); } - else if (fastcmp(word, "GLOBALEFXVAR2")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var2 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR3")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var3 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR4")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var4 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR5")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var5 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR6")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var6 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR7")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var7 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR8")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var8 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR9")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var9 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR10")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var10 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR11")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var11 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR12")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var12 = flonum ? flonum : get_number(word2); - } - else if (fastcmp(word, "GLOBALEFXVAR13")) - { - float flonum = atof(word2); - mapheaderinfo[num]->globalEFX->var13 = flonum ? flonum : get_number(word2); - } - // ignored for compatibility else if (fastcmp(word, "NEXTLEVEL") || fastcmp(word, "TIMEATTACK") || fastcmp(word, "RECORDATTACK")) continue; diff --git a/src/deh_tables.c b/src/deh_tables.c index 04ebd63be..3d876dd21 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1869,20 +1869,41 @@ struct int_const_s const INT_CONST[] = { {"TICCMD_USINGTILT", TICCMD_USINGTILT}, {"TICCMD_EXCESSTILT", TICCMD_EXCESSTILT}, - // EFX + // effecttypes_t {"EFFECT_NONE", EFFECT_NONE}, + {"EFFECT_EAXREVERB", EFFECT_EAXREVERB}, {"EFFECT_REVERB", EFFECT_REVERB}, {"EFFECT_CHORUS", EFFECT_CHORUS}, {"EFFECT_DISTORTION", EFFECT_DISTORTION}, {"EFFECT_ECHO", EFFECT_ECHO}, + {"EFFECT_FLANGER", EFFECT_FLANGER}, + {"EFFECT_FREQSHIFT", EFFECT_FREQSHIFT}, + {"EFFECT_VOCALMORPH", EFFECT_VOCALMORPH}, {"EFFECT_PITCHSHIFT", EFFECT_PITCHSHIFT}, {"EFFECT_RINGMOD", EFFECT_RINGMOD}, + {"EFFECT_AUTOWAH", EFFECT_AUTOWAH}, {"EFFECT_COMPRESSOR", EFFECT_COMPRESSOR}, {"EFFECT_EQ", EFFECT_EQ}, + // choruswaves_t {"CHORUSWAVE_SINUSOID", CHORUSWAVE_SINUSOID}, {"CHORUSWAVE_TRIANGLE", CHORUSWAVE_TRIANGLE}, + // flangerwaves_t + {"FLANGERWAVE_SINUSOID", FLANGERWAVE_SINUSOID}, + {"FLANGERWAVE_TRIANGLE", FLANGERWAVE_TRIANGLE}, + + // freqshiftdirection_t + {"FREQSHIFTDIR_DOWN", FREQSHIFTDIR_DOWN}, + {"FREQSHIFTDIR_UP", FREQSHIFTDIR_UP}, + {"FREQSHIFTDIR_OFF", FREQSHIFTDIR_OFF}, + + // vocalmorphwaves_t + {"VOCALMORPH_SIN", VOCALMORPH_SIN}, + {"VOCALMORPH_TRIANGLE", VOCALMORPH_TRIANGLE}, + {"VOCALMORPH_SAW", VOCALMORPH_SAW}, + + // ringmodwaves_t {"RINGMOD_SIN", RINGMOD_SIN}, {"RINGMOD_SAW", RINGMOD_SAW}, {"RINGMOD_SQUARE", RINGMOD_SQUARE}, diff --git a/src/doomdef.h b/src/doomdef.h index bcada94ca..fc1e0319a 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -339,6 +339,7 @@ typedef enum DBG_LUA = 0x00000800, DBG_RNG = 0x00001000, DBG_DEMO = 0x00002000, + DBG_EFX = 0x00004000, } debugFlags_t; struct debugFlagNames_s diff --git a/src/i_sound.h b/src/i_sound.h index 8bb431263..8aa3429a2 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -17,6 +17,7 @@ #include "doomdef.h" #include "sounds.h" #include "command.h" +#include "m_fixed.h" #ifdef HAVE_OPENAL #include "AL/al.h" @@ -48,55 +49,204 @@ typedef enum { typedef enum { EFFECT_NONE = 0, + EFFECT_EAXREVERB, EFFECT_REVERB, EFFECT_CHORUS, EFFECT_DISTORTION, EFFECT_ECHO, + EFFECT_FLANGER, + EFFECT_FREQSHIFT, + EFFECT_VOCALMORPH, EFFECT_PITCHSHIFT, EFFECT_RINGMOD, + EFFECT_AUTOWAH, EFFECT_COMPRESSOR, EFFECT_EQ, } effecttypes_t; typedef enum { -#ifdef HAVE_OPENAL - CHORUSWAVE_SINUSOID = AL_CHORUS_WAVEFORM_SINUSOID, - CHORUSWAVE_TRIANGLE = AL_CHORUS_WAVEFORM_TRIANGLE, -#else CHORUSWAVE_SINUSOID = 0, - CHORUSWAVE_TRIANGLE = 0, -#endif + CHORUSWAVE_TRIANGLE = 1, } choruswaves_t; +typedef enum +{ + FLANGERWAVE_SINUSOID = 0, + FLANGERWAVE_TRIANGLE = 1, +} flangerwaves_t; + +typedef enum +{ + FREQSHIFTDIR_DOWN = 0, + FREQSHIFTDIR_UP = 1, + FREQSHIFTDIR_OFF = 2, +} freqshiftdirection_t; + +typedef enum +{ + VOCALMORPH_SIN = 0, + VOCALMORPH_TRIANGLE = 1, + VOCALMORPH_SAW = 2, +} vocalmorphwaves_t; + typedef enum { RINGMOD_SIN = 0, - RINGMOD_SAW, - RINGMOD_SQUARE, + RINGMOD_SAW = 1, + RINGMOD_SQUARE = 2, } ringmodwaves_t; typedef struct { - // flags for effects #ifdef HAVE_OPENAL - ALuint effect; - ALuint slot; + struct + { + ALuint effect; + ALuint slot; + } al; #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; + + struct + { + float density; + float diffusion; + float gain; + float gainhf; + float gainlf; + float decay_time; + float decay_hfratio; + float decay_lfratio; + float reflections_gain; + float reflections_delay; + f_vector3_t reflections_pan; + float late_reverb_gain; + float late_reverb_delay; + f_vector3_t late_reverb_pan; + float echo_time; + float echo_depth; + float modulation_time; + float modulation_depth; + float air_absorption_gainhf; + float hfreference; + float lfreference; + float room_rolloff_factor; + boolean decay_hflimit; + } eaxreverb; + + struct + { + float density; + float diffusion; + float gain; + float gainhf; + float decay_time; + float decay_hfratio; + float reflections_gain; + float reflections_delay; + float late_reverb_gain; + float late_reverb_delay; + float air_absorption_gainhf; + float room_rolloff_factor; + boolean decay_hflimit; + } reverb; + + struct + { + SINT8 waveform; + INT16 phase; + float rate; + float depth; + float feedback; + float delay; + } chorus; + + struct + { + float edge; + float gain; + float lowpass_cutoff; + float eqcenter; + float eqbandwidth; + } distortion; + + struct + { + float delay; + float lrdelay; + float damping; + float feedback; + float spread; + } echo; + + struct + { + SINT8 waveform; + INT16 phase; + float rate; + float depth; + float feedback; + float delay; + } flanger; + + struct + { + float frequency; + SINT8 left_direction; + SINT8 right_direction; + } freqshift; + + struct + { + SINT8 phonemea; + SINT8 phonemeb; + SINT8 phonemea_coarse_tuning; + SINT8 phonemeb_coarse_tuning; + SINT8 waveform; + float rate; + } vocal_morpher; + + struct + { + SINT8 coarse_tune; + SINT8 fine_tune; + } pitchshift; + + struct + { + float frequency; + float highpass_cutoff; + SINT8 waveform; + } ringmod; + + struct + { + float attack_time; + float release_time; + float resonance; + float peak_gain; + } autowah; + + struct + { + boolean onoff; + } compressor; + + struct + { + float low_gain; + float low_cutoff; + float mid1_gain; + float mid1_center; + float mid1_width; + float mid2_gain; + float mid2_center; + float mid2_width; + float high_gain; + float high_cutoff; + } eq; } efx_t; /** \brief Sound subsystem runing and waiting @@ -317,6 +467,8 @@ void I_DeleteEFX(efx_t *efx); void I_CreateGlobalEFX(efx_t *efx); void I_DeleteGlobalEFX(void); +void I_InitEFXArray(efx_t *efx); + extern consvar_t cv_soundefx; #ifdef __cplusplus diff --git a/src/k_kart.c b/src/k_kart.c index 7ef0003e5..b768f5751 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9068,7 +9068,7 @@ INT32 K_GetKartRingPower(const player_t *player, boolean boosted) efx_t efx; S_InitEFXArray(&efx); efx.type = EFFECT_REVERB; - efx.var5 = 6; + efx.reverb.decay_time = 6.0; S_StartSoundAtVolumeEx(NULL, sfx_cdfm66, 255, &efx); } diff --git a/src/m_cheat.c b/src/m_cheat.c index c22dac95e..4a6a2e987 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -739,6 +739,8 @@ struct debugFlagNames_s const debug_flag_names[] = {"Randomizer", DBG_RNG}, // alt name {"Demo", DBG_DEMO}, {"Replay", DBG_DEMO}, // alt name + {"EFX", DBG_EFX}, + {"SoundEFX", DBG_EFX}, // alt name {NULL, 0} }; diff --git a/src/m_fixed.h b/src/m_fixed.h index c0c8ad7a0..628e8e05b 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -377,6 +377,13 @@ struct vector3_t fixed_t x, y, z; }; +struct f_vector3_t +{ + float x; + float y; + float z; +}; + vector3_t *FV3_Load(vector3_t *vec, fixed_t x, fixed_t y, fixed_t z); vector3_t *FV3_UnLoad(vector3_t *vec, fixed_t *x, fixed_t *y, fixed_t *z); vector3_t *FV3_Copy(vector3_t *a_o, const vector3_t *a_i); diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 50ce1ffa4..1ff689607 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -2589,4 +2589,3 @@ int M_RoundUp(double number) return (int)number; } - diff --git a/src/s_sound.c b/src/s_sound.c index 73d9e35ea..73907e14a 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -837,7 +837,11 @@ notinlevel: if (c->efx == NULL || c->endtime > c->efxtail + c->duration) { - //CONS_Printf("endtime: %f efxtail: %f duration: %f \n", c->endtime, c->efxtail, c->duration); + if (c->efx != NULL) + { + CONS_Debug(DBG_EFX, "S_UpdateSounds: endtime: %f efxtail: %f duration: %f \n", c->endtime, c->efxtail, c->duration); + } + S_StopChannel(cnum); } @@ -2904,14 +2908,7 @@ void ModFilter_OnChange(void) 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; + I_InitEFXArray(efx); } void S_CreateGlobalEFX(efx_t *efx) diff --git a/src/sdl/al_sound.c b/src/sdl/al_sound.c index b9c09a436..48ea9d0ba 100644 --- a/src/sdl/al_sound.c +++ b/src/sdl/al_sound.c @@ -406,6 +406,7 @@ void I_StartupSound(void) LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv); #undef LOAD_PROC + audio.globalefx.enabled = false; audio.music = INVALID_HANDLE; audio.bufferindex = 0; @@ -1016,9 +1017,9 @@ void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch, efx_t if (cv_soundefx.value && !dedicated) { - if (efx != NULL && TRY(alIsEffect, efx->effect) && TRY(alIsAuxiliaryEffectSlot, efx->slot)) + if (efx != NULL && TRY(alIsEffect, efx->al.effect) && TRY(alIsAuxiliaryEffectSlot, efx->al.slot)) { - TRY(alSource3i, source, AL_AUXILIARY_SEND_FILTER, efx->slot, 0, AL_FILTER_NULL); + TRY(alSource3i, source, AL_AUXILIARY_SEND_FILTER, efx->al.slot, 0, AL_FILTER_NULL); } else if (origin != NULL && audio.globalefx.enabled && TRY(alIsEffect, audio.globalefx.effect) @@ -1910,11 +1911,11 @@ boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void)) { - return I_FadeSongFromVolume(target_volume, (internal_volume * 100.f), ms, callback); + return I_FadeSongFromVolume(target_volume, (internal_volume * 100.f), ms, callback); } boolean I_FadeOutStopSong(UINT32 ms) { - return I_FadeSongFromVolume(0, (internal_volume * 100.f), ms, &I_StopSong); + return I_FadeSongFromVolume(0, (internal_volume * 100.f), ms, &I_StopSong); } boolean I_FadeInPlaySong(UINT32 ms, boolean looping) @@ -1925,135 +1926,173 @@ boolean I_FadeInPlaySong(UINT32 ms, boolean looping) return false; } +// Debugging +#define VAL(x) #x + +#define APPLY_EFFECT(alEffectType, field, altype, alfield) TRY(alEffectType, effect, AL_##altype##_##alfield, efx->field); \ +CONS_Debug(DBG_EFX, VAL(AL_##altype##_##alfield) ": %f\n", (float)efx->field) + +#define APPLY_EFFECT_BOOL(field, altype, alfield) TRY(alEffecti, effect, AL_##altype##_##alfield, efx->field ? AL_TRUE : AL_FALSE); \ +CONS_Debug(DBG_EFX, VAL(AL_##altype##_##alfield) ": %s\n", efx->field ? "TRUE" : "FALSE") + +#define APPLY_EFFECT_FVEC3(alEffectType, field, altype, alfield, min, max) \ +ALfloat vec3fields##alfield[3]; \ +vec3fields##alfield[0] = efx->field.x; \ +vec3fields##alfield[1] = efx->field.y; \ +vec3fields##alfield[2] = efx->field.z; \ +TRY(alEffectType, effect, AL_##altype##_##alfield, vec3fields##alfield); \ +CONS_Debug(DBG_EFX, VAL(AL_##altype##_##alfield) ": x=%f y=%f z=%f\n", vec3fields##alfield[0], vec3fields##alfield[1], vec3fields##alfield[2]) + + static void I_HandleEFXType(efx_t *efx, ALuint effect) { + CONS_Debug(DBG_EFX, "Attempting to Handle EFX type.\n"); switch (efx->type) { + case EFFECT_EAXREVERB: + TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); + + APPLY_EFFECT(alEffectf, eaxreverb.density, EAXREVERB, DENSITY); + APPLY_EFFECT(alEffectf, eaxreverb.diffusion, EAXREVERB, DIFFUSION); + APPLY_EFFECT(alEffectf, eaxreverb.gain, EAXREVERB, GAIN); + APPLY_EFFECT(alEffectf, eaxreverb.gainhf, EAXREVERB, GAINHF); + APPLY_EFFECT(alEffectf, eaxreverb.gainlf, EAXREVERB, GAINLF); + APPLY_EFFECT(alEffectf, eaxreverb.decay_time, EAXREVERB, DECAY_TIME); + APPLY_EFFECT(alEffectf, eaxreverb.decay_hfratio, EAXREVERB, DECAY_HFRATIO); + APPLY_EFFECT(alEffectf, eaxreverb.decay_lfratio, EAXREVERB, DECAY_LFRATIO); + APPLY_EFFECT(alEffectf, eaxreverb.reflections_gain, EAXREVERB, REFLECTIONS_GAIN); + APPLY_EFFECT(alEffectf, eaxreverb.reflections_delay, EAXREVERB, REFLECTIONS_DELAY); + APPLY_EFFECT_FVEC3(alEffectfv, eaxreverb.reflections_pan, EAXREVERB, REFLECTIONS_PAN, -1.0, 1.0); + APPLY_EFFECT(alEffectf, eaxreverb.late_reverb_gain, EAXREVERB, LATE_REVERB_GAIN); + APPLY_EFFECT(alEffectf, eaxreverb.late_reverb_delay, EAXREVERB, LATE_REVERB_DELAY); + APPLY_EFFECT_FVEC3(alEffectfv, eaxreverb.late_reverb_pan, EAXREVERB, LATE_REVERB_PAN, -1.0, 1.0); + APPLY_EFFECT(alEffectf, eaxreverb.echo_time, EAXREVERB, ECHO_TIME); + APPLY_EFFECT(alEffectf, eaxreverb.echo_depth, EAXREVERB, ECHO_DEPTH); + APPLY_EFFECT(alEffectf, eaxreverb.modulation_time, EAXREVERB, MODULATION_TIME); + APPLY_EFFECT(alEffectf, eaxreverb.modulation_depth, EAXREVERB, MODULATION_DEPTH); + APPLY_EFFECT(alEffectf, eaxreverb.air_absorption_gainhf, EAXREVERB, AIR_ABSORPTION_GAINHF); + APPLY_EFFECT(alEffectf, eaxreverb.hfreference, EAXREVERB, HFREFERENCE); + APPLY_EFFECT(alEffectf, eaxreverb.lfreference, EAXREVERB, LFREFERENCE); + APPLY_EFFECT(alEffectf, eaxreverb.room_rolloff_factor, EAXREVERB, ROOM_ROLLOFF_FACTOR); + APPLY_EFFECT_BOOL(eaxreverb.decay_hflimit, EAXREVERB, DECAY_HFLIMIT); + break; case EFFECT_REVERB: TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); - if (efx->var1 != -255) - TRY(alEffectf, effect, AL_REVERB_DENSITY, efx->var1); - if (efx->var2 != -255) - TRY(alEffectf, effect, AL_REVERB_DIFFUSION, efx->var2); - if (efx->var3 != -255) - TRY(alEffectf, effect, AL_REVERB_GAIN, efx->var3); - if (efx->var4 != -255) - TRY(alEffectf, effect, AL_REVERB_GAINHF, efx->var4); - if (efx->var5 != -255) - TRY(alEffectf, effect, AL_REVERB_DECAY_TIME, efx->var5); - if (efx->var6 != -255) - TRY(alEffectf, effect, AL_REVERB_DECAY_HFRATIO, efx->var6); - if (efx->var7 != -255) - TRY(alEffectf, effect, AL_REVERB_REFLECTIONS_GAIN, efx->var7); - if (efx->var8 != -255) - TRY(alEffectf, effect, AL_REVERB_REFLECTIONS_DELAY, efx->var8); - if (efx->var9 != -255) - TRY(alEffectf, effect, AL_REVERB_LATE_REVERB_GAIN, efx->var9); - if (efx->var10 != -255) - TRY(alEffectf, effect, AL_REVERB_LATE_REVERB_DELAY, efx->var10); - if (efx->var11 != -255) - TRY(alEffectf, effect, AL_REVERB_AIR_ABSORPTION_GAINHF, efx->var11); - if (efx->var12 != -255) - TRY(alEffectf, effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, efx->var12); - if (efx->var13 != -255) - TRY(alEffectf, effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, efx->var13); + APPLY_EFFECT(alEffectf, reverb.density, REVERB, DENSITY); + APPLY_EFFECT(alEffectf, reverb.diffusion, REVERB, DIFFUSION); + APPLY_EFFECT(alEffectf, reverb.gain, REVERB, GAIN); + APPLY_EFFECT(alEffectf, reverb.gainhf, REVERB, GAINHF); + APPLY_EFFECT(alEffectf, reverb.decay_time, REVERB, DECAY_TIME); + APPLY_EFFECT(alEffectf, reverb.decay_hfratio, REVERB, DECAY_HFRATIO); + APPLY_EFFECT(alEffectf, reverb.reflections_gain, REVERB, REFLECTIONS_GAIN); + APPLY_EFFECT(alEffectf, reverb.reflections_delay, REVERB, REFLECTIONS_DELAY); + APPLY_EFFECT(alEffectf, reverb.late_reverb_gain, REVERB, LATE_REVERB_GAIN); + APPLY_EFFECT(alEffectf, reverb.late_reverb_delay, REVERB, LATE_REVERB_DELAY); + APPLY_EFFECT(alEffectf, reverb.air_absorption_gainhf, REVERB, AIR_ABSORPTION_GAINHF); + APPLY_EFFECT_BOOL(reverb.decay_hflimit, REVERB, DECAY_HFLIMIT); break; case EFFECT_CHORUS: TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_CHORUS); - if (efx->var1 != -255) - TRY(alEffectf, effect, AL_CHORUS_WAVEFORM, efx->var1); - if (efx->var2 != -255) - TRY(alEffectf, effect, AL_CHORUS_PHASE, efx->var2); - if (efx->var3 != -255) - TRY(alEffectf, effect, AL_CHORUS_RATE, efx->var3); - if (efx->var4 != -255) - TRY(alEffectf, effect, AL_CHORUS_DEPTH, efx->var4); - if (efx->var5 != -255) - TRY(alEffectf, effect, AL_CHORUS_FEEDBACK, efx->var5); - if (efx->var6 != -255) - TRY(alEffectf, effect, AL_CHORUS_DELAY, efx->var6); + APPLY_EFFECT(alEffectf, chorus.waveform, CHORUS, WAVEFORM); + APPLY_EFFECT(alEffecti, chorus.phase, CHORUS, PHASE); + APPLY_EFFECT(alEffectf, chorus.rate, CHORUS, RATE); + APPLY_EFFECT(alEffectf, chorus.depth, CHORUS, DEPTH); + APPLY_EFFECT(alEffectf, chorus.feedback, CHORUS, FEEDBACK); + APPLY_EFFECT(alEffectf, chorus.delay, CHORUS, DELAY); break; case EFFECT_DISTORTION: TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_DISTORTION); - if (efx->var1 != -255) - TRY(alEffectf, effect, AL_DISTORTION_EDGE, efx->var1); - if (efx->var2 != -255) - TRY(alEffectf, effect, AL_DISTORTION_GAIN, efx->var2); - if (efx->var3 != -255) - TRY(alEffectf, effect, AL_DISTORTION_LOWPASS_CUTOFF, efx->var3); - if (efx->var4 != -255) - TRY(alEffectf, effect, AL_DISTORTION_EQCENTER, efx->var4); - if (efx->var5 != -255) - TRY(alEffectf, effect, AL_DISTORTION_EQBANDWIDTH, efx->var5); + APPLY_EFFECT(alEffectf, distortion.edge, DISTORTION, EDGE); + APPLY_EFFECT(alEffectf, distortion.gain, DISTORTION, GAIN); + APPLY_EFFECT(alEffectf, distortion.lowpass_cutoff, DISTORTION, LOWPASS_CUTOFF); + APPLY_EFFECT(alEffectf, distortion.eqcenter, DISTORTION, EQCENTER); + APPLY_EFFECT(alEffectf, distortion.eqbandwidth, DISTORTION, EQBANDWIDTH); break; case EFFECT_ECHO: TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_ECHO); - if (efx->var1 != -255) - TRY(alEffectf, effect, AL_ECHO_DELAY, efx->var1); - if (efx->var2 != -255) - TRY(alEffectf, effect, AL_ECHO_LRDELAY, efx->var2); - if (efx->var3 != -255) - TRY(alEffectf, effect, AL_ECHO_DAMPING, efx->var3); - if (efx->var4 != -255) - TRY(alEffectf, effect, AL_ECHO_FEEDBACK, efx->var4); - if (efx->var5 != -255) - TRY(alEffectf, effect, AL_ECHO_SPREAD, efx->var5); + APPLY_EFFECT(alEffectf, echo.delay, ECHO, DELAY); + APPLY_EFFECT(alEffectf, echo.lrdelay, ECHO, LRDELAY); + APPLY_EFFECT(alEffectf, echo.damping, ECHO, DAMPING); + APPLY_EFFECT(alEffectf, echo.feedback, ECHO, FEEDBACK); + APPLY_EFFECT(alEffectf, echo.spread, ECHO, SPREAD); + break; + case EFFECT_FLANGER: + TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_FLANGER); + + APPLY_EFFECT(alEffectf, flanger.waveform, FLANGER, WAVEFORM); + APPLY_EFFECT(alEffecti, flanger.phase, FLANGER, PHASE); + APPLY_EFFECT(alEffectf, flanger.rate, FLANGER, RATE); + APPLY_EFFECT(alEffectf, flanger.depth, FLANGER, DEPTH); + APPLY_EFFECT(alEffectf, flanger.feedback, FLANGER, FEEDBACK); + APPLY_EFFECT(alEffectf, flanger.delay, FLANGER, DELAY); + break; + case EFFECT_FREQSHIFT: + TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_FREQUENCY_SHIFTER); + + APPLY_EFFECT(alEffectf, freqshift.frequency, FREQUENCY_SHIFTER, FREQUENCY); + APPLY_EFFECT(alEffecti, freqshift.left_direction, FREQUENCY_SHIFTER, LEFT_DIRECTION); + APPLY_EFFECT(alEffecti, freqshift.right_direction, FREQUENCY_SHIFTER, RIGHT_DIRECTION); + break; + case EFFECT_VOCALMORPH: + TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_VOCAL_MORPHER); + + APPLY_EFFECT(alEffecti, vocal_morpher.phonemea, VOCAL_MORPHER, PHONEMEA); + APPLY_EFFECT(alEffecti, vocal_morpher.phonemeb, VOCAL_MORPHER, PHONEMEB); + APPLY_EFFECT(alEffecti, vocal_morpher.phonemea_coarse_tuning, VOCAL_MORPHER, PHONEMEA_COARSE_TUNING); + APPLY_EFFECT(alEffecti, vocal_morpher.phonemeb_coarse_tuning, VOCAL_MORPHER, PHONEMEB_COARSE_TUNING); + APPLY_EFFECT(alEffecti, vocal_morpher.waveform, VOCAL_MORPHER, WAVEFORM); + APPLY_EFFECT(alEffectf, vocal_morpher.rate, VOCAL_MORPHER, RATE); break; case EFFECT_PITCHSHIFT: TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER); - if (efx->var1 != -255) - TRY(alEffectf, effect, AL_PITCH_SHIFTER_COARSE_TUNE, efx->var1); - if (efx->var2 != -255) - TRY(alEffectf, effect, AL_PITCH_SHIFTER_FINE_TUNE , efx->var2); + APPLY_EFFECT(alEffecti, pitchshift.coarse_tune, PITCH_SHIFTER, COARSE_TUNE); + APPLY_EFFECT(alEffecti, pitchshift.fine_tune, PITCH_SHIFTER, FINE_TUNE); break; case EFFECT_RINGMOD: TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_RING_MODULATOR); - if (efx->var1 != -255) - TRY(alEffectf, effect, AL_RING_MODULATOR_FREQUENCY, efx->var1); - if (efx->var2 != -255) - TRY(alEffectf, effect, AL_RING_MODULATOR_HIGHPASS_CUTOFF, efx->var2); - if (efx->var3 != -255) - TRY(alEffectf, effect, AL_RING_MODULATOR_WAVEFORM, efx->var3); + APPLY_EFFECT(alEffectf, ringmod.frequency, RING_MODULATOR, FREQUENCY); + APPLY_EFFECT(alEffectf, ringmod.highpass_cutoff, RING_MODULATOR, HIGHPASS_CUTOFF); + APPLY_EFFECT(alEffecti, ringmod.waveform, RING_MODULATOR, WAVEFORM); + break; + case EFFECT_AUTOWAH: + TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_AUTOWAH); + + APPLY_EFFECT(alEffectf, autowah.attack_time, AUTOWAH, ATTACK_TIME); + APPLY_EFFECT(alEffectf, autowah.release_time, AUTOWAH, RELEASE_TIME); + APPLY_EFFECT(alEffectf, autowah.resonance, AUTOWAH, RESONANCE); + APPLY_EFFECT(alEffectf, autowah.peak_gain, AUTOWAH, PEAK_GAIN); break; case EFFECT_COMPRESSOR: TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_COMPRESSOR); - if (efx->var1 != -255) - TRY(alEffectf, effect, AL_COMPRESSOR_ONOFF, efx->var1); + APPLY_EFFECT(alEffectf, compressor.onoff, COMPRESSOR, ONOFF); break; case EFFECT_EQ: TRY(alEffecti, effect, AL_EFFECT_TYPE, AL_EFFECT_EQUALIZER); - if (efx->var1 != -255) - TRY(alEffectf, effect, AL_EQUALIZER_LOW_GAIN, efx->var1); - if (efx->var2 != -255) - TRY(alEffectf, effect, AL_EQUALIZER_LOW_CUTOFF, efx->var2); - if (efx->var3 != -255) - TRY(alEffectf, effect, AL_EQUALIZER_MID1_GAIN, efx->var3); - if (efx->var4 != -255) - TRY(alEffectf, effect, AL_EQUALIZER_MID1_CENTER, efx->var4); - if (efx->var5 != -255) - TRY(alEffectf, effect, AL_EQUALIZER_MID1_WIDTH, efx->var5); - if (efx->var6 != -255) - TRY(alEffectf, effect, AL_EQUALIZER_MID2_GAIN, efx->var6); - if (efx->var7 != -255) - TRY(alEffectf, effect, AL_EQUALIZER_MID2_CENTER, efx->var7); - if (efx->var8 != -255) - TRY(alEffectf, effect, AL_EQUALIZER_MID2_WIDTH, efx->var8); - if (efx->var9 != -255) - TRY(alEffectf, effect, AL_EQUALIZER_HIGH_GAIN, efx->var9); - if (efx->var10 != -255) - TRY(alEffectf, effect, AL_EQUALIZER_HIGH_CUTOFF, efx->var10); + APPLY_EFFECT(alEffectf, eq.low_gain, EQUALIZER, LOW_GAIN); + APPLY_EFFECT(alEffectf, eq.low_cutoff, EQUALIZER, LOW_CUTOFF); + APPLY_EFFECT(alEffectf, eq.mid1_gain, EQUALIZER, MID1_GAIN); + APPLY_EFFECT(alEffectf, eq.mid1_center, EQUALIZER, MID1_CENTER); + APPLY_EFFECT(alEffectf, eq.mid1_width, EQUALIZER, MID1_WIDTH); + APPLY_EFFECT(alEffectf, eq.mid2_gain, EQUALIZER, MID2_GAIN); + APPLY_EFFECT(alEffectf, eq.mid2_center, EQUALIZER, MID2_CENTER); + APPLY_EFFECT(alEffectf, eq.mid2_width, EQUALIZER, MID2_WIDTH); + APPLY_EFFECT(alEffectf, eq.high_gain, EQUALIZER, HIGH_GAIN); + APPLY_EFFECT(alEffectf, eq.high_cutoff, EQUALIZER, HIGH_CUTOFF); break; } } +#undef APPLY_EFFECT +#undef APPLY_EFFECT_FVEC3 + efx_t *I_CreateEFX(efx_t *efx) { LOCKAUDIO; @@ -2063,24 +2102,32 @@ efx_t *I_CreateEFX(efx_t *efx) efx_t *efxc = Z_Calloc(sizeof(efx_t), PU_STATIC, NULL); + CONS_Debug(DBG_EFX, "I_CreateEFX: Attempting to allocate new EFX.\n"); + if (efxc == NULL) I_Error("OpenAL: Ran out of memory generating EFX.\n"); if (efx != NULL) + { memcpy(efxc, efx, sizeof(efx_t)); + CONS_Debug(DBG_EFX, "I_CreateEFX: Given EFX exists, attempt to copy its data over.\n"); + } // Init effects and slots. - TRY(alGenEffects, 1, &efxc->effect); - TRY(alGenAuxiliaryEffectSlots, 1, &efxc->slot); + CONS_Debug(DBG_EFX, "I_CreateEFX: Generating Effect and Slot.\n"); + TRY(alGenEffects, 1, &efxc->al.effect); + TRY(alGenAuxiliaryEffectSlots, 1, &efxc->al.slot); - if (TRY(alIsEffect, efxc->effect) && TRY(alIsAuxiliaryEffectSlot, efxc->slot)) + if (TRY(alIsEffect, efxc->al.effect) && TRY(alIsAuxiliaryEffectSlot, efxc->al.slot)) { - I_HandleEFXType(efxc, efxc->effect); + CONS_Debug(DBG_EFX, "I_CreateEFX: Effect and Slot successfully created.\n"); + I_HandleEFXType(efxc, efxc->al.effect); - TRY(alAuxiliaryEffectSloti, efxc->slot, AL_EFFECTSLOT_EFFECT, efxc->effect); + TRY(alAuxiliaryEffectSloti, efxc->al.slot, AL_EFFECTSLOT_EFFECT, efxc->al.effect); return efxc; } + CONS_Debug(DBG_EFX, "I_CreateEFX: Effect or Slot failed to be created, freeing.\n"); Z_Free(efxc); return NULL; @@ -2100,10 +2147,7 @@ float I_GetEFXTail(efx_t *efx) switch(efx->type) { case EFFECT_REVERB: - if (efx->var5 != 255) - tailtime = efx->var5; - else - tailtime = 1.49; + tailtime = efx->reverb.decay_time; break; default: @@ -2111,6 +2155,7 @@ float I_GetEFXTail(efx_t *efx) break; } + CONS_Debug(DBG_EFX, "I_GetEFXTail: EFX tail is %f aka %f.\n", tailtime, tailtime*TICRATE); return tailtime*TICRATE; } @@ -2121,16 +2166,19 @@ void I_DeleteEFX(efx_t *efx) if (efx == NULL) return; - if (TRY(alIsEffect, efx->effect)) + if (TRY(alIsEffect, efx->al.effect)) { - TRY(alDeleteEffects, 1, &efx->effect); + CONS_Debug(DBG_EFX, "I_DeleteEFX: Effect exists, attempting to delete.\n"); + TRY(alDeleteEffects, 1, &efx->al.effect); } - if (TRY(alIsAuxiliaryEffectSlot, efx->slot)) + if (TRY(alIsAuxiliaryEffectSlot, efx->al.slot)) { - TRY(alDeleteAuxiliaryEffectSlots, 1, &efx->slot); + CONS_Debug(DBG_EFX, "I_DeleteEFX: Slot exists, attempting to delete.\n"); + TRY(alDeleteAuxiliaryEffectSlots, 1, &efx->al.slot); } + CONS_Debug(DBG_EFX, "I_DeleteEFX: Freeing allocated memory.\n"); Z_Free(efx); } @@ -2145,27 +2193,36 @@ void I_CreateGlobalEFX(efx_t *efx) return; // Init effects and slots. + CONS_Debug(DBG_EFX, "I_CreateGlobalEFX: Generating Effect and Slot.\n"); TRY(alGenEffects, 1, &audio.globalefx.effect); TRY(alGenAuxiliaryEffectSlots, 1, &audio.globalefx.slot); if (TRY(alIsEffect, audio.globalefx.effect) && TRY(alIsAuxiliaryEffectSlot, audio.globalefx.slot)) { + CONS_Debug(DBG_EFX, "I_CreateGlobalEFX: Effect and Slot successfully created.\n"); I_HandleEFXType(efx, audio.globalefx.effect); TRY(alAuxiliaryEffectSloti, audio.globalefx.slot, AL_EFFECTSLOT_EFFECT, audio.globalefx.effect); + + CONS_Debug(DBG_EFX, "I_CreateGlobalEFX: Global EFX enabled.\n"); audio.globalefx.enabled = true; return; } + CONS_Debug(DBG_EFX, "I_CreateEFX: Effect or Slot failed to be created.\n"); + if (TRY(alIsEffect, audio.globalefx.effect)) { + CONS_Debug(DBG_EFX, "I_CreateGlobalEFX: Effect exists, attempting to delete.\n"); TRY(alDeleteEffects, 1, &audio.globalefx.effect); } if (TRY(alIsAuxiliaryEffectSlot, audio.globalefx.slot)) { + CONS_Debug(DBG_EFX, "I_CreateGlobalEFX: Slot exists, attempting to delete.\n"); TRY(alDeleteAuxiliaryEffectSlots, 1, &audio.globalefx.slot); } + CONS_Debug(DBG_EFX, "I_CreateGlobalEFX: Global EFX disabled.\n"); audio.globalefx.enabled = false; } @@ -2178,15 +2235,139 @@ void I_DeleteGlobalEFX(void) if (TRY(alIsEffect, audio.globalefx.effect)) { + CONS_Debug(DBG_EFX, "I_DeleteGlobalEFX: Effect exists, attempting to delete.\n"); TRY(alDeleteEffects, 1, &audio.globalefx.effect); } if (TRY(alIsAuxiliaryEffectSlot, audio.globalefx.slot)) { + CONS_Debug(DBG_EFX, "I_DeleteGlobalEFX: Slot exists, attempting to delete.\n"); TRY(alDeleteAuxiliaryEffectSlots, 1, &audio.globalefx.slot); } + CONS_Debug(DBG_EFX, "I_DeleteGlobalEFX: Global EFX disabled.\n"); audio.globalefx.enabled = false; } +#define RESET_EFFECT(field, altype, alfield) efx->field = AL_##altype##_DEFAULT_##alfield; \ +CONS_Debug(DBG_EFX, VAL(AL_##altype##_##alfield) ": %f\n", (float)efx->field) + +#define RESET_EFFECT_FVEC3(field, altype, alfield) efx->field.x = AL_##altype##_DEFAULT_##alfield##_XYZ; \ +efx->field.y = AL_##altype##_DEFAULT_##alfield##_XYZ; \ +efx->field.z = AL_##altype##_DEFAULT_##alfield##_XYZ; \ +CONS_Debug(DBG_EFX, VAL(AL_##altype##_##alfield) ": x=%f y=%f z=%f\n", efx->field.x, efx->field.y, efx->field.z) + +void I_InitEFXArray(efx_t *efx) +{ + if (efx == NULL) + return; + + efx->type = EFFECT_NONE; + + CONS_Debug(DBG_EFX, "I_InitEFXArray: Resetting EFX array to defaults.\n"); + + RESET_EFFECT(eaxreverb.density, EAXREVERB, DENSITY); + RESET_EFFECT(eaxreverb.diffusion, EAXREVERB, DIFFUSION); + RESET_EFFECT(eaxreverb.gain, EAXREVERB, GAIN); + RESET_EFFECT(eaxreverb.gainhf, EAXREVERB, GAINHF); + RESET_EFFECT(eaxreverb.gainlf, EAXREVERB, GAINLF); + RESET_EFFECT(eaxreverb.decay_time, EAXREVERB, DECAY_TIME); + RESET_EFFECT(eaxreverb.decay_hfratio, EAXREVERB, DECAY_HFRATIO); + RESET_EFFECT(eaxreverb.decay_lfratio, EAXREVERB, DECAY_LFRATIO); + RESET_EFFECT(eaxreverb.reflections_gain, EAXREVERB, REFLECTIONS_GAIN); + RESET_EFFECT(eaxreverb.reflections_delay, EAXREVERB, REFLECTIONS_DELAY); + RESET_EFFECT_FVEC3(eaxreverb.reflections_pan, EAXREVERB, REFLECTIONS_PAN); + RESET_EFFECT(eaxreverb.late_reverb_gain, EAXREVERB, LATE_REVERB_GAIN); + RESET_EFFECT(eaxreverb.late_reverb_delay, EAXREVERB, LATE_REVERB_DELAY); + RESET_EFFECT_FVEC3(eaxreverb.late_reverb_pan, EAXREVERB, LATE_REVERB_PAN); + RESET_EFFECT(eaxreverb.echo_time, EAXREVERB, ECHO_TIME); + RESET_EFFECT(eaxreverb.echo_depth, EAXREVERB, ECHO_DEPTH); + RESET_EFFECT(eaxreverb.modulation_time, EAXREVERB, MODULATION_TIME); + RESET_EFFECT(eaxreverb.modulation_depth, EAXREVERB, MODULATION_DEPTH); + RESET_EFFECT(eaxreverb.air_absorption_gainhf, EAXREVERB, AIR_ABSORPTION_GAINHF); + RESET_EFFECT(eaxreverb.hfreference, EAXREVERB, HFREFERENCE); + RESET_EFFECT(eaxreverb.lfreference, EAXREVERB, LFREFERENCE); + RESET_EFFECT(eaxreverb.room_rolloff_factor, EAXREVERB, ROOM_ROLLOFF_FACTOR); + RESET_EFFECT(eaxreverb.decay_hflimit, EAXREVERB, DECAY_HFLIMIT); + + RESET_EFFECT(reverb.density, REVERB, DENSITY); + RESET_EFFECT(reverb.diffusion, REVERB, DIFFUSION); + RESET_EFFECT(reverb.gain, REVERB, GAIN); + RESET_EFFECT(reverb.gainhf, REVERB, GAINHF); + RESET_EFFECT(reverb.decay_time, REVERB, DECAY_TIME); + RESET_EFFECT(reverb.decay_hfratio, REVERB, DECAY_HFRATIO); + RESET_EFFECT(reverb.reflections_gain, REVERB, REFLECTIONS_GAIN); + RESET_EFFECT(reverb.reflections_delay, REVERB, REFLECTIONS_DELAY); + RESET_EFFECT(reverb.late_reverb_gain, REVERB, LATE_REVERB_GAIN); + RESET_EFFECT(reverb.late_reverb_delay, REVERB, LATE_REVERB_DELAY); + RESET_EFFECT(reverb.air_absorption_gainhf, REVERB, AIR_ABSORPTION_GAINHF); + RESET_EFFECT(reverb.decay_hflimit, REVERB, DECAY_HFLIMIT); + + RESET_EFFECT(chorus.waveform, CHORUS, WAVEFORM); + RESET_EFFECT(chorus.phase, CHORUS, PHASE); + RESET_EFFECT(chorus.rate, CHORUS, RATE); + RESET_EFFECT(chorus.depth, CHORUS, DEPTH); + RESET_EFFECT(chorus.feedback, CHORUS, FEEDBACK); + RESET_EFFECT(chorus.delay, CHORUS, DELAY); + + RESET_EFFECT(distortion.edge, DISTORTION, EDGE); + RESET_EFFECT(distortion.gain, DISTORTION, GAIN); + RESET_EFFECT(distortion.lowpass_cutoff, DISTORTION, LOWPASS_CUTOFF); + RESET_EFFECT(distortion.eqcenter, DISTORTION, EQCENTER); + RESET_EFFECT(distortion.eqbandwidth, DISTORTION, EQBANDWIDTH); + + RESET_EFFECT(echo.delay, ECHO, DELAY); + RESET_EFFECT(echo.lrdelay, ECHO, LRDELAY); + RESET_EFFECT(echo.damping, ECHO, DAMPING); + RESET_EFFECT(echo.feedback, ECHO, FEEDBACK); + RESET_EFFECT(echo.spread, ECHO, SPREAD); + + RESET_EFFECT(flanger.waveform, FLANGER, WAVEFORM); + RESET_EFFECT(flanger.phase, FLANGER, PHASE); + RESET_EFFECT(flanger.rate, FLANGER, RATE); + RESET_EFFECT(flanger.depth, FLANGER, DEPTH); + RESET_EFFECT(flanger.feedback, FLANGER, FEEDBACK); + RESET_EFFECT(flanger.delay, FLANGER, DELAY); + + RESET_EFFECT(freqshift.frequency, FREQUENCY_SHIFTER, FREQUENCY); + RESET_EFFECT(freqshift.left_direction, FREQUENCY_SHIFTER, LEFT_DIRECTION); + RESET_EFFECT(freqshift.right_direction, FREQUENCY_SHIFTER, RIGHT_DIRECTION); + + RESET_EFFECT(vocal_morpher.phonemea, VOCAL_MORPHER, PHONEMEA); + RESET_EFFECT(vocal_morpher.phonemeb, VOCAL_MORPHER, PHONEMEB); + RESET_EFFECT(vocal_morpher.phonemea_coarse_tuning, VOCAL_MORPHER, PHONEMEA_COARSE_TUNING); + RESET_EFFECT(vocal_morpher.phonemeb_coarse_tuning, VOCAL_MORPHER, PHONEMEB_COARSE_TUNING); + RESET_EFFECT(vocal_morpher.waveform, VOCAL_MORPHER, WAVEFORM); + RESET_EFFECT(vocal_morpher.rate, VOCAL_MORPHER, RATE); + + RESET_EFFECT(pitchshift.coarse_tune, PITCH_SHIFTER, COARSE_TUNE); + RESET_EFFECT(pitchshift.fine_tune, PITCH_SHIFTER, FINE_TUNE); + + RESET_EFFECT(ringmod.frequency, RING_MODULATOR, FREQUENCY); + RESET_EFFECT(ringmod.highpass_cutoff, RING_MODULATOR, HIGHPASS_CUTOFF); + RESET_EFFECT(ringmod.waveform, RING_MODULATOR, WAVEFORM); + + RESET_EFFECT(autowah.attack_time, AUTOWAH, ATTACK_TIME); + RESET_EFFECT(autowah.release_time, AUTOWAH, RELEASE_TIME); + RESET_EFFECT(autowah.resonance, AUTOWAH, RESONANCE); + RESET_EFFECT(autowah.peak_gain, AUTOWAH, PEAK_GAIN); + + RESET_EFFECT(compressor.onoff, COMPRESSOR, ONOFF); + + RESET_EFFECT(eq.low_gain, EQUALIZER, LOW_GAIN); + RESET_EFFECT(eq.low_cutoff, EQUALIZER, LOW_CUTOFF); + RESET_EFFECT(eq.mid1_gain, EQUALIZER, MID1_GAIN); + RESET_EFFECT(eq.mid1_center, EQUALIZER, MID1_CENTER); + RESET_EFFECT(eq.mid1_width, EQUALIZER, MID1_WIDTH); + RESET_EFFECT(eq.mid2_gain, EQUALIZER, MID2_GAIN); + RESET_EFFECT(eq.mid2_center, EQUALIZER, MID2_CENTER); + RESET_EFFECT(eq.mid2_width, EQUALIZER, MID2_WIDTH); + RESET_EFFECT(eq.high_gain, EQUALIZER, HIGH_GAIN); + RESET_EFFECT(eq.high_cutoff, EQUALIZER, HIGH_CUTOFF); +} + +#undef RESET_EFFECT +#undef RESET_EFFECT_FVEC3 +#undef VAL + #endif // defined(HAVE_OPENAL) diff --git a/src/typedef.h b/src/typedef.h index bf35ecadc..72b26bc8b 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -235,6 +235,7 @@ TYPEDEF (mdllistitem_t); TYPEDEF (vector2_t); TYPEDEF (f_vector2_t); TYPEDEF (vector3_t); +TYPEDEF (f_vector3_t); TYPEDEF (vector4_t); TYPEDEF (matrix_t);