diff --git a/src/m_menu.c b/src/m_menu.c
index 9fbcd55d7ab135cb7b630a44f7f4c521addae5ba..e2451de6ae36961f5426042fc8244b26f1f4cd5e 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -7023,36 +7023,42 @@ static tic_t st_time = 0;
 static patch_t* st_radio[9];
 static patch_t* st_launchpad[4];
 
-static void M_SoundTest(INT32 choice)
+static void M_CacheSoundTest(void)
 {
-	INT32 ul = skyRoomMenuTranslations[choice-1];
 	UINT8 i;
 	char buf[8];
 
-	soundtestpage = (UINT8)(unlockables[ul].variable);
-	if (!soundtestpage)
-		soundtestpage = 1;
-
-	if (!S_PrepareSoundTest())
-	{
-		M_StartMessage(M_GetText("No selectable tracks found.\n"),NULL,MM_NOTHING);
-		return;
-	}
-
 	STRBUFCPY(buf, "M_RADIOn");
 	for (i = 0; i < 9; i++)
 	{
 		buf[7] = (char)('0'+i);
-		st_radio[i] = W_CachePatchName(buf, PU_STATIC);
+		st_radio[i] = W_CachePatchName(buf, PU_PATCH);
 	}
 
 	STRBUFCPY(buf, "M_LPADn");
 	for (i = 0; i < 4; i++)
 	{
 		buf[6] = (char)('0'+i);
-		st_launchpad[i] = W_CachePatchName(buf, PU_STATIC);
+		st_launchpad[i] = W_CachePatchName(buf, PU_PATCH);
+	}
+}
+
+static void M_SoundTest(INT32 choice)
+{
+	INT32 ul = skyRoomMenuTranslations[choice-1];
+
+	soundtestpage = (UINT8)(unlockables[ul].variable);
+	if (!soundtestpage)
+		soundtestpage = 1;
+
+	if (!S_PrepareSoundTest())
+	{
+		M_StartMessage(M_GetText("No selectable tracks found.\n"),NULL,MM_NOTHING);
+		return;
 	}
 
+	M_CacheSoundTest();
+
 	curplaying = NULL;
 	st_time = 0;
 
@@ -7070,6 +7076,9 @@ static void M_DrawSoundTest(void)
 	fixed_t hscale = FRACUNIT/2, vscale = FRACUNIT/2, bounce = 0;
 	UINT8 frame[4] = {0, 0, -1, SKINCOLOR_RUBY};
 
+	if (needpatchrecache)
+		M_CacheSoundTest();
+
 	// let's handle the ticker first. ideally we'd tick this somewhere else, BUT...
 	if (curplaying)
 	{