Browse Source

Use SDL's audio converter for integer resample in SOUND_Play()

louyihua 8 years ago
parent
commit
1bf48cd079
1 changed files with 37 additions and 13 deletions
  1. 37 13
      sound.c

+ 37 - 13
sound.c

@@ -956,24 +956,48 @@ AUDIO_PlaySound(
    if (wavespec.freq != gSndPlayer.spec.freq)
    {
 	   /* Resampler is needed */
-	   resampler_set_quality(gSndPlayer.WavePlayer.resampler, AUDIO_IsIntegerConversion(wavespec.freq) ? RESAMPLER_QUALITY_MIN : gConfig.iResampleQuality);
-	   resampler_set_rate(gSndPlayer.WavePlayer.resampler, (double)wavespec.freq / (double)gSndPlayer.spec.freq);
-	   len = (int)ceil(wavespec.size * (double)gSndPlayer.spec.freq / (double)wavespec.freq) * (SDL_AUDIO_BITSIZE(AUDIO_S16SYS) / SDL_AUDIO_BITSIZE(wavespec.format));
-	   if (len >= wavespec.channels * 2 && (bufdec = malloc(len)))
+	   if (AUDIO_IsIntegerConversion(wavespec.freq))
 	   {
-		   if (wavespec.format == AUDIO_S16)
-			   SOUND_ResampleS16(bufsrc, &wavespec, bufdec, len, gSndPlayer.WavePlayer.resampler);
+		   resampler_set_quality(gSndPlayer.WavePlayer.resampler, AUDIO_IsIntegerConversion(wavespec.freq) ? RESAMPLER_QUALITY_MIN : gConfig.iResampleQuality);
+		   resampler_set_rate(gSndPlayer.WavePlayer.resampler, (double)wavespec.freq / (double)gSndPlayer.spec.freq);
+		   len = (int)ceil(wavespec.size * (double)gSndPlayer.spec.freq / (double)wavespec.freq) * (SDL_AUDIO_BITSIZE(AUDIO_S16SYS) / SDL_AUDIO_BITSIZE(wavespec.format));
+		   if (len >= wavespec.channels * 2 && (bufdec = malloc(len)))
+		   {
+			   if (wavespec.format == AUDIO_S16)
+				   SOUND_ResampleS16(bufsrc, &wavespec, bufdec, len, gSndPlayer.WavePlayer.resampler);
+			   else
+				   SOUND_ResampleU8(bufsrc, &wavespec, bufdec, len, gSndPlayer.WavePlayer.resampler);
+			   /* Free the original buffer and reset the pointer for simpler later operations */
+			   free(buf); buf = bufdec;
+			   wavespec.format = AUDIO_S16SYS;
+			   wavespec.freq = gSndPlayer.spec.freq;
+		   }
 		   else
-			   SOUND_ResampleU8(bufsrc, &wavespec, bufdec, len, gSndPlayer.WavePlayer.resampler);
-		   /* Free the original buffer and reset the pointer for simpler later operations */
-		   free(buf); buf = bufdec;
-		   wavespec.format = AUDIO_S16SYS;
-		   wavespec.freq = gSndPlayer.spec.freq;
+		   {
+			   free(buf);
+			   return;
+		   }
 	   }
 	   else
 	   {
-		   free(buf);
-		   return;
+		   SDL_BuildAudioCVT(&wavecvt, wavespec.format, wavespec.channels, wavespec.freq, wavespec.format, wavespec.channels, gSndPlayer.spec.freq);
+		   if (wavecvt.len_mult > 1)
+		   {
+			   wavecvt.buf = (LPBYTE)malloc(wavespec.size * wavecvt.len_mult);
+			   memcpy(wavecvt.buf, bufsrc, wavespec.size);
+		   }
+		   else
+			   wavecvt.buf = bufsrc;
+		   wavecvt.len = wavespec.size;
+		   SDL_ConvertAudio(&wavecvt);
+		   if (wavecvt.len_mult > 1)
+		   {
+			   free(buf);
+			   buf = wavecvt.buf;
+		   }
+		   bufdec = wavecvt.buf;
+		   len = (int)(wavespec.size * wavecvt.len_ratio);
+		   wavespec.freq = gSndPlayer.spec.freq;
 	   }
    }
    else