Index: darkplaces/snd_mem.c
diff -u darkplaces/snd_mem.c:1.45 darkplaces/snd_mem.c:1.46
--- darkplaces/snd_mem.c:1.45	Mon Nov  7 06:08:12 2005
+++ darkplaces/snd_mem.c	Tue Mar  7 05:14:28 2006
@@ -33,7 +33,7 @@
 */
 size_t ResampleSfx (const unsigned char *in_data, size_t in_length, const snd_format_t* in_format, unsigned char *out_data, const char* sfxname)
 {
-	size_t srclength, outcount, i;
+	size_t srclength, outcount;
 
 	srclength = in_length * in_format->channels;
 	outcount = (double)in_length * shm->format.speed / in_format->speed;
@@ -46,6 +46,8 @@
 	{
 		if (in_format->width == 1)
 		{
+			size_t i;
+
 			for (i = 0; i < srclength; i++)
 				((signed char*)out_data)[i] = in_data[i] - 128;
 		}
@@ -80,61 +82,110 @@
 		// also to be able to handle very long sounds.
 		while (total_out < outcount)
 		{
-			size_t tmpcount;
+			size_t tmpcount, i, j;
+			unsigned int interpolation_limit, srcsample;
 
 			samplefrac = 0;
 
 			// If more than 1 sec of sound remains to be converted
 			if (outcount - total_out > shm->format.speed)
+			{
 				tmpcount = shm->format.speed;
+				interpolation_limit = tmpcount;  // all samples can be interpolated
+			}
 			else
+			{
 				tmpcount = outcount - total_out;
+				interpolation_limit = ceil((double)(((remain_in / in_format->channels) - 1) << FRACTIONAL_BITS) / fracstep);
+				if (interpolation_limit > tmpcount)
+					interpolation_limit = tmpcount;
+			}
 
-			// Convert up to 1 sec of sound
-			for (i = 0; i < tmpcount; i++)
+			// 16 bit samples
+			if (in_format->width == 2)
 			{
-				unsigned int j = 0;
-				unsigned int srcsample = (samplefrac >> FRACTIONAL_BITS) * in_format->channels;
-				int a, b;
+				const short* in_ptr_short;
 
-				// 16 bit samples
-				if (in_format->width == 2)
+				// Interpolated part
+				for (i = 0; i < interpolation_limit; i++)
 				{
-					for (j = 0; j < in_format->channels; j++, srcsample++)
+					srcsample = (samplefrac >> FRACTIONAL_BITS) * in_format->channels;
+					in_ptr_short = &((const short*)in_ptr)[srcsample];
+
+					for (j = 0; j < in_format->channels; j++)
 					{
-						// No value to interpolate with?
-						if (srcsample + in_format->channels < remain_in)
-						{
-							a = ((const short*)in_ptr)[srcsample];
-							b = ((const short*)in_ptr)[srcsample + in_format->channels];
-							*((short*)out_ptr) = (((b - a) * (samplefrac & FRACTIONAL_MASK)) >> FRACTIONAL_BITS) + a;
-						}
-						else
-							*((short*)out_ptr) = ((const short*)in_ptr)[srcsample];
+						int a, b;
 
+						a = *in_ptr_short;
+						b = *(in_ptr_short + in_format->channels);
+						*((short*)out_ptr) = (((b - a) * (samplefrac & FRACTIONAL_MASK)) >> FRACTIONAL_BITS) + a;
+
+						in_ptr_short++;
 						out_ptr += sizeof (short);
 					}
+
+					samplefrac += fracstep;
 				}
-				// 8 bit samples
-				else  // if (in_format->width == 1)
+
+				// Non-interpolated part
+				for (/* nothing */; i < tmpcount; i++)
 				{
-					for (j = 0; j < in_format->channels; j++, srcsample++)
+					srcsample = (samplefrac >> FRACTIONAL_BITS) * in_format->channels;
+					in_ptr_short = &((const short*)in_ptr)[srcsample];
+
+					for (j = 0; j < in_format->channels; j++)
 					{
-						// No more value to interpolate with?
-						if (srcsample + in_format->channels < remain_in)
-						{
-							a = ((const unsigned char*)in_ptr)[srcsample] - 128;
-							b = ((const unsigned char*)in_ptr)[srcsample + in_format->channels] - 128;
-							*((signed char*)out_ptr) = (((b - a) * (samplefrac & FRACTIONAL_MASK)) >> FRACTIONAL_BITS) + a;
-						}
-						else
-							*((signed char*)out_ptr) = ((const unsigned char*)in_ptr)[srcsample] - 128;
+						*((short*)out_ptr) = *in_ptr_short;
+
+						in_ptr_short++;
+						out_ptr += sizeof (short);
+					}
 
+					samplefrac += fracstep;
+				}
+			}
+			// 8 bit samples
+			else  // if (in_format->width == 1)
+			{
+				const unsigned char* in_ptr_byte;
+
+				// Convert up to 1 sec of sound
+				for (i = 0; i < interpolation_limit; i++)
+				{
+					srcsample = (samplefrac >> FRACTIONAL_BITS) * in_format->channels;
+					in_ptr_byte = &((const unsigned char*)in_ptr)[srcsample];
+
+					for (j = 0; j < in_format->channels; j++)
+					{
+						int a, b;
+
+						a = *in_ptr_byte - 128;
+						b = *(in_ptr_byte + in_format->channels) - 128;
+						*((signed char*)out_ptr) = (((b - a) * (samplefrac & FRACTIONAL_MASK)) >> FRACTIONAL_BITS) + a;
+
+						in_ptr_byte++;
 						out_ptr += sizeof (signed char);
 					}
+
+					samplefrac += fracstep;
 				}
 
-				samplefrac += fracstep;
+				// Non-interpolated part
+				for (/* nothing */; i < tmpcount; i++)
+				{
+					srcsample = (samplefrac >> FRACTIONAL_BITS) * in_format->channels;
+					in_ptr_byte = &((const unsigned char*)in_ptr)[srcsample];
+
+					for (j = 0; j < in_format->channels; j++)
+					{
+						*((signed char*)out_ptr) = *in_ptr_byte - 128;
+
+						in_ptr_byte++;
+						out_ptr += sizeof (signed char);
+					}
+
+					samplefrac += fracstep;
+				}
 			}
 
 			// Update the counters and the buffer position