Saturday, 22 November 2008

Major sound handling improvements in S60 SDL

Audio handling in S60v3 SDL port was thoroughly broken. Well, it managed to play something, but the way it did that was just horrid.

In case of OpenTTD, the difference between the 'sdl' and 'null' audio drivers was very much visible. The game had that smooth feeling to it when no audio was playing, but was jerky with the sounds enabled. To make things worse there were cracks and pops just about all the time, which added more of that unpleasant "the phone can't handle it" feeling. Fortunately, these problems are now a thing of the past.

The taxation problem was fixed by these commits. The original author has some really weird ideas there. Introduction of multiple audio buffers increases the audio lag without any benefits. And the handling of audio buffer is just crazy. I will quote the commit message here:
Audio buffer size is there to allow a balancing act between smooth sound playback (ie. big buffer) and low latency times (ie. small buffer). The original author clearly didn't understood this concept, as the buffer size here always was 256 bytes, which resulted in playback system that had all the minuses of the two approaches but no pluses.
With one problem handled, the next one was just around the corner. The cracks and pops may not be easy to hear, but you'll for sure get a feeling that something's wrong. I even have a waveform plot with the gaps in audio data shown: The solution of that problem was to remove some never-correct delay time calculations and use a mutex-like mechanism to handle internal SDL audio wait. With that done the sound is now flawless.

There's also some new functionality added:
  • With silent profile enabled SDL will mute the audio. Mixing will still be done, for the need of games expecting audio-timer synchronization.
  • When the game is out of focus the audio will be disabled as well as mixing, to reduce energy usage.
  • In out of focus situations the video blit incurs a 0.1s delay to reduce power usage. The wait time is rather short for better responsivity when focus is regained and for some rare situations when the screen needs to be redrawn.
Thanks to the above changes the phone with OpenTTD in background now consumes just 0.13W of energy. Comparing it to total idle consumption of 0.11W and previous OpenTTD consumption of 0.5W it's a substantial improvement.