Big Mouth Billy Bass automation library

Dependents:   BillyBass_with_SD

Files at this revision

API Documentation at this revision

Comitter:
bikeNomad
Date:
Tue Jun 18 06:12:48 2013 +0000
Parent:
1:9b1f3eb204ac
Child:
3:6c91a6232c4a
Commit message:
Still not doing actions but loading OK;

Changed in this revision

action.hpp Show annotated file Show diff for this revision Revisions of this file
player.hpp Show annotated file Show diff for this revision Revisions of this file
song.hpp Show annotated file Show diff for this revision Revisions of this file
--- a/action.hpp	Tue Jun 18 00:07:47 2013 +0000
+++ b/action.hpp	Tue Jun 18 06:12:48 2013 +0000
@@ -9,20 +9,33 @@
 
 #define MAX_ACTION_LINE_LENGTH 30
 
-struct Action
-{
+struct Action {
     Action(float _time = -1.0,
-            bool _state = false,
-            DigitalOut *_out = 0,
-            char const *_outName = 0)
+           bool _state = false,
+           DigitalOut *_out = 0,
+           char const *_outName = 0)
         : actionTime(_time), desiredState(_state)
-        , output(_out), outputName(_outName)
-    {
+        , output(_out), outputName(_outName) {
+    }
+
+    bool operator < (Action const &other) const {
+        return actionTime < other.actionTime;
     }
 
-    bool operator < (Action const &other) const { return actionTime < other.actionTime; }
+    bool isValid() const {
+        return actionTime >= 0.0 && output != 0;
+    }
 
-    bool isValid() const { return actionTime >= 0.0 && output != 0; }
+    void act() {
+        output->write(desiredState ? 1 : 0);
+    }
+    
+    bool actIfPast(float _now) {
+        if (_now >= actionTime) {
+            act();
+            return true;
+        } else return false;
+    }
 
     float actionTime;
     bool desiredState;
--- a/player.hpp	Tue Jun 18 00:07:47 2013 +0000
+++ b/player.hpp	Tue Jun 18 06:12:48 2013 +0000
@@ -5,32 +5,27 @@
 
 class SongPlayer;
 
-struct SampleBuffer
-{
+struct SampleBuffer {
     Sample_t volatile buf[ SAMPLES_PER_BUFFER ];
     size_t volatile samplesRemaining;
     Sample_t volatile * volatile nextSample;
 
-    bool isDone()
-    {
+    bool isDone() {
         return !samplesRemaining;
     }
 
-    float remainingDuration()
-    {
+    float remainingDuration() {
         return samplesRemaining / SAMPLE_RATE_HZ;
     }
 
     // return true if we read any samples
-    bool loadFrom(FILE *fp)
-    {
+    bool loadFrom(FILE *fp) {
         samplesRemaining = fread((void*)buf, sizeof(Sample_t), SAMPLES_PER_BUFFER, fp);
         nextSample       = buf;
         return samplesRemaining > 0;
     }
 
-    Sample_t getNextSample()
-    {
+    Sample_t getNextSample() {
         --samplesRemaining;
         return *++nextSample;
     }
@@ -40,8 +35,7 @@
     }
 };
 
-struct SongPlayer
-{
+struct SongPlayer {
     SampleBuffer * volatile playing;
     SampleBuffer * volatile loading;
     SampleBuffer buffer[2];
@@ -50,29 +44,38 @@
     size_t volatile chunksRemaining;
     float timeInSong;
     Ticker sampleTicker;
+    Song *song;
+    Song::actions_t::iterator nextAction;
+    unsigned actionsDone;
 
     SongPlayer() : playing(0)
         , loading(0)
         , fp(0)
         , nChunks(0)
         , chunksRemaining(0)
-    {
+        , song(0)
+        , actionsDone(0)
+     {
     }
 
     // interrupt handler
-    void playNextSample(void)
-    {
+    void playNextSample(void) {
         if (playing->samplesRemaining == 0)
             swapBuffers();
         // NOTE bias of 0xC000 requires normalizing to 75% of full scale
         speaker.write_u16(static_cast<uint16_t>(playing->getNextSample() + 0x8000) / 2);
     }
 
-    bool startSong(char const *name)
-    {
-        pc.printf("starting %s: ", name);
+    bool startSong(Song *_song) {
+        if (song) delete song;
+        song = _song;
+        nextAction = song->getActions().begin();
+        timeInSong = 0.0;
+        actionsDone = 0;
+
+        pc.printf("starting %s: ", song->getSampleFileName());
         if (fp) fclose(fp);
-        fp = fopen(name, "rb");
+        fp = fopen(song->getSampleFileName(), "rb");
         pc.printf("opened, ");
         if (!fp) return false;
 
@@ -93,15 +96,14 @@
         if (!loadNextChunk())
             return false;
 
-        timeInSong = 0.0;
+
         sampleTicker.attach_us(this, &SongPlayer::playNextSample, SAMPLE_PERIOD_USEC);
         return true;
     }
 
     // swap loading/playing buffers;
     // decrement chunksRemaining
-    void swapBuffers()
-    {
+    void swapBuffers() {
         SampleBuffer * volatile tmp = playing;
         if (tmp == buffer + 0)
             playing = buffer + 1;
@@ -115,36 +117,35 @@
     // get next chunk of file into *loading
     // to prepare for eventual swap.
     // returns true if more samples remain
-    bool loadNextChunk()
-    {
+    bool loadNextChunk() {
         if (!chunksRemaining) return false;
 
         bool notDone = loading->loadFrom(fp);
         return notDone;
     }
 
-    bool isDone()
-    {
+    bool isDone() {
         return !chunksRemaining;
     }
 
     // look at loading buffer; load only if necessary.
-    bool loadIfNecessary()
-    {
-        if (loading->isDone())
-        {
+    bool loadIfNecessary() {
+        if (loading->isDone()) {
             timeInSong += SECONDS_PER_CHUNK;
             return loadNextChunk();
+        } else {
+            return true;
         }
-        else { return true; }
     }
 
-    void playEntireSong(char const *name)
-    {
-        if (!startSong(name)) return;
+    void playEntireSong(Song *_song) {
+        if (!startSong(_song)) return;
 
-        while (!isDone())
-        {
+        while (!isDone()) {
+            while (nextAction != song->getActions().end() && nextAction->actIfPast(timeInSong)) {
+                actionsDone++;
+                nextAction++;
+            }
             loadIfNecessary();
         }
         sampleTicker.detach();
--- a/song.hpp	Tue Jun 18 00:07:47 2013 +0000
+++ b/song.hpp	Tue Jun 18 06:12:48 2013 +0000
@@ -44,7 +44,7 @@
         strcpy(extension, textExtension);
         return fullname;
     }
-    actions_t const &getActions() const {
+    actions_t &getActions() {
         return actions;
     }