// // Programmer: Craig Stuart Sapp // Creation Date: Sat Jun 9 14:48:41 PDT 2001 // Last Modified: Sun Jun 20 13:35:41 PDT 2010 added rational rhythms // Last Modified: Wed Jan 26 18:14:20 PST 2011 added --debug // Last Modified: Tue Apr 12 12:04:23 PDT 2011 fixed findlcm for rational rhys. // Last Modified: Mon Apr 15 20:20:18 PDT 2013 Enabled multiple segment input // Filename: ...museinfo/examples/all/minrhy.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/minrhy.cpp // Syntax: C++; museinfo // // Description: calculates the minimum timebase which is the least common // multiple of all rhythms in the file. // // Todo: some things to clean up in rhythmic representation due to conversions // from ints to RationalNumber class for rhythms/durations... #include "humdrum.h" // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); int findlcm (Array& list); int findlcmR (Array& list); int GCD (int a, int b); void insertRhythm (Array& allrhythms, RationalNumber value); void sortArray (Array& rhythms); int ratcomp (const void* a, const void* b); template void uniqArray(Array& array); // global variables Options options; // database for command-line arguments int listQ = 0; // used with -l option int debugQ = 0; // used with --debug option int pathQ = 1; // used with -P option /////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { checkOptions(options, argc, argv); HumdrumFileSet infiles; int i, j; // figure out the number of input files to process infiles.read(options); Array timebase; RationalNumber zeroR(0, 1); timebase.setSize(infiles.getCount()); timebase.setAll(zeroR); timebase.allowGrowth(0); Array rhythms; Array allrhythms; allrhythms.setSize(100); allrhythms.setSize(0); allrhythms.setGrowth(1000); // can't handle standard input yet for (i=0; i 1) { if (pathQ) { cout << infiles[i].getFilename() << ":\t"; } else { const char* filename = infiles[i].getFilename().c_str(); const char* ptr = NULL; ptr = strrchr(filename, '/'); if (ptr != NULL) { cout << ++ptr << ":\t"; } else { cout << infiles[i].getFilename() << ":\t"; } } } if (listQ) { infiles[i].getRhythms(rhythms); sortArray(rhythms); uniqArray(rhythms); for (j=0; j 1) { if (listQ) { cout << "all:\t"; for (j=0; j 1) { cout << "all:\t" << findlcmR(timebase) << endl; } } } } ////////////////////////////// // // sortRatArray -- // void sortArray(Array& rhythms) { qsort(rhythms.getBase(), rhythms.getSize(), sizeof(RationalNumber), ratcomp); } ////////////////////////////// // // uniqArray -- filter out adjacent duplicate elements. // template void uniqArray(Array& array) { Array newarray(array.getSize()); newarray.setSize(0); if (array.getSize() <= 1) { // nothing to do return; } newarray.append(array[0]); int i; for (i=1; i *((RationalNumber*)b)) { return 1; } else { return 0; } } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // insertRhythm -- // void insertRhythm(Array& allrhythms, RationalNumber value) { int i; for (i=0; i& rhythms) { if (rhythms.getSize() == 0) { return 0; } int output = rhythms[0]; for (int i=1; i& rhythms) { if (rhythms.getSize() == 0) { return 0; } Array plain; plain.setSize(rhythms.getSize()); int i; for (i=0; i