I created a function to play low quality sampled sound out a speaker attached to an Arduino.
It plays 4000 1 bit per sample sound through a digital pin.
Maximum 50 seconds in atmega 328 memory.
It stores the data bit packed in an array.
It is enough to play short sounds at low quality.
Here is the function:
#include <avr/pgmspace.h>
void playSound(prog_uchar input[], long len, int soundpin){
long arrayc=0;
while(arrayc < len){
unsigned char s = pgm_read_byte_near(array + arrayc);
for(unsigned char bs = 1;bs < 128;bs *= 2){
digitalWrite(soundpin, s & bs);
delayMicroseconds(250);
}
arrayc++;
}
}
Syntax:
void playSound(prog_uchar input, long len, int sound)
where
input is a bit packed program space array of the samples to be played.
len is the length of the array in bytes
soundpin is the pin to play the sound out
The following program converts 8000hz 8 bit mono files to bit packed arrays for the function to play:
#include <stdio.h>
#include <stdlib.h>
#define N(x) ((x) > 130)? 1:0
int main(int argc, char *argv[]){
printf("Note: The input file must be in 8000 8 bit samples per second mono\n");
if(argc != 3){printf("Usage: %s <input.wav> <output.c>\n", argv[0]);}
FILE *f = fopen(argv[1], "rb");
FILE *o = fopen(argv[2], "w");
unsigned char a,b,c,d,e,byte;
fprintf(o, "#include <avr/pgmspace.h>\nprog_uchar array[] PROGMEM = {");
unsigned int cnt=0,_cnt=0;
while(!feof(f)){
fread(&a, 1, 1, f);
fread(&e, 1, 1, f);
fread(&b, 1, 1, f);
fread(&e, 1, 1, f);
fread(&c, 1, 1, f);
fread(&e, 1, 1, f);
fread(&d, 1, 1, f);
a = N(a);
b = N(b);
c = N(c);
d = N(d);
byte = (a | b << 1 | c << 2 | d << 3);
fread(&a, 1, 1, f);
fread(&e, 1, 1, f);
fread(&b, 1, 1, f);
fread(&e, 1, 1, f);
fread(&c, 1, 1, f);
fread(&e, 1, 1, f);
fread(&d, 1, 1, f);
a = N(a);
b = N(b);
c = N(c);
d = N(d);
byte |= (a << 4 | b << 5 | c << 6 | d << 7);
fprintf(o, "%d,", byte);
cnt++;
_cnt++;
if(cnt > 60){fprintf(o, "\n"); cnt = 0;}
}
fprintf(o, "0};");
fclose(o);
fclose(f);
printf("\nOutput array of %d bytes\n", _cnt);
return 0;
}
My code sucks but it works.