s

Fork of wave_player by Steve Ravet

Revision:
2:44a41c9ff2d4
Parent:
0:62c18ade9a60
diff -r acc3e18e77ad -r 44a41c9ff2d4 wave_player.cpp
--- a/wave_player.cpp	Tue Jan 18 03:57:27 2011 +0000
+++ b/wave_player.cpp	Mon May 02 08:00:12 2016 +0000
@@ -3,28 +3,32 @@
 //
 // explanation of wave file format.
 // https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
-
+ 
 // if VERBOSE is uncommented then the wave player will enter a verbose
 // mode that displays all data values as it reads them from the file
 // and writes them to the DAC.  Very slow and unusable output on the DAC,
 // but useful for debugging wave files that don't work.
 //#define VERBOSE
-
-
+ 
+ 
 #include <mbed.h>
 #include <stdio.h>
 #include <wave_player.h>
-
-
+ 
+ 
 //-----------------------------------------------------------------------------
 // constructor -- accepts an mbed pin to use for AnalogOut.  Only p18 will work
-wave_player::wave_player(AnalogOut *_dac)
-{
+wave_player::wave_player(AnalogOut *_dac, PwmOut *_pwm)
+{  
+ 
+    
+  wave_PWM= _pwm;  
   wave_DAC=_dac;
   wave_DAC->write_u16(32768);        //DAC is 0-3.3V, so idles at ~1.6V
+  *wave_PWM=32768;
   verbosity=0;
 }
-
+ 
 //-----------------------------------------------------------------------------
 // if verbosity is set then wave player enters a mode where the wave file
 // is decoded and displayed to the screen, including sample values put into
@@ -36,7 +40,7 @@
 {
   verbosity=v;
 }
-
+ 
 //-----------------------------------------------------------------------------
 // player function.  Takes a pointer to an opened wave file.  The file needs
 // to be stored in a filesystem with enough bandwidth to feed the wave data.
@@ -46,6 +50,8 @@
 //-----------------------------------------------------------------------------
 void wave_player::play(FILE *wavefile)
 {
+        extern float volume_change;
+        extern bool playing;
         unsigned chunk_id,chunk_size,channel;
         unsigned data,samp_int,i;
         short unsigned dac_data;
@@ -64,7 +70,7 @@
   }
   DAC_wptr=4;
   DAC_on=0;
-
+ 
   fread(&chunk_id,4,1,wavefile);
   fread(&chunk_size,4,1,wavefile);
   while (!feof(wavefile)) {
@@ -110,14 +116,14 @@
           printf("  Ideal sample interval=%d\n",(unsigned)(1000000.0/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
         if (verbosity)
           tick.attach_us(this,&wave_player::dac_out, 500000); 
         else
           tick.attach_us(this,&wave_player::dac_out, samp_int); 
         DAC_on=1; 
-
+ 
 // start reading slices, which contain one sample each for however many channels
 // are in the wave file.  one channel=mono, two channels=stereo, etc.  Since
 // mbed only has a single AnalogOut, all of the channels present are averaged
@@ -129,6 +135,9 @@
 // while 16 and 32 bit wave files use signed data
 //
         for (slice=0;slice<num_slices;slice+=1) {
+          if (playing == false){
+            break;
+          }
           fread(slice_buf,wav_format.block_align,1,wavefile);
           if (feof(wavefile)) {
             printf("Oops -- not enough slices in the wave file\n");
@@ -173,7 +182,7 @@
           dac_data=(short unsigned)slice_value;
           if (verbosity)
             printf("sample %d wptr %d slice_value %d dac_data %u\n",slice,DAC_wptr,(int)slice_value,dac_data);
-          DAC_fifo[DAC_wptr]=dac_data;
+          DAC_fifo[DAC_wptr]=((volume_change) * dac_data);
           DAC_wptr=(DAC_wptr+1) & 0xff;
           while (DAC_wptr==DAC_rptr) {
           }
@@ -196,16 +205,18 @@
     fread(&chunk_size,4,1,wavefile);
   }
 }
-
-
+ 
+ 
 void wave_player::dac_out()
 {
   if (DAC_on) {
 #ifdef VERBOSE
   printf("ISR rdptr %d got %u\n",DAC_rptr,DAC_fifo[DAC_rptr]);
 #endif
-    wave_DAC->write_u16(DAC_fifo[DAC_rptr]);
+    //scale down Analog voltage by 8 for PC speakers
+    wave_DAC->write_u16(DAC_fifo[DAC_rptr]>>3);
+    //Output to onboard speaker using PWM (Class D Audio Amp!)
+    wave_PWM->write(float(DAC_fifo[DAC_rptr]/65536.0));
     DAC_rptr=(DAC_rptr+1) & 0xff;
   }
-}
-
+}
\ No newline at end of file