Tone production:
 -Get sample from signal generator for toneIndex
 (-Get sample from signal generator for harmonic*toneIndex, and
   for overtoneIndex; multiply these by volume factors and add;
   perhaps in keeping with amplitude controls of AM modulation, the
   volume factors for these should just be shifts??)
 -Put this value in out[ch]

(For fm modulation: Do this before getting effIncr) {
  -Get sample from signal generator for fmIndex, offset appropriately
  -Multiply sample by fmDepth to get fmDisplacement in 256ths of octave
  -Look up fmDisplacement in tables to get interval factor
  -Multiply incr by interval factor to get effIncr
  -NOTE that fm modulation *does not* affect the samples used, it only
   ends up affecting toneIndex, which changes which sample is obtained
   *next* time.
}
 -Increment toneIndex by effIncr (effective increment,which is modified
  version of increment value)
AM modulation:
 -Get sample from signal generator for amIndex, offset appropriately
 -Don't bother scaling this value, the offset should cover it: ranges of
  -1 to 1, 0 to 1, and 0.5 to 1. That's all. I think that's about as much
  variation as a chiptune-style synth warrants.
 -Multiply out[ch] by this sample, keep MSB; NB: This leaves amplitude
  down by half due to signed multiplies!!! Hence my wondering whether to
  do these stages with *unsigned* arithmetic; but then I think the values
  might be wrong?
 -Increment amIndex by amIncr (increment which represents frequency of AM
  modulation)

Envelope application:
 (Only for ADSR envelopes first)
 -Get (unsigned) level for ADSR envelope
 -Multiply out[ch] by this level
 -Raise (or lower, depending on stage of envelope) level by delta for stage
  of envelope
 -...unless we see that that delta would take us past the limit for this
  stage (For attack, limit is 1 (or .9999, whatever); for decay, limit is
  *sustain level*. For sustain, there is no limit, because there is no
  delta! And for release, limit is 0), in which case set level *to* that
  limit, and advance to next stage. If stage had been release, this is
  the time to *stop*.
 -Hmm, as we work out if we'd pass the limit by comparing the distance to
  the limit to the delta, I suppose that we don't have to calculate the
  envelope level as a larger value than its full range...
 (cover graphical envelopes later?)

Is that the whole thing for each channel? Eh, not quite. At some point,
add *panning*, portamento, and normal volume controls. I suppose the
volume controls could be built into the envelope stage? Mmmh, I don't
think that's any different really.
Having done all that, possibly add a compensation factor to make up for
the fact that maximum amplitude for am, volume, and envelope, is 127/128
or 32767/32768? Perhaps just deal with it *shrug*

Now, that's for each channel in the sense of "voice". Still need to deal
with channels in the sense of left-vs-right speakers.
For each output channel, go through all the voice channels, and add the
values of out[ch] into a variable "mix", which should be big enough to
store such a value. Then divide by 4 or 8 as appropriate. This is of
course just shifting. EXCEPT that we have signed values...
(NB: Have written "intcast" test program to experiment with the effects
of various different integer castings, for a broad range of numbers;
this might help me figure out how to do this safely)


Now, if playing an 8-bit sound into 16-bit output device, or vice-versa,
must do *more* rescaling :(


-THEN, having processed some number of these samples (based on a samplerate-
dependant counter), call the function that updates the player state (eg:
start new notes playing, stop notes, change instruments, etc). When that
function returns.... continue processing :)
 Uh, unless the function says the playing has finished? I suppose it could
give a return value in such a case. The playing finishes when there's no
more notes pending, and all have either been cut or reached the end of their
ADSR release stage.
