Big Mouth Billy Bass automation library

Dependents:   BillyBass_with_SD

Files at this revision

API Documentation at this revision

Comitter:
bikeNomad
Date:
Thu Jun 20 04:10:22 2013 +0000
Parent:
6:ea8136eb6976
Child:
8:ad0c038ebfc1
Commit message:
try to shift times and enforce minimum times

Changed in this revision

action.hpp Show annotated file Show diff for this revision Revisions of this file
billybass.cpp Show annotated file Show diff for this revision Revisions of this file
billybass.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.cpp 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	Thu Jun 20 03:04:36 2013 +0000
+++ b/action.hpp	Thu Jun 20 04:10:22 2013 +0000
@@ -22,12 +22,16 @@
     }
 
     bool operator < (Action const &other) const {
-        return actionTime < other.actionTime;
+        if (actionTime < other.actionTime) return true;
+        if (actionTime > other.actionTime) return false;
+        return (code < other.code);
     }
 
     // return <0 if *p1 is before *p2
     static int compare(const void* p1, const void* p2) {
-        return static_cast<Action const *>(p1)->actionTime - static_cast<Action const *>(p2)->actionTime;
+        float tdiff = static_cast<Action const *>(p1)->actionTime - static_cast<Action const *>(p2)->actionTime;
+        if (tdiff != 0.0) return tdiff;
+        return static_cast<Action const *>(p1)->code - static_cast<Action const *>(p2)->code;
     }
 
     bool isValid() const {
@@ -38,8 +42,12 @@
         output->write(desiredState ? 1 : 0);
     }
 
+    bool isPast(float _now) {
+        return _now >= actionTime;
+    }
+
     bool actIfPast(float _now) {
-        if (_now >= actionTime) {
+        if (isPast(_now)) {
             act();
             return true;
         } else return false;
--- a/billybass.cpp	Thu Jun 20 03:04:36 2013 +0000
+++ b/billybass.cpp	Thu Jun 20 04:10:22 2013 +0000
@@ -9,21 +9,33 @@
 char const * BillyBass::bodyName = "body";
 char const * BillyBass::tailName = "tail";
 
-DigitalOut *BillyBass::outputNamed(char const *_outputName, char const **_pName)
+DigitalOut *BillyBass::outputNamed(char const *_outputName, char const **_pName, float *_pOnDelay, float *_pOffDelay, float *_pMinOnTime)
 {
     DigitalOut *output = 0;
+    float onDelay = 0.0, offDelay = 0.0, minOnTime = 0.0;
+    char const *name = 0;
 
     if (!strcmp(_outputName, mouthName)) {
         output = &mouth;
-        if (_pName) *_pName = mouthName;
+        name = mouthName;
+        onDelay = MOUTH_ON_DELAY;
+        offDelay = MOUTH_OFF_DELAY;
+        minOnTime = MOUTH_ON_DELAY / 2;
     } else if (!strcmp(_outputName, "head") || !strcmp(_outputName, bodyName)) {
         output = &body;
-        if (_pName) *_pName = bodyName;
+        name = bodyName;
+        minOnTime = onDelay = BODY_ON_DELAY;
+        offDelay = BODY_OFF_DELAY;
     } else if (!strcmp(_outputName, tailName)) {
         output = &tail;
-        if (_pName) *_pName = tailName;
+        name = tailName;
+        minOnTime = onDelay = TAIL_ON_DELAY;
+        offDelay = TAIL_OFF_DELAY;
     }
-
+    if (_pOnDelay) *_pOnDelay = onDelay;
+    if (_pOffDelay) *_pOffDelay = offDelay;
+    if (_pMinOnTime) *_pMinOnTime = minOnTime;
+    if (_pName) *_pName = name;
     return output;
 }
 
--- a/billybass.hpp	Thu Jun 20 03:04:36 2013 +0000
+++ b/billybass.hpp	Thu Jun 20 04:10:22 2013 +0000
@@ -20,7 +20,7 @@
     }
 
     // if *_pName, it will get the string name of the output
-    DigitalOut *outputNamed(char const *_outputName, char const **_pName = 0);
+    DigitalOut *outputNamed(char const *_outputName, char const **_pName = 0, float *_pOnDelay = 0, float *_pOffDelay = 0, float *_pMinOn = 0);
 
     static BillyBass *bassNumber(unsigned which) {
         return (which >= numFish) ? 0 : fish[which];
--- a/player.hpp	Thu Jun 20 03:04:36 2013 +0000
+++ b/player.hpp	Thu Jun 20 04:10:22 2013 +0000
@@ -149,9 +149,9 @@
         if (!startSong(_song)) return;
         Action* lastAction = song->getActions() + song->getNumActions();
         while (!isDone()) {
-            while (nextAction < lastAction && nextAction->actIfPast(timeInSong)) {
+            while (nextAction < lastAction && nextAction->isPast(timeInSong)) {
+                nextAction->act();
                 fputc(nextAction->code, stderr);
-                // fprintf(stderr, "%c", nextAction->code);
                 actionsDone++;
                 nextAction++;
             }
--- a/song.cpp	Thu Jun 20 03:04:36 2013 +0000
+++ b/song.cpp	Thu Jun 20 04:10:22 2013 +0000
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <algorithm>
+#include <math.h>
 
 #include "billybass.hpp"
 #include "song.hpp"
@@ -81,6 +82,24 @@
     return false;
 }
 
+bool Song::addAction(float _time, int _state, DigitalOut* _out, char _code)
+{
+    Action *priorAction = (numActions > 0) ? actions + numActions - 1 : 0;
+    if (priorAction ) {
+        if (priorAction->output == _out) {
+            if (priorAction->actionTime >= _time && priorAction->desiredState != _state)
+                return true;
+            if (priorAction->actionTime < _time && priorAction->desiredState == _state) {
+                priorAction->actionTime = _time;
+                return true;
+            }
+        }
+    }
+    if (numActions >= MAX_ACTIONS_PER_SONG) return false;
+    actions[numActions++].set(_time, _state, _out, _code);
+    return true;
+}
+
 bool Song::readActions()
 {
     fprintf(stderr, "reading actions of %s\r\n", getTextFileName());
@@ -122,18 +141,32 @@
             goto done;
 
         char const *outName;
-        DigitalOut *out = bass->outputNamed(++q, &outName);
+        float onDelay, offDelay, minOnTime;
+        DigitalOut *out = bass->outputNamed(++q, &outName, &onDelay, &offDelay, &minOnTime);
         if (!out) {
             fprintf(stderr, "%s line %d: bad outname \"%s\"\r\n", getTextFileName(), line, q);
             goto done;
         }
-        // fprintf(stderr, "%d add %f %f %s\r\n", line, startTime, endTime, outName);
+
+        startTime -= onDelay;
+        startTime -= remainder(startTime, SECONDS_PER_CHUNK);
+        if (startTime < 0.0) startTime = 0.0;
+
+        endTime -= offDelay;
+        endTime += remainder(endTime, SECONDS_PER_CHUNK);
+        if (endTime < startTime + minOnTime)
+            endTime = startTime + minOnTime;
+
+        fprintf(stderr, "%d %f %f %s\r\n", line, startTime, endTime, outName);
 
         addAction(startTime, bass->onState(), out, toupper(outName[0]));
         addAction(endTime, bass->offState(), out, outName[0]);
     }
     fprintf(stderr, "Added %d actions\r\n", numActions);
     qsort(actions, numActions, sizeof(Action), &Action::compare);
+    for (int i = 0; i < numActions; i++ ) {
+        fprintf(stderr, "%f %c\r\n", actions[i].actionTime, actions[i].code);
+    }
     retval = true;
 
 done:
--- a/song.hpp	Thu Jun 20 03:04:36 2013 +0000
+++ b/song.hpp	Thu Jun 20 04:10:22 2013 +0000
@@ -53,11 +53,8 @@
     Action *getActions() {
         return actions;
     }
-    bool addAction(float _time, int _state, DigitalOut* _out, char _code) {
-        if (numActions >= MAX_ACTIONS_PER_SONG) return false;
-        actions[numActions++].set(_time, _state, _out, _code);
-        return true;
-    }
+    bool addAction(float _time, int _state, DigitalOut* _out, char _code);
+    
     unsigned getNumActions() const {
         return numActions;
     }