There are several approaches you could use, of course. I'll assume for the moment that you have a 5MHz 65C02, and that whatever display system you intend doesn't need to steal/interleave/stretch cycles in order to operate.
The hardest option, from a CPU load point of view, is direct synthesis on the CPU itself. At 48kHz, that means you need to produce a sample every 104 CPU clocks, regular as clockwork. This is very hard to achieve for any kind of complicated synthesis which would justify this approach. But if you want to try it anyway, I advise putting a FIFO buffer on the I/O port and clocking out from that into the DAC at a hardware controlled rate, rather than attempting to do software timing. If you absolutely *must* try this approach, the 6502 really is not the best tool for the job; try a 68K or an ARM.
The next option is to do DDS using a largish RAM chip and a free-running counter, in which you can adjust the value added per cycle, the wrap address and the wrap decrement under CPU control. The counter should have more bits than the RAM chip has address lines, and you just use the high-order ones (for better frequency precision). You can load samples into the RAM chip from the CPU, either from disk or by pre-calculating synthetic waveforms. Updating this instrument, once running, can be done 1000 times per second with a much more comfortable cycle budget of 5000. The chip itself can make as many samples per second as you like; run it off the same master clock (10 or 20 MHz) as the CPU - ordinary 74HC logic can probably keep up with that if you lay out your PCB sanely.
For bonus marks, find a way to generate multiple overlapping tones (potentially from more than one instrument), and mix them together, by modifying the above hardware. You don't need 20 MS/s for an audio DAC; you can multiplex several address counters onto one RAM chip. You may use a single DAC fed by a digital adder tree, or multiple DACs if you want to apply independent analogue filters afterwards. Or implement a digital filter using a short FIFO and adder tree for frequency/phase effects, and a second RAM chip (64Kwords should be enough) for reverb.
Further bonus marks: feed the address generators into each other for FM synthesis with arbitrary waveforms. Use your imagination.
The third option is an analogue NCO and filter bank, similar to the SID. Again, 1000 updates per second is doable if you need it. Less will usually be quite sufficient. Investigate how quickly typical demoscene chiptunes arpeggiate; you don't need to do much better than that.
A fourth option is to use a speech generator chip. Not sure how easy they are to find these days, but some of them can take an external input signal and run it through their internal filter banks. The data rate they require is not very high; the old TMS5220 runs at 40 50-bit LPC frames per second, for a total of 2Kbps worst case, for an 8kHz sample rate. Within those frames, it interpolates the filter bank parameters in several steps.
You can do smooth interpolation with hardware assistance as well, using an EWMA filter. That is:
Code: Select all
X(n) = (1-1/N) * X(n-1) + (1/N) * C[/code}. If N is a power of two, you only need two adders to implement that. Chain two or more EWMA filters to get a smooth start as well as finish to the curve.