// Programmer: Craig Stuart Sapp // Programmer: Sachiko Deguchi // Creation Date: Thu Jun 27 12:17:39 PDT 2002 // Last Modified: Thu Jun 27 12:17:42 PDT 2002 // Filename: ...sig/doc/examples/all/kotomel.cpp // Syntax: C++; batonImprov 2.0 // // Description: // #define USE_TABLET #include "batonImprov.h" #define PCLASS 5 int pitches[PCLASS] = {2, 3, 7, 9, 10}; // pentatonic scale degrees typedef Array ArrayInt; typedef Array ArrayIntInt; Array emptyPattern(0); // dummy pattern Array patternA; // primary patterns Array patternB; // secondary patterns int xchoice = 0; // baton 2 pattern choice int ychoice = 0; // baton 2 pattern choice int startpoint = 0; // baton 1 trigger pattern start Array *currentPattern = NULL; // current pattern being played int position = 0; // current pattern index being played int startnote = 0; // starting note of pattern int note = 0; // current note being played int octave = 0; // octave of startnote int pitchclass = 0; // pitch class of startnote Voice voice; /*----------------- beginning of improvization algorithms ---------------*/ void fillPatterns(Array& patternA, Array& patternB); void setPattern(int xchoice, int ychoice, int startpoint); void fdata(Array& pattern, int* data); void fdata(Array& pattern, int state); void printPattern(Array& currentPattern); /*--------------------- maintenance algorithms --------------------------*/ ////////////////////////////// // // description -- this function is called by the improv interface // whenever a capital "D" is pressed on the computer keyboard. // Put a description of the program and how to use it here. // void description(void) { cout << "Write the program description here" << endl; } ////////////////////////////// // // initialization -- this function is called by the improv // interface once at the start of the program. Put items // here which need to be initialized at the beginning of // the program. // void initialization(void) { voice.setPort(synth.getPort()); voice.setChannel(0); fillPatterns(patternA, patternB); } ////////////////////////////// // // finishup -- this function is called by the improv interface // whenever the program is exited. Put items here which // need to be taken care of when the program is finished. // void finishup(void) { } /*-------------------- main loop algorithms -----------------------------*/ ////////////////////////////// // // mainloopalgorithms -- this function is called by the improv interface // continuously while the program is running. The global variable t_time // which stores the current time is set just before this function is // called and remains constant while in this functions. // void mainloopalgorithms(void) { } /*-------------------- triggered algorithms -----------------------------*/ ////////////////////////////// // // stick1trig -- this function is called automatically whenever // a baton stick #1 trigger is received. // void stick1trig(void) { cout << "position = " << position << endl; if (position == 0) { octave = midiscale(baton.y1t, 5, 6); pitchclass = midiscale(baton.x1t,0, PCLASS - 1); if (octave == 5) { startpoint = pitchclass; } else { startpoint = pitchclass + PCLASS; } startnote = octave * 12 + pitches[pitchclass]; note = startnote; cout << "Start Note: " << note << endl; voice.play(note, midiscale(baton.w1t, 30, 120)); // play: note, velocity :: velocity 30 <--> 120 position++; } else if (position == 1) { setPattern(xchoice, ychoice, startpoint); // check to see if a null pattern if (position > currentPattern->getSize()) { position = 0; return; } cout << "next note : " << note << " + " << (*currentPattern)[position-1]; note += (*currentPattern)[position-1]; cout << "\t= " << note << endl; voice.play(note, midiscale(baton.w1t, 30, 120)); position++; if (position > currentPattern->getSize()) { position = 0; } } else { cout << "next note : " << note << " + " << (*currentPattern)[position-1]; note += (*currentPattern)[position-1]; cout << "\t= " << note << endl; voice.play(note, midiscale(baton.w1t, 30, 120)); position++; if (position > currentPattern->getSize()) { position = 0; } } } ////////////////////////////// // // stick2trig -- this function is called automatically whenever // a baton stick #2 trigger is received. // void stick2trig(void) { static int oldx; static int oldy; oldx = xchoice; oldy = ychoice; xchoice = midiscale(baton.x2t, 0, 4); ychoice = midiscale(baton.y2t, 0, 3); cout << "Choice: x = " << xchoice << "\ty = " << ychoice << endl; if (xchoice == 0 && ychoice == 0) { xchoice = oldx; ychoice = oldy; voice.off(); cout << "Note off" << endl; position = 0; } if (xchoice == 0 && ychoice == 1) { xchoice = oldx; ychoice = oldy; voice.off(); cout << "Note off" << endl; position = 0; } } ////////////////////////////// // // setPattern -- return an index to the pattern to play // void setPattern(int xchoice, int ychoice, int startpoint) { switch (xchoice + 10 * ychoice) { case 30: currentPattern = &patternA[startpoint][0]; cout << "Using Pattern " << startpoint << " 1" << endl; break; case 31: if (patternA[startpoint][1].getSize() != 0) { currentPattern = &patternA[startpoint][1]; cout << "Using Pattern " << startpoint << " 2" << endl; } else if (patternA[startpoint][2].getSize() != 0) { currentPattern = &patternA[startpoint][2]; cout << "Using Pattern " << startpoint << " 3" << endl; } else { cout << "EMPTY PATTERN -- using last one" << endl; } break; case 32: if (patternA[startpoint][2].getSize() != 0) { currentPattern = &patternA[startpoint][2]; cout << "Using Pattern " << startpoint << " 3" << endl; } else if (patternA[startpoint][1].getSize() != 0) { currentPattern = &patternA[startpoint][1]; cout << "Using Pattern " << startpoint << " 2" << endl; } else { cout << "EMPTY PATTERN -- using last one" << endl; } break; case 33: if (patternA[startpoint][3].getSize() != 0) { currentPattern = &patternA[startpoint][3]; cout << "Using Pattern " << startpoint << " 4" << endl; } else if (patternA[startpoint][4].getSize() != 0) { currentPattern = &patternA[startpoint][4]; cout << "Using Pattern " << startpoint << " 5" << endl; } else { cout << "EMPTY PATTERN -- using last one" << endl; } break; case 34: if (patternA[startpoint][4].getSize() != 0) { currentPattern = &patternA[startpoint][4]; cout << "Using Pattern " << startpoint << " 5" << endl; } else if (patternA[startpoint][3].getSize() != 0) { currentPattern = &patternA[startpoint][3]; cout << "Using Pattern " << startpoint << " 4" << endl; } else { cout << "EMPTY PATTERN -- using last one" << endl; } break; case 20: if (patternB[startpoint][0].getSize() != 0) { currentPattern = &patternB[startpoint][0]; cout << "Using Pattern " << startpoint << " 1'" << endl; } else if (patternA[startpoint][0].getSize() != 0) { currentPattern = &patternA[startpoint][0]; cout << "Using Pattern " << startpoint << " 1" << endl; } else { cout << "EMPTY PATTERN -- using last one" << endl; } break; case 21: if (patternB[startpoint][1].getSize() != 0) { currentPattern = &patternB[startpoint][1]; cout << "Using Pattern " << startpoint << " 2'" << endl; } else if (patternA[startpoint][1].getSize() != 0) { currentPattern = &patternA[startpoint][1]; cout << "Using Pattern " << startpoint << " 2" << endl; } else if (patternB[startpoint][2].getSize() != 0) { currentPattern = &patternB[startpoint][2]; cout << "Using Pattern " << startpoint << " 3'" << endl; } else if (patternA[startpoint][2].getSize() != 0) { currentPattern = &patternA[startpoint][2]; cout << "Using Pattern " << startpoint << " 3" << endl; } break; case 22: if (patternB[startpoint][2].getSize() != 0) { currentPattern = &patternB[startpoint][2]; cout << "Using Pattern " << startpoint << " 3'" << endl; } else if (patternA[startpoint][2].getSize() != 0) { currentPattern = &patternA[startpoint][2]; cout << "Using Pattern " << startpoint << " 3" << endl; } else if (patternB[startpoint][1].getSize() != 0) { currentPattern = &patternB[startpoint][1]; cout << "Using Pattern " << startpoint << " 2'" << endl; } else if (patternA[startpoint][1].getSize() != 0) { currentPattern = &patternA[startpoint][1]; cout << "Using Pattern " << startpoint << " 2" << endl; } break; case 23: if (patternB[startpoint][3].getSize() != 0) { currentPattern = &patternB[startpoint][3]; cout << "Using Pattern " << startpoint << " 4'" << endl; } else if (patternA[startpoint][3].getSize() != 0) { currentPattern = &patternA[startpoint][3]; cout << "Using Pattern " << startpoint << " 4" << endl; } else if (patternB[startpoint][4].getSize() != 0) { currentPattern = &patternB[startpoint][4]; cout << "Using Pattern " << startpoint << " 5'" << endl; } else if (patternA[startpoint][4].getSize() != 0) { currentPattern = &patternA[startpoint][4]; cout << "Using Pattern " << startpoint << " 5" << endl; } break; case 24: if (patternB[startpoint][4].getSize() != 0) { currentPattern = &patternB[startpoint][4]; cout << "Using Pattern " << startpoint << " 5'" << endl; } else if (patternA[startpoint][4].getSize() != 0) { currentPattern = &patternA[startpoint][4]; cout << "Using Pattern " << startpoint << " 5" << endl; } else if (patternB[startpoint][3].getSize() != 0) { currentPattern = &patternB[startpoint][3]; cout << "Using Pattern " << startpoint << " 4'" << endl; } else if (patternA[startpoint][5].getSize() != 0) { currentPattern = &patternA[startpoint][5]; cout << "Using Pattern " << startpoint << " 4" << endl; } break; case 10: position = 0; currentPattern = &emptyPattern; break; case 11: if (patternA[startpoint][5].getSize() != 0) { currentPattern = &patternA[startpoint][5]; cout << "Using Pattern " << startpoint << " 6" << endl; } else if (patternA[startpoint][6].getSize() != 0) { currentPattern = &patternA[startpoint][6]; cout << "Using Pattern " << startpoint << " 7" << endl; } else { cout << "EMPTY PATTERN -- using last one" << endl; } break; case 12: if (patternA[startpoint][6].getSize() != 0) { currentPattern = &patternA[startpoint][6]; cout << "Using Pattern " << startpoint << " 7" << endl; } else if (patternA[startpoint][5].getSize() != 0) { currentPattern = &patternA[startpoint][5]; cout << "Using Pattern " << startpoint << " 6" << endl; } else { cout << "EMPTY PATTERN -- using last one" << endl; } break; case 13: if (patternA[startpoint][7].getSize() != 0) { currentPattern = &patternA[startpoint][7]; cout << "Using Pattern " << startpoint << " 8" << endl; } else if (patternA[startpoint][8].getSize() != 0) { currentPattern = &patternA[startpoint][8]; cout << "Using Pattern " << startpoint << " 9" << endl; } else { cout << "EMPTY PATTERN -- using last one" << endl; } break; case 14: if (patternA[startpoint][8].getSize() != 0) { currentPattern = &patternA[startpoint][8]; cout << "Using Pattern " << startpoint << " 9" << endl; } else if (patternA[startpoint][7].getSize() != 0) { currentPattern = &patternA[startpoint][7]; cout << "Using Pattern " << startpoint << " 8" << endl; } else { cout << "EMPTY PATTERN -- using last one" << endl; } break; case 0: position = 0; currentPattern = &emptyPattern; break; case 1: if (patternB[startpoint][5].getSize() != 0) { currentPattern = &patternB[startpoint][5]; cout << "Using Pattern " << startpoint << " 6'" << endl; } else if (patternA[startpoint][5].getSize() != 0) { currentPattern = &patternA[startpoint][5]; cout << "Using Pattern " << startpoint << " 6" << endl; } else if (patternB[startpoint][6].getSize() != 0) { currentPattern = &patternB[startpoint][6]; cout << "Using Pattern " << startpoint << " 7'" << endl; } else if (patternA[startpoint][6].getSize() != 0) { currentPattern = &patternA[startpoint][6]; cout << "Using Pattern " << startpoint << " 7" << endl; } break; case 2: if (patternB[startpoint][6].getSize() != 0) { currentPattern = &patternB[startpoint][6]; cout << "Using Pattern " << startpoint << " 7'" << endl; } else if (patternA[startpoint][6].getSize() != 0) { currentPattern = &patternA[startpoint][6]; cout << "Using Pattern " << startpoint << " 7" << endl; } else if (patternB[startpoint][5].getSize() != 0) { currentPattern = &patternB[startpoint][5]; cout << "Using Pattern " << startpoint << " 6'" << endl; } else if (patternA[startpoint][5].getSize() != 0) { currentPattern = &patternA[startpoint][5]; cout << "Using Pattern " << startpoint << " 6" << endl; } break; case 3: if (patternB[startpoint][7].getSize() != 0) { currentPattern = &patternB[startpoint][7]; cout << "Using Pattern " << startpoint << " 8'" << endl; } else if (patternA[startpoint][7].getSize() != 0) { currentPattern = &patternA[startpoint][7]; cout << "Using Pattern " << startpoint << " 8" << endl; } else if (patternB[startpoint][8].getSize() != 0) { currentPattern = &patternB[startpoint][8]; cout << "Using Pattern " << startpoint << " 9'" << endl; } else if (patternA[startpoint][8].getSize() != 0) { currentPattern = &patternA[startpoint][8]; cout << "Using Pattern " << startpoint << " 9" << endl; } break; case 4: if (patternB[startpoint][8].getSize() != 0) { currentPattern = &patternB[startpoint][8]; cout << "Using Pattern " << startpoint << " 9'" << endl; } else if (patternA[startpoint][8].getSize() != 0) { currentPattern = &patternA[startpoint][8]; cout << "Using Pattern " << startpoint << " 9" << endl; } else if (patternB[startpoint][7].getSize() != 0) { currentPattern = &patternB[startpoint][7]; cout << "Using Pattern " << startpoint << " 8'" << endl; } else if (patternA[startpoint][7].getSize() != 0) { currentPattern = &patternA[startpoint][7]; cout << "Using Pattern " << startpoint << " 8" << endl; } break; default: currentPattern = &patternA[startpoint][0]; cout << "Using Pattern " << startpoint << " 1 (default)" << endl; break; } printPattern(*currentPattern); } ////////////////////////////// // // printPattern -- // void printPattern(Array& currentPattern) { int i; cout << "Pattern(" << currentPattern.getSize() << "):\t"; for (i=0; i& patternA, Array& patternB) { patternA.setSize(11); patternB.setSize(11); int i; for (i=0; i<11; i++) { patternA[i].setSize(18); patternB[i].setSize(18); } // S1 patterns fdata(patternA[0][0], 0); fdata(patternB[0][0], 0); fdata(patternA[0][1], 0); fdata(patternB[0][1], 0); fdata(patternA[0][2], 0); fdata(patternB[0][2], 0); fdata(patternA[0][3], 0); fdata(patternB[0][3], 0); fdata(patternA[0][4], 0); fdata(patternB[0][4], 0); fdata(patternA[0][5], pS1_6); fdata(patternB[0][5], 0); fdata(patternA[0][6], 0); fdata(patternB[0][6], 0); fdata(patternA[0][7], 0); fdata(patternB[0][7], 0); fdata(patternA[0][8], 0); fdata(patternB[0][8], 0); // S2 patterns fdata(patternA[1][0], 0); fdata(patternB[1][0], 0); fdata(patternA[1][1], pS2_2); fdata(patternB[1][1], 0); fdata(patternA[1][2], 0); fdata(patternB[1][2], 0); fdata(patternA[1][3], pS2_4); fdata(patternB[1][3], 0); fdata(patternA[1][4], 0); fdata(patternB[1][4], 0); fdata(patternA[1][5], pS2_6); fdata(patternB[1][5], 0); fdata(patternA[1][6], 0); fdata(patternB[1][6], 0); fdata(patternA[1][7], pS2_8); fdata(patternB[1][7], 0); fdata(patternA[1][8], pS2_9); fdata(patternB[1][8], 0); // S4 patterns fdata(patternA[2][0], pS4_1); fdata(patternB[2][0], pS4_1b); fdata(patternA[2][1], 0); fdata(patternB[2][1], 0); fdata(patternA[2][2], 0); fdata(patternB[2][2], 0); fdata(patternA[2][3], pS4_4); fdata(patternB[2][3], 0); fdata(patternA[2][4], 0); fdata(patternB[2][4], 0); fdata(patternA[2][5], pS4_6); fdata(patternB[2][5], 0); fdata(patternA[2][6], pS4_7); fdata(patternB[2][6], 0); fdata(patternA[2][7], 0); fdata(patternB[2][7], 0); fdata(patternA[2][8], 0); fdata(patternB[2][8], 0); // S5 patterns fdata(patternA[3][0], pS5_1); fdata(patternB[3][0], 0); fdata(patternA[3][1], pS5_2); fdata(patternB[3][1], 0); fdata(patternA[3][2], 0); fdata(patternB[3][2], 0); fdata(patternA[3][3], pS5_4); fdata(patternB[3][3], pS5_4b); fdata(patternA[3][4], pS5_5); fdata(patternB[3][4], 0); fdata(patternA[3][5], pS5_6); fdata(patternB[3][5], 0); fdata(patternA[3][6], 0); fdata(patternB[3][6], 0); fdata(patternA[3][7], 0); fdata(patternB[3][7], 0); fdata(patternA[3][8], 0); fdata(patternB[3][8], 0); // S6 patterns fdata(patternA[4][0], pS6_1); fdata(patternB[4][0], 0); fdata(patternA[4][1], pS6_2); fdata(patternB[4][1], 0); fdata(patternA[4][2], 0); fdata(patternB[4][2], 0); fdata(patternA[4][3], pS6_4); fdata(patternB[4][3], 0); fdata(patternA[4][4], 0); fdata(patternB[4][4], 0); fdata(patternA[4][5], pS6_6); fdata(patternB[4][5], 0); fdata(patternA[4][6], pS6_7); fdata(patternB[4][6], 0); fdata(patternA[4][7], 0); fdata(patternB[4][7], 0); fdata(patternA[4][8], 0); fdata(patternB[4][8], 0); // S1b patterns fdata(patternA[5][0], pS1b_1); fdata(patternB[5][0], pS1b_1b); fdata(patternA[5][1], 0); fdata(patternB[5][1], 0); fdata(patternA[5][2], pS1b_3); fdata(patternB[5][2], 0); fdata(patternA[5][3], pS1b_4); fdata(patternB[5][3], pS1b_4b); fdata(patternA[5][4], pS1b_5); fdata(patternB[5][4], 0); fdata(patternA[5][5], pS1b_6); fdata(patternB[5][5], pS1b_6b); fdata(patternA[5][6], 0); fdata(patternB[5][6], 0); fdata(patternA[5][7], 0); fdata(patternB[5][7], 0); fdata(patternA[5][8], 0); fdata(patternB[5][8], 0); // S2b patterns fdata(patternA[6][0], 0); fdata(patternB[6][0], 0); fdata(patternA[6][1], pS2b_2); fdata(patternB[6][1], pS2b_2b); fdata(patternA[6][2], 0); fdata(patternB[6][2], 0); fdata(patternA[6][3], pS2b_4); fdata(patternB[6][3], 0); fdata(patternA[6][4], 0); fdata(patternB[6][4], 0); fdata(patternA[6][5], pS2b_6); fdata(patternB[6][5], 0); fdata(patternA[6][6], 0); fdata(patternB[6][6], 0); fdata(patternA[6][7], pS2b_8); fdata(patternB[6][7], 0); fdata(patternA[6][8], pS2b_9); fdata(patternB[6][8], 0); // S4b patterns fdata(patternA[7][0], pS4b_1); fdata(patternB[7][0], pS4b_1b); fdata(patternA[7][1], 0); fdata(patternB[7][1], 0); fdata(patternA[7][2], 0); fdata(patternB[7][2], 0); fdata(patternA[7][3], pS4b_4); fdata(patternB[7][3], 0); fdata(patternA[7][4], 0); fdata(patternB[7][4], 0); fdata(patternA[7][5], pS4b_6); fdata(patternB[7][5], 0); fdata(patternA[7][6], pS4b_7); fdata(patternB[7][6], 0); fdata(patternA[7][7], 0); fdata(patternB[7][7], 0); fdata(patternA[7][8], 0); fdata(patternB[7][8], 0); // S5b patterns fdata(patternA[8][0], pS5b_1); fdata(patternB[8][0], 0); fdata(patternA[8][1], pS5b_2); fdata(patternB[8][1], 0); fdata(patternA[8][2], 0); fdata(patternB[8][2], 0); fdata(patternA[8][3], pS5b_4); fdata(patternB[8][3], pS5b_4b); fdata(patternA[8][4], pS5b_5); fdata(patternB[8][4], 0); fdata(patternA[8][5], pS5b_6); fdata(patternB[8][5], 0); fdata(patternA[8][6], 0); fdata(patternB[8][6], 0); fdata(patternA[8][7], 0); fdata(patternB[8][7], 0); fdata(patternA[8][8], 0); fdata(patternB[8][8], 0); // S6b patterns fdata(patternA[9][0], pS6b_1); fdata(patternB[9][0], 0); fdata(patternA[9][1], pS6b_2); fdata(patternB[9][1], 0); fdata(patternA[9][2], 0); fdata(patternB[9][2], 0); fdata(patternA[9][3], pS6b_4); fdata(patternB[9][3], 0); fdata(patternA[9][4], 0); fdata(patternB[9][4], 0); fdata(patternA[9][5], pS6b_6); fdata(patternB[9][5], 0); fdata(patternA[9][6], pS6b_7); fdata(patternB[9][6], 0); fdata(patternA[9][7], 0); fdata(patternB[9][7], 0); fdata(patternA[9][8], 0); fdata(patternB[9][8], 0); // S1c patterns fdata(patternA[10][0], pS1c_1); fdata(patternB[10][0], pS1c_1b); fdata(patternA[10][1], 0); fdata(patternB[10][1], 0); fdata(patternA[10][2], pS1c_3); fdata(patternB[10][2], 0); fdata(patternA[10][3], pS1c_4); fdata(patternB[10][3], pS1c_4b); fdata(patternA[10][4], 0); fdata(patternB[10][4], 0); fdata(patternA[10][5], 0); fdata(patternB[10][5], 0); fdata(patternA[10][6], 0); fdata(patternB[10][6], 0); fdata(patternA[10][7], 0); fdata(patternB[10][7], 0); fdata(patternA[10][8], 0); fdata(patternB[10][8], 0); } ////////////////////////////// // // fdata -- fill an array with data. // void fdata(Array& pattern, int state) { pattern.setSize(0); } void fdata(Array& pattern, int* data) { pattern.setSize(0); int i = 0; while (data[i] != 0) { pattern.append(data[i]); i++; } } /*------------------ end improvization algorithms -----------------------*/