// // Programmer: Craig Stuart Sapp // Creation Date: Mon May 20 14:21:40 PDT 2002 // Last Modified: Mon May 20 14:21:43 PDT 2002 // Filename: ...sig/examples/all/kern2koto.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/kern2koto.cpp // Syntax: C++; museinfo // // Description: Convert **kern representation to **koto representation // // Note: Not finished // #include "humdrum.h" #include #include #include #include // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const string& command); void convertKernToKoto (HumdrumFile& infile); void processKernData (HumdrumRecord& line); void processKernDatum (const string& astring); void processInterpretation (HumdrumRecord& line); void storeTuning (const string& tunestring); void printRhythm (const string& astring); void printPitch (const string& astring); void printString (int stringno); void getKeyAndRange (HumdrumFile& infile, int& key, int& lownote, int& highnote, Array& profile); int getTranspose (int key, int lownote, int highnote, Array& profile); // command line options: Options options; // database for command-line arguments int debugQ = 0; // for debugging options --debug int appendQ = 0; // for use with -a option int automaticQ = 1; // for use with -A option int transpose = 0; int lownote = -1; int highnote = -1; int key = -1; Array profile(128); Array tuning; // for koto tuning // Hira choshi: //const char* defaultTuning = "*tune[d:G:A:A#:d:d#:g:a:a#:dd:dd#:gg:aa]"; // Synthetic Chinese tuning: // const char* defaultTuning = "*tune[C#:E:F#:A:B:c#:e:f#:a:b:cc#:ee:ff#]"; string majorTuningC = "*tune[c:d:e:f:g:a:b:cc:dd:ee:ff:gg:aa]"; string majorTuningG = "*tune[c:d:e:f#:g:a:b:cc:dd:ee:ff#:gg:aa]"; string defaultTuning = majorTuningC; /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { HumdrumFile infile; // input Humdrum Format file tuning.setSize(13); tuning.allowGrowth(0); // process the command-line options checkOptions(options, argc, argv); // figure out the number of input files to process int numinputs = options.getArgCount(); for (int i=0; i& profile) { double center = 0.0; double norm = 0.0; int i; for (i=0; i<128; i++) { center += i * profile[i]; norm += profile[i]; } center = center / norm; int notecenter = (int)(center + 0.5); cout << "!! Key is: " << key << endl; cout << "!! Center pitch is: " << center << endl; cout << "!! Median center is: " << (highnote - lownote)/2.0 + lownote << endl; // find the relationship between the key and the note center int octave = notecenter / 12; int diff0 = (octave-1) * 12 + key - notecenter; int diff1 = octave * 12 + key - notecenter; int diff2 = (octave+1) * 12 + key - notecenter; int mode = 'G'; // cout << "diff0 = " << diff0 << "\t" // << "diff1 = " << diff1 << "\t" // << "diff2 = " << diff2 << endl; if ((abs(diff0) <= abs(diff1)) && (abs(diff0) <= abs(diff2))) { octave = octave - 1; if (diff0 < 0) { // closest tonic below the center mode = 'C'; } else { // closest tonic above the center mode = 'G'; } } else if ((abs(diff1) <= abs(diff0)) && (abs(diff1) <= abs(diff2))) { if (diff1 < 0) { // closest tonic below the center mode = 'C'; } else { // closest tonic above the center mode = 'G'; } } else if ((abs(diff2) <= abs(diff0)) && (abs(diff2) <= abs(diff1))) { octave = octave + 1; if (diff2 < 0) { // closest tonic below the center mode = 'C'; } else { // closest tonic above the center mode = 'G'; } } cout << "!! MODE = " << (char)mode << endl; int transpose = 0; if (mode == 'G') { storeTuning(majorTuningG); transpose = tuning[4] - (key + octave * 12); defaultTuning = majorTuningG; } else { storeTuning(majorTuningC); transpose = tuning[7] - (key + octave * 12); defaultTuning = majorTuningC; } // 0 1 2 3 4 5 6 7 8 9 0 1 2 // majorTuningC = "*tune[c:d:e:f :g:a:b:cc:dd:ee:ff:gg:aa]"; // majorTuningG = "*tune[c:d:e:f#:g:a:b:cc:dd:ee:ff:gg:aa]"; int lowerrors = 0; int hierrors = 0; for (i=0; i 0) { if (i+transpose < tuning[0]) { lowerrors++; } else if (i+transpose > tuning[12]) { hierrors++; } } } if (lowerrors && mode == 'G') { mode = 'C'; defaultTuning = majorTuningC; storeTuning(majorTuningC); transpose = tuning[7] - (key + octave * 12); } cout << "!! Transpose = " << transpose << endl; return transpose; } ////////////////////////////// // // getKeyAndRange -- // void getKeyAndRange(HumdrumFile& infile, int& key, int& lownote, int& highnote, Array& profile) { Array pitches; pitches.setSize(infile.getNumLines()*2); pitches.setSize(0); Array durations; durations.setSize(infile.getNumLines()*2); durations.setSize(0); profile.setSize(128); profile.setAll(0.0); int tokencount; char buffer[1024] = {0}; int pitch = 0; double duration = 0.0; lownote = 127; highnote = 0; key = 0; int i, j; for (i=0; i highnote) highnote = pitch; } } Array scores(24); Array distribution(12); key = analyzeKeyKS(scores.getBase(), distribution.getBase(), pitches.getBase(), durations.getBase(), pitches.getSize(), 1, 1); // don't distinguish between major and minor for now: if (key >= 12) key = (key + 3) % 12; } ////////////////////////////// // // convertKernToKoto -- // void convertKernToKoto(HumdrumFile& infile) { int i; for (i=0; i info(13); for (i=0; i<13; i++) { info[i] = -1; } for (i=6; i 0) { tuning[i] = info[i]; } } } ////////////////////////////// // // processKernData -- // void processKernData(HumdrumRecord& line) { static char buffer[1024] = {0}; if (appendQ) { cout << line << "\t"; } if (strncmp(line[0], "-", 1) == 0) { cout << ".\n"; return; } int tokencount = line.getTokenCount(0); int i; for (i=0; i= 2.0) { cout << "+"; } if (duration >= 3.0) { cout << "+"; } if (duration >= 4.0) { cout << "+"; } for (i=0; i difference(13); difference.setAll(0); int i; for (i=0; i<13; i++) { difference[i] = pitch - tuning[i]; if (difference[i] == 0) { printString(i+1); return; } } for (i=0; i<13; i++) { if (difference[i] == 1) { printString(i+1); cout << "#"; return; } } for (i=0; i<13; i++) { if (difference[i] == 2) { printString(i+1); cout << "##"; return; } } for (i=0; i<13; i++) { if (difference[i] == 3) { printString(i+1); cout << "###"; return; } } cout << "X"; } ////////////////////////////// // // printString -- // void printString(int stringno) { if (stringno < 10) { cout << stringno; return; } if (stringno == 10) { cout << "A"; return; } if (stringno == 11) { cout << "B"; return; } if (stringno == 12) { cout << "C"; return; } if (stringno == 13) { cout << "D"; return; } cout << "X"; } ////////////////////////////// // // checkOptions -- validate and process command-line options. // void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("a|append=b", "append analysis"); opts.define("A|no-automatic=b", "no automatic transposition"); opts.define("t|tuning=s:", "tuning to use"); opts.define("debug=b", "trace input parsing"); opts.define("author=b", "author of the program"); opts.define("version=b", "compilation information"); opts.define("example=b", "example usage"); opts.define("h|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 2002" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: 20 May 2002" << endl; cout << "compiled: " << __DATE__ << endl; cout << MUSEINFO_VERSION << endl; exit(0); } else if (opts.getBoolean("help")) { usage(opts.getCommand()); exit(0); } else if (opts.getBoolean("example")) { example(); exit(0); } appendQ = opts.getBoolean("append"); debugQ = opts.getBoolean("debug"); automaticQ = !opts.getBoolean("no-automatic"); if (opts.getBoolean("tuning")) { defaultTuning = opts.getString("tuning"); } } ////////////////////////////// // // example -- example usage of the scrub program // void example(void) { cout << " \n" << endl; } ////////////////////////////// // // usage -- gives the usage statement for the scrub program // void usage(const string& command) { cout << " \n" << endl; } // md5sum: fb0434a5477b14d1873a919a4b074500 kern2koto.cpp [20160320]