diff --git a/src/i_sound.h b/src/i_sound.h
index e38a17626b95dac976295a27c53e5583ce4043fb..09047442e548c971bb4bc496f743800ae432f42d 100644
--- a/src/i_sound.h
+++ b/src/i_sound.h
@@ -75,10 +75,11 @@ void I_ShutdownSound(void);
 	\param	sep	left-right balancle
 	\param	pitch	not used
 	\param	priority	not used
+	\parm   loops number of loops to play
 
 	\return	sfx handle
 */
-INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel);
+INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel, INT16 loops);
 
 /**	\brief	Stops a sound channel.
 
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 350c1585fab2478bf4dfa438306215a510b330b2..65bb6c0982266647383712cec94ec759ced4d7d8 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -2818,6 +2818,7 @@ static int lib_sStartSound(lua_State *L)
 	void *origin = NULL;
 	sfxenum_t sound_id = luaL_checkinteger(L, 2);
 	player_t *player = NULL;
+	INT16 loops;
 	//NOHUD
 
 	if (sound_id >= NUMSFX)
@@ -2829,6 +2830,9 @@ static int lib_sStartSound(lua_State *L)
 		if (!player)
 			return LUA_ErrInvalid(L, "player_t");
 	}
+
+	loops = (INT16)luaL_optinteger(L, 4, 0);
+
 	if (!lua_isnil(L, 1))
 		if (!GetValidSoundOrigin(L, &origin))
 			return 0;
@@ -2837,7 +2841,7 @@ static int lib_sStartSound(lua_State *L)
 		if (hud_running || hook_cmd_running)
 			origin = NULL;	// HUD rendering and CMD building startsound shouldn't have an origin, just remove it instead of having a retarded error.
 
-		S_StartSound(origin, sound_id);
+		S_StartSoundEx(origin, sound_id, loops);
 	}
 	return 0;
 }
@@ -2848,6 +2852,7 @@ static int lib_sStartSoundAtVolume(lua_State *L)
 	sfxenum_t sound_id = luaL_checkinteger(L, 2);
 	INT32 volume = (INT32)luaL_checkinteger(L, 3);
 	player_t *player = NULL;
+	INT16 loops;
 	//NOHUD
 
 	if (sound_id >= NUMSFX)
@@ -2862,8 +2867,10 @@ static int lib_sStartSoundAtVolume(lua_State *L)
 		if (!GetValidSoundOrigin(L, &origin))
 			return LUA_ErrInvalid(L, "mobj_t/sector_t");
 
+	loops = (INT16)luaL_optinteger(L, 5, 0);
+
 	if (!player || P_IsLocalPlayer(player))
-		S_StartSoundAtVolume(origin, sound_id, volume);
+		S_StartSoundAtVolumeEx(origin, sound_id, volume, loops);
 	return 0;
 }
 
diff --git a/src/s_sound.c b/src/s_sound.c
index 30f24236923a45200f40ccddd5eff680f4e98c99..18419dd1e1be8612185411d2b29727aeb6cd4cca 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -516,7 +516,7 @@ void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan)
 	closedcaptions[set].b = 2; // bob
 }
 
-void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
+void S_StartSoundAtVolumeEx(const void *origin_p, sfxenum_t sfx_id, INT32 volume, INT16 loops)
 {
 	const INT32 initial_volume = volume;
 	INT32 sep, pitch, priority, cnum;
@@ -663,7 +663,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
 
 		// Assigns the handle to one of the channels in the
 		// mix/output buffer.
-		channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
+		channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum, loops);
 	}
 
 dontplay:
@@ -717,10 +717,10 @@ dontplay:
 	// Assigns the handle to one of the channels in the
 	// mix/output buffer.
 	channels[cnum].volume = initial_volume;
-	channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
+	channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum, loops);
 }
 
-void S_StartSound(const void *origin, sfxenum_t sfx_id)
+void S_StartSoundEx(const void *origin, sfxenum_t sfx_id, INT16 loops)
 {
 	if (S_SoundDisabled())
 		return;
@@ -792,7 +792,7 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id)
 		HW3S_StartSound(origin, sfx_id);
 	else
 #endif
-		S_StartSoundAtVolume(origin, sfx_id, 255);
+		S_StartSoundAtVolumeEx(origin, sfx_id, 255, loops);
 }
 
 void S_StopSound(void *origin)
diff --git a/src/s_sound.h b/src/s_sound.h
index 8fcb816d906accd7f63b6756d8915327a97c4bc0..5fe6d1a530edd65186a7ef93077821be175f1353 100644
--- a/src/s_sound.h
+++ b/src/s_sound.h
@@ -140,12 +140,15 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx);
 boolean S_SoundDisabled(void);
 
 //
-// Start sound for thing at <origin> using <sound_id> from sounds.h
+// Start sound for thing at <origin> using <sound_id> from sounds.h, looped <loops> times
 //
-void S_StartSound(const void *origin, sfxenum_t sound_id);
+void S_StartSoundEx(const void *origin, sfxenum_t sound_id, INT16 loops);
 
 // Will start a sound at a given volume.
-void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume);
+void S_StartSoundAtVolumeEx(const void *origin, sfxenum_t sound_id, INT32 volume, INT16 loops);
+
+#define S_StartSoundAtVolume(a, b, c) S_StartSoundAtVolumeEx(a, b, c, 0)
+#define S_StartSound(a, b) S_StartSoundEx(a, b, 0)
 
 // Stop sound for thing at <origin>
 void S_StopSound(void *origin);
@@ -162,7 +165,7 @@ boolean S_MusicPaused(void);
 boolean S_MusicNotInFocus(void);
 musictype_t S_MusicType(void);
 const char *S_MusicName(void);
-boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
+boolean S_MusicExists(const char *mnaame, boolean checkMIDI, boolean checkDigi);
 #define S_DigExists(a) S_MusicExists(a, false, true)
 #define S_MIDIExists(a) S_MusicExists(a, true, false)
 
@@ -319,7 +322,7 @@ INT32 S_OriginPlaying(void *origin);
 INT32 S_IdPlaying(sfxenum_t id);
 INT32 S_SoundPlaying(void *origin, sfxenum_t id);
 
-void S_StartSoundName(void *mo, const  char *soundname);
+void S_StartSoundName(void *mo, const char *soundname);
 
 void S_StopSoundByID(void *origin, sfxenum_t sfx_id);
 void S_StopSoundByNum(sfxenum_t sfxnum);
diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c
index 35a79acc0b16ece0a457018db2df9d7a94b2781b..98d60adf96b1e31302842ce25118bdc44b3dbd7b 100644
--- a/src/sdl/mixer_sound.c
+++ b/src/sdl/mixer_sound.c
@@ -589,10 +589,10 @@ void I_FreeSfx(sfxinfo_t *sfx)
 	sfx->lumpnum = LUMPERROR;
 }
 
-INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
+INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel, INT16 loops)
 {
 	UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
-	INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0);
+	INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, loops);
 	Mix_Volume(handle, volume);
 	Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
 	(void)pitch; // Mixer can't handle pitch