diff --git a/indra/llaudio/llstreamingaudio_fmod.cpp b/indra/llaudio/llstreamingaudio_fmod.cpp
index a4620fa13c5fe5331e0c587d7b1ea51f3616d9ff..fe9468856504c262fc465709af6fb5cd2413287c 100644
--- a/indra/llaudio/llstreamingaudio_fmod.cpp
+++ b/indra/llaudio/llstreamingaudio_fmod.cpp
@@ -271,7 +271,7 @@ void LLStreamingAudio_FMOD::setGain(F32 vol)
 
 	if (mFMODInternetStreamChannel != -1)
 	{
-		vol = llclamp(vol, 0.f, 1.f);
+		vol = llclamp(vol * vol, 0.f, 1.f);
 		int vol_int = llround(vol * 255.f);
 		FSOUND_SetVolumeAbsolute(mFMODInternetStreamChannel, vol_int);
 	}
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
index cc03d9cb72d58a7970d8ad2be59aeb5334e04b57..85318aea3ba9fb43938e901b359a0dc9b574909f 100644
--- a/indra/media_plugins/CMakeLists.txt
+++ b/indra/media_plugins/CMakeLists.txt
@@ -10,4 +10,8 @@ if (WINDOWS OR DARWIN)
     add_subdirectory(quicktime)
 endif (WINDOWS OR DARWIN)
 
+if (WINDOWS)
+    add_subdirectory(winmmshim)
+endif (WINDOWS)
+
 add_subdirectory(example)
diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/webkit/windows_volume_catcher.cpp
index 8debe8fac685c16ee394cc124fe1a9f94cd9f59c..fdff28c2c173e82a8f7574ba95fd57222d7225cf 100644
--- a/indra/media_plugins/webkit/windows_volume_catcher.cpp
+++ b/indra/media_plugins/webkit/windows_volume_catcher.cpp
@@ -33,262 +33,62 @@
 
 #include "volume_catcher.h"
 #include <windows.h>
+#include "llsingleton.h"
 
-//
-// Abstracts a Win32 mixer line and associated state
-// for muting and changing volume on a given output
-//
-class Mixer
-{
-public:
-	static Mixer* create(U32 index);
-	~Mixer();
-
-	void setMute(bool mute);
-	void setVolume(F32 volume_left, F32 volume_right);
-
-private:
-	// use create(index) to create a Mixer
-	Mixer(HMIXER handle, U32 mute_control_id, U32 volume_control_id, U32 min_volume, U32 max_volume);
-
-	HMIXER	mHandle;		
-	U32		mMuteControlID;		// handle to mixer controller for muting
-	U32		mVolumeControlID;	// handle to mixer controller for changing volume
-	U32		mMinVolume;			// value that specifies minimum volume as reported by mixer
-	U32		mMaxVolume;			// value that specifies maximum volume as reported by mixer
-};
-
-// factory function that attempts to create a Mixer object associated with a given mixer line index
-// returns NULL if creation failed
-// static 
-Mixer* Mixer::create(U32 index)
-{
-	// get handle to mixer object
-	HMIXER mixer_handle;
-	MMRESULT result = mixerOpen( &mixer_handle,
-							index,	
-							0,	// HWND to call when state changes - not used
-							0,	// user data for callback - not used
-							MIXER_OBJECTF_MIXER );
-
-	if (result == MMSYSERR_NOERROR)
-	{
-		MIXERLINE mixer_line;
-		mixer_line.cbStruct = sizeof( MIXERLINE );
-
-		// try speakers first
-		mixer_line.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
-
-		MMRESULT result = mixerGetLineInfo( reinterpret_cast< HMIXEROBJ >( mixer_handle ),
-								&mixer_line,
-								MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE );
-		if (result != MMSYSERR_NOERROR)
-		{	// failed - try headphones next
-			mixer_line.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_HEADPHONES;
-			result = mixerGetLineInfo( reinterpret_cast< HMIXEROBJ >( mixer_handle ),
-									&mixer_line,
-									MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE );
-		}
-
-		if (result == MMSYSERR_NOERROR)
-		{	// successfully found mixer line object, now use it to get volume and mute controls
-
-			// reuse these objects to query for both volume and mute controls
-			MIXERCONTROL mixer_control;
-			MIXERLINECONTROLS mixer_line_controls;
-			mixer_line_controls.cbStruct = sizeof( MIXERLINECONTROLS );
-			mixer_line_controls.dwLineID = mixer_line.dwLineID;
-			mixer_line_controls.cControls = 1;
-			mixer_line_controls.cbmxctrl = sizeof( MIXERCONTROL );
-			mixer_line_controls.pamxctrl = &mixer_control;
-
-			// first, query for mute
-			mixer_line_controls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
-
-			// get control id for mute controls
-			result = mixerGetLineControls( reinterpret_cast< HMIXEROBJ >( mixer_handle ),
-				&mixer_line_controls,
-				MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE );
-			if (result == MMSYSERR_NOERROR )
-			{	// we have a mute controls.  Remember the mute control id and then query for 
-				// volume controls using the same struct, but different dwControlType
-
-				U32 mute_control_id = mixer_control.dwControlID;
-				mixer_line_controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
-				result = mixerGetLineControls( reinterpret_cast< HMIXEROBJ >( mixer_handle ),
-					&mixer_line_controls,
-					MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE );
-
-				if (result == MMSYSERR_NOERROR)
-				{	// we have both mute and volume controls for this mixer, so we're keeping it
-					return new Mixer(mixer_handle, 
-								mute_control_id, 
-								mixer_control.dwControlID, 
-								mixer_control.Bounds.dwMinimum, 
-								mixer_control.Bounds.dwMaximum);
-				}
-			}
-		}
-	}
-
-	// if we got here, we didn't successfully create a Mixer object
-	mixerClose(mixer_handle);
-	return NULL;
-}
-
-Mixer::Mixer(HMIXER handle, U32 mute_control_id, U32 volume_control_id, U32 min_volume, U32 max_volume)
-:	mHandle(handle),
-	mMuteControlID(mute_control_id),
-	mVolumeControlID(volume_control_id),
-	mMinVolume(min_volume),
-	mMaxVolume(max_volume)
-{}
-
-Mixer::~Mixer()
-{}
-
-// toggle mute for this mixer
-// if mute is set, then volume level will be ignored
-void Mixer::setMute(bool mute)
-{
-	MIXERCONTROLDETAILS_BOOLEAN mixer_control_details_bool = { mute };
-	MIXERCONTROLDETAILS mixer_control_details;
-	mixer_control_details.cbStruct = sizeof( MIXERCONTROLDETAILS );
-	mixer_control_details.dwControlID = mMuteControlID;
-	mixer_control_details.cChannels = 1;
-	mixer_control_details.cMultipleItems = 0;
-	mixer_control_details.cbDetails = sizeof( MIXERCONTROLDETAILS_BOOLEAN );
-	mixer_control_details.paDetails = &mixer_control_details_bool;
-
-	mixerSetControlDetails( reinterpret_cast< HMIXEROBJ >( mHandle ),
-								 &mixer_control_details,
-								 MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE );
-}
-
-// set individual volume levels for left and right channels
-// if mute is set, then these values will apply once mute is unset
-void Mixer::setVolume(F32 volume_left, F32 volume_right)
-{
-	// assuming pan is in range [-1, 1] set volume levels accordingly
-	// if pan == -1 then	volume_left_mixer = volume_left	&& volume_right_mixer = 0
-	// if pan == 0 then		volume_left_mixer = volume_left	&& volume_right_mixer = volume_right
-	// if pan == 1 then		volume_left_mixer = 0			&& volume_right_mixer = volume_right
-	U32 volume_left_mixer = (U32)
-							((F32)mMinVolume 
-								+ (volume_left * ((F32)mMaxVolume - (F32)mMinVolume)));
-	U32 volume_right_mixer = (U32)
-							((F32)mMinVolume 
-								+ (volume_right * ((F32)mMaxVolume - (F32)mMinVolume)));
-
-	// pass volume levels on to mixer
-	MIXERCONTROLDETAILS_UNSIGNED mixer_control_details_unsigned[ 2 ] = { volume_left_mixer, volume_right_mixer };
-	MIXERCONTROLDETAILS mixer_control_details;
-	mixer_control_details.cbStruct = sizeof( MIXERCONTROLDETAILS );
-	mixer_control_details.dwControlID = mVolumeControlID;
-	mixer_control_details.cChannels = 2;
-	mixer_control_details.cMultipleItems = 0;
-	mixer_control_details.cbDetails = sizeof( MIXERCONTROLDETAILS_UNSIGNED );
-	mixer_control_details.paDetails = &mixer_control_details_unsigned;
-
-	mixerSetControlDetails( reinterpret_cast< HMIXEROBJ >( mHandle ),
-								 &mixer_control_details,
-								 MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE );
-}
-
-class VolumeCatcherImpl
+class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl>
 {
+friend LLSingleton<VolumeCatcherImpl>;
 public:
 
 	void setVolume(F32 volume);
 	void setPan(F32 pan);
 	
-	static VolumeCatcherImpl *getInstance();
 private:
 	// This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
 	VolumeCatcherImpl();
 	~VolumeCatcherImpl();
 
-	static VolumeCatcherImpl *sInstance;
-	
+	typedef void (*set_volume_func_t)(F32);
+	typedef void (*set_mute_func_t)(bool);
+
+	set_volume_func_t mSetVolumeFunc;
+	set_mute_func_t mSetMuteFunc;
+
 	F32 	mVolume;
 	F32 	mPan;
-	typedef std::vector<Mixer*> mixer_vector_t;
-	mixer_vector_t	mMixers;
 };
 
-VolumeCatcherImpl *VolumeCatcherImpl::sInstance = NULL;
-
-VolumeCatcherImpl *VolumeCatcherImpl::getInstance()
-{
-	if(!sInstance)
-	{
-		sInstance = new VolumeCatcherImpl;
-	}
-	
-	return sInstance;
-}
-
 VolumeCatcherImpl::VolumeCatcherImpl()
 :	mVolume(1.0f),	// default volume is max
 	mPan(0.f)		// default pan is centered
 {
-	OSVERSIONINFOEX	V = {sizeof(OSVERSIONINFOEX)};	//EX for NT 5.0 and later
-
-	::GetVersionEx((POSVERSIONINFO)&V);
-
-	// disable volume on XP and below
-	if (V.dwPlatformId == VER_PLATFORM_WIN32_NT && V.dwMajorVersion >= 6)
+	HMODULE handle = ::LoadLibrary(L"winmm.dll");
+	if(handle)
 	{
-		// for each reported mixer "device", create a proxy object and add to list
-		U32 num_mixers = mixerGetNumDevs();
-		for (U32 mixer_index = 0; mixer_index < num_mixers; ++mixer_index)
-		{
-			Mixer* mixerp = Mixer::create(mixer_index);
-			if (mixerp)
-			{
-				mMixers.push_back(mixerp);
-			}
-		}
+		mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume");
+		mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute");
 	}
 }
 
 VolumeCatcherImpl::~VolumeCatcherImpl()
 {
-	for(mixer_vector_t::iterator it = mMixers.begin(), end_it = mMixers.end();
-		it != end_it;
-		++it)
-	{
-		delete *it;
-		*it = NULL;
-	}
 }
 
 
 void VolumeCatcherImpl::setVolume(F32 volume)
 {
-	F32 left_volume = volume * min(1.f, 1.f - mPan);
-	F32 right_volume = volume * max(0.f, 1.f + mPan);
+	//F32 left_volume = volume * min(1.f, 1.f - mPan);
+	//F32 right_volume = volume * max(0.f, 1.f + mPan);
 	
-	for(mixer_vector_t::iterator it = mMixers.begin(), end_it = mMixers.end();
-		it != end_it;
-		++it)
-	{	// set volume levels and mute for each mixer
-		// note that a muted mixer will ignore this volume level
-
-		(*it)->setVolume(left_volume, right_volume);
-		
-		if (volume == 0.f && mVolume != 0.f)
-		{
-			(*it)->setMute(true);
-		}
-		else if (mVolume == 0.f && volume != 0.f)
-		{
-			(*it)->setMute(false);
-		}
-
-	}
-
 	mVolume = volume;
+	if (mSetMuteFunc)
+	{
+		mSetMuteFunc(volume == 0.f);
+	}
+	if (mSetVolumeFunc)
+	{
+		mSetVolumeFunc(mVolume);
+	}
 }
 
 void VolumeCatcherImpl::setPan(F32 pan)
diff --git a/indra/media_plugins/winmmshim/CMakeLists.txt b/indra/media_plugins/winmmshim/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d35e97fc62e1b4ed7c150fd147be302f6b1cd619
--- /dev/null
+++ b/indra/media_plugins/winmmshim/CMakeLists.txt
@@ -0,0 +1,34 @@
+# -*- cmake -*-
+
+project(winmm_shim)
+
+### winmm_shim
+
+set(winmm_shim_SOURCE_FILES
+    forwarding_api.cpp
+    winmm_shim.cpp
+    )
+
+set(winmm_shim_HEADER_FILES
+    forwarding_api.h
+    winmm.def
+    )
+
+list(APPEND winmm_shim_SOURCE_FILES ${winmm_shim_HEADER_FILES})
+
+set_source_files_properties(${media_plugin_webkit_HEADER_FILES}
+                            PROPERTIES HEADER_FILE_ONLY TRUE)
+
+add_library(winmm_shim
+    SHARED
+    ${winmm_shim_SOURCE_FILES}
+)
+
+if (WINDOWS)
+  set_target_properties(
+    winmm_shim
+    PROPERTIES
+    LINK_FLAGS "/MANIFEST:NO"
+	OUTPUT_NAME "winmm"
+    )
+endif (WINDOWS)
diff --git a/indra/media_plugins/winmmshim/forwarding_api.cpp b/indra/media_plugins/winmmshim/forwarding_api.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aaa229fe9db77390b860858b0ea8d7ad63679d37
--- /dev/null
+++ b/indra/media_plugins/winmmshim/forwarding_api.cpp
@@ -0,0 +1,1460 @@
+/** 
+ * @file forwarding_api.cpp
+ * @brief forwards winmm API calls to real winmm.dll
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "forwarding_api.h"
+
+CloseDriver_type CloseDriver_orig;
+OpenDriver_type OpenDriver_orig;
+SendDriverMessage_type SendDriverMessage_orig;
+DrvGetModuleHandle_type DrvGetModuleHandle_orig;
+GetDriverModuleHandle_type GetDriverModuleHandle_orig;
+DefDriverProc_type DefDriverProc_orig;
+DriverCallback_type DriverCallback_orig;
+mmsystemGetVersion_type mmsystemGetVersion_orig;
+sndPlaySoundA_type sndPlaySoundA_orig;
+sndPlaySoundW_type sndPlaySoundW_orig;
+PlaySoundA_type PlaySoundA_orig;
+PlaySoundW_type PlaySoundW_orig;
+waveOutGetNumDevs_type waveOutGetNumDevs_orig;
+waveOutGetDevCapsA_type waveOutGetDevCapsA_orig;
+waveOutGetDevCapsW_type waveOutGetDevCapsW_orig;
+waveOutGetVolume_type waveOutGetVolume_orig;
+waveOutSetVolume_type waveOutSetVolume_orig;
+waveOutGetErrorTextA_type waveOutGetErrorTextA_orig;
+waveOutGetErrorTextW_type waveOutGetErrorTextW_orig;
+waveOutOpen_type waveOutOpen_orig;
+waveOutClose_type waveOutClose_orig;
+waveOutPrepareHeader_type waveOutPrepareHeader_orig;
+waveOutUnprepareHeader_type waveOutUnprepareHeader_orig;
+waveOutWrite_type waveOutWrite_orig;
+waveOutPause_type waveOutPause_orig;
+waveOutRestart_type waveOutRestart_orig;
+waveOutReset_type waveOutReset_orig;
+waveOutBreakLoop_type waveOutBreakLoop_orig;
+waveOutGetPosition_type waveOutGetPosition_orig;
+waveOutGetPitch_type waveOutGetPitch_orig;
+waveOutSetPitch_type waveOutSetPitch_orig;
+waveOutGetPlaybackRate_type waveOutGetPlaybackRate_orig;
+waveOutSetPlaybackRate_type waveOutSetPlaybackRate_orig;
+waveOutGetID_type waveOutGetID_orig;
+waveOutMessage_type waveOutMessage_orig;
+waveInGetNumDevs_type waveInGetNumDevs_orig;
+waveInGetDevCapsA_type waveInGetDevCapsA_orig;
+waveInGetDevCapsW_type waveInGetDevCapsW_orig;
+waveInGetErrorTextA_type waveInGetErrorTextA_orig;
+waveInGetErrorTextW_type waveInGetErrorTextW_orig;
+waveInOpen_type waveInOpen_orig;
+waveInClose_type waveInClose_orig;
+waveInPrepareHeader_type waveInPrepareHeader_orig;
+waveInUnprepareHeader_type waveInUnprepareHeader_orig;
+waveInAddBuffer_type waveInAddBuffer_orig;
+waveInStart_type waveInStart_orig;
+waveInStop_type waveInStop_orig;
+waveInReset_type waveInReset_orig;
+waveInGetPosition_type waveInGetPosition_orig;
+waveInGetID_type waveInGetID_orig;
+waveInMessage_type waveInMessage_orig;
+midiOutGetNumDevs_type midiOutGetNumDevs_orig;
+midiStreamOpen_type midiStreamOpen_orig;
+midiStreamClose_type midiStreamClose_orig;
+midiStreamProperty_type midiStreamProperty_orig;
+midiStreamPosition_type midiStreamPosition_orig;
+midiStreamOut_type midiStreamOut_orig;
+midiStreamPause_type midiStreamPause_orig;
+midiStreamRestart_type midiStreamRestart_orig;
+midiStreamStop_type midiStreamStop_orig;
+midiConnect_type midiConnect_orig;
+midiDisconnect_type midiDisconnect_orig;
+midiOutGetDevCapsA_type midiOutGetDevCapsA_orig;
+midiOutGetDevCapsW_type midiOutGetDevCapsW_orig;
+midiOutGetVolume_type midiOutGetVolume_orig;
+midiOutSetVolume_type midiOutSetVolume_orig;
+midiOutGetErrorTextA_type midiOutGetErrorTextA_orig;
+midiOutGetErrorTextW_type midiOutGetErrorTextW_orig;
+midiOutOpen_type midiOutOpen_orig;
+midiOutClose_type midiOutClose_orig;
+midiOutPrepareHeader_type midiOutPrepareHeader_orig;
+midiOutUnprepareHeader_type midiOutUnprepareHeader_orig;
+midiOutShortMsg_type midiOutShortMsg_orig;
+midiOutLongMsg_type midiOutLongMsg_orig;
+midiOutReset_type midiOutReset_orig;
+midiOutCachePatches_type midiOutCachePatches_orig;
+midiOutCacheDrumPatches_type midiOutCacheDrumPatches_orig;
+midiOutGetID_type midiOutGetID_orig;
+midiOutMessage_type midiOutMessage_orig;
+midiInGetNumDevs_type midiInGetNumDevs_orig;
+midiInGetDevCapsA_type midiInGetDevCapsA_orig;
+midiInGetDevCapsW_type midiInGetDevCapsW_orig;
+midiInGetErrorTextA_type midiInGetErrorTextA_orig;
+midiInGetErrorTextW_type midiInGetErrorTextW_orig;
+midiInOpen_type midiInOpen_orig;
+midiInClose_type midiInClose_orig;
+midiInPrepareHeader_type midiInPrepareHeader_orig;
+midiInUnprepareHeader_type midiInUnprepareHeader_orig;
+midiInAddBuffer_type midiInAddBuffer_orig;
+midiInStart_type midiInStart_orig;
+midiInStop_type midiInStop_orig;
+midiInReset_type midiInReset_orig;
+midiInGetID_type midiInGetID_orig;
+midiInMessage_type midiInMessage_orig;
+auxGetNumDevs_type auxGetNumDevs_orig;
+auxGetDevCapsA_type auxGetDevCapsA_orig;
+auxGetDevCapsW_type auxGetDevCapsW_orig;
+auxSetVolume_type auxSetVolume_orig;
+auxGetVolume_type auxGetVolume_orig;
+auxOutMessage_type auxOutMessage_orig;
+mixerGetNumDevs_type mixerGetNumDevs_orig;
+mixerGetDevCapsA_type mixerGetDevCapsA_orig;
+mixerGetDevCapsW_type mixerGetDevCapsW_orig;
+mixerOpen_type mixerOpen_orig;
+mixerClose_type mixerClose_orig;
+mixerMessage_type mixerMessage_orig;
+mixerGetLineInfoA_type mixerGetLineInfoA_orig;
+mixerGetLineInfoW_type mixerGetLineInfoW_orig;
+mixerGetID_type mixerGetID_orig;
+mixerGetLineControlsA_type mixerGetLineControlsA_orig;
+mixerGetLineControlsW_type mixerGetLineControlsW_orig;
+mixerGetControlDetailsA_type mixerGetControlDetailsA_orig;
+mixerGetControlDetailsW_type mixerGetControlDetailsW_orig;
+mixerSetControlDetails_type mixerSetControlDetails_orig;
+mmGetCurrentTask_type mmGetCurrentTask_orig;
+mmTaskBlock_type mmTaskBlock_orig;
+mmTaskCreate_type mmTaskCreate_orig;
+mmTaskSignal_type mmTaskSignal_orig;
+mmTaskYield_type mmTaskYield_orig;
+timeGetSystemTime_type timeGetSystemTime_orig;
+timeGetTime_type timeGetTime_orig;
+timeSetEvent_type timeSetEvent_orig;
+timeKillEvent_type timeKillEvent_orig;
+timeGetDevCaps_type timeGetDevCaps_orig;
+timeBeginPeriod_type timeBeginPeriod_orig;
+timeEndPeriod_type timeEndPeriod_orig;
+joyGetNumDevs_type joyGetNumDevs_orig;
+joyConfigChanged_type joyConfigChanged_orig;
+joyGetDevCapsA_type joyGetDevCapsA_orig;
+joyGetDevCapsW_type joyGetDevCapsW_orig;
+joyGetPos_type joyGetPos_orig;
+joyGetPosEx_type joyGetPosEx_orig;
+joyGetThreshold_type joyGetThreshold_orig;
+joyReleaseCapture_type joyReleaseCapture_orig;
+joySetCapture_type joySetCapture_orig;
+joySetThreshold_type joySetThreshold_orig;
+mmioStringToFOURCCA_type mmioStringToFOURCCA_orig;
+mmioStringToFOURCCW_type mmioStringToFOURCCW_orig;
+mmioInstallIOProcA_type mmioInstallIOProcA_orig;
+mmioInstallIOProcW_type mmioInstallIOProcW_orig;
+mmioOpenA_type mmioOpenA_orig;
+mmioOpenW_type mmioOpenW_orig;
+mmioRenameA_type mmioRenameA_orig;
+mmioRenameW_type mmioRenameW_orig;
+mmioClose_type mmioClose_orig;
+mmioRead_type mmioRead_orig;
+mmioWrite_type mmioWrite_orig;
+mmioSeek_type mmioSeek_orig;
+mmioGetInfo_type mmioGetInfo_orig;
+mmioSetInfo_type mmioSetInfo_orig;
+mmioSetBuffer_type mmioSetBuffer_orig;
+mmioFlush_type mmioFlush_orig;
+mmioAdvance_type mmioAdvance_orig;
+mmioSendMessage_type mmioSendMessage_orig;
+mmioDescend_type mmioDescend_orig;
+mmioAscend_type mmioAscend_orig;
+mmioCreateChunk_type mmioCreateChunk_orig;
+mciSendCommandA_type mciSendCommandA_orig;
+mciSendCommandW_type mciSendCommandW_orig;
+mciSendStringA_type mciSendStringA_orig;
+mciSendStringW_type mciSendStringW_orig;
+mciGetDeviceIDA_type mciGetDeviceIDA_orig;
+mciGetDeviceIDW_type mciGetDeviceIDW_orig;
+mciGetDeviceIDFromElementIDA_type mciGetDeviceIDFromElementIDA_orig;
+mciGetDeviceIDFromElementIDW_type mciGetDeviceIDFromElementIDW_orig;
+mciGetDriverData_type mciGetDriverData_orig;
+mciGetErrorStringA_type mciGetErrorStringA_orig;
+mciGetErrorStringW_type mciGetErrorStringW_orig;
+mciSetDriverData_type mciSetDriverData_orig;
+mciDriverNotify_type mciDriverNotify_orig;
+mciDriverYield_type mciDriverYield_orig;
+mciSetYieldProc_type mciSetYieldProc_orig;
+mciFreeCommandResource_type mciFreeCommandResource_orig;
+mciGetCreatorTask_type mciGetCreatorTask_orig;
+mciGetYieldProc_type mciGetYieldProc_orig;
+mciLoadCommandResource_type mciLoadCommandResource_orig;
+mciExecute_type mciExecute_orig;
+
+
+void init_function_pointers(HMODULE winmm_handle)
+{
+	CloseDriver_orig = (CloseDriver_type)::GetProcAddress(winmm_handle, "CloseDriver");
+	OpenDriver_orig = (OpenDriver_type)::GetProcAddress(winmm_handle, "OpenDriver");
+	SendDriverMessage_orig = (SendDriverMessage_type)::GetProcAddress(winmm_handle, "SendDriverMessage");
+	DrvGetModuleHandle_orig = (DrvGetModuleHandle_type)::GetProcAddress(winmm_handle, "DrvGetModuleHandle");
+	GetDriverModuleHandle_orig = (GetDriverModuleHandle_type)::GetProcAddress(winmm_handle, "GetDriverModuleHandle");
+	DefDriverProc_orig = (DefDriverProc_type)::GetProcAddress(winmm_handle, "DefDriverProc");
+	DriverCallback_orig = (DriverCallback_type)::GetProcAddress(winmm_handle, "DriverCallback");
+	mmsystemGetVersion_orig = (mmsystemGetVersion_type)::GetProcAddress(winmm_handle, "mmsystemGetVersion");
+	sndPlaySoundA_orig = (sndPlaySoundA_type)::GetProcAddress(winmm_handle, "sndPlaySoundA");
+	sndPlaySoundW_orig = (sndPlaySoundW_type)::GetProcAddress(winmm_handle, "sndPlaySoundW");
+	PlaySoundA_orig = (PlaySoundA_type)::GetProcAddress(winmm_handle, "PlaySoundA");
+	PlaySoundW_orig = (PlaySoundW_type)::GetProcAddress(winmm_handle, "PlaySoundW");
+	waveOutGetNumDevs_orig = (waveOutGetNumDevs_type)::GetProcAddress(winmm_handle, "waveOutGetNumDevs");
+	waveOutGetDevCapsA_orig = (waveOutGetDevCapsA_type)::GetProcAddress(winmm_handle, "waveOutGetDevCapsA");
+	waveOutGetDevCapsW_orig = (waveOutGetDevCapsW_type)::GetProcAddress(winmm_handle, "waveOutGetDevCapsW");
+	waveOutGetVolume_orig = (waveOutGetVolume_type)::GetProcAddress(winmm_handle, "waveOutGetVolume");
+	waveOutSetVolume_orig = (waveOutSetVolume_type)::GetProcAddress(winmm_handle, "waveOutSetVolume");
+	waveOutGetErrorTextA_orig = (waveOutGetErrorTextA_type)::GetProcAddress(winmm_handle, "waveOutGetErrorTextA");
+	waveOutGetErrorTextW_orig = (waveOutGetErrorTextW_type)::GetProcAddress(winmm_handle, "waveOutGetErrorTextW");
+	waveOutOpen_orig = (waveOutOpen_type)::GetProcAddress(winmm_handle, "waveOutOpen");
+	waveOutClose_orig = (waveOutClose_type)::GetProcAddress(winmm_handle, "waveOutClose");
+	waveOutPrepareHeader_orig = (waveOutPrepareHeader_type)::GetProcAddress(winmm_handle, "waveOutPrepareHeader");
+	waveOutUnprepareHeader_orig = (waveOutUnprepareHeader_type)::GetProcAddress(winmm_handle, "waveOutUnprepareHeader");
+	waveOutWrite_orig = (waveOutWrite_type)::GetProcAddress(winmm_handle, "waveOutWrite");
+	waveOutPause_orig = (waveOutPause_type)::GetProcAddress(winmm_handle, "waveOutPause");
+	waveOutRestart_orig = (waveOutRestart_type)::GetProcAddress(winmm_handle, "waveOutRestart");
+	waveOutReset_orig = (waveOutReset_type)::GetProcAddress(winmm_handle, "waveOutReset");
+	waveOutBreakLoop_orig = (waveOutBreakLoop_type)::GetProcAddress(winmm_handle, "waveOutBreakLoop");
+	waveOutGetPosition_orig = (waveOutGetPosition_type)::GetProcAddress(winmm_handle, "waveOutGetPosition");
+	waveOutGetPitch_orig = (waveOutGetPitch_type)::GetProcAddress(winmm_handle, "waveOutGetPitch");
+	waveOutSetPitch_orig = (waveOutSetPitch_type)::GetProcAddress(winmm_handle, "waveOutSetPitch");
+	waveOutGetPlaybackRate_orig = (waveOutGetPlaybackRate_type)::GetProcAddress(winmm_handle, "waveOutGetPlaybackRate");
+	waveOutSetPlaybackRate_orig = (waveOutSetPlaybackRate_type)::GetProcAddress(winmm_handle, "waveOutSetPlaybackRate");
+	waveOutGetID_orig = (waveOutGetID_type)::GetProcAddress(winmm_handle, "waveOutGetID");
+	waveOutMessage_orig = (waveOutMessage_type)::GetProcAddress(winmm_handle, "waveOutMessage");
+	waveInGetNumDevs_orig = (waveInGetNumDevs_type)::GetProcAddress(winmm_handle, "waveInGetNumDevs");
+	waveInGetDevCapsA_orig = (waveInGetDevCapsA_type)::GetProcAddress(winmm_handle, "waveInGetDevCapsA");
+	waveInGetDevCapsW_orig = (waveInGetDevCapsW_type)::GetProcAddress(winmm_handle, "waveInGetDevCapsW");
+	waveInGetErrorTextA_orig = (waveInGetErrorTextA_type)::GetProcAddress(winmm_handle, "waveInGetErrorTextA");
+	waveInGetErrorTextW_orig = (waveInGetErrorTextW_type)::GetProcAddress(winmm_handle, "waveInGetErrorTextW");
+	waveInOpen_orig = (waveInOpen_type)::GetProcAddress(winmm_handle, "waveInOpen");
+	waveInClose_orig = (waveInClose_type)::GetProcAddress(winmm_handle, "waveInClose");
+	waveInPrepareHeader_orig = (waveInPrepareHeader_type)::GetProcAddress(winmm_handle, "waveInPrepareHeader");
+	waveInUnprepareHeader_orig = (waveInUnprepareHeader_type)::GetProcAddress(winmm_handle, "waveInUnprepareHeader");
+	waveInAddBuffer_orig = (waveInAddBuffer_type)::GetProcAddress(winmm_handle, "waveInAddBuffer");
+	waveInStart_orig = (waveInStart_type)::GetProcAddress(winmm_handle, "waveInStart");
+	waveInStop_orig = (waveInStop_type)::GetProcAddress(winmm_handle, "waveInStop");
+	waveInReset_orig = (waveInReset_type)::GetProcAddress(winmm_handle, "waveInReset");
+	waveInGetPosition_orig = (waveInGetPosition_type)::GetProcAddress(winmm_handle, "waveInGetPosition");
+	waveInGetID_orig = (waveInGetID_type)::GetProcAddress(winmm_handle, "waveInGetID");
+	waveInMessage_orig = (waveInMessage_type)::GetProcAddress(winmm_handle, "waveInMessage");
+	midiOutGetNumDevs_orig = (midiOutGetNumDevs_type)::GetProcAddress(winmm_handle, "midiOutGetNumDevs");
+	midiStreamOpen_orig = (midiStreamOpen_type)::GetProcAddress(winmm_handle, "midiStreamOpen");
+	midiStreamClose_orig = (midiStreamClose_type)::GetProcAddress(winmm_handle, "midiStreamClose");
+	midiStreamProperty_orig = (midiStreamProperty_type)::GetProcAddress(winmm_handle, "midiStreamProperty");
+	midiStreamPosition_orig = (midiStreamPosition_type)::GetProcAddress(winmm_handle, "midiStreamPosition");
+	midiStreamOut_orig = (midiStreamOut_type)::GetProcAddress(winmm_handle, "midiStreamOut");
+	midiStreamPause_orig = (midiStreamPause_type)::GetProcAddress(winmm_handle, "midiStreamPause");
+	midiStreamRestart_orig = (midiStreamRestart_type)::GetProcAddress(winmm_handle, "midiStreamRestart");
+	midiStreamStop_orig = (midiStreamStop_type)::GetProcAddress(winmm_handle, "midiStreamStop");
+	midiConnect_orig = (midiConnect_type)::GetProcAddress(winmm_handle, "midiConnect");
+	midiDisconnect_orig = (midiDisconnect_type)::GetProcAddress(winmm_handle, "midiDisconnect");
+	midiOutGetDevCapsA_orig = (midiOutGetDevCapsA_type)::GetProcAddress(winmm_handle, "midiOutGetDevCapsA");
+	midiOutGetDevCapsW_orig = (midiOutGetDevCapsW_type)::GetProcAddress(winmm_handle, "midiOutGetDevCapsW");
+	midiOutGetVolume_orig = (midiOutGetVolume_type)::GetProcAddress(winmm_handle, "midiOutGetVolume");
+	midiOutSetVolume_orig = (midiOutSetVolume_type)::GetProcAddress(winmm_handle, "midiOutSetVolume");
+	midiOutGetErrorTextA_orig = (midiOutGetErrorTextA_type)::GetProcAddress(winmm_handle, "midiOutGetErrorTextA");
+	midiOutGetErrorTextW_orig = (midiOutGetErrorTextW_type)::GetProcAddress(winmm_handle, "midiOutGetErrorTextW");
+	midiOutOpen_orig = (midiOutOpen_type)::GetProcAddress(winmm_handle, "midiOutOpen");
+	midiOutClose_orig = (midiOutClose_type)::GetProcAddress(winmm_handle, "midiOutClose");
+	midiOutPrepareHeader_orig = (midiOutPrepareHeader_type)::GetProcAddress(winmm_handle, "midiOutPrepareHeader");
+	midiOutUnprepareHeader_orig = (midiOutUnprepareHeader_type)::GetProcAddress(winmm_handle, "midiOutUnprepareHeader");
+	midiOutShortMsg_orig = (midiOutShortMsg_type)::GetProcAddress(winmm_handle, "midiOutShortMsg");
+	midiOutLongMsg_orig = (midiOutLongMsg_type)::GetProcAddress(winmm_handle, "midiOutLongMsg");
+	midiOutReset_orig = (midiOutReset_type)::GetProcAddress(winmm_handle, "midiOutReset");
+	midiOutCachePatches_orig = (midiOutCachePatches_type)::GetProcAddress(winmm_handle, "midiOutCachePatches");
+	midiOutCacheDrumPatches_orig = (midiOutCacheDrumPatches_type)::GetProcAddress(winmm_handle, "midiOutCacheDrumPatches");
+	midiOutGetID_orig = (midiOutGetID_type)::GetProcAddress(winmm_handle, "midiOutGetID");
+	midiOutMessage_orig = (midiOutMessage_type)::GetProcAddress(winmm_handle, "midiOutMessage");
+	midiInGetNumDevs_orig = (midiInGetNumDevs_type)::GetProcAddress(winmm_handle, "midiInGetNumDevs");
+	midiInGetDevCapsA_orig = (midiInGetDevCapsA_type)::GetProcAddress(winmm_handle, "midiInGetDevCapsA");
+	midiInGetDevCapsW_orig = (midiInGetDevCapsW_type)::GetProcAddress(winmm_handle, "midiInGetDevCapsW");
+	midiInGetErrorTextA_orig = (midiInGetErrorTextA_type)::GetProcAddress(winmm_handle, "midiInGetErrorTextA");
+	midiInGetErrorTextW_orig = (midiInGetErrorTextW_type)::GetProcAddress(winmm_handle, "midiInGetErrorTextW");
+	midiInOpen_orig = (midiInOpen_type)::GetProcAddress(winmm_handle, "midiInOpen");
+	midiInClose_orig = (midiInClose_type)::GetProcAddress(winmm_handle, "midiInClose");
+	midiInPrepareHeader_orig = (midiInPrepareHeader_type)::GetProcAddress(winmm_handle, "midiInPrepareHeader");
+	midiInUnprepareHeader_orig = (midiInUnprepareHeader_type)::GetProcAddress(winmm_handle, "midiInUnprepareHeader");
+	midiInAddBuffer_orig = (midiInAddBuffer_type)::GetProcAddress(winmm_handle, "midiInAddBuffer");
+	midiInStart_orig = (midiInStart_type)::GetProcAddress(winmm_handle, "midiInStart");
+	midiInStop_orig = (midiInStop_type)::GetProcAddress(winmm_handle, "midiInStop");
+	midiInReset_orig = (midiInReset_type)::GetProcAddress(winmm_handle, "midiInReset");
+	midiInGetID_orig = (midiInGetID_type)::GetProcAddress(winmm_handle, "midiInGetID");
+	midiInMessage_orig = (midiInMessage_type)::GetProcAddress(winmm_handle, "midiInMessage");
+	auxGetNumDevs_orig = (auxGetNumDevs_type)::GetProcAddress(winmm_handle, "auxGetNumDevs");
+	auxGetDevCapsA_orig = (auxGetDevCapsA_type)::GetProcAddress(winmm_handle, "auxGetDevCapsA");
+	auxGetDevCapsW_orig = (auxGetDevCapsW_type)::GetProcAddress(winmm_handle, "auxGetDevCapsW");
+	auxSetVolume_orig = (auxSetVolume_type)::GetProcAddress(winmm_handle, "auxSetVolume");
+	auxGetVolume_orig = (auxGetVolume_type)::GetProcAddress(winmm_handle, "auxGetVolume");
+	auxOutMessage_orig = (auxOutMessage_type)::GetProcAddress(winmm_handle, "auxOutMessage");
+	mixerGetNumDevs_orig = (mixerGetNumDevs_type)::GetProcAddress(winmm_handle, "mixerGetNumDevs");
+	mixerGetDevCapsA_orig = (mixerGetDevCapsA_type)::GetProcAddress(winmm_handle, "mixerGetDevCapsA");
+	mixerGetDevCapsW_orig = (mixerGetDevCapsW_type)::GetProcAddress(winmm_handle, "mixerGetDevCapsW");
+	mixerOpen_orig = (mixerOpen_type)::GetProcAddress(winmm_handle, "mixerOpen");
+	mixerClose_orig = (mixerClose_type)::GetProcAddress(winmm_handle, "mixerClose");
+	mixerMessage_orig = (mixerMessage_type)::GetProcAddress(winmm_handle, "mixerMessage");
+	mixerGetLineInfoA_orig = (mixerGetLineInfoA_type)::GetProcAddress(winmm_handle, "mixerGetLineInfoA");
+	mixerGetLineInfoW_orig = (mixerGetLineInfoW_type)::GetProcAddress(winmm_handle, "mixerGetLineInfoW");
+	mixerGetID_orig = (mixerGetID_type)::GetProcAddress(winmm_handle, "mixerGetID");
+	mixerGetLineControlsA_orig = (mixerGetLineControlsA_type)::GetProcAddress(winmm_handle, "mixerGetLineControlsA");
+	mixerGetLineControlsW_orig = (mixerGetLineControlsW_type)::GetProcAddress(winmm_handle, "mixerGetLineControlsW");
+	mixerGetControlDetailsA_orig = (mixerGetControlDetailsA_type)::GetProcAddress(winmm_handle, "mixerGetControlDetailsA");
+	mixerGetControlDetailsW_orig = (mixerGetControlDetailsW_type)::GetProcAddress(winmm_handle, "mixerGetControlDetailsW");
+	mixerSetControlDetails_orig = (mixerSetControlDetails_type)::GetProcAddress(winmm_handle, "mixerSetControlDetails");
+	mmGetCurrentTask_orig = (mmGetCurrentTask_type)::GetProcAddress(winmm_handle, "mmGetCurrentTask");
+	mmTaskBlock_orig = (mmTaskBlock_type)::GetProcAddress(winmm_handle, "mmTaskBlock");
+	mmTaskCreate_orig = (mmTaskCreate_type)::GetProcAddress(winmm_handle, "mmTaskCreate");
+	mmTaskSignal_orig = (mmTaskSignal_type)::GetProcAddress(winmm_handle, "mmTaskSignal");
+	mmTaskYield_orig = (mmTaskYield_type)::GetProcAddress(winmm_handle, "mmTaskYield");
+	timeGetSystemTime_orig = (timeGetSystemTime_type)::GetProcAddress(winmm_handle, "timeGetSystemTime");
+	timeGetTime_orig = (timeGetTime_type)::GetProcAddress(winmm_handle, "timeGetTime");
+	timeSetEvent_orig = (timeSetEvent_type)::GetProcAddress(winmm_handle, "timeSetEvent");
+	timeKillEvent_orig = (timeKillEvent_type)::GetProcAddress(winmm_handle, "timeKillEvent");
+	timeGetDevCaps_orig = (timeGetDevCaps_type)::GetProcAddress(winmm_handle, "timeGetDevCaps");
+	timeBeginPeriod_orig = (timeBeginPeriod_type)::GetProcAddress(winmm_handle, "timeBeginPeriod");
+	timeEndPeriod_orig = (timeEndPeriod_type)::GetProcAddress(winmm_handle, "timeEndPeriod");
+	joyGetNumDevs_orig = (joyGetNumDevs_type)::GetProcAddress(winmm_handle, "joyGetNumDevs");
+	joyConfigChanged_orig = (joyConfigChanged_type)::GetProcAddress(winmm_handle, "joyConfigChanged");
+	joyGetDevCapsA_orig = (joyGetDevCapsA_type)::GetProcAddress(winmm_handle, "joyGetDevCapsA");
+	joyGetDevCapsW_orig = (joyGetDevCapsW_type)::GetProcAddress(winmm_handle, "joyGetDevCapsW");
+	joyGetPos_orig = (joyGetPos_type)::GetProcAddress(winmm_handle, "joyGetPos");
+	joyGetPosEx_orig = (joyGetPosEx_type)::GetProcAddress(winmm_handle, "joyGetPosEx");
+	joyGetThreshold_orig = (joyGetThreshold_type)::GetProcAddress(winmm_handle, "joyGetThreshold");
+	joyReleaseCapture_orig = (joyReleaseCapture_type)::GetProcAddress(winmm_handle, "joyReleaseCapture");
+	joySetCapture_orig = (joySetCapture_type)::GetProcAddress(winmm_handle, "joySetCapture");
+	joySetThreshold_orig = (joySetThreshold_type)::GetProcAddress(winmm_handle, "joySetThreshold");
+	mciDriverNotify_orig = (mciDriverNotify_type)::GetProcAddress(winmm_handle, "mciDriverNotify");
+	mciDriverYield_orig = (mciDriverYield_type)::GetProcAddress(winmm_handle, "mciDriverYield");
+	mmioStringToFOURCCA_orig = (mmioStringToFOURCCA_type)::GetProcAddress(winmm_handle, "mmioStringToFOURCCA");
+	mmioStringToFOURCCW_orig = (mmioStringToFOURCCW_type)::GetProcAddress(winmm_handle, "mmioStringToFOURCCW");
+	mmioInstallIOProcA_orig = (mmioInstallIOProcA_type)::GetProcAddress(winmm_handle, "mmioInstallIOProcA");
+	mmioInstallIOProcW_orig = (mmioInstallIOProcW_type)::GetProcAddress(winmm_handle, "mmioInstallIOProcW");
+	mmioOpenA_orig = (mmioOpenA_type)::GetProcAddress(winmm_handle, "mmioOpenA");
+	mmioOpenW_orig = (mmioOpenW_type)::GetProcAddress(winmm_handle, "mmioOpenW");
+	mmioRenameA_orig = (mmioRenameA_type)::GetProcAddress(winmm_handle, "mmioRenameA");
+	mmioRenameW_orig = (mmioRenameW_type)::GetProcAddress(winmm_handle, "mmioRenameW");
+	mmioClose_orig = (mmioClose_type)::GetProcAddress(winmm_handle, "mmioClose");
+	mmioRead_orig = (mmioRead_type)::GetProcAddress(winmm_handle, "mmioRead");
+	mmioWrite_orig = (mmioWrite_type)::GetProcAddress(winmm_handle, "mmioWrite");
+	mmioSeek_orig = (mmioSeek_type)::GetProcAddress(winmm_handle, "mmioSeek");
+	mmioGetInfo_orig = (mmioGetInfo_type)::GetProcAddress(winmm_handle, "mmioGetInfo");
+	mmioSetInfo_orig = (mmioSetInfo_type)::GetProcAddress(winmm_handle, "mmioSetInfo");
+	mmioSetBuffer_orig = (mmioSetBuffer_type)::GetProcAddress(winmm_handle, "mmioSetBuffer");
+	mmioFlush_orig = (mmioFlush_type)::GetProcAddress(winmm_handle, "mmioFlush");
+	mmioAdvance_orig = (mmioAdvance_type)::GetProcAddress(winmm_handle, "mmioAdvance");
+	mmioSendMessage_orig = (mmioSendMessage_type)::GetProcAddress(winmm_handle, "mmioSendMessage");
+	mmioDescend_orig = (mmioDescend_type)::GetProcAddress(winmm_handle, "mmioDescend");
+	mmioAscend_orig = (mmioAscend_type)::GetProcAddress(winmm_handle, "mmioAscend");
+	mmioCreateChunk_orig = (mmioCreateChunk_type)::GetProcAddress(winmm_handle, "mmioCreateChunk");
+	mciSendCommandA_orig = (mciSendCommandA_type)::GetProcAddress(winmm_handle, "mciSendCommandA");
+	mciSendCommandW_orig = (mciSendCommandW_type)::GetProcAddress(winmm_handle, "mciSendCommandW");
+	mciSendStringA_orig = (mciSendStringA_type)::GetProcAddress(winmm_handle, "mciSendStringA");
+	mciSendStringW_orig = (mciSendStringW_type)::GetProcAddress(winmm_handle, "mciSendStringW");
+	mciGetDeviceIDA_orig = (mciGetDeviceIDA_type)::GetProcAddress(winmm_handle, "mciGetDeviceIDA");
+	mciGetDeviceIDW_orig = (mciGetDeviceIDW_type)::GetProcAddress(winmm_handle, "mciGetDeviceIDW");
+	mciGetDeviceIDFromElementIDA_orig = (mciGetDeviceIDFromElementIDA_type)::GetProcAddress(winmm_handle, "mciGetDeviceIDFromElementIDA");
+	mciGetDeviceIDFromElementIDW_orig = (mciGetDeviceIDFromElementIDW_type)::GetProcAddress(winmm_handle, "mciGetDeviceIDFromElementIDW");
+	mciGetDriverData_orig = (mciGetDriverData_type)::GetProcAddress(winmm_handle, "mciGetDriverData");
+	mciGetErrorStringA_orig = (mciGetErrorStringA_type)::GetProcAddress(winmm_handle, "mciGetErrorStringA");
+	mciGetErrorStringW_orig = (mciGetErrorStringW_type)::GetProcAddress(winmm_handle, "mciGetErrorStringW");
+	mciSetDriverData_orig = (mciSetDriverData_type)::GetProcAddress(winmm_handle, "mciSetDriverData");
+	mciSetYieldProc_orig = (mciSetYieldProc_type)::GetProcAddress(winmm_handle, "mciSetYieldProc");
+	mciFreeCommandResource_orig = (mciFreeCommandResource_type)::GetProcAddress(winmm_handle, "mciFreeCommandResource");
+	mciGetCreatorTask_orig = (mciGetCreatorTask_type)::GetProcAddress(winmm_handle, "mciGetCreatorTask");
+	mciGetYieldProc_orig = (mciGetYieldProc_type)::GetProcAddress(winmm_handle, "mciGetYieldProc");
+	mciLoadCommandResource_orig = (mciLoadCommandResource_type)::GetProcAddress(winmm_handle, "mciLoadCommandResource");
+	mciExecute_orig = (mciExecute_type)::GetProcAddress(winmm_handle, "mciExecute");
+}
+
+extern "C" {
+	LRESULT   WINAPI CloseDriver( HDRVR hDriver, LPARAM lParam1, LPARAM lParam2)
+	{
+		//OutputDebugString(L"CloseDriver\n");
+		return CloseDriver_orig( hDriver, lParam1, lParam2);
+	}
+
+	HDRVR     WINAPI OpenDriver( LPCWSTR szDriverName, LPCWSTR szSectionName, LPARAM lParam2)
+	{
+		//OutputDebugString(L"OpenDriver\n");
+		return OpenDriver_orig( szDriverName, szSectionName, lParam2);
+	}
+
+	LRESULT   WINAPI SendDriverMessage( HDRVR hDriver, UINT message, LPARAM lParam1, LPARAM lParam2)
+	{
+		//OutputDebugString(L"SendDriverMessage\n");
+		return SendDriverMessage_orig( hDriver, message, lParam1, lParam2);
+	}
+
+	HMODULE   WINAPI DrvGetModuleHandle( HDRVR hDriver)
+	{
+		//OutputDebugString(L"DrvGetModuleHandle\n");
+		return DrvGetModuleHandle_orig( hDriver);
+	}
+
+	HMODULE   WINAPI GetDriverModuleHandle( HDRVR hDriver)
+	{
+		//OutputDebugString(L"GetDriverModuleHandle\n");
+		return GetDriverModuleHandle_orig( hDriver);
+	}
+
+	LRESULT   WINAPI DefDriverProc( DWORD_PTR dwDriverIdentifier, HDRVR hdrvr, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
+	{
+		//OutputDebugString(L"DefDriverProc\n");
+		return DefDriverProc_orig( dwDriverIdentifier, hdrvr, uMsg, lParam1, lParam2);
+	}
+
+	BOOL WINAPI DriverCallback( DWORD dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
+	{
+		//OutputDebugString(L"DriverCallback\n");
+		return DriverCallback_orig(dwCallBack, dwFlags, hdrvr, msg, dwUser, dwParam1, dwParam2);
+	}
+
+	UINT WINAPI mmsystemGetVersion(void)
+	{
+		//OutputDebugString(L"mmsystemGetVersion\n");
+		return mmsystemGetVersion_orig();
+	}
+
+	BOOL WINAPI sndPlaySoundA( LPCSTR pszSound, UINT fuSound)
+	{
+		//OutputDebugString(L"sndPlaySoundA\n");
+		return sndPlaySoundA_orig( pszSound, fuSound);
+	}
+
+	BOOL WINAPI sndPlaySoundW( LPCWSTR pszSound, UINT fuSound)
+	{
+		//OutputDebugString(L"sndPlaySoundW\n");
+		return sndPlaySoundW_orig( pszSound, fuSound);
+	}
+
+	BOOL WINAPI PlaySoundA( LPCSTR pszSound, HMODULE hmod, DWORD fdwSound)
+	{
+		//OutputDebugString(L"PlaySoundA\n");
+		return PlaySoundA_orig( pszSound, hmod, fdwSound);
+	}
+
+	BOOL WINAPI PlaySoundW( LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
+	{
+		//OutputDebugString(L"PlaySoundW\n");
+		return PlaySoundW_orig( pszSound, hmod, fdwSound);
+	}
+
+	UINT WINAPI waveOutGetNumDevs(void)
+	{
+		//OutputDebugString(L"waveOutGetNumDevs\n");
+		return waveOutGetNumDevs_orig();
+	}
+
+	MMRESULT WINAPI waveOutGetDevCapsA( UINT_PTR uDeviceID, LPWAVEOUTCAPSA pwoc, UINT cbwoc)
+	{
+		//OutputDebugString(L"waveOutGetDevCapsA\n");
+		return waveOutGetDevCapsA_orig( uDeviceID, pwoc, cbwoc);
+	}
+
+	MMRESULT WINAPI waveOutGetDevCapsW( UINT_PTR uDeviceID, LPWAVEOUTCAPSW pwoc, UINT cbwoc)
+	{
+		//OutputDebugString(L"waveOutGetDevCapsW\n");
+		return waveOutGetDevCapsW_orig( uDeviceID, pwoc, cbwoc);
+	}
+
+
+	MMRESULT WINAPI waveOutGetVolume( HWAVEOUT hwo, LPDWORD pdwVolume)
+	{
+		//OutputDebugString(L"waveOutGetVolume\n");
+		return waveOutGetVolume_orig( hwo, pdwVolume);
+	}
+
+	MMRESULT WINAPI waveOutSetVolume( HWAVEOUT hwo, DWORD dwVolume)
+	{
+		//OutputDebugString(L"waveOutSetVolume\n");
+		return waveOutSetVolume_orig( hwo, dwVolume);
+	}
+
+	MMRESULT WINAPI waveOutGetErrorTextA( MMRESULT mmrError, LPSTR pszText, UINT cchText)
+	{
+		//OutputDebugString(L"waveOutGetErrorTextA\n");
+		return waveOutGetErrorTextA_orig( mmrError, pszText, cchText);
+	}
+
+	MMRESULT WINAPI waveOutGetErrorTextW( MMRESULT mmrError, LPWSTR pszText, UINT cchText)
+	{
+		//OutputDebugString(L"waveOutGetErrorTextW\n");
+		return waveOutGetErrorTextW_orig( mmrError, pszText, cchText);
+	}
+
+	//MMRESULT WINAPI waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
+	//{
+	//	//OutputDebugString(L"waveOutGetErrorTextW\n");
+	//	return waveOutOpen_orig( phwo, uDeviceID, pwfx, dwCallback, dwInstance, fdwOpen);
+	//}
+
+	//MMRESULT WINAPI waveOutClose( HWAVEOUT hwo)
+	//{
+	//	//OutputDebugString(L"waveOutGetErrorTextW\n");
+	//	return waveOutClose_orig( hwo );
+	//}
+
+	MMRESULT WINAPI waveOutPrepareHeader( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
+	{
+		//OutputDebugString(L"waveOutPrepareHeader\n");
+		return waveOutPrepareHeader_orig( hwo, pwh, cbwh);
+	}
+
+	MMRESULT WINAPI waveOutUnprepareHeader( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
+	{
+		//OutputDebugString(L"waveOutUnprepareHeader\n");
+		return waveOutUnprepareHeader_orig( hwo, pwh, cbwh);
+	}
+
+
+	//MMRESULT WINAPI waveOutWrite( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
+	//{
+	//	//OutputDebugString(L"waveOutUnprepareHeader\n");
+	//	return waveOutUnprepareHeader_orig( hwo, pwh, cbwh);
+	//}
+
+	MMRESULT WINAPI waveOutPause( HWAVEOUT hwo)
+	{
+		//OutputDebugString(L"waveOutPause\n");
+		return waveOutPause_orig( hwo);
+	}
+
+	MMRESULT WINAPI waveOutRestart( HWAVEOUT hwo)
+	{
+		//OutputDebugString(L"waveOutRestart\n");
+		return waveOutRestart_orig( hwo);
+	}
+
+	MMRESULT WINAPI waveOutReset( HWAVEOUT hwo)
+	{
+		//OutputDebugString(L"waveOutReset\n");
+		return waveOutReset_orig( hwo);
+	}
+
+	MMRESULT WINAPI waveOutBreakLoop( HWAVEOUT hwo)
+	{
+		//OutputDebugString(L"waveOutBreakLoop\n");
+		return waveOutBreakLoop_orig( hwo);
+	}
+
+	MMRESULT WINAPI waveOutGetPosition( HWAVEOUT hwo, LPMMTIME pmmt, UINT cbmmt)
+	{
+		//OutputDebugString(L"waveOutGetPosition\n");
+		return waveOutGetPosition_orig( hwo, pmmt, cbmmt);
+	}
+
+	MMRESULT WINAPI waveOutGetPitch( HWAVEOUT hwo, LPDWORD pdwPitch)
+	{
+		//OutputDebugString(L"waveOutGetPitch\n");
+		return waveOutGetPitch_orig( hwo, pdwPitch);
+	}
+
+	MMRESULT WINAPI waveOutSetPitch( HWAVEOUT hwo, DWORD dwPitch)
+	{
+		//OutputDebugString(L"waveOutSetPitch\n");
+		return waveOutSetPitch_orig( hwo, dwPitch);
+	}
+
+	MMRESULT WINAPI waveOutGetPlaybackRate( HWAVEOUT hwo, LPDWORD pdwRate)
+	{
+		//OutputDebugString(L"waveOutGetPlaybackRate\n");
+		return waveOutGetPlaybackRate_orig( hwo, pdwRate);
+	}
+
+	MMRESULT WINAPI waveOutSetPlaybackRate( HWAVEOUT hwo, DWORD dwRate)
+	{
+		//OutputDebugString(L"waveOutSetPlaybackRate\n");
+		return waveOutSetPlaybackRate_orig( hwo, dwRate);
+	}
+
+	MMRESULT WINAPI waveOutGetID( HWAVEOUT hwo, LPUINT puDeviceID)
+	{
+		//OutputDebugString(L"waveOutGetID\n");
+		return waveOutGetID_orig( hwo, puDeviceID);
+	}
+
+	MMRESULT WINAPI waveOutMessage( HWAVEOUT hwo, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)
+	{
+		//OutputDebugString(L"waveOutMessage\n");
+		return waveOutMessage_orig( hwo, uMsg, dw1, dw2);
+	}
+
+	UINT WINAPI waveInGetNumDevs(void)
+	{
+		//OutputDebugString(L"waveInGetNumDevs\n");
+		return waveInGetNumDevs_orig();
+	}
+
+	MMRESULT WINAPI waveInGetDevCapsA( UINT_PTR uDeviceID, LPWAVEINCAPSA pwic, UINT cbwic)
+	{
+		//OutputDebugString(L"waveInGetDevCapsA\n");
+		return waveInGetDevCapsA_orig( uDeviceID, pwic, cbwic);
+	}
+
+	MMRESULT WINAPI waveInGetDevCapsW( UINT_PTR uDeviceID, LPWAVEINCAPSW pwic, UINT cbwic)
+	{
+		//OutputDebugString(L"waveInGetDevCapsW\n");
+		return waveInGetDevCapsW_orig( uDeviceID, pwic, cbwic);
+	}
+
+	MMRESULT WINAPI waveInGetErrorTextA(MMRESULT mmrError, LPSTR pszText, UINT cchText)
+	{
+		//OutputDebugString(L"waveInGetErrorTextA\n");
+		return waveInGetErrorTextA_orig(mmrError, pszText, cchText);
+	}
+
+	MMRESULT WINAPI waveInGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText)
+	{
+		//OutputDebugString(L"waveInGetErrorTextW\n");
+		return waveInGetErrorTextW_orig(mmrError, pszText, cchText);
+	}
+
+	MMRESULT WINAPI waveInOpen( LPHWAVEIN phwi, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
+	{
+		//OutputDebugString(L"waveInOpen\n");
+		return waveInOpen_orig(phwi, uDeviceID, pwfx, dwCallback, dwInstance, fdwOpen);
+	}
+
+	MMRESULT WINAPI waveInClose( HWAVEIN hwi)
+	{
+		//OutputDebugString(L"waveInClose\n");
+		return waveInClose_orig( hwi);
+	}
+
+	MMRESULT WINAPI waveInPrepareHeader( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh)
+	{
+		//OutputDebugString(L"waveInPrepareHeader\n");
+		return waveInPrepareHeader_orig( hwi, pwh, cbwh);
+	}
+
+	MMRESULT WINAPI waveInUnprepareHeader( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh)
+	{
+		//OutputDebugString(L"waveInUnprepareHeader\n");
+		return waveInUnprepareHeader_orig( hwi, pwh, cbwh);
+	}
+
+	MMRESULT WINAPI waveInAddBuffer( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh)
+	{
+		//OutputDebugString(L"waveInAddBuffer\n");
+		return waveInAddBuffer_orig( hwi, pwh, cbwh);
+	}
+
+	MMRESULT WINAPI waveInStart( HWAVEIN hwi)
+	{
+		//OutputDebugString(L"waveInStart\n");
+		return waveInStart_orig( hwi);
+	}
+
+	MMRESULT WINAPI waveInStop( HWAVEIN hwi)
+	{
+		//OutputDebugString(L"waveInStop\n");
+		return waveInStop_orig(hwi);
+	}
+
+	MMRESULT WINAPI waveInReset( HWAVEIN hwi)
+	{
+		//OutputDebugString(L"waveInReset\n");
+		return waveInReset_orig(hwi);
+	}
+
+	MMRESULT WINAPI waveInGetPosition( HWAVEIN hwi, LPMMTIME pmmt, UINT cbmmt)
+	{
+		//OutputDebugString(L"waveInGetPosition\n");
+		return waveInGetPosition_orig( hwi, pmmt, cbmmt);
+	}
+
+	MMRESULT WINAPI waveInGetID( HWAVEIN hwi, LPUINT puDeviceID)
+	{
+		//OutputDebugString(L"waveInGetID\n");
+		return waveInGetID_orig( hwi, puDeviceID);
+	}
+
+	MMRESULT WINAPI waveInMessage( HWAVEIN hwi, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)
+	{
+		//OutputDebugString(L"waveInMessage\n");
+		return waveInMessage_orig( hwi, uMsg, dw1, dw2);
+	}
+
+	UINT WINAPI midiOutGetNumDevs(void)
+	{
+		//OutputDebugString(L"midiOutGetNumDevs\n");
+		return midiOutGetNumDevs_orig();
+	}
+
+	MMRESULT WINAPI midiStreamOpen( LPHMIDISTRM phms, LPUINT puDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
+	{
+		//OutputDebugString(L"midiStreamOpen\n");
+		return midiStreamOpen_orig( phms, puDeviceID, cMidi, dwCallback, dwInstance, fdwOpen);
+	}
+
+	MMRESULT WINAPI midiStreamClose( HMIDISTRM hms)
+	{
+		//OutputDebugString(L"midiStreamClose\n");
+		return midiStreamClose_orig( hms);
+	}
+
+	MMRESULT WINAPI midiStreamProperty( HMIDISTRM hms, LPBYTE lppropdata, DWORD dwProperty)
+	{
+		//OutputDebugString(L"midiStreamProperty\n");
+		return midiStreamProperty_orig( hms, lppropdata, dwProperty);
+	}
+
+	MMRESULT WINAPI midiStreamPosition( HMIDISTRM hms, LPMMTIME lpmmt, UINT cbmmt)
+	{
+		//OutputDebugString(L"midiStreamPosition\n");
+		return midiStreamPosition_orig( hms, lpmmt, cbmmt);
+	}
+
+	MMRESULT WINAPI midiStreamOut( HMIDISTRM hms, LPMIDIHDR pmh, UINT cbmh)
+	{
+		//OutputDebugString(L"midiStreamOut\n");
+		return midiStreamOut_orig( hms, pmh, cbmh);
+	}
+
+	MMRESULT WINAPI midiStreamPause( HMIDISTRM hms)
+	{
+		//OutputDebugString(L"midiStreamPause\n");
+		return midiStreamPause_orig( hms);
+	}
+
+	MMRESULT WINAPI midiStreamRestart( HMIDISTRM hms)
+	{
+		//OutputDebugString(L"midiStreamRestart\n");
+		return midiStreamRestart_orig( hms);
+	}
+
+	MMRESULT WINAPI midiStreamStop( HMIDISTRM hms)
+	{
+		//OutputDebugString(L"midiStreamStop\n");
+		return midiStreamStop_orig( hms);
+	}
+
+	MMRESULT WINAPI midiConnect( HMIDI hmi, HMIDIOUT hmo, LPVOID pReserved)
+	{
+		//OutputDebugString(L"midiConnect\n");
+		return midiConnect_orig( hmi, hmo, pReserved);
+	}
+
+	MMRESULT WINAPI midiDisconnect( HMIDI hmi, HMIDIOUT hmo, LPVOID pReserved)
+	{
+		//OutputDebugString(L"midiDisconnect\n");
+		return midiDisconnect_orig( hmi, hmo, pReserved);
+	}
+
+	MMRESULT WINAPI midiOutGetDevCapsA( UINT_PTR uDeviceID, LPMIDIOUTCAPSA pmoc, UINT cbmoc)
+	{
+		//OutputDebugString(L"midiOutGetDevCapsA\n");
+		return midiOutGetDevCapsA_orig( uDeviceID, pmoc, cbmoc);
+	}
+
+	MMRESULT WINAPI midiOutGetDevCapsW( UINT_PTR uDeviceID, LPMIDIOUTCAPSW pmoc, UINT cbmoc)
+	{
+		//OutputDebugString(L"midiOutGetDevCapsW\n");
+		return midiOutGetDevCapsW_orig( uDeviceID, pmoc, cbmoc);
+	}
+
+	MMRESULT WINAPI midiOutGetVolume( HMIDIOUT hmo, LPDWORD pdwVolume)
+	{
+		//OutputDebugString(L"midiOutGetVolume\n");
+		return midiOutGetVolume_orig( hmo, pdwVolume);
+	}
+
+	MMRESULT WINAPI midiOutSetVolume( HMIDIOUT hmo, DWORD dwVolume)
+	{
+		//OutputDebugString(L"midiOutSetVolume\n");
+		return midiOutSetVolume_orig( hmo, dwVolume);
+	}
+
+	MMRESULT WINAPI midiOutGetErrorTextA( MMRESULT mmrError, LPSTR pszText, UINT cchText)
+	{
+		//OutputDebugString(L"midiOutGetErrorTextA\n");
+		return midiOutGetErrorTextA_orig( mmrError, pszText, cchText);
+	}
+
+	MMRESULT WINAPI midiOutGetErrorTextW( MMRESULT mmrError, LPWSTR pszText, UINT cchText)
+	{
+		//OutputDebugString(L"midiOutGetErrorTextW\n");
+		return midiOutGetErrorTextW_orig( mmrError, pszText, cchText);
+	}
+
+	MMRESULT WINAPI midiOutOpen( LPHMIDIOUT phmo, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
+	{
+		//OutputDebugString(L"midiOutOpen\n");
+		return midiOutOpen_orig(phmo, uDeviceID, dwCallback, dwInstance, fdwOpen);
+	}
+
+	MMRESULT WINAPI midiOutClose( HMIDIOUT hmo)
+	{
+		//OutputDebugString(L"midiOutClose\n");
+		return midiOutClose_orig( hmo);
+	}
+
+	MMRESULT WINAPI midiOutPrepareHeader( HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh)
+	{
+		//OutputDebugString(L"midiOutPrepareHeader\n");
+		return midiOutPrepareHeader_orig( hmo, pmh, cbmh);
+	}
+
+	MMRESULT WINAPI midiOutUnprepareHeader(HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh)
+	{
+		//OutputDebugString(L"midiOutUnprepareHeader\n");
+		return midiOutUnprepareHeader_orig(hmo, pmh, cbmh);
+	}
+
+	MMRESULT WINAPI midiOutShortMsg( HMIDIOUT hmo, DWORD dwMsg)
+	{
+		//OutputDebugString(L"midiOutShortMsg\n");
+		return midiOutShortMsg_orig( hmo, dwMsg);
+	}
+
+	MMRESULT WINAPI midiOutLongMsg(HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh)
+	{
+		//OutputDebugString(L"midiOutLongMsg\n");
+		return midiOutLongMsg_orig(hmo, pmh, cbmh);
+	}
+
+	MMRESULT WINAPI midiOutReset( HMIDIOUT hmo)
+	{
+		//OutputDebugString(L"midiOutReset\n");
+		return midiOutReset_orig( hmo);
+	}
+
+	MMRESULT WINAPI midiOutCachePatches( HMIDIOUT hmo, UINT uBank, LPWORD pwpa, UINT fuCache)
+	{
+		//OutputDebugString(L"midiOutCachePatches\n");
+		return midiOutCachePatches_orig( hmo, uBank, pwpa, fuCache);
+	}
+
+	MMRESULT WINAPI midiOutCacheDrumPatches( HMIDIOUT hmo, UINT uPatch, LPWORD pwkya, UINT fuCache)
+	{
+		//OutputDebugString(L"midiOutCacheDrumPatches\n");
+		return midiOutCacheDrumPatches_orig( hmo, uPatch, pwkya, fuCache);
+	}
+
+	MMRESULT WINAPI midiOutGetID( HMIDIOUT hmo, LPUINT puDeviceID)
+	{
+		//OutputDebugString(L"midiOutGetID\n");
+		return midiOutGetID_orig( hmo, puDeviceID);
+	}
+
+	MMRESULT WINAPI midiOutMessage( HMIDIOUT hmo, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)
+	{
+		//OutputDebugString(L"midiOutMessage\n");
+		return midiOutMessage_orig( hmo, uMsg, dw1, dw2);
+	}
+
+	UINT WINAPI midiInGetNumDevs(void)
+	{
+		//OutputDebugString(L"midiInGetNumDevs\n");
+		return midiInGetNumDevs_orig();
+	}
+
+	MMRESULT WINAPI midiInGetDevCapsA( UINT_PTR uDeviceID, LPMIDIINCAPSA pmic, UINT cbmic)
+	{
+		//OutputDebugString(L"midiInGetDevCapsA\n");
+		return midiInGetDevCapsA_orig( uDeviceID, pmic, cbmic);
+	}
+
+	MMRESULT WINAPI midiInGetDevCapsW( UINT_PTR uDeviceID, LPMIDIINCAPSW pmic, UINT cbmic)
+	{
+		//OutputDebugString(L"midiInGetDevCapsW\n");
+		return midiInGetDevCapsW_orig( uDeviceID, pmic, cbmic);
+	}
+
+	MMRESULT WINAPI midiInGetErrorTextA( MMRESULT mmrError, LPSTR pszText, UINT cchText)
+	{
+		//OutputDebugString(L"midiInGetErrorTextA\n");
+		return midiInGetErrorTextA_orig( mmrError, pszText, cchText);
+	}
+
+	MMRESULT WINAPI midiInGetErrorTextW( MMRESULT mmrError, LPWSTR pszText, UINT cchText)
+	{
+		//OutputDebugString(L"midiInGetErrorTextW\n");
+		return midiInGetErrorTextW_orig( mmrError, pszText, cchText);
+	}
+
+	MMRESULT WINAPI midiInOpen( LPHMIDIIN phmi, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
+	{
+		//OutputDebugString(L"midiInOpen\n");
+		return midiInOpen_orig(phmi, uDeviceID, dwCallback, dwInstance, fdwOpen);
+	}
+
+	MMRESULT WINAPI midiInClose( HMIDIIN hmi)
+	{
+		//OutputDebugString(L"midiInClose\n");
+		return midiInClose_orig( hmi);
+	}
+
+	MMRESULT WINAPI midiInPrepareHeader( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh)
+	{
+		//OutputDebugString(L"midiInPrepareHeader\n");
+		return midiInPrepareHeader_orig( hmi, pmh, cbmh);
+	}
+
+	MMRESULT WINAPI midiInUnprepareHeader( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh)
+	{
+		//OutputDebugString(L"midiInUnprepareHeader\n");
+		return midiInUnprepareHeader_orig( hmi, pmh, cbmh);
+	}
+
+	MMRESULT WINAPI midiInAddBuffer( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh)
+	{
+		//OutputDebugString(L"midiInAddBuffer\n");
+		return midiInAddBuffer_orig( hmi, pmh, cbmh);
+	}
+
+	MMRESULT WINAPI midiInStart( HMIDIIN hmi)
+	{
+		//OutputDebugString(L"midiInStart\n");
+		return midiInStart_orig( hmi);
+	}
+
+	MMRESULT WINAPI midiInStop( HMIDIIN hmi)
+	{
+		//OutputDebugString(L"midiInStop\n");
+		return midiInStop_orig(hmi);
+	}
+
+	MMRESULT WINAPI midiInReset( HMIDIIN hmi)
+	{
+		//OutputDebugString(L"midiInReset\n");
+		return midiInReset_orig( hmi);
+	}
+
+	MMRESULT WINAPI midiInGetID( HMIDIIN hmi, LPUINT puDeviceID)
+	{
+		//OutputDebugString(L"midiInGetID\n");
+		return midiInGetID_orig( hmi, puDeviceID);
+	}
+
+	MMRESULT WINAPI midiInMessage( HMIDIIN hmi, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)
+	{
+		//OutputDebugString(L"midiInMessage\n");
+		return midiInMessage_orig( hmi, uMsg, dw1, dw2);
+	}
+
+	UINT WINAPI auxGetNumDevs(void)
+	{
+		//OutputDebugString(L"auxGetNumDevs\n");
+		return auxGetNumDevs_orig();
+	}
+
+	MMRESULT WINAPI auxGetDevCapsA( UINT_PTR uDeviceID, LPAUXCAPSA pac, UINT cbac)
+	{
+		//OutputDebugString(L"auxGetDevCapsA\n");
+		return auxGetDevCapsA_orig( uDeviceID, pac, cbac);
+	}
+
+	MMRESULT WINAPI auxGetDevCapsW( UINT_PTR uDeviceID, LPAUXCAPSW pac, UINT cbac)
+	{
+		//OutputDebugString(L"auxGetDevCapsW\n");
+		return auxGetDevCapsW_orig( uDeviceID, pac, cbac);
+	}
+
+	MMRESULT WINAPI auxSetVolume( UINT uDeviceID, DWORD dwVolume)
+	{
+		//OutputDebugString(L"auxSetVolume\n");
+		return auxSetVolume_orig( uDeviceID, dwVolume);
+	}
+
+	MMRESULT WINAPI auxGetVolume( UINT uDeviceID, LPDWORD pdwVolume)
+	{
+		//OutputDebugString(L"auxGetVolume\n");
+		return auxGetVolume_orig( uDeviceID, pdwVolume);
+	}
+
+	MMRESULT WINAPI auxOutMessage( UINT uDeviceID, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)
+	{
+		//OutputDebugString(L"auxOutMessage\n");
+		return auxOutMessage_orig( uDeviceID, uMsg, dw1, dw2);
+	}
+
+	UINT WINAPI mixerGetNumDevs(void)
+	{
+		//OutputDebugString(L"mixerGetNumDevs\n");
+		return mixerGetNumDevs_orig();
+	}
+
+	MMRESULT WINAPI mixerGetDevCapsA( UINT_PTR uMxId, LPMIXERCAPSA pmxcaps, UINT cbmxcaps)
+	{
+		//OutputDebugString(L"mixerGetDevCapsA\n");
+		return mixerGetDevCapsA_orig( uMxId, pmxcaps, cbmxcaps);
+	}
+
+	MMRESULT WINAPI mixerGetDevCapsW( UINT_PTR uMxId, LPMIXERCAPSW pmxcaps, UINT cbmxcaps)
+	{
+		//OutputDebugString(L"mixerGetDevCapsW\n");
+		return mixerGetDevCapsW_orig( uMxId, pmxcaps, cbmxcaps);
+	}
+
+	MMRESULT WINAPI mixerOpen( LPHMIXER phmx, UINT uMxId, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
+	{
+		//OutputDebugString(L"mixerOpen\n");
+		return mixerOpen_orig( phmx, uMxId, dwCallback, dwInstance, fdwOpen);
+	}
+
+	MMRESULT WINAPI mixerClose( HMIXER hmx)
+	{
+		//OutputDebugString(L"mixerClose\n");
+		return mixerClose_orig( hmx);
+	}
+
+	DWORD WINAPI mixerMessage( HMIXER hmx, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
+	{
+		//OutputDebugString(L"mixerMessage\n");
+		return mixerMessage_orig( hmx, uMsg, dwParam1, dwParam2);
+	}
+
+	MMRESULT WINAPI mixerGetLineInfoA( HMIXEROBJ hmxobj, LPMIXERLINEA pmxl, DWORD fdwInfo)
+	{
+		//OutputDebugString(L"mixerGetLineInfoA\n");
+		return mixerGetLineInfoA_orig( hmxobj, pmxl, fdwInfo);
+	}
+
+	MMRESULT WINAPI mixerGetLineInfoW( HMIXEROBJ hmxobj, LPMIXERLINEW pmxl, DWORD fdwInfo)
+	{
+		//OutputDebugString(L"mixerGetLineInfoW\n");
+		return mixerGetLineInfoW_orig( hmxobj, pmxl, fdwInfo);
+	}
+
+	MMRESULT WINAPI mixerGetID( HMIXEROBJ hmxobj, UINT FAR *puMxId, DWORD fdwId)
+	{
+		//OutputDebugString(L"mixerGetID\n");
+		return mixerGetID_orig( hmxobj, puMxId, fdwId);
+	}
+
+	MMRESULT WINAPI mixerGetLineControlsA( HMIXEROBJ hmxobj, LPMIXERLINECONTROLSA pmxlc, DWORD fdwControls)
+	{
+		//OutputDebugString(L"mixerGetLineControlsA\n");
+		return mixerGetLineControlsA_orig( hmxobj, pmxlc, fdwControls);
+	}
+
+	MMRESULT WINAPI mixerGetLineControlsW( HMIXEROBJ hmxobj, LPMIXERLINECONTROLSW pmxlc, DWORD fdwControls)
+	{
+		//OutputDebugString(L"mixerGetLineControlsW\n");
+		return mixerGetLineControlsW_orig( hmxobj, pmxlc, fdwControls);
+	}
+
+	MMRESULT WINAPI mixerGetControlDetailsA( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)
+	{
+		//OutputDebugString(L"mixerGetControlDetailsA\n");
+		return mixerGetControlDetailsA_orig( hmxobj, pmxcd, fdwDetails);
+	}
+
+	MMRESULT WINAPI mixerGetControlDetailsW( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)
+	{
+		//OutputDebugString(L"mixerGetControlDetailsW\n");
+		return mixerGetControlDetailsW_orig( hmxobj, pmxcd, fdwDetails);
+	}
+
+	MMRESULT WINAPI mixerSetControlDetails( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)
+	{
+		//OutputDebugString(L"mixerSetControlDetails\n");
+		return mixerSetControlDetails_orig( hmxobj, pmxcd, fdwDetails);
+	}
+
+	DWORD    WINAPI mmGetCurrentTask(void)
+	{
+		//OutputDebugString(L"mmGetCurrentTask\n");
+		return mmGetCurrentTask_orig();
+	}
+
+	void WINAPI mmTaskBlock(DWORD val)
+	{
+		//OutputDebugString(L"mmTaskBlock\n");
+		return mmTaskBlock_orig(val);
+	}
+
+	UINT WINAPI mmTaskCreate(LPTASKCALLBACK a, HANDLE* b, DWORD_PTR c)
+	{
+		//OutputDebugString(L"mmTaskCreate\n");
+		return mmTaskCreate_orig(a, b, c);
+	}
+
+	BOOL WINAPI mmTaskSignal(DWORD a)
+	{
+		//OutputDebugString(L"mmTaskSignal\n");
+		return mmTaskSignal_orig(a);
+	}
+
+	VOID WINAPI mmTaskYield()
+	{
+		//OutputDebugString(L"mmTaskYield\n");
+		mmTaskYield_orig();
+	}
+
+	MMRESULT WINAPI timeGetSystemTime( LPMMTIME pmmt, UINT cbmmt)
+	{
+		//OutputDebugString(L"timeGetSystemTime\n");
+		return timeGetSystemTime_orig( pmmt, cbmmt);
+	}
+
+	DWORD WINAPI timeGetTime(void)
+	{
+		//OutputDebugString(L"timeGetTime\n");
+		return timeGetTime_orig();
+	}
+
+	MMRESULT WINAPI timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD_PTR dwUser, UINT fuEvent)
+	{
+		//OutputDebugString(L"timeSetEvent\n");
+		return timeSetEvent_orig(uDelay, uResolution, fptc, dwUser, fuEvent);
+	}
+
+	MMRESULT WINAPI timeKillEvent( UINT uTimerID)
+	{
+		//OutputDebugString(L"timeKillEvent\n");
+		return timeKillEvent_orig( uTimerID);
+	}
+
+	MMRESULT WINAPI timeGetDevCaps( LPTIMECAPS ptc, UINT cbtc)
+	{
+		//OutputDebugString(L"timeGetDevCaps\n");
+		return timeGetDevCaps_orig( ptc, cbtc);
+	}
+
+	MMRESULT WINAPI timeBeginPeriod( UINT uPeriod)
+	{
+		//OutputDebugString(L"timeBeginPeriod\n");
+		return timeBeginPeriod_orig( uPeriod);
+	}
+
+	MMRESULT WINAPI timeEndPeriod( UINT uPeriod)
+	{
+		//OutputDebugString(L"timeEndPeriod\n");
+		return timeEndPeriod_orig( uPeriod);
+	}
+
+	UINT WINAPI joyGetNumDevs(void)
+	{
+		//OutputDebugString(L"joyGetNumDevs\n");
+		return joyGetNumDevs_orig();
+	}
+
+	MMRESULT WINAPI joyConfigChanged(DWORD dwFlags)
+	{
+		//OutputDebugString(L"joyConfigChanged\n");
+		return joyConfigChanged_orig(dwFlags);
+	}
+
+	MMRESULT WINAPI joyGetDevCapsA( UINT_PTR uJoyID, LPJOYCAPSA pjc, UINT cbjc)
+	{
+		//OutputDebugString(L"joyGetDevCapsA\n");
+		return joyGetDevCapsA_orig( uJoyID, pjc, cbjc);
+	}
+
+	MMRESULT WINAPI joyGetDevCapsW( UINT_PTR uJoyID, LPJOYCAPSW pjc, UINT cbjc)
+	{
+		//OutputDebugString(L"joyGetDevCapsW\n");
+		return joyGetDevCapsW_orig( uJoyID, pjc, cbjc);
+	}
+
+	MMRESULT WINAPI joyGetPos( UINT uJoyID, LPJOYINFO pji)
+	{
+		//OutputDebugString(L"joyGetPos\n");
+		return joyGetPos_orig( uJoyID, pji);
+	}
+
+	MMRESULT WINAPI joyGetPosEx( UINT uJoyID, LPJOYINFOEX pji)
+	{
+		//OutputDebugString(L"joyGetPosEx\n");
+		return joyGetPosEx_orig( uJoyID, pji);
+	}
+
+	MMRESULT WINAPI joyGetThreshold( UINT uJoyID, LPUINT puThreshold)
+	{
+		//OutputDebugString(L"joyGetThreshold\n");
+		return joyGetThreshold_orig( uJoyID, puThreshold);
+	}
+
+	MMRESULT WINAPI joyReleaseCapture( UINT uJoyID)
+	{
+		//OutputDebugString(L"joyReleaseCapture\n");
+		return joyReleaseCapture_orig( uJoyID);
+	}
+
+	MMRESULT WINAPI joySetCapture( HWND hwnd, UINT uJoyID, UINT uPeriod, BOOL fChanged)
+	{
+		//OutputDebugString(L"joySetCapture\n");
+		return joySetCapture_orig(hwnd, uJoyID, uPeriod, fChanged);
+	}
+
+	MMRESULT WINAPI joySetThreshold( UINT uJoyID, UINT uThreshold)
+	{
+		//OutputDebugString(L"joySetThreshold\n");
+		return joySetThreshold_orig( uJoyID, uThreshold);
+	}
+
+	BOOL WINAPI  mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
+	{
+		//OutputDebugString(L"mciDriverNotify\n");
+		return mciDriverNotify_orig(hwndCallback, uDeviceID, uStatus);
+	}
+
+	UINT WINAPI  mciDriverYield(UINT uDeviceID)
+	{
+		//OutputDebugString(L"mciDriverYield\n");
+		return mciDriverYield_orig(uDeviceID);
+	}	
+
+	FOURCC WINAPI mmioStringToFOURCCA( LPCSTR sz, UINT uFlags)
+	{
+		//OutputDebugString(L"mmioStringToFOURCCA\n");
+		return mmioStringToFOURCCA_orig( sz, uFlags);
+	}
+
+	FOURCC WINAPI mmioStringToFOURCCW( LPCWSTR sz, UINT uFlags)
+	{
+		//OutputDebugString(L"mmioStringToFOURCCW\n");
+		return mmioStringToFOURCCW_orig( sz, uFlags);
+	}
+
+	LPMMIOPROC WINAPI mmioInstallIOProcA( FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags)
+	{
+		//OutputDebugString(L"mmioInstallIOProcA\n");
+		return mmioInstallIOProcA_orig( fccIOProc, pIOProc, dwFlags);
+	}
+
+	LPMMIOPROC WINAPI mmioInstallIOProcW( FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags)
+	{
+		//OutputDebugString(L"mmioInstallIOProcW\n");
+		return mmioInstallIOProcW_orig( fccIOProc, pIOProc, dwFlags);
+	}
+
+	HMMIO WINAPI mmioOpenA( LPSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen)
+	{
+		//OutputDebugString(L"mmioOpenA\n");
+		return mmioOpenA_orig( pszFileName, pmmioinfo, fdwOpen);
+	}
+
+	HMMIO WINAPI mmioOpenW( LPWSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen)
+	{
+		//OutputDebugString(L"mmioOpenW\n");
+		return mmioOpenW_orig( pszFileName, pmmioinfo, fdwOpen);
+	}
+
+	MMRESULT WINAPI mmioRenameA( LPCSTR pszFileName, LPCSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename)
+	{
+		//OutputDebugString(L"mmioRenameA\n");
+		return mmioRenameA_orig( pszFileName, pszNewFileName, pmmioinfo, fdwRename);
+	}
+
+	MMRESULT WINAPI mmioRenameW( LPCWSTR pszFileName, LPCWSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename)
+	{
+		//OutputDebugString(L"mmioRenameW\n");
+		return mmioRenameW_orig( pszFileName, pszNewFileName, pmmioinfo, fdwRename);
+	}
+
+	MMRESULT WINAPI mmioClose( HMMIO hmmio, UINT fuClose)
+	{
+		//OutputDebugString(L"mmioClose\n");
+		return mmioClose_orig( hmmio, fuClose);
+	}
+
+	LONG WINAPI mmioRead( HMMIO hmmio, HPSTR pch, LONG cch)
+	{
+		//OutputDebugString(L"mmioRead\n");
+		return mmioRead_orig( hmmio, pch, cch);
+	}
+
+	LONG WINAPI mmioWrite( HMMIO hmmio, const char _huge* pch, LONG cch)
+	{
+		//OutputDebugString(L"mmioWrite\n");
+		return mmioWrite_orig( hmmio, pch, cch);
+	}
+
+	LONG WINAPI mmioSeek( HMMIO hmmio, LONG lOffset, int iOrigin)
+	{
+		//OutputDebugString(L"mmioSeek\n");
+		return mmioSeek_orig(hmmio, lOffset, iOrigin);
+	}
+
+	MMRESULT WINAPI mmioGetInfo( HMMIO hmmio, LPMMIOINFO pmmioinfo, UINT fuInfo)
+	{
+		//OutputDebugString(L"mmioGetInfo\n");
+		return mmioGetInfo_orig( hmmio, pmmioinfo, fuInfo);
+	}
+
+	MMRESULT WINAPI mmioSetInfo( HMMIO hmmio, LPCMMIOINFO pmmioinfo, UINT fuInfo)
+	{
+		//OutputDebugString(L"mmioSetInfo\n");
+		return mmioSetInfo_orig( hmmio, pmmioinfo, fuInfo);
+	}
+
+	MMRESULT WINAPI mmioSetBuffer( HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT fuBuffer)
+	{
+		//OutputDebugString(L"mmioSetBuffer\n");
+		return mmioSetBuffer_orig(hmmio, pchBuffer, cchBuffer, fuBuffer);
+	}
+
+	MMRESULT WINAPI mmioFlush( HMMIO hmmio, UINT fuFlush)
+	{
+		//OutputDebugString(L"mmioFlush\n");
+		return mmioFlush_orig( hmmio, fuFlush);
+	}
+
+	MMRESULT WINAPI mmioAdvance( HMMIO hmmio, LPMMIOINFO pmmioinfo, UINT fuAdvance)
+	{
+		//OutputDebugString(L"mmioAdvance\n");
+		return mmioAdvance_orig( hmmio, pmmioinfo, fuAdvance);
+	}
+
+	LRESULT WINAPI mmioSendMessage( HMMIO hmmio, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
+	{
+		//OutputDebugString(L"mmioSendMessage\n");
+		return mmioSendMessage_orig(hmmio, uMsg, lParam1, lParam2);
+	}
+
+	MMRESULT WINAPI mmioDescend( HMMIO hmmio, LPMMCKINFO pmmcki, const MMCKINFO FAR* pmmckiParent, UINT fuDescend)
+	{
+		//OutputDebugString(L"mmioDescend\n");
+		return mmioDescend_orig(hmmio, pmmcki, pmmckiParent, fuDescend);
+	}
+
+	MMRESULT WINAPI mmioAscend( HMMIO hmmio, LPMMCKINFO pmmcki, UINT fuAscend)
+	{
+		//OutputDebugString(L"mmioAscend\n");
+		return mmioAscend_orig( hmmio, pmmcki, fuAscend);
+	}
+
+	MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, LPMMCKINFO pmmcki, UINT fuCreate)
+	{
+		//OutputDebugString(L"mmioCreateChunk\n");
+		return mmioCreateChunk_orig(hmmio, pmmcki, fuCreate);
+	}
+
+	MCIERROR WINAPI mciSendCommandA( MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
+	{
+		//OutputDebugString(L"mciSendCommandA\n");
+		return mciSendCommandA_orig( mciId, uMsg, dwParam1, dwParam2);
+	}
+
+	MCIERROR WINAPI mciSendCommandW( MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
+	{
+		//OutputDebugString(L"mciSendCommandW\n");
+		return mciSendCommandW_orig( mciId, uMsg, dwParam1, dwParam2);
+	}
+
+	MCIERROR  WINAPI mciSendStringA( LPCSTR lpstrCommand, LPSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback)
+	{
+		//OutputDebugString(L"mciSendStringA\n");
+		return mciSendStringA_orig( lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback);
+	}
+
+	MCIERROR  WINAPI mciSendStringW( LPCWSTR lpstrCommand, LPWSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback)
+	{
+		//OutputDebugString(L"mciSendStringW\n");
+		return mciSendStringW_orig( lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback);
+	}
+
+	MCIDEVICEID WINAPI mciGetDeviceIDA( LPCSTR pszDevice)
+	{
+		//OutputDebugString(L"mciGetDeviceIDA\n");
+		return mciGetDeviceIDA_orig( pszDevice);
+	}
+
+	MCIDEVICEID WINAPI mciGetDeviceIDW( LPCWSTR pszDevice)
+	{
+		//OutputDebugString(L"mciGetDeviceIDW\n");
+		return mciGetDeviceIDW_orig( pszDevice);
+	}
+
+	MCIDEVICEID WINAPI mciGetDeviceIDFromElementIDA( DWORD dwElementID, LPCSTR lpstrType )
+	{
+		//OutputDebugString(L"mciGetDeviceIDFromElementIDA\n");
+		return mciGetDeviceIDFromElementIDA_orig( dwElementID, lpstrType );
+	}
+
+	MCIDEVICEID WINAPI mciGetDeviceIDFromElementIDW( DWORD dwElementID, LPCWSTR lpstrType )
+	{
+		//OutputDebugString(L"mciGetDeviceIDFromElementIDW\n");
+		return mciGetDeviceIDFromElementIDW_orig( dwElementID, lpstrType );
+	}
+
+	DWORD_PTR WINAPI  mciGetDriverData(UINT uDeviceID)
+	{
+		//OutputDebugString(L"mciGetDriverData\n");
+		return mciGetDriverData_orig(uDeviceID);
+	}
+
+	BOOL WINAPI mciGetErrorStringA( MCIERROR mcierr, LPSTR pszText, UINT cchText)
+	{
+		//OutputDebugString(L"mciGetErrorStringA\n");
+		return mciGetErrorStringA_orig( mcierr, pszText, cchText);
+	}
+
+	BOOL WINAPI mciGetErrorStringW( MCIERROR mcierr, LPWSTR pszText, UINT cchText)
+	{
+		//OutputDebugString(L"mciGetErrorStringW\n");
+		return mciGetErrorStringW_orig( mcierr, pszText, cchText);
+	}
+
+	BOOL WINAPI  mciSetDriverData(UINT uDeviceID, DWORD_PTR dwData)
+	{
+		//OutputDebugString(L"mciSetDriverData_type\n");
+		return mciSetDriverData_orig( uDeviceID, dwData );
+	}
+
+	BOOL WINAPI mciSetYieldProc( MCIDEVICEID mciId, YIELDPROC fpYieldProc, DWORD dwYieldData)
+	{
+		//OutputDebugString(L"mciSetYieldProc\n");
+		return mciSetYieldProc_orig(mciId, fpYieldProc, dwYieldData);
+	}
+
+	BOOL WINAPI  mciFreeCommandResource(UINT uTable)
+	{
+		//OutputDebugString(L"mciFreeCommandResource\n");
+		return mciFreeCommandResource_orig(uTable);
+	}
+
+	HTASK WINAPI mciGetCreatorTask( MCIDEVICEID mciId)
+	{
+		//OutputDebugString(L"mciGetCreatorTask\n");
+		return mciGetCreatorTask_orig( mciId);
+	}
+
+	YIELDPROC WINAPI mciGetYieldProc( MCIDEVICEID mciId, LPDWORD pdwYieldData)
+	{
+		//OutputDebugString(L"mciGetYieldProc\n");
+		return mciGetYieldProc_orig( mciId, pdwYieldData);
+	}
+
+	UINT WINAPI mciLoadCommandResource(HINSTANCE hInstance, LPCWSTR lpResName, UINT uType)
+	{
+		//OutputDebugString(L"mciLoadCommandResource");
+		return mciLoadCommandResource_orig(hInstance, lpResName, uType);
+	}
+	
+
+	BOOL WINAPI mciExecute(LPCSTR pszCommand)
+	{
+		//OutputDebugString(L"mciExecute\n");
+		return mciExecute_orig(pszCommand);
+	}
+}
\ No newline at end of file
diff --git a/indra/media_plugins/winmmshim/forwarding_api.h b/indra/media_plugins/winmmshim/forwarding_api.h
new file mode 100644
index 0000000000000000000000000000000000000000..31e2186aa2cc6d6b3fc66d3744bea7e3c9d2c7b6
--- /dev/null
+++ b/indra/media_plugins/winmmshim/forwarding_api.h
@@ -0,0 +1,395 @@
+/** 
+ * @file forwarding_api.h
+ * @brief forwards winmm API calls to real winmm.dll
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// this turns off __declspec(dllimport) for the functions declared in mmsystem.h
+#define _WINMM_
+#include <windows.h>
+#include <mmsystem.h>
+
+void init_function_pointers(HMODULE winmm_handle);
+
+typedef VOID (*LPTASKCALLBACK)(DWORD_PTR dwInst);
+
+typedef LRESULT   (WINAPI *CloseDriver_type)( HDRVR hDriver, LPARAM lParam1, LPARAM lParam2);
+extern CloseDriver_type CloseDriver_orig;
+typedef HDRVR     (WINAPI *OpenDriver_type)( LPCWSTR szDriverName, LPCWSTR szSectionName, LPARAM lParam2);
+extern OpenDriver_type OpenDriver_orig;
+typedef LRESULT   (WINAPI *SendDriverMessage_type)( HDRVR hDriver, UINT message, LPARAM lParam1, LPARAM lParam2);
+extern SendDriverMessage_type SendDriverMessage_orig;
+typedef HMODULE   (WINAPI *DrvGetModuleHandle_type)( HDRVR hDriver);
+extern DrvGetModuleHandle_type DrvGetModuleHandle_orig;
+typedef HMODULE   (WINAPI *GetDriverModuleHandle_type)( HDRVR hDriver);
+extern GetDriverModuleHandle_type GetDriverModuleHandle_orig;
+typedef LRESULT   (WINAPI *DefDriverProc_type)( DWORD_PTR dwDriverIdentifier, HDRVR hdrvr, UINT uMsg, LPARAM lParam1, LPARAM lParam2);
+extern DefDriverProc_type DefDriverProc_orig;
+typedef BOOL (WINAPI *DriverCallback_type)(DWORD dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
+extern DriverCallback_type DriverCallback_orig;
+typedef UINT (WINAPI *mmsystemGetVersion_type)(void);
+extern mmsystemGetVersion_type mmsystemGetVersion_orig;
+typedef BOOL (WINAPI *sndPlaySoundA_type)( LPCSTR pszSound, UINT fuSound);
+extern sndPlaySoundA_type sndPlaySoundA_orig;
+typedef BOOL (WINAPI *sndPlaySoundW_type)( LPCWSTR pszSound, UINT fuSound);
+extern sndPlaySoundW_type sndPlaySoundW_orig;
+typedef BOOL (WINAPI *PlaySoundA_type)( LPCSTR pszSound, HMODULE hmod, DWORD fdwSound);
+extern PlaySoundA_type PlaySoundA_orig;
+typedef BOOL (WINAPI *PlaySoundW_type)( LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound);
+extern PlaySoundW_type PlaySoundW_orig;
+typedef UINT (WINAPI *waveOutGetNumDevs_type)(void);
+extern waveOutGetNumDevs_type waveOutGetNumDevs_orig;
+typedef MMRESULT (WINAPI *waveOutGetDevCapsA_type)( UINT_PTR uDeviceID, LPWAVEOUTCAPSA pwoc, UINT cbwoc);
+extern waveOutGetDevCapsA_type waveOutGetDevCapsA_orig;
+typedef MMRESULT (WINAPI *waveOutGetDevCapsW_type)( UINT_PTR uDeviceID, LPWAVEOUTCAPSW pwoc, UINT cbwoc);
+extern waveOutGetDevCapsW_type waveOutGetDevCapsW_orig;
+typedef MMRESULT (WINAPI *waveOutGetVolume_type)( HWAVEOUT hwo, LPDWORD pdwVolume);
+extern waveOutGetVolume_type waveOutGetVolume_orig;
+typedef MMRESULT (WINAPI *waveOutSetVolume_type)( HWAVEOUT hwo, DWORD dwVolume);
+extern waveOutSetVolume_type waveOutSetVolume_orig;
+typedef MMRESULT (WINAPI *waveOutGetErrorTextA_type)( MMRESULT mmrError, LPSTR pszText, UINT cchText);
+extern waveOutGetErrorTextA_type waveOutGetErrorTextA_orig;
+typedef MMRESULT (WINAPI *waveOutGetErrorTextW_type)( MMRESULT mmrError, LPWSTR pszText, UINT cchText);
+extern waveOutGetErrorTextW_type waveOutGetErrorTextW_orig;
+typedef MMRESULT (WINAPI *waveOutOpen_type)( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
+extern waveOutOpen_type waveOutOpen_orig;
+typedef MMRESULT (WINAPI *waveOutClose_type)( HWAVEOUT hwo);
+extern waveOutClose_type waveOutClose_orig;
+typedef MMRESULT (WINAPI *waveOutPrepareHeader_type)( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh);
+extern waveOutPrepareHeader_type waveOutPrepareHeader_orig;
+typedef MMRESULT (WINAPI *waveOutUnprepareHeader_type)( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh);
+extern waveOutUnprepareHeader_type waveOutUnprepareHeader_orig;
+typedef MMRESULT (WINAPI *waveOutWrite_type)( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh);
+extern waveOutWrite_type waveOutWrite_orig;
+typedef MMRESULT (WINAPI *waveOutPause_type)( HWAVEOUT hwo);
+extern waveOutPause_type waveOutPause_orig;
+typedef MMRESULT (WINAPI *waveOutRestart_type)( HWAVEOUT hwo);
+extern waveOutRestart_type waveOutRestart_orig;
+typedef MMRESULT (WINAPI *waveOutReset_type)( HWAVEOUT hwo);
+extern waveOutReset_type waveOutReset_orig;
+typedef MMRESULT (WINAPI *waveOutBreakLoop_type)( HWAVEOUT hwo);
+extern waveOutBreakLoop_type waveOutBreakLoop_orig;
+typedef MMRESULT (WINAPI *waveOutGetPosition_type)( HWAVEOUT hwo, LPMMTIME pmmt, UINT cbmmt);
+extern waveOutGetPosition_type waveOutGetPosition_orig;
+typedef MMRESULT (WINAPI *waveOutGetPitch_type)( HWAVEOUT hwo, LPDWORD pdwPitch);
+extern waveOutGetPitch_type waveOutGetPitch_orig;
+typedef MMRESULT (WINAPI *waveOutSetPitch_type)( HWAVEOUT hwo, DWORD dwPitch);
+extern waveOutSetPitch_type waveOutSetPitch_orig;
+typedef MMRESULT (WINAPI *waveOutGetPlaybackRate_type)( HWAVEOUT hwo, LPDWORD pdwRate);
+extern waveOutGetPlaybackRate_type waveOutGetPlaybackRate_orig;
+typedef MMRESULT (WINAPI *waveOutSetPlaybackRate_type)( HWAVEOUT hwo, DWORD dwRate);
+extern waveOutSetPlaybackRate_type waveOutSetPlaybackRate_orig;
+typedef MMRESULT (WINAPI *waveOutGetID_type)( HWAVEOUT hwo, LPUINT puDeviceID);
+extern waveOutGetID_type waveOutGetID_orig;
+typedef MMRESULT (WINAPI *waveOutMessage_type)( HWAVEOUT hwo, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2);
+extern waveOutMessage_type waveOutMessage_orig;
+typedef UINT (WINAPI *waveInGetNumDevs_type)(void);
+extern waveInGetNumDevs_type waveInGetNumDevs_orig;
+typedef MMRESULT (WINAPI *waveInGetDevCapsA_type)( UINT_PTR uDeviceID, LPWAVEINCAPSA pwic, UINT cbwic);
+extern waveInGetDevCapsA_type waveInGetDevCapsA_orig;
+typedef MMRESULT (WINAPI *waveInGetDevCapsW_type)( UINT_PTR uDeviceID, LPWAVEINCAPSW pwic, UINT cbwic);
+extern waveInGetDevCapsW_type waveInGetDevCapsW_orig;
+typedef MMRESULT (WINAPI *waveInGetErrorTextA_type)(MMRESULT mmrError, LPSTR pszText, UINT cchText);
+extern waveInGetErrorTextA_type waveInGetErrorTextA_orig;
+typedef MMRESULT (WINAPI *waveInGetErrorTextW_type)(MMRESULT mmrError, LPWSTR pszText, UINT cchText);
+extern waveInGetErrorTextW_type waveInGetErrorTextW_orig;
+typedef MMRESULT (WINAPI *waveInOpen_type)( LPHWAVEIN phwi, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
+extern waveInOpen_type waveInOpen_orig;
+typedef MMRESULT (WINAPI *waveInClose_type)( HWAVEIN hwi);
+extern waveInClose_type waveInClose_orig;
+typedef MMRESULT (WINAPI *waveInPrepareHeader_type)( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh);
+extern waveInPrepareHeader_type waveInPrepareHeader_orig;
+typedef MMRESULT (WINAPI *waveInUnprepareHeader_type)( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh);
+extern waveInUnprepareHeader_type waveInUnprepareHeader_orig;
+typedef MMRESULT (WINAPI *waveInAddBuffer_type)( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh);
+extern waveInAddBuffer_type waveInAddBuffer_orig;
+typedef MMRESULT (WINAPI *waveInStart_type)( HWAVEIN hwi);
+extern waveInStart_type waveInStart_orig;
+typedef MMRESULT (WINAPI *waveInStop_type)( HWAVEIN hwi);
+extern waveInStop_type waveInStop_orig;
+typedef MMRESULT (WINAPI *waveInReset_type)( HWAVEIN hwi);
+extern waveInReset_type waveInReset_orig;
+typedef MMRESULT (WINAPI *waveInGetPosition_type)( HWAVEIN hwi, LPMMTIME pmmt, UINT cbmmt);
+extern waveInGetPosition_type waveInGetPosition_orig;
+typedef MMRESULT (WINAPI *waveInGetID_type)( HWAVEIN hwi, LPUINT puDeviceID);
+extern waveInGetID_type waveInGetID_orig;
+typedef MMRESULT (WINAPI *waveInMessage_type)( HWAVEIN hwi, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2);
+extern waveInMessage_type waveInMessage_orig;
+typedef UINT (WINAPI *midiOutGetNumDevs_type)(void);
+extern midiOutGetNumDevs_type midiOutGetNumDevs_orig;
+typedef MMRESULT (WINAPI *midiStreamOpen_type)( LPHMIDISTRM phms, LPUINT puDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
+extern midiStreamOpen_type midiStreamOpen_orig;
+typedef MMRESULT (WINAPI *midiStreamClose_type)( HMIDISTRM hms);
+extern midiStreamClose_type midiStreamClose_orig;
+typedef MMRESULT (WINAPI *midiStreamProperty_type)( HMIDISTRM hms, LPBYTE lppropdata, DWORD dwProperty);
+extern midiStreamProperty_type midiStreamProperty_orig;
+typedef MMRESULT (WINAPI *midiStreamPosition_type)( HMIDISTRM hms, LPMMTIME lpmmt, UINT cbmmt);
+extern midiStreamPosition_type midiStreamPosition_orig;
+typedef MMRESULT (WINAPI *midiStreamOut_type)( HMIDISTRM hms, LPMIDIHDR pmh, UINT cbmh);
+extern midiStreamOut_type midiStreamOut_orig;
+typedef MMRESULT (WINAPI *midiStreamPause_type)( HMIDISTRM hms);
+extern midiStreamPause_type midiStreamPause_orig;
+typedef MMRESULT (WINAPI *midiStreamRestart_type)( HMIDISTRM hms);
+extern midiStreamRestart_type midiStreamRestart_orig;
+typedef MMRESULT (WINAPI *midiStreamStop_type)( HMIDISTRM hms);
+extern midiStreamStop_type midiStreamStop_orig;
+typedef MMRESULT (WINAPI *midiConnect_type)( HMIDI hmi, HMIDIOUT hmo, LPVOID pReserved);
+extern midiConnect_type midiConnect_orig;
+typedef MMRESULT (WINAPI *midiDisconnect_type)( HMIDI hmi, HMIDIOUT hmo, LPVOID pReserved);
+extern midiDisconnect_type midiDisconnect_orig;
+typedef MMRESULT (WINAPI *midiOutGetDevCapsA_type)( UINT_PTR uDeviceID, LPMIDIOUTCAPSA pmoc, UINT cbmoc);
+extern midiOutGetDevCapsA_type midiOutGetDevCapsA_orig;
+typedef MMRESULT (WINAPI *midiOutGetDevCapsW_type)( UINT_PTR uDeviceID, LPMIDIOUTCAPSW pmoc, UINT cbmoc);
+extern midiOutGetDevCapsW_type midiOutGetDevCapsW_orig;
+typedef MMRESULT (WINAPI *midiOutGetVolume_type)( HMIDIOUT hmo, LPDWORD pdwVolume);
+extern midiOutGetVolume_type midiOutGetVolume_orig;
+typedef MMRESULT (WINAPI *midiOutSetVolume_type)( HMIDIOUT hmo, DWORD dwVolume);
+extern midiOutSetVolume_type midiOutSetVolume_orig;
+typedef MMRESULT (WINAPI *midiOutGetErrorTextA_type)( MMRESULT mmrError, LPSTR pszText, UINT cchText);
+extern midiOutGetErrorTextA_type midiOutGetErrorTextA_orig;
+typedef MMRESULT (WINAPI *midiOutGetErrorTextW_type)( MMRESULT mmrError, LPWSTR pszText, UINT cchText);
+extern midiOutGetErrorTextW_type midiOutGetErrorTextW_orig;
+typedef MMRESULT (WINAPI *midiOutOpen_type)( LPHMIDIOUT phmo, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
+extern midiOutOpen_type midiOutOpen_orig;
+typedef MMRESULT (WINAPI *midiOutClose_type)( HMIDIOUT hmo);
+extern midiOutClose_type midiOutClose_orig;
+typedef MMRESULT (WINAPI *midiOutPrepareHeader_type)( HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh);
+extern midiOutPrepareHeader_type midiOutPrepareHeader_orig;
+typedef MMRESULT (WINAPI *midiOutUnprepareHeader_type)(HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh);
+extern midiOutUnprepareHeader_type midiOutUnprepareHeader_orig;
+typedef MMRESULT (WINAPI *midiOutShortMsg_type)( HMIDIOUT hmo, DWORD dwMsg);
+extern midiOutShortMsg_type midiOutShortMsg_orig;
+typedef MMRESULT (WINAPI *midiOutLongMsg_type)(HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh);
+extern midiOutLongMsg_type midiOutLongMsg_orig;
+typedef MMRESULT (WINAPI *midiOutReset_type)( HMIDIOUT hmo);
+extern midiOutReset_type midiOutReset_orig;
+typedef MMRESULT (WINAPI *midiOutCachePatches_type)( HMIDIOUT hmo, UINT uBank, LPWORD pwpa, UINT fuCache);
+extern midiOutCachePatches_type midiOutCachePatches_orig;
+typedef MMRESULT (WINAPI *midiOutCacheDrumPatches_type)( HMIDIOUT hmo, UINT uPatch, LPWORD pwkya, UINT fuCache);
+extern midiOutCacheDrumPatches_type midiOutCacheDrumPatches_orig;
+typedef MMRESULT (WINAPI *midiOutGetID_type)( HMIDIOUT hmo, LPUINT puDeviceID);
+extern midiOutGetID_type midiOutGetID_orig;
+typedef MMRESULT (WINAPI *midiOutMessage_type)( HMIDIOUT hmo, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2);
+extern midiOutMessage_type midiOutMessage_orig;
+typedef UINT (WINAPI *midiInGetNumDevs_type)(void);
+extern midiInGetNumDevs_type midiInGetNumDevs_orig;
+typedef MMRESULT (WINAPI *midiInGetDevCapsA_type)( UINT_PTR uDeviceID, LPMIDIINCAPSA pmic, UINT cbmic);
+extern midiInGetDevCapsA_type midiInGetDevCapsA_orig;
+typedef MMRESULT (WINAPI *midiInGetDevCapsW_type)( UINT_PTR uDeviceID, LPMIDIINCAPSW pmic, UINT cbmic);
+extern midiInGetDevCapsW_type midiInGetDevCapsW_orig;
+typedef MMRESULT (WINAPI *midiInGetErrorTextA_type)( MMRESULT mmrError, LPSTR pszText, UINT cchText);
+extern midiInGetErrorTextA_type midiInGetErrorTextA_orig;
+typedef MMRESULT (WINAPI *midiInGetErrorTextW_type)( MMRESULT mmrError, LPWSTR pszText, UINT cchText);
+extern midiInGetErrorTextW_type midiInGetErrorTextW_orig;
+typedef MMRESULT (WINAPI *midiInOpen_type)( LPHMIDIIN phmi, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
+extern midiInOpen_type midiInOpen_orig;
+typedef MMRESULT (WINAPI *midiInClose_type)( HMIDIIN hmi);
+extern midiInClose_type midiInClose_orig;
+typedef MMRESULT (WINAPI *midiInPrepareHeader_type)( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh);
+extern midiInPrepareHeader_type midiInPrepareHeader_orig;
+typedef MMRESULT (WINAPI *midiInUnprepareHeader_type)( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh);
+extern midiInUnprepareHeader_type midiInUnprepareHeader_orig;
+typedef MMRESULT (WINAPI *midiInAddBuffer_type)( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh);
+extern midiInAddBuffer_type midiInAddBuffer_orig;
+typedef MMRESULT (WINAPI *midiInStart_type)( HMIDIIN hmi);
+extern midiInStart_type midiInStart_orig;
+typedef MMRESULT (WINAPI *midiInStop_type)( HMIDIIN hmi);
+extern midiInStop_type midiInStop_orig;
+typedef MMRESULT (WINAPI *midiInReset_type)( HMIDIIN hmi);
+extern midiInReset_type midiInReset_orig;
+typedef MMRESULT (WINAPI *midiInGetID_type)( HMIDIIN hmi, LPUINT puDeviceID);
+extern midiInGetID_type midiInGetID_orig;
+typedef MMRESULT (WINAPI *midiInMessage_type)( HMIDIIN hmi, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2);
+extern midiInMessage_type midiInMessage_orig;
+typedef UINT (WINAPI *auxGetNumDevs_type)(void);
+extern auxGetNumDevs_type auxGetNumDevs_orig;
+typedef MMRESULT (WINAPI *auxGetDevCapsA_type)( UINT_PTR uDeviceID, LPAUXCAPSA pac, UINT cbac);
+extern auxGetDevCapsA_type auxGetDevCapsA_orig;
+typedef MMRESULT (WINAPI *auxGetDevCapsW_type)( UINT_PTR uDeviceID, LPAUXCAPSW pac, UINT cbac);
+extern auxGetDevCapsW_type auxGetDevCapsW_orig;
+typedef MMRESULT (WINAPI *auxSetVolume_type)( UINT uDeviceID, DWORD dwVolume);
+extern auxSetVolume_type auxSetVolume_orig;
+typedef MMRESULT (WINAPI *auxGetVolume_type)( UINT uDeviceID, LPDWORD pdwVolume);
+extern auxGetVolume_type auxGetVolume_orig;
+typedef MMRESULT (WINAPI *auxOutMessage_type)( UINT uDeviceID, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2);
+extern auxOutMessage_type auxOutMessage_orig;
+typedef UINT (WINAPI *mixerGetNumDevs_type)(void);
+extern mixerGetNumDevs_type mixerGetNumDevs_orig;
+typedef MMRESULT (WINAPI *mixerGetDevCapsA_type)( UINT_PTR uMxId, LPMIXERCAPSA pmxcaps, UINT cbmxcaps);
+extern mixerGetDevCapsA_type mixerGetDevCapsA_orig;
+typedef MMRESULT (WINAPI *mixerGetDevCapsW_type)( UINT_PTR uMxId, LPMIXERCAPSW pmxcaps, UINT cbmxcaps);
+extern mixerGetDevCapsW_type mixerGetDevCapsW_orig;
+typedef MMRESULT (WINAPI *mixerOpen_type)( LPHMIXER phmx, UINT uMxId, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
+extern mixerOpen_type mixerOpen_orig;
+typedef MMRESULT (WINAPI *mixerClose_type)( HMIXER hmx);
+extern mixerClose_type mixerClose_orig;
+typedef DWORD (WINAPI *mixerMessage_type)( HMIXER hmx, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
+extern mixerMessage_type mixerMessage_orig;
+typedef MMRESULT (WINAPI *mixerGetLineInfoA_type)( HMIXEROBJ hmxobj, LPMIXERLINEA pmxl, DWORD fdwInfo);
+extern mixerGetLineInfoA_type mixerGetLineInfoA_orig;
+typedef MMRESULT (WINAPI *mixerGetLineInfoW_type)( HMIXEROBJ hmxobj, LPMIXERLINEW pmxl, DWORD fdwInfo);
+extern mixerGetLineInfoW_type mixerGetLineInfoW_orig;
+typedef MMRESULT (WINAPI *mixerGetID_type)( HMIXEROBJ hmxobj, UINT FAR *puMxId, DWORD fdwId);
+extern mixerGetID_type mixerGetID_orig;
+typedef MMRESULT (WINAPI *mixerGetLineControlsA_type)( HMIXEROBJ hmxobj, LPMIXERLINECONTROLSA pmxlc, DWORD fdwControls);
+extern mixerGetLineControlsA_type mixerGetLineControlsA_orig;
+typedef MMRESULT (WINAPI *mixerGetLineControlsW_type)( HMIXEROBJ hmxobj, LPMIXERLINECONTROLSW pmxlc, DWORD fdwControls);
+extern mixerGetLineControlsW_type mixerGetLineControlsW_orig;
+typedef MMRESULT (WINAPI *mixerGetControlDetailsA_type)( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails);
+extern mixerGetControlDetailsA_type mixerGetControlDetailsA_orig;
+typedef MMRESULT (WINAPI *mixerGetControlDetailsW_type)( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails);
+extern mixerGetControlDetailsW_type mixerGetControlDetailsW_orig;
+typedef MMRESULT (WINAPI *mixerSetControlDetails_type)( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails);
+extern mixerSetControlDetails_type mixerSetControlDetails_orig;
+typedef DWORD    (WINAPI *mmGetCurrentTask_type)(void);
+extern mmGetCurrentTask_type mmGetCurrentTask_orig;
+typedef void (WINAPI *mmTaskBlock_type)(DWORD);
+extern mmTaskBlock_type mmTaskBlock_orig;
+typedef UINT (WINAPI *mmTaskCreate_type)(LPTASKCALLBACK, HANDLE*, DWORD_PTR);
+extern mmTaskCreate_type mmTaskCreate_orig;
+typedef BOOL (WINAPI *mmTaskSignal_type)(DWORD);
+extern mmTaskSignal_type mmTaskSignal_orig;
+typedef VOID (WINAPI *mmTaskYield_type)(VOID);
+extern mmTaskYield_type mmTaskYield_orig;
+typedef MMRESULT (WINAPI *timeGetSystemTime_type)( LPMMTIME pmmt, UINT cbmmt);
+extern timeGetSystemTime_type timeGetSystemTime_orig;
+typedef DWORD (WINAPI *timeGetTime_type)(void);
+extern timeGetTime_type timeGetTime_orig;
+typedef MMRESULT (WINAPI *timeSetEvent_type)( UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD_PTR dwUser, UINT fuEvent);
+extern timeSetEvent_type timeSetEvent_orig;
+typedef MMRESULT (WINAPI *timeKillEvent_type)( UINT uTimerID);
+extern timeKillEvent_type timeKillEvent_orig;
+typedef MMRESULT (WINAPI *timeGetDevCaps_type)( LPTIMECAPS ptc, UINT cbtc);
+extern timeGetDevCaps_type timeGetDevCaps_orig;
+typedef MMRESULT (WINAPI *timeBeginPeriod_type)( UINT uPeriod);
+extern timeBeginPeriod_type timeBeginPeriod_orig;
+typedef MMRESULT (WINAPI *timeEndPeriod_type)( UINT uPeriod);
+extern timeEndPeriod_type timeEndPeriod_orig;
+typedef UINT (WINAPI *joyGetNumDevs_type)(void);
+extern joyGetNumDevs_type joyGetNumDevs_orig;
+typedef MMRESULT (WINAPI *joyConfigChanged_type)(DWORD dwFlags);
+extern joyConfigChanged_type joyConfigChanged_orig;
+typedef MMRESULT (WINAPI *joyGetDevCapsA_type)( UINT_PTR uJoyID, LPJOYCAPSA pjc, UINT cbjc);
+extern joyGetDevCapsA_type joyGetDevCapsA_orig;
+typedef MMRESULT (WINAPI *joyGetDevCapsW_type)( UINT_PTR uJoyID, LPJOYCAPSW pjc, UINT cbjc);
+extern joyGetDevCapsW_type joyGetDevCapsW_orig;
+typedef MMRESULT (WINAPI *joyGetPos_type)( UINT uJoyID, LPJOYINFO pji);
+extern joyGetPos_type joyGetPos_orig;
+typedef MMRESULT (WINAPI *joyGetPosEx_type)( UINT uJoyID, LPJOYINFOEX pji);
+extern joyGetPosEx_type joyGetPosEx_orig;
+typedef MMRESULT (WINAPI *joyGetThreshold_type)( UINT uJoyID, LPUINT puThreshold);
+extern joyGetThreshold_type joyGetThreshold_orig;
+typedef MMRESULT (WINAPI *joyReleaseCapture_type)( UINT uJoyID);
+extern joyReleaseCapture_type joyReleaseCapture_orig;
+typedef MMRESULT (WINAPI *joySetCapture_type)( HWND hwnd, UINT uJoyID, UINT uPeriod, BOOL fChanged);
+extern joySetCapture_type joySetCapture_orig;
+typedef MMRESULT (WINAPI *joySetThreshold_type)( UINT uJoyID, UINT uThreshold);
+extern joySetThreshold_type joySetThreshold_orig;
+typedef BOOL (WINAPI  *mciDriverNotify_type)(HWND hwndCallback, UINT uDeviceID, UINT uStatus);
+extern mciDriverNotify_type mciDriverNotify_orig;
+typedef UINT (WINAPI  *mciDriverYield_type)(UINT uDeviceID);
+extern mciDriverYield_type mciDriverYield_orig;
+typedef FOURCC (WINAPI *mmioStringToFOURCCA_type)( LPCSTR sz, UINT uFlags);
+extern mmioStringToFOURCCA_type mmioStringToFOURCCA_orig;
+typedef FOURCC (WINAPI *mmioStringToFOURCCW_type)( LPCWSTR sz, UINT uFlags);
+extern mmioStringToFOURCCW_type mmioStringToFOURCCW_orig;
+typedef LPMMIOPROC (WINAPI *mmioInstallIOProcA_type)( FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags);
+extern mmioInstallIOProcA_type mmioInstallIOProcA_orig;
+typedef LPMMIOPROC (WINAPI *mmioInstallIOProcW_type)( FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags);
+extern mmioInstallIOProcW_type mmioInstallIOProcW_orig;
+typedef HMMIO (WINAPI *mmioOpenA_type)( LPSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen);
+extern mmioOpenA_type mmioOpenA_orig;
+typedef HMMIO (WINAPI *mmioOpenW_type)( LPWSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen);
+extern mmioOpenW_type mmioOpenW_orig;
+typedef MMRESULT (WINAPI *mmioRenameA_type)( LPCSTR pszFileName, LPCSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename);
+extern mmioRenameA_type mmioRenameA_orig;
+typedef MMRESULT (WINAPI *mmioRenameW_type)( LPCWSTR pszFileName, LPCWSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename);
+extern mmioRenameW_type mmioRenameW_orig;
+typedef MMRESULT (WINAPI *mmioClose_type)( HMMIO hmmio, UINT fuClose);
+extern mmioClose_type mmioClose_orig;
+typedef LONG (WINAPI *mmioRead_type)( HMMIO hmmio, HPSTR pch, LONG cch);
+extern mmioRead_type mmioRead_orig;
+typedef LONG (WINAPI *mmioWrite_type)( HMMIO hmmio, const char _huge* pch, LONG cch);
+extern mmioWrite_type mmioWrite_orig;
+typedef LONG (WINAPI *mmioSeek_type)( HMMIO hmmio, LONG lOffset, int iOrigin);
+extern mmioSeek_type mmioSeek_orig;
+typedef MMRESULT (WINAPI *mmioGetInfo_type)( HMMIO hmmio, LPMMIOINFO pmmioinfo, UINT fuInfo);
+extern mmioGetInfo_type mmioGetInfo_orig;
+typedef MMRESULT (WINAPI *mmioSetInfo_type)( HMMIO hmmio, LPCMMIOINFO pmmioinfo, UINT fuInfo);
+extern mmioSetInfo_type mmioSetInfo_orig;
+typedef MMRESULT (WINAPI *mmioSetBuffer_type)( HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT fuBuffer);
+extern mmioSetBuffer_type mmioSetBuffer_orig;
+typedef MMRESULT (WINAPI *mmioFlush_type)( HMMIO hmmio, UINT fuFlush);
+extern mmioFlush_type mmioFlush_orig;
+typedef MMRESULT (WINAPI *mmioAdvance_type)( HMMIO hmmio, LPMMIOINFO pmmioinfo, UINT fuAdvance);
+extern mmioAdvance_type mmioAdvance_orig;
+typedef LRESULT (WINAPI *mmioSendMessage_type)( HMMIO hmmio, UINT uMsg, LPARAM lParam1, LPARAM lParam2);
+extern mmioSendMessage_type mmioSendMessage_orig;
+typedef MMRESULT (WINAPI *mmioDescend_type)( HMMIO hmmio, LPMMCKINFO pmmcki, const MMCKINFO FAR* pmmckiParent, UINT fuDescend);
+extern mmioDescend_type mmioDescend_orig;
+typedef MMRESULT (WINAPI *mmioAscend_type)( HMMIO hmmio, LPMMCKINFO pmmcki, UINT fuAscend);
+extern mmioAscend_type mmioAscend_orig;
+typedef MMRESULT (WINAPI *mmioCreateChunk_type)(HMMIO hmmio, LPMMCKINFO pmmcki, UINT fuCreate);
+extern mmioCreateChunk_type mmioCreateChunk_orig;
+typedef MCIERROR (WINAPI *mciSendCommandA_type)( MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
+extern mciSendCommandA_type mciSendCommandA_orig;
+typedef MCIERROR (WINAPI *mciSendCommandW_type)( MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
+extern mciSendCommandW_type mciSendCommandW_orig;
+typedef MCIERROR  (WINAPI *mciSendStringA_type)( LPCSTR lpstrCommand, LPSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback);
+extern mciSendStringA_type mciSendStringA_orig;
+typedef MCIERROR  (WINAPI *mciSendStringW_type)( LPCWSTR lpstrCommand, LPWSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback);
+extern mciSendStringW_type mciSendStringW_orig;
+typedef MCIDEVICEID (WINAPI *mciGetDeviceIDA_type)( LPCSTR pszDevice);
+extern mciGetDeviceIDA_type mciGetDeviceIDA_orig;
+typedef MCIDEVICEID (WINAPI *mciGetDeviceIDW_type)( LPCWSTR pszDevice);
+extern mciGetDeviceIDW_type mciGetDeviceIDW_orig;
+typedef MCIDEVICEID (WINAPI *mciGetDeviceIDFromElementIDA_type)( DWORD dwElementID, LPCSTR lpstrType );
+extern mciGetDeviceIDFromElementIDA_type mciGetDeviceIDFromElementIDA_orig;
+typedef MCIDEVICEID (WINAPI *mciGetDeviceIDFromElementIDW_type)( DWORD dwElementID, LPCWSTR lpstrType );
+extern mciGetDeviceIDFromElementIDW_type mciGetDeviceIDFromElementIDW_orig;
+typedef DWORD_PTR (WINAPI  *mciGetDriverData_type)(UINT uDeviceID);
+extern mciGetDriverData_type mciGetDriverData_orig;
+typedef BOOL (WINAPI *mciGetErrorStringA_type)( MCIERROR mcierr, LPSTR pszText, UINT cchText);
+extern mciGetErrorStringA_type mciGetErrorStringA_orig;
+typedef BOOL (WINAPI *mciGetErrorStringW_type)( MCIERROR mcierr, LPWSTR pszText, UINT cchText);
+extern mciGetErrorStringW_type mciGetErrorStringW_orig;
+typedef BOOL (WINAPI  *mciSetDriverData_type)(UINT uDeviceID, DWORD_PTR dwData);
+extern mciSetDriverData_type mciSetDriverData_orig;
+typedef BOOL (WINAPI *mciSetYieldProc_type)( MCIDEVICEID mciId, YIELDPROC fpYieldProc, DWORD dwYieldData);
+extern mciSetYieldProc_type mciSetYieldProc_orig;
+typedef BOOL (WINAPI  *mciFreeCommandResource_type)(UINT uTable);
+extern mciFreeCommandResource_type mciFreeCommandResource_orig;
+typedef HTASK (WINAPI *mciGetCreatorTask_type)( MCIDEVICEID mciId);
+extern mciGetCreatorTask_type mciGetCreatorTask_orig;
+typedef YIELDPROC (WINAPI *mciGetYieldProc_type)( MCIDEVICEID mciId, LPDWORD pdwYieldData);
+extern mciGetYieldProc_type mciGetYieldProc_orig;
+typedef UINT (WINAPI *mciLoadCommandResource_type)(HINSTANCE hInstance, LPCWSTR lpResName, UINT uType);
+extern mciLoadCommandResource_type mciLoadCommandResource_orig;
+typedef BOOL (WINAPI *mciExecute_type)(LPCSTR pszCommand);
+extern mciExecute_type mciExecute_orig;
diff --git a/indra/media_plugins/winmmshim/winmm.def b/indra/media_plugins/winmmshim/winmm.def
new file mode 100644
index 0000000000000000000000000000000000000000..c55a2845f8b50aa0e4a9e7a059ff9666f9df980c
--- /dev/null
+++ b/indra/media_plugins/winmmshim/winmm.def
@@ -0,0 +1,218 @@
+; 
+;   winmm.def
+;
+;   Exports for WINMM DLL
+;
+
+LIBRARY WINMM
+EXPORTS
+CloseDriver
+DefDriverProc
+DriverCallback
+DrvGetModuleHandle
+GetDriverModuleHandle
+;MigrateAllDrivers
+;MigrateSoundEvents
+;NotifyCallbackData
+OpenDriver
+;PlaySound
+PlaySoundA
+PlaySoundW
+SendDriverMessage
+;WOW32DriverCallback
+;WOW32ResolveMultiMediaHandle
+;WOWAppExit
+;WinmmLogoff
+;WinmmLogon
+;aux32Message
+auxGetDevCapsA
+auxGetDevCapsW
+auxGetNumDevs
+auxGetVolume
+auxOutMessage
+auxSetVolume
+;gfxAddGfx
+;gfxBatchChange
+;gfxCreateGfxFactoriesList
+;gfxCreateZoneFactoriesList
+;gfxDestroyDeviceInterfaceList
+;gfxEnumerateGfxs
+;gfxLogoff
+;gfxLogon
+;gfxModifyGfx
+;gfxOpenGfx
+;gfxRemoveGfx
+;joy32Message
+joyConfigChanged
+joyGetDevCapsA
+joyGetDevCapsW
+joyGetNumDevs
+joyGetPos
+joyGetPosEx
+joyGetThreshold
+joyReleaseCapture
+joySetCapture
+joySetThreshold
+;mci32Message
+mciDriverNotify
+mciDriverYield
+mciExecute
+mciFreeCommandResource
+mciGetCreatorTask
+mciGetDeviceIDA
+mciGetDeviceIDFromElementIDA
+mciGetDeviceIDFromElementIDW
+mciGetDeviceIDW
+mciGetDriverData
+mciGetErrorStringA
+mciGetErrorStringW
+mciGetYieldProc
+mciLoadCommandResource
+mciSendCommandA
+mciSendCommandW
+mciSendStringA
+mciSendStringW
+mciSetDriverData
+mciSetYieldProc
+;mid32Message
+midiConnect
+midiDisconnect
+midiInAddBuffer
+midiInClose
+midiInGetDevCapsA
+midiInGetDevCapsW
+midiInGetErrorTextA
+midiInGetErrorTextW
+midiInGetID
+midiInGetNumDevs
+midiInMessage
+midiInOpen
+midiInPrepareHeader
+midiInReset
+midiInStart
+midiInStop
+midiInUnprepareHeader
+midiOutCacheDrumPatches
+midiOutCachePatches
+midiOutClose
+midiOutGetDevCapsA
+midiOutGetDevCapsW
+midiOutGetErrorTextA
+midiOutGetErrorTextW
+midiOutGetID
+midiOutGetNumDevs
+midiOutGetVolume
+midiOutLongMsg
+midiOutMessage
+midiOutOpen
+midiOutPrepareHeader
+midiOutReset
+midiOutSetVolume
+midiOutShortMsg
+midiOutUnprepareHeader
+midiStreamClose
+midiStreamOpen
+midiStreamOut
+midiStreamPause
+midiStreamPosition
+midiStreamProperty
+midiStreamRestart
+midiStreamStop
+mixerClose
+mixerGetControlDetailsA
+mixerGetControlDetailsW
+mixerGetDevCapsA
+mixerGetDevCapsW
+mixerGetID
+mixerGetLineControlsA
+mixerGetLineControlsW
+mixerGetLineInfoA
+mixerGetLineInfoW
+mixerGetNumDevs
+mixerMessage
+mixerOpen
+mixerSetControlDetails
+;mmDrvInstall
+mmGetCurrentTask
+mmTaskBlock
+mmTaskCreate
+mmTaskSignal
+mmTaskYield
+mmioAdvance
+mmioAscend
+mmioClose
+mmioCreateChunk
+mmioDescend
+mmioFlush
+mmioGetInfo
+mmioInstallIOProcA
+mmioInstallIOProcW
+mmioOpenA
+mmioOpenW
+mmioRead
+mmioRenameA
+mmioRenameW
+mmioSeek
+mmioSendMessage
+mmioSetBuffer
+mmioSetInfo
+mmioStringToFOURCCA
+mmioStringToFOURCCW
+mmioWrite
+mmsystemGetVersion
+;mod32Message
+;mxd32Message
+sndPlaySoundA
+sndPlaySoundW
+;tid32Message
+timeBeginPeriod
+timeEndPeriod
+timeGetDevCaps
+timeGetSystemTime
+timeGetTime
+timeKillEvent
+timeSetEvent
+waveInAddBuffer
+waveInClose
+waveInGetDevCapsA
+waveInGetDevCapsW
+waveInGetErrorTextA
+waveInGetErrorTextW
+waveInGetID
+waveInGetNumDevs
+waveInGetPosition
+waveInMessage
+waveInOpen
+waveInPrepareHeader
+waveInReset
+waveInStart
+waveInStop
+waveInUnprepareHeader
+waveOutBreakLoop
+waveOutClose
+waveOutGetDevCapsA
+waveOutGetDevCapsW
+waveOutGetErrorTextA
+waveOutGetErrorTextW
+waveOutGetID
+waveOutGetNumDevs
+waveOutGetPitch
+waveOutGetPlaybackRate
+waveOutGetPosition
+waveOutGetVolume
+waveOutMessage
+waveOutOpen
+waveOutPause
+waveOutPrepareHeader
+waveOutReset
+waveOutRestart
+waveOutSetPitch
+waveOutSetPlaybackRate
+waveOutSetVolume
+waveOutUnprepareHeader
+waveOutWrite
+;wid32Message
+;winmmSetDebugLevel
+;wod32Message
+setPluginVolume
+setPluginMute
\ No newline at end of file
diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a46d908962811a0fee128ed1898b749decd12c75
--- /dev/null
+++ b/indra/media_plugins/winmmshim/winmm_shim.cpp
@@ -0,0 +1,178 @@
+/** 
+ * @file winmmshim.cpp
+ * @brief controls volume level of process by intercepting calls to winmm.dll
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "forwarding_api.h"
+#include <xmmintrin.h>
+#include <map>
+#include <math.h>
+
+using std::wstring;
+
+static float sVolumeLevel = 1.f;
+static bool sMute = false;
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+					 )
+{
+	static bool initialized = false;
+	if (!initialized)
+	{
+		TCHAR system_path[MAX_PATH];
+		TCHAR dll_path[MAX_PATH];
+		::GetSystemDirectory(system_path, MAX_PATH);
+
+		wsprintf(dll_path, "%s\\winmm.dll", system_path);
+		HMODULE winmm_handle = ::LoadLibrary(dll_path);
+		
+		if (winmm_handle != NULL)
+		{
+			initialized = true;
+			init_function_pointers(winmm_handle);
+			return true;
+		}
+		return false;
+	}
+	return true;
+}
+
+
+extern "C" 
+{
+	struct WaveOutFormat
+	{
+		WaveOutFormat(int bits_per_sample)
+		:	mBitsPerSample(bits_per_sample)
+		{}
+		int	mBitsPerSample;
+	};
+	typedef std::map<HWAVEOUT, WaveOutFormat*> wave_out_map_t;
+	static wave_out_map_t sWaveOuts;
+
+	MMRESULT WINAPI waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
+	{
+		//OutputDebugString(L"waveOutOpen\n");
+		if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
+		{
+			return WAVERR_BADFORMAT;
+		}
+		MMRESULT result = waveOutOpen_orig(phwo, uDeviceID, pwfx, dwCallback, dwInstance, fdwOpen);
+		if (result == MMSYSERR_NOERROR 
+			&& ((fdwOpen & WAVE_FORMAT_QUERY) == 0)) // not just querying for format support
+		{
+			WaveOutFormat* wave_outp = new WaveOutFormat(pwfx->wBitsPerSample);
+			sWaveOuts.insert(std::make_pair(*phwo, wave_outp));
+		}
+		return result;
+	}
+
+	MMRESULT WINAPI waveOutClose( HWAVEOUT hwo)
+	{
+		//OutputDebugString(L"waveOutClose\n");
+		wave_out_map_t::iterator found_it = sWaveOuts.find(hwo);
+		if (found_it != sWaveOuts.end())
+		{
+			delete found_it->second;
+			sWaveOuts.erase(found_it);
+		}
+		return waveOutClose_orig( hwo);
+	}
+
+	MMRESULT WINAPI waveOutWrite( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
+	{
+		//OutputDebugString(L"waveOutWrite\n");
+		MMRESULT result = MMSYSERR_NOERROR;
+
+		if (sMute)
+		{
+			memset(pwh->lpData, 0, pwh->dwBufferLength);
+		}
+		else
+		{
+			wave_out_map_t::iterator found_it = sWaveOuts.find(hwo);
+			if (found_it != sWaveOuts.end())
+			{
+				WaveOutFormat* formatp = found_it->second;
+				switch (formatp->mBitsPerSample){
+				case 8:
+					{
+						char volume = (char)(sVolumeLevel * 127.f);
+						for (unsigned int i = 0; i < pwh->dwBufferLength; i++)
+						{
+							pwh->lpData[i] = (pwh->lpData[i] * volume) >> 7;
+						}
+						break;
+					}
+				case 16:
+					{
+						short volume_16 = (short)(sVolumeLevel * 32767.f);
+
+						__m64 volume_64 = _mm_set_pi16(volume_16, volume_16, volume_16, volume_16);
+						__m64 *sample_64;
+						for (sample_64 = (__m64*)pwh->lpData;
+							sample_64 < (__m64*)(pwh->lpData + pwh->dwBufferLength);
+							++sample_64)
+						{
+							__m64 scaled_sample = _mm_mulhi_pi16(*sample_64, volume_64);
+							*sample_64 =  _mm_slli_pi16(scaled_sample, 1); //lose 1 bit of precision here
+						}
+
+						_mm_empty();
+
+						for (short* sample_16 = (short*)sample_64;
+							sample_16 < (short*)(pwh->lpData + pwh->dwBufferLength);
+							++sample_16)
+						{
+							*sample_16 = (*sample_16 * volume_16) >> 15;
+						}
+
+						break;
+					}
+				default:
+					// don't do anything
+					break;
+				}
+			}
+		}
+		return waveOutWrite_orig( hwo, pwh, cbwh);
+	}
+
+	void WINAPI setPluginVolume(float volume)
+	{
+		sVolumeLevel = volume;
+	}
+
+	void WINAPI setPluginMute(bool mute)
+	{
+		sMute = mute;
+	}
+}
\ No newline at end of file
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 99ba356d9e012444690644d47c5bbc2854a293ed..14f9414c920bbfba1508724a3e9bc77dfcccb688 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1457,8 +1457,6 @@ if (WINDOWS)
       ${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt
       ${CMAKE_CURRENT_SOURCE_DIR}/dbghelp.dll
       ${CMAKE_CURRENT_SOURCE_DIR}/fmod.dll
-      ${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}/media_plugin_quicktime.dll
-      ${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}/media_plugin_webkit.dll
       ${ARCH_PREBUILT_DIRS_RELEASE}/libeay32.dll
       ${ARCH_PREBUILT_DIRS_RELEASE}/qtcore4.dll
       ${ARCH_PREBUILT_DIRS_RELEASE}/qtgui4.dll
@@ -1498,6 +1496,7 @@ if (WINDOWS)
       SLPlugin
       media_plugin_quicktime
       media_plugin_webkit
+      winmm_shim
       windows-crash-logger
       windows-updater
       )
@@ -1538,8 +1537,6 @@ if (WINDOWS)
         
     add_dependencies(${VIEWER_BINARY_NAME} 
       SLPlugin 
-      media_plugin_quicktime 
-      media_plugin_webkit
       windows-updater 
       windows-crash-logger
       )
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 2661c9f32b3b9e6aad1a228fdcfacb3c9c037bf6..9559311e3c6def777126d9e80f60a9744c98059c 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -145,7 +145,7 @@ void audio_update_volume(bool force_update)
 	{		
 		F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
 		BOOL music_muted = gSavedSettings.getBOOL("MuteMusic");
-		music_volume = mute_volume * master_volume * (music_volume*music_volume);
+		music_volume = mute_volume * master_volume * music_volume;
 		gAudiop->setInternetStreamGain ( music_muted ? 0.f : music_volume );
 	
 	}
@@ -153,7 +153,7 @@ void audio_update_volume(bool force_update)
 	// Streaming Media
 	F32 media_volume = gSavedSettings.getF32("AudioLevelMedia");
 	BOOL media_muted = gSavedSettings.getBOOL("MuteMedia");
-	media_volume = mute_volume * master_volume * (media_volume*media_volume);
+	media_volume = mute_volume * master_volume * media_volume;
 	LLViewerMedia::setVolume( media_muted ? 0.0f : media_volume );
 
 	// Voice
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 19b18b3282a7033ece655a466bd4196d347d6712..653dbefa18630940a050233ce25842056fc13282 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -332,6 +332,12 @@ def construct(self):
             self.path("media_plugin_webkit.dll")
             self.end_prefix()
 
+		# winmm.dll shim
+        if self.prefix(src='../media_plugins/winmmshim/%s' % self.args['configuration'], dst="llplugin"):
+            self.path("winmm.dll")
+            self.end_prefix()
+
+
         if self.args['configuration'].lower() == 'debug':
             if self.prefix(src=os.path.join(os.pardir, os.pardir, 'libraries', 'i686-win32', 'lib', 'debug'),
                            dst="llplugin"):