[hatari-devel] DMA sound improvements

Nicolas Pomarède npomarede at corp.free.fr
Thu Apr 7 23:31:48 CEST 2011


Hello

I committed a first round of patches that should improve sound quality 
as well as accuracy.

  - use fixed values for dma sound freqs ; on STE, clock for dma sound 
(as well as fdc or ym2149) is not the result of dividing the main 32 Mhz 
clock, but it uses a separate dedicated 8 Mhz clock (also, dividing by 
160,320,... doesn't give the right value anyway)

  - reorder / factorize some common code

  - handle programs that write in the sample buffer at the same time 
this buffer is played by the DMA

This last point is audible in the demo "Mental Hangover" for example 
(very noisy sound output) as well as in the game "Power Up Plus" (nearly 
no sound at all).

In order to fix this, I updated the code to work in a similar way to DMA 
sound on a real STE. On STE, the DMA sound uses a small 8 bytes FIFO to 
store the next bytes to be sent to the DAC at the requested output freq 
(50066, 25033, ...).
To keep this FIFO filled (you need approx 6.5 bytes per VBL at 50066 Hz 
stereo), the DMA sound has some bus accesses during the end of the HBL 
(while the shifter doesn't need to read data to be displayed).
During those accesses, the DMA sound will read as many bytes as 
necessary to get 8 bytes in the FIFO.

This means that once the DMA read some bytes at the current sample frame 
address, you can immediatly write some new bytes in the sample buffer 
before this address, those addresses won't be read until the sample loops.

So, even if it's more complex than using double buffer, it's completly 
possible to have a single buffer replay routine that generates new 
samples at the same time it plays the rest of the buffer (this is 
similar to how some demos work at the video level, where they use only 
one video buffer and use some synchronisation with $ff8209 to be sure 
there's no "conflict" with the data the shifter will read next (the game 
Enchanted Lands works this way due to RAM limit to use double buffer for 
video)).

To emulate this way of processing DMA sound bytes, I added the function 
DmaSnd_HBL_Update and call this function on every HBL in video.c. This 
way, we now "read" sample data at the same video position that the DMA 
does on STE (in the case of Hatari, I don't handle a real 8 bytes FIFO, 
but this difference should not be hearable).

Instead of generating ~500 samples in one go per VBL (for 25066 Hz 
sound), we now generate small chunks of samples at every HBL. The most 
important for this to work is that the total number of bytes per VBL 
remains the same (but whether we generate one big chunk in one go or 100 
smallers chunks doesn't matter).


Let me know if you here some regressions. I'm not sure a lot of programs 
will benefit from this fix, as using single buffer instead of double 
buffer when generating sample is rather rare.


I still have some other patches pending to increase accuracy as well as 
fixing the audio/video synchro problem reported in "More Or Less Zero", 
but they require modifications to other parts than dmaSnd.c, so it will 
take a little more time to clean.


PS : Anders, regarding the DMA sound FIFO, you once told me that doing a 
stop/start to change sample address was messing with the overscan timing 
(because the DMA will try to read 8 bytes in one go), but have you ever 
tried to play 50066 Hz stereo sound during an overscan in loop mode ? 
I'd like to know if this breaks the timings (with 230 or 224 bytes per line)



Nicolas



More information about the hatari-devel mailing list