Quote:
I'm reading the code as, "If the 5 sample KON delay has passed then use the Source Loop Start Address (LSA) instead of the Source Start Address (SA).
Yeah. If a KON isn't happening, then the only address it will need is the loop for when it reaches the end.
It only reads one of the two sample addresses (SA, LSA) each time through the DSP loop. When kon_delay is non-zero, a KON is in progress and the sample won't be looping, so it reads SA. Then at some point in the KON process it uses this. Some times through the DSP loop it will read this pointer but not do anything with it, so for those it doesn't matter which it reads.
References:
apudsp.txt wrote:
More specifically, the registers and memory are accessed as follows. Note that
most register values are read once per sample output and cached internally for
use as needed. Note also that the S-DSP may perform some of the "if necessary"
operations unconditionally but only make use of the result "if necessary". For
example, in voice processing step V2 it may load the sample pointer
unconditionally, but this has no effect unless there was a loop or KON.
...
V2. Load the sample pointer (using previously loaded DIR and VxSRCN) if
necessary.
Spc_Dsp.cpp wrote:
Code:
inline VOICE_CLOCK( V2 )
{
// Read sample pointer (ignored if not needed)
byte const* entry = &ram [m.t_dir_addr];
if ( !v->kon_delay ) // *********
entry += 2;
m.t_brr_next_addr = GET_LE16A( entry ); // *********
m.t_adsr0 = VREG(v->regs,adsr0);
// Read pitch, spread over two clocks
m.t_pitch = VREG(v->regs,pitchl);
}
VOICE_CLOCK( V3c )
{
// Pitch modulation using previous voice's output
if ( m.t_pmon & v->vbit )
m.t_pitch += ((m.t_output >> 5) * m.t_pitch) >> 10;
if ( v->kon_delay )
{
// Get ready to start BRR decoding on next sample
if ( v->kon_delay == 5 )
{
v->brr_addr = m.t_brr_next_addr; // *********
v->brr_offset = 1;
v->buf_pos = 0;
m.t_brr_header = 0; // header is ignored on this sample
kon_check = true;
}
...
}
VOICE_CLOCK( V4 )
{
// Decode BRR
m.t_looped = 0;
if ( v->interp_pos >= 0x4000 )
{
decode_brr( v );
if ( (v->brr_offset += 2) >= brr_block_size )
{
// Start decoding next BRR block
assert( v->brr_offset == brr_block_size );
v->brr_addr = (v->brr_addr + brr_block_size) & 0xFFFF;
if ( m.t_brr_header & 1 )
{
v->brr_addr = m.t_brr_next_addr;// *********
m.t_looped = v->vbit;
}
v->brr_offset = 1;
}
}
...
}