Just a quick play with some PCM code found in the Playground area.
/*
Created by WilliamK @ Wusik Dot Com (c) 2011 - http://arduino.wusik.com
Code excerpts from: http://www.arduino.cc/playground/Code/PCMAudio
Michael Smith <michael@hurts.ca>
8-Bit Sound Test using PWM on Pin 11
*/
#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define SAMPLE_RATE 44100
volatile uint16_t sample[4] = {0,0,0,0};
unsigned long mixer = 0;
// Sound Data //
// 44100 Pulse //
const unsigned char sounddata_data1[] PROGMEM = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
const unsigned char sounddata_data2[] PROGMEM = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
const unsigned char sounddata_data3[] PROGMEM = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
const unsigned char sounddata_data4[] PROGMEM = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
const int sounddata_length[4]={sizeof(sounddata_data1),sizeof(sounddata_data2),sizeof(sounddata_data3),sizeof(sounddata_data4)};
ISR(TIMER1_COMPA_vect) { nextSample(); }
inline void nextSample()
{
mixer = pgm_read_byte(&sounddata_data1[sample[0]]);
mixer += pgm_read_byte(&sounddata_data2[sample[1]]);
mixer += pgm_read_byte(&sounddata_data3[sample[2]]);
mixer += pgm_read_byte(&sounddata_data4[sample[3]]);
mixer /= 4;
OCR2A = (unsigned char)mixer;
for (char x=0; x<4; x++)
{
++sample[x];
if (sample[x] >= sounddata_length[x]) sample[x] = 0; // Loop //
}
}
void setup()
{
pinMode(11, OUTPUT); // Speaker uses Pin 11 - this is fixed and can't be changed //
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
TCCR2A |= _BV(WGM21) | _BV(WGM20);
TCCR2B &= ~_BV(WGM22);
TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
cli();
TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
nextSample();
TIMSK1 |= _BV(OCIE1A);
sei();
}
void loop()
{
while (true);
}