Wow! Thanks Gordon. This is the kinda nitty gritty I was looking for RE PICs and how to make voices with them. I don't completely understand everything you explained, but it's the best description I've found yet. -Blaine --- In korgpolyex@yahoogroups.com, Gordon JC Pearce <gordon@...> wrote: PWM - pulse width modulation - is familiar to us from > synthesis as an effect. With microcontrollers it is used to do > something similar to a DAC. If you connect an LED to a PWM pin, with > PWM set to 50% the LED will be at half brightness, with it set to 25% it > will be at quarter brightness and so on. You pedantic bastards can all > shut the hell up about the linearity of light intensity. > > If you do the PWM fast enough you can no longer hear the carrier (say if > it's at 32kHz) but if you filter that carrier off you get a varying DC > voltage from the pulse width. Now, the "output compare" stuff works > because you have a counter and you compare the value of that with your > desired PWM level. So, start with your output pin high and the counter > at zero, count until you reach 128 and the comparator matches, toggle > the pin low and keep counting until 255 (because we're using an 8-bit > counter for this example), and the counter wraps back to zero so reset > the pin back to high. And, here lies the clever bit. > > When that overflow interrupt fires to say we've wrapped, the ISR > contains a routine that calculates the next value for the sample you > want to play. Let me demonstrate: > > https://github.com/gordonjcp/gyoza/blob/master/acidmatic/acidmatic.pde > > Line 242 is where the ISR starts. This is called every 31.25μs when the > 32kHz timer interrupt fires. Line 245 to 248 set a flag roughly every > 990μs which signals that we should run the envelope calculations. > > line 251-252, phaccu is the phase accumulator. It is a 32-bit value > which has the timing word tword_m added to it for every sample. The > timing word is calculated from 2**32 (the size of the word) times the > desired frequency divided by sample rate) - I *think*, I can't quite > remember how I wrote that bit. Anyway you end up with the upper eight > bits of phaccu being a sawtooth wave at the desired output frequency, > which we get into an 8-bit value icnt by shifting right 24 times. > > line 255 clips it into a squarewave at not quite full scale, to avoid > overdriving the next bit... > > ... which is line 260-262, a fastish integer implementation of a biquad > lowpass. > > line 265 sets the output level by multiplying the filter output by gain > (from 0 to 127) and shifting it back down to 0-255, and finally... > > line 266 loads the value into the output compare register, where it sets > the PWM switching point. > > Whew. Did I mention this all happens in a shade over 31 microseconds? > I haven't got recordings of this exact code, but its predecessor sounded > like this: > http://www.gjcp.net/~gordonjcp/mp3s/arduinoacid.ogg > The drum samples were played by the same Arduino using a similar trick. > > In that repository you'll see another sketch called fmtoy, which sounds > like this: > http://www.gjcp.net/~gordonjcp/mp3s/fmtoy.ogg > > Simple 2-op FM synthesis implemented in a 16MHz AVR, with 8-bit sample > playback hence the gritty aliasing. > > Right, now one of you clever little sods can take that code and work out > how to use it to make a replacement for the Poly800 oscillator chip. > > -- > Gordon JC Pearce MM0YEQ >
Message
Re: A study of Ensoniq Voice Chip (ESQ-1)
2012-10-29 by bimmerfan222
Attachments
- No local attachments were found for this message.