Blob Blame History Raw
diff --git a/src/common/ConfigManager.cpp b/src/common/ConfigManager.cpp
index dafdb72..06752e4 100644
--- a/src/common/ConfigManager.cpp
+++ b/src/common/ConfigManager.cpp
@@ -220,6 +220,7 @@ int speedupToggle;
 int sunBars;
 int surfaceSizeX;
 int surfaceSizeY;
+int synchronize = false;
 int threadPriority;
 int tripleBuffering;
 int useBios = 0;
@@ -522,6 +523,7 @@ void LoadConfig()
 	soundFiltering = (float)ReadPref("gbaSoundFiltering", 50) / 100.0f;
 	soundInterpolation = ReadPref("gbaSoundInterpolation", 1);
 	soundRecordDir = ReadPrefString("soundRecordDir");
+	synchronize = ReadPref("synchronize", 1);
 	threadPriority = ReadPref("priority", 2);
 	throttle = ReadPref("throttle", 100);
 	tripleBuffering = ReadPref("tripleBuffering", 0);
@@ -1038,6 +1040,13 @@ int ReadOpts(int argc, char ** argv)
 			}
 			break;
 
+		case OPT_SYNCHRONIZE:
+			// --synchronize
+			if (optarg) {
+				synchronize = atoi(optarg);
+			}
+			break;
+
 		case OPT_VIDEO_OPTION:
 			// --video-option
 			if (optarg) {
diff --git a/src/common/ConfigManager.h b/src/common/ConfigManager.h
index e6a1008..034ceed 100644
--- a/src/common/ConfigManager.h
+++ b/src/common/ConfigManager.h
@@ -119,6 +119,7 @@ extern int speedupToggle;
 extern int sunBars;
 extern int surfaceSizeX;
 extern int surfaceSizeY;
+extern int synchronize;
 extern int threadPriority;
 extern int tripleBuffering;
 extern int useBios;
diff --git a/src/common/SoundSDL.cpp b/src/common/SoundSDL.cpp
index 9713d44..09c46a7 100644
--- a/src/common/SoundSDL.cpp
+++ b/src/common/SoundSDL.cpp
@@ -18,17 +18,15 @@
 #include "SoundSDL.h"
 #include "ConfigManager.h"
 #include "../gba/Globals.h"
-#include "../gba/Sound.h"
 
 extern int emulating;
 
-// Hold up to 32 ms of data in the ring buffer
-const float SoundSDL::_delay = 0.032f;
+// Hold up to 100 ms of data in the ring buffer
+const float SoundSDL::_delay = 0.1f;
 
 SoundSDL::SoundSDL():
 	_rbuf(0),
 	_dev(-1),
-	current_rate(0),
 	_initialized(false)
 {
 
@@ -48,7 +46,7 @@ void SoundSDL::read(uint16_t * stream, int length)
 	/* since this is running in a different thread, speedup and
 	 * throttle can change at any time; save the value so locks
 	 * stay in sync */
-	bool lock = (emulating && !speedup && throttle && !gba_joybus_active) ? true : false;
+	bool lock = (emulating && !speedup && synchronize && !gba_joybus_active) ? true : false;
 
 	if (lock)
 		SDL_SemWait (_semBufferFull);
@@ -77,7 +75,7 @@ void SoundSDL::write(uint16_t * finalWave, int length)
 	std::size_t avail;
 	while ((avail = _rbuf.avail() / 2) < samples)
 	{
-		bool lock = (emulating && !speedup && throttle && !gba_joybus_active) ? true : false;
+		bool lock = (emulating && !speedup && synchronize && !gba_joybus_active) ? true : false;
 
 		_rbuf.write(finalWave, avail * 2);
 
@@ -89,12 +87,6 @@ void SoundSDL::write(uint16_t * finalWave, int length)
 		if (lock)
 		{
 			SDL_SemWait(_semBufferEmpty);
-			if (throttle > 0 && throttle != current_rate)
-			{
-				SDL_CloseAudio();
-				init(soundGetSampleRate() * throttle / 100);
-				current_rate = throttle;
-			}
 		}
 		else
 		{
@@ -131,13 +123,10 @@ bool SoundSDL::init(long sampleRate)
 
 	_rbuf.reset(_delay * sampleRate * 2);
 
-	if (!_initialized)
-	{
-		_mutex = SDL_CreateMutex();
-		_semBufferFull  = SDL_CreateSemaphore (0);
-		_semBufferEmpty = SDL_CreateSemaphore (1);
-		_initialized    = true;
-	}
+	_mutex          = SDL_CreateMutex();
+	_semBufferFull  = SDL_CreateSemaphore (0);
+	_semBufferEmpty = SDL_CreateSemaphore (1);
+	_initialized    = true;
 
 	return true;
 }
@@ -165,8 +154,6 @@ SoundSDL::~SoundSDL()
 	SDL_CloseAudioDevice(_dev);
 
 	emulating = iSave;
-
-	_initialized = false;
 }
 
 void SoundSDL::pause()
diff --git a/src/wx/cmdevents.cpp b/src/wx/cmdevents.cpp
index c083678..5e31c1d 100644
--- a/src/wx/cmdevents.cpp
+++ b/src/wx/cmdevents.cpp
@@ -2625,6 +2625,12 @@ EVT_HANDLER(SkipIntro, "Skip BIOS initialization")
     update_opts();
 }
 
+EVT_HANDLER(SyncGameAudio, "Synchronize game to audio")
+{
+	GetMenuOptionInt("SyncGameAudio", synchronize, 1);
+	update_opts();
+}
+
 EVT_HANDLER(BootRomEn, "Use the specified BIOS file for GBA")
 {
     GetMenuOptionInt("BootRomEn", useBiosFileGBA, 1);
diff --git a/src/wx/dsound.cpp b/src/wx/dsound.cpp
index 2ed26e2..062b1b2 100644
--- a/src/wx/dsound.cpp
+++ b/src/wx/dsound.cpp
@@ -233,7 +233,7 @@ void DirectSound::write(uint16_t* finalWave, int length)
     LPVOID lpvPtr2;
     DWORD dwBytes2 = 0;
 
-    if (!speedup && throttle && !gba_joybus_active) {
+    if (!speedup && synchronize && !throttle && !gba_joybus_active) {
         hr = dsbSecondary->GetStatus(&status);
 
         if (status & DSBSTATUS_PLAYING) {
diff --git a/src/wx/openal.cpp b/src/wx/openal.cpp
index a3a08da..82e2f72 100644
--- a/src/wx/openal.cpp
+++ b/src/wx/openal.cpp
@@ -286,7 +286,7 @@ void OpenAL::write(uint16_t* finalWave, int length)
             }
         }
 
-        if (!speedup && throttle && !gba_joybus_active) {
+        if (!speedup && synchronize && !throttle && !gba_joybus_active) {
             // wait until at least one buffer has finished
             while (nBuffersProcessed == 0) {
                 winlog(" waiting...\n");
diff --git a/src/wx/opts.cpp b/src/wx/opts.cpp
index 68198c4..f96cffe 100644
--- a/src/wx/opts.cpp
+++ b/src/wx/opts.cpp
@@ -246,6 +246,7 @@ opt_desc opts[] = {
     INTOPT("preferences/skipBios", "SkipIntro", wxTRANSLATE("Skip BIOS initialization"), skipBios, 0, 1),
     INTOPT("preferences/skipSaveGameCheats", "", wxTRANSLATE("Do not overwrite cheat list when loading state"), skipSaveGameCheats, 0, 1),
     INTOPT("preferences/skipSaveGameBattery", "", wxTRANSLATE("Do not overwrite native (battery) save when loading state"), skipSaveGameBattery, 0, 1),
+	INTOPT ("preferences/synchronize", "SyncGameAudio", wxTRANSLATE("Synchronize game to audio"), synchronize, 0, 1),
     INTOPT("preferences/throttle", "", wxTRANSLATE("Throttle game speed, even when accelerated (0-1000%, 0 = disabled)"), throttle, 0, 1000),
     INTOPT("preferences/useBiosGB", "BootRomGB", wxTRANSLATE("Use the specified BIOS file for GB"), useBiosFileGB, 0, 1),
     INTOPT("preferences/useBiosGBA", "BootRomEn", wxTRANSLATE("Use the specified BIOS file"), useBiosFileGBA, 0, 1),
diff --git a/src/wx/xrc/MainMenu.xrc b/src/wx/xrc/MainMenu.xrc
index 5313057..b778ab2 100644
--- a/src/wx/xrc/MainMenu.xrc
+++ b/src/wx/xrc/MainMenu.xrc
@@ -242,6 +242,10 @@
         <label>_VSync</label>
         <checkable>1</checkable>
       </object>
+      <object class="wxMenuItem" name="SyncGameAudio">
+        <label>_Audio sync</label>
+        <checkable>1</checkable>
+      </object>
       <object class="wxMenuItem" name="FrameSkipAuto">
         <label>_Auto skip frames</label>
         <checkable>1</checkable>