Simutrans Wiki Manual
The official on-line manual for Simutrans. Read and contribute.

[r7168] Music volume lowers after sound effect

Started by An_dz, April 27, 2014, 05:52:14 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


In the Portuguese forum user danielrubens revived an old bug report from 2008 where the music volume is lowered when a sound effect plays. I tested on r7168 and I confirm that the bug exists.


Known issue assuming you're using Windows Vista/7/8. This can't be fixed without completely redoing how Simutrans does sound, and since the sound/music in game is so uncompelling, there's no real incentive to redo.


I assume this is the fundamental problem of mixing two (or more) sounds that each may use the full range of the datatype they are stored in.


Nope. It's the result of not mixing them at all!
With Vista, the Windows mixer was changed to have a single volume per running application rather than separate volumes for different sound types. Simutrans sets the volume for the MIDI out, and then before playing each sound sets the volume for the WAV out. However with Vista, those calls now set the volume for the 'Simutrans' out instead. Hence every sound played changes the music volume. A mixer would have to be added to the Simutrans code.


Ah, so the volume stays down afterwards. I guess Windows will have troubles doing this if one have a hardware MIDI synth. Perhaps even with a non-Windows MIDI synth as well. Does this affect only GDI? The SDL code seems to do mixing.


Yes SDL do sound mixing and playback aparently but itself. The current code only play one sound at a time too for the GDI backend. Not sure, if starting a sound thread would solve this.


A sound thread would not solve this. The only fix is for Simutrans to reduce the volume of the samples being sent to Windows for playback since Windows no longer has a mechanism to mix the sounds/music with different volumes. Or atleast it doesn't in the ancient mmsystem API being used.


Simutrans needs to be able to read WAV files then. After that, stuffing it into DirectSound isn't that hard. It will possibly require a thread to clean up sounds that have finished playing.

Just noticed that while mingw ships with support for Direct3D9 (and even a DirectShow header, that doesn't look functional to me), it doesn't come with DirectSound support. That means 3rd party DirectX headers and import libraries will be necessary. I think I used to use Microsoft's DirectX SDK when I last did DirectX with mingw, but this has now been merged into the Windows SDK, which is not, in general, compatible with GCC. Mingw seems to be becomming obsolete.


Here is a quick and dirty sound backend based on DirectSound 8. Code style is about as messed up as in the other sound backends I based this on. As mentioned, there is a drawback that this won't compile on mingw32 out of the box. Any modern Microsoft SDK as well as mingw64 should work, but I've only tested this with Windows SDK 7.1. I have not tested if this actually cures the music problem, but since volume is set per sample, I can't see how it can not.

There are two quirks with this implementation, neither of which is particularly difficult to change:

  • One sound buffer is created per sample. This means that a sound can not play simultaneously with itself. If there are many sound files, there might be some limit.
  • DirectSound is not shut down properly, since Simutrans doesn't appear to have a concept of having to shut down the sound backends. Hopefully, Windows tidies up properly when the process terminates.

The WAV file loading is also very rudimental. It's possible to do some more tolerant reading using the mmio API, but mmioopen is listed as deprecated.