Skip to content

Commit

Permalink
Merge pull request #567 from jmtd/pitch-shifting
Browse files Browse the repository at this point in the history
Implementation of pitch shifting.

This appeared in early versions of Doom and (more importantly) in Heretic
and Hexen. Sound effects get pitched up and down to sound less repetitive.
  • Loading branch information
fragglet committed Jul 9, 2015
2 parents 4780944 + 8a3621b commit 93fe112
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 57 deletions.
41 changes: 39 additions & 2 deletions src/doom/s_sound.c
Expand Up @@ -59,7 +59,6 @@


#define S_STEREO_SWING (96 * FRACUNIT) #define S_STEREO_SWING (96 * FRACUNIT)


#define NORM_PITCH 128
#define NORM_PRIORITY 64 #define NORM_PRIORITY 64
#define NORM_SEP 128 #define NORM_SEP 128


Expand All @@ -74,6 +73,8 @@ typedef struct
// handle of the sound being played // handle of the sound being played
int handle; int handle;


int pitch;

} channel_t; } channel_t;


// The set of channels available // The set of channels available
Expand Down Expand Up @@ -141,6 +142,12 @@ void S_Init(int sfxVolume, int musicVolume)
S_sfx[i].lumpnum = S_sfx[i].usefulness = -1; S_sfx[i].lumpnum = S_sfx[i].usefulness = -1;
} }


// Doom defaults to pitch-shifting off.
if(snd_pitchshift == -1)
{
snd_pitchshift = 0;
}

I_AtExit(S_Shutdown, true); I_AtExit(S_Shutdown, true);
} }


Expand Down Expand Up @@ -390,12 +397,28 @@ static int S_AdjustSoundParams(mobj_t *listener, mobj_t *source,
return (*vol > 0); return (*vol > 0);
} }


// clamp supplied integer to the range 0 <= x <= 255.

static int Clamp(int x)
{
if (x < 0)
{
return 0;
}
else if (x > 255)
{
return 255;
}
return x;
}

void S_StartSound(void *origin_p, int sfx_id) void S_StartSound(void *origin_p, int sfx_id)
{ {
sfxinfo_t *sfx; sfxinfo_t *sfx;
mobj_t *origin; mobj_t *origin;
int rc; int rc;
int sep; int sep;
int pitch;
int cnum; int cnum;
int volume; int volume;


Expand All @@ -411,9 +434,11 @@ void S_StartSound(void *origin_p, int sfx_id)
sfx = &S_sfx[sfx_id]; sfx = &S_sfx[sfx_id];


// Initialize sound parameters // Initialize sound parameters
pitch = NORM_PITCH;
if (sfx->link) if (sfx->link)
{ {
volume += sfx->volume; volume += sfx->volume;
pitch = sfx->pitch;


if (volume < 1) if (volume < 1)
{ {
Expand Down Expand Up @@ -452,6 +477,17 @@ void S_StartSound(void *origin_p, int sfx_id)
sep = NORM_SEP; sep = NORM_SEP;
} }


// hacks to vary the sfx pitches
if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit)
{
pitch += 8 - (M_Random()&15);
}
else if (sfx_id != sfx_itemup && sfx_id != sfx_tink)
{
pitch += 16 - (M_Random()&31);
}
pitch = Clamp(pitch);

// kill old sound // kill old sound
S_StopSound(origin); S_StopSound(origin);


Expand All @@ -474,7 +510,8 @@ void S_StartSound(void *origin_p, int sfx_id)
sfx->lumpnum = I_GetSfxLumpNum(sfx); sfx->lumpnum = I_GetSfxLumpNum(sfx);
} }


channels[cnum].handle = I_StartSound(sfx, cnum, volume, sep); channels[cnum].pitch = pitch;
channels[cnum].handle = I_StartSound(sfx, cnum, volume, sep, channels[cnum].pitch);
} }


// //
Expand Down
17 changes: 10 additions & 7 deletions src/heretic/s_sound.c
Expand Up @@ -268,10 +268,8 @@ void S_StartSound(void *_origin, int sound_id)
sep = 512 - sep; sep = 512 - sep;
} }


// TODO: Play pitch-shifted sounds as in Vanilla Heretic channel[i].pitch = (byte) (NORM_PITCH + (M_Random() & 7) - (M_Random() & 7));

channel[i].handle = I_StartSound(&S_sfx[sound_id], i, vol, sep, channel[i].pitch);
channel[i].pitch = (byte) (127 + (M_Random() & 7) - (M_Random() & 7));
channel[i].handle = I_StartSound(&S_sfx[sound_id], i, vol, sep);
channel[i].mo = origin; channel[i].mo = origin;
channel[i].sound_id = sound_id; channel[i].sound_id = sound_id;
channel[i].priority = priority; channel[i].priority = priority;
Expand Down Expand Up @@ -327,9 +325,8 @@ void S_StartSoundAtVolume(void *_origin, int sound_id, int volume)
S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]); S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]);
} }


// TODO: Pitch shifting. channel[i].pitch = (byte) (NORM_PITCH - (M_Random() & 3) + (M_Random() & 3));
channel[i].pitch = (byte) (127 - (M_Random() & 3) + (M_Random() & 3)); channel[i].handle = I_StartSound(&S_sfx[sound_id], i, volume, 128, channel[i].pitch);
channel[i].handle = I_StartSound(&S_sfx[sound_id], i, volume, 128);
channel[i].mo = origin; channel[i].mo = origin;
channel[i].sound_id = sound_id; channel[i].sound_id = sound_id;
channel[i].priority = 1; //super low priority. channel[i].priority = 1; //super low priority.
Expand Down Expand Up @@ -527,6 +524,12 @@ void S_Init(void)


I_AtExit(S_ShutDown, true); I_AtExit(S_ShutDown, true);


// Heretic defaults to pitch-shifting on
if(snd_pitchshift == -1)
{
snd_pitchshift = 1;
}

I_PrecacheSounds(S_sfx, NUMSFX); I_PrecacheSounds(S_sfx, NUMSFX);
} }


Expand Down
22 changes: 14 additions & 8 deletions src/hexen/s_sound.c
Expand Up @@ -498,17 +498,16 @@ void S_StartSoundAtVolume(mobj_t * origin, int sound_id, int volume)
// vol = SoundCurve[dist]; // vol = SoundCurve[dist];
} }


#if 0 // if the sfxinfo_t is marked as 'can be pitch shifted'
// TODO if (S_sfx[sound_id].pitch)
if (S_sfx[sound_id].changePitch)
{ {
Channel[i].pitch = (byte) (127 + (M_Random() & 7) - (M_Random() & 7)); Channel[i].pitch = (byte) (NORM_PITCH + (M_Random() & 7) - (M_Random() & 7));
} }
else else
{ {
Channel[i].pitch = 127; Channel[i].pitch = NORM_PITCH;
} }
#endif
if (S_sfx[sound_id].lumpnum == 0) if (S_sfx[sound_id].lumpnum == 0)
{ {
S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]); S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]);
Expand All @@ -517,7 +516,8 @@ void S_StartSoundAtVolume(mobj_t * origin, int sound_id, int volume)
Channel[i].handle = I_StartSound(&S_sfx[sound_id], Channel[i].handle = I_StartSound(&S_sfx[sound_id],
i, i,
vol, vol,
sep /* , Channel[i].pitch] */); sep,
Channel[i].pitch);
Channel[i].sound_id = sound_id; Channel[i].sound_id = sound_id;
Channel[i].priority = priority; Channel[i].priority = priority;
Channel[i].volume = volume; Channel[i].volume = volume;
Expand Down Expand Up @@ -771,7 +771,7 @@ void S_UpdateSounds(mobj_t * listener)
if (sep > 192) if (sep > 192)
sep = 512 - sep; sep = 512 - sep;
} }
I_UpdateSoundParams(i, vol, sep /*, Channel[i].pitch */); I_UpdateSoundParams(i, vol, sep);
priority = S_sfx[Channel[i].sound_id].priority; priority = S_sfx[Channel[i].sound_id].priority;
priority *= PRIORITY_MAX_ADJUST - (dist / DIST_ADJUST); priority *= PRIORITY_MAX_ADJUST - (dist / DIST_ADJUST);
Channel[i].priority = priority; Channel[i].priority = priority;
Expand Down Expand Up @@ -799,6 +799,12 @@ void S_Init(void)


I_AtExit(S_ShutDown, true); I_AtExit(S_ShutDown, true);


// Hexen defaults to pitch-shifting on
if(snd_pitchshift == -1)
{
snd_pitchshift = 1;
}

I_PrecacheSounds(S_sfx, NUMSFX); I_PrecacheSounds(S_sfx, NUMSFX);


// Attempt to setup CD music // Attempt to setup CD music
Expand Down
3 changes: 2 additions & 1 deletion src/i_pcsound.c
Expand Up @@ -174,7 +174,8 @@ static boolean IsDisabledSound(sfxinfo_t *sfxinfo)
static int I_PCS_StartSound(sfxinfo_t *sfxinfo, static int I_PCS_StartSound(sfxinfo_t *sfxinfo,
int channel, int channel,
int vol, int vol,
int sep) int sep,
int pitch)
{ {
int result; int result;


Expand Down

0 comments on commit 93fe112

Please sign in to comment.