Sigma-Delta or plain delta modulation on Arduinos

Yeah, I know it's not Arduino. I am making a chiptune synth on an ATMega328, Olivier is using a ATMega644p, both are rated for 20Mhz clock max, so it is not overclocked. These two chips have the same timers I think.

https://github.com/pichenettes/shruthi-1/blob/master/shruthi/shruthi.cc

In shruthi/shruthi.cc you can see he is using the 8-bit Timer2, and producing a sample approximately every 40khz.

On my project I am using Phase Correct Fast PWM mode, so the timer counts from 0 to 255, and then down to 0 again, 510 clock divisions, 20Mhz / 510 ~= 39215.7 MHz

In the same file you can see he is using phase correct mode as well:

Timer<2>::set_prescaler(1);
Timer<2>::set_mode(TIMER_PWM_PHASE_CORRECT);

Then in the interrupt handler you see where he causes a sample to be emitted:

ISR(TIMER2_OVF_vect) {
     ...
     // 40kHz: audio sample
    audio_out.EmitSample();

audio_out is a an instance of a class derived from his custom AVR library Avril, avrlib::AudioOutput< avrlib::PwmOutput>

https://github.com/pichenettes/avril/blob/master/audio_output.h

// Audio output. Supports PWM (through a PwmOutput object) and DAC (through a 
// Dac object, for example the one defined in mcp492x.h).

Now we check https://github.com/pichenettes/avril/blob/master/devices/mcp492x.h

Which is his C++ template driver:

// Driver for a MCP492x DAC (SPI single/dual 12-bits DAC).

You're right, it is outputting 10MHz, not 1MHz, I remembered that wrong, but this is why I'm saying he is ultimately using a DAC for converting his 8-bit value to 10MHz 1-bit. That DAC uses SPI, so I believe he needs to bit-bang the 8-bit value into it.

Having said all that, you can produce audio with the PWM modes on an ATMega processor that will inherently be 1-bit, followed by a filter to smooth it out into analog voltages without a DAC. The description of how to do that is in the OpenMusicLabs link in my previous post, and this is probably the direction I'm going to go, for now.

If you produce a PWM carrier wave at frequency Fs, which is twice as high as human hearing, preferably higher still, it divides time into segments of 1/Fs seconds, and that would be your digital sample period. You can set the timer to either overflow or match the output compare register every T = 1/Fs seconds, and call an interrupt, like in the Shruthi

If you were using an 8-bit timer, and it overflows after 255, that divides the period T into 256 smaller segments where it can be high 1, or low 0, depending on the duty cycle.

You take your 8-bit sample value, 0-255 for example, and set the duty cycle using that number, and on average the voltage will be some number between 0 and 5V, like as if you were dimming an LED with PWM.

It's still 1-bit, being only either 0 or 5V, you want to average it, which can be done by a low pass filter on the PWM pin. This will produce the real continuous analog voltage you want for audio.

8-bit doesn't have that great of a signal to noise ratio, the noise floor is like 50dB or something, it's audible. This is why Olivier is using a 12-bit DAC. This is as far as I've gotten, I have sounds playing out of my ATMega now in 8-bit.

I was linking you to the OpenMusicLabs link because if you don't want to use a DAC, it explains how you can use Dual PWM mixed together to get more bit depth, I am thinking of trying this myself.

As far as I can tell, this is how he gets a 10Mhz 1-bit signal, it's not with the ATMega alone, I don't think it would be possible to actually run the ATMega PWM at 10Mhz, well, maybe you can if you set the timer compare really low, but how would you produce a sample that quickly each sample period T= 1/10000000 seconds? It's my understanding so far, that I don't think you can, the 12 bit DAC he using must be what allows him to do that at ~40KHz, he gets an 8-bit quality sound with a 12-bit noise floor.

/r/electronics Thread Parent