Example #1
0
bool Playlist::playAdjacent(int8_t bump, bool chainingPlaylists) {
    if( ! isFirst) {
        int8_t next = playIndex + bump;
        setPlayIndex(next);
        if(chainingPlaylists && playIndex != next) { // we've wrapped
            // advance playlists until find another list with chirps or we're back where we started
            for(int i = 0; i < N_PLAYLISTS; i++) {
                Playlist *p = Playlists::useAdjacentPlaylist(bump, false); // false to not store
                if(p->nChirps) {
                    Playlists::useAdjacentPlaylist(0); // use this one & store it this time
                    p->setPlayIndex(bump > 0 ? 0 : -1); // -1 forces wrap to nChirps - 1
                    return p->play();
                }
            }
        }
    }
    return play();
}
Example #2
0
bool doCommand(char *command) {
	// new commands always turn off immediate autoplay
	immediateAutoplayStop();

	int length = strlen(command);
	if(length == 0) {
		return true;
	}

	char commandChar = toupper(command[0]);
	char *parameters = &command[1];
	bool noParameters = length == 1;
	char firstParameterChar = noParameters ? '\0' : toupper(*parameters);

	Serial.println(command);
	Playlist *playlist = Playlists::currentPlaylist();

	switch(commandChar) {
		case '+': // see also default at end of switch for making chirps without preceding with +
			if( ! noParameters) {
				return makeNewChirp(parameters);
			}
			break;

		case ']':
		case ')':
			if(noParameters) {
				Serial.println(F("next"));
				playlist->playAdjacent(1, commandChar == ')'); // ] wraps, ) chains
			}
			break;

		case '[':
		case '(':
			if(noParameters) {
				Serial.println(F("back"));
				playlist->playAdjacent(-1, commandChar == '('); // [ wraps, ( chains
			}
			break;

		case ',':
			if(noParameters) {
				Serial.println(F("step"));
				playlist->playSequenced();
			}
			break;

		case '@': // select playlist by index number..
			if(noParameters) {
				playlist->setPlayIndex(0); // ..or reset play index to 0 in current playlist
			}
			else {
				playlist = Playlists::usePlaylist(number(parameters, playlist->playlistIndex));
			}
			break;

		case '}':
		case '{':
			if(noParameters) {
				playlist = Playlists::useAdjacentPlaylist(commandChar == '}' ? 1 : -1);
			}
			break;

		case '!': // play current or supplied code
			if(noParameters) {
				playlist->play();
			}
			else if(isAChirpCode(parameters)) {
				playlist->playChirpCode(parameters);
			}
			else {
				playlist->playIndexed(number(parameters, playlist->playIndex));
			}
			break;

		case '?':
			if(noParameters) {
				Serial.println(F("lookup"));
				return ! playerLink.fetchChirpContent(playlist);
			}
			break;

		case '~': // clearing
			Serial.println(F("clear"));
			if(noParameters) {
				playlist->clear(CLEAR_LIST);
			}
			else if(firstParameterChar == '#') {
				playlist->clear(CLEAR_SCRIPT_URL);
			}
			else if(strcmp(parameters, "!") == 0) {
				Playlists::clearAll();
			}
			else {
				playlist->clear(number(parameters));
			}
			break;

		case '.': // autoplay order & chirping interval
			if( ! noParameters && strchr("FBRS", firstParameterChar)) {
				playlist->setPlayOrder(firstParameterChar);
				parameters++;
				if(*parameters == '\0') {
					return true;
				}
			}
			playlist->setInterval(number(parameters, DEFAULT_INTERVAL));
			break;

		case ':': // sound
			if( ! noParameters && strchr("PNM", firstParameterChar)) {
				if(firstParameterChar == 'M') {
					muted = ! muted;
					Serial.print(F("muting "));
					Serial.println(muted ? F("on") : F("off"));
				}
				else {
					playlist->setPortamento(firstParameterChar == 'P');
				}
				parameters++;
				if(*parameters == '\0') {
					return true;
				}
			}
			playlist->setVolume(number(parameters, DEFAULT_VOLUME)); // noParam form will set volume to default
			break;

		case '*': // autoplay
			if(noParameters) {
				Serial.println(F("autoplay now"));
				immediateAutoplayStart();
				return false; // don't show prompt
			}
			else {
				doAutoplaySettingsCommand(playlist, parameters);
			}
			break;

		case '|':
			Serial.println(F("limit"));
			playlist->setAutoplayChirpLimit(number(parameters, PLAYLIST_CAPACITY));
			break;

		case '^': // times
			Serial.println(F("time"));
			if(noParameters) {
				return ! playerLink.fetchTimeNow();
			}
			else if(firstParameterChar == '-') {
				adjustTimeSeconds(-number(&parameters[1]));
			}
			else if(firstParameterChar == '+') {
				adjustTimeSeconds(number(&parameters[1]));
			}
			if(stringToSeconds(parameters)) {
				setTimeUTC(parameters);
			}
			break;

		case '#': // scripts
			if(noParameters) {
				if( ! playlist->requestUpdate()) {
					Serial.println(F("no script"));
				}
			}
			else {
				if(length == 2) {
					if(firstParameterChar == '?') { // #? to print current playlist in script format
						playlist->printAsScript();
					}
					else {
						playlist->setUpdateFlags(number(parameters));
					}
				}
				else {
					playlist->setScriptAddress(parameters);
				}
			}
			break;

		case '/': // run named script, or update all playlists with scripts
			Serial.println(F("run"));
			if(noParameters) {
				Playlists::updateAll(false); // false => not conditional on playlist flags
			}
			else {
				return ! playerLink.fetchScript(-1, parameters); // -1 signals is general script, not one for a particular playlist
			}
			break;

		case '=': // invoke trigger from the command line
			Trigger::trigger(parameters);
			break;

		case '-':
			inactivityTrigger.setWaitSeconds(number(parameters));
			break;

		case '%': // comment line; ignore
			break;

		default:
			if(isAChirpCode(command)) {
				playlist->add(command);
			}
			else {
				Serial.println(F("uh?"));
			}
			break;
	}
	return true;
}