Since the emulated Z80 runs a lot faster than a real Z80, the instructions for the AY chip will be delivered in short bursts every frame (at 50Hz). Because of this, the generated audio signal will not be timed exactly right. Normally, this won't be a problem, considering that the error will be less than 0.02 seconds. However, when the program uses precise timing to generate digital sound, it will not work.
One way to generate digital sound on an AY chip is to set both the tone and noise signals off in the mix. This will result in a permanent high output, which can then be modulated with the volume control to produce a waveform. This technique is used in this demo: b2gemba.tap. To handle this I implemented a class which worked in the same way as the beeper, using the nAudio BufferedWaveProvider. Activated by setting both tone and noise off in the mix, whenever the volume changed, I would feed the buffer with a number of samples corresponding to the number of T-states that had passed since the previous volume change, and with the previous amplitude. The nAudio player would then play back the samples at the correct rate. This worked in principle, but the sound quality was not great. I also found that some programs use another technique which my solution did not support. One such game is Parsec (an excellent game by the way) which modulates the volume of a high pitch signal (pitch value 0) to generate some speech synthesis. To handle this I had to synchronize the regular AY signal with the Z80. After some failed experimenting with extending the buffered wave provider to handle all aspects of the AY signal I choose instead to implement an instruction queue of sorts in my existing solution. Instead of processing instructions sent to the AY directly, the instructions are now placed in a queue, together with the sample number within the frame where the instruction should be processed (the sample number corresponding to the T-state at which the instruction was received). I then added a routine in the signal generator Read-method to pull instructions from the queue at the correct point in time with regard to the current sample number within the frame being processed. This solution now also handles the case where a constant high signal is modulated.
0 Comments
|
Archives
November 2020
Categories
All
|