Can someone please help me understand how the 't_dir_addr' variable is working in Blargg's SNES SPC emulator? The variable is declared in SPC_DSP.h as part of the DSP's state struct and then used in SPC_DSP.cpp.
The 't_dir_addr' variable holds the pointer to the audio source directory and is the result of taking the contents of the DSP's 'DIR' register and the specific voice's 'SRCN' register. Blargg calls these t_dir and t_srcn, respectively. In Blargg's code it correctly calculates the value of 't_dir_addr' as follows in voice processing step 1:
But I don't understand how it can possibly work right because there is only a single t_dir_addr variable for the entire DSP state (i.e. there is only a single t_dir_addr variable to be used by all 8 voices). The problem that I see is that a t_dir_addr value that was calculated for voice N in step V1 can be clobbered by another voice M before it is used in step V2.
A perfect example of this is voice's 6 and 7. If we look in Anomie's apudsp.txt we see (I removed the irrelevant voices to make it clearer):
From the above, in DSP cycle 11 we run voice processing step V1 for voice #6. In this step we calculate the 't_dir_addr' value. And then in DSP cycle 15 we need to use this 't_dir_addr' value in order to get the correct sample pointer. But................in DSP cycle 14 we clobbered the 't_dir_addr' value we needed for voice 6 with the value needed for voice 7. And I have actually confirmed by running the emulator with some debug output enabled that the voice 6 step V1 t_dir_addr assignment really does get clobbered by the assignment in voice 7 step 1.
How can this possibly work right? It seems like you would have to have a separate 't_dir_addr' for each voice in order to ensure that they don't clobber each other.
But obviously the current way that it's coded is correct since Blargg's emulator is extremely accurate. And if I modify the code to have a separate t_dir_addr for each voice then the resulting audio doesn't sound right at all. I really want (need) to understand how/why it works with the t_dir_addr getting clobbered throughout the voice processing steps.
The way I'm thinking about it at a high level is that each voice channel has a separate "directory" of audio data with each DIR+SRCN pair pointing to a unique set of BRR samples. Like so...
DIR+V0SRCN = Pointer to Voice 0 BRR Data
DIR+V1SRCN = Pointer to Voice 1 BRR Data
DIR+V2SRCN = Pointer to Voice 2 BRR Data
...and so on...
But seeing how the t_dir_addr variable gets clobbered across different voices in Blargg's code it doesn't seem to be that simple.
The 't_dir_addr' variable holds the pointer to the audio source directory and is the result of taking the contents of the DSP's 'DIR' register and the specific voice's 'SRCN' register. Blargg calls these t_dir and t_srcn, respectively. In Blargg's code it correctly calculates the value of 't_dir_addr' as follows in voice processing step 1:
Code:
m.t_dir_addr = m.t_dir * 0x100 + m.t_srcn * 4;
But I don't understand how it can possibly work right because there is only a single t_dir_addr variable for the entire DSP state (i.e. there is only a single t_dir_addr variable to be used by all 8 voices). The problem that I see is that a t_dir_addr value that was calculated for voice N in step V1 can be clobbered by another voice M before it is used in step V2.
A perfect example of this is voice's 6 and 7. If we look in Anomie's apudsp.txt we see (I removed the irrelevant voices to make it clearer):
Code:
11. Voice steps: 6:V1
12. Voice steps:
13. Voice steps:
14. Voice steps: 7:V1
15. Voice steps: 6:V2
12. Voice steps:
13. Voice steps:
14. Voice steps: 7:V1
15. Voice steps: 6:V2
From the above, in DSP cycle 11 we run voice processing step V1 for voice #6. In this step we calculate the 't_dir_addr' value. And then in DSP cycle 15 we need to use this 't_dir_addr' value in order to get the correct sample pointer. But................in DSP cycle 14 we clobbered the 't_dir_addr' value we needed for voice 6 with the value needed for voice 7. And I have actually confirmed by running the emulator with some debug output enabled that the voice 6 step V1 t_dir_addr assignment really does get clobbered by the assignment in voice 7 step 1.
How can this possibly work right? It seems like you would have to have a separate 't_dir_addr' for each voice in order to ensure that they don't clobber each other.
But obviously the current way that it's coded is correct since Blargg's emulator is extremely accurate. And if I modify the code to have a separate t_dir_addr for each voice then the resulting audio doesn't sound right at all. I really want (need) to understand how/why it works with the t_dir_addr getting clobbered throughout the voice processing steps.
The way I'm thinking about it at a high level is that each voice channel has a separate "directory" of audio data with each DIR+SRCN pair pointing to a unique set of BRR samples. Like so...
DIR+V0SRCN = Pointer to Voice 0 BRR Data
DIR+V1SRCN = Pointer to Voice 1 BRR Data
DIR+V2SRCN = Pointer to Voice 2 BRR Data
...and so on...
But seeing how the t_dir_addr variable gets clobbered across different voices in Blargg's code it doesn't seem to be that simple.