Goto: [ Program Documentation ]
// // Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu> // Creation Date: 23 January 1998 // Last Modified: Sat Jan 16 15:08:32 PST 1999 // Filename: ...sig/doc/examples/improv/synthImprov/sinus/sinus.cpp // Syntax: C++; synthImprov 2.0 // // Description: you press a key on the synthesizer keyboard, and a pitch // pattern shaped like a sinewave is generated. Attack velocity give // amplitude of sine wave. Alternatively, there is a synthesizer // keyboard mapped to the computer keyboard: the octave is controlled // by the numbers 0-9, and the chromatic pitches are on the bottom // two rows of the keyboard (e.g., 'z' is the note C). '-' and '=' // control the period size which controls how many notes to play // in one sinewave cycle. '[' and ']' controls the tempo of the // sinewave notes in 100 millisecond increments. If you play // a note loudly, then the sinewave pattern will be soft, and // if you play a note softly, then the pattern will be loud. // The pattern is played as long as you are holding down a note. // If you are playing notes from the computer keyboard, then // their attack velocities are assigned random values from 1 to // 127 since computer keyboards don't record attack velocity. // #include "synthImprov.h" /*----------------- beginning of improvization algorithms ---------------*/ #define TWOPI 6.283185307 int centernote = 0; // played note which centers sinewave pattern int amplitude = 0; // greatest deviation amplitude of sine function int sinenote = 0; // current note of the sinewave int sinevelocity = 0; // current velocity of the sinewave int period = 5; // how many notes to play in the sinewave pattern int counte = 0; // which note of the period we are on int duration = 200; // duration of sine notes int octave = 4; // octave range for computer keyboard notes int keyboardnote = 0; // computer keyboard note int lastoff = 0; // last note which was turned off int nextnotetime = 0; // time for the next note MidiMessage noteMessage; // for reading keyno and velocity (and time) Voice sinevoice; // for handling note-offs /*--------------------- maintenance algorithms --------------------------*/ void description(void) { printboxtop(); psl("Sinus -- by Craig Stuart Sapp <craig@ccrma.stanford.edu>, 24 Jan 1998"); psl(""); psl(" Description: press a key on the synthesizer keyboard, and a pitch "); psl(" pattern shaped like a sinewave is generated. Attack velocity gives"); psl(" inverse amplitude of sine wave. Computer keyboard keys are assigned"); psl(" random attack velocities"); printintermediateline(); psl(" User commands:"); psl(" \"-\" = decrease period length \"=\" = increase period length "); psl(" \"[\" = decrease duration \"]\" = increase duration"); psl(" "); psl(" \"0\"-\"9\" = octave number of computer keyboard notes"); psl(" Notes: s d g h j "); psl(" z x c v b n m "); printboxbottom(); } void initialization(void) { sinevoice.setPort(synth.getOutputPort()); sinevoice.setChannel(0); } void finishup(void) { sinevoice.off(); } /*-------------------- main loop algorithms -----------------------------*/ void mainloopalgorithms(void) { while (synth.getNoteCount() > 0) { noteMessage = synth.extractNote(); if (noteMessage.p2() != 0) { sinevelocity = 127 - noteMessage.p2(); } else { break; } centernote = noteMessage.p1(); counte = 0; amplitude = midiscale(noteMessage.p2(), 0, 24); cout << "\rcenter = " << setw(4) << centernote << " amplitude = " << setw(4) << amplitude << "\t\t\t\t"; cout.flush(); } if (nextnotetime <= t_time && sinevelocity != 0) { nextnotetime = t_time + duration; sinenote = (int)(centernote + amplitude * sin(TWOPI * counte / period) + 0.5); sinevoice.play(sinenote, sinevelocity); counte++; } } /*-------------------- 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()%127 + 1; // 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 '-': period--; if (period < 1) period = 1; cout << "\r period = " << period << " \t\t\t\t\t"; cout.flush(); break; case '=': period++; if (period > 50) period = 50; cout << "\r period = " << period << " \t\t\t\t\t"; cout.flush(); break; case '[': duration -= 25; if (duration < 25) duration = 25; break; case ']': duration += 25; break; default: keyboard(key); } } /*------------------ end improvization algorithms -----------------------*/ // md5sum: 50a059b97e63b61ce970727ba865e4fe sinus.cpp [20050403]