Also please don't use analogRead() if you care about performance.
Here is a simple example to read the A0 and output it using PWM on pin 3.
#include <stdint.h>
int speakerPin = 3; // Can be either 3 or 11, two PWM outputs connected to Timer 2
void startPlayback()
{
pinMode(speakerPin, OUTPUT);
// Set up Timer 2 to do pulse width modulation on the speaker
// pin.
// Use internal clock (datasheet p.160)
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
// Set fast PWM mode (p.157)
TCCR2A |= _BV(WGM21) | _BV(WGM20);
TCCR2B &= ~_BV(WGM22);
// Do non-inverting PWM on pin OC2B (p.155)
// On the Arduino this is pin 3.
TCCR2A = (TCCR2A | _BV(COM2B1)) & ~_BV(COM2B0);
TCCR2A &= ~(_BV(COM2A1) | _BV(COM2A0));
// No prescaler (p.158)
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
}
void setup()
{
pinMode(ledPin, OUTPUT);
OCR2B=0;
startPlayback();
ADMUX = (1<<REFS0)|(1<<ADLAR);
ADCSRA = (1<<ADEN)|(1<<ADPS2);
}
void loop()
{
// start single convertion
// write ’1? to ADSC
ADCSRA |= (1<<ADSC);
// wait for conversion to complete
// ADSC becomes ’0? again
// till then, run loop continuously
while(ADCSRA & (1<<ADSC));
OCR2B=ADCH;
}
A tip to speed up DSP processing is process the previous byte while waiting for the next one.
Also note that this example ignores the lower 2 bits if you want the lower 2bits to get a total of 10 bits you will need to need to remove |(1<<ADLAR) then read ADCL first do something like this
uint8_t temp=ADCL;
uint16_t output=temp|(ADCH<<8);
Notices how I did not just do
ADCL|(ADCH<<8)
This is because ADCL must be read first.