[mupen64plus-audio-sdl] 02/163: Imported Upstream version 1.99.2

Sven Eckelmann ecsv-guest at moszumanska.debian.org
Thu Nov 26 05:53:00 UTC 2015


This is an automated email from the git hooks/post-receive script.

ecsv-guest pushed a commit to branch armhf_test
in repository mupen64plus-audio-sdl.

commit b3a4b38ef92ed2050025f30ed780ea71dde40154
Author: Sven Eckelmann <sven.eckelmann at gmx.de>
Date:   Sat Feb 13 01:41:55 2010 +0100

    Imported Upstream version 1.99.2
---
 .hg_archival.txt                            |   2 +-
 .hgtags                                     |   2 +
 RELEASE                                     |  13 +
 projects/msvc8/mupen64plus-audio-sdl.vcproj | 213 +++++++++++++++
 projects/unix/Makefile                      |  42 +--
 src/main.c                                  | 384 ++++++++++++++++------------
 src/main.h                                  |   2 +-
 src/osal_dynamiclib_win32.c                 |  74 ++++++
 src/{main.h => osal_preproc.h}              |  31 +--
 src/volume.c                                |  11 +-
 10 files changed, 560 insertions(+), 214 deletions(-)

diff --git a/.hg_archival.txt b/.hg_archival.txt
index d810634..c31e991 100644
--- a/.hg_archival.txt
+++ b/.hg_archival.txt
@@ -1,2 +1,2 @@
 repo: e41300f623483c2381899a457deb6435027bad09
-node: 5203c76b1bc83c58c17a7b970e3d2010687a11e2
+node: e81e77cbb0d62ebe4496ae6a614d7c3214d68fd7
diff --git a/.hgtags b/.hgtags
new file mode 100644
index 0000000..2885044
--- /dev/null
+++ b/.hgtags
@@ -0,0 +1,2 @@
+5203c76b1bc83c58c17a7b970e3d2010687a11e2 1.99.1
+3c4beee185882db04e88382fd30585f1e50639ef 1.99.2
diff --git a/RELEASE b/RELEASE
index d339540..fbb4448 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1,6 +1,19 @@
 SDL Audio plugin for Mupen64Plus
 ---------------------------------
 
+Mupen64Plus-audio-sdl v1.99.2 - January 6, 2010
+-------------------------------------------------
+ - new feature: Completely re-wrote buffering/synchronization code:
+   - Buffer parameters now work as advertised and all use the same units
+   - Bugfix: previous defaults and algorithm behavior caused audio choppiness on slower PCs
+   - Bugfix: maximum speed was previously limited to low value by constraints from primary buffer size
+ - bugfix: SDL volume control will always be used on systems without OSS support
+ - new feature: added MSVC8 project file, minor code refactoring to build in Windows
+ - Makefile improvements:
+   - throw error if OS/CPU not supported
+   - use DESTDIR in install/uninstall paths
+   - Allow user-specified CC/CXX/LD paths
+
 Mupen64Plus-audio-sdl v1.99.1 - December 14, 2009
 -------------------------------------------------
  - Converted to new Mupen64Plus 2.0 API
diff --git a/projects/msvc8/mupen64plus-audio-sdl.vcproj b/projects/msvc8/mupen64plus-audio-sdl.vcproj
new file mode 100644
index 0000000..6a6d9db
--- /dev/null
+++ b/projects/msvc8/mupen64plus-audio-sdl.vcproj
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="mupen64plus-audio-sdl"
+	ProjectGUID="{96969748-EA54-43FC-8103-A346E9AD98E7}"
+	RootNamespace="mupen64plusaudiosdl"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\..\src\main.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\osal_dynamiclib_win32.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\..\src\main.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\osal_dynamiclib.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\osal_preproc.h"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/projects/unix/Makefile b/projects/unix/Makefile
index 82e221a..f872fd3 100644
--- a/projects/unix/Makefile
+++ b/projects/unix/Makefile
@@ -23,6 +23,7 @@
 
 # detect operation system
 UNAME = $(shell uname -s)
+OS := NONE
 ifeq ("$(UNAME)","Linux")
   OS = LINUX
   SHARED = -shared
@@ -43,10 +44,14 @@ ifeq ("$(UNAME)","FreeBSD")
   SHARED = -shared
   SO_EXTENSION = so
 endif
+ifeq ("$(OS)","NONE")
+  $(error OS type "$(UNAME)" not supported.  Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
+endif
 
 # detect system architecture
 HOST_CPU ?= $(shell uname -m)
 NO_ASM ?= 1
+CPU := NONE
 ifneq ("$(filter x86_64 amd64,$(HOST_CPU))","")
   CPU := X86
   ifeq ("$(BITS)", "32")
@@ -59,13 +64,17 @@ ifneq ("$(filter pentium i%86,$(HOST_CPU))","")
   CPU := X86
   ARCH_DETECTED := 32BITS
 endif
-ifneq ("$(filter ppc powerpc,$(HOST_CPU))","")
-  CPU := PPC
-  ARCH_DETECTED := 32BITS
-endif
-ifneq ("$(filter ppc64 powerpc64,$(HOST_CPU))","")
-  CPU := PPC
-  ARCH_DETECTED := 64BITS
+# PPC doesn't work yet
+#ifneq ("$(filter ppc powerpc,$(HOST_CPU))","")
+#  CPU := PPC
+#  ARCH_DETECTED := 32BITS
+#endif
+#ifneq ("$(filter ppc64 powerpc64,$(HOST_CPU))","")
+#  CPU := PPC
+#  ARCH_DETECTED := 64BITS
+#endif
+ifeq ("$(CPU)","NONE")
+  $(error CPU type "$(HOST_CPU)" not supported.  Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
 endif
 
 # base CFLAGS, LIBS, and LDFLAGS
@@ -165,15 +174,15 @@ else
 endif
 
 # set shell function names
-CC      = gcc
-CXX     = g++
-LD      = g++
-INSTALL = install
+CC      ?= gcc
+CXX     ?= g++
+LD      ?= g++
+INSTALL ?= install
 ifeq ($(OS),LINUX)
-  STRIP	= strip -s
+  STRIP	?= strip -s
 endif
 ifeq ($(OS),OSX)
-  STRIP	= strip -x 
+  STRIP	?= strip -x 
 endif
 
 # set special flags for given Makefile parameters
@@ -221,6 +230,7 @@ targets:
 	@echo "  Install Options:"
 	@echo "    PREFIX=path   == install/uninstall prefix (default: /usr/local)"
 	@echo "    LIBDIR=path   == path to install plugin libraries (default: PREFIX/lib/mupen64plus)"
+	@echo "    DESTDIR=path  == path to prepend to all installation paths (only for packagers)"
 	@echo "  Debugging Options:"
 	@echo "    DEBUG=1       == add debugging symbols"
 
@@ -228,11 +238,11 @@ targets:
 all: $(TARGET)
 
 install: $(TARGET)
-	$(INSTALL) -d -v "$(LIBDIR)"
-	$(INSTALL) -m 0644 $(TARGET) "$(LIBDIR)"
+	$(INSTALL) -d -v "$(DESTDIR)$(LIBDIR)"
+	$(INSTALL) -m 0644 $(TARGET) "$(DESTDIR)$(LIBDIR)"
 
 uninstall:
-	rm -f "$(LIBDIR)/$(TARGET)"
+	rm -f "$(DESTDIR)$(LIBDIR)/$(TARGET)"
 
 clean:
 	rm -rf ./_obj/* $(TARGET)
diff --git a/src/main.c b/src/main.c
index 265b63f..dfc056c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -40,37 +40,35 @@
 #include "main.h"
 #include "volume.h"
 #include "osal_dynamiclib.h"
-
-/* Size of primary buffer in bytes. This is the buffer where audio is loaded
-after it's extracted from n64's memory. */
-#define PRIMARY_BUFFER_SIZE 65536
-
-/* If buffer load goes under LOW_BUFFER_LOAD_LEVEL then game is speeded up to
-fill the buffer. If buffer load exeeds HIGH_BUFFER_LOAD_LEVEL then some
-extra slowdown is added to prevent buffer overflow (which is not supposed
-to happen in any circumstanses if syncronization is working but because
-computer's clock is such inaccurate (10ms) that might happen. I'm planning
-to add support for Real Time Clock for greater accuracy but we will see.
-
-The plugin tries to keep the buffer's load always between these values.
-So if you change only PRIMARY_BUFFER_SIZE, nothing changes. You have to
-adjust these values instead. You propably want to play with
-LOW_BUFFER_LOAD_LEVEL if you get dropouts. */
-#define LOW_BUFFER_LOAD_LEVEL 16384
-#define HIGH_BUFFER_LOAD_LEVEL 32768
-
-/* Size of secondary buffer. This is actually SDL's hardware buffer. This is
-amount of samples, so final bufffer size is four times this. */
-#define SECONDARY_BUFFER_SIZE 4096
+#include "osal_preproc.h"
+
+/* Default start-time size of primary buffer (in equivalent output samples).
+   This is the buffer where audio is loaded after it's extracted from n64's memory.
+   This value must be larger than PRIMARY_BUFFER_TARGET */
+#define PRIMARY_BUFFER_SIZE 16384
+
+/* this is the buffer fullness level (in equivalent output samples) which is targeted
+   for the primary audio buffer (by inserting delays) each time data is received from
+   the running N64 program.  This value must be larger than the SECONDARY_BUFFER_SIZE.
+   Decreasing this value will reduce audio latency but requires a faster PC to avoid
+   choppiness. Increasing this will increase audio latency but reduce the chance of
+   drop-outs. The default value 10240 gives a 232ms maximum A/V delay at 44.1khz */
+#define PRIMARY_BUFFER_TARGET 10240
+
+/* Size of secondary buffer, in output samples. This is the requested size of SDL's
+   hardware buffer, and the size of the mix buffer for doing SDL volume control. The
+   SDL documentation states that this should be a power of two between 512 and 8192. */
+#define SECONDARY_BUFFER_SIZE 2048
 
 /* This sets default frequency what is used if rom doesn't want to change it.
-Popably only game that needs this is Zelda: Ocarina Of Time Master Quest 
-*NOTICE* We should try to find out why Demos' frequencies are always wrong
-They tend to rely on a default frequency, apparently, never the same one ;)*/
+   Probably only game that needs this is Zelda: Ocarina Of Time Master Quest 
+   *NOTICE* We should try to find out why Demos' frequencies are always wrong
+   They tend to rely on a default frequency, apparently, never the same one ;)*/
 #define DEFAULT_FREQUENCY 33600
 
-/* Name of config file */
-#define CONFIG_FILE "jttl_audio.conf"
+/* number of bytes per sample */
+#define N64_SAMPLE_BYTES 4
+#define SDL_SAMPLE_BYTES 4
 
 /* volume mixer types */
 #define VOLUME_TYPE_SDL     1
@@ -86,29 +84,26 @@ static AUDIO_INFO AudioInfo;
 /* The hardware specifications we are using */
 static SDL_AudioSpec *hardware_spec;
 /* Pointer to the primary audio buffer */
-static unsigned char *buffer = NULL;
+static unsigned char *primaryBuffer = NULL;
+static unsigned int primaryBufferBytes = 0;
 /* Pointer to the mixing buffer for voume control*/
 static unsigned char *mixBuffer = NULL;
 /* Position in buffer array where next audio chunk should be placed */
 static unsigned int buffer_pos = 0;
 /* Audio frequency, this is usually obtained from the game, but for compatibility we set default value */
 static int GameFreq = DEFAULT_FREQUENCY;
-/* This is for syncronization, it's ticks saved just before AiLenChanged() returns. */
-static unsigned int last_ticks = 0;
+/* timestamp for the last time that our audio callback was called */
+static unsigned int last_callback_ticks = 0;
 /* SpeedFactor is used to increase/decrease game playback speed */
 static unsigned int speed_factor = 100;
-// AI_LEN_REG at previous round */
-static unsigned int prev_len_reg = 0;
 // If this is true then left and right channels are swapped */
 static int SwapChannels = 0;
-// Size of Primary audio buffer
+// Size of Primary audio buffer in equivalent output samples
 static unsigned int PrimaryBufferSize = PRIMARY_BUFFER_SIZE;
-// Size of Secondary audio buffer
+// Fullness level target for Primary audio buffer, in equivalent output samples
+static unsigned int PrimaryBufferTarget = PRIMARY_BUFFER_TARGET;
+// Size of Secondary audio buffer in output samples
 static unsigned int SecondaryBufferSize = SECONDARY_BUFFER_SIZE;
-// Lowest buffer load before we need to speed things up
-static unsigned int LowBufferLoadLevel = LOW_BUFFER_LOAD_LEVEL;
-// Highest buffer load before we need to slow things down
-static unsigned int HighBufferLoadLevel = HIGH_BUFFER_LOAD_LEVEL;
 // Resample or not
 static unsigned char Resample = 1;
 // volume to scale the audio by, range of 0..100
@@ -124,6 +119,8 @@ static int VolumeControlType = VOLUME_TYPE_OSS;
 
 static int OutputFreq;
 
+// Prototype of local functions
+static void my_audio_callback(void *userdata, unsigned char *stream, int len);
 static void InitializeAudio(int freq);
 static void ReadConfig();
 static void InitializeSDL();
@@ -263,19 +260,22 @@ EXPORT void CALL AiDacrateChanged( int SystemType )
 
 EXPORT void CALL AiLenChanged( void )
 {
+    static int PausedForSync = 1; /* Audio is started in paused state after SDL initialization */
+    unsigned int LenReg;
+    unsigned char *p;
+    unsigned int CurrLevel, CurrTime, ExpectedLevel, ExpectedTime;
+
     if (critical_failure == 1)
         return;
     if (!l_PluginInit)
         return;
 
-    unsigned int LenReg = *AudioInfo.AI_LEN_REG;
-    unsigned char *p = (unsigned char*)(AudioInfo.RDRAM + (*AudioInfo.AI_DRAM_ADDR_REG & 0xFFFFFF));
-
-    DebugMessage(M64MSG_VERBOSE, "AiLenChanged(): New audio chunk, %i bytes", LenReg);
+    LenReg = *AudioInfo.AI_LEN_REG;
+    p = (unsigned char*)(AudioInfo.RDRAM + (*AudioInfo.AI_DRAM_ADDR_REG & 0xFFFFFF));
 
-    if(buffer_pos + LenReg  < PrimaryBufferSize)
+    if (buffer_pos + LenReg < primaryBufferBytes)
     {
-        register unsigned int i;
+        unsigned int i;
 
         SDL_LockAudio();
         for ( i = 0 ; i < LenReg ; i += 4 )
@@ -284,20 +284,20 @@ EXPORT void CALL AiLenChanged( void )
             if(SwapChannels == 0)
             {
                 // Left channel
-                buffer[ buffer_pos + i ] = p[ i + 2 ];
-                buffer[ buffer_pos + i + 1 ] = p[ i + 3 ];
+                primaryBuffer[ buffer_pos + i ] = p[ i + 2 ];
+                primaryBuffer[ buffer_pos + i + 1 ] = p[ i + 3 ];
 
                 // Right channel
-                buffer[ buffer_pos + i + 2 ] = p[ i ];
-                buffer[ buffer_pos + i + 3 ] = p[ i + 1 ];
+                primaryBuffer[ buffer_pos + i + 2 ] = p[ i ];
+                primaryBuffer[ buffer_pos + i + 3 ] = p[ i + 1 ];
             } else {
                 // Left channel
-                buffer[ buffer_pos + i ] = p[ i ];
-                buffer[ buffer_pos + i + 1 ] = p[ i + 1 ];
+                primaryBuffer[ buffer_pos + i ] = p[ i ];
+                primaryBuffer[ buffer_pos + i + 1 ] = p[ i + 1 ];
 
                 // Right channel
-                buffer[ buffer_pos + i + 2 ] = p[ i + 2];
-                buffer[ buffer_pos + i + 3 ] = p[ i + 3 ];
+                primaryBuffer[ buffer_pos + i + 2 ] = p[ i + 2];
+                primaryBuffer[ buffer_pos + i + 3 ] = p[ i + 3 ];
             }
         }
         buffer_pos += i;
@@ -305,54 +305,48 @@ EXPORT void CALL AiLenChanged( void )
     }
     else
     {
-        DebugMessage(M64MSG_VERBOSE, "AiLenChanged(): Audio buffer overflow.");
-    }
-
-    // Time that should be sleeped to keep game in sync.
-    int wait_time = 0;
-
-    // And then syncronization */
-
-    /* If buffer is running slow we speed up the game a bit. Actually we skip the syncronization. */
-    if (buffer_pos < LowBufferLoadLevel)
-    {
-        wait_time = -1;
-        if(buffer_pos < SecondaryBufferSize*4)
-          SDL_PauseAudio(1);
-    }
+        DebugMessage(M64MSG_WARNING, "AiLenChanged(): Audio buffer overflow.");
+    }
+
+    /* Now we need to handle synchronization, by inserting time delay to keep the emulator running at the correct speed */
+    /* Start by calculating the current Primary buffer fullness in terms of output samples */
+    CurrLevel = (unsigned int) (((long long) (buffer_pos/N64_SAMPLE_BYTES) * OutputFreq * 100) / (GameFreq * speed_factor));
+    /* Next, extrapolate to the buffer level at the expected time of the next audio callback, assuming that the
+       buffer is filled at the same rate as the output frequency */
+    CurrTime = SDL_GetTicks();
+    ExpectedTime = last_callback_ticks + ((1000 * SecondaryBufferSize) / OutputFreq);
+    ExpectedLevel = CurrLevel;
+    if (CurrTime < ExpectedTime)
+        ExpectedLevel += (ExpectedTime - CurrTime) * OutputFreq / 1000;
+    /* If the expected value of the Primary Buffer Fullness at the time of the next audio callback is more than 10
+       milliseconds ahead of our target buffer fullness level, then insert a delay now */
+    DebugMessage(M64MSG_VERBOSE, "%03i New audio bytes: %i  Time to next callback: %i  Current/Expected buffer level: %i/%i",
+                 CurrTime % 1000, LenReg, (int) (ExpectedTime - CurrTime), CurrLevel, ExpectedLevel);
+    if (ExpectedLevel >= PrimaryBufferTarget + OutputFreq / 100)
+    {
+        unsigned int WaitTime = (ExpectedLevel - PrimaryBufferTarget) * 1000 / OutputFreq;
+        DebugMessage(M64MSG_VERBOSE, "    AiLenChanged(): Waiting %ims", WaitTime);
+        if (PausedForSync)
+            SDL_PauseAudio(0);
+        PausedForSync = 0;
+        SDL_Delay(WaitTime);
+    }
+    /* Or if the expected level of the primary buffer is less than the secondary buffer size
+       (ie, predicting an underflow), then pause the audio to let the emulator catch up to speed */
+    else if (ExpectedLevel < SecondaryBufferSize)
+    {
+        DebugMessage(M64MSG_VERBOSE, "    AiLenChanged(): Possible underflow at next audio callback; pausing playback");
+        if (!PausedForSync)
+            SDL_PauseAudio(1);
+        PausedForSync = 1;
+    }
+    /* otherwise the predicted buffer level is within our tolerance, so everything is okay */
     else
-        SDL_PauseAudio(0);
-
-    if (wait_time != -1)
     {
-        /* Adjust the game frequency by the playback speed factor for the purposes of timing */
-        int InputFreq = GameFreq * speed_factor / 100;
-
-        /* If for some reason game is runnin extremely fast and there is risk buffer is going to
-           overflow, we slow down the game a bit to keep sound smooth. The overspeed is caused
-           by inaccuracy in machines clock. */
-        if (buffer_pos > HighBufferLoadLevel)
-        {
-            int overflow = (buffer_pos - HIGH_BUFFER_LOAD_LEVEL) / 4; /* in samples */
-            wait_time += overflow * 1000 / InputFreq;                 /* in milliseconds */
-        }
-
-        /* calculate how many milliseconds should have elapsed since the last audio chunk was added */
-        int prev_samples = prev_len_reg / 4;
-        int expected_ticks = prev_samples * 1000 / InputFreq;  /* in milliseconds */
-
-        /* now determine if we are ahead of schedule, and if so, wait */
-        int cur_ticks = SDL_GetTicks();
-        if (last_ticks + expected_ticks > cur_ticks)
-        {
-            wait_time += (last_ticks + expected_ticks) - cur_ticks;
-            DebugMessage(M64MSG_VERBOSE, "AiLenChanged(): wait_time: %i, Buffer: %i/%i", wait_time, buffer_pos, PrimaryBufferSize);
-            SDL_Delay(wait_time);
-        }
+        if (PausedForSync)
+            SDL_PauseAudio(0);
+        PausedForSync = 0;
     }
-
-    last_ticks = SDL_GetTicks();
-    prev_len_reg = LenReg;
 }
 
 EXPORT int CALL InitiateAudio( AUDIO_INFO Audio_Info )
@@ -449,33 +443,44 @@ static int resample(unsigned char *input, int input_avail, int oldsamplerate, un
 
 static void my_audio_callback(void *userdata, unsigned char *stream, int len)
 {
+    int oldsamplerate, newsamplerate;
+
     if (!l_PluginInit)
         return;
 
-    int newsamplerate = OutputFreq * 100 / speed_factor;
-    int oldsamplerate = GameFreq;
+    /* mark the time, for synchronization on the input side */
+    last_callback_ticks = SDL_GetTicks();
+
+    newsamplerate = OutputFreq * 100 / speed_factor;
+    oldsamplerate = GameFreq;
 
-    if (buffer_pos > (len * oldsamplerate) / newsamplerate)
+    if (buffer_pos > (unsigned int) (len * oldsamplerate) / newsamplerate)
     {
         int input_used;
-        if (VolumeControlType == VOLUME_TYPE_SDL)
+#if defined(HAS_OSS_SUPPORT)
+        if (VolumeControlType == VOLUME_TYPE_OSS)
         {
-            input_used = resample(buffer, buffer_pos, oldsamplerate, mixBuffer, len, newsamplerate);
-            SDL_MixAudio(stream, mixBuffer, len, VolSDL);
+            input_used = resample(primaryBuffer, buffer_pos, oldsamplerate, stream, len, newsamplerate);
         }
         else
+#endif
         {
-            input_used = resample(buffer, buffer_pos, oldsamplerate, stream, len, newsamplerate);
+            input_used = resample(primaryBuffer, buffer_pos, oldsamplerate, mixBuffer, len, newsamplerate);
+            SDL_MixAudio(stream, mixBuffer, len, VolSDL);
         }
-        memmove(buffer, &buffer[input_used], buffer_pos - input_used);
+        memmove(primaryBuffer, &primaryBuffer[input_used], buffer_pos - input_used);
         buffer_pos -= input_used;
+        DebugMessage(M64MSG_VERBOSE, "%03i my_audio_callback: used %i samples",
+                     last_callback_ticks % 1000, len / SDL_SAMPLE_BYTES);
     }
     else
     {
+        unsigned int SamplesNeeded = (len * oldsamplerate) / (newsamplerate * SDL_SAMPLE_BYTES);
+        unsigned int SamplesPresent = buffer_pos / N64_SAMPLE_BYTES;
         underrun_count++;
-        DebugMessage(M64MSG_VERBOSE, "Audio buffer underrun (%i).",underrun_count);
+        DebugMessage(M64MSG_VERBOSE, "%03i Buffer underflow (%i).  %i samples present, %i needed",
+                     last_callback_ticks % 1000, underrun_count, SamplesPresent, SamplesNeeded);
         memset(stream , 0, len);
-        buffer_pos = 0;
     }
 }
 EXPORT void CALL RomOpen()
@@ -491,10 +496,9 @@ static void InitializeSDL()
 {
     DebugMessage(M64MSG_INFO, "Initializing SDL audio subsystem...");
 
-    DebugMessage(M64MSG_VERBOSE, "Primary buffer: %i bytes.", PrimaryBufferSize);
-    DebugMessage(M64MSG_VERBOSE, "Secondary buffer: %i bytes.", SecondaryBufferSize * 4);
-    DebugMessage(M64MSG_VERBOSE, "Low buffer level: %i bytes.", LowBufferLoadLevel);
-    DebugMessage(M64MSG_VERBOSE, "High buffer level: %i bytes.", HighBufferLoadLevel);
+    DebugMessage(M64MSG_VERBOSE, "Primary buffer: %i output samples.", PrimaryBufferSize);
+    DebugMessage(M64MSG_VERBOSE, "Primary target fullness: %i output samples.", PrimaryBufferTarget);
+    DebugMessage(M64MSG_VERBOSE, "Secondary buffer: %i output sample.", SecondaryBufferSize);
 
     if(SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0)
     {
@@ -506,8 +510,35 @@ static void InitializeSDL()
 
 }
 
+static void CreatePrimaryBuffer(void)
+{
+    unsigned int newPrimaryBytes = (unsigned int) ((long long) PrimaryBufferSize * GameFreq * speed_factor /
+                                                   (OutputFreq * 100)) * N64_SAMPLE_BYTES;
+    if (primaryBuffer == NULL)
+    {
+        DebugMessage(M64MSG_VERBOSE, "Allocating memory for audio buffer: %i bytes.", newPrimaryBytes);
+        primaryBuffer = (unsigned char*) malloc(newPrimaryBytes);
+        memset(primaryBuffer, 0, newPrimaryBytes);
+        primaryBufferBytes = newPrimaryBytes;
+    }
+    else if (newPrimaryBytes > primaryBufferBytes) /* primary buffer only grows; there's no point in shrinking it */
+    {
+        unsigned char *newPrimaryBuffer = (unsigned char*) malloc(newPrimaryBytes);
+        unsigned char *oldPrimaryBuffer = primaryBuffer;
+        SDL_LockAudio();
+        memcpy(newPrimaryBuffer, oldPrimaryBuffer, primaryBufferBytes);
+        memset(newPrimaryBuffer + primaryBufferBytes, 0, newPrimaryBytes - primaryBufferBytes);
+        primaryBuffer = newPrimaryBuffer;
+        primaryBufferBytes = newPrimaryBytes;
+        SDL_UnlockAudio();
+        free(oldPrimaryBuffer);
+    }
+}
+
 static void InitializeAudio(int freq)
 {
+    SDL_AudioSpec *desired, *obtained;
+    
     if(SDL_WasInit(SDL_INIT_AUDIO|SDL_INIT_TIMER) == (SDL_INIT_AUDIO|SDL_INIT_TIMER) ) 
     {
         DebugMessage(M64MSG_VERBOSE, "Audio and timer already initialized.");
@@ -524,12 +555,6 @@ static void InitializeAudio(int freq)
     SDL_PauseAudio(1);
     SDL_CloseAudio();
 
-    // Prototype of our callback function
-    void my_audio_callback(void *userdata, unsigned char *stream, int len);
-
-    // Open the audio device
-    SDL_AudioSpec *desired, *obtained;
-    
     // Allocate a desired SDL_AudioSpec
     desired = malloc(sizeof(SDL_AudioSpec));
     
@@ -553,34 +578,17 @@ static void InitializeAudio(int freq)
     desired->channels=2;
     /* Large audio buffer reduces risk of dropouts but increases response time */
     desired->samples=SecondaryBufferSize;
-
     /* Our callback function */
     desired->callback=my_audio_callback;
     desired->userdata=NULL;
 
-    if(buffer == NULL)
-    {
-        DebugMessage(M64MSG_VERBOSE, "Allocating memory for audio buffer: %i bytes.", PrimaryBufferSize);
-        buffer = (unsigned char*) malloc(PrimaryBufferSize);
-    }
-
-    if (mixBuffer == NULL)
-    {
-        //this should be the size of the SDL audio buffer
-        mixBuffer = (unsigned char*) malloc(SecondaryBufferSize * 4);
-    }
-
-    memset(buffer, 0, PrimaryBufferSize);
-
     /* Open the audio device */
-    if ( SDL_OpenAudio(desired, obtained) < 0 )
+    if (SDL_OpenAudio(desired, obtained) < 0)
     {
         DebugMessage(M64MSG_ERROR, "Couldn't open audio: %s", SDL_GetError());
         critical_failure = 1;
         return;
     }
-    /* desired spec is no longer needed */
-
     if(desired->format != obtained->format)
     {
         DebugMessage(M64MSG_WARNING, "Obtained audio format differs from requested.");
@@ -589,9 +597,31 @@ static void InitializeAudio(int freq)
     {
         DebugMessage(M64MSG_WARNING, "Obtained frequency differs from requested.");
     }
+
+    /* desired spec is no longer needed */
     free(desired);
     hardware_spec=obtained;
 
+    /* allocate memory for audio buffers */
+    OutputFreq = hardware_spec->freq;
+    SecondaryBufferSize = hardware_spec->samples;
+    if (PrimaryBufferTarget < SecondaryBufferSize)
+        PrimaryBufferTarget = SecondaryBufferSize;
+    if (PrimaryBufferSize < PrimaryBufferTarget)
+        PrimaryBufferSize = PrimaryBufferTarget;
+    if (PrimaryBufferSize < SecondaryBufferSize * 2)
+        PrimaryBufferSize = SecondaryBufferSize * 2;
+    CreatePrimaryBuffer();
+    if (mixBuffer == NULL)
+    {
+        //this should be the size of the SDL audio buffer
+        mixBuffer = (unsigned char*) malloc(SecondaryBufferSize * SDL_SAMPLE_BYTES);
+    }
+
+    /* preset the last callback time */
+    if (last_callback_ticks == 0)
+        last_callback_ticks = SDL_GetTicks();
+
     DebugMessage(M64MSG_VERBOSE, "Frequency: %i", hardware_spec->freq);
     DebugMessage(M64MSG_VERBOSE, "Format: %i", hardware_spec->format);
     DebugMessage(M64MSG_VERBOSE, "Channels: %i", hardware_spec->channels);
@@ -599,16 +629,16 @@ static void InitializeAudio(int freq)
     DebugMessage(M64MSG_VERBOSE, "Samples: %i", hardware_spec->samples);
     DebugMessage(M64MSG_VERBOSE, "Size: %i", hardware_spec->size);
 
-    SDL_PauseAudio(0);
-    
     /* set playback volume */
-    if (VolumeControlType == VOLUME_TYPE_SDL)
+#if defined(HAS_OSS_SUPPORT)
+    if (VolumeControlType == VOLUME_TYPE_OSS)
     {
-        VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
+        VolPercent = volGet();
     }
     else
+#endif
     {
-        VolPercent = volGet();
+        VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
     }
 
 }
@@ -625,10 +655,11 @@ EXPORT void CALL RomClosed( void )
     SDL_CloseAudio();
 
     // Delete the buffer, as we are done producing sound
-    if (buffer != NULL)
+    if (primaryBuffer != NULL)
     {
-        free(buffer);
-        buffer = NULL;
+        primaryBufferBytes = 0;
+        free(primaryBuffer);
+        primaryBuffer = NULL;
     }
     if (mixBuffer != NULL)
     {
@@ -639,7 +670,6 @@ EXPORT void CALL RomClosed( void )
     // Delete the hardware spec struct
     if(hardware_spec != NULL) free(hardware_spec);
     hardware_spec = NULL;
-    buffer = NULL;
 
     // Shutdown the respective subsystems
     if(SDL_WasInit(SDL_INIT_AUDIO) != 0) SDL_QuitSubSystem(SDL_INIT_AUDIO);
@@ -656,6 +686,8 @@ EXPORT void CALL SetSpeedFactor(int percentage)
         return;
     if (percentage >= 10 && percentage <= 300)
         speed_factor = percentage;
+    // we need a different size primary buffer to store the N64 samples when the speed changes
+    CreatePrimaryBuffer();
 }
 
 static void ReadConfig()
@@ -672,10 +704,9 @@ static void ReadConfig()
     /* set the default values for this plugin */
     ConfigSetDefaultInt(ConfigAudio, "DEFAULT_FREQUENCY",     DEFAULT_FREQUENCY,     "Frequency which is used if rom doesn't want to change it");
     ConfigSetDefaultBool(ConfigAudio, "SWAP_CHANNELS",        0,                     "Swaps left and right channels");
-    ConfigSetDefaultInt(ConfigAudio, "PRIMARY_BUFFER_SIZE",   PRIMARY_BUFFER_SIZE,   "Size of primary buffer in bytes. This is where audio is loaded after it's extracted from n64's memory.");
-    ConfigSetDefaultInt(ConfigAudio, "SECONDARY_BUFFER_SIZE", SECONDARY_BUFFER_SIZE, "Size of secondary buffer in samples. This is SDL's hardware buffer."); 
-    ConfigSetDefaultInt(ConfigAudio, "LOW_BUFFER_LOAD_LEVEL", LOW_BUFFER_LOAD_LEVEL, "If the primary buffer level falls below this level, then the audio sync delay is skipped to speed up playback");
-    ConfigSetDefaultInt(ConfigAudio, "HIGH_BUFFER_LOAD_LEVEL",HIGH_BUFFER_LOAD_LEVEL,"If the primary buffer level goes above this level, then extra audio sync delay is inserted reduce the buffer level");
+    ConfigSetDefaultInt(ConfigAudio, "PRIMARY_BUFFER_SIZE",   PRIMARY_BUFFER_SIZE,   "Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory.");
+    ConfigSetDefaultInt(ConfigAudio, "PRIMARY_BUFFER_TARGET", PRIMARY_BUFFER_TARGET, "Fullness level target for Primary audio buffer, in equivalent output samples");
+    ConfigSetDefaultInt(ConfigAudio, "SECONDARY_BUFFER_SIZE", SECONDARY_BUFFER_SIZE, "Size of secondary buffer in output samples. This is SDL's hardware buffer.");
     ConfigSetDefaultInt(ConfigAudio, "RESAMPLE",              1,                     "Audio resampling algorithm.  1 = unfiltered, 2 = SINC resampling (Best Quality, requires libsamplerate)");
     ConfigSetDefaultInt(ConfigAudio, "VOLUME_CONTROL_TYPE",   VOLUME_TYPE_OSS,       "Volume control type: 1 = SDL (only affects Mupen64Plus output)  2 = OSS mixer (adjusts master PC volume)");
     ConfigSetDefaultInt(ConfigAudio, "VOLUME_ADJUST",         5,                     "Percentage change each time the volume is increased or decreased");
@@ -685,9 +716,8 @@ static void ReadConfig()
     GameFreq = ConfigGetParamInt(ConfigAudio, "DEFAULT_FREQUENCY");
     SwapChannels = ConfigGetParamBool(ConfigAudio, "SWAP_CHANNELS");
     PrimaryBufferSize = ConfigGetParamInt(ConfigAudio, "PRIMARY_BUFFER_SIZE");
+    PrimaryBufferTarget = ConfigGetParamInt(ConfigAudio, "PRIMARY_BUFFER_TARGET");
     SecondaryBufferSize = ConfigGetParamInt(ConfigAudio, "SECONDARY_BUFFER_SIZE");
-    LowBufferLoadLevel = ConfigGetParamInt(ConfigAudio, "LOW_BUFFER_LOAD_LEVEL");
-    HighBufferLoadLevel = ConfigGetParamInt(ConfigAudio, "HIGH_BUFFER_LOAD_LEVEL");
     Resample = ConfigGetParamInt(ConfigAudio, "RESAMPLE");
     VolumeControlType = ConfigGetParamInt(ConfigAudio, "VOLUME_CONTROL_TYPE");
     VolDelta = ConfigGetParamInt(ConfigAudio, "VOLUME_ADJUST");
@@ -704,14 +734,16 @@ EXPORT void CALL VolumeMute(void)
         //unmute
         VolPercent = VolMutedSave;
         VolMutedSave = -1;
-        if (VolumeControlType == VOLUME_TYPE_SDL)
+#if defined(HAS_OSS_SUPPORT)
+        if (VolumeControlType == VOLUME_TYPE_OSS)
         {
-            VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
+            //OSS mixer volume
+            volSet(VolPercent);
         }
         else
+#endif
         {
-            //OSS mixer volume
-            volSet(VolPercent);
+            VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
         }
     } 
     else
@@ -719,14 +751,16 @@ EXPORT void CALL VolumeMute(void)
         //mute
         VolMutedSave = VolPercent;
         VolPercent = 0;
-        if (VolumeControlType == VOLUME_TYPE_SDL)
+#if defined(HAS_OSS_SUPPORT)
+        if (VolumeControlType == VOLUME_TYPE_OSS)
         {
-            VolSDL = 0;
+            //OSS mixer volume
+            volSet(0);
         }
         else
+#endif
         {
-            //OSS mixer volume
-            volSet(0);
+            VolSDL = 0;
         }
     }
 }
@@ -740,25 +774,29 @@ EXPORT void CALL VolumeUp(void)
     if (VolMutedSave > -1)
         VolumeMute();
 
+#if defined(HAS_OSS_SUPPORT)
     // reload volume if we're using OSS
     if (VolumeControlType == VOLUME_TYPE_OSS)
     {
         VolPercent = volGet();
     }
+#endif
 
     // adjust volume variable
     VolPercent += VolDelta;
     if (VolPercent > 100)
         VolPercent = 100;
 
-    if (VolumeControlType == VOLUME_TYPE_SDL) 
+#if defined(HAS_OSS_SUPPORT)
+    if (VolumeControlType == VOLUME_TYPE_OSS)
     {
-        VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
+        //OSS mixer volume
+        volSet(VolPercent);
     }
     else
+#endif
     {
-        //OSS mixer volume
-        volSet(VolPercent);
+        VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
     }
 }
 
@@ -771,25 +809,29 @@ EXPORT void CALL VolumeDown(void)
     if (VolMutedSave > -1)
         VolumeMute();
 
+#if defined(HAS_OSS_SUPPORT)
     // reload volume if we're using OSS
     if (VolumeControlType == VOLUME_TYPE_OSS)
     {
         VolPercent = volGet();
     }
+#endif
 
     // adjust volume variable
     VolPercent -= VolDelta;
     if (VolPercent < 0)
         VolPercent = 0;
 
-    if (VolumeControlType == VOLUME_TYPE_SDL)
+#if defined(HAS_OSS_SUPPORT)
+    if (VolumeControlType == VOLUME_TYPE_OSS)
     {
-        VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
+        //OSS mixer volume
+        volSet(VolPercent);
     }
     else
+#endif
     {
-        //OSS mixer volume
-        volSet(VolPercent);
+        VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
     }
 }
 
@@ -810,14 +852,16 @@ EXPORT void CALL VolumeSetLevel(int level)
     else if (VolPercent > 100)
         VolPercent = 100;
 
-    if (VolumeControlType == VOLUME_TYPE_SDL)
+#if defined(HAS_OSS_SUPPORT)
+    if (VolumeControlType == VOLUME_TYPE_OSS)
     {
-        VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
+        //OSS mixer volume
+        volSet(VolPercent);
     }
     else
+#endif
     {
-        //OSS mixer volume
-        volSet(VolPercent);
+        VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
     }
 }
 
diff --git a/src/main.h b/src/main.h
index f69ff61..cd11452 100644
--- a/src/main.h
+++ b/src/main.h
@@ -20,7 +20,7 @@
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 /* version info */
-#define SDL_AUDIO_PLUGIN_VERSION 0x016301
+#define SDL_AUDIO_PLUGIN_VERSION 0x016302
 
 /* declarations of pointers to Core config functions */
 extern ptr_ConfigListSections     ConfigListSections;
diff --git a/src/osal_dynamiclib_win32.c b/src/osal_dynamiclib_win32.c
new file mode 100644
index 0000000..4455cee
--- /dev/null
+++ b/src/osal_dynamiclib_win32.c
@@ -0,0 +1,74 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *   Mupen64plus-ui-console - osal_dynamiclib_win32.c                      *
+ *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
+ *   Copyright (C) 2009 Richard Goedeken                                   *
+ *                                                                         *
+ *   This program 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 2 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, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "m64p_types.h"
+#include "osal_dynamiclib.h"
+
+m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath)
+{
+    if (pLibHandle == NULL || pccLibraryPath == NULL)
+        return M64ERR_INPUT_ASSERT;
+
+    *pLibHandle = LoadLibrary(pccLibraryPath);
+
+    if (*pLibHandle == NULL)
+    {
+        char *pchErrMsg;
+        DWORD dwErr = GetLastError(); 
+        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
+                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
+        fprintf(stderr, "LoadLibrary('%s') error: %s\n", pccLibraryPath, pchErrMsg);
+        LocalFree(pchErrMsg);
+        return M64ERR_INPUT_NOT_FOUND;
+    }
+
+    return M64ERR_SUCCESS;
+}
+
+void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
+{
+    if (pccProcedureName == NULL)
+        return NULL;
+
+    return GetProcAddress(LibHandle, pccProcedureName);
+}
+
+m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle)
+{
+    int rval = FreeLibrary(LibHandle);
+
+    if (rval == 0)
+    {
+        char *pchErrMsg;
+        DWORD dwErr = GetLastError(); 
+        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
+                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
+        fprintf(stderr, "FreeLibrary() error: %s\n", pchErrMsg);
+        LocalFree(pchErrMsg);
+        return M64ERR_INTERNAL;
+    }
+
+    return M64ERR_SUCCESS;
+}
diff --git a/src/main.h b/src/osal_preproc.h
similarity index 57%
copy from src/main.h
copy to src/osal_preproc.h
index f69ff61..26e724d 100644
--- a/src/main.h
+++ b/src/osal_preproc.h
@@ -1,7 +1,8 @@
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- *   Mupen64plus - main.h                                                  *
+ *   Mupen64plus - osal_preproc.h                                          *
  *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
- *   Copyright (C) 2008 Tillin9                                            *
+ *   Copyright (C) 2009 Richard Goedeken                                   *
+ *   Copyright (C) 2002 Hacktarux                                          *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -19,23 +20,13 @@
  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-/* version info */
-#define SDL_AUDIO_PLUGIN_VERSION 0x016301
+/* this header file is for system-dependent #defines, #includes, and typedefs */
 
-/* declarations of pointers to Core config functions */
-extern ptr_ConfigListSections     ConfigListSections;
-extern ptr_ConfigOpenSection      ConfigOpenSection;
-extern ptr_ConfigListParameters   ConfigListParameters;
-extern ptr_ConfigSaveFile         ConfigSaveFile;
-extern ptr_ConfigSetParameter     ConfigSetParameter;
-extern ptr_ConfigGetParameter     ConfigGetParameter;
-extern ptr_ConfigGetParameterHelp ConfigGetParameterHelp;
-extern ptr_ConfigSetDefaultInt    ConfigSetDefaultInt;
-extern ptr_ConfigSetDefaultFloat  ConfigSetDefaultFloat;
-extern ptr_ConfigSetDefaultBool   ConfigSetDefaultBool;
-extern ptr_ConfigSetDefaultString ConfigSetDefaultString;
-extern ptr_ConfigGetParamInt      ConfigGetParamInt;
-extern ptr_ConfigGetParamFloat    ConfigGetParamFloat;
-extern ptr_ConfigGetParamBool     ConfigGetParamBool;
-extern ptr_ConfigGetParamString   ConfigGetParamString;
+#if !defined(OSAL_PREPROC_H)
+#define OSAL_PREPROC_H
 
+#if defined(__linux__)
+  #define HAS_OSS_SUPPORT
+#endif
+
+#endif // OSAL_PREPROC_H
\ No newline at end of file
diff --git a/src/volume.c b/src/volume.c
index 5cf46ec..d172561 100644
--- a/src/volume.c
+++ b/src/volume.c
@@ -20,10 +20,12 @@
  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
+#include "osal_preproc.h"
+
+#if defined(HAS_OSS_SUPPORT)
+
 /* Sound volume functions. */
-#if defined(__linux__)
 #include <sys/soundcard.h>
-#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
@@ -54,9 +56,7 @@ void volSet(int percent)
         percent = 0;
 
     vol = (percent << 8) + percent; // set both left/right channels to same vol
-#if defined(__linux__)
     ret = ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_PCM), &vol);
-#endif
     if(ret < 0)
         perror("Setting PCM volume: ");
 
@@ -78,9 +78,7 @@ int volGet(void)
         return 0;
     }
 
-#if defined(__linux__)
     ret = ioctl(mixerfd, MIXER_READ(SOUND_MIXER_PCM), &vol);
-#endif
     if(ret < 0)
         perror("Reading PCM volume: ");
 
@@ -89,3 +87,4 @@ int volGet(void)
     return vol & 0xff; // just return the left channel
 }
 
+#endif /* defined(HAS_OSS_SUPPORT) */

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/mupen64plus-audio-sdl.git



More information about the Pkg-games-commits mailing list