Dependencies:   mbed

Revision:
0:143457f10e26
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Dec 06 17:08:31 2009 +0000
@@ -0,0 +1,191 @@
+//todo red button and light sensor
+
+
+#include "mbed.h"
+#include "SDFileSystem.h"
+
+AnalogOut DACout(p18);
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+DigitalOut digout(p8);
+Ticker tick;
+SDFileSystem sd(p5, p6, p7, p13, "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");
+}
+  
+void play_wave(char *wavname)
+{
+        unsigned chunk_id,chunk_size,channel;
+        unsigned *data_wptr,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(DAC_fifo[DAC_rptr]);
+    DAC_rptr=(DAC_rptr+1) & 0xff;
+    digout=0;
+  }
+}
+
+