Big Mouth Billy Bass automation library
song.cpp@3:6c91a6232c4a, 2013-06-18 (annotated)
- 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?
User | Revision | Line number | New 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 | } |