diff --git a/src/d_main.c b/src/d_main.c
index 95af1f75446a9063c539d3aac59b62b42181b003..17fac0b0cb50006423c18cf2f861ab9ca1b99976 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -1197,7 +1197,7 @@ void D_SRB2Main(void)
 	}
 	else
 	{
-		CONS_Printf("S_Init(): Setting up sound.\n");
+		CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
 	}
 	if (M_CheckParm("-nosound"))
 		nosound = true;
@@ -1212,7 +1212,7 @@ void D_SRB2Main(void)
 	}
 	I_StartupSound();
 	I_InitMusic();
-	S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
+	S_InitSfxChannels(cv_soundvolume.value);
 
 	CONS_Printf("ST_Init(): Init status bar.\n");
 	ST_Init();
diff --git a/src/i_sound.h b/src/i_sound.h
index 2045752de91edef1b928fdc1c5d791a9854fb435..8799449feafaea1e6ece723711f92cbb4198be93 100644
--- a/src/i_sound.h
+++ b/src/i_sound.h
@@ -125,6 +125,8 @@ void I_SetSfxVolume(UINT8 volume);
 //
 
 musictype_t I_GetMusicType(void);
+boolean I_MusicPlaying(void);
+boolean I_MusicPaused(void);
 
 /** \brief Init the music systems
 */
diff --git a/src/m_menu.c b/src/m_menu.c
index fd3deab8456afcabf4248ae40baf61ca166ac1e3..9a86d56e1de84dbfb9f179a68481296cc3e70e02 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -9421,7 +9421,7 @@ static void M_ToggleSFX(INT32 choice)
 		nosound = false;
 		I_StartupSound();
 		if (nosound) return;
-		S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
+		S_InitSfxChannels(cv_soundvolume.value);
 		S_StartSound(NULL, sfx_strpst);
 		OP_SoundOptionsMenu[6].status = IT_STRING | IT_CVAR;
 		//M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING);
@@ -9474,7 +9474,7 @@ static void M_ToggleDigital(INT32 choice)
 		nodigimusic = false;
 		I_InitMusic();
 		if (nodigimusic) return;
-		S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
+		S_InitSfxChannels(cv_soundvolume.value);
 		S_StopMusic();
 		if (Playing())
 			P_RestoreMusic(&players[consoleplayer]);
@@ -9531,7 +9531,7 @@ static void M_ToggleMIDI(INT32 choice)
 		nomidimusic = false;
 		I_InitMusic();
 		if (nomidimusic) return;
-		S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
+		S_InitSfxChannels(cv_soundvolume.value);
 		if (Playing())
 			P_RestoreMusic(&players[consoleplayer]);
 		else
diff --git a/src/s_sound.c b/src/s_sound.c
index f58db414573838863de7957d50e25fab87d1b747..077b798b8a31f683e2213940a16348a42e9a56bf 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -1283,6 +1283,43 @@ void S_StartSoundName(void *mo, const char *soundname)
 	S_StartSound(mo, soundnum);
 }
 
+//
+// Initializes sound stuff, including volume
+// Sets channels, SFX volume,
+//  allocates channel buffer, sets S_sfx lookup.
+//
+void S_InitSfxChannels(INT32 sfxVolume)
+{
+	INT32 i;
+
+	if (dedicated)
+		return;
+
+	S_SetSfxVolume(sfxVolume);
+
+	SetChannelsNum();
+
+	// Note that sounds have not been cached (yet).
+	for (i = 1; i < NUMSFX; i++)
+	{
+		S_sfx[i].usefulness = -1; // for I_GetSfx()
+		S_sfx[i].lumpnum = LUMPERROR;
+	}
+
+	// precache sounds if requested by cmdline, or precachesound var true
+	if (!nosound && (M_CheckParm("-precachesound") || precachesound.value))
+	{
+		// Initialize external data (all sounds) at start, keep static.
+		CONS_Printf(M_GetText("Loading sounds... "));
+
+		for (i = 1; i < NUMSFX; i++)
+			if (S_sfx[i].name)
+				S_sfx[i].data = I_GetSfx(&S_sfx[i]);
+
+		CONS_Printf(M_GetText(" pre-cached all sound data\n"));
+	}
+}
+
 /// ------------------------
 /// Music
 /// ------------------------
@@ -1309,10 +1346,7 @@ const char *compat_special_music_slots[16] =
 };
 #endif
 
-#define music_playing (music_name[0]) // String is empty if no music is playing
-
 static char      music_name[7]; // up to 6-character name
-static boolean   mus_paused     = 0;  // whether songs are mus_paused
 
 /// ------------------------
 /// Music Status
@@ -1338,6 +1372,29 @@ boolean S_MusicDisabled()
 	);
 }
 
+boolean S_MusicPlaying(void)
+{
+	return I_MusicPlaying();
+}
+
+boolean S_MusicPaused(void)
+{
+	return I_MusicPaused();
+}
+
+const char *S_MusicName(void)
+{
+	return music_name;
+}
+
+boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi)
+{
+	return (
+		(checkDigi ? W_CheckNumForName(va("O_%s", mname)) != LUMPERROR : false)
+		|| (checkMIDI ? W_CheckNumForName(va("D_%s", mname)) != LUMPERROR : false)
+	);
+}
+
 /// ------------------------
 /// Music Properties
 /// ------------------------
@@ -1361,15 +1418,15 @@ static boolean S_LoadMusic(const char *mname)
 
 	if (S_DigMusicDisabled())
 	{
-		if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR)
+		if (!S_MIDIExists(mname))
 			return false;
 		mlumpnum = W_GetNumForName(va("d_%s", mname));
 	}
 	else
 	{
-		if (W_CheckNumForName(va("o_%s", mname)) != LUMPERROR)
+		if (S_DigExists(mname))
 			mlumpnum = W_GetNumForName(va("o_%s", mname));
-		else if (W_CheckNumForName(va("d_%s", mname)) != LUMPERROR)
+		else if (S_MIDIExists(mname))
 			mlumpnum = W_GetNumForName(va("d_%s", mname));
 		else
 			return false;
@@ -1442,10 +1499,10 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
 
 void S_StopMusic(void)
 {
-	if (!music_playing)
+	if (!I_MusicPlaying())
 		return;
 
-	if (mus_paused)
+	if (I_MusicPaused())
 		I_ResumeSong();
 
 	S_SpeedMusic(1.0f);
@@ -1465,6 +1522,31 @@ void S_StopMusic(void)
 	}
 }
 
+//
+// Stop and resume music, during game PAUSE.
+//
+void S_PauseAudio(void)
+{
+	if (I_MusicPlaying() && !I_MusicPaused())
+		I_PauseSong();
+
+	// pause cd music
+#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
+	I_PauseCD();
+#else
+	I_StopCD();
+#endif
+}
+
+void S_ResumeAudio(void)
+{
+	if (I_MusicPlaying() && I_MusicPaused())
+		I_ResumeSong();
+
+	// resume cd music
+	I_ResumeCD();
+}
+
 void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
 {
 	if (digvolume < 0)
@@ -1477,7 +1559,7 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
 	CV_SetValue(&cv_digmusicvolume, digvolume&31);
 	actualdigmusicvolume = cv_digmusicvolume.value;   //check for change of var
 
-	if (digvolume < 0 || digvolume > 31)
+	if (seqvolume < 0 || seqvolume > 31)
 		CONS_Alert(CONS_WARNING, "midimusicvolume should be between 0-31\n");
 	CV_SetValue(&cv_midimusicvolume, seqvolume&31);
 	actualmidimusicvolume = cv_midimusicvolume.value;   //check for change of var
@@ -1497,52 +1579,11 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
 	}
 }
 
+
 /// ------------------------
 /// Init & Others
 /// ------------------------
 
-//
-// Initializes sound stuff, including volume
-// Sets channels, SFX and music volume,
-//  allocates channel buffer, sets S_sfx lookup.
-//
-void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume)
-{
-	INT32 i;
-
-	if (dedicated)
-		return;
-
-	S_SetSfxVolume(sfxVolume);
-	S_SetMusicVolume(digMusicVolume, midiMusicVolume);
-
-	SetChannelsNum();
-
-	// no sounds are playing, and they are not mus_paused
-	mus_paused = 0;
-
-	// Note that sounds have not been cached (yet).
-	for (i = 1; i < NUMSFX; i++)
-	{
-		S_sfx[i].usefulness = -1; // for I_GetSfx()
-		S_sfx[i].lumpnum = LUMPERROR;
-	}
-
-	// precache sounds if requested by cmdline, or precachesound var true
-	if (!nosound && (M_CheckParm("-precachesound") || precachesound.value))
-	{
-		// Initialize external data (all sounds) at start, keep static.
-		CONS_Printf(M_GetText("Loading sounds... "));
-
-		for (i = 1; i < NUMSFX; i++)
-			if (S_sfx[i].name)
-				S_sfx[i].data = I_GetSfx(&S_sfx[i]);
-
-		CONS_Printf(M_GetText(" pre-cached all sound data\n"));
-	}
-}
-
-
 //
 // Per level startup code.
 // Kills playing sounds at start of level,
@@ -1557,46 +1598,7 @@ void S_Start(void)
 		mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
 	}
 
-	mus_paused = 0;
-
 	if (cv_resetmusic.value)
 		S_StopMusic();
 	S_ChangeMusic(mapmusname, mapmusflags, true);
 }
-
-//
-// Stop and resume music, during game PAUSE.
-//
-void S_PauseAudio(void)
-{
-	if (!nodigimusic)
-		I_PauseSong();
-
-	if (music_playing && !mus_paused)
-	{
-		I_PauseSong();
-		mus_paused = true;
-	}
-
-	// pause cd music
-#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
-	I_PauseCD();
-#else
-	I_StopCD();
-#endif
-}
-
-void S_ResumeAudio(void)
-{
-	if (!nodigimusic)
-		I_ResumeSong();
-	else
-	if (music_playing && mus_paused)
-	{
-		I_ResumeSong();
-		mus_paused = false;
-	}
-
-	// resume cd music
-	I_ResumeCD();
-}
diff --git a/src/s_sound.h b/src/s_sound.h
index 891254b4c01488e7fb4742071a6f7b4e007d82b3..730dfd8d63127d621ed3b291fb10888ee4c1c018 100644
--- a/src/s_sound.h
+++ b/src/s_sound.h
@@ -97,9 +97,9 @@ void S_RegisterSoundStuff(void);
 
 //
 // Initializes sound stuff, including volume
-// Sets channels, SFX and music volume, allocates channel buffer, sets S_sfx lookup.
+// Sets channels, SFX, allocates channel buffer, sets S_sfx lookup.
 //
-void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume);
+void S_InitSfxChannels(INT32 sfxVolume);
 
 //
 // Per level startup code.
@@ -129,9 +129,16 @@ void S_StopSound(void *origin);
 // Music Status
 //
 
-boolean S_DigMusicDisabled();
-boolean S_MIDIMusicDisabled();
-boolean S_MusicDisabled();
+boolean S_DigMusicDisabled(void);
+boolean S_MIDIMusicDisabled(void);
+boolean S_MusicDisabled(void);
+boolean S_MusicPlaying(void);
+boolean S_MusicPaused(void);
+const char *S_MusicName(void);
+boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
+#define S_DigExists(a) S_MusicExists(a, false, true)
+#define S_MIDIExists(a) S_MusicExists(a, true, false)
+
 
 //
 // Music Properties
diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c
index 2ebc5750d8c076518542c3294d54c8d919a6411e..8f40cd1758d709a1c63fc6cea10bba0948b65f44 100644
--- a/src/sdl/mixer_sound.c
+++ b/src/sdl/mixer_sound.c
@@ -453,6 +453,16 @@ musictype_t I_GetMusicType(void)
 		return (musictype_t)Mix_GetMusicType(music);
 }
 
+boolean I_MusicPlaying(void)
+{
+	return (boolean)music;
+}
+
+boolean I_MusicPaused(void)
+{
+	return songpaused;
+}
+
 // Music hooks
 static void music_loop(void)
 {