One-bit synth technofobies
Mikko Helin
MHELIN at tne01.ntc.nokia.com
Thu Nov 12 16:58:37 CET 1998
I hope this is the right list, but anyway, I've been thinking this
really hard. You know, it is really hard, to do the job of the
sigma-delta modulator. New designs use 128-times (Crystal) and even
256-times (Philips Bitstream) oversampling, which is beyond the Atmel
AVR (AT90S1200) chip's capability. PWM is another way, but I don't
think it could be much better than PC's speaker output (though it's
kind of cool). But the one-bit DACs use PDM (pulse density
modulation), which is much more difficult. The "zero" level with 50%
of one's density is made of "01010101" looking pulse stream. The most
negative output looks like "010010010" (30% one's density) and the
most positive output level with 70% one's density looks like like
"101101101101", that's it.
Instead of it, I've been thinking to use a CS4331 DAC - or actually
half of it in mono mode - to play back waves calculated by the AVR.
OK- this is how it can be done:
MCLK comes from 12.2880 MHz osc to both AVR and DAC.
SCLK is not needed!!
LRCLK is generated by AVR.
SDATA is generated by AVR.
So actually LRCLK and SDATA are the only signals that come out of the
AVR. The input to AVR is two eight-bit latches, which store the phase
accumulation factor (in DCDO application).
So let's go to the timing and wave data output:
* MCLK is 256 x Fs
* one half of the Fs (L or R channel) is 32 SCLK periods of which 16
are used by AVR to output data & lrclk info (two pins on AVR)
* one SCLK period is 4 instructions (or MCLK cycles)
* there are 256 clock cycles (instructions) to make up and play the
16-bit sample, some are needed to shift the bits and output
them, the other like the 16 after L channel sample data frame
and the 32 of the Right channel are used to calculate the next
sample
* the timing and operation for I2S compatible DAC goes like this:
<LRCLK up> ; this starts conversion
<nop> ; one
<nop> ; sample
<nop> ; delay!
<bit 15> ; MSB of the first byte
<op> ; / sampled by DAC
<op> ; \ about here
<op> ;
<bit 14> ; long ... press <Page Down>
<op>
<op>
<op>
<bit 13>
<op>
<op>
<op>
<bit 12>
<op>
<op>
<op>
<bit 11>
<op>
<op>
<op>
<bit 10>
<op>
<op>
<op>
<bit 9>
<op>
<op>
<op>
<bit 8>
<op>
<op>
<op>
<bit 7> ; the second byte is used here!
<op>
<op>
<op>
<bit 6>
<op>
<op>
<op>
<bit 5>
<op>
<op>
<op>
<bit 4>
<op>
<op>
<op>
<bit 3>
<op>
<op>
<op>
<bit 2>
<op>
<op>
<op>
<bit 1>
<op>
<op>
<op>
<bit 0> ; LSB
<op> ; / sampled
<op> ; \ here
<op> ;
<OUTPUT 0> ; 69th instr -> rest bits for 17 - 24 bit
; converters are truncated
<Do something during 128 - 69 = 59 <op>'s >
<LRCLK down>
<Do something during 32 * 4 -1 = 128 -1 = 127 <op>'s,
including the last JMP to the beginning>
It can be seen that two bytes are needed to store the sample value,
and between instructions the accumulator register is just shifted
before output, nothing else needs to be done.
During the 69-cycle period the output frequency is read from the
multiplexed input port, and during the 127-cycle period a new sample
value (two bytes) is calculated.
It's bad AVR hasn't got multiplication instruction, though the bit
shifts can be used.
This code could also work on PIC16C54-HS/P, if it's clocked at 24.576
MHz for 48 kHz sample rate or at 22.5792 MHz for 44.1 kHz sample rate,
as PIC's use two clocks for each cycle. PIC16C54B-HS/P is also dead
cheap (~15 FMK, $3).
Now, if I only had 64 kB of EEPROM, 16-bit registers and
multiplication operation, all would be nicely set for an inexpensive
soft synth. There are such chips, called DSP controllers, and they are
also inexpensive (TMS320C15 etc.) and work at 10-20 MHz rates, one
instruction/clock cycle, in 10-20 MIPS. Somehow they just aren't so
fascinating.
This device could also be used as a simple sample player, at a fixed
frequency, with one voice and with an external EEPROM. Would make a
nice drum player! One unit for BD, another for SD, third for cymbals
and the fourth one for the tom's. As sample playing is not so hard
work that the other channel couldn't also be employed, as there are 59
cycles time for retrieving the next sample (two bytes) from the
EEPROM. You need 16 bit address bus for 64 kB, with multiplexing you
could get more memory access (even megabytes).
Just some thoughts (hope you don't mind),
Mikko
More information about the Synth-diy
mailing list