Diff: main.cpp
- Revision:
- 0:4cda52c0c66e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sat Jan 02 17:07:38 2010 +0000
@@ -0,0 +1,190 @@
+#include "mbed.h"
+#include "SDFileSystem.h"
+
+AnalogOut DACout(p18);
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(p8);
+DigitalOut digout(LED4);
+Ticker tick;
+SDFileSystem sd(p11, p12, p13, p14, "sd");
+
+#define SAMPLE_FREQ 40000
+#define BUF_SIZE (SAMPLE_FREQ/10)
+#define SLICE_BUF_SIZE 1
+
+void dac_out(void);
+void play_wave(char *);
+void cleanup(char *);
+void fill_adc_buf(short *, unsigned);
+void swapword(unsigned *);
+
+// a FIFO for the DAC
+short DAC_fifo[256];
+short DAC_wptr;
+short DAC_rptr;
+short DAC_on;
+
+typedef struct uFMT_STRUCT {
+ short comp_code;
+ short num_channels;
+ unsigned sample_rate;
+ unsigned avg_Bps;
+ short block_align;
+ short sig_bps;
+} FMT_STRUCT;
+
+
+int main() {
+ led1=0; wait(.5); led1=1; wait(.5); led1=0;
+ printf("Hello, world!\n");
+ play_wave("/sd/baddonut.wav");
+ printf("Back from play_wave()\n");
+ play_wave("/sd/clint16.wav");
+ printf("Back from play_wave()\n");
+ printf("Goodbye, world!\n");
+ led1=1; wait(.5); led1=0; wait(.5); led1=1;
+}
+
+void play_wave(char *wavname)
+{
+ unsigned chunk_id,chunk_size,channel;
+// unsigned *data_wptr,data,samp_int,i;
+ unsigned data,samp_int,i;
+ short dac_data;
+ char *slice_buf;
+ short *data_sptr;
+// char *data_bptr;
+ FMT_STRUCT wav_format;
+ FILE *wavfile;
+ long slice,num_slices;
+ DAC_wptr=0;
+ DAC_rptr=0;
+ for (i=0;i<256;i+=2) {
+ DAC_fifo[i]=0;
+ DAC_fifo[i+1]=3000;
+ }
+ DAC_wptr=4;
+ DAC_on=0;
+
+ led1=led2=led3=led4=0;
+
+ printf("Playing wave file '%s'\n",wavname);
+
+ wavfile=fopen(wavname,"rb");
+ if (!wavfile) {
+ printf("Unable to open wav file '%s'\n",wavname);
+ exit(1);
+ }
+
+ fread(&chunk_id,4,1,wavfile);
+ fread(&chunk_size,4,1,wavfile);
+ while (!feof(wavfile)) {
+ printf("Read chunk ID 0x%x, size 0x%x\n",chunk_id,chunk_size);
+ switch (chunk_id) {
+ case 0x46464952:
+ fread(&data,4,1,wavfile);
+ printf("RIFF chunk\n");
+ printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
+ printf(" RIFF type 0x%x\n",data);
+ break;
+ case 0x20746d66:
+ fread(&wav_format,sizeof(wav_format),1,wavfile);
+ printf("FORMAT chunk\n");
+ printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
+ printf(" compression code %d\n",wav_format.comp_code);
+ printf(" %d channels\n",wav_format.num_channels);
+ printf(" %d samples/sec\n",wav_format.sample_rate);
+ printf(" %d bytes/sec\n",wav_format.avg_Bps);
+ printf(" block align %d\n",wav_format.block_align);
+ printf(" %d bits per sample\n",wav_format.sig_bps);
+ if (chunk_size > sizeof(wav_format))
+ fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR);
+// create a slice buffer large enough to hold multiple slices
+ slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
+ if (!slice_buf) {
+ printf("Unable to malloc slice buffer");
+ exit(1);
+ }
+ break;
+ case 0x61746164:
+ slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
+ if (!slice_buf) {
+ printf("Unable to malloc slice buffer");
+ exit(1);
+ } num_slices=chunk_size/wav_format.block_align;
+ printf("DATA chunk\n");
+ printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
+ printf(" %d slices\n",num_slices);
+ printf(" Ideal sample interval=%d\n",(unsigned)(1000000.0/wav_format.sample_rate));
+ samp_int=1000000/(wav_format.sample_rate);
+ printf(" programmed interrupt tick interval=%d\n",samp_int);
+
+// starting up ticker to write samples out -- no printfs until tick.detach is called
+ tick.attach_us(&dac_out, samp_int);
+ DAC_on=1;
+ led2=1;
+ for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) {
+ fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile);
+ if (feof(wavfile)) {
+ printf("Oops -- not enough slices in the wave file\n");
+ exit(1);
+ }
+ data_sptr=(short *)slice_buf;
+ for (i=0;i<SLICE_BUF_SIZE;i++) {
+ dac_data=0;
+
+// for a stereo wave file average the two channels.
+ for (channel=0;channel<wav_format.num_channels;channel++) {
+ switch (wav_format.sig_bps) {
+ case 16:
+ dac_data+=( ((int)(*data_sptr++)) +32768)>>5;
+ break;
+ }
+ }
+ dac_data>>=1;
+ DAC_fifo[DAC_wptr]=dac_data;
+ DAC_wptr=(DAC_wptr+1) & 0xff;
+ while (DAC_wptr==DAC_rptr) {
+ led1=1;
+ }
+ led1=0;
+ }
+ }
+ DAC_on=0;
+ led2=0;
+ tick.detach();
+ printf("Ticker detached\n");
+ led3=1;
+ free(slice_buf);
+ break;
+ case 0x5453494c:
+ printf("INFO chunk, size %d\n",chunk_size);
+ fseek(wavfile,chunk_size,SEEK_CUR);
+ break;
+ default:
+ printf("unknown chunk type 0x%x, size %d\n",chunk_id,chunk_size);
+ data=fseek(wavfile,chunk_size,SEEK_CUR);
+ break;
+ }
+ fread(&chunk_id,4,1,wavfile);
+ fread(&chunk_size,4,1,wavfile);
+ }
+ printf("Done with wave file\n");
+ fclose(wavfile);
+ led1=0;
+}
+
+
+void dac_out()
+{
+ if (DAC_on) {
+ digout=1;
+ DACout.write_u16(DAC_fifo[DAC_rptr]);
+ DAC_rptr=(DAC_rptr+1) & 0xff;
+ digout=0;
+ }
+}
+
+