I've been finding tablereads kinda oppressive when trying to write realtime
instruments with Sfx. Tablereads are a *lot* slower than array references,
since either interpolation has to be performed, or an explicit test has to
be made for the integer-ness of the index. Neither of these is terribly
fast. I'm not sure that interp settings have an effect either way. I'm just
polishing off a performance monitor opcode, but I rather suspect that Sfx's
high-quality interpolator is acually faster than the linear interpolation of
"interp 0" due to the divide required to do linear interpolation. (I'll find
out tomorrow).
My grumble for today: SAOL could *really* use an integer version of
table-read.
I've been tracing through elpelele to figure out why it doesn't run in
realtime. (Reason one: trills and sustains generate enormous numbers of note
instances because SAOl doesn't perform voice scavenging of midi; reason two:
although I can run about 90 elpelele voices, the reverb blows the entire
compute budget because of heavy table-reads performed at a-rate (and a
gratiutous call or two to pow as well)).
Soo.. I came up withe the bright idea of writing my own voice scavenger.
And then the following horrible thought occurred to me.
#define MAX_MIDI_NOTE 128
globals {
ivar iLastNoteInstance[MAX_MIDI_NOTE];
}
kopcode IsNoteDuplicated(ivar iMidiNote)
{
imports exports iLastNoteDuplicated[MAX_MIDI_NOTE];
ivar iNoteInstance;
ksig kMidiNote;
ksig kResult;
kMidiNote = iMidiNote;
iLastNoteInstance[iMidiNote] = iLastNoteInstance[iMidiNote]+1;
iNoteInstance = iLastNoteInstance[iMidiNote];
if (iLastNoteIntance[kMidiNote] == iNoteInstance) { // [1]
return (0);
} else {
return (1);
}
}
The opcode determines whether another note with the same midi pitch has
started since the note started, so that duplicate midinotes can be
automatically note-off'ed.
It's soooo close to being legal. I suspect that its close enough that it
probably does work on most compilers.
Here's the problem. It's a subtle one. If the iLastNoteInstance array really
is copy-in/copy-out-ed then it gets copied-in and copied-out at the
beginning and the end of the i-rate execution pass. Hence, the array
reference on line [1], which would otherwise be legal, fails to get the
correct value since the array doesn't get copied in at the beginning of a
k-cycle. Semantically, I suppose this would be an error, although the
standard doesn't consider this case, although it does explicitly say that
the l-value rate is calculated as expected by this opcode.
I know that SFRONT uses references for imports/exports. Sfx certainly does.
I'm not sure what SAOLC does. Using a reference instead of a
copy-in/copy-out seemed like a pretty safe thing to do, since unless
aliasing occurs, copy-in/copy-out and call-by-reference are provably
equivalent (or so I thought). Since imports exports statements use the
global name, no aliasing can occur.
However, here's a test that would allow a program to actually determine
whether the target of an imports exports statement actually is using
copy-in/copy-out or direct references.
(btw, the fix for the given opcode is to add a first-time flag and grab the
note instance at k-rate, so I'm not toooo upset yet. I'm more concerned
about the fact that behaviour in this case is.. well.... is it or isn't it
legal?).
Regards,
Robin Davies.
This archive was generated by hypermail 2b29 : Mon Jan 28 2002 - 12:03:55 EST