[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