Index: code/hud/hud.cpp
===================================================================
--- code/hud/hud.cpp	(revision 7840)
+++ code/hud/hud.cpp	 (working copy)
@@ -1811,14 +1811,13 @@ void update_throttle_sound()
 
 			if ( percent_throttle < ZERO_PERCENT ) {
 				if ( Player_engine_snd_loop > -1 )	{
-					snd_chg_loop_status(Player_engine_snd_loop, 0);
 					snd_stop(Player_engine_snd_loop); // Backslash - otherwise, long engine loops keep playing
 					Player_engine_snd_loop = -1;
 				}
 			}
 			else {
 				if ( Player_engine_snd_loop == -1 ){
-					Player_engine_snd_loop = snd_play_looping( &Snds[SND_ENGINE], 0.0f , -1, -1, percent_throttle * ENGINE_MAX_VOL );
+					Player_engine_snd_loop = snd_play_looping( &Snds[SND_ENGINE], 0.0f , -1, -1, percent_throttle * ENGINE_MAX_VOL, FALSE);
 				} else {
 					// The sound may have been trashed at the low-level if sound channel overflow.
 					// TODO: implement system where certain sounds cannot be interrupted (priority?)
Index: code/hud/hudlock.cpp
===================================================================
--- code/hud/hudlock.cpp	(revision 7840)
+++ code/hud/hudlock.cpp	 (working copy)
@@ -625,7 +625,7 @@ void hud_do_lock_indicator(float frametime)
 
 	if (Player_ai->current_target_is_locked) {
 		if ( Missile_track_loop > -1 )	{
-			snd_chg_loop_status(Missile_track_loop, 0);
+			snd_stop(Missile_track_loop);
 			Missile_track_loop = -1;
 			Missile_lock_loop = snd_play(&Snds[SND_MISSILE_LOCK]);
 		}
@@ -863,7 +863,7 @@ void hud_calculate_lock_position(float frametime)
 	} else {
 
 		if ( Missile_track_loop > -1 )	{
-			snd_chg_loop_status(Missile_track_loop, 0);
+			snd_stop(Missile_track_loop);
 			Missile_track_loop = -1;
 		}
 
Index: code/sound/sound.cpp
===================================================================
--- code/sound/sound.cpp	(revision 7840)
+++ code/sound/sound.cpp	 (working copy)
@@ -56,6 +56,8 @@ float Master_voice_volume = 0.7f;	// range is 0 -> 1, used for all voice playbac
 
 unsigned int SND_ENV_DEFAULT = 0;
 
+SCP_list<int> currentlyLoopingSoundHandles;
+
 //For the adjust-audio-volume sexp
 float aav_voice_volume = 1.0f;
 float aav_music_volume = 1.0f;
@@ -757,28 +759,18 @@ int snd_get_3d_vol_and_pan(game_snd *gs, vec3d *pos, float* vol, float *pan, flo
 	return 0;
 }
 
-// ---------------------------------------------------------------------------------------
-// volume 0 to 1.0.  Returns the handle of the sound. -1 if failed.
-// If startloop or stoploop are not -1, then then are used.
-//
-//	NOTE: vol_scale parameter is the multiplicative scaling applied to the default volume
-//       (vol_scale is a default parameter with a default value of 1.0f)
-//
-// input:	gs				=>	game-level sound description
-//				source_pos	=>	global pos of where the sound is
-//				listen_pos	=>	global pos of where listener is
-//				source_vel	=>	velocity of the source playing the sound (used for DirectSound3D only)
-//				looping		=>	flag to indicate the sound should loop (default value 0)
-//				vol_scale	=>	factor to scale the static volume by (applied before attenuation)
-//				priority		=> SND_PRIORITY_MUST_PLAY			(default value)
-//									SND_PRIORITY_SINGLE_INSTANCE
-//									SND_PRIORITY_DOUBLE_INSTANCE
-//									SND_PRIORITY_TRIPLE_INSTANCE
-//
-// returns:		-1		=>		sound could not be played
-//					n		=>		handle for instance of sound
-//
-int snd_play_looping( game_snd *gs, float pan, int start_loop, int stop_loop, float vol_scale, int priority, int force )
+/**
+ * Starts looping a game sound
+ *
+ * @param gs game-level sound description
+ * @param pan -1.0 (full left) to 1.0 (full right)
+ * @param start_loop TODO remove this parameter
+ * @param stop_loop TODO remove this parameter
+ * @param vol_scale factor to scale the static volume by (applied before attenuation)
+ * @param scriptingUpdateVolume if true the looping sound value is updated default is TRUE
+ * @return -1 on error, else the handle for this playing sound
+ */
+int snd_play_looping( game_snd *gs, float pan, int start_loop, int stop_loop, float vol_scale, int scriptingUpdateVolume)
 {	
 	float volume;
 	int	handle = -1;
@@ -815,20 +807,22 @@ int snd_play_looping( game_snd *gs, float pan, int start_loop, int stop_loop, fl
 	if ( volume > 1.0f )
 		volume = 1.0f;
 
-	if ( (volume > MIN_SOUND_VOLUME) || force) {
-		handle = ds_play( snd->sid, gs->id_sig, ds_priority(priority), volume, pan, 1);
+	if (volume > MIN_SOUND_VOLUME) {
+		handle = ds_play( snd->sid, gs->id_sig, DS_MUST_PLAY, volume, pan, 1);
+
+		if(handle != -1 && scriptingUpdateVolume) {
+			currentlyLoopingSoundHandles.push_back(handle);
+		}
 	}
 
 	return handle;
 }
 
-// ---------------------------------------------------------------------------------------
-// snd_stop()
-//
-// Stop a sound from playing.
-//
-// parameters:		sig => handle to sound, what is returned from snd_play()
-//
+/**
+ * Stop a sound from playing.
+ *
+ * @param sig handle to sound, what is returned from snd_play()
+ */
 void snd_stop( int sig )
 {
 	int channel;
@@ -840,9 +834,35 @@ void snd_stop( int sig )
 	if ( channel == -1 )
 		return;
 	
+	SCP_list<int>::iterator iter = currentlyLoopingSoundHandles.begin();
+	while (iter != currentlyLoopingSoundHandles.end())
+	{
+		int handle = *iter;
+		if(handle == sig) {
+			iter = currentlyLoopingSoundHandles.erase(iter);
+		} else {
+			++iter;
+		}
+	}
+
 	ds_stop_channel(channel);
 }
 
+/**
+ * Stop all playing sound channels (including looping sounds)
+ *
+ * NOTE: This stops all sounds that are playing from Channels[] sound buffers.
+ * It doesn't stop every secondary sound buffer in existance.
+ */
+void snd_stop_all()
+{
+	if (!ds_initialized)
+		return;
+
+	currentlyLoopingSoundHandles.clear();
+	ds_stop_channel_all();
+}
+
 // ---------------------------------------------------------------------------------------
 // snd_set_volume()
 //
@@ -985,50 +1005,6 @@ int snd_is_playing( int sig )
 	return 0;
 }
 
-
-// ---------------------------------------------------------------------------------------
-// snd_chg_loop_status()
-//
-// Change whether a currently playing song is looping or not
-//
-// parameters:		sig			=> handle to sound, what is returned from snd_play()
-//						loop			=> whether to start (1) or stop (0) looping
-//
-void snd_chg_loop_status(int sig, int loop)
-{
-	int channel;
-
-	if (!ds_initialized)
-		return;
-
-	if ( sig < 0 )
-		return;
-
-	channel = ds_get_channel(sig);
-	if ( channel == -1 ) {
-		nprintf(( "Sound", "WARNING: Trying to change loop status of a non-playing sound!\n" ));
-		return;
-	}
-
-	ds_chg_loop_status(channel, loop);
-}
-
-// ---------------------------------------------------------------------------------------
-// snd_stop_all()
-//
-// Stop all playing sound channels (including looping sounds)
-//
-// NOTE: This stops all sounds that are playing from Channels[] sound buffers.  It doesn't
-//			stop every secondary sound buffer in existance
-//
-void snd_stop_all()
-{
-	if (!ds_initialized)
-		return;
-
-	ds_stop_channel_all();
-}
-
 // ---------------------------------------------------------------------------------------
 // snd_is_inited()
 //
@@ -1368,6 +1344,13 @@ void snd_do_frame()
 	adjust_volume_on_frame(&aav_music_volume, &aav_data[AAV_MUSIC]);
 	adjust_volume_on_frame(&aav_voice_volume, &aav_data[AAV_VOICE]);
 	adjust_volume_on_frame(&aav_effect_volume, &aav_data[AAV_EFFECTS]);
+
+	SCP_list<int>::iterator iter;
+	for (iter = currentlyLoopingSoundHandles.begin(); iter != currentlyLoopingSoundHandles.end(); ++iter) {
+		int handle = *iter;
+		snd_set_volume(handle, 1.0f);
+	}
+
 	ds_do_frame();
 }
 
Index: code/sound/sound.h
===================================================================
--- code/sound/sound.h	(revision 7840)
+++ code/sound/sound.h	 (working copy)
@@ -97,7 +97,7 @@ void snd_update_3d_pos(int soudnnum, game_snd *gs, vec3d *new_pos, float radius
 // Use these for looping sounds.
 // Returns the handle of the sound. -1 if failed.
 // If startloop or stoploop are not -1, then then are used.
-int	snd_play_looping( game_snd *gs, float pan=0.0f, int start_loop=-1, int stop_loop=-1, float vol_scale=1.0f, int priority = SND_PRIORITY_MUST_PLAY, int force = 0 );
+int	snd_play_looping( game_snd *gs, float pan=0.0f, int start_loop=-1, int stop_loop=-1, float vol_scale=1.0f, int scriptingUpdateVolume = 1);
 
 void	snd_stop( int snd_handle );
 
@@ -172,4 +172,4 @@ int sound_env_supported();
 // adjust-audio-volume
 void snd_aav_init();
 
-#endif
\ No newline at end of file
+#endif
