Big Mouth Billy Bass player that takes raw wavefiles and decision list text files from an SD card

Dependencies:   SDFileSystem mbed BillyBass

Revision:
1:f3f439154ab4
Parent:
0:0944c3654ded
Child:
2:f96989f2b8a1
--- a/main.cpp	Wed Jun 05 15:33:45 2013 +0000
+++ b/main.cpp	Fri Jun 07 03:33:10 2013 +0000
@@ -40,6 +40,7 @@
 
 const size_t BUFFER_SIZE = 512;
 const float SAMPLE_RATE_HZ = 8000.0;
+const unsigned SAMPLE_PERIOD_USEC = (unsigned)(1.0e6/SAMPLE_RATE_HZ);
 const size_t SAMPLES_PER_BUFFER = BUFFER_SIZE / sizeof(Sample_t);
 const float SECONDS_PER_CHUNK = SAMPLES_PER_BUFFER / SAMPLE_RATE_HZ;
 
@@ -141,6 +142,11 @@
         return samplesRemaining > 0;
     }
 
+    Sample_t getNextSample() {
+        --samplesRemaining;
+        return *++nextSample;
+    }
+
     SampleBuffer() : samplesRemaining(0), nextSample(buf) { }
 };
 
@@ -151,6 +157,15 @@
     FILE *fp;
     size_t nChunks;
     size_t volatile chunksRemaining;
+    Ticker sampleTicker;
+
+    // interrupt handler
+    void playNextSample(void) {
+        if (!playing->samplesRemaining)
+            swapBuffers();
+        // TODO change bias to 0xC000 (requires normalizing to 75% of full scale)
+        speaker.write_u16(static_cast<uint16_t>(playing->getNextSample() + 0x8000));
+    }
 
     bool startSong(char const *name) {
         if (fp) fclose(fp);
@@ -163,7 +178,10 @@
         chunksRemaining = nChunks = fileSize / BUFFER_SIZE;
         loading = &buffer[0];
         playing = &buffer[1];
-        return loadNextChunk();
+        if (! loadNextChunk())
+            return false;
+        sampleTicker.attach_us(this, &SongPlayer::playNextSample, SAMPLE_PERIOD_USEC);
+        return true;
     }
 
     // swap loading/playing buffers;
@@ -192,6 +210,12 @@
         return !chunksRemaining;
     }
 
+    // look at loading buffer; load only if necessary.
+    bool loadIfNecessary() {
+        if (loading->isDone()) {
+            return loadNextChunk();
+        } else return true;
+    }
 };
 
 std::list<Song> songs;