Big Mouth Billy Bass automation library

Dependents:   BillyBass_with_SD

Committer:
bikeNomad
Date:
Mon Jun 17 22:17:59 2013 +0000
Revision:
0:84aaade0de8f
Child:
1:9b1f3eb204ac
Mostly working; hangs when reading actions

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 // class static
bikeNomad 0:84aaade0de8f 19 std::list<Song*> Song::songs;
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 0:84aaade0de8f 25 Song *s = new Song;
bikeNomad 0:84aaade0de8f 26 if (!s) {
bikeNomad 0:84aaade0de8f 27 pc.printf("new Song == 0\r\n");
bikeNomad 0:84aaade0de8f 28 return 0;
bikeNomad 0:84aaade0de8f 29 }
bikeNomad 0:84aaade0de8f 30 if (! s->parseFilename(_name)) {
bikeNomad 0:84aaade0de8f 31 pc.printf("parseFilename(%s) failed\r\n", _name);
bikeNomad 0:84aaade0de8f 32 goto on_error;
bikeNomad 0:84aaade0de8f 33 }
bikeNomad 0:84aaade0de8f 34 if (! s->readActions()) {
bikeNomad 0:84aaade0de8f 35 pc.printf("readActions(%s) failed\r\n", _name);
bikeNomad 0:84aaade0de8f 36 goto on_error;
bikeNomad 0:84aaade0de8f 37 }
bikeNomad 0:84aaade0de8f 38 songs.push_back(s);
bikeNomad 0:84aaade0de8f 39
bikeNomad 0:84aaade0de8f 40 return s;
bikeNomad 0:84aaade0de8f 41
bikeNomad 0:84aaade0de8f 42 on_error:
bikeNomad 0:84aaade0de8f 43 delete s;
bikeNomad 0:84aaade0de8f 44 return 0;
bikeNomad 0:84aaade0de8f 45 }
bikeNomad 0:84aaade0de8f 46
bikeNomad 0:84aaade0de8f 47 // class static
bikeNomad 0:84aaade0de8f 48 void Song::clearAllSongs()
bikeNomad 0:84aaade0de8f 49 {
bikeNomad 0:84aaade0de8f 50 for (std::list<Song *>::const_iterator song = songs.begin(); song != songs.end(); song++)
bikeNomad 0:84aaade0de8f 51 delete *song;
bikeNomad 0:84aaade0de8f 52 songs.clear();
bikeNomad 0:84aaade0de8f 53 }
bikeNomad 0:84aaade0de8f 54
bikeNomad 0:84aaade0de8f 55 // class static
bikeNomad 0:84aaade0de8f 56 unsigned Song::readAllSongs(DIR *bassDir)
bikeNomad 0:84aaade0de8f 57 {
bikeNomad 0:84aaade0de8f 58 if (!bassDir) return 0;
bikeNomad 0:84aaade0de8f 59 clearAllSongs();
bikeNomad 0:84aaade0de8f 60
bikeNomad 0:84aaade0de8f 61 while (dirent *dir = bassDir->readdir()) {
bikeNomad 0:84aaade0de8f 62 pc.printf("Reading %s\r\n", dir->d_name);
bikeNomad 0:84aaade0de8f 63 unsigned namelen = strlen(dir->d_name);
bikeNomad 0:84aaade0de8f 64 if (namelen > 9 && !strcasecmp(dir->d_name + namelen - 3, sampleExtension)) {
bikeNomad 0:84aaade0de8f 65 Song *song = Song::newSong(dir->d_name);
bikeNomad 0:84aaade0de8f 66 if (!song) {
bikeNomad 0:84aaade0de8f 67 pc.printf("ERROR reading %s\r\n", dir->d_name);
bikeNomad 0:84aaade0de8f 68 } else {
bikeNomad 0:84aaade0de8f 69 song->print(pc);
bikeNomad 0:84aaade0de8f 70 }
bikeNomad 0:84aaade0de8f 71 }
bikeNomad 0:84aaade0de8f 72 }
bikeNomad 0:84aaade0de8f 73
bikeNomad 0:84aaade0de8f 74 return songs.size();
bikeNomad 0:84aaade0de8f 75 }
bikeNomad 0:84aaade0de8f 76
bikeNomad 0:84aaade0de8f 77 bool Song::parseFilename(char const *_name)
bikeNomad 0:84aaade0de8f 78 {
bikeNomad 0:84aaade0de8f 79 if (strlen(_name) > MAX_BASENAME_LENGTH)
bikeNomad 0:84aaade0de8f 80 goto on_error;
bikeNomad 0:84aaade0de8f 81
bikeNomad 0:84aaade0de8f 82 strcpy(fullname, directoryName);
bikeNomad 0:84aaade0de8f 83 basename = fullname + BASS_DIRECTORY_LENGTH;
bikeNomad 0:84aaade0de8f 84 *basename++ = '/';
bikeNomad 0:84aaade0de8f 85 strcpy(basename, _name);
bikeNomad 0:84aaade0de8f 86
bikeNomad 0:84aaade0de8f 87 char *p;
bikeNomad 0:84aaade0de8f 88 long n = strtol(_name, &p, 10);
bikeNomad 0:84aaade0de8f 89 if (*p != '_' || n <= 0)
bikeNomad 0:84aaade0de8f 90 goto on_error;
bikeNomad 0:84aaade0de8f 91
bikeNomad 0:84aaade0de8f 92 sequenceNumber = (unsigned)(n - 1);
bikeNomad 0:84aaade0de8f 93
bikeNomad 0:84aaade0de8f 94 p++; // skip underscore
bikeNomad 0:84aaade0de8f 95 n = strtol(p, &p, 10);
bikeNomad 0:84aaade0de8f 96 if (*p != '_' || n <= 0 || n > MAX_FISH)
bikeNomad 0:84aaade0de8f 97 goto on_error;
bikeNomad 0:84aaade0de8f 98
bikeNomad 0:84aaade0de8f 99 whichFish = (unsigned)(n - 1);
bikeNomad 0:84aaade0de8f 100
bikeNomad 0:84aaade0de8f 101 p = strrchr(basename, '.');
bikeNomad 0:84aaade0de8f 102 if (!p)
bikeNomad 0:84aaade0de8f 103 goto on_error;
bikeNomad 0:84aaade0de8f 104
bikeNomad 0:84aaade0de8f 105 extension = p+1;
bikeNomad 0:84aaade0de8f 106
bikeNomad 0:84aaade0de8f 107 if (strcasecmp(extension, sampleExtension))
bikeNomad 0:84aaade0de8f 108 goto on_error;
bikeNomad 0:84aaade0de8f 109
bikeNomad 0:84aaade0de8f 110 return true;
bikeNomad 0:84aaade0de8f 111
bikeNomad 0:84aaade0de8f 112 on_error:
bikeNomad 0:84aaade0de8f 113 whichFish = NO_FISH;
bikeNomad 0:84aaade0de8f 114 basename = 0;
bikeNomad 0:84aaade0de8f 115 return false;
bikeNomad 0:84aaade0de8f 116 }
bikeNomad 0:84aaade0de8f 117
bikeNomad 0:84aaade0de8f 118 bool Song::readActions()
bikeNomad 0:84aaade0de8f 119 {
bikeNomad 0:84aaade0de8f 120 FILE *txtfile = fopen(getTextFileName(), "r");
bikeNomad 0:84aaade0de8f 121 if (!txtfile) {
bikeNomad 0:84aaade0de8f 122 pc.printf("can't open %s\r\n", getTextFileName());
bikeNomad 0:84aaade0de8f 123 return false;
bikeNomad 0:84aaade0de8f 124 }
bikeNomad 0:84aaade0de8f 125 bool retval = false;
bikeNomad 0:84aaade0de8f 126
bikeNomad 0:84aaade0de8f 127 BillyBass *bass = BillyBass::bassNumber(whichFish);
bikeNomad 0:84aaade0de8f 128 if (!bass) {
bikeNomad 0:84aaade0de8f 129 pc.printf("No bass!\r\n");
bikeNomad 0:84aaade0de8f 130 goto done;
bikeNomad 0:84aaade0de8f 131 }
bikeNomad 0:84aaade0de8f 132
bikeNomad 0:84aaade0de8f 133 // read actions from file
bikeNomad 0:84aaade0de8f 134 unsigned line = 1;
bikeNomad 0:84aaade0de8f 135 char actionLine[ MAX_ACTION_LINE_LENGTH + 1 ];
bikeNomad 0:84aaade0de8f 136 while (true) {
bikeNomad 0:84aaade0de8f 137 if (!fgets(actionLine, sizeof(actionLine), txtfile))
bikeNomad 0:84aaade0de8f 138 break;
bikeNomad 0:84aaade0de8f 139
bikeNomad 0:84aaade0de8f 140 // delete trailing whitespace
bikeNomad 0:84aaade0de8f 141 char *p = actionLine + strlen(actionLine) - 1;
bikeNomad 0:84aaade0de8f 142 while (isspace(*p)) *p-- = 0;
bikeNomad 0:84aaade0de8f 143
bikeNomad 0:84aaade0de8f 144 float startTime = strtof(actionLine, &p);
bikeNomad 0:84aaade0de8f 145 if (p == actionLine)
bikeNomad 0:84aaade0de8f 146 goto done;
bikeNomad 0:84aaade0de8f 147
bikeNomad 0:84aaade0de8f 148 char *q;
bikeNomad 0:84aaade0de8f 149 float endTime = strtof(p, &q);
bikeNomad 0:84aaade0de8f 150 if (q == p)
bikeNomad 0:84aaade0de8f 151 goto done;
bikeNomad 0:84aaade0de8f 152
bikeNomad 0:84aaade0de8f 153 while (isspace(*q)) q++;
bikeNomad 0:84aaade0de8f 154
bikeNomad 0:84aaade0de8f 155 char const *outName;
bikeNomad 0:84aaade0de8f 156 DigitalOut *out = bass->outputNamed(q, &outName);
bikeNomad 0:84aaade0de8f 157 if (!out) {
bikeNomad 0:84aaade0de8f 158 pc.printf("%s line %d: bad outname \"%s\"\r\n", getTextFileName(), line, q);
bikeNomad 0:84aaade0de8f 159 goto done;
bikeNomad 0:84aaade0de8f 160 }
bikeNomad 0:84aaade0de8f 161 pc.printf("%d add %f %f %s\r\n", line, startTime, endTime, outName);
bikeNomad 0:84aaade0de8f 162
bikeNomad 0:84aaade0de8f 163 actions.push_back(Action(startTime, true, out, outName));
bikeNomad 0:84aaade0de8f 164 actions.push_back(Action(endTime, false, out, outName));
bikeNomad 0:84aaade0de8f 165
bikeNomad 0:84aaade0de8f 166 line++;
bikeNomad 0:84aaade0de8f 167 }
bikeNomad 0:84aaade0de8f 168
bikeNomad 0:84aaade0de8f 169 std::sort(actions.begin(), actions.end()); // sort actions by time
bikeNomad 0:84aaade0de8f 170 retval = true;
bikeNomad 0:84aaade0de8f 171
bikeNomad 0:84aaade0de8f 172 done:
bikeNomad 0:84aaade0de8f 173 if (!retval) {
bikeNomad 0:84aaade0de8f 174 pc.printf("Error reading action from \"%s\"\r\n", actionLine);
bikeNomad 0:84aaade0de8f 175 }
bikeNomad 0:84aaade0de8f 176 fclose(txtfile);
bikeNomad 0:84aaade0de8f 177 return retval;
bikeNomad 0:84aaade0de8f 178 }