// // Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu> // Creation Date: Mon Apr 26 12:57:44 PDT 2004 // Last Modified: Wed Apr 28 00:32:30 PDT 2004 // Filename: ...sig/examples/all/phrasenum.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/phrasenum.cpp // Syntax: C++; museinfo // // Description: Extracts the phrase locations in a monophonic song // according to which note the phrases start on. // #include "humdrum.h" #include <string.h> #ifndef OLDCPP #include <iostream> using namespace std; #else #include <iostream.h> #endif // includes needed for file/directory processing: #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <string.h> // function declarations: void checkOptions(Options& opts, int argc, char** argv); void example(void); void usage(const char* command); void processFile(HumdrumFile& hfile, const char* filename); void printAnalysis(Array<int>& phrase, Array<int>& phrasestart, Array<int>& notes, const char* filename); void processArgument(const char* path); int is_file (const char* path); int is_directory (const char* path); // User interface variables: Options options; ////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { // process the command-line options checkOptions(options, argc, argv); int i; int numinputs = options.getArgCount(); HumdrumFile hfile; for (i=0; i<numinputs || i==0; i++) { hfile.clear(); // if no command-line arguments read data file from standard input if (numinputs < 1) { hfile.read(cin); processFile(hfile, ""); } else { processArgument(options.getArg(i+1)); } } return 0; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // processArgument -- check if the argument is a file or a directory. // if a directory, then process all files/subdirectories in it. // void processArgument(const char* path) { HumdrumFile hfile; DIR* dir = NULL; char* fullname; struct dirent* entry; int namelen = 0; int valid = 0; if (is_file(path)) { namelen = strlen(path); valid = 0; if (strcmp(&(path[namelen-4]), ".thm") == 0) { valid = 1; } else if (strcmp(&(path[namelen-4]), ".krn") == 0) { valid = 1; } else if (strcmp(&(path[namelen-4]), ".THM") == 0) { valid = 1; } else if (strcmp(&(path[namelen-4]), ".KRN") == 0) { valid = 1; } if (!valid) { return; } hfile.read(path); processFile(hfile, path); } else if (is_directory(path)) { dir = opendir(path); if (dir == NULL) { return; } entry = readdir(dir); while (entry != NULL) { if (strncmp(entry->d_name, ".", 1) == 0) { entry = readdir(dir); continue; } fullname = new char[strlen(path) + 1 + strlen(entry->d_name) + 1]; strcpy(fullname, path); strcat(fullname, "/"); strcat(fullname, entry->d_name); processArgument(fullname); entry = readdir(dir); } } closedir(dir); } ////////////////////////////// // // processFile -- print the analysis // void processFile(HumdrumFile& hfile, const char* filename) { Array<int> notes; Array<int> phrase; Array<int> phrasestart; notes.setSize(1000); notes.setSize(0); phrase.setSize(1000); phrase.setSize(0); phrasestart.setSize(1000); phrasestart.setSize(0); int pitch; int counter = 0; int i; int start; for (i=0; i<hfile.getNumLines(); i++) { switch (hfile[i].getType()) { case E_humrec_data: if (strcmp(hfile[i][0], ".") == 0) { break; } if (strchr(hfile[i][0], ']') != NULL) { break; } if (strchr(hfile[i][0], 'r') != NULL) { if (strchr(hfile[i][0], '{') != NULL) { counter++; start = notes.getSize()+1; phrasestart.append(start); } break; // don't store rests } if (strchr(hfile[i][0], '_') != NULL) { break; } pitch = Convert::kernToBase40(hfile[i][0]); notes.append(pitch); if (strchr(hfile[i][0], '{') != NULL) { counter++; start = notes.getSize(); phrasestart.append(start); } phrase.append(counter); } } printAnalysis(phrase, phrasestart, notes, filename); } /////////////////////////////// // // printAnalysis -- // void printAnalysis(Array<int>& phrase, Array<int>& phrasestart, Array<int>& notes, const char* filename) { if ((filename != NULL) && (filename[0] != '\0')) { cout << filename << "\t"; } // cout << "There are " << phrasestart.getSize() << " phrases.\n"; // cout << "Starting on the note numbers (offset from 1):\n"; int i; for (i=0; i<phrasestart.getSize(); i++) { cout << phrasestart[i]; if (i<phrasestart.getSize()-1) { cout << " "; } } cout << "\t"; // print the note pitch classes. // cout << "Notes\n"; char buffer[1024] = {0}; for (i=0; i<notes.getSize(); i++) { cout << Convert::base40ToKern(buffer, notes[i] % 40 + 4 * 40); if (i<notes.getSize()-1) { cout << " "; } } cout << "\n"; } ////////////////////////////// // // checkOptions -- // void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("author=b", "author of program"); opts.define("version=b", "compilation info"); opts.define("example=b", "example usages"); 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, April 2004" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: April 2004" << 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); } } ////////////////////////////// // // example -- // void example(void) { } ////////////////////////////// // // usage -- // void usage(const char* command) { } ////////////////////////////// // // is_file -- returns true if the string is a file. // int is_file(const char* path) { struct stat filestat; stat(path, &filestat); return S_ISREG(filestat.st_mode); } ////////////////////////////// // // is_directory -- returns true if the string is a directory. // int is_directory(const char* path) { struct stat filestat; stat(path, &filestat); return S_ISDIR(filestat.st_mode); } // md5sum: 737b0c1c8f2a18127e054dd6708ae096 phrasenum.cpp [20050403]