shithub: choc

Download patch

ref: 51efdd70e49a1378cc828113a3ee3997f85cdc14
parent: 525e8d80dfd67d4562b7a4d40e685a26b860eada
author: Simon Howard <fraggle@gmail.com>
date: Thu Oct 2 14:46:11 EDT 2008

Split out high-level sound code from hexen/i_ibm.c and refactor to use
common interface.

Subversion-branch: /branches/raven-branch
Subversion-revision: 1324

--- a/src/doom/deh_sound.c
+++ b/src/doom/deh_sound.c
@@ -98,7 +98,6 @@
     // Set the field value
 
     DEH_SetMapping(context, &sound_mapping, sfx, variable_name, ivalue);
-
 }
 
 deh_section_t deh_section_sound =
--- a/src/doom/sounds.c
+++ b/src/doom/sounds.c
@@ -117,9 +117,9 @@
 //
 
 #define SOUND(name, priority) \
-  { name, priority, NULL, -1, -1, 0, 0, -1, NULL }
+  { NULL, name, priority, NULL, -1, -1, 0, 0, -1, NULL }
 #define SOUND_LINK(name, priority, link_id, pitch, volume) \
-  { name, priority, &S_sfx[link_id], pitch, volume, 0, 0, -1, NULL }
+  { NULL, name, priority, &S_sfx[link_id], pitch, volume, 0, 0, -1, NULL }
 
 sfxinfo_t S_sfx[] =
 {
--- a/src/heretic/sounds.c
+++ b/src/heretic/sounds.c
@@ -103,9 +103,9 @@
     */
 
 #define SOUND(name, priority, numchannels) \
-    { name, priority, NULL, -1, -1, -1, 0, numchannels, NULL }
+    { NULL, name, priority, NULL, -1, -1, -1, 0, numchannels, NULL }
 #define SOUND_LINK(name, link_id, priority, numchannels) \
-    { name, priority, &S_sfx[link_id], 0, 0, -1, 0, numchannels, NULL }
+    { NULL, name, priority, &S_sfx[link_id], 0, 0, -1, 0, numchannels, NULL }
 
 sfxinfo_t S_sfx[] = {
     SOUND("",        0,   0),
--- a/src/hexen/Makefile.am
+++ b/src/hexen/Makefile.am
@@ -49,11 +49,11 @@
 r_plane.c                             \
 r_segs.c                              \
 r_things.c                            \
+s_sound.c           s_sound.h         \
 sb_bar.c                              \
 sc_man.c                              \
 sn_sonix.c                            \
 sounds.c            sounds.h          \
-                    soundst.h         \
 st_start.c          st_start.h        \
 sv_save.c                             \
                     textdefs.h        \
@@ -61,6 +61,6 @@
 
 EXTRA_DIST=                           \
 i_ibm.c                               \
-i_sound.c           i_sound.h
+i_sound.c           
 
 libhexen_a_SOURCES=$(SOURCE_FILES)
--- a/src/hexen/a_action.c
+++ b/src/hexen/a_action.c
@@ -26,7 +26,7 @@
 
 #include "h2def.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 // MACROS ------------------------------------------------------------------
 
--- a/src/hexen/ct_chat.c
+++ b/src/hexen/ct_chat.c
@@ -25,9 +25,9 @@
 #include <string.h>
 #include <ctype.h>
 #include "h2def.h"
+#include "s_sound.h"
 #include "doomkeys.h"
 #include "p_local.h"
-#include "soundst.h"
 #include "v_video.h"
 
 #define NUMKEYS 256
--- a/src/hexen/d_net.c
+++ b/src/hexen/d_net.c
@@ -23,6 +23,7 @@
 
 
 #include "h2def.h"
+#include "s_sound.h"
 #include "doomkeys.h"
 #include "i_video.h"
 #include "i_system.h"
--- a/src/hexen/f_finale.c
+++ b/src/hexen/f_finale.c
@@ -27,8 +27,8 @@
 #include "h2def.h"
 #include "i_system.h"
 #include "i_video.h"
-#include "soundst.h"
 #include "p_local.h"
+#include "s_sound.h"
 #include <ctype.h>
 #include "v_video.h"
 
--- a/src/hexen/g_game.c
+++ b/src/hexen/g_game.c
@@ -24,6 +24,7 @@
 
 #include <string.h>
 #include "h2def.h"
+#include "s_sound.h"
 #include "doomkeys.h"
 #include "i_video.h"
 #include "i_system.h"
@@ -30,7 +31,6 @@
 #include "i_timer.h"
 #include "m_misc.h"
 #include "p_local.h"
-#include "soundst.h"
 #include "v_video.h"
 
 #define AM_STARTKEY	9
--- a/src/hexen/h2_main.c
+++ b/src/hexen/h2_main.c
@@ -33,10 +33,10 @@
 #include <stdlib.h>
 #include <time.h>
 #include "h2def.h"
+#include "s_sound.h"
 #include "i_system.h"
 #include "m_argv.h"
 #include "p_local.h"
-#include "soundst.h"
 #include "v_video.h"
 
 // MACROS ------------------------------------------------------------------
--- a/src/hexen/i_ibm.c
+++ b/src/hexen/i_ibm.c
@@ -34,7 +34,6 @@
 #include "p_local.h"            // for P_AproxDistance
 #include "sounds.h"
 #include "i_sound.h"
-#include "soundst.h"
 #include "st_start.h"
 #include "dmx.h"
 #include "dpmiapi.h"
@@ -41,10 +40,6 @@
 
 // Macros
 
-#define DEFAULT_ARCHIVEPATH     "o:\\sound\\archive\\"
-#define PRIORITY_MAX_ADJUST 10
-#define DIST_ADJUST (MAX_SND_DIST/PRIORITY_MAX_ADJUST)
-
 #define DPMI_INT 0x31
 
 #define SEQ_ADDR 0x3C4
@@ -102,969 +97,6 @@
 int i_Vector;
 externdata_t *i_ExternData;
 boolean useexterndriver;
-
-boolean i_CDMusic;
-int i_CDTrack;
-int i_CDCurrentTrack;
-int i_CDMusicLength;
-int oldTic;
-
-/*
-===============================================================================
-
-		MUSIC & SFX API
-
-===============================================================================
-*/
-
-//static channel_t channel[MAX_CHANNELS];
-
-//static int rs; //the current registered song.
-//int mus_song = -1;
-//int mus_lumpnum;
-//void *mus_sndptr;
-//byte *soundCurve;
-
-extern sfxinfo_t S_sfx[];
-extern musicinfo_t S_music[];
-
-static channel_t Channel[MAX_CHANNELS];
-static int RegisteredSong;      //the current registered song.
-static int NextCleanup;
-static boolean MusicPaused;
-static int Mus_Song = -1;
-static int Mus_LumpNum;
-static void *Mus_SndPtr;
-static byte *SoundCurve;
-
-static boolean UseSndScript;
-static char ArchivePath[128];
-
-extern int snd_MusicDevice;
-extern int snd_SfxDevice;
-extern int snd_MaxVolume;
-extern int snd_MusicVolume;
-extern int snd_Channels;
-
-extern int startepisode;
-extern int startmap;
-
-// int AmbChan;
-
-//==========================================================================
-//
-// S_Start
-//
-//==========================================================================
-
-void S_Start(void)
-{
-    S_StopAllSound();
-    S_StartSong(gamemap, true);
-}
-
-//==========================================================================
-//
-// S_StartSong
-//
-//==========================================================================
-
-void S_StartSong(int song, boolean loop)
-{
-    char *songLump;
-    int track;
-
-    if (i_CDMusic)
-    {                           // Play a CD track, instead
-        if (i_CDTrack)
-        {                       // Default to the player-chosen track
-            track = i_CDTrack;
-        }
-        else
-        {
-            track = P_GetMapCDTrack(gamemap);
-        }
-        if (track == i_CDCurrentTrack && i_CDMusicLength > 0)
-        {
-            return;
-        }
-        if (!I_CDMusPlay(track))
-        {
-            if (loop)
-            {
-                i_CDMusicLength = 35 * I_CDMusTrackLength(track);
-                oldTic = gametic;
-            }
-            else
-            {
-                i_CDMusicLength = -1;
-            }
-            i_CDCurrentTrack = track;
-        }
-    }
-    else
-    {
-        if (song == Mus_Song)
-        {                       // don't replay an old song
-            return;
-        }
-        if (RegisteredSong)
-        {
-            I_StopSong(RegisteredSong);
-            I_UnRegisterSong(RegisteredSong);
-            if (UseSndScript)
-            {
-                Z_Free(Mus_SndPtr);
-            }
-            else
-            {
-                Z_ChangeTag(lumpcache[Mus_LumpNum], PU_CACHE);
-            }
-#ifdef __WATCOMC__
-            _dpmi_unlockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size);
-#endif
-            RegisteredSong = 0;
-        }
-        songLump = P_GetMapSongLump(song);
-        if (!songLump)
-        {
-            return;
-        }
-        if (UseSndScript)
-        {
-            char name[128];
-            sprintf(name, "%s%s.lmp", ArchivePath, songLump);
-            M_ReadFile(name, (byte **) & Mus_SndPtr);
-        }
-        else
-        {
-            Mus_LumpNum = W_GetNumForName(songLump);
-            Mus_SndPtr = W_CacheLumpNum(Mus_LumpNum, PU_MUSIC);
-        }
-#ifdef __WATCOMC__
-        _dpmi_lockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size);
-#endif
-        RegisteredSong = I_RegisterSong(Mus_SndPtr);
-        I_PlaySong(RegisteredSong, loop);       // 'true' denotes endless looping.
-        Mus_Song = song;
-    }
-}
-
-//==========================================================================
-//
-// S_StartSongName
-//
-//==========================================================================
-
-void S_StartSongName(char *songLump, boolean loop)
-{
-    int cdTrack;
-
-    if (!songLump)
-    {
-        return;
-    }
-    if (i_CDMusic)
-    {
-        cdTrack = 0;
-
-        if (!strcmp(songLump, "hexen"))
-        {
-            cdTrack = P_GetCDTitleTrack();
-        }
-        else if (!strcmp(songLump, "hub"))
-        {
-            cdTrack = P_GetCDIntermissionTrack();
-        }
-        else if (!strcmp(songLump, "hall"))
-        {
-            cdTrack = P_GetCDEnd1Track();
-        }
-        else if (!strcmp(songLump, "orb"))
-        {
-            cdTrack = P_GetCDEnd2Track();
-        }
-        else if (!strcmp(songLump, "chess") && !i_CDTrack)
-        {
-            cdTrack = P_GetCDEnd3Track();
-        }
-/*	Uncomment this, if Kevin writes a specific song for startup
-		else if(!strcmp(songLump, "start"))
-		{
-			cdTrack = P_GetCDStartTrack();
-		}
-*/
-        if (!cdTrack || (cdTrack == i_CDCurrentTrack && i_CDMusicLength > 0))
-        {
-            return;
-        }
-        if (!I_CDMusPlay(cdTrack))
-        {
-            if (loop)
-            {
-                i_CDMusicLength = 35 * I_CDMusTrackLength(cdTrack);
-                oldTic = gametic;
-            }
-            else
-            {
-                i_CDMusicLength = -1;
-            }
-            i_CDCurrentTrack = cdTrack;
-            i_CDTrack = false;
-        }
-    }
-    else
-    {
-        if (RegisteredSong)
-        {
-            I_StopSong(RegisteredSong);
-            I_UnRegisterSong(RegisteredSong);
-            if (UseSndScript)
-            {
-                Z_Free(Mus_SndPtr);
-            }
-            else
-            {
-                Z_ChangeTag(lumpcache[Mus_LumpNum], PU_CACHE);
-            }
-#ifdef __WATCOMC__
-            _dpmi_unlockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size);
-#endif
-            RegisteredSong = 0;
-        }
-        if (UseSndScript)
-        {
-            char name[128];
-            sprintf(name, "%s%s.lmp", ArchivePath, songLump);
-            M_ReadFile(name, (byte **) & Mus_SndPtr);
-        }
-        else
-        {
-            Mus_LumpNum = W_GetNumForName(songLump);
-            Mus_SndPtr = W_CacheLumpNum(Mus_LumpNum, PU_MUSIC);
-        }
-#ifdef __WATCOMC__
-        _dpmi_lockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size);
-#endif
-        RegisteredSong = I_RegisterSong(Mus_SndPtr);
-        I_PlaySong(RegisteredSong, loop);       // 'true' denotes endless looping.
-        Mus_Song = -1;
-    }
-}
-
-//==========================================================================
-//
-// S_GetSoundID
-//
-//==========================================================================
-
-int S_GetSoundID(char *name)
-{
-    int i;
-
-    for (i = 0; i < NUMSFX; i++)
-    {
-        if (!strcmp(S_sfx[i].tagName, name))
-        {
-            return i;
-        }
-    }
-    return 0;
-}
-
-//==========================================================================
-//
-// S_StartSound
-//
-//==========================================================================
-
-void S_StartSound(mobj_t * origin, int sound_id)
-{
-    S_StartSoundAtVolume(origin, sound_id, 127);
-}
-
-//==========================================================================
-//
-// S_StartSoundAtVolume
-//
-//==========================================================================
-
-void S_StartSoundAtVolume(mobj_t * origin, int sound_id, int volume)
-{
-    int dist, vol;
-    int i;
-    int priority;
-    int sep;
-    int angle;
-    int absx;
-    int absy;
-
-    static int sndcount = 0;
-    int chan;
-
-    if (sound_id == 0 || snd_MaxVolume == 0)
-        return;
-    if (origin == NULL)
-    {
-        origin = players[displayplayer].mo;
-    }
-    if (volume == 0)
-    {
-        return;
-    }
-
-    // calculate the distance before other stuff so that we can throw out
-    // sounds that are beyond the hearing range.
-    absx = abs(origin->x - players[displayplayer].mo->x);
-    absy = abs(origin->y - players[displayplayer].mo->y);
-    dist = absx + absy - (absx > absy ? absy >> 1 : absx >> 1);
-    dist >>= FRACBITS;
-    if (dist >= MAX_SND_DIST)
-    {
-        return;                 // sound is beyond the hearing range...
-    }
-    if (dist < 0)
-    {
-        dist = 0;
-    }
-    priority = S_sfx[sound_id].priority;
-    priority *= (PRIORITY_MAX_ADJUST - (dist / DIST_ADJUST));
-    if (!S_StopSoundID(sound_id, priority))
-    {
-        return;                 // other sounds have greater priority
-    }
-    for (i = 0; i < snd_Channels; i++)
-    {
-        if (origin->player)
-        {
-            i = snd_Channels;
-            break;              // let the player have more than one sound.
-        }
-        if (origin == Channel[i].mo)
-        {                       // only allow other mobjs one sound
-            S_StopSound(Channel[i].mo);
-            break;
-        }
-    }
-    if (i >= snd_Channels)
-    {
-        for (i = 0; i < snd_Channels; i++)
-        {
-            if (Channel[i].mo == NULL)
-            {
-                break;
-            }
-        }
-        if (i >= snd_Channels)
-        {
-            // look for a lower priority sound to replace.
-            sndcount++;
-            if (sndcount >= snd_Channels)
-            {
-                sndcount = 0;
-            }
-            for (chan = 0; chan < snd_Channels; chan++)
-            {
-                i = (sndcount + chan) % snd_Channels;
-                if (priority >= Channel[i].priority)
-                {
-                    chan = -1;  //denote that sound should be replaced.
-                    break;
-                }
-            }
-            if (chan != -1)
-            {
-                return;         //no free channels.
-            }
-            else                //replace the lower priority sound.
-            {
-                if (Channel[i].handle)
-                {
-                    if (I_SoundIsPlaying(Channel[i].handle))
-                    {
-                        I_StopSound(Channel[i].handle);
-                    }
-                    if (S_sfx[Channel[i].sound_id].usefulness > 0)
-                    {
-                        S_sfx[Channel[i].sound_id].usefulness--;
-                    }
-                }
-            }
-        }
-    }
-    if (S_sfx[sound_id].lumpnum == 0)
-    {
-        S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]);
-    }
-    if (S_sfx[sound_id].snd_ptr == NULL)
-    {
-        if (UseSndScript)
-        {
-            char name[128];
-            sprintf(name, "%s%s.lmp", ArchivePath, S_sfx[sound_id].lumpname);
-            M_ReadFile(name, (byte **) & S_sfx[sound_id].snd_ptr);
-        }
-        else
-        {
-            S_sfx[sound_id].snd_ptr = W_CacheLumpNum(S_sfx[sound_id].lumpnum,
-                                                     PU_SOUND);
-        }
-#ifdef __WATCOMC__
-        _dpmi_lockregion(S_sfx[sound_id].snd_ptr,
-                         lumpinfo[S_sfx[sound_id].lumpnum].size);
-#endif
-    }
-
-    vol = (SoundCurve[dist] * (snd_MaxVolume * 8) * volume) >> 14;
-    if (origin == players[displayplayer].mo)
-    {
-        sep = 128;
-//              vol = (volume*(snd_MaxVolume+1)*8)>>7;
-    }
-    else
-    {
-        angle = R_PointToAngle2(players[displayplayer].mo->x,
-                                players[displayplayer].mo->y,
-                                Channel[i].mo->x, Channel[i].mo->y);
-        angle = (angle - viewangle) >> 24;
-        sep = angle * 2 - 128;
-        if (sep < 64)
-            sep = -sep;
-        if (sep > 192)
-            sep = 512 - sep;
-//              vol = SoundCurve[dist];
-    }
-
-    if (S_sfx[sound_id].changePitch)
-    {
-        Channel[i].pitch = (byte) (127 + (M_Random() & 7) - (M_Random() & 7));
-    }
-    else
-    {
-        Channel[i].pitch = 127;
-    }
-    Channel[i].handle = I_StartSound(sound_id, S_sfx[sound_id].snd_ptr, vol,
-                                     sep, Channel[i].pitch, 0);
-    Channel[i].mo = origin;
-    Channel[i].sound_id = sound_id;
-    Channel[i].priority = priority;
-    Channel[i].volume = volume;
-    if (S_sfx[sound_id].usefulness < 0)
-    {
-        S_sfx[sound_id].usefulness = 1;
-    }
-    else
-    {
-        S_sfx[sound_id].usefulness++;
-    }
-}
-
-//==========================================================================
-//
-// S_StopSoundID
-//
-//==========================================================================
-
-boolean S_StopSoundID(int sound_id, int priority)
-{
-    int i;
-    int lp;                     //least priority
-    int found;
-
-    if (S_sfx[sound_id].numchannels == -1)
-    {
-        return (true);
-    }
-    lp = -1;                    //denote the argument sound_id
-    found = 0;
-    for (i = 0; i < snd_Channels; i++)
-    {
-        if (Channel[i].sound_id == sound_id && Channel[i].mo)
-        {
-            found++;            //found one.  Now, should we replace it??
-            if (priority >= Channel[i].priority)
-            {                   // if we're gonna kill one, then this'll be it
-                lp = i;
-                priority = Channel[i].priority;
-            }
-        }
-    }
-    if (found < S_sfx[sound_id].numchannels)
-    {
-        return (true);
-    }
-    else if (lp == -1)
-    {
-        return (false);         // don't replace any sounds
-    }
-    if (Channel[lp].handle)
-    {
-        if (I_SoundIsPlaying(Channel[lp].handle))
-        {
-            I_StopSound(Channel[lp].handle);
-        }
-        if (S_sfx[Channel[lp].sound_id].usefulness > 0)
-        {
-            S_sfx[Channel[lp].sound_id].usefulness--;
-        }
-        Channel[lp].mo = NULL;
-    }
-    return (true);
-}
-
-//==========================================================================
-//
-// S_StopSound
-//
-//==========================================================================
-
-void S_StopSound(mobj_t * origin)
-{
-    int i;
-
-    for (i = 0; i < snd_Channels; i++)
-    {
-        if (Channel[i].mo == origin)
-        {
-            I_StopSound(Channel[i].handle);
-            if (S_sfx[Channel[i].sound_id].usefulness > 0)
-            {
-                S_sfx[Channel[i].sound_id].usefulness--;
-            }
-            Channel[i].handle = 0;
-            Channel[i].mo = NULL;
-        }
-    }
-}
-
-//==========================================================================
-//
-// S_StopAllSound
-//
-//==========================================================================
-
-void S_StopAllSound(void)
-{
-    int i;
-
-    //stop all sounds
-    for (i = 0; i < snd_Channels; i++)
-    {
-        if (Channel[i].handle)
-        {
-            S_StopSound(Channel[i].mo);
-        }
-    }
-    memset(Channel, 0, 8 * sizeof(channel_t));
-}
-
-//==========================================================================
-//
-// S_SoundLink
-//
-//==========================================================================
-
-void S_SoundLink(mobj_t * oldactor, mobj_t * newactor)
-{
-    int i;
-
-    for (i = 0; i < snd_Channels; i++)
-    {
-        if (Channel[i].mo == oldactor)
-            Channel[i].mo = newactor;
-    }
-}
-
-//==========================================================================
-//
-// S_PauseSound
-//
-//==========================================================================
-
-void S_PauseSound(void)
-{
-    if (i_CDMusic)
-    {
-        I_CDMusStop();
-    }
-    else
-    {
-        I_PauseSong(RegisteredSong);
-    }
-}
-
-//==========================================================================
-//
-// S_ResumeSound
-//
-//==========================================================================
-
-void S_ResumeSound(void)
-{
-    if (i_CDMusic)
-    {
-        I_CDMusResume();
-    }
-    else
-    {
-        I_ResumeSong(RegisteredSong);
-    }
-}
-
-//==========================================================================
-//
-// S_UpdateSounds
-//
-//==========================================================================
-
-void S_UpdateSounds(mobj_t * listener)
-{
-    int i, dist, vol;
-    int angle;
-    int sep;
-    int priority;
-    int absx;
-    int absy;
-
-    if (i_CDMusic)
-    {
-        I_UpdateCDMusic();
-    }
-    if (snd_MaxVolume == 0)
-    {
-        return;
-    }
-
-    // Update any Sequences
-    SN_UpdateActiveSequences();
-
-    if (NextCleanup < gametic)
-    {
-        if (UseSndScript)
-        {
-            for (i = 0; i < NUMSFX; i++)
-            {
-                if (S_sfx[i].usefulness == 0 && S_sfx[i].snd_ptr)
-                {
-                    S_sfx[i].usefulness = -1;
-                }
-            }
-        }
-        else
-        {
-            for (i = 0; i < NUMSFX; i++)
-            {
-                if (S_sfx[i].usefulness == 0 && S_sfx[i].snd_ptr)
-                {
-                    if (lumpcache[S_sfx[i].lumpnum])
-                    {
-                        if (((memblock_t *) ((byte *)
-                                             (lumpcache[S_sfx[i].lumpnum]) -
-                                             sizeof(memblock_t)))->id ==
-                            0x1d4a11)
-                        {       // taken directly from the Z_ChangeTag macro
-                            Z_ChangeTag2(lumpcache[S_sfx[i].lumpnum],
-                                         PU_CACHE);
-#ifdef __WATCOMC__
-                            _dpmi_unlockregion(S_sfx[i].snd_ptr,
-                                               lumpinfo[S_sfx[i].lumpnum].
-                                               size);
-#endif
-                        }
-                    }
-                    S_sfx[i].usefulness = -1;
-                    S_sfx[i].snd_ptr = NULL;
-                }
-            }
-        }
-        NextCleanup = gametic + 35 * 30;        // every 30 seconds
-    }
-    for (i = 0; i < snd_Channels; i++)
-    {
-        if (!Channel[i].handle || S_sfx[Channel[i].sound_id].usefulness == -1)
-        {
-            continue;
-        }
-        if (!I_SoundIsPlaying(Channel[i].handle))
-        {
-            if (S_sfx[Channel[i].sound_id].usefulness > 0)
-            {
-                S_sfx[Channel[i].sound_id].usefulness--;
-            }
-            Channel[i].handle = 0;
-            Channel[i].mo = NULL;
-            Channel[i].sound_id = 0;
-        }
-        if (Channel[i].mo == NULL || Channel[i].sound_id == 0
-            || Channel[i].mo == listener)
-        {
-            continue;
-        }
-        else
-        {
-            absx = abs(Channel[i].mo->x - listener->x);
-            absy = abs(Channel[i].mo->y - listener->y);
-            dist = absx + absy - (absx > absy ? absy >> 1 : absx >> 1);
-            dist >>= FRACBITS;
-
-            if (dist >= MAX_SND_DIST)
-            {
-                S_StopSound(Channel[i].mo);
-                continue;
-            }
-            if (dist < 0)
-            {
-                dist = 0;
-            }
-            //vol = SoundCurve[dist];
-            vol =
-                (SoundCurve[dist] * (snd_MaxVolume * 8) *
-                 Channel[i].volume) >> 14;
-            if (Channel[i].mo == listener)
-            {
-                sep = 128;
-            }
-            else
-            {
-                angle = R_PointToAngle2(listener->x, listener->y,
-                                        Channel[i].mo->x, Channel[i].mo->y);
-                angle = (angle - viewangle) >> 24;
-                sep = angle * 2 - 128;
-                if (sep < 64)
-                    sep = -sep;
-                if (sep > 192)
-                    sep = 512 - sep;
-            }
-            I_UpdateSoundParams(Channel[i].handle, vol, sep,
-                                Channel[i].pitch);
-            priority = S_sfx[Channel[i].sound_id].priority;
-            priority *= PRIORITY_MAX_ADJUST - (dist / DIST_ADJUST);
-            Channel[i].priority = priority;
-        }
-    }
-}
-
-//==========================================================================
-//
-// S_Init
-//
-//==========================================================================
-
-void S_Init(void)
-{
-    SoundCurve = W_CacheLumpName("SNDCURVE", PU_STATIC);
-//      SoundCurve = Z_Malloc(MAX_SND_DIST, PU_STATIC, NULL);
-    I_StartupSound();
-    if (snd_Channels > 8)
-    {
-        snd_Channels = 8;
-    }
-    I_SetChannels(snd_Channels);
-    I_SetMusicVolume(snd_MusicVolume);
-
-    // Attempt to setup CD music
-    if (snd_MusicDevice == snd_CDMUSIC)
-    {
-        ST_Message("    Attempting to initialize CD Music: ");
-        if (!cdrom)
-        {
-            i_CDMusic = (I_CDMusInit() != -1);
-        }
-        else
-        {                       // The user is trying to use the cdrom for both game and music
-            i_CDMusic = false;
-        }
-        if (i_CDMusic)
-        {
-            ST_Message("initialized.\n");
-        }
-        else
-        {
-            ST_Message("failed.\n");
-        }
-    }
-}
-
-//==========================================================================
-//
-// S_GetChannelInfo
-//
-//==========================================================================
-
-void S_GetChannelInfo(SoundInfo_t * s)
-{
-    int i;
-    ChanInfo_t *c;
-
-    s->channelCount = snd_Channels;
-    s->musicVolume = snd_MusicVolume;
-    s->soundVolume = snd_MaxVolume;
-    for (i = 0; i < snd_Channels; i++)
-    {
-        c = &s->chan[i];
-        c->id = Channel[i].sound_id;
-        c->priority = Channel[i].priority;
-        c->name = S_sfx[c->id].lumpname;
-        c->mo = Channel[i].mo;
-        c->distance = P_AproxDistance(c->mo->x - viewx, c->mo->y - viewy)
-            >> FRACBITS;
-    }
-}
-
-//==========================================================================
-//
-// S_GetSoundPlayingInfo
-//
-//==========================================================================
-
-boolean S_GetSoundPlayingInfo(mobj_t * mobj, int sound_id)
-{
-    int i;
-
-    for (i = 0; i < snd_Channels; i++)
-    {
-        if (Channel[i].sound_id == sound_id && Channel[i].mo == mobj)
-        {
-            if (I_SoundIsPlaying(Channel[i].handle))
-            {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-//==========================================================================
-//
-// S_SetMusicVolume
-//
-//==========================================================================
-
-void S_SetMusicVolume(void)
-{
-    if (i_CDMusic)
-    {
-        I_CDMusSetVolume(snd_MusicVolume * 16); // 0-255
-    }
-    else
-    {
-        I_SetMusicVolume(snd_MusicVolume);
-    }
-    if (snd_MusicVolume == 0)
-    {
-        if (!i_CDMusic)
-        {
-            I_PauseSong(RegisteredSong);
-        }
-        MusicPaused = true;
-    }
-    else if (MusicPaused)
-    {
-        if (!i_CDMusic)
-        {
-            I_ResumeSong(RegisteredSong);
-        }
-        MusicPaused = false;
-    }
-}
-
-//==========================================================================
-//
-// S_ShutDown
-//
-//==========================================================================
-
-void S_ShutDown(void)
-{
-    extern int tsm_ID;
-    if (tsm_ID != -1)
-    {
-        I_StopSong(RegisteredSong);
-        I_UnRegisterSong(RegisteredSong);
-        I_ShutdownSound();
-    }
-    if (i_CDMusic)
-    {
-        I_CDMusStop();
-    }
-}
-
-//==========================================================================
-//
-// S_InitScript
-//
-//==========================================================================
-
-void S_InitScript(void)
-{
-    int p;
-    int i;
-
-    strcpy(ArchivePath, DEFAULT_ARCHIVEPATH);
-    if (!(p = M_CheckParm("-devsnd")))
-    {
-        UseSndScript = false;
-        SC_OpenLump("sndinfo");
-    }
-    else
-    {
-        UseSndScript = true;
-        SC_OpenFile(myargv[p + 1]);
-    }
-    while (SC_GetString())
-    {
-        if (*sc_String == '$')
-        {
-            if (!stricmp(sc_String, "$ARCHIVEPATH"))
-            {
-                SC_MustGetString();
-                strcpy(ArchivePath, sc_String);
-            }
-            else if (!stricmp(sc_String, "$MAP"))
-            {
-                SC_MustGetNumber();
-                SC_MustGetString();
-                if (sc_Number)
-                {
-                    P_PutMapSongLump(sc_Number, sc_String);
-                }
-            }
-            continue;
-        }
-        else
-        {
-            for (i = 0; i < NUMSFX; i++)
-            {
-                if (!strcmp(S_sfx[i].tagName, sc_String))
-                {
-                    SC_MustGetString();
-                    if (*sc_String != '?')
-                    {
-                        strcpy(S_sfx[i].lumpname, sc_String);
-                    }
-                    else
-                    {
-                        strcpy(S_sfx[i].lumpname, "default");
-                    }
-                    break;
-                }
-            }
-            if (i == NUMSFX)
-            {
-                SC_MustGetString();
-            }
-        }
-    }
-    SC_Close();
-
-    for (i = 0; i < NUMSFX; i++)
-    {
-        if (!strcmp(S_sfx[i].lumpname, ""))
-        {
-            strcpy(S_sfx[i].lumpname, "default");
-        }
-    }
-}
 
 //==========================================================================
 //
--- a/src/hexen/i_sound.h
+++ /dev/null
@@ -1,90 +1,0 @@
-// Emacs style mode select   -*- C++ -*- 
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 1993-1996 Id Software, Inc.
-// Copyright(C) 1993-2008 Raven Software
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-//
-//-----------------------------------------------------------------------------
-#ifndef __SOUND__
-#define __SOUND__
-
-#define SND_TICRATE             140     // tic rate for updating sound
-#define SND_MAXSONGS    40      // max number of songs in game
-#define SND_SAMPLERATE  11025   // sample rate of sound effects
-
-typedef enum
-{
-    snd_none,
-    snd_PC,
-    snd_Adlib,
-    snd_SB,
-    snd_PAS,
-    snd_GUS,
-    snd_MPU,
-    snd_MPU2,
-    snd_MPU3,
-    snd_AWE,
-    snd_CDMUSIC,
-    NUM_SCARDS
-} cardenum_t;
-
-void I_PauseSong(int handle);
-void I_ResumeSong(int handle);
-void I_SetMusicVolume(int volume);
-void I_SetSfxVolume(int volume);
-int I_RegisterSong(void *data);
-void I_UnRegisterSong(int handle);
-int I_QrySongPlaying(int handle);
-void I_StopSong(int handle);
-void I_PlaySong(int handle, int looping);
-int I_GetSfxLumpNum(sfxinfo_t * sound);
-int I_StartSound(int id, void *data, int vol, int sep, int pitch,
-                 int priority);
-void I_StopSound(int handle);
-int I_SoundIsPlaying(int handle);
-void I_UpdateSoundParams(int handle, int vol, int sep, int pitch);
-void I_sndArbitrateCards(void);
-void I_StartupSound(void);
-void I_ShutdownSound(void);
-void I_SetChannels(int channels);
-
-#endif
-
-#ifndef __ICDMUS__
-#define __ICDMUS__
-
-#define CDERR_NOTINSTALLED   10 // MSCDEX not installed
-#define CDERR_NOAUDIOSUPPORT 11 // CD-ROM Doesn't support audio
-#define CDERR_NOAUDIOTRACKS  12 // Current CD has no audio tracks
-#define CDERR_BADDRIVE       20 // Bad drive number
-#define CDERR_BADTRACK       21 // Bad track number
-#define CDERR_IOCTLBUFFMEM   22 // Not enough low memory for IOCTL
-#define CDERR_DEVREQBASE     100        // DevReq errors
-
-extern int cd_Error;
-
-int I_CDMusInit(void);
-int I_CDMusPlay(int track);
-int I_CDMusStop(void);
-int I_CDMusResume(void);
-int I_CDMusSetVolume(int volume);
-int I_CDMusFirstTrack(void);
-int I_CDMusLastTrack(void);
-int I_CDMusTrackLength(int track);
-
-#endif
--- a/src/hexen/in_lude.c
+++ b/src/hexen/in_lude.c
@@ -23,6 +23,7 @@
 
 
 #include "h2def.h"
+#include "s_sound.h"
 #include "i_system.h"
 #include "i_video.h"
 #include <ctype.h>
--- a/src/hexen/m_misc.c
+++ b/src/hexen/m_misc.c
@@ -38,7 +38,7 @@
 #include "i_system.h"
 #include "m_argv.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 // MACROS ------------------------------------------------------------------
 
--- a/src/hexen/mn_menu.c
+++ b/src/hexen/mn_menu.c
@@ -31,7 +31,7 @@
 #include "i_video.h"
 #include "p_local.h"
 #include "r_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 #include "v_video.h"
 
 // MACROS ------------------------------------------------------------------
--- a/src/hexen/p_acs.c
+++ b/src/hexen/p_acs.c
@@ -25,6 +25,7 @@
 // HEADER FILES ------------------------------------------------------------
 
 #include "h2def.h"
+#include "s_sound.h"
 #include "i_system.h"
 #include "p_local.h"
 
--- a/src/hexen/p_anim.c
+++ b/src/hexen/p_anim.c
@@ -27,6 +27,7 @@
 #include "h2def.h"
 #include "i_system.h"
 #include "p_local.h"
+#include "s_sound.h"
 
 // MACROS ------------------------------------------------------------------
 
--- a/src/hexen/p_ceilng.c
+++ b/src/hexen/p_ceilng.c
@@ -24,7 +24,6 @@
 
 #include "h2def.h"
 #include "p_local.h"
-#include "soundst.h"
 
 //==================================================================
 //==================================================================
--- a/src/hexen/p_doors.c
+++ b/src/hexen/p_doors.c
@@ -24,7 +24,6 @@
 
 #include "h2def.h"
 #include "p_local.h"
-#include "soundst.h"
 
 //==================================================================
 //==================================================================
--- a/src/hexen/p_enemy.c
+++ b/src/hexen/p_enemy.c
@@ -26,7 +26,7 @@
 #include "i_system.h"
 #include "i_swap.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 // Macros
 // Types
--- a/src/hexen/p_floor.c
+++ b/src/hexen/p_floor.c
@@ -25,7 +25,6 @@
 #include "h2def.h"
 #include "i_system.h"
 #include "p_local.h"
-#include "soundst.h"
 
 extern fixed_t FloatBobOffsets[64];
 
--- a/src/hexen/p_inter.c
+++ b/src/hexen/p_inter.c
@@ -25,7 +25,7 @@
 #include "h2def.h"
 #include "i_system.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 #define BONUSADD 6
 
--- a/src/hexen/p_map.c
+++ b/src/hexen/p_map.c
@@ -26,7 +26,7 @@
 #include "i_system.h"
 #include "m_bbox.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 static void CheckForPushSpecial(line_t * line, int side, mobj_t * mobj);
 
--- a/src/hexen/p_mobj.c
+++ b/src/hexen/p_mobj.c
@@ -27,8 +27,8 @@
 #include "h2def.h"
 #include "i_system.h"
 #include "p_local.h"
+#include "s_sound.h"
 #include "sounds.h"
-#include "soundst.h"
 
 // MACROS ------------------------------------------------------------------
 
--- a/src/hexen/p_plats.c
+++ b/src/hexen/p_plats.c
@@ -25,7 +25,6 @@
 #include "h2def.h"
 #include "i_system.h"
 #include "p_local.h"
-#include "soundst.h"
 
 plat_t *activeplats[MAXPLATS];
 
--- a/src/hexen/p_pspr.c
+++ b/src/hexen/p_pspr.c
@@ -26,7 +26,7 @@
 
 #include "h2def.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 // MACROS ------------------------------------------------------------------
 
--- a/src/hexen/p_setup.c
+++ b/src/hexen/p_setup.c
@@ -31,8 +31,8 @@
 #include "m_argv.h"
 #include "m_bbox.h"
 #include "i_swap.h"
+#include "s_sound.h"
 #include "p_local.h"
-#include "soundst.h"
 
 // MACROS ------------------------------------------------------------------
 
--- a/src/hexen/p_spec.c
+++ b/src/hexen/p_spec.c
@@ -27,7 +27,7 @@
 #include "h2def.h"
 #include "i_system.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 // MACROS ------------------------------------------------------------------
 
--- a/src/hexen/p_switch.c
+++ b/src/hexen/p_switch.c
@@ -25,7 +25,7 @@
 #include "h2def.h"
 #include "i_system.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 //==================================================================
 //
--- a/src/hexen/p_telept.c
+++ b/src/hexen/p_telept.c
@@ -27,7 +27,7 @@
 #include "h2def.h"
 #include "i_system.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 // MACROS ------------------------------------------------------------------
 
--- a/src/hexen/p_things.c
+++ b/src/hexen/p_things.c
@@ -26,7 +26,7 @@
 
 #include "h2def.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 // MACROS ------------------------------------------------------------------
 
--- a/src/hexen/p_user.c
+++ b/src/hexen/p_user.c
@@ -25,7 +25,7 @@
 #include "h2def.h"
 #include "i_system.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 
 void P_PlayerNextArtifact(player_t * player);
 
--- /dev/null
+++ b/src/hexen/s_sound.c
@@ -1,0 +1,909 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 1993-2008 Raven Software
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+//-----------------------------------------------------------------------------
+
+#include "h2def.h"
+#include "i_cdmus.h"
+#include "i_sound.h"
+#include "i_system.h"
+#include "m_argv.h"
+#include "m_misc.h"
+#include "r_local.h"
+#include "p_local.h"            // for P_AproxDistance
+#include "sounds.h"
+#include "s_sound.h"
+
+#define PRIORITY_MAX_ADJUST 10
+#define DIST_ADJUST (MAX_SND_DIST/PRIORITY_MAX_ADJUST)
+
+#define DEFAULT_ARCHIVEPATH     "o:\\sound\\archive\\"
+
+boolean i_CDMusic;
+int i_CDTrack;
+int i_CDCurrentTrack;
+int i_CDMusicLength;
+int oldTic;
+
+/*
+===============================================================================
+
+		MUSIC & SFX API
+
+===============================================================================
+*/
+
+//static channel_t channel[MAX_CHANNELS];
+
+//static int rs; //the current registered song.
+//int mus_song = -1;
+//int mus_lumpnum;
+//void *mus_sndptr;
+//byte *soundCurve;
+
+extern sfxinfo_t S_sfx[];
+extern musicinfo_t S_music[];
+
+static channel_t Channel[MAX_CHANNELS];
+static void *RegisteredSong;      //the current registered song.
+static boolean MusicPaused;
+static int Mus_Song = -1;
+static byte *Mus_SndPtr;
+static byte *SoundCurve;
+
+static char ArchivePath[128];
+
+extern int snd_MusicDevice;
+extern int snd_SfxDevice;
+extern int snd_MaxVolume;
+extern int snd_MusicVolume;
+extern int snd_Channels;
+
+extern int startepisode;
+extern int startmap;
+
+// int AmbChan;
+
+//==========================================================================
+//
+// S_Start
+//
+//==========================================================================
+
+void S_Start(void)
+{
+    S_StopAllSound();
+    S_StartSong(gamemap, true);
+}
+
+//==========================================================================
+//
+// S_StartSong
+//
+//==========================================================================
+
+void S_StartSong(int song, boolean loop)
+{
+    char *songLump;
+    int lumpnum;
+    int length;
+    int track;
+
+    if (i_CDMusic)
+    {                           // Play a CD track, instead
+        if (i_CDTrack)
+        {                       // Default to the player-chosen track
+            track = i_CDTrack;
+        }
+        else
+        {
+            track = P_GetMapCDTrack(gamemap);
+        }
+        if (track == i_CDCurrentTrack && i_CDMusicLength > 0)
+        {
+            return;
+        }
+        if (!I_CDMusPlay(track))
+        {
+            if (loop)
+            {
+                i_CDMusicLength = 35 * I_CDMusTrackLength(track);
+                oldTic = gametic;
+            }
+            else
+            {
+                i_CDMusicLength = -1;
+            }
+            i_CDCurrentTrack = track;
+        }
+    }
+    else
+    {
+        if (song == Mus_Song)
+        {                       // don't replay an old song
+            return;
+        }
+        if (RegisteredSong)
+        {
+            I_StopSong();
+            I_UnRegisterSong(RegisteredSong);
+            RegisteredSong = 0;
+        }
+        songLump = P_GetMapSongLump(song);
+        if (!songLump)
+        {
+            return;
+        }
+
+        lumpnum = W_GetNumForName(songLump);
+        Mus_SndPtr = W_CacheLumpNum(lumpnum, PU_STATIC);
+        length = W_LumpLength(lumpnum);
+
+        RegisteredSong = I_RegisterSong(Mus_SndPtr, length);
+        I_PlaySong(RegisteredSong, loop);
+        Mus_Song = song;
+
+        W_ReleaseLumpNum(lumpnum);
+    }
+}
+
+//==========================================================================
+//
+// S_StartSongName
+//
+//==========================================================================
+
+void S_StartSongName(char *songLump, boolean loop)
+{
+    int lumpnum;
+    int cdTrack;
+    int length;
+
+    if (!songLump)
+    {
+        return;
+    }
+    if (i_CDMusic)
+    {
+        cdTrack = 0;
+
+        if (!strcmp(songLump, "hexen"))
+        {
+            cdTrack = P_GetCDTitleTrack();
+        }
+        else if (!strcmp(songLump, "hub"))
+        {
+            cdTrack = P_GetCDIntermissionTrack();
+        }
+        else if (!strcmp(songLump, "hall"))
+        {
+            cdTrack = P_GetCDEnd1Track();
+        }
+        else if (!strcmp(songLump, "orb"))
+        {
+            cdTrack = P_GetCDEnd2Track();
+        }
+        else if (!strcmp(songLump, "chess") && !i_CDTrack)
+        {
+            cdTrack = P_GetCDEnd3Track();
+        }
+/*	Uncomment this, if Kevin writes a specific song for startup
+		else if(!strcmp(songLump, "start"))
+		{
+			cdTrack = P_GetCDStartTrack();
+		}
+*/
+        if (!cdTrack || (cdTrack == i_CDCurrentTrack && i_CDMusicLength > 0))
+        {
+            return;
+        }
+        if (!I_CDMusPlay(cdTrack))
+        {
+            if (loop)
+            {
+                i_CDMusicLength = 35 * I_CDMusTrackLength(cdTrack);
+                oldTic = gametic;
+            }
+            else
+            {
+                i_CDMusicLength = -1;
+            }
+            i_CDCurrentTrack = cdTrack;
+            i_CDTrack = false;
+        }
+    }
+    else
+    {
+        if (RegisteredSong)
+        {
+            I_StopSong();
+            I_UnRegisterSong(RegisteredSong);
+            RegisteredSong = NULL;
+        }
+
+        lumpnum = W_GetNumForName(songLump);
+        Mus_SndPtr = W_CacheLumpNum(lumpnum, PU_MUSIC);
+        length = W_LumpLength(lumpnum);
+
+        RegisteredSong = I_RegisterSong(Mus_SndPtr, length);
+        I_PlaySong(RegisteredSong, loop);
+        W_ReleaseLumpNum(lumpnum);
+        Mus_Song = -1;
+    }
+}
+
+//==========================================================================
+//
+// S_GetSoundID
+//
+//==========================================================================
+
+int S_GetSoundID(char *name)
+{
+    int i;
+
+    for (i = 0; i < NUMSFX; i++)
+    {
+        if (!strcmp(S_sfx[i].tagname, name))
+        {
+            return i;
+        }
+    }
+    return 0;
+}
+
+//==========================================================================
+//
+// S_StartSound
+//
+//==========================================================================
+
+void S_StartSound(mobj_t * origin, int sound_id)
+{
+    S_StartSoundAtVolume(origin, sound_id, 127);
+}
+
+//==========================================================================
+//
+// S_StartSoundAtVolume
+//
+//==========================================================================
+
+void S_StartSoundAtVolume(mobj_t * origin, int sound_id, int volume)
+{
+    int dist, vol;
+    int i;
+    int priority;
+    int sep;
+    int angle;
+    int absx;
+    int absy;
+
+    static int sndcount = 0;
+    int chan;
+
+    if (sound_id == 0 || snd_MaxVolume == 0)
+        return;
+    if (origin == NULL)
+    {
+        origin = players[displayplayer].mo;
+    }
+    if (volume == 0)
+    {
+        return;
+    }
+
+    // calculate the distance before other stuff so that we can throw out
+    // sounds that are beyond the hearing range.
+    absx = abs(origin->x - players[displayplayer].mo->x);
+    absy = abs(origin->y - players[displayplayer].mo->y);
+    dist = absx + absy - (absx > absy ? absy >> 1 : absx >> 1);
+    dist >>= FRACBITS;
+    if (dist >= MAX_SND_DIST)
+    {
+        return;                 // sound is beyond the hearing range...
+    }
+    if (dist < 0)
+    {
+        dist = 0;
+    }
+    priority = S_sfx[sound_id].priority;
+    priority *= (PRIORITY_MAX_ADJUST - (dist / DIST_ADJUST));
+    #if 0
+    // TODO
+    if (!S_StopSoundID(sound_id, priority))
+    {
+        return;                 // other sounds have greater priority
+    }
+    #endif
+    for (i = 0; i < snd_Channels; i++)
+    {
+        if (origin->player)
+        {
+            i = snd_Channels;
+            break;              // let the player have more than one sound.
+        }
+        if (origin == Channel[i].mo)
+        {                       // only allow other mobjs one sound
+            S_StopSound(Channel[i].mo);
+            break;
+        }
+    }
+    if (i >= snd_Channels)
+    {
+        for (i = 0; i < snd_Channels; i++)
+        {
+            if (Channel[i].mo == NULL)
+            {
+                break;
+            }
+        }
+        if (i >= snd_Channels)
+        {
+            // look for a lower priority sound to replace.
+            sndcount++;
+            if (sndcount >= snd_Channels)
+            {
+                sndcount = 0;
+            }
+            for (chan = 0; chan < snd_Channels; chan++)
+            {
+                i = (sndcount + chan) % snd_Channels;
+                if (priority >= Channel[i].priority)
+                {
+                    chan = -1;  //denote that sound should be replaced.
+                    break;
+                }
+            }
+            if (chan != -1)
+            {
+                return;         //no free channels.
+            }
+            else                //replace the lower priority sound.
+            {
+                if (Channel[i].handle)
+                {
+                    if (I_SoundIsPlaying(Channel[i].handle))
+                    {
+                        I_StopSound(Channel[i].handle);
+                    }
+                    if (S_sfx[Channel[i].sound_id].usefulness > 0)
+                    {
+                        S_sfx[Channel[i].sound_id].usefulness--;
+                    }
+                }
+            }
+        }
+    }
+
+    vol = (SoundCurve[dist] * (snd_MaxVolume * 8) * volume) >> 14;
+    if (origin == players[displayplayer].mo)
+    {
+        sep = 128;
+//              vol = (volume*(snd_MaxVolume+1)*8)>>7;
+    }
+    else
+    {
+        angle = R_PointToAngle2(players[displayplayer].mo->x,
+                                players[displayplayer].mo->y,
+                                Channel[i].mo->x, Channel[i].mo->y);
+        angle = (angle - viewangle) >> 24;
+        sep = angle * 2 - 128;
+        if (sep < 64)
+            sep = -sep;
+        if (sep > 192)
+            sep = 512 - sep;
+//              vol = SoundCurve[dist];
+    }
+
+#if 0
+// TODO
+    if (S_sfx[sound_id].changePitch)
+    {
+        Channel[i].pitch = (byte) (127 + (M_Random() & 7) - (M_Random() & 7));
+    }
+    else
+    {
+        Channel[i].pitch = 127;
+    }
+#endif
+    Channel[i].handle = I_StartSound(&S_sfx[sound_id],
+                                     i,
+                                     vol,
+                                     sep /* , Channel[i].pitch] */);
+    Channel[i].mo = origin;
+    Channel[i].sound_id = sound_id;
+    Channel[i].priority = priority;
+    Channel[i].volume = volume;
+    if (S_sfx[sound_id].usefulness < 0)
+    {
+        S_sfx[sound_id].usefulness = 1;
+    }
+    else
+    {
+        S_sfx[sound_id].usefulness++;
+    }
+}
+
+//==========================================================================
+//
+// S_StopSoundID
+//
+//==========================================================================
+
+boolean S_StopSoundID(int sound_id, int priority)
+{
+    int i;
+    int lp;                     //least priority
+    int found;
+
+    if (S_sfx[sound_id].numchannels == -1)
+    {
+        return (true);
+    }
+    lp = -1;                    //denote the argument sound_id
+    found = 0;
+    for (i = 0; i < snd_Channels; i++)
+    {
+        if (Channel[i].sound_id == sound_id && Channel[i].mo)
+        {
+            found++;            //found one.  Now, should we replace it??
+            if (priority >= Channel[i].priority)
+            {                   // if we're gonna kill one, then this'll be it
+                lp = i;
+                priority = Channel[i].priority;
+            }
+        }
+    }
+    if (found < S_sfx[sound_id].numchannels)
+    {
+        return (true);
+    }
+    else if (lp == -1)
+    {
+        return (false);         // don't replace any sounds
+    }
+    if (Channel[lp].handle)
+    {
+        if (I_SoundIsPlaying(Channel[lp].handle))
+        {
+            I_StopSound(Channel[lp].handle);
+        }
+        if (S_sfx[Channel[lp].sound_id].usefulness > 0)
+        {
+            S_sfx[Channel[lp].sound_id].usefulness--;
+        }
+        Channel[lp].mo = NULL;
+    }
+    return (true);
+}
+
+//==========================================================================
+//
+// S_StopSound
+//
+//==========================================================================
+
+void S_StopSound(mobj_t * origin)
+{
+    int i;
+
+    for (i = 0; i < snd_Channels; i++)
+    {
+        if (Channel[i].mo == origin)
+        {
+            I_StopSound(Channel[i].handle);
+            if (S_sfx[Channel[i].sound_id].usefulness > 0)
+            {
+                S_sfx[Channel[i].sound_id].usefulness--;
+            }
+            Channel[i].handle = 0;
+            Channel[i].mo = NULL;
+        }
+    }
+}
+
+//==========================================================================
+//
+// S_StopAllSound
+//
+//==========================================================================
+
+void S_StopAllSound(void)
+{
+    int i;
+
+    //stop all sounds
+    for (i = 0; i < snd_Channels; i++)
+    {
+        if (Channel[i].handle)
+        {
+            S_StopSound(Channel[i].mo);
+        }
+    }
+    memset(Channel, 0, 8 * sizeof(channel_t));
+}
+
+//==========================================================================
+//
+// S_SoundLink
+//
+//==========================================================================
+
+void S_SoundLink(mobj_t * oldactor, mobj_t * newactor)
+{
+    int i;
+
+    for (i = 0; i < snd_Channels; i++)
+    {
+        if (Channel[i].mo == oldactor)
+            Channel[i].mo = newactor;
+    }
+}
+
+//==========================================================================
+//
+// S_PauseSound
+//
+//==========================================================================
+
+void S_PauseSound(void)
+{
+    if (i_CDMusic)
+    {
+        I_CDMusStop();
+    }
+    else
+    {
+        I_PauseSong();
+    }
+}
+
+//==========================================================================
+//
+// S_ResumeSound
+//
+//==========================================================================
+
+void S_ResumeSound(void)
+{
+    if (i_CDMusic)
+    {
+        I_CDMusResume();
+    }
+    else
+    {
+        I_ResumeSong();
+    }
+}
+
+//==========================================================================
+//
+// S_UpdateSounds
+//
+//==========================================================================
+
+void S_UpdateSounds(mobj_t * listener)
+{
+    int i, dist, vol;
+    int angle;
+    int sep;
+    int priority;
+    int absx;
+    int absy;
+
+#ifdef CDMUSIC
+    if (i_CDMusic)
+    {
+        I_UpdateCDMusic();
+    }
+#endif
+    if (snd_MaxVolume == 0)
+    {
+        return;
+    }
+
+    // Update any Sequences
+    SN_UpdateActiveSequences();
+
+    for (i = 0; i < snd_Channels; i++)
+    {
+        if (!Channel[i].handle || S_sfx[Channel[i].sound_id].usefulness == -1)
+        {
+            continue;
+        }
+        if (!I_SoundIsPlaying(Channel[i].handle))
+        {
+            if (S_sfx[Channel[i].sound_id].usefulness > 0)
+            {
+                S_sfx[Channel[i].sound_id].usefulness--;
+            }
+            Channel[i].handle = 0;
+            Channel[i].mo = NULL;
+            Channel[i].sound_id = 0;
+        }
+        if (Channel[i].mo == NULL || Channel[i].sound_id == 0
+            || Channel[i].mo == listener)
+        {
+            continue;
+        }
+        else
+        {
+            absx = abs(Channel[i].mo->x - listener->x);
+            absy = abs(Channel[i].mo->y - listener->y);
+            dist = absx + absy - (absx > absy ? absy >> 1 : absx >> 1);
+            dist >>= FRACBITS;
+
+            if (dist >= MAX_SND_DIST)
+            {
+                S_StopSound(Channel[i].mo);
+                continue;
+            }
+            if (dist < 0)
+            {
+                dist = 0;
+            }
+            //vol = SoundCurve[dist];
+            vol =
+                (SoundCurve[dist] * (snd_MaxVolume * 8) *
+                 Channel[i].volume) >> 14;
+            if (Channel[i].mo == listener)
+            {
+                sep = 128;
+            }
+            else
+            {
+                angle = R_PointToAngle2(listener->x, listener->y,
+                                        Channel[i].mo->x, Channel[i].mo->y);
+                angle = (angle - viewangle) >> 24;
+                sep = angle * 2 - 128;
+                if (sep < 64)
+                    sep = -sep;
+                if (sep > 192)
+                    sep = 512 - sep;
+            }
+            I_UpdateSoundParams(i, vol, sep /*, Channel[i].pitch */);
+            priority = S_sfx[Channel[i].sound_id].priority;
+            priority *= PRIORITY_MAX_ADJUST - (dist / DIST_ADJUST);
+            Channel[i].priority = priority;
+        }
+    }
+}
+
+//==========================================================================
+//
+// S_Init
+//
+//==========================================================================
+
+void S_Init(void)
+{
+    SoundCurve = W_CacheLumpName("SNDCURVE", PU_STATIC);
+//      SoundCurve = Z_Malloc(MAX_SND_DIST, PU_STATIC, NULL);
+
+    I_InitSound(false);
+
+    if (snd_Channels > 8)
+    {
+        snd_Channels = 8;
+    }
+    I_SetMusicVolume(snd_MusicVolume);
+
+#ifdef CDMUSIC
+//TODO
+    // Attempt to setup CD music
+    if (snd_MusicDevice == snd_CDMUSIC)
+    {
+        ST_Message("    Attempting to initialize CD Music: ");
+        if (!cdrom)
+        {
+            i_CDMusic = (I_CDMusInit() != -1);
+        }
+        else
+        {                       // The user is trying to use the cdrom for both game and music
+            i_CDMusic = false;
+        }
+        if (i_CDMusic)
+        {
+            ST_Message("initialized.\n");
+        }
+        else
+        {
+            ST_Message("failed.\n");
+        }
+    }
+#endif
+}
+
+//==========================================================================
+//
+// S_GetChannelInfo
+//
+//==========================================================================
+
+void S_GetChannelInfo(SoundInfo_t * s)
+{
+    int i;
+    ChanInfo_t *c;
+
+    s->channelCount = snd_Channels;
+    s->musicVolume = snd_MusicVolume;
+    s->soundVolume = snd_MaxVolume;
+    for (i = 0; i < snd_Channels; i++)
+    {
+        c = &s->chan[i];
+        c->id = Channel[i].sound_id;
+        c->priority = Channel[i].priority;
+        c->name = S_sfx[c->id].name;
+        c->mo = Channel[i].mo;
+        c->distance = P_AproxDistance(c->mo->x - viewx, c->mo->y - viewy)
+            >> FRACBITS;
+    }
+}
+
+//==========================================================================
+//
+// S_GetSoundPlayingInfo
+//
+//==========================================================================
+
+boolean S_GetSoundPlayingInfo(mobj_t * mobj, int sound_id)
+{
+    int i;
+
+    for (i = 0; i < snd_Channels; i++)
+    {
+        if (Channel[i].sound_id == sound_id && Channel[i].mo == mobj)
+        {
+            if (I_SoundIsPlaying(Channel[i].handle))
+            {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+//==========================================================================
+//
+// S_SetMusicVolume
+//
+//==========================================================================
+
+void S_SetMusicVolume(void)
+{
+    if (i_CDMusic)
+    {
+        I_CDMusSetVolume(snd_MusicVolume * 16); // 0-255
+    }
+    else
+    {
+        I_SetMusicVolume(snd_MusicVolume);
+    }
+    if (snd_MusicVolume == 0)
+    {
+        if (!i_CDMusic)
+        {
+            I_PauseSong();
+        }
+        MusicPaused = true;
+    }
+    else if (MusicPaused)
+    {
+        if (!i_CDMusic)
+        {
+            I_ResumeSong();
+        }
+        MusicPaused = false;
+    }
+}
+
+//==========================================================================
+//
+// S_ShutDown
+//
+//==========================================================================
+
+void S_ShutDown(void)
+{
+    extern int tsm_ID;
+    if (tsm_ID != -1)
+    {
+        I_StopSong();
+        I_UnRegisterSong(RegisteredSong);
+        I_ShutdownSound();
+    }
+    if (i_CDMusic)
+    {
+        I_CDMusStop();
+    }
+}
+
+//==========================================================================
+//
+// S_InitScript
+//
+//==========================================================================
+
+void S_InitScript(void)
+{
+    int p;
+    int i;
+
+    strcpy(ArchivePath, DEFAULT_ARCHIVEPATH);
+
+    SC_OpenLump("sndinfo");
+
+    while (SC_GetString())
+    {
+        if (*sc_String == '$')
+        {
+            if (!strcasecmp(sc_String, "$ARCHIVEPATH"))
+            {
+                SC_MustGetString();
+                strcpy(ArchivePath, sc_String);
+            }
+            else if (!strcasecmp(sc_String, "$MAP"))
+            {
+                SC_MustGetNumber();
+                SC_MustGetString();
+                if (sc_Number)
+                {
+                    P_PutMapSongLump(sc_Number, sc_String);
+                }
+            }
+            continue;
+        }
+        else
+        {
+            for (i = 0; i < NUMSFX; i++)
+            {
+                if (!strcmp(S_sfx[i].tagname, sc_String))
+                {
+                    SC_MustGetString();
+                    if (*sc_String != '?')
+                    {
+                        strcpy(S_sfx[i].name, sc_String);
+                    }
+                    else
+                    {
+                        strcpy(S_sfx[i].name, "default");
+                    }
+                    break;
+                }
+            }
+            if (i == NUMSFX)
+            {
+                SC_MustGetString();
+            }
+        }
+    }
+    SC_Close();
+
+    for (i = 0; i < NUMSFX; i++)
+    {
+        if (!strcmp(S_sfx[i].name, ""))
+        {
+            strcpy(S_sfx[i].name, "default");
+        }
+    }
+}
+
--- /dev/null
+++ b/src/hexen/s_sound.h
@@ -1,0 +1,97 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 1993-2008 Raven Software
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __S_SOUND__
+#define __S_SOUND__
+
+/*
+typedef struct
+{
+    char name[8];
+    int p1;
+} musicinfo_t;
+*/
+
+/*
+typedef struct sfxinfo_s
+{
+    char tagName[32];
+    char lumpname[12];          // Only need 9 bytes, but padded out to be dword aligned
+    //struct sfxinfo_s *link; // Make alias for another sound
+    int priority;               // Higher priority takes precendence
+    int usefulness;             // Determines when a sound should be cached out
+    void *snd_ptr;
+    int lumpnum;
+    int numchannels;            // total number of channels a sound type may occupy
+    boolean changePitch;
+} sfxinfo_t;
+*/
+
+typedef struct
+{
+    mobj_t *mo;
+    int sound_id;
+    int handle;
+    int volume;
+    int pitch;
+    int priority;
+} channel_t;
+
+typedef struct
+{
+    long id;
+    unsigned short priority;
+    char *name;
+    mobj_t *mo;
+    int distance;
+} ChanInfo_t;
+
+typedef struct
+{
+    int channelCount;
+    int musicVolume;
+    int soundVolume;
+    ChanInfo_t chan[8];
+} SoundInfo_t;
+
+extern int snd_MaxVolume;
+extern int snd_MusicVolume;
+
+void S_Start(void);
+void S_StartSound(mobj_t * origin, int sound_id);
+int S_GetSoundID(char *name);
+void S_StartSoundAtVolume(mobj_t * origin, int sound_id, int volume);
+void S_StopSound(mobj_t * origin);
+void S_StopAllSound(void);
+void S_PauseSound(void);
+void S_ResumeSound(void);
+void S_UpdateSounds(mobj_t * listener);
+void S_StartSong(int song, boolean loop);
+void S_StartSongName(char *songLump, boolean loop);
+void S_Init(void);
+void S_GetChannelInfo(SoundInfo_t * s);
+void S_SetMusicVolume(void);
+boolean S_GetSoundPlayingInfo(mobj_t * mobj, int sound_id);
+
+#endif
--- a/src/hexen/sb_bar.c
+++ b/src/hexen/sb_bar.c
@@ -28,7 +28,7 @@
 #include "i_video.h"
 #include "m_bbox.h"
 #include "p_local.h"
-#include "soundst.h"
+#include "s_sound.h"
 #include "v_video.h"
 
 #ifdef __WATCOMC__
--- a/src/hexen/sn_sonix.c
+++ b/src/hexen/sn_sonix.c
@@ -27,7 +27,8 @@
 #include <string.h>
 #include "h2def.h"
 #include "i_system.h"
-#include "soundst.h"
+#include "i_sound.h"
+#include "s_sound.h"
 
 // MACROS ------------------------------------------------------------------
 
@@ -165,7 +166,7 @@
 
     for (i = 0; i < NUMSFX; i++)
     {
-        if (!strcasecmp(name, S_sfx[i].tagName))
+        if (!strcasecmp(name, S_sfx[i].tagname))
         {
             return i;
         }
--- a/src/hexen/sounds.c
+++ b/src/hexen/sounds.c
@@ -66,496 +66,255 @@
 
 // Sound info
 
+#define SOUND(name, priority, numchannels, pitchshift) \
+    { name, "", priority, NULL, pitchshift, 0, -1, 0, numchannels, NULL }
+
 sfxinfo_t S_sfx[] = {
     // tagname, lumpname, priority, usefulness, snd_ptr, lumpnum, numchannels,
     //              pitchshift
-    {"", "", 0, -1, NULL, 0, 0, 0}
-    ,
-    {"PlayerFighterNormalDeath", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerFighterCrazyDeath", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerFighterExtreme1Death", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerFighterExtreme2Death", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerFighterExtreme3Death", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerFighterBurnDeath", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerClericNormalDeath", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerClericCrazyDeath", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerClericExtreme1Death", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerClericExtreme2Death", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerClericExtreme3Death", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerClericBurnDeath", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerMageNormalDeath", "", 256, -1, NULL, 0, 2, 0}
-    ,
-    {"PlayerMageCrazyDeath", "", 256, -1, NULL, 0, 2, 0}
-    ,
-    {"PlayerMageExtreme1Death", "", 256, -1, NULL, 0, 2, 0}
-    ,
-    {"PlayerMageExtreme2Death", "", 256, -1, NULL, 0, 2, 0}
-    ,
-    {"PlayerMageExtreme3Death", "", 256, -1, NULL, 0, 2, 0}
-    ,
-    {"PlayerMageBurnDeath", "", 256, -1, NULL, 0, 2, 0}
-    ,
-    {"PlayerFighterPain", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerClericPain", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerMagePain", "", 256, -1, NULL, 0, 2, 0}
-    ,
-    {"PlayerFighterGrunt", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerClericGrunt", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerMageGrunt", "", 256, -1, NULL, 0, 2, 0}
-    ,
-    {"PlayerLand", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerPoisonCough", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerFighterFallingScream", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerClericFallingScream", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerMageFallingScream", "", 256, -1, NULL, 0, 2, 0}
-    ,
-    {"PlayerFallingSplat", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PlayerFighterFailedUse", "", 256, -1, NULL, 0, 1, 1}
-    ,
-    {"PlayerClericFailedUse", "", 256, -1, NULL, 0, 1, 1}
-    ,
-    {"PlayerMageFailedUse", "", 256, -1, NULL, 0, 1, 0}
-    ,
-    {"PlatformStart", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"PlatformStartMetal", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"PlatformStop", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"StoneMove", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"MetalMove", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"DoorOpen", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"DoorLocked", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"DoorOpenMetal", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"DoorCloseMetal", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"DoorCloseLight", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"DoorCloseHeavy", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"DoorCreak", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"PickupWeapon", "", 36, -1, NULL, 0, 2, 0}
-    ,
-    {"PickupArtifact", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"PickupKey", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"PickupItem", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"PickupPiece", "", 36, -1, NULL, 0, 2, 0}
-    ,
-    {"WeaponBuild", "", 36, -1, NULL, 0, 2, 0}
-    ,
-    {"UseArtifact", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"BlastRadius", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"Teleport", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"ThunderCrash", "", 30, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterPunchMiss", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterPunchHitThing", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterPunchHitWall", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterGrunt", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterAxeHitThing", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterHammerMiss", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterHammerHitThing", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterHammerHitWall", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterHammerContinuous", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterHammerExplode", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterSwordFire", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"FighterSwordExplode", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"ClericCStaffFire", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"ClericCStaffExplode", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"ClericCStaffHitThing", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"ClericFlameFire", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"ClericFlameExplode", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"ClericFlameCircle", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"MageWandFire", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"MageLightningFire", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"MageLightningZap", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"MageLightningContinuous", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"MageLightningReady", "", 30, -1, NULL, 0, 2, 1}
-    ,
-    {"MageShardsFire", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"MageShardsExplode", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"MageStaffFire", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"MageStaffExplode", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"Switch1", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"Switch2", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SerpentSight", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SerpentActive", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SerpentPain", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SerpentAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SerpentMeleeHit", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SerpentDeath", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"SerpentBirth", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SerpentFXContinuous", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SerpentFXHit", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"PotteryExplode", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"Drip", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"CentaurSight", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"CentaurActive", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"CentaurPain", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"CentaurAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"CentaurDeath", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"CentaurLeaderAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"CentaurMissileExplode", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"Wind", "", 1, -1, NULL, 0, 2, 1}
-    ,
-    {"BishopSight", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"BishopActive", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"BishopPain", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"BishopAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"BishopDeath", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"BishopMissileExplode", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"BishopBlur", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"DemonSight", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"DemonActive", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"DemonPain", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"DemonAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"DemonMissileFire", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"DemonMissileExplode", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"DemonDeath", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"WraithSight", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"WraithActive", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"WraithPain", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"WraithAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"WraithMissileFire", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"WraithMissileExplode", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"WraithDeath", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"PigActive1", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"PigActive2", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"PigPain", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"PigAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"PigDeath", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"MaulatorSight", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"MaulatorActive", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"MaulatorPain", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"MaulatorHamSwing", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"MaulatorHamHit", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"MaulatorMissileHit", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"MaulatorDeath", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"FreezeDeath", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"FreezeShatter", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"EttinSight", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"EttinActive", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"EttinPain", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"EttinAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"EttinDeath", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"FireDemonSpawn", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"FireDemonActive", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"FireDemonPain", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"FireDemonAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"FireDemonMissileHit", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"FireDemonDeath", "", 40, -1, NULL, 0, 2, 1}
-    ,
-    {"IceGuySight", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"IceGuyActive", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"IceGuyAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"IceGuyMissileExplode", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SorcererSight", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"SorcererActive", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"SorcererPain", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"SorcererSpellCast", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"SorcererBallWoosh", "", 256, -1, NULL, 0, 4, 1}
-    ,
-    {"SorcererDeathScream", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"SorcererBishopSpawn", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"SorcererBallPop", "", 80, -1, NULL, 0, 2, 1}
-    ,
-    {"SorcererBallBounce", "", 80, -1, NULL, 0, 3, 1}
-    ,
-    {"SorcererBallExplode", "", 80, -1, NULL, 0, 3, 1}
-    ,
-    {"SorcererBigBallExplode", "", 80, -1, NULL, 0, 3, 1}
-    ,
-    {"SorcererHeadScream", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"DragonSight", "", 64, -1, NULL, 0, 2, 1}
-    ,
-    {"DragonActive", "", 64, -1, NULL, 0, 2, 1}
-    ,
-    {"DragonWingflap", "", 64, -1, NULL, 0, 2, 1}
-    ,
-    {"DragonAttack", "", 64, -1, NULL, 0, 2, 1}
-    ,
-    {"DragonPain", "", 64, -1, NULL, 0, 2, 1}
-    ,
-    {"DragonDeath", "", 64, -1, NULL, 0, 2, 1}
-    ,
-    {"DragonFireballExplode", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxSight", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxActive", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxPain", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxAttack", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxCommand", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxDeath", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxStep", "", 128, -1, NULL, 0, 2, 1}
-    ,
-    {"ThrustSpikeRaise", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"ThrustSpikeLower", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"GlassShatter", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"FlechetteBounce", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"FlechetteExplode", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"LavaMove", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"WaterMove", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"IceStartMove", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"EarthStartMove", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"WaterSplash", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"LavaSizzle", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SludgeGloop", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"HolySymbolFire", "", 64, -1, NULL, 0, 2, 1}
-    ,
-    {"SpiritActive", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SpiritAttack", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SpiritDie", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"ValveTurn", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"RopePull", "", 36, -1, NULL, 0, 2, 1}
-    ,
-    {"FlyBuzz", "", 20, -1, NULL, 0, 2, 1}
-    ,
-    {"Ignite", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"PuzzleSuccess", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PuzzleFailFighter", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PuzzleFailCleric", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"PuzzleFailMage", "", 256, -1, NULL, 0, 2, 1}
-    ,
-    {"Earthquake", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"BellRing", "", 32, -1, NULL, 0, 2, 0}
-    ,
-    {"TreeBreak", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"TreeExplode", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SuitofArmorBreak", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"PoisonShroomPain", "", 20, -1, NULL, 0, 2, 1}
-    ,
-    {"PoisonShroomDeath", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"Ambient1", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient2", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient3", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient4", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient5", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient6", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient7", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient8", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient9", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient10", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient11", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient12", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient13", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient14", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"Ambient15", "", 1, -1, NULL, 0, 1, 1}
-    ,
-    {"StartupTick", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"SwitchOtherLevel", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"Respawn", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxVoiceGreetings", "", 512, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxVoiceReady", "", 512, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxVoiceBlood", "", 512, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxVoiceGame", "", 512, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxVoiceBoard", "", 512, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxVoiceWorship", "", 512, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxVoiceMaybe", "", 512, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxVoiceStrong", "", 512, -1, NULL, 0, 2, 1}
-    ,
-    {"KoraxVoiceFace", "", 512, -1, NULL, 0, 2, 1}
-    ,
-    {"BatScream", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"Chat", "", 512, -1, NULL, 0, 2, 1}
-    ,
-    {"MenuMove", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"ClockTick", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"Fireball", "", 32, -1, NULL, 0, 2, 1}
-    ,
-    {"PuppyBeat", "", 30, -1, NULL, 0, 2, 1}
-    ,
-    {"MysticIncant", "", 32, -1, NULL, 0, 4, 1}
+    SOUND("", 0, 0, 0),
+    SOUND("PlayerFighterNormalDeath", 256, 2, 1),
+    SOUND("PlayerFighterCrazyDeath", 256, 2, 1),
+    SOUND("PlayerFighterExtreme1Death", 256, 2, 1),
+    SOUND("PlayerFighterExtreme2Death", 256, 2, 1),
+    SOUND("PlayerFighterExtreme3Death", 256, 2, 1),
+    SOUND("PlayerFighterBurnDeath", 256, 2, 1),
+    SOUND("PlayerClericNormalDeath", 256, 2, 1),
+    SOUND("PlayerClericCrazyDeath", 256, 2, 1),
+    SOUND("PlayerClericExtreme1Death", 256, 2, 1),
+    SOUND("PlayerClericExtreme2Death", 256, 2, 1),
+    SOUND("PlayerClericExtreme3Death", 256, 2, 1),
+    SOUND("PlayerClericBurnDeath", 256, 2, 1),
+    SOUND("PlayerMageNormalDeath", 256, 2, 0),
+    SOUND("PlayerMageCrazyDeath", 256, 2, 0),
+    SOUND("PlayerMageExtreme1Death", 256, 2, 0),
+    SOUND("PlayerMageExtreme2Death", 256, 2, 0),
+    SOUND("PlayerMageExtreme3Death", 256, 2, 0),
+    SOUND("PlayerMageBurnDeath", 256, 2, 0),
+    SOUND("PlayerFighterPain", 256, 2, 1),
+    SOUND("PlayerClericPain", 256, 2, 1),
+    SOUND("PlayerMagePain", 256, 2, 0),
+    SOUND("PlayerFighterGrunt", 256, 2, 1),
+    SOUND("PlayerClericGrunt", 256, 2, 1),
+    SOUND("PlayerMageGrunt", 256, 2, 0),
+    SOUND("PlayerLand", 32, 2, 1),
+    SOUND("PlayerPoisonCough", 256, 2, 1),
+    SOUND("PlayerFighterFallingScream", 256, 2, 1),
+    SOUND("PlayerClericFallingScream", 256, 2, 1),
+    SOUND("PlayerMageFallingScream", 256, 2, 0),
+    SOUND("PlayerFallingSplat", 256, 2, 1),
+    SOUND("PlayerFighterFailedUse", 256, 1, 1),
+    SOUND("PlayerClericFailedUse", 256, 1, 1),
+    SOUND("PlayerMageFailedUse", 256, 1, 0),
+    SOUND("PlatformStart", 36, 2, 1),
+    SOUND("PlatformStartMetal", 36, 2, 1),
+    SOUND("PlatformStop", 40, 2, 1),
+    SOUND("StoneMove", 32, 2, 1),
+    SOUND("MetalMove", 32, 2, 1),
+    SOUND("DoorOpen", 36, 2, 1),
+    SOUND("DoorLocked", 36, 2, 1),
+    SOUND("DoorOpenMetal", 36, 2, 1),
+    SOUND("DoorCloseMetal", 36, 2, 1),
+    SOUND("DoorCloseLight", 36, 2, 1),
+    SOUND("DoorCloseHeavy", 36, 2, 1),
+    SOUND("DoorCreak", 36, 2, 1),
+    SOUND("PickupWeapon", 36, 2, 0),
+    SOUND("PickupArtifact", 36, 2, 1),
+    SOUND("PickupKey", 36, 2, 1),
+    SOUND("PickupItem", 36, 2, 1),
+    SOUND("PickupPiece", 36, 2, 0),
+    SOUND("WeaponBuild", 36, 2, 0),
+    SOUND("UseArtifact", 36, 2, 1),
+    SOUND("BlastRadius", 36, 2, 1),
+    SOUND("Teleport", 256, 2, 1),
+    SOUND("ThunderCrash", 30, 2, 1),
+    SOUND("FighterPunchMiss", 80, 2, 1),
+    SOUND("FighterPunchHitThing", 80, 2, 1),
+    SOUND("FighterPunchHitWall", 80, 2, 1),
+    SOUND("FighterGrunt", 80, 2, 1),
+    SOUND("FighterAxeHitThing", 80, 2, 1),
+    SOUND("FighterHammerMiss", 80, 2, 1),
+    SOUND("FighterHammerHitThing", 80, 2, 1),
+    SOUND("FighterHammerHitWall", 80, 2, 1),
+    SOUND("FighterHammerContinuous", 32, 2, 1),
+    SOUND("FighterHammerExplode", 80, 2, 1),
+    SOUND("FighterSwordFire", 80, 2, 1),
+    SOUND("FighterSwordExplode", 80, 2, 1),
+    SOUND("ClericCStaffFire", 80, 2, 1),
+    SOUND("ClericCStaffExplode", 40, 2, 1),
+    SOUND("ClericCStaffHitThing", 80, 2, 1),
+    SOUND("ClericFlameFire", 80, 2, 1),
+    SOUND("ClericFlameExplode", 80, 2, 1),
+    SOUND("ClericFlameCircle", 80, 2, 1),
+    SOUND("MageWandFire", 80, 2, 1),
+    SOUND("MageLightningFire", 80, 2, 1),
+    SOUND("MageLightningZap", 32, 2, 1),
+    SOUND("MageLightningContinuous", 32, 2, 1),
+    SOUND("MageLightningReady", 30, 2, 1),
+    SOUND("MageShardsFire", 80, 2, 1),
+    SOUND("MageShardsExplode", 36, 2, 1),
+    SOUND("MageStaffFire", 80, 2, 1),
+    SOUND("MageStaffExplode", 40, 2, 1),
+    SOUND("Switch1", 32, 2, 1),
+    SOUND("Switch2", 32, 2, 1),
+    SOUND("SerpentSight", 32, 2, 1),
+    SOUND("SerpentActive", 32, 2, 1),
+    SOUND("SerpentPain", 32, 2, 1),
+    SOUND("SerpentAttack", 32, 2, 1),
+    SOUND("SerpentMeleeHit", 32, 2, 1),
+    SOUND("SerpentDeath", 40, 2, 1),
+    SOUND("SerpentBirth", 32, 2, 1),
+    SOUND("SerpentFXContinuous", 32, 2, 1),
+    SOUND("SerpentFXHit", 32, 2, 1),
+    SOUND("PotteryExplode", 32, 2, 1),
+    SOUND("Drip", 32, 2, 1),
+    SOUND("CentaurSight", 32, 2, 1),
+    SOUND("CentaurActive", 32, 2, 1),
+    SOUND("CentaurPain", 32, 2, 1),
+    SOUND("CentaurAttack", 32, 2, 1),
+    SOUND("CentaurDeath", 40, 2, 1),
+    SOUND("CentaurLeaderAttack", 32, 2, 1),
+    SOUND("CentaurMissileExplode", 32, 2, 1),
+    SOUND("Wind", 1, 2, 1),
+    SOUND("BishopSight", 32, 2, 1),
+    SOUND("BishopActive", 32, 2, 1),
+    SOUND("BishopPain", 32, 2, 1),
+    SOUND("BishopAttack", 32, 2, 1),
+    SOUND("BishopDeath", 40, 2, 1),
+    SOUND("BishopMissileExplode", 32, 2, 1),
+    SOUND("BishopBlur", 32, 2, 1),
+    SOUND("DemonSight", 32, 2, 1),
+    SOUND("DemonActive", 32, 2, 1),
+    SOUND("DemonPain", 32, 2, 1),
+    SOUND("DemonAttack", 32, 2, 1),
+    SOUND("DemonMissileFire", 32, 2, 1),
+    SOUND("DemonMissileExplode", 32, 2, 1),
+    SOUND("DemonDeath", 40, 2, 1),
+    SOUND("WraithSight", 32, 2, 1),
+    SOUND("WraithActive", 32, 2, 1),
+    SOUND("WraithPain", 32, 2, 1),
+    SOUND("WraithAttack", 32, 2, 1),
+    SOUND("WraithMissileFire", 32, 2, 1),
+    SOUND("WraithMissileExplode", 32, 2, 1),
+    SOUND("WraithDeath", 40, 2, 1),
+    SOUND("PigActive1", 32, 2, 1),
+    SOUND("PigActive2", 32, 2, 1),
+    SOUND("PigPain", 32, 2, 1),
+    SOUND("PigAttack", 32, 2, 1),
+    SOUND("PigDeath", 40, 2, 1),
+    SOUND("MaulatorSight", 32, 2, 1),
+    SOUND("MaulatorActive", 32, 2, 1),
+    SOUND("MaulatorPain", 32, 2, 1),
+    SOUND("MaulatorHamSwing", 32, 2, 1),
+    SOUND("MaulatorHamHit", 32, 2, 1),
+    SOUND("MaulatorMissileHit", 32, 2, 1),
+    SOUND("MaulatorDeath", 40, 2, 1),
+    SOUND("FreezeDeath", 40, 2, 1),
+    SOUND("FreezeShatter", 40, 2, 1),
+    SOUND("EttinSight", 32, 2, 1),
+    SOUND("EttinActive", 32, 2, 1),
+    SOUND("EttinPain", 32, 2, 1),
+    SOUND("EttinAttack", 32, 2, 1),
+    SOUND("EttinDeath", 40, 2, 1),
+    SOUND("FireDemonSpawn", 32, 2, 1),
+    SOUND("FireDemonActive", 32, 2, 1),
+    SOUND("FireDemonPain", 32, 2, 1),
+    SOUND("FireDemonAttack", 32, 2, 1),
+    SOUND("FireDemonMissileHit", 32, 2, 1),
+    SOUND("FireDemonDeath", 40, 2, 1),
+    SOUND("IceGuySight", 32, 2, 1),
+    SOUND("IceGuyActive", 32, 2, 1),
+    SOUND("IceGuyAttack", 32, 2, 1),
+    SOUND("IceGuyMissileExplode", 32, 2, 1),
+    SOUND("SorcererSight", 256, 2, 1),
+    SOUND("SorcererActive", 256, 2, 1),
+    SOUND("SorcererPain", 256, 2, 1),
+    SOUND("SorcererSpellCast", 256, 2, 1),
+    SOUND("SorcererBallWoosh", 256, 4, 1),
+    SOUND("SorcererDeathScream", 256, 2, 1),
+    SOUND("SorcererBishopSpawn", 80, 2, 1),
+    SOUND("SorcererBallPop", 80, 2, 1),
+    SOUND("SorcererBallBounce", 80, 3, 1),
+    SOUND("SorcererBallExplode", 80, 3, 1),
+    SOUND("SorcererBigBallExplode", 80, 3, 1),
+    SOUND("SorcererHeadScream", 256, 2, 1),
+    SOUND("DragonSight", 64, 2, 1),
+    SOUND("DragonActive", 64, 2, 1),
+    SOUND("DragonWingflap", 64, 2, 1),
+    SOUND("DragonAttack", 64, 2, 1),
+    SOUND("DragonPain", 64, 2, 1),
+    SOUND("DragonDeath", 64, 2, 1),
+    SOUND("DragonFireballExplode", 32, 2, 1),
+    SOUND("KoraxSight", 256, 2, 1),
+    SOUND("KoraxActive", 256, 2, 1),
+    SOUND("KoraxPain", 256, 2, 1),
+    SOUND("KoraxAttack", 256, 2, 1),
+    SOUND("KoraxCommand", 256, 2, 1),
+    SOUND("KoraxDeath", 256, 2, 1),
+    SOUND("KoraxStep", 128, 2, 1),
+    SOUND("ThrustSpikeRaise", 32, 2, 1),
+    SOUND("ThrustSpikeLower", 32, 2, 1),
+    SOUND("GlassShatter", 32, 2, 1),
+    SOUND("FlechetteBounce", 32, 2, 1),
+    SOUND("FlechetteExplode", 32, 2, 1),
+    SOUND("LavaMove", 36, 2, 1),
+    SOUND("WaterMove", 36, 2, 1),
+    SOUND("IceStartMove", 36, 2, 1),
+    SOUND("EarthStartMove", 36, 2, 1),
+    SOUND("WaterSplash", 32, 2, 1),
+    SOUND("LavaSizzle", 32, 2, 1),
+    SOUND("SludgeGloop", 32, 2, 1),
+    SOUND("HolySymbolFire", 64, 2, 1),
+    SOUND("SpiritActive", 32, 2, 1),
+    SOUND("SpiritAttack", 32, 2, 1),
+    SOUND("SpiritDie", 32, 2, 1),
+    SOUND("ValveTurn", 36, 2, 1),
+    SOUND("RopePull", 36, 2, 1),
+    SOUND("FlyBuzz", 20, 2, 1),
+    SOUND("Ignite", 32, 2, 1),
+    SOUND("PuzzleSuccess", 256, 2, 1),
+    SOUND("PuzzleFailFighter", 256, 2, 1),
+    SOUND("PuzzleFailCleric", 256, 2, 1),
+    SOUND("PuzzleFailMage", 256, 2, 1),
+    SOUND("Earthquake", 32, 2, 1),
+    SOUND("BellRing", 32, 2, 0),
+    SOUND("TreeBreak", 32, 2, 1),
+    SOUND("TreeExplode", 32, 2, 1),
+    SOUND("SuitofArmorBreak", 32, 2, 1),
+    SOUND("PoisonShroomPain", 20, 2, 1),
+    SOUND("PoisonShroomDeath", 32, 2, 1),
+    SOUND("Ambient1", 1, 1, 1),
+    SOUND("Ambient2", 1, 1, 1),
+    SOUND("Ambient3", 1, 1, 1),
+    SOUND("Ambient4", 1, 1, 1),
+    SOUND("Ambient5", 1, 1, 1),
+    SOUND("Ambient6", 1, 1, 1),
+    SOUND("Ambient7", 1, 1, 1),
+    SOUND("Ambient8", 1, 1, 1),
+    SOUND("Ambient9", 1, 1, 1),
+    SOUND("Ambient10", 1, 1, 1),
+    SOUND("Ambient11", 1, 1, 1),
+    SOUND("Ambient12", 1, 1, 1),
+    SOUND("Ambient13", 1, 1, 1),
+    SOUND("Ambient14", 1, 1, 1),
+    SOUND("Ambient15", 1, 1, 1),
+    SOUND("StartupTick", 32, 2, 1),
+    SOUND("SwitchOtherLevel", 32, 2, 1),
+    SOUND("Respawn", 32, 2, 1),
+    SOUND("KoraxVoiceGreetings", 512, 2, 1),
+    SOUND("KoraxVoiceReady", 512, 2, 1),
+    SOUND("KoraxVoiceBlood", 512, 2, 1),
+    SOUND("KoraxVoiceGame", 512, 2, 1),
+    SOUND("KoraxVoiceBoard", 512, 2, 1),
+    SOUND("KoraxVoiceWorship", 512, 2, 1),
+    SOUND("KoraxVoiceMaybe", 512, 2, 1),
+    SOUND("KoraxVoiceStrong", 512, 2, 1),
+    SOUND("KoraxVoiceFace", 512, 2, 1),
+    SOUND("BatScream", 32, 2, 1),
+    SOUND("Chat", 512, 2, 1),
+    SOUND("MenuMove", 32, 2, 1),
+    SOUND("ClockTick", 32, 2, 1),
+    SOUND("Fireball", 32, 2, 1),
+    SOUND("PuppyBeat", 30, 2, 1),
+    SOUND("MysticIncant", 32, 4, 1),
 };
--- a/src/hexen/sounds.h
+++ b/src/hexen/sounds.h
@@ -25,7 +25,7 @@
 #ifndef __SOUNDSH__
 #define __SOUNDSH__
 
-#include "soundst.h"
+#include "i_sound.h"
 
 #define MAX_SND_DIST    2025
 #define MAX_CHANNELS    16
--- a/src/hexen/soundst.h
+++ /dev/null
@@ -1,93 +1,0 @@
-// Emacs style mode select   -*- C++ -*- 
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 1993-1996 Id Software, Inc.
-// Copyright(C) 1993-2008 Raven Software
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-//
-//-----------------------------------------------------------------------------
-
-
-#ifndef __SOUNDSTH__
-#define __SOUNDSTH__
-
-typedef struct
-{
-    char name[8];
-    int p1;
-} musicinfo_t;
-
-typedef struct sfxinfo_s
-{
-    char tagName[32];
-    char lumpname[12];          // Only need 9 bytes, but padded out to be dword aligned
-    //struct sfxinfo_s *link; // Make alias for another sound
-    int priority;               // Higher priority takes precendence
-    int usefulness;             // Determines when a sound should be cached out
-    void *snd_ptr;
-    int lumpnum;
-    int numchannels;            // total number of channels a sound type may occupy
-    boolean changePitch;
-} sfxinfo_t;
-
-typedef struct
-{
-    mobj_t *mo;
-    int sound_id;
-    int handle;
-    int volume;
-    int pitch;
-    int priority;
-} channel_t;
-
-typedef struct
-{
-    long id;
-    unsigned short priority;
-    char *name;
-    mobj_t *mo;
-    int distance;
-} ChanInfo_t;
-
-typedef struct
-{
-    int channelCount;
-    int musicVolume;
-    int soundVolume;
-    ChanInfo_t chan[8];
-} SoundInfo_t;
-
-extern int snd_MaxVolume;
-extern int snd_MusicVolume;
-
-void S_Start(void);
-void S_StartSound(mobj_t * origin, int sound_id);
-int S_GetSoundID(char *name);
-void S_StartSoundAtVolume(mobj_t * origin, int sound_id, int volume);
-void S_StopSound(mobj_t * origin);
-void S_StopAllSound(void);
-void S_PauseSound(void);
-void S_ResumeSound(void);
-void S_UpdateSounds(mobj_t * listener);
-void S_StartSong(int song, boolean loop);
-void S_StartSongName(char *songLump, boolean loop);
-void S_Init(void);
-void S_GetChannelInfo(SoundInfo_t * s);
-void S_SetMusicVolume(void);
-boolean S_GetSoundPlayingInfo(mobj_t * mobj, int sound_id);
-
-#endif
--- a/src/i_sound.h
+++ b/src/i_sound.h
@@ -38,8 +38,13 @@
 
 struct sfxinfo_struct
 {
-    // up to 6-character name
-    char *name;
+    // tag name, used for hexen.
+    char *tagname;
+    
+    // lump name.  If we are running with use_sfx_prefix=true, a
+    // 'DS' (or 'DP' for PC speaker sounds) is prepended to this.
+
+    char name[9];
 
     // Sfx priority
     int priority;