Big Mouth Billy Bass automation library
Revision 2:eaba75af0f0d, committed 2013-06-18
- Comitter:
- bikeNomad
- Date:
- Tue Jun 18 06:12:48 2013 +0000
- Parent:
- 1:9b1f3eb204ac
- Child:
- 3:6c91a6232c4a
- Commit message:
- Still not doing actions but loading OK;
Changed in this revision
--- a/action.hpp Tue Jun 18 00:07:47 2013 +0000
+++ b/action.hpp Tue Jun 18 06:12:48 2013 +0000
@@ -9,20 +9,33 @@
#define MAX_ACTION_LINE_LENGTH 30
-struct Action
-{
+struct Action {
Action(float _time = -1.0,
- bool _state = false,
- DigitalOut *_out = 0,
- char const *_outName = 0)
+ bool _state = false,
+ DigitalOut *_out = 0,
+ char const *_outName = 0)
: actionTime(_time), desiredState(_state)
- , output(_out), outputName(_outName)
- {
+ , output(_out), outputName(_outName) {
+ }
+
+ bool operator < (Action const &other) const {
+ return actionTime < other.actionTime;
}
- bool operator < (Action const &other) const { return actionTime < other.actionTime; }
+ bool isValid() const {
+ return actionTime >= 0.0 && output != 0;
+ }
- bool isValid() const { return actionTime >= 0.0 && output != 0; }
+ void act() {
+ output->write(desiredState ? 1 : 0);
+ }
+
+ bool actIfPast(float _now) {
+ if (_now >= actionTime) {
+ act();
+ return true;
+ } else return false;
+ }
float actionTime;
bool desiredState;
--- a/player.hpp Tue Jun 18 00:07:47 2013 +0000
+++ b/player.hpp Tue Jun 18 06:12:48 2013 +0000
@@ -5,32 +5,27 @@
class SongPlayer;
-struct SampleBuffer
-{
+struct SampleBuffer {
Sample_t volatile buf[ SAMPLES_PER_BUFFER ];
size_t volatile samplesRemaining;
Sample_t volatile * volatile nextSample;
- bool isDone()
- {
+ bool isDone() {
return !samplesRemaining;
}
- float remainingDuration()
- {
+ float remainingDuration() {
return samplesRemaining / SAMPLE_RATE_HZ;
}
// return true if we read any samples
- bool loadFrom(FILE *fp)
- {
+ bool loadFrom(FILE *fp) {
samplesRemaining = fread((void*)buf, sizeof(Sample_t), SAMPLES_PER_BUFFER, fp);
nextSample = buf;
return samplesRemaining > 0;
}
- Sample_t getNextSample()
- {
+ Sample_t getNextSample() {
--samplesRemaining;
return *++nextSample;
}
@@ -40,8 +35,7 @@
}
};
-struct SongPlayer
-{
+struct SongPlayer {
SampleBuffer * volatile playing;
SampleBuffer * volatile loading;
SampleBuffer buffer[2];
@@ -50,29 +44,38 @@
size_t volatile chunksRemaining;
float timeInSong;
Ticker sampleTicker;
+ Song *song;
+ Song::actions_t::iterator nextAction;
+ unsigned actionsDone;
SongPlayer() : playing(0)
, loading(0)
, fp(0)
, nChunks(0)
, chunksRemaining(0)
- {
+ , song(0)
+ , actionsDone(0)
+ {
}
// interrupt handler
- void playNextSample(void)
- {
+ void playNextSample(void) {
if (playing->samplesRemaining == 0)
swapBuffers();
// NOTE bias of 0xC000 requires normalizing to 75% of full scale
speaker.write_u16(static_cast<uint16_t>(playing->getNextSample() + 0x8000) / 2);
}
- bool startSong(char const *name)
- {
- pc.printf("starting %s: ", name);
+ bool startSong(Song *_song) {
+ if (song) delete song;
+ song = _song;
+ nextAction = song->getActions().begin();
+ timeInSong = 0.0;
+ actionsDone = 0;
+
+ pc.printf("starting %s: ", song->getSampleFileName());
if (fp) fclose(fp);
- fp = fopen(name, "rb");
+ fp = fopen(song->getSampleFileName(), "rb");
pc.printf("opened, ");
if (!fp) return false;
@@ -93,15 +96,14 @@
if (!loadNextChunk())
return false;
- timeInSong = 0.0;
+
sampleTicker.attach_us(this, &SongPlayer::playNextSample, SAMPLE_PERIOD_USEC);
return true;
}
// swap loading/playing buffers;
// decrement chunksRemaining
- void swapBuffers()
- {
+ void swapBuffers() {
SampleBuffer * volatile tmp = playing;
if (tmp == buffer + 0)
playing = buffer + 1;
@@ -115,36 +117,35 @@
// get next chunk of file into *loading
// to prepare for eventual swap.
// returns true if more samples remain
- bool loadNextChunk()
- {
+ bool loadNextChunk() {
if (!chunksRemaining) return false;
bool notDone = loading->loadFrom(fp);
return notDone;
}
- bool isDone()
- {
+ bool isDone() {
return !chunksRemaining;
}
// look at loading buffer; load only if necessary.
- bool loadIfNecessary()
- {
- if (loading->isDone())
- {
+ bool loadIfNecessary() {
+ if (loading->isDone()) {
timeInSong += SECONDS_PER_CHUNK;
return loadNextChunk();
+ } else {
+ return true;
}
- else { return true; }
}
- void playEntireSong(char const *name)
- {
- if (!startSong(name)) return;
+ void playEntireSong(Song *_song) {
+ if (!startSong(_song)) return;
- while (!isDone())
- {
+ while (!isDone()) {
+ while (nextAction != song->getActions().end() && nextAction->actIfPast(timeInSong)) {
+ actionsDone++;
+ nextAction++;
+ }
loadIfNecessary();
}
sampleTicker.detach();
--- a/song.hpp Tue Jun 18 00:07:47 2013 +0000
+++ b/song.hpp Tue Jun 18 06:12:48 2013 +0000
@@ -44,7 +44,7 @@
strcpy(extension, textExtension);
return fullname;
}
- actions_t const &getActions() const {
+ actions_t &getActions() {
return actions;
}
Ned Konz