Big Mouth Billy Bass automation library

Dependents:   BillyBass_with_SD

Committer:
bikeNomad
Date:
Tue Jun 18 14:10:34 2013 +0000
Revision:
4:f009306756b3
Parent:
3:6c91a6232c4a
Child:
5:869b3711bdb3
working. re-used one Song for memory reduction.

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