// // Programmer: Craig Stuart Sapp // Creation Date: Sun Feb 3 16:03:55 PST 2008 // Last Modified: Sun Feb 3 16:03:58 PST 2008 // Filename: ...sig/examples/all/nscale.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/nscale.cpp // Syntax: C++; museinfo // // Description: Create Fast Keyscapes using MIDI file or Humdrum file. // #include "humdrum.h" #include "MidiFile.h" #include #include #include #include /* for qsort and bsearch functions */ #ifndef OLDCPP #include #include #else #include #include #endif #define PHRASEBOUNDARY 0x8080 #define REST 0x8081 // function declarations: void checkOptions (Options& opts, int argc, char** argv); void example (void); void usage (const char* command); void printAnalysis (Array& sequence); void getSequence (Array& sequence, HumdrumFile& infile, int pspine = 1); int getPspineIndex (HumdrumFile& infile, int line, int pspine); void fillScaleArray (Array& scaledegrees, int keychroma, int keymode); int getSubsequence (Array& subsequence, Array& sequence, int start); double getDegree (double value); // User interface variables: Options options; int ccount = 5; // for -n option int displaycountQ = 0; // for -c option int repeatQ = 1; // for -R option int keepphraseQ = 0; // for -P option ////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { Array sequence; sequence.setSize(0); HumdrumFile infile; checkOptions(options, argc, argv); int numinputs = options.getArgCount(); int i; for (i=0; i& sequence, HumdrumFile& infile, int pspine) { int keychroma = 0; int keymode = 0; // 0 = major; 1 = minor sequence.setSize(infile.getNumLines()); sequence.setSize(0); Array base40toScaleDegree(40); base40toScaleDegree.zero(); fillScaleArray(base40toScaleDegree, 2, 0); // C major int i; int ii; int octave; double value; int base40; int length; for (i=0; i= 3 && length <= 4) { if (infile[i][ii][length-1] == ':') { keychroma = Convert::kernToBase40(infile[i][ii]); octave = keychroma % 40; if (octave >= 4) { keymode = 0; // major } else { keymode = 1; // minor } keychroma = keychroma % 40; } // cout << "KEY = " << infile[i][ii] << endl; fillScaleArray(base40toScaleDegree, keychroma, keymode); } break; case E_humrec_data: ii = getPspineIndex(infile, i, pspine); if (strcmp(infile[i][ii], ".") == 0) { break; } else if (strchr(infile[i][ii], '_') != NULL) { // ignore tied note mid notes } else if (strchr(infile[i][ii], ']') != NULL) { // ignore tied note end notes } else if (strchr(infile[i][ii], 'r') != NULL) { value = REST; // sequence.append(value); don't store for now } else { if (keepphraseQ) { if (strchr(infile[i][ii], '{') != NULL) { value = PHRASEBOUNDARY; sequence.append(value); } } base40 = Convert::kernToBase40(infile[i][ii]); if (base40 >= 0) { octave = (base40 - keychroma + 40) / 40; value = base40toScaleDegree[base40 % 40]; value = value + octave * 7; if (repeatQ == 0) { if (sequence[sequence.getSize()-1] != value) { sequence.append(value); } } else { sequence.append(value); } } } break; case E_humrec_none: case E_humrec_empty: case E_humrec_global_comment: case E_humrec_bibliography: case E_humrec_data_comment: case E_humrec_data_kern_measure: default: // don't do anything break; } } } ////////////////////////////// // // fillScaleArray -- // void fillScaleArray(Array& scaledegrees, int keychroma, int keymode) { if (keymode == 1) { scaledegrees[(38 + keychroma) % 40] = 7.0 - 1; // C-- scaledegrees[(39 + keychroma) % 40] = 7.5 - 1; // C- scaledegrees[(0 + keychroma) % 40] = 1.0 - 1; // C scaledegrees[(1 + keychroma) % 40] = 1.5 - 1; // C# scaledegrees[(2 + keychroma) % 40] = 2.0 - 1; // C## scaledegrees[(4 + keychroma) % 40] = 1.0 - 1; // D-- scaledegrees[(5 + keychroma) % 40] = 1.5 - 1; // D- scaledegrees[(6 + keychroma) % 40] = 2.0 - 1; // D scaledegrees[(7 + keychroma) % 40] = 3.0 - 1; // D# scaledegrees[(8 + keychroma) % 40] = 3.5 - 1; // D## scaledegrees[(10 + keychroma) % 40] = 2.0 - 1; // E-- scaledegrees[(11 + keychroma) % 40] = 3.0 - 1; // E- scaledegrees[(12 + keychroma) % 40] = 3.5 - 1; // E scaledegrees[(13 + keychroma) % 40] = 4.0 - 1; // E# scaledegrees[(14 + keychroma) % 40] = 4.5 - 1; // E## scaledegrees[(15 + keychroma) % 40] = 3.0 - 1; // F-- scaledegrees[(16 + keychroma) % 40] = 3.5 - 1; // F- scaledegrees[(17 + keychroma) % 40] = 4.0 - 1; // F scaledegrees[(18 + keychroma) % 40] = 4.5 - 1; // F# scaledegrees[(19 + keychroma) % 40] = 5.0 - 1; // F## scaledegrees[(21 + keychroma) % 40] = 4.0 - 1; // G-- scaledegrees[(22 + keychroma) % 40] = 4.5 - 1; // G- scaledegrees[(23 + keychroma) % 40] = 5.0 - 1; // G scaledegrees[(24 + keychroma) % 40] = 6.0 - 1; // G# scaledegrees[(25 + keychroma) % 40] = 6.5 - 1; // G## scaledegrees[(27 + keychroma) % 40] = 5.0 - 1; // A-- scaledegrees[(28 + keychroma) % 40] = 6.0 - 1; // A- scaledegrees[(29 + keychroma) % 40] = 6.5 - 1; // A scaledegrees[(30 + keychroma) % 40] = 7.0 - 1; // A# scaledegrees[(31 + keychroma) % 40] = 7.5 - 1; // A## scaledegrees[(33 + keychroma) % 40] = 6.5 - 1; // B-- scaledegrees[(34 + keychroma) % 40] = 7.0 - 1; // B- scaledegrees[(35 + keychroma) % 40] = 7.5 - 1; // B scaledegrees[(36 + keychroma) % 40] = 1.0 - 1; // B# scaledegrees[(37 + keychroma) % 40] = 1.5 - 1; // B## } else { scaledegrees[(38 + keychroma) % 40] = 6.5 - 1; // C-- scaledegrees[(39 + keychroma) % 40] = 7.0 - 1; // C- scaledegrees[(0 + keychroma) % 40] = 1.0 - 1; // C scaledegrees[(1 + keychroma) % 40] = 1.5 - 1; // C# scaledegrees[(2 + keychroma) % 40] = 2.0 - 1; // C## scaledegrees[(4 + keychroma) % 40] = 1.0 - 1; // D-- scaledegrees[(5 + keychroma) % 40] = 1.5 - 1; // D- scaledegrees[(6 + keychroma) % 40] = 2.0 - 1; // D scaledegrees[(7 + keychroma) % 40] = 2.5 - 1; // D# scaledegrees[(8 + keychroma) % 40] = 3.0 - 1; // D## scaledegrees[(10 + keychroma) % 40] = 2.0 - 1; // E-- scaledegrees[(11 + keychroma) % 40] = 2.5 - 1; // E- scaledegrees[(12 + keychroma) % 40] = 3.0 - 1; // E scaledegrees[(13 + keychroma) % 40] = 4.0 - 1; // E# scaledegrees[(14 + keychroma) % 40] = 4.5 - 1; // E## scaledegrees[(15 + keychroma) % 40] = 2.5 - 1; // F-- scaledegrees[(16 + keychroma) % 40] = 3.0 - 1; // F- scaledegrees[(17 + keychroma) % 40] = 4.0 - 1; // F scaledegrees[(18 + keychroma) % 40] = 4.5 - 1; // F# scaledegrees[(19 + keychroma) % 40] = 5.0 - 1; // F## scaledegrees[(21 + keychroma) % 40] = 4.0 - 1; // G-- scaledegrees[(22 + keychroma) % 40] = 4.5 - 1; // G- scaledegrees[(23 + keychroma) % 40] = 5.0 - 1; // G scaledegrees[(24 + keychroma) % 40] = 5.5 - 1; // G# scaledegrees[(25 + keychroma) % 40] = 6.0 - 1; // G## scaledegrees[(27 + keychroma) % 40] = 5.0 - 1; // A-- scaledegrees[(28 + keychroma) % 40] = 5.5 - 1; // A- scaledegrees[(29 + keychroma) % 40] = 6.0 - 1; // A scaledegrees[(30 + keychroma) % 40] = 6.5 - 1; // A# scaledegrees[(31 + keychroma) % 40] = 7.0 - 1; // A## scaledegrees[(33 + keychroma) % 40] = 6.0 - 1; // B-- scaledegrees[(34 + keychroma) % 40] = 6.5 - 1; // B- scaledegrees[(35 + keychroma) % 40] = 7.0 - 1; // B scaledegrees[(36 + keychroma) % 40] = 1.0 - 1; // B# scaledegrees[(37 + keychroma) % 40] = 1.5 - 1; // B## } } ////////////////////////////// // // getPspineIndex -- // int getPspineIndex(HumdrumFile& infile, int line, int pspine) { int i; int output = 0; for (i=0; i& sequence) { int i,j; Array subsequence; subsequence.setSize(ccount); subsequence.allowGrowth(0); subsequence.zero(); for (i=0; i& subsequence, Array& sequence, int start) { int status = 0; int i; int subi; if (start + subsequence.getSize() >= sequence.getSize()) { return status; } i = start; subi = 0; while (i < sequence.getSize() && subi < subsequence.getSize()) { if (sequence[i] == PHRASEBOUNDARY) { if (keepphraseQ) { i++; continue; } else { return status; } } else { subsequence[subi++] = sequence[i++]; } } if (subi == subsequence.getSize()) { status = 1; } return status; } ////////////////////////////// // // checkOptions -- // void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("n|length=i:5", "length of sequences"); opts.define("c|count=b", "display length of sequences"); opts.define("P|phrase=b", "ignore phrase information"); opts.define("R|repeat=b", "ignore repeated notes"); opts.define("author=b", "author of program"); opts.define("version=b", "compilation info"); opts.define("example=b", "example usages"); opts.define("help=b", "short description"); opts.process(argc, argv); // handle basic options: if (opts.getBoolean("author")) { cout << "Written by Craig Stuart Sapp, " << "craig@ccrma.stanford.edu, May 2008" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: 18 May 2008" << endl; cout << "compiled: " << __DATE__ << endl; cout << MUSEINFO_VERSION << endl; exit(0); } else if (opts.getBoolean("help")) { usage(opts.getCommand().c_str()); exit(0); } else if (opts.getBoolean("example")) { example(); exit(0); } ccount = opts.getInteger("length"); displaycountQ = opts.getBoolean("count"); repeatQ = !opts.getBoolean("repeat"); keepphraseQ = opts.getBoolean("phrase"); } ////////////////////////////// // // example -- // void example(void) { } ////////////////////////////// // // usage -- // void usage(const char* command) { } // md5sum: 545b467fcf162badd0699428f5e965d9 nscale.cpp [20160320]