diff --git a/src/d_main.c b/src/d_main.c
index df33987525d1520278c094f717309625c58327f2..f2da8586cea824d593f16520613510628861a9f3 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -1217,7 +1217,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;
@@ -1232,7 +1232,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 1d4d6ff7233030b8b44e487e112a18536a6e4053..901e6c28474943c0a85183b78de1af7b168427d9 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 79ac6800b7cf18a7fb7df362f37dc5329f150e4a..82242c0c16d9933bb4fbf3117631dfa21fd8c2f1 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -6955,7 +6955,7 @@ static void M_ToggleSFX(void)
 		nosound = false;
 		I_StartupSound();
 		if (nosound) return;
-		S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
+		S_InitSfxChannels(cv_soundvolume.value);
 		M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING);
 	}
 	else
@@ -6981,7 +6981,7 @@ static void M_ToggleDigital(void)
 		nodigimusic = false;
 		I_InitDigMusic();
 		if (nodigimusic) return;
-		S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
+		S_InitSfxChannels(cv_soundvolume.value);
 		S_StopMusic();
 		S_ChangeMusicInternal("lclear", false);
 		M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING);
@@ -7009,7 +7009,7 @@ static void M_ToggleMIDI(void)
 		nomidimusic = false;
 		I_InitMIDIMusic();
 		if (nomidimusic) return;
-		S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
+		S_InitSfxChannels(cv_soundvolume.value);
 		S_ChangeMusicInternal("lclear", false);
 		M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING);
 	}
diff --git a/src/s_sound.c b/src/s_sound.c
index a1c53acd2de2f8e4f2c0972dd3fadc6a4d7a9738..e035c4192fdcb4e1df248cb47b3e669483f1f927 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -1151,6 +1151,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
 /// ------------------------
@@ -1177,10 +1214,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
@@ -1206,6 +1240,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
 /// ------------------------
@@ -1229,15 +1286,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;
@@ -1326,10 +1383,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);
@@ -1343,6 +1400,31 @@ void S_StopMusic(void)
 	music_name[0] = 0;
 }
 
+//
+// 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)
@@ -1355,7 +1437,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
@@ -1375,52 +1457,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,
@@ -1435,46 +1476,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 bce3ab8bbaa982b376e89c93394a9d5eef98fd61..9a3f2805ca48ce0b2316a02f3e80cf0c6f772ed8 100644
--- a/src/s_sound.h
+++ b/src/s_sound.h
@@ -69,9 +69,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.
@@ -101,9 +101,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 457f74f95128cd3d84b262d0fb145d02ed7749ae..1384f1da03b526750a99c8e121975958ac31fa47 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)
 {