// // Programmer: Craig Stuart Sapp // Creation Date: Wed Jun 16 20:02:43 PDT 2004 // Last Modified: Wed Jun 16 20:02:46 PDT 2004 // Filename: ...sig/examples/all/transfix.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/transfix.cpp // Syntax: C++; museinfo // // Description: Identify and transpose **kern musical data in parts // which need to be transposed. Test algorithm for future // application to identify MuseData parts that need // transposition. // #include "humdrum.h" #include #include #include #include // function declarations: void checkOptions (Options& opts, int argc, char** argv); void example (void); void usage (const char* command); void printFile (HumdrumFile& infile); int generateFieldList (Array& fieldlist,const char* fieldstring); void processFile (HumdrumFile& infile); void printNewKernString (const char* string); void printHumdrumKernToken (HumdrumRecord& record, int index); void printHumdrumDataRecord(HumdrumRecord& record, Array& spineprocess); int getBase40ValueFromInterval(const char* string); void printAnalysis (HumdrumFile& infile, Array& transamount); void determineTransposition(Array& transamount, Array >& keyarray); void analyzeKeys (HumdrumFile& infile, Array >& keyarray); void analyzeKeyPart (HumdrumFile& infile, Array& keyarray, int tracknum, double hop, double window); int findStartBeatIndex (HumdrumFile& infile, double startbeat); int findStopBeatIndex (HumdrumFile& infile, double endbeat); // User interface variables: Options options; int debugQ = 0; // used with --debug option int transval = 0; // used with -b option string fieldstring = ""; // used with -f option int fieldQ = 0; // used with -f option double hop = 16.0; // used with -h option double window = 16.0; // used with -w option ////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { // process the command-line options checkOptions(options, argc, argv); HumdrumFile infile; infile.read(options.getArg(1)); infile.analyzeRhythm("4"); Array > keyarray; analyzeKeys(infile, keyarray); Array transamount; determineTransposition(transamount, keyarray); printAnalysis(infile, transamount); return 0; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // analyzeKeys -- check the key of the music at various regular intervals. // void analyzeKeys(HumdrumFile& infile, Array >& keyarray) { int count = infile.getMaxTracks(); if (count <= 0) { cout << "Error: not enough spines in Humdrum file: " << count << endl; exit(1); } keyarray.setSize(count); int i; for (i=0; i& keyarray, int tracknum, double hop, double window) { int framecount = (int)(infile[infile.getNumLines()-1].getAbsBeat() / hop); if (debugQ) { cout << "!!! Frame count = " << framecount << endl; } keyarray.setSize(framecount); keyarray.setSize(0); int keyanalysis = 0; Array scores(24); scores.setAll(0); int startindex; int stopindex; double startbeat; double endbeat; int i; for (i=0; i= startbeat) { output = i; break; } } if (output == -1) { return infile.getNumLines()-1; } else { return output; } } ////////////////////////////// // // findStopBeatIndex -- figure out which index into the Humdrum file // stops at the given absolute beat position. Very simple algorithm // which is not efficient at all. // int findStopBeatIndex(HumdrumFile& infile, double endbeat) { int i; int output = -1; for (i=infile.getNumLines()-1; i>=0; i++) { // compensate for any rounding errors if ((infile[i].getAbsBeat()+0.0001) < endbeat) { output = i+1; break; } } if (output >= infile.getNumLines()) { output = infile.getNumLines()-1; } if (output == -1) { return infile.getNumLines()-1; } else { return output; } } ////////////////////////////// // // determineTransposition -- // void determineTransposition(Array& transamount, Array >& keyarray) { cout << "GOT TO DETERMINE_TRANSPOSITION" << endl; transamount.setSize(keyarray.getSize()); transamount.setAll(0); int i; int j; Array histogram(48); histogram.setAll(0); int value = 0; if (debugQ) { cout << "!!! Key analyses for each part:\n"; for (j=0; j= 2) { cout << "\t"; value = keyarray[0][j] - keyarray[1][j]; cout << value; histogram[value+24]++; } } cout << "\n"; } cout << "Histogram of difference between parts in spines 1 and 2:" <= 12 && i <= 32) { if (histogram[i] > histogram[max]) { max = i; } } } cout << "Most likely transposition between parts is: " << max-24 << endl; } } ////////////////////////////// // // printAnalysis -- // void printAnalysis(HumdrumFile& infile, Array& transamount) { // cout << "GOT TO PRINTANALYSIS" << endl; } ////////////////////////////// // // processFile -- From old transposition function // void processFile(HumdrumFile& infile) { int i; Array fieldlist; Array spineprocess(infile.getMaxTracks()); if (fieldQ) { spineprocess.setAll(0); generateFieldList(fieldlist, fieldstring.c_str()); for (i=0; i& spineprocess) { int i; for (i=0; i& fieldlist, const char* fieldstring) { cout << "ENTERING GENERATEFIELD LIST" << endl; int maxfield = 0; int length = strlen(fieldstring); char* buffer = new char[length+1]; strcpy(buffer, fieldstring); int starti, stopi; int temp; int num; char* ptr = strtok(buffer, " ,;:"); while (ptr != NULL) { if (strchr(ptr, '-') != NULL) { sscanf(ptr, "%d-%d", &starti, &stopi); if (starti > stopi) { temp = starti; starti=stopi; stopi = temp; } for (num=starti; num<=stopi; num++) { fieldlist.append(num); } if (num > maxfield) { maxfield = num; } } else { sscanf(ptr, "%d", &num); fieldlist.append(num); if (num > maxfield) { maxfield = num; } } ptr = strtok(NULL, " ,;:"); } cout << "LEAVING GENERATEFIELD LIST" << endl; return maxfield; } // md5sum: ab7828a769cc3821278219b418b0234a transfix.cpp [20160320]