diff --git a/src/s_sound.c b/src/s_sound.c
index ea0a1bbe70d0a6139ac45989ade3eda00eeaed0d..d80fa1ca9ed0b3f6c6e77ffc583aac2701e4ef9c 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -46,7 +46,7 @@ extern INT32 msg_id;
 // 3D Sound Interface
 #include "hardware/hw3sound.h"
 #else
-static INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
+static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
 #endif
 
 CV_PossibleValue_t soundvolume_cons_t[] = {{0, "MIN"}, {31, "MAX"}, {0, NULL}};
@@ -189,8 +189,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo)
 	// channel number to use
 	INT32 cnum;
 
-	channel_t *c;
-
 	// Find an open channel
 	for (cnum = 0; cnum < numofchannels; cnum++)
 	{
@@ -202,7 +200,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo)
 		else if (sfxinfo == channels[cnum].sfxinfo && (sfxinfo->pitch & SF_NOMULTIPLESOUND))
 		{
 			return -1;
-			break;
 		}
 		else if (sfxinfo == channels[cnum].sfxinfo && sfxinfo->singularity == true)
 		{
@@ -246,12 +243,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo)
 		}
 	}
 
-	c = &channels[cnum];
-
-	// channel is decided to be cnum.
-	c->sfxinfo = sfxinfo;
-	c->origin = origin;
-
 	return cnum;
 }
 
@@ -407,7 +398,6 @@ void S_StopSoundByID(void *origin, sfxenum_t sfx_id)
 		if (channels[cnum].sfxinfo == &S_sfx[sfx_id] && channels[cnum].origin == origin)
 		{
 			S_StopChannel(cnum);
-			break;
 		}
 	}
 }
@@ -428,28 +418,42 @@ void S_StopSoundByNum(sfxenum_t sfxnum)
 		if (channels[cnum].sfxinfo == &S_sfx[sfxnum])
 		{
 			S_StopChannel(cnum);
-			break;
 		}
 	}
 }
 
+static INT32 S_ScaleVolumeWithSplitscreen(INT32 volume)
+{
+	fixed_t root = INT32_MAX;
+
+	if (splitscreen == 0)
+	{
+		return volume;
+	}
+
+	root = FixedSqrt((splitscreen + 1) * (FRACUNIT/3));
+
+	return FixedDiv(
+		volume * FRACUNIT,
+		root
+	) / FRACUNIT;
+}
+
+
 void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
 {
-	const INT32 initial_volume = volume;
-	INT32 sep, pitch, priority, cnum;
-	sfxinfo_t *sfx;
-	const boolean reverse = (stereoreverse.value ^ encoremode);
 	const mobj_t *origin = (const mobj_t *)origin_p;
+	const boolean reverse = (stereoreverse.value ^ encoremode);
+	const INT32 initial_volume = (origin ? S_ScaleVolumeWithSplitscreen(volume) : volume);
 
-	listener_t listener  = {0,0,0,0};
-	listener_t listener2 = {0,0,0,0};
-	listener_t listener3 = {0,0,0,0};
-	listener_t listener4 = {0,0,0,0};
+	sfxinfo_t *sfx;
+	INT32 sep, pitch, priority, cnum;
+	boolean anyListeners = false;
+	boolean itsUs = false;
+	INT32 i;
 
-	mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo;
-	mobj_t *listenmobj2 = NULL;
-	mobj_t *listenmobj3 = NULL;
-	mobj_t *listenmobj4 = NULL;
+	listener_t listener[MAXSPLITSCREENPLAYERS];
+	mobj_t *listenmobj[MAXSPLITSCREENPLAYERS];
 
 	if (sound_disabled || !sound_started)
 		return;
@@ -458,27 +462,29 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
 	if (sfx_id == sfx_None)
 		return;
 
-	if (players[displayplayers[0]].awayviewtics)
-		listenmobj = players[displayplayers[0]].awayviewmobj;
-
-	if (splitscreen)
+	for (i = 0; i <= splitscreen; i++)
 	{
-		listenmobj2 = players[displayplayers[1]].mo;
-		if (players[displayplayers[1]].awayviewtics)
-			listenmobj2 = players[displayplayers[1]].awayviewmobj;
+		player_t *player = &players[displayplayers[i]];
 
-		if (splitscreen > 1)
+		memset(&listener[i], 0, sizeof (listener[i]));
+		listenmobj[i] = NULL;
+
+		if (i == 0 && democam.soundmobj)
+		{
+			listenmobj[i] = democam.soundmobj;
+		}
+		else if (player->awayviewtics)
+		{
+			listenmobj[i] = player->awayviewmobj;
+		}
+		else
 		{
-			listenmobj3 = players[displayplayers[2]].mo;
-			if (players[displayplayers[2]].awayviewtics)
-				listenmobj3 = players[displayplayers[2]].awayviewmobj;
+			listenmobj[i] = player->mo;
+		}
 
-			if (splitscreen > 2)
-			{
-				listenmobj4 = players[displayplayers[3]].mo;
-				if (players[displayplayers[3]].awayviewtics)
-					listenmobj4 = players[displayplayers[3]].awayviewmobj;
-			}
+		if (origin && origin == listenmobj[i])
+		{
+			itsUs = true;
 		}
 	}
 
@@ -490,75 +496,32 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
 	};
 #endif
 
-	if (camera[0].chase && !players[displayplayers[0]].awayviewtics)
-	{
-		listener.x = camera[0].x;
-		listener.y = camera[0].y;
-		listener.z = camera[0].z;
-		listener.angle = camera[0].angle;
-	}
-	else if (listenmobj)
-	{
-		listener.x = listenmobj->x;
-		listener.y = listenmobj->y;
-		listener.z = listenmobj->z;
-		listener.angle = listenmobj->angle;
-	}
-	else if (origin)
-		return;
-
-	if (listenmobj2)
+	for (i = 0; i <= splitscreen; i++)
 	{
-		if (camera[1].chase && !players[displayplayers[1]].awayviewtics)
-		{
-			listener2.x = camera[1].x;
-			listener2.y = camera[1].y;
-			listener2.z = camera[1].z;
-			listener2.angle = camera[1].angle;
-		}
-		else
-		{
-			listener2.x = listenmobj2->x;
-			listener2.y = listenmobj2->y;
-			listener2.z = listenmobj2->z;
-			listener2.angle = listenmobj2->angle;
-		}
-	}
+		player_t *player = &players[displayplayers[i]];
 
-	if (listenmobj3)
-	{
-		if (camera[2].chase && !players[displayplayers[2]].awayviewtics)
+		if (camera[i].chase && !player->awayviewtics)
 		{
-			listener3.x = camera[2].x;
-			listener3.y = camera[2].y;
-			listener3.z = camera[2].z;
-			listener3.angle = camera[2].angle;
+			listener[i].x = camera[i].x;
+			listener[i].y = camera[i].y;
+			listener[i].z = camera[i].z;
+			listener[i].angle = camera[i].angle;
+			anyListeners = true;
 		}
-		else
+		else if (listenmobj[i])
 		{
-			listener3.x = listenmobj3->x;
-			listener3.y = listenmobj3->y;
-			listener3.z = listenmobj3->z;
-			listener3.angle = listenmobj3->angle;
+			listener[i].x = listenmobj[i]->x;
+			listener[i].y = listenmobj[i]->y;
+			listener[i].z = listenmobj[i]->z;
+			listener[i].angle = listenmobj[i]->angle;
+			anyListeners = true;
 		}
 	}
 
-	if (listenmobj4)
+	if (origin && anyListeners == false)
 	{
-		if (camera[3].chase && !players[displayplayers[3]].awayviewtics)
-		{
-			listener4.x = camera[3].x;
-			listener4.y = camera[3].y;
-			listener4.z = camera[3].z;
-			listener4.angle = camera[3].angle;
-		}
-		else
-		{
-			listener4.x = listenmobj4->x;
-			listener4.y = listenmobj4->y;
-			listener4.z = listenmobj4->z;
-			listener4.angle = listenmobj4->angle;
-		}
+		// If a mobj is trying to make a noise, and no one is around to hear it, does it make a sound?
+		return;
 	}
 
 	// check for bogus sound #
@@ -577,93 +540,51 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
 	// Initialize sound parameters
 	pitch = NORM_PITCH;
 	priority = NORM_PRIORITY;
+	sep = NORM_SEP;
 
-	if (splitscreen && origin)
-		volume = FixedDiv(volume<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
+	i = 0; // sensible default
 
-	if (splitscreen && listenmobj2) // Copy the sound for the split player
 	{
 		// Check to see if it is audible, and if not, modify the params
-		if (origin && origin != listenmobj2)
+		if (origin && !itsUs)
 		{
-			INT32 rc;
-			rc = S_AdjustSoundParams(listenmobj2, origin, &volume, &sep, &pitch, sfx);
-
-			if (!rc)
-				goto dontplay; // Maybe the other player can hear it...
-
-			if (origin->x == listener2.x && origin->y == listener2.y)
-				sep = NORM_SEP;
-		}
-		else if (!origin)
-			// Do not play origin-less sounds for the second player.
-			// The first player will be able to hear it just fine,
-			// we really don't want it playing twice.
-			goto dontplay;
-		else
-			sep = NORM_SEP;
-
-		// try to find a channel
-		cnum = S_getChannel(origin, sfx);
-
-		if (cnum < 0)
-			return; // If there's no free channels, it's not gonna be free for player 1, either.
-
-		// This is supposed to handle the loading/caching.
-		// For some odd reason, the caching is done nearly
-		// each time the sound is needed?
-
-		// cache data if necessary
-		// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
-		if (!sfx->data)
-			sfx->data = I_GetSfx(sfx);
-
-		// increase the usefulness
-		if (sfx->usefulness++ < 0)
-			sfx->usefulness = -1;
+			boolean audible = false;
+			if (splitscreen > 0)
+			{
+				fixed_t recdist = INT32_MAX;
+				UINT8 j = 0;
 
-		// Avoid channel reverse if surround
-		if (reverse
-#ifdef SURROUND
-			&& sep != SURROUND_SEP
-#endif
-		)
-			sep = (~sep) & 255;
+				for (; j <= splitscreen; j++)
+				{
+					fixed_t thisdist = INT32_MAX;
 
-		// 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);
-	}
+					if (!listenmobj[j])
+					{
+						continue;
+					}
 
-dontplay:
+					thisdist = P_AproxDistance(listener[j].x - origin->x, listener[j].y - origin->y);
 
-	if (splitscreen > 1 && listenmobj3) // Copy the sound for the third player
-	{
-		// Check to see if it is audible, and if not, modify the params
-		if (origin && origin != listenmobj3)
-		{
-			INT32 rc;
-			rc = S_AdjustSoundParams(listenmobj3, origin, &volume, &sep, &pitch, sfx);
+					if (thisdist >= recdist)
+					{
+						continue;
+					}
+				
+					recdist = thisdist;
+					i = j;
+				}
+			}
 
-			if (!rc)
-				goto dontplay3; // Maybe the other player can hear it...
+			if (listenmobj[i])
+			{
+				audible = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, &pitch, sfx);
+			}
 
-			if (origin->x == listener3.x && origin->y == listener3.y)
-				sep = NORM_SEP;
+			if (!audible)
+			{
+				return;
+			}
 		}
-		else if (!origin)
-			// Do not play origin-less sounds for the second player.
-			// The first player will be able to hear it just fine,
-			// we really don't want it playing twice.
-			goto dontplay3;
-		else
-			sep = NORM_SEP;
-
-		// try to find a channel
-		cnum = S_getChannel(origin, sfx);
-
-		if (cnum < 0)
-			return; // If there's no free channels, it's not gonna be free for player 1, either.
 
 		// This is supposed to handle the loading/caching.
 		// For some odd reason, the caching is done nearly
@@ -672,129 +593,40 @@ dontplay:
 		// cache data if necessary
 		// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
 		if (!sfx->data)
+		{
 			sfx->data = I_GetSfx(sfx);
+		}
 
 		// increase the usefulness
 		if (sfx->usefulness++ < 0)
+		{
 			sfx->usefulness = -1;
+		}
 
 		// Avoid channel reverse if surround
 		if (reverse
 #ifdef SURROUND
 			&& sep != SURROUND_SEP
 #endif
-		)
-			sep = (~sep) & 255;
-
-		// 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);
-	}
-
-dontplay3:
-
-	if (splitscreen > 2 && listenmobj4) // Copy the sound for the split player
-	{
-		// Check to see if it is audible, and if not, modify the params
-		if (origin && origin != listenmobj4)
+			)
 		{
-			INT32 rc;
-			rc = S_AdjustSoundParams(listenmobj4, origin, &volume, &sep, &pitch, sfx);
-
-			if (!rc)
-				goto dontplay4; // Maybe the other player can hear it...
-
-			if (origin->x == listener4.x && origin->y == listener4.y)
-				sep = NORM_SEP;
+			sep = (~sep) & 255;
 		}
-		else if (!origin)
-			// Do not play origin-less sounds for the second player.
-			// The first player will be able to hear it just fine,
-			// we really don't want it playing twice.
-			goto dontplay4;
-		else
-			sep = NORM_SEP;
 
-		// try to find a channel
+		// At this point it is determined that a sound can and should be played, so find a free channel to play it on
 		cnum = S_getChannel(origin, sfx);
 
 		if (cnum < 0)
-			return; // If there's no free channels, it's not gonna be free for player 1, either.
-
-		// This is supposed to handle the loading/caching.
-		// For some odd reason, the caching is done nearly
-		// each time the sound is needed?
-
-		// cache data if necessary
-		// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
-		if (!sfx->data)
-			sfx->data = I_GetSfx(sfx);
-
-		// increase the usefulness
-		if (sfx->usefulness++ < 0)
-			sfx->usefulness = -1;
-
-		// Avoid channel reverse if surround
-		if (reverse
-#ifdef SURROUND
-			&& sep != SURROUND_SEP
-#endif
-		)
-			sep = (~sep) & 255;
+		{
+			return; // If there's no free channels, there won't be any for anymore players either
+		}
 
-		// Assigns the handle to one of the channels in the
-		// mix/output buffer.
+		// Now that we know we are going to play a sound, fill out this info
+		channels[cnum].sfxinfo = sfx;
+		channels[cnum].origin = origin;
+		channels[cnum].volume = initial_volume;
 		channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
 	}
-
-dontplay4:
-
-	// Check to see if it is audible, and if not, modify the params
-	if (origin && origin != listenmobj)
-	{
-		INT32 rc;
-		rc = S_AdjustSoundParams(listenmobj, origin, &volume, &sep, &pitch, sfx);
-
-		if (!rc)
-			return;
-
-		if (origin->x == listener.x && origin->y == listener.y)
-			sep = NORM_SEP;
-	}
-	else
-		sep = NORM_SEP;
-
-	// try to find a channel
-	cnum = S_getChannel(origin, sfx);
-
-	if (cnum < 0)
-		return;
-
-	// This is supposed to handle the loading/caching.
-	// For some odd reason, the caching is done nearly
-	// each time the sound is needed?
-
-	// cache data if necessary
-	// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
-	if (!sfx->data)
-		sfx->data = I_GetSfx(sfx);
-
-	// increase the usefulness
-	if (sfx->usefulness++ < 0)
-		sfx->usefulness = -1;
-
-	// Avoid channel reverse if surround
-	if (reverse
-#ifdef SURROUND
-		&& sep != SURROUND_SEP
-#endif
-	)
-		sep = (~sep) & 255;
-
-	// 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);
 }
 
 void S_StartSound(const void *origin, sfxenum_t sfx_id)
@@ -884,7 +716,6 @@ void S_StopSound(void *origin)
 		if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
 		{
 			S_StopChannel(cnum);
-			break;
 		}
 	}
 }
@@ -900,23 +731,13 @@ static INT32 actualmidimusicvolume;
 
 void S_UpdateSounds(void)
 {
-	INT32 audible, cnum, volume, sep, pitch;
+	INT32 cnum, volume, sep, pitch;
+	boolean audible = false;
 	channel_t *c;
+	INT32 i;
 
-	listener_t listener;
-	listener_t listener2;
-	listener_t listener3;
-	listener_t listener4;
-
-	mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo;
-	mobj_t *listenmobj2 = NULL;
-	mobj_t *listenmobj3 = NULL;
-	mobj_t *listenmobj4 = NULL;
-
-	memset(&listener, 0, sizeof(listener_t));
-	memset(&listener2, 0, sizeof(listener_t));
-	memset(&listener3, 0, sizeof(listener_t));
-	memset(&listener4, 0, sizeof(listener_t));
+	listener_t listener[MAXSPLITSCREENPLAYERS];
+	mobj_t *listenmobj[MAXSPLITSCREENPLAYERS];
 
 	// Update sound/music volumes, if changed manually at console
 	if (actualsfxvolume != cv_soundvolume.value)
@@ -933,7 +754,7 @@ void S_UpdateSounds(void)
 	{
 #ifndef NOMUMBLE
 		// Stop Mumble cutting out. I'm sick of it.
-		I_UpdateMumble(NULL, listener);
+		I_UpdateMumble(NULL, listener[0]);
 #endif
 
 		// Stop cutting FMOD out. WE'RE sick of it.
@@ -944,47 +765,31 @@ void S_UpdateSounds(void)
 	if (dedicated || sound_disabled)
 		return;
 
-	if (players[displayplayers[0]].awayviewtics)
-		listenmobj = players[displayplayers[0]].awayviewmobj;
-
-	if (splitscreen)
+	for (i = 0; i <= splitscreen; i++)
 	{
-		listenmobj2 = players[displayplayers[1]].mo;
-		if (players[displayplayers[1]].awayviewtics)
-			listenmobj2 = players[displayplayers[1]].awayviewmobj;
+		player_t *player = &players[displayplayers[i]];
 
-		if (splitscreen > 1)
-		{
-			listenmobj3 = players[displayplayers[2]].mo;
-			if (players[displayplayers[2]].awayviewtics)
-				listenmobj3 = players[displayplayers[2]].awayviewmobj;
+		memset(&listener[i], 0, sizeof (listener[i]));
+		listenmobj[i] = NULL;
 
-			if (splitscreen > 2)
-			{
-				listenmobj4 = players[displayplayers[3]].mo;
-				if (players[displayplayers[3]].awayviewtics)
-					listenmobj4 = players[displayplayers[3]].awayviewmobj;
-			}
+		if (i == 0 && democam.soundmobj)
+		{
+			listenmobj[i] = democam.soundmobj;
+			continue;
 		}
-	}
 
-	if (camera[0].chase && !players[displayplayers[0]].awayviewtics)
-	{
-		listener.x = camera[0].x;
-		listener.y = camera[0].y;
-		listener.z = camera[0].z;
-		listener.angle = camera[0].angle;
-	}
-	else if (listenmobj)
-	{
-		listener.x = listenmobj->x;
-		listener.y = listenmobj->y;
-		listener.z = listenmobj->z;
-		listener.angle = listenmobj->angle;
+		if (player->awayviewtics)
+		{
+			listenmobj[i] = player->awayviewmobj;
+		}
+		else
+		{
+			listenmobj[i] = player->mo;
+		}
 	}
 
 #ifndef NOMUMBLE
-	I_UpdateMumble(players[consoleplayer].mo, listener);
+	I_UpdateMumble(players[consoleplayer].mo, listener[0]);
 #endif
 
 #ifdef HW3SOUND
@@ -996,57 +801,23 @@ void S_UpdateSounds(void)
 	}
 #endif
 
-	if (listenmobj2)
+	for (i = 0; i <= splitscreen; i++)
 	{
-		if (camera[1].chase && !players[displayplayers[1]].awayviewtics)
-		{
-			listener2.x = camera[1].x;
-			listener2.y = camera[1].y;
-			listener2.z = camera[1].z;
-			listener2.angle = camera[1].angle;
-		}
-		else
-		{
-			listener2.x = listenmobj2->x;
-			listener2.y = listenmobj2->y;
-			listener2.z = listenmobj2->z;
-			listener2.angle = listenmobj2->angle;
-		}
-	}
+		player_t *player = &players[displayplayers[i]];
 
-	if (listenmobj3)
-	{
-		if (camera[2].chase && !players[displayplayers[2]].awayviewtics)
+		if (camera[i].chase && !player->awayviewtics)
 		{
-			listener3.x = camera[2].x;
-			listener3.y = camera[2].y;
-			listener3.z = camera[2].z;
-			listener3.angle = camera[2].angle;
+			listener[i].x = camera[i].x;
+			listener[i].y = camera[i].y;
+			listener[i].z = camera[i].z;
+			listener[i].angle = camera[i].angle;
 		}
-		else
+		else if (listenmobj[i])
 		{
-			listener3.x = listenmobj3->x;
-			listener3.y = listenmobj3->y;
-			listener3.z = listenmobj3->z;
-			listener3.angle = listenmobj3->angle;
-		}
-	}
-
-	if (listenmobj4)
-	{
-		if (camera[3].chase && !players[displayplayers[3]].awayviewtics)
-		{
-			listener4.x = camera[3].x;
-			listener4.y = camera[3].y;
-			listener4.z = camera[3].z;
-			listener4.angle = camera[3].angle;
-		}
-		else
-		{
-			listener4.x = listenmobj4->x;
-			listener4.y = listenmobj4->y;
-			listener4.z = listenmobj4->z;
-			listener4.angle = listenmobj4->angle;
+			listener[i].x = listenmobj[i]->x;
+			listener[i].y = listenmobj[i]->y;
+			listener[i].z = listenmobj[i]->z;
+			listener[i].angle = listenmobj[i]->angle;
 		}
 	}
 
@@ -1063,83 +834,60 @@ void S_UpdateSounds(void)
 				pitch = NORM_PITCH;
 				sep = NORM_SEP;
 
-				if (splitscreen && c->origin)
-					volume = FixedDiv(volume<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
-
 				// check non-local sounds for distance clipping
 				//  or modify their params
-				if (c->origin && ((c->origin != players[consoleplayer].mo)
-					|| (splitscreen && c->origin != players[displayplayers[1]].mo)
-					|| (splitscreen > 1 && c->origin != players[displayplayers[2]].mo)
-					|| (splitscreen > 2 && c->origin != players[displayplayers[3]].mo)))
+				if (c->origin)
 				{
-					// Whomever is closer gets the sound, but only in splitscreen.
-					if (splitscreen)
+					boolean itsUs = false;
+
+					for (i = splitscreen; i >= 0; i--)
+					{
+						if (c->origin != listenmobj[i])
+							continue;
+
+						itsUs = true;
+					}
+
+					if (itsUs == false)
 					{
-						const mobj_t *soundmobj = c->origin;
-						fixed_t recdist = -1;
-						INT32 i, p = -1;
+						const mobj_t *origin = c->origin;
+
+						i = 0;
 
-						for (i = 0; i <= splitscreen; i++)
+						if (splitscreen > 0)
 						{
-							fixed_t thisdist = -1;
-
-							if (i == 0 && listenmobj)
-								thisdist = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y);
-							else if (i == 1 && listenmobj2)
-								thisdist = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y);
-							else if (i == 2 && listenmobj3)
-								thisdist = P_AproxDistance(listener3.x-soundmobj->x, listener3.y-soundmobj->y);
-							else if (i == 3 && listenmobj4)
-								thisdist = P_AproxDistance(listener4.x-soundmobj->x, listener4.y-soundmobj->y);
-							else
-								continue;
-
-							if (recdist == -1 || (thisdist != -1 && thisdist < recdist))
+							fixed_t recdist = INT32_MAX;
+							UINT8 j = 0;
+
+							for (; j <= splitscreen; j++)
 							{
+								fixed_t thisdist = INT32_MAX;
+
+								if (!listenmobj[j])
+								{
+									continue;
+								}
+
+								thisdist = P_AproxDistance(listener[j].x - origin->x, listener[j].y - origin->y);
+
+								if (thisdist >= recdist)
+								{
+									continue;
+								}
+
 								recdist = thisdist;
-								p = i;
+								i = j;
 							}
 						}
 
-						if (p != -1)
+						if (listenmobj[i])
 						{
-							if (p == 1)
-							{
-								// Player 2 gets the sound
-								audible = S_AdjustSoundParams(listenmobj2, c->origin, &volume, &sep, &pitch,
-									c->sfxinfo);
-							}
-							else if (p == 2)
-							{
-								// Player 3 gets the sound
-								audible = S_AdjustSoundParams(listenmobj3, c->origin, &volume, &sep, &pitch,
-								c->sfxinfo);
-							}
-							else if (p == 3)
-							{
-								// Player 4 gets the sound
-								audible = S_AdjustSoundParams(listenmobj4, c->origin, &volume, &sep, &pitch,
-									c->sfxinfo);
-							}
-							else
-							{
-								// Player 1 gets the sound
-								audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch,
-									c->sfxinfo);
-							}
-
-							if (audible)
-								I_UpdateSoundParams(c->handle, volume, sep, pitch);
-							else
-								S_StopChannel(cnum);
+							audible = S_AdjustSoundParams(
+								listenmobj[i], c->origin,
+								&volume, &sep, &pitch,
+								c->sfxinfo
+							);
 						}
-					}
-					else if (listenmobj && !splitscreen)
-					{
-						// In the case of a single player, he or she always should get updated sound.
-						audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch,
-							c->sfxinfo);
 
 						if (audible)
 							I_UpdateSoundParams(c->handle, volume, sep, pitch);
@@ -1242,54 +990,38 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t
 // If the sound is not audible, returns a 0.
 // Otherwise, modifies parameters and returns 1.
 //
-INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch,
+boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch,
 	sfxinfo_t *sfxinfo)
 {
+	const boolean reverse = (stereoreverse.value ^ encoremode);
+
 	fixed_t approx_dist;
-	angle_t angle;
 
 	listener_t listensource;
-
-	const boolean reverse = (stereoreverse.value ^ encoremode);
+	INT32 i;
 
 	(void)pitch;
+
 	if (!listener)
 		return false;
 
-	if (listener == players[displayplayers[0]].mo && camera[0].chase)
-	{
-		listensource.x = camera[0].x;
-		listensource.y = camera[0].y;
-		listensource.z = camera[0].z;
-		listensource.angle = camera[0].angle;
-	}
-	else if (splitscreen && listener == players[displayplayers[1]].mo && camera[1].chase)
-	{
-		listensource.x = camera[1].x;
-		listensource.y = camera[1].y;
-		listensource.z = camera[1].z;
-		listensource.angle = camera[1].angle;
-	}
-	else if (splitscreen > 1 && listener == players[displayplayers[2]].mo && camera[2].chase)
-	{
-		listensource.x = camera[2].x;
-		listensource.y = camera[2].y;
-		listensource.z = camera[2].z;
-		listensource.angle = camera[2].angle;
-	}
-	else if (splitscreen > 2 && listener == players[displayplayers[3]].mo && camera[3].chase)
-	{
-		listensource.x = camera[3].x;
-		listensource.y = camera[3].y;
-		listensource.z = camera[3].z;
-		listensource.angle = camera[3].angle;
-	}
-	else
+	// Init listensource with default listener
+	listensource.x = listener->x;
+	listensource.y = listener->y;
+	listensource.z = listener->z;
+	listensource.angle = listener->angle;
+
+	for (i = 0; i <= splitscreen; i++)
 	{
-		listensource.x = listener->x;
-		listensource.y = listener->y;
-		listensource.z = listener->z;
-		listensource.angle = listener->angle;
+		// If listener is a chasecam player, use the camera instead
+		if (listener == players[displayplayers[i]].mo && camera[i].chase)
+		{
+			listensource.x = camera[i].x;
+			listensource.y = camera[i].y;
+			listensource.z = camera[i].z;
+			listensource.angle = camera[i].angle;
+			break;
+		}
 	}
 
 	if (sfxinfo->pitch & SF_OUTSIDESOUND) // Rain special case
@@ -1339,30 +1071,37 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v
 		approx_dist = FixedDiv(approx_dist,2*FRACUNIT);
 
 	if (approx_dist > S_CLIPPING_DIST)
-		return 0;
-
-	// angle of source to listener
-	angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y);
+		return false;
 
-	if (angle > listensource.angle)
-		angle = angle - listensource.angle;
+	if (source->x == listensource.x && source->y == listensource.y)
+	{
+		*sep = NORM_SEP;
+	}
 	else
-		angle = angle + InvAngle(listensource.angle);
+	{
+		// angle of source to listener
+		angle_t angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y);
 
-	if (reverse)
-		angle = InvAngle(angle);
+		if (angle > listensource.angle)
+			angle = angle - listensource.angle;
+		else
+			angle = angle + InvAngle(listensource.angle);
+
+		if (reverse)
+			angle = InvAngle(angle);
 
 #ifdef SURROUND
-	// Produce a surround sound for angle from 105 till 255
-	if (surround.value == 1 && (angle > ANG105 && angle < ANG255 ))
-		*sep = SURROUND_SEP;
-	else
+		// Produce a surround sound for angle from 105 till 255
+		if (surround.value == 1 && (angle > ANG105 && angle < ANG255 ))
+			*sep = SURROUND_SEP;
+		else
 #endif
-	{
-		angle >>= ANGLETOFINESHIFT;
+		{
+			angle >>= ANGLETOFINESHIFT;
 
-		// stereo separation
-		*sep = 128 - (FixedMul(S_STEREO_SWING, FINESINE(angle))>>FRACBITS);
+			// stereo separation
+			*sep = 128 - (FixedMul(S_STEREO_SWING, FINESINE(angle))>>FRACBITS);
+		}
 	}
 
 	// volume calculation
@@ -1374,9 +1113,6 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v
 		*vol = FixedMul(*vol * FRACUNIT / 255, n) / S_ATTENUATOR;
 	}
 
-	if (splitscreen)
-		*vol = FixedDiv((*vol)<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
-
 	return (*vol > 0);
 }