Big Mouth Billy Bass automation library
song.cpp
- Committer:
- bikeNomad
- Date:
- 2013-06-18
- Revision:
- 1:9b1f3eb204ac
- Parent:
- 0:84aaade0de8f
- Child:
- 3:6c91a6232c4a
File content as of revision 1:9b1f3eb204ac:
#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) { pc.printf("new Song == 0\r\n"); return 0; } if (! s->parseFilename(_name)) { pc.printf("parseFilename(%s) failed\r\n", _name); goto on_error; } pc.printf("parsed filename OK\r\n"); if (! s->readActions()) { pc.printf("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() { pc.printf("reading actions of %s\r\n", getTextFileName()); FILE *txtfile = fopen(getTextFileName(), "r"); if (!txtfile) { pc.printf("can't open %s\r\n", getTextFileName()); return false; } else pc.printf("opened %s OK\r\n", getTextFileName()); bool retval = false; BillyBass *bass = BillyBass::bassNumber(whichFish); if (!bass) { pc.printf("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); pc.printf("Read %d\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) { pc.printf("%s line %d: bad outname \"%s\"\r\n", getTextFileName(), line, q); goto done; } pc.printf("%d add %f %f %s\r\n", line, startTime, endTime, outName); // actions.push_back(Action(startTime, true, out, outName)); // actions.push_back(Action(endTime, false, out, outName)); } std::sort(actions.begin(), actions.end()); // sort actions by time retval = true; done: fclose(txtfile); return retval; }