// // Programmer: Craig Stuart Sapp // Creation Date: Thu Jan 15 17:34:02 PST 2009 // Last Modified: Sun Jan 18 21:14:59 PST 2009 // Filename: ...sig/doc/examples/improv/synthImprov/jazzchord.cpp // Syntax: C++; synthImprov 2.0 // // Description: Chord recognition. // #include "humdrum.h" #include "synthImprov.h" // includes the default Win95 console interface // for the synthImprov environment #ifndef OLDCPP #include #include #define SSTREAM stringstream #define CSTRING str().c_str() using namespace std; #else #include #ifdef VISUAL #include #else #include #endif #define SSTREAM strstream #define CSTRING str() #endif Array keystates; Array currentchord; Array tempchord; Array > names; Array > chordset; MidiMessage message; long lastnotetime = 0; long timedelta = 60; char lastprintchord[1024] = {0}; // function declarations: void getNewChordInfo (Array& tempchord, Array& keystates); int equalChord (Array& tempchord, Array& currentchord); void storeChordData (Array& chordinfo, HumdrumFile& infile, int index); void prepareChordSet (Array >& names, Array >& chordset); int compareChords (int* chorda, int* chordb, int count); void printNewChord (Array& tempchord, Array >& chordset, Array >& names); ////////////////////////////// // // printNewChord -- // void printNewChord(Array& tempchord, Array >& chordset, Array >& names) { SSTREAM chordstream; int i, j, k; int length; Array testset(24); testset.allowGrowth(0); for (i=0; i<12; i++) { testset[i] = tempchord[i]; testset[i+12] = tempchord[i]; } int count = 0; int equal; char buffer[1024] = {0}; for (i=0; i 0) { chordstream << " or "; } count++; Convert::base12ToKern(buffer, j+4*12); length = strlen(buffer); for (k=0; k 0) { chordstream << ends; strcpy(lastprintchord, chordstream.CSTRING); cout << lastprintchord; cout << endl; } } ///////////////////////////// // // compareChords -- // int compareChords(int* chorda, int* chordb, int count) { int i; for (i=0; i& tempchord, Array& keystates) { int i; tempchord.setAll(0); for (i=0; i& tempchord, Array& currentchord) { int i; for (i=0; i& chord) { int i; cout << "["; for (i=0; i >& names, Array >& chordset) { SSTREAM stream; stream << "!! Column 1: Root of the chord\n"; stream << "!! Column 2: Other notes in the chord\n"; stream << "!! Column 3: Notated chord symbol\n"; stream << "!! Column 4: Full chord name\n"; stream << "!! substitutes with pitch in first column\n"; stream << "**kern\t**kern\t**label\t**name\n"; stream << "!root\t!others\t!\t!\n"; stream << "4C\t4e 4g\t.\tMajor\n"; stream << "4C\t4e- 4g\tm\tMinor\n"; stream << "4C\t4e 4g#\t+\tAugmented Triad\n"; stream << "4C\t4f 4g\tsus4\tSuspended 4th\n"; stream << "4C\t4e- 4g-\to\tDiminished Triad\n"; stream << "4C\t4e 4g 4a\t6\tMajor 6th\n"; stream << "4C\t4e- 4g 4a\tm6\tMinor 6th\n"; stream << "4C\t4e 4g 4b\tmaj7\tMajor 7th\n"; stream << "4C\t4e- 4g 4b-\tm7\tMinor 7th\n"; stream << "4C\t4e 4g 4b-\t7\tDominant 7th\n"; stream << "4C\t4f 4g 4b-\t7sus4\tDominant 7th sus4\n"; stream << "4C\t4e 4g# 4b-\t7+5\tDominant 7th Augmented 5th\n"; stream << "4C\t4e 4g- 4b-\t7-5\tDominant 7th Flattened 5th\n"; stream << "4C\t4e- 4g- 4b--\tdim7\tDiminished 7th\n"; stream << "4C\t4e- 4g- 4b-\tm7-5\tMinor 7th Flattened 5th\n"; stream << "4C\t4e- 4g 4b\tmmaj7\tMinor-Major 7th\n"; stream << "4C\t4e 4g 4b 4dd\tmaj9\tMajor 9th\n"; stream << "4C\t4e- 4g 4b- 4dd\tm9\tMinor 9th\n"; stream << "4C\t4e 4g 4b- 4dd\t9\tDominant 9th\n"; stream << "4C\t4e 4g# 4b- 4dd\t9+5\t9th Augmented 5th\n"; stream << "4C\t4e 4g- 4b- 4dd\t9-5\t9th Flattened 5th\n"; stream << "4C\t4e 4g 4a 4b- 4dd\t9/6\t9th Add 6th\n"; stream << "4C\t4e 4g 4b 4dd 4ff\tmaj11\tMajor 11th\n"; stream << "4C\t4e- 4g 4b- 4dd 4ff\tm11\tMinor 11th\n"; stream << "4C\t4e 4g 4b- 4dd 4ff\t11\tDominant 11th\n"; stream << "4C\t4e 4g 4b- 4dd- 4ff\t11-9\t11th Flattened 9th\n"; stream << "4C\t4e 4g 4b 4dd 4ff 4aa\tmaj13\tMajor 13th\n"; stream << "4C\t4e- 4g 4b- 4dd 4ff 4aa\tm13\tMinor 13th\n"; stream << "4C\t4e 4g 4b- 4dd 4ff 4aa\t13\tDominant 13th\n"; stream << "4C\t4e 4g 4b- 4dd- 4ff 4aa\t13-9\t13th Flattened 9th\n"; stream << "*-\t*-\t*-\t*-\n"; stream << ends; HumdrumFile infile; infile.read(stream); chordset.setSize(infile.getNumLines()); chordset.setSize(0); names.setSize(infile.getNumLines()); names.setSize(0); int index; int length; int i; for (i=0; i& chordinfo, HumdrumFile& infile, int index) { int i; int note; chordinfo.setSize(12); chordinfo.allowGrowth(0); chordinfo.setAll(0); note = Convert::kernToMidiNoteNumber(infile[index][0]) % 12; if (note != 0) { cout << "Error reading chord: " << infile[index] << endl; } chordinfo[0] = 1; char buffer[1024] = {0}; int count = infile[index].getTokenCount(1); for (i=0; i 0) { while (synth.getNoteCount() > 0) { message = synth.extractNote(); if ((message.p2() == 0) || ((message.p0() & 0xf0) == 0x80)) { keystates[message.p1()] = 0; } else if (message.p2() != 0) { keystates[message.p1()] = 1; } } getNewChordInfo(tempchord, keystates); lastnotetime = t_time; } if (t_time > lastnotetime + timedelta) { if (!equalChord(tempchord, currentchord)) { printNewChord(tempchord, chordset, names); currentchord = tempchord; } } } /*-------------------- triggered algorithms -----------------------------*/ /////////////////////////////// // // keyboardchar -- this function is called by the improv interface // whenever a key is pressed on the computer keyboard. // Put commands here which will be executed when a key is // pressed on the computer keyboard. // void keyboardchar(int key) { switch (key) { case '\n': cout << endl; break; case ' ': if (strcmp(lastprintchord, "") != 0) { cout << "\t\t\t" << lastprintchord << endl; } } } /*------------------ end improvization algorithms -----------------------*/ // md5sum: 163c49a5ec5e0bd41298728add43c609 jazzchord.cpp [20090129]