Korg Poly800/EX800 Users group photo

Yahoo Groups archive

Korg Poly800/EX800 Users

Index last updated: 2026-04-28 23:27 UTC

Message

Re: A study of Ensoniq Voice Chip (ESQ-1)

2012-10-29 by bimmerfan222

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
>

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.