Browse Source

New sound play model: Moving major processing steps (resample & convert) from main thread to audio thread

louyihua 8 years ago
parent
commit
f3ae0012c5
12 changed files with 1234 additions and 788 deletions
  1. 605 0
      audio.c
  2. 7 7
      sound.h
  3. 1 1
      main.h
  4. 4 4
      mp3play.c
  5. 4 4
      oggplay.c
  6. 12 7
      players.h
  7. 2 2
      resampler.c
  8. 4 4
      rixplay.cpp
  9. 586 754
      sound.c
  10. 1 1
      uibattle.c
  11. 2 1
      win32/sdlpal.vcxproj
  12. 6 3
      win32/sdlpal.vcxproj.filters

+ 605 - 0
audio.c

@@ -0,0 +1,605 @@
+/* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */
+//
+// Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
+// All rights reserved.
+//
+// This file is part of SDLPAL.
+//
+// SDLPAL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "palcommon.h"
+#include "global.h"
+#include "palcfg.h"
+#include "audio.h"
+#include "players.h"
+#include "util.h"
+#include "resampler.h"
+#include "midi.h"
+#include <math.h>
+
+#if PAL_HAS_OGG
+#include <vorbis/codec.h>
+#endif
+
+#define PAL_CDTRACK_BASE    10000
+
+typedef void(*ResampleMixFunction)(void *, const void *, int, void *, int, int, uint8_t);
+
+typedef struct tagAUDIODEVICE
+{
+   SDL_AudioSpec             spec;		/* Actual-used sound specification */
+   SDL_AudioCVT              cvt;		/* Audio format conversion parameter */
+   SDL_mutex                *mtx;		/* Mutex for preventing using destroyed objects */
+   AUDIOPLAYER              *pMusPlayer;
+   AUDIOPLAYER              *pCDPlayer;
+#if PAL_HAS_SDLCD
+   SDL_CD                   *pCD;
+#endif
+   AUDIOPLAYER              *pSoundPlayer;
+   void                     *pSoundBuffer;	/* The output buffer for sound */
+   INT                       iMusicVolume;	/* The BGM volume ranged in [0, 128] for better performance */
+   INT                       iSoundVolume;	/* The sound effect volume ranged in [0, 128] for better performance */
+   BOOL                      fMusicEnabled; /* Is BGM enabled? */
+   BOOL                      fSoundEnabled; /* Is sound effect enabled? */
+   BOOL                      fOpened;       /* Is the audio device opened? */
+} AUDIODEVICE;
+
+static AUDIODEVICE gAudioDevice;
+
+PAL_FORCE_INLINE
+void
+AUDIO_MixNative(
+	short     *dst,
+	short     *src,
+	int        samples
+)
+{
+	while (samples > 0)
+	{
+		int val = *src++ + *dst;
+		if (val > SHRT_MAX)
+			*dst++ = SHRT_MAX;
+		else if (val < SHRT_MIN)
+			*dst++ = SHRT_MIN;
+		else
+			*dst++ = (short)val;
+		samples--;
+	}
+}
+
+PAL_FORCE_INLINE
+void
+AUDIO_AdjustVolume(
+	short     *srcdst,
+	int        iVolume,
+	int        samples
+)
+{
+	if (iVolume == SDL_MIX_MAXVOLUME) return;
+	if (iVolume == 0) { memset(srcdst, 0, samples << 1); return; }
+	while (samples > 0)
+	{
+		*srcdst = *srcdst * iVolume / SDL_MIX_MAXVOLUME;
+		samples--; srcdst++;
+	}
+}
+
+static VOID SDLCALL
+AUDIO_FillBuffer(
+   LPVOID          udata,
+   LPBYTE          stream,
+   INT             len
+)
+/*++
+  Purpose:
+
+    SDL sound callback function.
+
+  Parameters:
+
+    [IN]  udata - pointer to user-defined parameters (Not used).
+
+    [OUT] stream - pointer to the stream buffer.
+
+    [IN]  len - Length of the buffer.
+
+  Return value:
+
+    None.
+
+--*/
+{
+#if SDL_VERSION_ATLEAST(2,0,0)
+   memset(stream, 0, len);
+#endif
+
+   SDL_mutexP(gAudioDevice.mtx);
+
+   gAudioDevice.cvt.buf = stream;
+   gAudioDevice.cvt.len = len;
+
+   //
+   // Play music
+   //
+   if (gAudioDevice.fMusicEnabled && gAudioDevice.iMusicVolume > 0)
+   {
+      if (gAudioDevice.pMusPlayer)
+      {
+         gAudioDevice.pMusPlayer->FillBuffer(gAudioDevice.pMusPlayer, stream, len);
+      }
+
+      if (gAudioDevice.pCDPlayer)
+      {
+         gAudioDevice.pCDPlayer->FillBuffer(gAudioDevice.pCDPlayer, stream, len);
+      }
+
+      //
+      // Adjust volume for music
+      //
+      AUDIO_AdjustVolume((short *)stream, gAudioDevice.iMusicVolume, len >> 1);
+   }
+
+   //
+   // Play sound
+   //
+   if (gAudioDevice.fSoundEnabled && gAudioDevice.pSoundPlayer && gAudioDevice.iSoundVolume > 0)
+   {
+	   memset(gAudioDevice.pSoundBuffer, 0, len);
+
+	   gAudioDevice.pSoundPlayer->FillBuffer(gAudioDevice.pSoundPlayer, gAudioDevice.pSoundBuffer, len);
+
+	   //
+	   // Adjust volume for sound
+	   //
+	   AUDIO_AdjustVolume((short *)gAudioDevice.pSoundBuffer, gAudioDevice.iSoundVolume, len >> 1);
+
+	   //
+	   // Mix sound & music
+	   //
+	   AUDIO_MixNative((short *)stream, gAudioDevice.pSoundBuffer, len >> 1);
+   }
+
+   //
+   // Convert audio from native byte-order to actual byte-order
+   //
+   SDL_ConvertAudio(&gAudioDevice.cvt);
+
+   SDL_mutexV(gAudioDevice.mtx);
+}
+
+INT
+AUDIO_OpenDevice(
+   VOID
+)
+/*++
+  Purpose:
+
+    Initialize the audio subsystem.
+
+  Parameters:
+
+    None.
+
+  Return value:
+
+    0 if succeed, others if failed.
+
+--*/
+{
+   SDL_AudioSpec spec;
+
+   if (gAudioDevice.fOpened)
+   {
+      //
+      // Already opened
+      //
+      return -1;
+   }
+
+   gAudioDevice.fOpened = FALSE;
+   gAudioDevice.fMusicEnabled = TRUE;
+   gAudioDevice.fSoundEnabled = TRUE;
+   gAudioDevice.iMusicVolume = gConfig.iMusicVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
+   gAudioDevice.iSoundVolume = gConfig.iSoundVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
+
+   //
+   // Initialize the resampler module
+   //
+   resampler_init();
+
+   //
+   // Open the audio device.
+   //
+   gAudioDevice.spec.freq = gConfig.iSampleRate;
+   gAudioDevice.spec.format = AUDIO_S16;
+   gAudioDevice.spec.channels = gConfig.iAudioChannels;
+   gAudioDevice.spec.samples = gConfig.wAudioBufferSize;
+   gAudioDevice.spec.callback = AUDIO_FillBuffer;
+
+   if (SDL_OpenAudio(&gAudioDevice.spec, &spec) < 0)
+   {
+      //
+      // Failed
+      //
+      return -3;
+   }
+   else
+   {
+      gAudioDevice.spec = spec;
+      gAudioDevice.pSoundBuffer = malloc(spec.size);
+   }
+
+   SDL_BuildAudioCVT(&gAudioDevice.cvt, AUDIO_S16SYS, spec.channels, spec.freq, spec.format, spec.channels, spec.freq);
+
+   gAudioDevice.mtx = SDL_CreateMutex();
+   gAudioDevice.fOpened = TRUE;
+
+   //
+   // Initialize the sound subsystem.
+   //
+   gAudioDevice.pSoundPlayer = SOUND_Init();
+
+   //
+   // Initialize the music subsystem.
+   //
+   switch (gConfig.eMusicType)
+   {
+   case MUSIC_RIX:
+	   if (!(gAudioDevice.pMusPlayer = RIX_Init(va("%s%s", gConfig.pszGamePath, "mus.mkf"))))
+	   {
+		   gAudioDevice.pMusPlayer = RIX_Init(va("%s%s", gConfig.pszGamePath, "MUS.MKF"));
+	   }
+	   break;
+   case MUSIC_MP3:
+#if PAL_HAS_MP3
+	   gAudioDevice.pMusPlayer = MP3_Init(NULL);
+#else
+	   gAudioDevice.pMusPlayer = NULL;
+#endif
+	   break;
+   case MUSIC_OGG:
+#if PAL_HAS_OGG
+	   gAudioDevice.pMusPlayer = OGG_Init(NULL);
+#else
+	   gAudioDevice.pMusPlayer = NULL;
+#endif
+	   break;
+   case MUSIC_MIDI:
+	   gAudioDevice.pMusPlayer = NULL;
+	   break;
+   }
+
+   //
+   // Initialize the CD audio.
+   //
+   switch (gConfig.eCDType)
+   {
+   case MUSIC_SDLCD:
+   {
+#if PAL_HAS_SDLCD
+	   int i;
+	   gAudioDevice.pCD = NULL;
+
+	   for (i = 0; i < SDL_CDNumDrives(); i++)
+	   {
+		   gAudioDevice.pCD = SDL_CDOpen(i);
+		   if (gAudioDevice.pCD != NULL)
+		   {
+			   if (!CD_INDRIVE(SDL_CDStatus(gAudioDevice.pCD)))
+			   {
+				   SDL_CDClose(gAudioDevice.pCD);
+				   gAudioDevice.pCD = NULL;
+			   }
+			   else
+			   {
+				   break;
+			   }
+		   }
+	   }
+#endif
+	   gAudioDevice.pCDPlayer = NULL;
+	   break;
+   }
+   case MUSIC_MP3:
+#if PAL_HAS_MP3
+	   gAudioDevice.pCDPlayer = MP3_Init(NULL);
+#else
+	   gAudioDevice.pCDPlayer = NULL;
+#endif
+	   break;
+   case MUSIC_OGG:
+#if PAL_HAS_OGG
+	   gAudioDevice.pCDPlayer = OGG_Init(NULL);
+#else
+	   gAudioDevice.pCDPlayer = NULL;
+#endif
+	   break;
+   }
+
+   //
+   // Let the callback function run so that musics will be played.
+   //
+   SDL_PauseAudio(0);
+
+   return 0;
+}
+
+VOID
+AUDIO_CloseDevice(
+   VOID
+)
+/*++
+  Purpose:
+
+    Close the audio subsystem.
+
+  Parameters:
+
+    None.
+
+  Return value:
+
+    None.
+
+--*/
+{
+   SDL_CloseAudio();
+
+   SDL_mutexP(gAudioDevice.mtx);
+
+   if (gAudioDevice.pSoundPlayer != NULL)
+   {
+      gAudioDevice.pSoundPlayer->Shutdown(gAudioDevice.pSoundPlayer);
+      gAudioDevice.pSoundPlayer = NULL;
+   }
+
+   if (gAudioDevice.pMusPlayer)
+   {
+	   gAudioDevice.pMusPlayer->Shutdown(gAudioDevice.pMusPlayer);
+	   gAudioDevice.pMusPlayer = NULL;
+   }
+
+   if (gAudioDevice.pCDPlayer)
+   {
+	   gAudioDevice.pCDPlayer->Shutdown(gAudioDevice.pCDPlayer);
+	   gAudioDevice.pCDPlayer = NULL;
+   }
+
+#if PAL_HAS_SDLCD
+   if (gAudioDevice.pCD != NULL)
+   {
+      AUDIO_PlayCDTrack(-1);
+      SDL_CDClose(gAudioDevice.pCD);
+   }
+#endif
+
+   if (gAudioDevice.pSoundBuffer != NULL)
+   {
+      free(gAudioDevice.pSoundBuffer);
+	  gAudioDevice.pSoundBuffer = NULL;
+   }
+
+   if (gConfig.eMusicType == MUSIC_MIDI) MIDI_Play(0, FALSE);
+
+   SDL_mutexV(gAudioDevice.mtx);
+   SDL_DestroyMutex(gAudioDevice.mtx);
+}
+
+SDL_AudioSpec*
+AUDIO_GetDeviceSpec(
+	VOID
+)
+{
+	return &gAudioDevice.spec;
+}
+
+static INT
+AUDIO_ChangeVolumeByValue(
+   INT   *iVolume,
+   INT    iValue
+)
+{
+   *iVolume += iValue;
+   if (*iVolume > PAL_MAX_VOLUME)
+      *iVolume = PAL_MAX_VOLUME;
+   else if (*iVolume < 0)
+      *iVolume = 0;
+   return *iVolume;
+}
+
+VOID
+AUDIO_IncreaseVolume(
+   VOID
+)
+/*++
+  Purpose:
+
+    Increase global volume by 3%.
+
+  Parameters:
+
+    None.
+
+  Return value:
+
+    None.
+
+--*/
+{
+   AUDIO_ChangeVolumeByValue(&gConfig.iMusicVolume, 3);
+   AUDIO_ChangeVolumeByValue(&gConfig.iSoundVolume, 3);
+   gAudioDevice.iMusicVolume = gConfig.iMusicVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
+   gAudioDevice.iSoundVolume = gConfig.iSoundVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
+}
+
+VOID
+AUDIO_DecreaseVolume(
+   VOID
+)
+/*++
+  Purpose:
+
+    Decrease global volume by 3%.
+
+  Parameters:
+
+    None.
+
+  Return value:
+
+    None.
+
+--*/
+{
+   AUDIO_ChangeVolumeByValue(&gConfig.iMusicVolume, -3);
+   AUDIO_ChangeVolumeByValue(&gConfig.iSoundVolume, -3);
+   gAudioDevice.iMusicVolume = gConfig.iMusicVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
+   gAudioDevice.iSoundVolume = gConfig.iSoundVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
+}
+
+VOID
+AUDIO_PlaySound(
+   INT    iSoundNum
+)
+/*++
+  Purpose:
+
+    Play a sound in voc.mkf/sounds.mkf file.
+
+  Parameters:
+
+    [IN]  iSoundNum - number of the sound; the absolute value is used.
+
+  Return value:
+
+    None.
+
+--*/
+{
+   SDL_mutexP(gAudioDevice.mtx);
+   if (gAudioDevice.pSoundPlayer)
+   {
+      gAudioDevice.pSoundPlayer->Play(gAudioDevice.pSoundPlayer, iSoundNum, FALSE, 0.0f);
+   }
+   SDL_mutexV(gAudioDevice.mtx);
+}
+
+VOID
+AUDIO_PlayMusic(
+   INT       iNumRIX,
+   BOOL      fLoop,
+   FLOAT     flFadeTime
+)
+{
+   SDL_mutexP(gAudioDevice.mtx);
+   if (gConfig.eMusicType == MUSIC_MIDI)
+   {
+      MIDI_Play(iNumRIX, fLoop);
+   }
+   else if (gAudioDevice.pMusPlayer)
+   {
+      gAudioDevice.pMusPlayer->Play(gAudioDevice.pMusPlayer, iNumRIX, fLoop, flFadeTime);
+   }
+   SDL_mutexV(gAudioDevice.mtx);
+}
+
+BOOL
+AUDIO_PlayCDTrack(
+   INT    iNumTrack
+)
+/*++
+  Purpose:
+
+    Play a CD Audio Track.
+
+  Parameters:
+
+    [IN]  iNumTrack - number of the CD Audio Track.
+
+  Return value:
+
+    TRUE if the track can be played, FALSE if not.
+
+--*/
+{
+	BOOL ret = FALSE;
+#if PAL_HAS_SDLCD
+   if (gAudioDevice.pCD != NULL)
+   {
+      if (CD_INDRIVE(SDL_CDStatus(gAudioDevice.pCD)))
+      {
+         SDL_CDStop(gAudioDevice.pCD);
+
+         if (iNumTrack != -1)
+         {
+            AUDIO_PlayMusic(-1, FALSE, 0);
+
+            if (SDL_CDPlayTracks(gAudioDevice.pCD, iNumTrack - 1, 0, 1, 0) == 0)
+            {
+               return TRUE;
+            }
+         }
+      }
+   }
+#endif
+   SDL_mutexP(gAudioDevice.mtx);
+   if (gAudioDevice.pCDPlayer)
+   {
+	   if (iNumTrack != -1)
+	   {
+		   AUDIO_PlayMusic(-1, FALSE, 0);
+		   ret = gAudioDevice.pCDPlayer->Play(gAudioDevice.pCDPlayer, PAL_CDTRACK_BASE + iNumTrack, TRUE, 0);
+	   }
+	   else
+	   {
+		   ret = gAudioDevice.pCDPlayer->Play(gAudioDevice.pCDPlayer, -1, FALSE, 0);
+	   }
+   }
+   SDL_mutexV(gAudioDevice.mtx);
+
+   return ret;
+}
+
+VOID
+AUDIO_EnableMusic(
+   BOOL   fEnable
+)
+{
+   gAudioDevice.fMusicEnabled = fEnable;
+}
+
+BOOL
+AUDIO_MusicEnabled(
+   VOID
+)
+{
+   return gAudioDevice.fMusicEnabled;
+}
+
+VOID
+AUDIO_EnableSound(
+   BOOL   fEnable
+)
+{
+	gAudioDevice.fSoundEnabled = fEnable;
+}
+
+BOOL
+AUDIO_SoundEnabled(
+   VOID
+)
+{
+   return gAudioDevice.fSoundEnabled;
+}

+ 7 - 7
sound.h

@@ -19,8 +19,8 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
-#ifndef SOUND_H
-#define SOUND_H
+#ifndef AUDIO_H
+#define AUDIO_H
 
 #include "common.h"
 
@@ -39,11 +39,6 @@ AUDIO_CloseDevice(
    VOID
 );
 
-VOID
-AUDIO_PlaySound(
-   INT    iSoundNum
-);
-
 SDL_AudioSpec*
 AUDIO_GetDeviceSpec(
    VOID
@@ -71,6 +66,11 @@ AUDIO_PlayCDTrack(
    INT    iNumTrack
 );
 
+VOID
+AUDIO_PlaySound(
+   INT    iSoundNum
+);
+
 VOID
 AUDIO_EnableMusic(
    BOOL   fEnable

+ 1 - 1
main.h

@@ -32,7 +32,7 @@
 #include "res.h"
 #include "scene.h"
 #include "players.h"
-#include "sound.h"
+#include "audio.h"
 #include "video.h"
 #include "input.h"
 #include "text.h"

+ 4 - 4
mp3play.c

@@ -26,14 +26,14 @@
 
 #if PAL_HAS_MP3
 
-#include "sound.h"
+#include "audio.h"
 #include "players.h"
 #include "resampler.h"
 #include "libmad/music_mad.h"
 
 typedef struct tagMP3PLAYER
 {
-	MUSICPLAYER_COMMONS;
+	AUDIOPLAYER_COMMONS;
 
 	mad_data           *pMP3;
 	INT                 iMusic;
@@ -136,7 +136,7 @@ MP3_Play(
 	}
 }
 
-LPMUSICPLAYER
+LPAUDIOPLAYER
 MP3_Init(
 	LPCSTR szFileName
 	)
@@ -151,7 +151,7 @@ MP3_Init(
 		player->pMP3 = NULL;
 		player->iMusic = -1;
 		player->fLoop = FALSE;
-		return (LPMUSICPLAYER)player;
+		return (LPAUDIOPLAYER)player;
 	}
 	else
 	{

+ 4 - 4
oggplay.c

@@ -26,7 +26,7 @@
 #include "global.h"
 #include "palcfg.h"
 #include "players.h"
-#include "sound.h"
+#include "audio.h"
 #include <math.h>
 #if PAL_HAS_OGG
 #include <vorbis/vorbisfile.h>
@@ -49,7 +49,7 @@
 
 typedef struct tagOGGPLAYER
 {
-	MUSICPLAYER_COMMONS;
+	AUDIOPLAYER_COMMONS;
 
 	ogg_sync_state   oy; /* sync and verify incoming physical bitstream */
 	ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
@@ -470,7 +470,7 @@ OGG_Shutdown(
 	}
 }
 
-LPMUSICPLAYER
+LPAUDIOPLAYER
 OGG_Init(
 	LPCSTR szFileName
 	)
@@ -503,7 +503,7 @@ OGG_Init(
 			}
 		}
 
-		return (LPMUSICPLAYER)player;
+		return (LPAUDIOPLAYER)player;
 	}
 	else
 	{

+ 12 - 7
players.h

@@ -31,19 +31,19 @@ extern "C"
 {
 #endif
 
-typedef struct tagMUSICPLAYER
+typedef struct tagAUDIOPLAYER
 {
-#define MUSICPLAYER_COMMONS \
+#define AUDIOPLAYER_COMMONS \
 	VOID (*Shutdown)(VOID*); \
 	BOOL (*Play)(VOID*, INT, BOOL, FLOAT); \
 	VOID (*FillBuffer)(VOID*, LPBYTE, INT)
 
-	MUSICPLAYER_COMMONS;
-} MUSICPLAYER, *LPMUSICPLAYER;
+	AUDIOPLAYER_COMMONS;
+} AUDIOPLAYER, *LPAUDIOPLAYER;
 
 /* RIX */
 
-LPMUSICPLAYER
+LPAUDIOPLAYER
 RIX_Init(
    LPCSTR     szFileName
 );
@@ -51,7 +51,7 @@ RIX_Init(
 /* OGG */
 #if PAL_HAS_OGG
 
-LPMUSICPLAYER
+LPAUDIOPLAYER
 OGG_Init(
 	LPCSTR    szFileName
 );
@@ -61,13 +61,18 @@ OGG_Init(
 /* MP3 */
 #if PAL_HAS_MP3
 
-LPMUSICPLAYER
+LPAUDIOPLAYER
 MP3_Init(
 	LPCSTR    szFileName
 );
 
 #endif
 
+LPAUDIOPLAYER
+SOUND_Init(
+	VOID
+);
+
 #ifdef __cplusplus
 }
 #endif

+ 2 - 2
resampler.c

@@ -925,10 +925,10 @@ void resampler_remove_sample(void *_r)
     }
 }
 
-/* Get a 16-bit sample without overflow */
+/* Get a 16-bit sample with saturation */
 short resampler_get_and_remove_sample(void *_r)
 {
-	int sample = (int)round(resampler_get_sample(_r) / 256.0);
+	int sample = resampler_get_sample(_r) >> 8;
 	resampler_remove_sample(_r);
 	if (sample > 32767)
 		return 32767;

+ 4 - 4
rixplay.cpp

@@ -24,7 +24,7 @@
 #include "global.h"
 #include "palcfg.h"
 #include "players.h"
-#include "sound.h"
+#include "audio.h"
 
 #include "resampler.h"
 #include "adplug/opl.h"
@@ -35,7 +35,7 @@
 #include "adplug/rix.h"
 
 typedef struct tagRIXPLAYER :
-	public MUSICPLAYER
+	public AUDIOPLAYER
 {
    Copl                      *opl;
    CrixPlayer                *rix;
@@ -64,7 +64,7 @@ RIX_FillBuffer(
 	Purpose:
 
 	Fill the background music into the sound buffer. Called by the SDL sound
-	callback function only (sound.c: SOUND_FillAudio).
+	callback function only (audio.c: AUDIO_FillBuffer).
 
 	Parameters:
 
@@ -373,7 +373,7 @@ RIX_Play(
 	return TRUE;
 }
 
-LPMUSICPLAYER
+LPAUDIOPLAYER
 RIX_Init(
 	LPCSTR     szFileName
 	)

File diff suppressed because it is too large
+ 586 - 754
sound.c


+ 1 - 1
uibattle.c

@@ -613,7 +613,7 @@ PAL_BattleUIPlayerReady(
       gpGlobals->rgPlayerStatus[w][kStatusConfused] == 0 &&
       !g_Battle.UI.fAutoAttack && !gpGlobals->fAutoBattle)
    {
-      SOUND_PlayChannel(78, 1);
+      AUDIO_PlaySound(78);
    }
 #endif
 }

+ 2 - 1
win32/sdlpal.vcxproj

@@ -227,6 +227,7 @@
       <OmitFramePointers Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</OmitFramePointers>
     </ClCompile>
     <ClCompile Include="..\adplug\demuopl.cpp" />
+    <ClCompile Include="..\audio.c" />
     <ClCompile Include="..\battle.c" />
     <ClCompile Include="..\ending.c" />
     <ClCompile Include="..\fight.c" />
@@ -387,7 +388,7 @@
     <ClInclude Include="..\rngplay.h" />
     <ClInclude Include="..\scene.h" />
     <ClInclude Include="..\script.h" />
-    <ClInclude Include="..\sound.h" />
+    <ClInclude Include="..\audio.h" />
     <ClInclude Include="..\text.h" />
     <ClInclude Include="..\ui.h" />
     <ClInclude Include="..\uibattle.h" />

+ 6 - 3
win32/sdlpal.vcxproj.filters

@@ -308,6 +308,9 @@
     <ClCompile Include="..\palcfg.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\audio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\ascii.h">
@@ -373,9 +376,6 @@
     <ClInclude Include="..\script.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\sound.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="..\text.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -649,6 +649,9 @@
     <ClInclude Include="..\palcfg.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\audio.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\sdlpal.ico">