// // Programmer: Craig Stuart Sapp // Creation Date: Sat Mar 2 22:32:12 PST 1996 // Last Modified: 5 February 1998 // Filename: gl.cpp // Syntax: Visual C++ 5.0; Synth Improv // // #include "synthimprov.h" #include "Note.h" #include "FunctionNote.h" #include "EventBuffer.h" /*----------------- beginning of improvization algorithms ---------------*/ int octave = 4; // octave range for computer keyboard notes int keyboardnote = 0; // computer keyboard note MidiMessage noteMessage; // for reading keyno and velocity (and time) EventBuffer eventBuffer(2000); // for future notes int direction = 1; // direction of glissandos, 1=up, -1=down int step = 1; // step to take for each note in glissando int rate = 300; // tempo of gliss notes ////////////////////////////// // // GlissNoteFunction -- creates glissandos. To be // used with the FunctionNote class; Notes are generated one at a // time in the EventBuffer from a FunctionNote. // static void GlissNoteFunction(Note* p) { static Note tn; // temporary note before placing in buffer tn.setOnDur(t_time, p->getOffTime()); // off time holds dur tn.play(p->getKey(), p->getVel(), p->getChan()); p->setKeyno(tn.getKey()+step*direction); p->setOnTime(p->getOnTime() + p->getOffTime()); // OffTime stores duration eventBuffer.insert(&tn); if (p->getKey() > C7 || p->getKey() < A0 ) p->off(); } /*--------------------- maintenance algorithms --------------------------*/ void description(void) { printtopline(); printstringline( " Gliss -- by Craig Stuart Sapp -- 5 Feb 1998"); printstringline(""); printstringline( " Description: Creates glissandos when you press a key on the keyboard."); printstringline( " Computer keyboard keys are assigned random attack velocities."); printintermediateline(); printstringline( " User commands:"); printstringline( " \"-\" = decrease step \"=\" = increase step \"\\\" = change direction"); printstringline( " \"[\" = increase rate \"]\" = decrease rate "); printstringline( " \"0\"-\"9\" = octave number of computer keyboard notes"); printstringline( " Notes: s d g h j "); printstringline( " z x c v b n m "); printbottomline(); } void initialization(void) { eventBuffer.setPollRate(10); } void finishup(void) { } /*-------------------- main loop algorithms -----------------------------*/ void playgliss(MidiMessage aMessage) { static Note tn; // a Temporary Note for copying into eventBuffer // setting the fields of the function note, fields are defined in function tn.setStatus(FUNCTION_NOTE); tn.setTag((char*)&GlissNoteFunction); tn.setKeyno(aMessage.p1()); tn.setVelocity(aMessage.p2()); // off time of note holds duration: tn.setOnOff(t_time, rate); eventBuffer.insert(&tn); cout << "UP: StartKey = " << (int)aMessage.p1() << "\tVelocity = " << (int)aMessage.p2() << "\tRate = " << rate << endl; } void mainloopalgorithms(void) { eventBuffer.checkPoll(); // see if any notes need playing while (synth.getNoteCount() > 0) { noteMessage = synth.extractNote(); if (noteMessage.p2() != 0) { playgliss(noteMessage); } } } /*-------------------- triggered algorithms -----------------------------*/ void keyboard(int key) { synth.play(0, keyboardnote, 0); noteMessage.command() = 0x90; noteMessage.p1() = keyboardnote; noteMessage.p2() = 0; synth.insert(noteMessage); switch (key) { case 'z': keyboardnote = 12 * octave + 0; break; // C case 's': keyboardnote = 12 * octave + 1; break; // C# case 'x': keyboardnote = 12 * octave + 2; break; // D case 'd': keyboardnote = 12 * octave + 3; break; // D# case 'c': keyboardnote = 12 * octave + 4; break; // E case 'v': keyboardnote = 12 * octave + 5; break; // F case 'g': keyboardnote = 12 * octave + 6; break; // F# case 'b': keyboardnote = 12 * octave + 7; break; // G case 'h': keyboardnote = 12 * octave + 8; break; // G# case 'n': keyboardnote = 12 * octave + 9; break; // A case 'j': keyboardnote = 12 * octave + 10; break; // A# case 'm': keyboardnote = 12 * octave + 11; break; // B case ',': keyboardnote = 12 * octave + 12; break; // C default: return; } if (keyboardnote < 0) keyboardnote = 0; else if (keyboardnote > 127) keyboardnote = 127; noteMessage.command() = 0x90; noteMessage.p1() = keyboardnote; noteMessage.p2() = rand()%47 + 80; // random int from 1 to 127 synth.play(0, noteMessage.p1(), noteMessage.p2()); synth.insert(noteMessage); } void keyboardchar(int key) { if (isdigit((char)key)) { octave = key - '0'; return; } switch (key) { case '-': step--; if (step < 1) step = 1; cout << "Step = " << step << endl; break; case '=': step++; if (step > 12) step = 12; cout << "Step = " << step << endl; break; case '\\': direction *= -1; if (direction == 1) { cout << "Up" << endl; } else { cout << "Down" << endl; } break; case '[': rate -= 20; if (rate < 20) rate = 20; cout << "Rate = " << rate << endl; break; case ']': rate += 20; cout << "Rate = " << rate << endl; break; default: keyboard(key); } } /*------------------ end improvization algorithms -----------------------*/