December 28th, 2011, 01:25 Posted By: wraggster
Merry Christmas! Since this Sunday happened to occur on the Christmas day, I decided to write most of the post beforehand, and then just add a few words and post it on the actual Christmas day. I don't want to spend all of my Christmas working on DS2x86, I'll need to have some free time to enjoy the holidays as well. :-)
[h=4]Doom audio work[/h]During my first Xmas vacation week I have continued working on the SB digitized audio handling for the new transfer system. On Monday, as I was testing the clicking problem, it occurred to me that it would help me in pinpointing the location of the clicks if I could see the actual waveform produced. Thus I began recording the audio from the Nintendo DS headphone connector to my PC. This was a big help, for example when I added four samples of value 0x90 (where the SB middle point is at 0x80) into a certain position of every 128-byte sample block, I could see that the clicks always happened at offset 32 into this 128-byte block. Due to the fact that Doom sound initialization plays first a small sample before starting the auto-init looping mode, offset 32 meant that the clicks were always at the beginning of the transfer buffer. The actual clicks looked like the following (with the 4 samples of 0x90 value being at the beginning of each 128-sample block):
Finally by Monday evening I found the cause for the clicks in the audio. These were caused by the card FIFO containing an extra word in it before the actual audio sample data, and as the receiving routine on the ARM side assumed the whole transfer buffer consisted of audio samples, these 4 invalid samples caused the clicks. The actual reason why there were an extra word in the FIFO is still a bit of a mystery to me. After spending most of Tuesday experimenting with this, it seemed that the extra word was the result of a previous command to the card when the MIPS side was not able to respond quite as fast as the ARM side expected. The problem got worse when I reduced the MIPS CPU speed, which also pointed to a timing problem. After some more experimenting I finally managed to adjust my new transfer system so that it now seems to work with all possible CPU speeds and with the card FIFO always containing only correct data.
After I got rid of the clicks, I decided to record the whole Doom demo, so that I could compare the audio quality of the original (current) DS2x86 transfer system with the new system. I noticed that in the old system (with the audio playing at a constant 22kHz rate) the audio had repeating 512-sample dropouts, which I had not been able to fix using the original DSTwo audio transfer buffering system. Here below are images of the first AdLib note in Doom, on top is the waveform from the old transfer system (with one 512-sample dropout selected) and below it the waveform from the new system (where AdLib audio is generated on ARM7 and played at 32kHz, so there are no dropouts and the quality is in general much better).
After getting Doom to work, I continued with getting the SB digitized audio of my own LineWars II working. It does not use auto-init audio, instead it does the buffer swapping in software. It re-starts the audio playing from the other buffer inside the SB IRQ (which happens when playing the current buffer finishes). It then prepares the next buffer inside the same IRQ handler, and then returns to the actual game play. This system is currently almost working, but there are gaps in the audio, which I believe occur when the SB IRQ on the MIPS side happens just after the previous 1/30th second block has been transferred to the ARM side. I think I need to delay the audio playing so that I don't keep running out of the currently playing buffer on the ARM7 side before the next buffer transfer has started from the MIPS side to the ARM9 side.
[h=4]New transfer system performance[/h]As I was recording the Doom demos from both the old system and the new transfer system, I noticed that the recording from the old system was considerably longer than the recording from the new system. Seems like this is one way to calculate the real-world speedup that I was able to achieve with the new transfer system. The new system is not fully optimized yet, but it does transfer all graphics and audio data, so the results should be quite comparable. The time it took from the start of the first AdLib note to the end of the final sound was 3:34.90 (or 214.90 seconds) using the old transfer system, and 3:06.94 (186.94 seconds) using the new transfer system. That is, with the new system Doom uses only 87% of the time to run the whole demo, so the new system does give a nice performance boost. Both of these timings were taken with the 360MHz CPU speed and 30fps screen refresh rate with scaling mode Zoom.
[h=4]Plans for the next week[/h]During the remainder of my Xmas vacation I plan to first work on the more essential missing features of the new transfer system, like the whole EGA graphics mode support, and then hopefully still improve the SB digitized audio somewhat. I believe the SB audio support is not quite essential to be included in the next version, but the EGA support pretty much is. I also just added PC speaker audio support to DS2x86, as that is a new feature that has until now been completely missing. Using the old transfer system I would have needed to create a waveform and mix it into the 16-bit stereo buffer (which already had AdLib and SB digitized audio). I thought this was too much work for such a small feature so I never got around to implementing it. However, with the new transfer system all I need to do is to send the frequency value (a single 16-bit value) from the MIPS side, and the ARM7 can then use the PSG sounds to create a beep at that frequency. Very simple, and very similar to the way it works in the original DSx86. The only difference is that in DS2x86 the speaker frequency will only change at most 30 times a second, while in DSx86 it can change much faster.
The next released version of DS2x86 will have the new transfer system, but it will very likely still miss a lot of features. One feature that will probably be completely removed is the ability to take screen copies. This is because the actual screen image is now created on the ARM9 side, and there is no (fast) way to transfer it to the MIPS side for writing to the SD card. If I wanted to have screen copies, I should duplicate the screen handling to the MIPS side, and that would just increase the size of the code too much. In any case, the only thing I can promise for sure is that the next version (with version number 0.30) will run Doom faster than ever before, with much improved audio quality. Any other game or software might not work properly, so please be prepared to have many games still fail to run in the next version. But, I hope that when I get the next version released, you would be interested enough to test your favourite games and report to me in what way they fail to run. :-)
Anyways, have a nice holiday and the end of this year! It might be that I will release the next version on the January 1st, 2012!
For more information and downloads, click here!
There are 0 comments - Join In and Discuss Here