diff --git a/src/i_sound.h b/src/i_sound.h
index 450072cba2240dffeb73d2696d8766dc69b74ffc..99e343491bc9ebee83a20bc14b85c516574429b6 100644
--- a/src/i_sound.h
+++ b/src/i_sound.h
@@ -136,14 +136,6 @@ void I_ResumeSong(INT32 handle);
 //  MIDI I/O
 //
 
-/**	\brief Startup the MIDI music system
-*/
-void I_InitMIDIMusic(void);
-
-/**	\brief Shutdown the MIDI music system
-*/
-void I_ShutdownMIDIMusic(void);
-
 /**	\brief	Registers a song handle to song data.
 
 	\param	data	pointer to song data
@@ -153,7 +145,7 @@ void I_ShutdownMIDIMusic(void);
 
 	\todo Remove this
 */
-INT32 I_RegisterSong(void *data, size_t len);
+boolean I_LoadSong(void *data, size_t len);
 
 /**	\brief	Called by anything that wishes to start music
 
@@ -164,7 +156,7 @@ INT32 I_RegisterSong(void *data, size_t len);
 
 	\todo pass music name, not handle
 */
-boolean I_PlaySong(INT32 handle, boolean looping);
+boolean I_PlaySong(void);
 
 /**	\brief	Stops a song over 3 seconds
 
@@ -173,46 +165,25 @@ boolean I_PlaySong(INT32 handle, boolean looping);
 
 	/todo drop handle
 */
-void I_StopSong(INT32 handle);
+void I_StopSong(void);
 
-/**	\brief	See ::I_RegisterSong, then think backwards
+/**	\brief	See ::I_LoadSong, then think backwards
 
 	\param	handle	song handle
 
-	\sa I_RegisterSong
+	\sa I_LoadSong
 	\todo remove midi handle
 */
-void I_UnRegisterSong(INT32 handle);
+void I_UnloadSong(void);
 
 //
 //  DIGMUSIC I/O
 //
 
-/**	\brief Startup the music system
-*/
-void I_InitDigMusic(void);
-
-/**	\brief Shutdown the music system
-*/
-void I_ShutdownDigMusic(void);
-
 boolean I_SetSongSpeed(float speed);
 
 boolean I_SetSongTrack(INT32 track);
 
-/**	\brief The I_StartDigSong function
-
-	\param	musicname	music lump name
-	\param	looping	if true, loop the song
-
-	\return	if true, song playing
-*/
-boolean I_StartDigSong(const char *musicname, boolean looping);
-
-/**	\brief stop non-MIDI song
-*/
-void I_StopDigSong(void);
-
 /**	\brief The I_SetDigMusicVolume function
 
 	\param	volume	volume to set at
diff --git a/src/locale/en.po b/src/locale/en.po
index 069930b8144c7576fe6e371b3f6af5b28e9540ff..cc1426e0815d003883b1d8ba649c3f3e30f9ee82 100644
--- a/src/locale/en.po
+++ b/src/locale/en.po
@@ -3825,7 +3825,7 @@ msgid "Music lump is not MID music format\n"
 msgstr ""
 
 #: win32/win_snd.c:2128
-msgid "I_RegisterSong: StreamBufferSetup FAILED"
+msgid "I_LoadSong: StreamBufferSetup FAILED"
 msgstr ""
 
 #: win32/win_sys.c:892
diff --git a/src/locale/srb2.pot b/src/locale/srb2.pot
index ced13bbe655569d00a616ec396c11a0b6abeba89..4203cfe752895b8c014c20d0055c66b637953196 100644
--- a/src/locale/srb2.pot
+++ b/src/locale/srb2.pot
@@ -4021,7 +4021,7 @@ msgid "Music lump is not MID music format\n"
 msgstr ""
 
 #: win32/win_snd.c:2126
-msgid "I_RegisterSong: StreamBufferSetup FAILED"
+msgid "I_LoadSong: StreamBufferSetup FAILED"
 msgstr ""
 
 #: win32/win_sys.c:894
diff --git a/src/m_menu.c b/src/m_menu.c
index 1f4c3ebc3f4917dc21bfd73ee28d0523c855e1f7..9764cd728f0a79d5f9730345416ba488edb7a721 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -9469,7 +9469,7 @@ static void M_ToggleDigital(INT32 choice)
 	if (nodigimusic)
 	{
 		nodigimusic = false;
-		I_InitDigMusic();
+		I_InitMusic();
 		if (nodigimusic) return;
 		S_Init(cv_soundvolume.value, cv_digmusicvolume.value);
 		S_StopMusic();
@@ -9526,7 +9526,7 @@ static void M_ToggleMIDI(INT32 choice)
 	if (nomidimusic)
 	{
 		nomidimusic = false;
-		I_InitMIDIMusic();
+		I_InitMusic();
 		if (nomidimusic) return;
 		S_Init(cv_soundvolume.value, cv_digmusicvolume.value);
 		if (Playing())
diff --git a/src/s_sound.c b/src/s_sound.c
index 6a55523b8038b795f268eff105dde3c56b0411a4..531eb76424046476b22861e0e04195a69a0881f6 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -807,7 +807,7 @@ void S_UpdateSounds(void)
 	if (actualsfxvolume != cv_soundvolume.value)
 		S_SetSfxVolume (cv_soundvolume.value);
 	if (actualdigmusicvolume != cv_digmusicvolume.value)
-		S_SetDigMusicVolume (cv_digmusicvolume.value);
+		S_SetMusicVolume (cv_digmusicvolume.value);
 
 	// We're done now, if we're not in a level.
 	if (gamestate != GS_LEVEL)
@@ -1308,13 +1308,11 @@ const char *compat_special_music_slots[16] =
 #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 lumpnum_t music_lumpnum; // lump number of music (used??)
-static void     *music_data;    // music raw data
-static INT32     music_handle;  // once registered, the handle for the music
 
-static boolean mus_paused     = 0;  // whether songs are mus_paused
+static boolean   mus_forcemidi  = 0;  // force midi even when digital exists
+static boolean   mus_paused     = 0;  // whether songs are mus_paused
 
-static boolean S_MIDIMusic(const char *mname, boolean looping)
+static boolean S_LoadMusic(const char *mname, boolean looping)
 {
 	lumpnum_t mlumpnum;
 	void *mdata;
@@ -1323,51 +1321,57 @@ static boolean S_MIDIMusic(const char *mname, boolean looping)
 	if (nomidimusic || music_disabled)
 		return false; // didn't search.
 
-	if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR)
-		return false;
-	mlumpnum = W_GetNumForName(va("d_%s", mname));
+	if (mus_forcemidi)
+	{
+		if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR)
+			return false;
+		mlumpnum = W_GetNumForName(va("d_%s", mname));
+	}
+	else
+	{
+		if (W_CheckNumForName(va("o_%s", mname)) != LUMPERROR)
+			mlumpnum = W_GetNumForName(va("o_%s", mname));
+		else if (W_CheckNumForName(va("d_%s", mname)) != LUMPERROR)
+			mlumpnum = W_GetNumForName(va("d_%s", mname));
+		else
+			return false;
+	}
 
 	// load & register it
 	mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC);
-	mhandle = I_RegisterSong(mdata, W_LumpLength(mlumpnum));
 
-#ifdef MUSSERV
-	if (msg_id != -1)
+	if (I_LoadSong(mdata, W_LumpLength(mlumpnum)))
 	{
-		struct musmsg msg_buffer;
-
-		msg_buffer.msg_type = 6;
-		memset(msg_buffer.msg_text, 0, sizeof (msg_buffer.msg_text));
-		sprintf(msg_buffer.msg_text, "d_%s", mname);
-		msgsnd(msg_id, (struct msgbuf*)&msg_buffer, sizeof (msg_buffer.msg_text), IPC_NOWAIT);
+		strncpy(music_name, mname, 7);
+		music_name[6] = 0;
+		return true;
 	}
-#endif
-
-	// play it
-	if (!I_PlaySong(mhandle, looping))
+	else
 		return false;
+}
 
-	strncpy(music_name, mname, 7);
-	music_name[6] = 0;
-	music_lumpnum = mlumpnum;
-	music_data = mdata;
-	music_handle = mhandle;
-	return true;
+static void S_UnloadSong(void)
+{
+	I_UnloadSong();
+	music_name[0] = 0;
 }
 
-static boolean S_DigMusic(const char *mname, boolean looping)
+static boolean S_PlayMusic(const char *mname, boolean looping)
 {
 	if (nodigimusic || digital_disabled)
 		return false; // try midi
 
-	if (!I_StartDigSong(mname, looping))
+	if (!S_LoadSong(mname, looping))
+		return false;
+
+	if (!I_PlaySong())
+	{
+		S_UnloadSong();
 		return false;
+	}
 
 	strncpy(music_name, mname, 7);
 	music_name[6] = 0;
-	music_lumpnum = LUMPERROR;
-	music_data = NULL;
-	music_handle = 0;
 	return true;
 }
 
@@ -1386,7 +1390,7 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
 	if (strncmp(music_name, mmusic, 6))
 	{
 		S_StopMusic(); // shutdown old music
-		if (!S_DigMusic(mmusic, looping) && !S_MIDIMusic(mmusic, looping))
+		if (!S_LoadMusic(mmusic, looping) && !S_PlayMusic(mmusic, looping))
 		{
 			CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mmusic);
 			return;
@@ -1408,12 +1412,9 @@ void S_StopMusic(void)
 	if (mus_paused)
 		I_ResumeSong(music_handle);
 
-	if (!nodigimusic)
-		I_StopDigSong();
-
 	S_SpeedMusic(1.0f);
-	I_StopSong(music_handle);
-	I_UnRegisterSong(music_handle);
+	I_StopSong();
+	I_UnloadSong();
 
 #ifndef HAVE_SDL //SDL uses RWOPS
 	Z_ChangeTag(music_data, PU_CACHE);
@@ -1429,7 +1430,7 @@ void S_StopMusic(void)
 	}
 }
 
-void S_SetDigMusicVolume(INT32 volume)
+void S_SetMusicVolume(INT32 volume)
 {
 	if (volume < 0 || volume > 31)
 		CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
@@ -1460,7 +1461,7 @@ void S_Init(INT32 sfxVolume, INT32 digMusicVolume)
 		return;
 
 	S_SetSfxVolume(sfxVolume);
-	S_SetDigMusicVolume(digMusicVolume);
+	S_SetMusicVolume(digMusicVolume);
 
 	SetChannelsNum();
 
diff --git a/src/s_sound.h b/src/s_sound.h
index 3c3ff1b2478acea430b6aedb2a4df0ff7db6a41e..053f586698559bb715095c9e6c49092cb9e0fa69 100644
--- a/src/s_sound.h
+++ b/src/s_sound.h
@@ -149,7 +149,7 @@ void S_UpdateSounds(void);
 
 FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
 
-void S_SetDigMusicVolume(INT32 volume);
+void S_SetMusicVolume(INT32 volume);
 void S_SetSfxVolume(INT32 volume);
 
 INT32 S_OriginPlaying(void *origin);
diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c
index a4758c8542758f0cdeec5849e7aa839938fab396..7e9bd4bde186284934846fd661c8d6f929b2b62f 100644
--- a/src/sdl/mixer_sound.c
+++ b/src/sdl/mixer_sound.c
@@ -466,12 +466,29 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
 
 FUNCMATH void I_InitMusic(void)
 {
+#ifdef HAVE_LIBGME
+	gme = NULL;
+	current_track = -1;
+#endif
 }
 
 void I_ShutdownMusic(void)
 {
-	I_ShutdownDigMusic();
-	I_ShutdownMIDIMusic();
+	if (midimode)
+		return;
+#ifdef HAVE_LIBGME
+	if (gme)
+	{
+		Mix_HookMusic(NULL, NULL);
+		gme_delete(gme);
+		gme = NULL;
+	}
+#endif
+	if (!music)
+		return;
+	Mix_HookMusicFinished(NULL);
+	Mix_FreeMusic(music);
+	music = NULL;
 }
 
 void I_PauseSong(INT32 handle)
@@ -492,51 +509,74 @@ void I_ResumeSong(INT32 handle)
 // Digital Music
 //
 
-void I_InitDigMusic(void)
+void I_SetDigMusicVolume(UINT8 volume)
+{
+	music_volume = volume;
+	if (midimode || !music)
+		return;
+	Mix_VolumeMusic((UINT32)volume*128/31);
+}
+
+boolean I_SetSongSpeed(float speed)
 {
+	if (speed > 250.0f)
+		speed = 250.0f; //limit speed up to 250x
 #ifdef HAVE_LIBGME
-	gme = NULL;
-	current_track = -1;
+	if (gme)
+	{
+		SDL_LockAudio();
+		gme_set_tempo(gme, speed);
+		SDL_UnlockAudio();
+		return true;
+	}
+#else
+	(void)speed;
 #endif
+	return false;
 }
 
-void I_ShutdownDigMusic(void)
+boolean I_SetSongTrack(int track)
 {
-	if (midimode)
-		return;
 #ifdef HAVE_LIBGME
+	if (current_track == track)
+		return false;
+
+	// If the specified track is within the number of tracks playing, then change it
 	if (gme)
 	{
-		Mix_HookMusic(NULL, NULL);
-		gme_delete(gme);
-		gme = NULL;
+		SDL_LockAudio();
+		if (track >= 0
+			&& track < gme_track_count(gme))
+		{
+			gme_err_t gme_e = gme_start_track(gme, track);
+			if (gme_e != NULL)
+			{
+				CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
+				return false;
+			}
+			current_track = track;
+			SDL_UnlockAudio();
+			return true;
+		}
+		SDL_UnlockAudio();
+		return false;
 	}
 #endif
-	if (!music)
-		return;
-	Mix_HookMusicFinished(NULL);
-	Mix_FreeMusic(music);
-	music = NULL;
+	(void)track;
+	return false;
 }
 
-boolean I_StartDigSong(const char *musicname, boolean looping)
-{
-	char *data;
-	size_t len;
-	lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname));
+//
+// MIDI Music
+//
 
+boolean I_LoadSong(void *data, size_t len)
+{
 	I_Assert(!music);
 #ifdef HAVE_LIBGME
 	I_Assert(!gme);
 #endif
 
-	if (lumpnum == LUMPERROR)
-		return false;
-	midimode = false;
-
-	data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC);
-	len = W_LumpLength(lumpnum);
-
 #ifdef HAVE_LIBGME
 	if ((UINT8)data[0] == 0x1F
 		&& (UINT8)data[1] == 0x8B)
@@ -627,10 +667,6 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 	else if (!gme_open_data(data, len, &gme, 44100))
 	{
 		gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
-		gme_start_track(gme, 0);
-		current_track = 0;
-		gme_set_equalizer(gme, &eq);
-		Mix_HookMusic(mix_gme, gme);
 		return true;
 	}
 #endif
@@ -639,7 +675,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 	if (!music)
 	{
 		CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
-		return true;
+		return false;
 	}
 
 	// Find the OGG loop point.
@@ -677,10 +713,28 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 		}
 	}
 
+	return true;
+}
+
+boolean I_PlaySong(void)
+{
+	if (!music)
+		return false;
+#ifdef HAVE_GME
+	if (gme)
+	{
+		gme_start_track(gme, 0);
+		current_track = 0;
+		gme_set_equalizer(gme, &eq);
+		Mix_HookMusic(mix_gme, gme);
+		return true;
+	}
+#endif
+
 	if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1)
 	{
 		CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
-		return true;
+		return false;
 	}
 	Mix_VolumeMusic((UINT32)music_volume*128/31);
 
@@ -689,7 +743,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 	return true;
 }
 
-void I_StopDigSong(void)
+void I_StopSong(void)
 {
 	if (midimode)
 		return;
@@ -710,116 +764,7 @@ void I_StopDigSong(void)
 	music = NULL;
 }
 
-void I_SetDigMusicVolume(UINT8 volume)
-{
-	music_volume = volume;
-	if (midimode || !music)
-		return;
-	Mix_VolumeMusic((UINT32)volume*128/31);
-}
-
-boolean I_SetSongSpeed(float speed)
-{
-	if (speed > 250.0f)
-		speed = 250.0f; //limit speed up to 250x
-#ifdef HAVE_LIBGME
-	if (gme)
-	{
-		SDL_LockAudio();
-		gme_set_tempo(gme, speed);
-		SDL_UnlockAudio();
-		return true;
-	}
-#else
-	(void)speed;
-#endif
-	return false;
-}
-
-boolean I_SetSongTrack(int track)
-{
-#ifdef HAVE_LIBGME
-	if (current_track == track)
-		return false;
-
-	// If the specified track is within the number of tracks playing, then change it
-	if (gme)
-	{
-		SDL_LockAudio();
-		if (track >= 0
-			&& track < gme_track_count(gme))
-		{
-			gme_err_t gme_e = gme_start_track(gme, track);
-			if (gme_e != NULL)
-			{
-				CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
-				return false;
-			}
-			current_track = track;
-			SDL_UnlockAudio();
-			return true;
-		}
-		SDL_UnlockAudio();
-		return false;
-	}
-#endif
-	(void)track;
-	return false;
-}
-
-//
-// MIDI Music
-//
-
-FUNCMATH void I_InitMIDIMusic(void)
-{
-}
-
-void I_ShutdownMIDIMusic(void)
-{
-	if (!midimode || !music)
-		return;
-	Mix_FreeMusic(music);
-	music = NULL;
-}
-
-INT32 I_RegisterSong(void *data, size_t len)
-{
-	music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE);
-	if (!music)
-	{
-		CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
-		return -1;
-	}
-	return 1337;
-}
-
-boolean I_PlaySong(INT32 handle, boolean looping)
-{
-	(void)handle;
-
-	midimode = true;
-
-	if (Mix_PlayMusic(music, looping ? -1 : 0) == -1)
-	{
-		CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
-		return false;
-	}
-
-	Mix_VolumeMusic((UINT32)midi_volume*128/31);
-	return true;
-}
-
-void I_StopSong(INT32 handle)
-{
-	if (!midimode || !music)
-		return;
-
-	(void)handle;
-	Mix_HaltMusic();
-}
-
-void I_UnRegisterSong(INT32 handle)
+void I_UnloadSong(void)
 {
 	if (!midimode || !music)
 		return;