|
It looks and sounds as if only the DMC period is affecting the pitch. The slopes of the saws are evenly stepped, with no delays in them, so it seems the fine-tune delay isn't having any effect. My guess is that the IRQ occurs immediately after the first (and only) byte is fetched, and that the retriggering of the DMC is delayed until after all 8 bits of the sample have been played:
_ _ | |_ | |_ | |_ | |_ | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | ___| |________________| AB C B C B C B
A: Reset DAC. Start DMC with 1 sample.
B: DMC fetches first and only byte of sample. It invokes IRQ handler immediately since no *more* samples need to be fetched. IRQ handler runs delay loop while DMC outputs 8 1-bit samples.
C: IRQ handler's delay loop completes and DMC is set to restart, but this is deferred since it's already playing. Thus the delay loop has no effect.
B: DMC finishes previous sample. Restart request is noted so it starts playing a new sample. DMC reads byte. No more bytes, so trigger IRQ. IRQ handler enters delay loop.
C: Delay loop finishes... etc.
If this is what's happening, it makes fine-tuning of the overall wave period more tricky. A solution is to insert a larger delay at the end of the wave, with the DMC still outputting the sample while the delay takes place. This would use more CPU time but for lower notes would be somewhat reasonable. The new scheme would work like this:
_ _ | |_ | |_ | |_ | |_ | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | | |_ | ___| |________________| A B C D E
A: Start DMC. Immediate IRQ. Set DMC to start again after current sample finishes.
B: DMC IRQ as it begins second sample. Set DMC to start again after current sample finishes.
C: DMC IRQ as it begins third sample. Delay while DMC finishes
D: DMC finishes sample. Still delaying.
E: Start DMC. Immediate IRQ. Set DMC to start again after current sample finishes.
etc.
In this example, 33% or more CPU would be used for the delay.
I have some other ideas if this is the case. They involve running the DMC with a 17-byte sample to quickly move through some of the samples by setting its period to a higher value for a short time, then setting it back down. This might allow lower CPU usage.
I'm going to modify my NSF player to do what I think the real NES hardware does based on this new data and if it generates similar output, then I'm going to try out some new schemes.
|