Background: MediaPortal on Windows 7 only allows changing the volume and playing back UI sounds(e.g. key presses) on the default audio device. If you have multiple audio devices on Windows 7, and want to have MediaPortal channel all audio output to the non-default device, this patch is what you probably need. NOTE: This patch has only been tested on MediaPortal 1.2.3 on Windows 7. USE AT YOUR OWN RISK! --------------------------------------------------------------------- Binaries Installation For Users: 1. Close MediaPortal if it is running. 2. Make a copy of Configuration.exe and core.dll in the MediaPortal installation folder ("C:\Program Files (x86)\Team MediaPortal\MediaPortal" for 64-bit Windows 7 and "C:\Program Files\Team MediaPortal\MediaPortal" for 32-bit Windows 7). 3. Copy the patched Configuration.exe and core.dll binaries from "Binaries\Program Files (x86)\Team MediaPortal\MediaPortal" in this archive and overwrite the original copies in the MediaPortal installation folder above. 4. Open <MediaPortal Configuration->General->Volume Settings> and set the Audio Renderer to the device that you want MediaPortal to play back all UI sounds and change the volume with. 5. Save and close MediaPortal Configuration. 6. Open MediaPortal. Observe that all UI sounds are properly played back through the selected audio device, even though it may not be set as the default Windows audio device. Also observe that changing the volume now works as expected. --------------------------------------------------------------------- For Developers Only: Any kind MediaPortal developers who feels that this is a useful patch and has some time to spare, please feel free to evaluate and integrate the patched sources included in this archive for future Mediaportal releases. I am not a MediaPortal developer nor am I a native C# developer, so my approach may not be the most ideal. It may even be plain stupid. Comments are welcome though. Here's a short write-up of the changes made and their potential issues/improvement: 1. GeneralVolume.cs I decided that the Volume Settings tab is the most convenient place to display the Audio Renderer selection combo box, with minimal changes required. This adds a new 'audiorenderer' setting to MediaPortal.xml under the same volume section. Enumeration of the audio devices makes use of DirectSound's DevicesCollection() API called in MediaPortal.Util.Utils.GetAudioDevices(). [Thoughts] Not exactly the most intuitive place for this setting. Maybe a separate tab under 'Codecs and Renderer' would have been better. 2. Mixer.cs and MixerNativeMethods.cs Changes here are to allow volume changing to be done through the selected audio device, and not always to use the default audio device. A new method 'Open(string mixerName, bool isDigital)' is added to overload the existing 'Open(int mixerIndex, bool isDigital)'. The overloaded Open() takes in the 'mixerName' string from the caller(MediaPortal.Player.VolumeHandler()) and uses it to find the corresponding mixer device index from the list of mixers registered with the system. The matched mixer index is then passed through the original Open() method. [Thoughts] Would be better if the mixer index matching can be done only once during startup, and not having to do this everytime the volume is changed. Is there a dedicated place to perform such one-time initializations? [Update] On second thoughts, it is better to retain the dynamic matching of device name to mixer index, since mixer indices change as the system default audio device is changed. 3. VolumeHandler.cs This is a simple change to fetch the selected audiorenderer setting from MediaPortal.xml and then call the overloaded 'Open(string mixerName, bool isDigital)' with the selected audiorenderer string instead of the original 'Open(int mixerIndex, bool isDigital)' with the mixerIndex always set to '0' ('0' specifies the default mixer device). 4. Util.cs A new method 'PlaySoundToDevice(string sSoundFile, int Snd_Options)' is added to do the work of playing the sound that was originally done with sndPlaySoundA(), which only allows sending the output to the default audio device. 'PlaySoundToDevice()' uses DirectSound APIs to play the wav files, simply because it is easier than using the primitive waveout functions. [Thoughts] Would be better if the audio device guid matching can be done only once during startup, and not having to do this everytime a sound is played. Is there a dedicated place to perform such one-time initializations? [Update 1.1] Fixed. Perform the one-time matching within the static constructor, and store the matched device guid as a static variable. Also changed some DirectSound parameters to eliminate 'pops' and 'missed' sounds.