Big Mouth Billy Bass automation library
song.cpp
- Committer:
- bikeNomad
- Date:
- 2013-06-18
- Revision:
- 3:6c91a6232c4a
- Parent:
- 1:9b1f3eb204ac
- Child:
- 4:f009306756b3
File content as of revision 3:6c91a6232c4a:
#include <stdlib.h> #include <string.h> #include <stdio.h> #include <ctype.h> #include <algorithm> #include "billybass.hpp" #include "song.hpp" // class static char const Song::directoryName[ BASS_DIRECTORY_LENGTH + 1 ] = BASS_DIRECTORY; // class static char const *Song::textExtension = "txt"; // class static char const *Song::sampleExtension = "raw"; // class static unsigned const Song::NO_FISH = MAX_FISH + 1; // _name is relative to BASS_DIRECTORY // class static Song *Song::newSong(char const *_name) { Song *s = new Song; if (!s) { fprintf(stderr, "new Song == 0\r\n"); return 0; } if (! s->parseFilename(_name)) { fprintf(stderr, "parseFilename(%s) failed\r\n", _name); goto on_error; } fprintf(stderr, "parsed filename OK\r\n"); if (! s->readActions()) { fprintf(stderr, "readActions(%s) failed\r\n", _name); goto on_error; } return s; on_error: delete s; return 0; } bool Song::parseFilename(char const *_name) { if (strlen(_name) > MAX_BASENAME_LENGTH) goto on_error; strcpy(fullname, directoryName); basename = fullname + BASS_DIRECTORY_LENGTH; *basename++ = '/'; strcpy(basename, _name); char *p; long n = strtol(_name, &p, 10); if (*p != '_' || n <= 0) goto on_error; sequenceNumber = (unsigned)(n - 1); p++; // skip underscore n = strtol(p, &p, 10); if (*p != '_' || n <= 0 || n > MAX_FISH) goto on_error; whichFish = (unsigned)(n - 1); p = strrchr(basename, '.'); if (!p) goto on_error; extension = p+1; if (strcasecmp(extension, sampleExtension)) goto on_error; return true; on_error: whichFish = NO_FISH; basename = 0; return false; } bool Song::readActions() { fprintf(stderr, "reading actions of %s\r\n", getTextFileName()); FILE *txtfile = fopen(getTextFileName(), "r"); if (!txtfile) { fprintf(stderr, "can't open %s\r\n", getTextFileName()); return false; } else fprintf(stderr, "opened %s OK\r\n", getTextFileName()); bool retval = false; BillyBass *bass = BillyBass::bassNumber(whichFish); if (!bass) { fprintf(stderr, "No bass!\r\n"); goto done; } // read actions from file static char textFileBuffer[ 2048 ]; memset(textFileBuffer, 0, sizeof(textFileBuffer)); int nread = fread(textFileBuffer, 1, sizeof(textFileBuffer), txtfile); // fprintf(stderr, "Read %d bytes\r\n", nread); if (nread <= 0 || nread == sizeof(textFileBuffer)) { goto done; } unsigned line = 1; for (char *actionLine = strtok(textFileBuffer, "\r\n"); actionLine; actionLine = strtok(0, "\r\n"), line++) { char *p; float startTime = strtof(actionLine, &p); if (p == actionLine) goto done; char *q; float endTime = strtof(p, &q); if (q == p) goto done; char const *outName; DigitalOut *out = bass->outputNamed(++q, &outName); 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); actions.push_back(Action(startTime, bass->onState(), out, outName)); actions.push_back(Action(endTime, bass->offState(), out, outName)); } fprintf(stderr, "Added %d actions\r\n", actions.size()); std::sort(actions.begin(), actions.end()); // sort actions by time retval = true; done: fclose(txtfile); return retval; }