// Test of simultaneous triggering with chords
//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Sat Mar 9 13:23:13 PST 1996
// Last Modified: Tue Apr 23 00:20:01 PDT 1996
// Last Modified: Tue Apr 18 18:31:15 PDT 2000 (syntax updated)
// Filename: ...sig/doc/examples/all/major/major.cpp
// Syntax: C++; batonImprov 2.0
//
// Description: // A major triad will be played if both batons
// are triggered at the same time. The root of the triad
// is controlled by the paragraph below. If baton 1
// is hit hard, a minor third below the root will be
// played; if hit very hard, a major third below will be
// played. In a similar manner, if baton 2 is hit hard,
// notes will be played above the fifth of the triad.
//
#include "batonImprov.h"
Voice bass; // submediant note
Voice tenor; // tonic note
Voice alto; // mediant note
Voice soprano; // dominant note
Voice quintus; // subtonic note
const int HitHard = 80;
const int HitMedium = 50;
int time1 = 0;
int time2 = 0;
void dial1response(void);
/***************** Beginning of user functions ****************************/
int makeDigit(int x, int y) {
static const int digitHolder[5][2] = // 1 2 3 4 5
{{6,1},{7,2},{8,3},{9,4},{0,5}}; // 6 7 8 9 0
return digitHolder[x][y];
}
int makeKeyno(void) {
return 10 * makeDigit(midiscale(baton.x1t,0,4), midiscale(baton.y1t,0,1)) +
1 * makeDigit(midiscale(baton.x2t,0,4), midiscale(baton.y2t,0,1));
}
/*---------------- Documentation functions -------------------------------*/
void description(void) {
cout
<< "______________________________________________________________ \n"
<< "| Description: |\n"
<< "| A major triad will be played if both batons are |\n"
<< "| triggered at the same time. The root of the triad |\n"
<< "| is controlled by the paragraph below. If baton 1 |\n"
<< "| is hit hard, a minor third below the root will be |\n"
<< "| played; if hit very hard, a major third below will be |\n"
<< "| played. In a similar manner, if baton 2 is hit hard, |\n"
<< "| notes will be played above the fifth of the triad. |\n"
<< "| |\n"
<< "| The radio baton is divided into 10 locations: |\n"
<< "| 5 divisions along the x direction and 2 divisions along |\n"
<< "| the y direction. Batons control the key number of the |\n"
<< "| MIDI note, Baton 1 controlling the tens digits of the |\n"
<< "| key number, and Baton 2 controlling the ones digit of |\n"
<< "| the key number. Digits are arranged on the radio baton as:|\n"
<< "| 1 2 3 4 5 |\n"
<< "| 6 7 8 9 0 |\n"
<< "| -- Craig Stuart Sapp, 10 Mar 1996 |\n"
<< "---------------------------------------------------------------\n"
;
}
void programhelp(void) {
cout
<< "> \n"
<< "> Baton 1: Tens digit of keyno to play \n"
<< "> x1t: Five divisions \n"
<< "> y1t: Two divisions \n"
<< "> w1t: Averages with w2t for key velocity of some notes. \n"
<< "> Baton 2: Ones digit of keyno to play \n"
<< "> x2t: Five divisions \n"
<< "> y2t: Two divisions \n"
<< "> w2t: Averages with w1t for key velocity of some notes. \n"
<< "> \n"
<< "> p1p: Channel Number to play chord on. \n"
<< "> p2p: Timber to play chord with. \n"
<< "> +b14: Command mode. \n"
<< "> +b15: This help screen. \n"
<< "> \n"
;
}
/*---------------- Initialization functions ------------------------------*/
void initialization(void) {
description();
baton.dial1position = dial1response;
}
/*---------------- Main loop functions -----------------------------------*/
void mainloopalgorithms(void) { }
/*---------------- Trigger response functions ----------------------------*/
int togetherQ(int separation = 50) {
if (abs(time1 - time2) < separation) {
return 1;
} else {
return 0;
}
}
void ActIfTogether(void) {
if (togetherQ(60)) {
int triggerKey, average;
triggerKey = makeKeyno();
average = (baton.w1t + baton.w2t)/2;
cout << "Keyno = " << triggerKey
<< "\t w1t = " << baton.w1t << "\tw2t = " << baton.w2t << endl;
// key vel
tenor.play (triggerKey, baton.w1t);
alto.play (triggerKey+4, average);
soprano.play (triggerKey+7, baton.w2t);
// determine bass note:
if (baton.w1t > HitMedium && triggerKey > 3) {
if (baton.w1t > HitHard) {
bass.play(triggerKey-4, average);
} else {
bass.play(triggerKey-3, average);
}
} else {
bass.off();
}
// determine quintus note:
if (baton.w2t > HitMedium) {
if (baton.w2t > HitHard) {
quintus.play(triggerKey+11, average);
} else {
quintus.play(triggerKey+10, average);
}
} else {
quintus.off();
}
}
}
void stick1trig(void) {
cout << "Baton 1 triggered." << endl;
time1 = t_time;
ActIfTogether();
}
void stick2trig(void) {
cout << "Baton 2 triggered." << endl;
time2 = t_time;
ActIfTogether();
}
void b14plustrig(void) { cout << "B14+ triggered\n"; programhelp(); }
void b15plustrig(void) { cout << "B15+ triggered\n"; programhelp(); }
void b14minusuptrig(void) { }
void b14minusdowntrig(void) { }
void b15minusuptrig(void) { }
void b15minusdowntrig(void) { }
void keyboardchar(int key) { }
/*---------------- Poll response functions -------------------------------*/
void stick1pollresponse(void) { }
void stick2pollresponse(void) { }
void dial1response(void) {
if (midiscale(baton.d2pb[0],0,63) - midiscale(baton.d2pb[1],0,63)) {
cout << "Timbre = " << GeneralMidiName(midiscale(baton.d2p, 0, 63))
<< endl;
tenor.pc(midiscale(baton.d2p, 0, 63));
}
}
/*---------------- Actions to take just before leaving program -----------*/
void finishup(void) { }
/***************** End of user functions **********************************/
// md5sum: e7907a885c97362ebc02c06eb81a41a8 major.cpp [20050403]