Theo Verelst Digital Sound Synthesis page
Some of the ideas I gathered up on digital synthesis. Note that
due to lack of access to ANY computer system except an internet
terminal currently (a not too slow notebook with sound would be
more than suifficient), I can't program some of the things
I already long thought of. I will include some of the
digital / analog combination ideas I've used in the recent
and far past as well.
Basic tunable sample sound synthesis
Roughly, there are two methods of changing the tuning of a digital
sound sample: changing the playback sample rate, or use varying
sample table increments. The first has the main disadvantage
of either causing reconstruction filter problems or
requiring much higher sample playback rates than strickly needed.
The second may need averaging filters for (fixed point)
point increment factors greater than one or interpolation filters
to prevent sampling noise for increment factors smaller than one,
depending on the sampling noise due to time or amplitude step
inaccuracies.
...
old Z80 fixed point sample pointer update using a 2pow(1/12)
semitone increment lookup table.
register pairs (ops)
==============
(ld BC,(notebase+desired_note))
(ld DE,current_generator_sample_position)
(ld H,sample_base)
Increment B C ; sample incement, 0100h for base note
(add, double)
Relative D E ; per generator relative sample pos.
pointer (ld L,D)
Table H L
Pointer
(ld a,(HL))
(out (n),a)
(EXX)
(repeat and loop)
...
Basic sine generators
A far more complex problem, coupled harmonic oscilators or
waveguides has been tackled here (will add link).
More deatils later.
4 pole time varying resonating and oscilating digitally controlled
filter
Note that this is as yet untested! However, the oscilating wave guide
worked even for lengths of thousands of coupled two pole units,
so I see no reason why a pentium or so with 32 bit word width
operations wouldn't work on this example.
update_filter()
{
for (i=0; i<4; i++) { /* four sections */
a[i] += fc[i]*ii[i]+fcb[i]*a[i];
}
a[0] += fb[3]*fc[0]*a[3]; /* and the feedback */
}
the a variables are the filter storage elements, fc the filter
coefficients, fb the feedback (resonance) component. The rest
is temporal storage + ...
It is quite possible to include non-linearities by including a
table lookup or some kind of polynomial interpolative function
during the feedback or feedforward increment.
Multiple sample playing generators
No additional filtering! Take n=8 for 8 note polyphony with
dual oscilators per voice, and take SAMPLEVALUES as an array
capable of holding at least 2n samples, or wathever alternative
seems fit, these examples were used to do a course MIPS/MFLOP
analysis which made clear these oscillators with the above
filter and additional envelope generator++ stuff would without
much difficulty run on for instance a sharc dsp (costing
$29 industrial price, didn't check all others yet, it was
just to have an idea), with time to spare.
ENVELOPES is an array of structures with a state(either up/down,
or stage1..n, possibly extended with lin/log/table) a relative and
a (quantized) absolute envelope generator value.
all_update_oscilators() /* eternaly looped samples */
{
for (i=0; i(n; i++)
for (j=0; j(2; j++) {
p[i][j] = (p[i][j]+incr[i][j])%sl[i][j];
o[i][j] = ot(p[i][j]);
}
output_samples(o)
}
output_samples(o)
SAMPLEVALUES o;
{
SAMPLEVALUES oe, of;
LONGWORD out;
for (all generators) {
envelope(o,oe);
filter(oe,of);
mixdown(of,out);
}
output_and _da_convert(out);
}
envelopegenerator() /* 1mS or so interupt driven */
{ /* or faster for high accuracy */
ENVELOPES e; /* or split (dynamic timing) */
for (all generators)
{
update(&state,e[].quant);
}
}