// // Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu> // Creation Date: Thu Oct 15 12:40:15 PDT 1998 // Last Modified: Thu Oct 15 13:07:01 PDT 1998 // Filename: ...sig/doc/examples/improv/synthImprov/yekyek/yekyek.cpp // Syntax: C++; synthImprov 2.0 // // Description: Does the opposite of the keykey program // you input a text file and the program will play // the synthesizer according to the specified letters // You can control the interword time and the speed of // the transmission of the characters. Try extending // the program by assigning pitch patterns to the // 10 transmission keys, and using different rhythmic // patterns. // #include "synthImprov.h" #define INTERFACE_FUNCTION /* just a label so you can see req. functions */ #define LOCAL_FUNCTION /* defined just for this program */ /*----------------- beginning of improvization algorithms ---------------*/ int lastNoteTime = 0; // time at which to play next note pair. int notePeriod = 100; // duration of each note int restPeriod = 300; // duration of a non-letter character int duration = 100; // duration of the current note. Voice leftHand; // Voice for left hand notes. Voice rightHand; // Voice for right hand notes. fstream infile; // input file stream for characters int source = 0; // 0 = keyboard; 1 = file int sounding = 0; // 0 = rest, 1 = note on. int character = 0; // character to send int volume = 127; // volume of MIDI int note[10] = {48, 50, 52, 53, 55, 60, 62, 64, 65, 67}; // notes to play // function declarations: void playNotes(int left, int right); void playCharacter(int aCharacter); int getCharacter(void); /*--------------------- maintenance algorithms --------------------------*/ INTERFACE_FUNCTION void description(void) { cout << "\nKeykey: (Craig Stuart Sapp <craig@ccrma.stanford.edu>)" "15 Oct 1998\n" << "Use the white midi keys C-G below middle C for the left hand\n" << "and middle C-G white keys for the right hand\n" << "left hand: C=5, D=4, E=3, F=2, G=1\n" << "right hand: C=1, D=4, E=3, F=4, G=5\n" << "Here are the key combinations (LH col, RH row):\n\n" << " 5 E J O T Y\n" << " 4 D I N S X For example:\n" << " 3 C H M R W LH3+RH2 = F\n" << " 2 B G L Q V LH5+RH3 = O\n" << " 1 A F K P U LH1+RH1 = A\n" << " 1 2 3 4 5" << " Commands:\n" << " 1 = keyboard control, 2 = file control\n" << " - = speed up, = = slow down\n" << endl; } INTERFACE_FUNCTION void initialization(void) { leftHand.setPort(synth.getOutputPort()); rightHand.setPort(synth.getOutputPort()); } INTERFACE_FUNCTION void finishup(void) { leftHand.off(); rightHand.off(); } /*-------------------- main loop algorithms -----------------------------*/ INTERFACE_FUNCTION void mainloopalgorithms(void) { if (source && lastNoteTime + duration <= t_time) { character = getCharacter(); if (character >= 0) { lastNoteTime = t_time; playCharacter(character); if (sounding) { duration = notePeriod; } else { duration = restPeriod; } } } } LOCAL_FUNCTION int getCharacter(void) { int output; if (source == 0) { // keyboard characters are handled elsewhere return -1; } else { output = interfaceKeyboard.getch(); if (infile.eof()) { source = 0; } } if (isalpha(output) || output == '\n') { cout << tolower(output) << flush; } return output; } LOCAL_FUNCTION void playCharacter(int aCharacter) { switch (tolower(aCharacter)) { case 'a': playNotes(1, 1); sounding = 1; break; case 'b': playNotes(2, 1); sounding = 1; break; case 'c': playNotes(3, 1); sounding = 1; break; case 'd': playNotes(4, 1); sounding = 1; break; case 'e': playNotes(5, 1); sounding = 1; break; case 'f': playNotes(1, 2); sounding = 1; break; case 'g': playNotes(2, 2); sounding = 1; break; case 'h': playNotes(3, 2); sounding = 1; break; case 'i': playNotes(4, 2); sounding = 1; break; case 'j': playNotes(5, 2); sounding = 1; break; case 'k': playNotes(1, 3); sounding = 1; break; case 'l': playNotes(2, 3); sounding = 1; break; case 'm': playNotes(3, 3); sounding = 1; break; case 'n': playNotes(4, 3); sounding = 1; break; case 'o': playNotes(5, 3); sounding = 1; break; case 'p': playNotes(1, 4); sounding = 1; break; case 'q': playNotes(2, 4); sounding = 1; break; case 'r': playNotes(3, 4); sounding = 1; break; case 's': playNotes(4, 4); sounding = 1; break; case 't': playNotes(5, 4); sounding = 1; break; case 'u': playNotes(1, 5); sounding = 1; break; case 'v': playNotes(2, 5); sounding = 1; break; case 'w': playNotes(3, 5); sounding = 1; break; case 'x': playNotes(4, 5); sounding = 1; break; case 'y': playNotes(5, 5); sounding = 1; break; default: playNotes(0, 0); sounding = 0; break; } } LOCAL_FUNCTION void playNotes(int left, int right) { switch (left) { case 0: leftHand.off(); case 1: leftHand.play(note[0], volume); case 2: leftHand.play(note[1], volume); case 3: leftHand.play(note[2], volume); case 4: leftHand.play(note[3], volume); case 5: leftHand.play(note[4], volume); } switch (right) { case 0: rightHand.off(); case 1: rightHand.play(note[0+5], volume); case 2: rightHand.play(note[1+5], volume); case 3: rightHand.play(note[2+5], volume); case 4: rightHand.play(note[3+5], volume); case 5: rightHand.play(note[4+5], volume); } } /*-------------------- triggered algorithms -----------------------------*/ INTERFACE_FUNCTION void keyboardchar(int key) { cout << tolower(key) << flush; playCharacter(key); } /*------------------ end improvization algorithms -----------------------*/ // md5sum: 2141ce2c943938b97a28ebc36319f9cd yekyek.cpp [20050403]