Big Mouth Billy Bass automation library

Dependents:   BillyBass_with_SD

Committer:
bikeNomad
Date:
Tue Jun 18 13:11:07 2013 +0000
Revision:
3:6c91a6232c4a
Parent:
1:9b1f3eb204ac
Child:
4:f009306756b3
changed debug messages; added inversion of BB outputs

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bikeNomad 0:84aaade0de8f 1 #include <stdlib.h>
bikeNomad 0:84aaade0de8f 2 #include <string.h>
bikeNomad 0:84aaade0de8f 3 #include <stdio.h>
bikeNomad 0:84aaade0de8f 4 #include <ctype.h>
bikeNomad 0:84aaade0de8f 5 #include <algorithm>
bikeNomad 0:84aaade0de8f 6
bikeNomad 0:84aaade0de8f 7 #include "billybass.hpp"
bikeNomad 0:84aaade0de8f 8 #include "song.hpp"
bikeNomad 0:84aaade0de8f 9
bikeNomad 0:84aaade0de8f 10 // class static
bikeNomad 0:84aaade0de8f 11 char const Song::directoryName[ BASS_DIRECTORY_LENGTH + 1 ] = BASS_DIRECTORY;
bikeNomad 0:84aaade0de8f 12 // class static
bikeNomad 0:84aaade0de8f 13 char const *Song::textExtension = "txt";
bikeNomad 0:84aaade0de8f 14 // class static
bikeNomad 0:84aaade0de8f 15 char const *Song::sampleExtension = "raw";
bikeNomad 0:84aaade0de8f 16 // class static
bikeNomad 0:84aaade0de8f 17 unsigned const Song::NO_FISH = MAX_FISH + 1;
bikeNomad 0:84aaade0de8f 18
bikeNomad 0:84aaade0de8f 19 // _name is relative to BASS_DIRECTORY
bikeNomad 0:84aaade0de8f 20 // class static
bikeNomad 0:84aaade0de8f 21 Song *Song::newSong(char const *_name)
bikeNomad 0:84aaade0de8f 22 {
bikeNomad 0:84aaade0de8f 23 Song *s = new Song;
bikeNomad 0:84aaade0de8f 24 if (!s) {
bikeNomad 3:6c91a6232c4a 25 fprintf(stderr, "new Song == 0\r\n");
bikeNomad 0:84aaade0de8f 26 return 0;
bikeNomad 0:84aaade0de8f 27 }
bikeNomad 0:84aaade0de8f 28 if (! s->parseFilename(_name)) {
bikeNomad 3:6c91a6232c4a 29 fprintf(stderr, "parseFilename(%s) failed\r\n", _name);
bikeNomad 0:84aaade0de8f 30 goto on_error;
bikeNomad 0:84aaade0de8f 31 }
bikeNomad 3:6c91a6232c4a 32 fprintf(stderr, "parsed filename OK\r\n");
bikeNomad 0:84aaade0de8f 33 if (! s->readActions()) {
bikeNomad 3:6c91a6232c4a 34 fprintf(stderr, "readActions(%s) failed\r\n", _name);
bikeNomad 0:84aaade0de8f 35 goto on_error;
bikeNomad 0:84aaade0de8f 36 }
bikeNomad 0:84aaade0de8f 37
bikeNomad 0:84aaade0de8f 38 return s;
bikeNomad 0:84aaade0de8f 39
bikeNomad 0:84aaade0de8f 40 on_error:
bikeNomad 0:84aaade0de8f 41 delete s;
bikeNomad 0:84aaade0de8f 42 return 0;
bikeNomad 0:84aaade0de8f 43 }
bikeNomad 0:84aaade0de8f 44
bikeNomad 0:84aaade0de8f 45 bool Song::parseFilename(char const *_name)
bikeNomad 0:84aaade0de8f 46 {
bikeNomad 0:84aaade0de8f 47 if (strlen(_name) > MAX_BASENAME_LENGTH)
bikeNomad 0:84aaade0de8f 48 goto on_error;
bikeNomad 0:84aaade0de8f 49
bikeNomad 0:84aaade0de8f 50 strcpy(fullname, directoryName);
bikeNomad 0:84aaade0de8f 51 basename = fullname + BASS_DIRECTORY_LENGTH;
bikeNomad 0:84aaade0de8f 52 *basename++ = '/';
bikeNomad 0:84aaade0de8f 53 strcpy(basename, _name);
bikeNomad 0:84aaade0de8f 54
bikeNomad 0:84aaade0de8f 55 char *p;
bikeNomad 0:84aaade0de8f 56 long n = strtol(_name, &p, 10);
bikeNomad 0:84aaade0de8f 57 if (*p != '_' || n <= 0)
bikeNomad 0:84aaade0de8f 58 goto on_error;
bikeNomad 0:84aaade0de8f 59
bikeNomad 0:84aaade0de8f 60 sequenceNumber = (unsigned)(n - 1);
bikeNomad 0:84aaade0de8f 61
bikeNomad 0:84aaade0de8f 62 p++; // skip underscore
bikeNomad 0:84aaade0de8f 63 n = strtol(p, &p, 10);
bikeNomad 0:84aaade0de8f 64 if (*p != '_' || n <= 0 || n > MAX_FISH)
bikeNomad 0:84aaade0de8f 65 goto on_error;
bikeNomad 0:84aaade0de8f 66
bikeNomad 0:84aaade0de8f 67 whichFish = (unsigned)(n - 1);
bikeNomad 0:84aaade0de8f 68
bikeNomad 0:84aaade0de8f 69 p = strrchr(basename, '.');
bikeNomad 0:84aaade0de8f 70 if (!p)
bikeNomad 0:84aaade0de8f 71 goto on_error;
bikeNomad 0:84aaade0de8f 72
bikeNomad 0:84aaade0de8f 73 extension = p+1;
bikeNomad 0:84aaade0de8f 74
bikeNomad 0:84aaade0de8f 75 if (strcasecmp(extension, sampleExtension))
bikeNomad 0:84aaade0de8f 76 goto on_error;
bikeNomad 0:84aaade0de8f 77
bikeNomad 0:84aaade0de8f 78 return true;
bikeNomad 0:84aaade0de8f 79
bikeNomad 0:84aaade0de8f 80 on_error:
bikeNomad 0:84aaade0de8f 81 whichFish = NO_FISH;
bikeNomad 0:84aaade0de8f 82 basename = 0;
bikeNomad 0:84aaade0de8f 83 return false;
bikeNomad 0:84aaade0de8f 84 }
bikeNomad 0:84aaade0de8f 85
bikeNomad 0:84aaade0de8f 86 bool Song::readActions()
bikeNomad 0:84aaade0de8f 87 {
bikeNomad 3:6c91a6232c4a 88 fprintf(stderr, "reading actions of %s\r\n", getTextFileName());
bikeNomad 1:9b1f3eb204ac 89
bikeNomad 0:84aaade0de8f 90 FILE *txtfile = fopen(getTextFileName(), "r");
bikeNomad 0:84aaade0de8f 91 if (!txtfile) {
bikeNomad 3:6c91a6232c4a 92 fprintf(stderr, "can't open %s\r\n", getTextFileName());
bikeNomad 0:84aaade0de8f 93 return false;
bikeNomad 1:9b1f3eb204ac 94 } else
bikeNomad 3:6c91a6232c4a 95 fprintf(stderr, "opened %s OK\r\n", getTextFileName());
bikeNomad 0:84aaade0de8f 96 bool retval = false;
bikeNomad 0:84aaade0de8f 97
bikeNomad 0:84aaade0de8f 98 BillyBass *bass = BillyBass::bassNumber(whichFish);
bikeNomad 0:84aaade0de8f 99 if (!bass) {
bikeNomad 3:6c91a6232c4a 100 fprintf(stderr, "No bass!\r\n");
bikeNomad 0:84aaade0de8f 101 goto done;
bikeNomad 0:84aaade0de8f 102 }
bikeNomad 0:84aaade0de8f 103
bikeNomad 0:84aaade0de8f 104 // read actions from file
bikeNomad 1:9b1f3eb204ac 105 static char textFileBuffer[ 2048 ];
bikeNomad 1:9b1f3eb204ac 106 memset(textFileBuffer, 0, sizeof(textFileBuffer));
bikeNomad 1:9b1f3eb204ac 107 int nread = fread(textFileBuffer, 1, sizeof(textFileBuffer), txtfile);
bikeNomad 3:6c91a6232c4a 108 // fprintf(stderr, "Read %d bytes\r\n", nread);
bikeNomad 1:9b1f3eb204ac 109 if (nread <= 0 || nread == sizeof(textFileBuffer)) {
bikeNomad 1:9b1f3eb204ac 110 goto done;
bikeNomad 1:9b1f3eb204ac 111 }
bikeNomad 0:84aaade0de8f 112 unsigned line = 1;
bikeNomad 1:9b1f3eb204ac 113 for (char *actionLine = strtok(textFileBuffer, "\r\n");
bikeNomad 1:9b1f3eb204ac 114 actionLine;
bikeNomad 1:9b1f3eb204ac 115 actionLine = strtok(0, "\r\n"), line++) {
bikeNomad 1:9b1f3eb204ac 116 char *p;
bikeNomad 0:84aaade0de8f 117 float startTime = strtof(actionLine, &p);
bikeNomad 0:84aaade0de8f 118 if (p == actionLine)
bikeNomad 0:84aaade0de8f 119 goto done;
bikeNomad 0:84aaade0de8f 120
bikeNomad 0:84aaade0de8f 121 char *q;
bikeNomad 0:84aaade0de8f 122 float endTime = strtof(p, &q);
bikeNomad 0:84aaade0de8f 123 if (q == p)
bikeNomad 0:84aaade0de8f 124 goto done;
bikeNomad 0:84aaade0de8f 125
bikeNomad 0:84aaade0de8f 126 char const *outName;
bikeNomad 1:9b1f3eb204ac 127 DigitalOut *out = bass->outputNamed(++q, &outName);
bikeNomad 0:84aaade0de8f 128 if (!out) {
bikeNomad 3:6c91a6232c4a 129 fprintf(stderr, "%s line %d: bad outname \"%s\"\r\n", getTextFileName(), line, q);
bikeNomad 0:84aaade0de8f 130 goto done;
bikeNomad 0:84aaade0de8f 131 }
bikeNomad 3:6c91a6232c4a 132 // fprintf(stderr, "%d add %f %f %s\r\n", line, startTime, endTime, outName);
bikeNomad 0:84aaade0de8f 133
bikeNomad 3:6c91a6232c4a 134 actions.push_back(Action(startTime, bass->onState(), out, outName));
bikeNomad 3:6c91a6232c4a 135 actions.push_back(Action(endTime, bass->offState(), out, outName));
bikeNomad 0:84aaade0de8f 136 }
bikeNomad 3:6c91a6232c4a 137 fprintf(stderr, "Added %d actions\r\n", actions.size());
bikeNomad 0:84aaade0de8f 138 std::sort(actions.begin(), actions.end()); // sort actions by time
bikeNomad 0:84aaade0de8f 139 retval = true;
bikeNomad 0:84aaade0de8f 140
bikeNomad 0:84aaade0de8f 141 done:
bikeNomad 1:9b1f3eb204ac 142
bikeNomad 0:84aaade0de8f 143 fclose(txtfile);
bikeNomad 0:84aaade0de8f 144 return retval;
bikeNomad 0:84aaade0de8f 145 }