Go Down

Topic: I created a function / library to play sampled sounds (Read 3 times) previous topic - next topic

smeezekitty

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:
Code: [Select]

#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:
Code: [Select]

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:
Code: [Select]

#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.
Avoid throwing electronics out as you or someone else might need them for parts or use.
Solid state rectifiers are the only REAL rectifiers.
Resistors for LEDS!

smeezekitty

Avoid throwing electronics out as you or someone else might need them for parts or use.
Solid state rectifiers are the only REAL rectifiers.
Resistors for LEDS!

robtillaart

Would it be possible to play "byte" files from an SD card or an I2C EEPROM?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

smeezekitty

Not really.
The format is different (8 bit vs 1 bit) and the sample rate is different (4000 vs 8000) and it has no provision for reading from an SD card.
Avoid throwing electronics out as you or someone else might need them for parts or use.
Solid state rectifiers are the only REAL rectifiers.
Resistors for LEDS!

Vanyamba

... to make sound louder.  :)

Go Up