void printKernOutput(HumdrumFile& infile) { int i, j; infile.analyzeRhythm("4"); infile.printNonemptySegmentLabel(cout); for (i=0; i<infile.getNumLines(); i++) { if (!infile[i].isData()) { cout << infile[i].getLine() << "\n"; continue; } for (j=0; j<infile[i].getFieldCount(); j++) { if (!infile[i].isExInterp(j, "**kern")) { if (strcmp(infile[i][j], ".") == 0) { if (parensQ) { cout << "("; } cout << infile.getDotValue(i, j); if (parensQ) { cout << ")"; } } else { cout << infile[i][j]; } } else { // this is **kern data, so create tied notes if note duration // is longer than the current line's duration printKernTokenLineDuration(infile, i, j); } if (j < infile[i].getFieldCount() - 1) { cout << "\t"; } } cout << "\n"; } }
void analyzeTiming(HumdrumFile& infile, Array<double>& timings, Array<double>& tempo) { infile.analyzeRhythm("4"); timings.setSize(infile.getNumLines()); timings.setAll(0.0); tempo.setSize(infile.getNumLines()); tempo.setAll(dtempo); tempo[0] = dtempo; double currtempo = dtempo; double input = 0.0; int count; int i; for (i=1; i<infile.getNumLines(); i++) { // check for new tempo... if (strncmp(infile[i][0], "*MM", 3) == 0) { count = sscanf(infile[i][0], "*MM%lf", &input); if (count == 1) { currtempo = input; if (i > 0) { tempo[i-1] = currtempo; } tempo[i] = currtempo; } } tempo[i] = currtempo; timings[i] = timings[i-1] + (infile[i].getAbsBeat() - infile[i-1].getAbsBeat()) * 60.0/currtempo; } }
int main(int argc, char* argv[]) { HumdrumFile infile; // process the command-line options checkOptions(options, argc, argv); // figure out the number of input files to process int numinputs = options.getArgCount(); Array<double> absbeat; Array<int> pitch; Array<int> testset; Array<double> duration; Array<double> level; Array<double> coef; for (int i=0; i<numinputs || i==0; i++) { infile.clear(); // if no command-line arguments read data file from standard input if (numinputs < 1) { infile.read(cin); } else { infile.read(options.getArg(i+1)); } infile.analyzeRhythm(); cout << "(cmn\n"; convertToCMN(infile); cout << ")\n"; } return 0; }
void analyzeTiming(HumdrumFile& infile, vector<double>& timings, vector<double>& tempo) { infile.analyzeRhythm(); timings.resize(infile.getNumLines()); fill(timings.begin(), timings.end(), 0.0); tempo.resize(infile.getNumLines()); fill(tempo.begin(), tempo.end(), dtempo); double currtempo = dtempo; double input = 0.0; int count; int i; for (i=1; i<infile.getNumLines(); i++) { // check for new tempo... if (strncmp(infile[i][0], "*MM", 3) == 0) { count = sscanf(infile[i][0], "*MM%lf", &input); if (count == 1) { currtempo = input; if (i > 0) { tempo[i-1] = currtempo; } tempo[i] = currtempo; } } tempo[i] = currtempo; timings[i] = timings[i-1] + (infile[i].getAbsBeat() - infile[i-1].getAbsBeat()) * 60.0/currtempo; } }
int main(int argc, char** argv) { HumdrumFile hfile; // process the command-line options checkOptions(options, argc, argv); // figure out the number of input files to process numinputs = options.getArgCount(); const char* filename = ""; for (int i=0; i<numinputs || i==0; i++) { hfile.clear(); // if no command-line arguments read data file from standard input if (numinputs < 1) { filename = ""; hfile.read(cin); } else { filename = options.getArg(i+1).data(); hfile.read(filename); } hfile.analyzeRhythm(); displayResults(hfile, numinputs, filename); } return 0; }
int main(int argc, char** argv) { // process the command-line options checkOptions(options, argc, argv); HumdrumFile infile; infile.read(options.getArg(1)); if (distQ) { infile.analyzeRhythm(); } Array<NoteUnit> notes; getNotes(notes, infile); scrambleNotes(notes); if (transQ) { printNotes(notes); } else { replaceNotes(infile, notes); cout << infile; } if (displaySeedQ) { cout << "!!!seed: " << seed << endl; } return 0; }
int main(int argc, char** argv) { if (argc > 2) { cout << "Usage: " << argv[0] << " input-file" << endl; exit(1); } HumdrumFile hfile; if (argc == 2) { hfile.read(argv[1]); } else if (argc == 1) { hfile.read(cin); } hfile.analyzeRhythm("4", DEBUG); int measure = 0; cout << "absbeat\tdur\tbeat\tmeasure\t::\tdata\n"; cout << ":::::::::::::::::::::::::::::::::::::::::::::::::::::\n"; for (int i=0; i<hfile.getNumLines(); i++) { if (hfile[i].isMeasure()) { sscanf(hfile[i][0], "=%d", &measure); } cout << hfile.getAbsBeat(i) << '\t' << hfile.getDuration(i) << '\t' << measure << '\t' << hfile.getBeat(i) << "\t::\t" << hfile.getLine(i) << endl; } return 0; }
int main(int argc, char** argv) { // process the command-line options checkOptions(options, argc, argv); // figure out the number of input files to process int numinputs = options.getArgCount(); HumdrumFile hfile; for (int 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); } else { hfile.read(options.getArg(i+1)); } hfile.analyzeRhythm(); divisions = hfile.getMinTimeBase(); if (divisions % 4 == 0) { divisions = divisions/4; } else { // don't know what this case may be } convertToMusicXML(hfile); } return 0; }
int main(int argc, char** argv) { // process the command-line options checkOptions(options, argc, argv); HumdrumStream streamer(options); HumdrumFile hfile; if (!streamer.read(hfile)) { // no data could be read exit(1); } hfile.analyzeRhythm("4"); printOutput(hfile); return 0; }
int main(int argc, char** argv) { checkOptions(options, argc, argv); HumdrumStream streamer(options); HumdrumFile infile; while (streamer.read(infile)) { if (beatQ || absQ) { infile.analyzeRhythm(); } processFile(infile); } return 0; }
void inputNewFile(void) { data.clear(); linenum = 0; if (!streamer.read(data)) { finishup(); exit(0); } data.analyzeRhythm("4"); if (fileNumber > 1) { millisleep((float)(1000 * options.getDouble("pause"))); } fileNumber++; }
void getLocations(Array<double>& measures, HumdrumFile& infile, int segments) { infile.analyzeRhythm("4"); double totaldur = infile.getTotalDuration(); measures.setSize(segments); measures.allowGrowth(0); measures.setAll(-1); int barnum = 0; int index; int i; for (i=0; i<infile.getNumLines(); i++) { if (!infile[i].isMeasure()) { continue; } if (sscanf(infile[i][0], "=%d", &barnum) == 1) { index = int(infile[i].getAbsBeat() / totaldur * segments); measures[index] = barnum; } } for (i=1; i<segments; i++) { if (measures[i] < 0) { measures[i] = measures[i-1]; } } index = -1; for (i=0; i<segments; i++) { if (measures[i] != -1) { index = i - 1; break; } } if (index < 0) { return; } if (index >= segments) { return; } for (i=index; i>=0; i--) { measures[i] = measures[index+1] - 1; } }
void loadHistograms(Array<Array<double> >& histograms, HumdrumFile& infile, int segments) { infile.analyzeRhythm("4"); double totalduration = infile.getTotalDuration(); double duration; int i; int j; int k; char buffer[10000] = {0}; int pitch; double start; int tokencount; for (i=0; i<infile.getNumLines(); i++) { if (infile[i].getType() != E_humrec_data) { continue; } start = infile[i].getAbsBeat(); for (j=0; j<infile[i].getFieldCount(); j++) { if (strcmp(infile[i].getExInterp(j), "**kern") != 0) { continue; } if (strcmp(infile[i][j], ".") == 0) { continue; // ignore null tokens } tokencount = infile[i].getTokenCount(j); for (k=0; k<tokencount; k++) { infile[i].getToken(buffer, j, k); if (strcmp(buffer, ".") == 0) { continue; // ignore illegal inline null tokens } pitch = Convert::kernToMidiNoteNumber(buffer); if (pitch < 0) { continue; // ignore rests or strange objects } pitch = pitch % 12; // convert to chromatic pitch-class duration = Convert::kernToDuration(buffer); if (duration <= 0.0) { continue; // ignore grace notes and strange objects } addToHistogramDouble(histograms, pitch, start, duration, totalduration, segments); } } } }
void processFileAuto(HumdrumFile& infile) { infile.analyzeRhythm("4"); PerlRegularExpression pre; RationalNumber fraction = 1; int barcounter = 0; RationalNumber barstarttime; RationalNumber barduration; RationalNumber nextbarmessage; int dashQ = 0; for (int i=0; i<infile.getNumLines(); i++) { if ((nextbarmessage > 0) && (infile[i].getAbsBeatR() >= nextbarmessage)) { cout << "!!barline: absbeat=" << nextbarmessage; if (dashQ) { cout << " dash"; } cout << endl; if (infile[i].getAbsBeatR() > nextbarmessage) { cout << "!!barline: dataline" << endl; } barcounter++; if (barcounter+1 == fraction.getDenominator()) { nextbarmessage = -1; } else { nextbarmessage = barstarttime + barduration * fraction * (barcounter + 1); } } if (infile[i].isGlobalComment()) { if (pre.search(infile[i][0], "!!BARLINES:\\s*(\\d+)/(\\d+)")) { fraction = atoi(pre.getSubmatch(1)); fraction /= atoi(pre.getSubmatch(2)); if (pre.search(infile[i][0], "dash", "i")) { dashQ = 1; } else { dashQ = 0; } continue; } } if (fraction == 1) { cout << infile[i] << endl; continue; } if (infile[i].isBarline()) { barcounter = 0; barstarttime = infile[i].getAbsBeatR(); barduration = infile[i].getMeasureDuration(); if (barduration <= 0) { nextbarmessage = -1; } else { nextbarmessage = barstarttime + barduration * fraction; } cout << infile[i] << endl; continue; } cout << infile[i] << endl; } }
void processFile(HumdrumFile& infile) { infile.analyzeRhythm("4"); Array<int> measureline; // line number in the file where measure occur Array<double> measurebeats; // duration of measure Array<double> timesigbeats; // duration according to timesignature Array<int> control; // control = numbered measure Array<int> measurenums; // output measure numbers measureline.setSize(infile.getNumLines()); measureline.setSize(0); measurebeats.setSize(infile.getNumLines()); measurebeats.setSize(0); timesigbeats.setSize(infile.getNumLines()); timesigbeats.setSize(0); int i, j; double timesigdur = 0.0; double timetop = 4; double timebot = 1; double value = 1; double lastvalue = 1; for (i=0; i<infile.getNumLines(); i++) { if (debugQ) { cout << "LINE " << i+1 << "\t" << infile[i] << endl; } if (infile[i].getType() == E_humrec_interpretation) { for (j=0; j<infile[i].getFieldCount(); j++) { if ((strncmp(infile[i][j], "*M", 2) == 0) && (strchr(infile[i][j], '/') != NULL)) { timetop = Convert::kernTimeSignatureTop(infile[i][j]); timebot = Convert::kernTimeSignatureBottomToDuration(infile[i][j]); timesigdur = timetop * timebot; // fix last timesigbeats value if (timesigbeats.getSize() > 0) { timesigbeats[timesigbeats.getSize()-1] = timesigdur; measurebeats[measurebeats.getSize()-1] = lastvalue * timebot; } } } } else if (infile[i].getType() == E_humrec_data_measure) { measureline.append(i); lastvalue = infile[i].getBeat(); // shouldn't use timebot (now analyzing rhythm by "4") // value = lastvalue * timebot; value = lastvalue; measurebeats.append(value); timesigbeats.append(timesigdur); } } if (debugQ) { cout << "measure beats / timesig beats" << endl; for (i=0; i<measurebeats.getSize(); i++) { cout << measurebeats[i] << "\t" << timesigbeats[i] << endl; } } if (measurebeats.getSize() == 0) { // no barlines, nothing to do... cout << infile; return; } // Identify controlling/non-controlling barlines // at each measure line determine one of three cases: // // (1) all ok -- the summation of durations in the measure // matches the current time sign // (2) a partial measure -- the measure durations do not // add up to the time signature, but the measure is // at the start/end of a musical section such as the // beginning of a piece, end of a piece, or between // repeat bar dividing a full measure. // (3) the sum of the durations does not match the // time signature because the durations are incorrectly // given. // control.setSize(measureline.getSize()); measurenums.setSize(measureline.getSize()); control.setAll(-1); measurenums.setAll(-1); // If the time signature and the number of beats in a measure // agree, then the bar is worth numbering: for (i=0; i<control.getSize(); i++) { if (measurebeats[i] == timesigbeats[i]) { control[i] = 1; } } // Determine first bar (which is marked with a negative value // if there is a pickup bar) if (measurebeats[0] < 0) { if (-measurebeats[0] == timesigbeats[0]) { control[0] = 1; } } // Check for intermediate barlines which split one measure for (i=0; i<control.getSize()-2; i++) { if ((control[i] == 1) || (control[i+1] == 1)) { continue; } if (timesigbeats[i] != timesigbeats[i+1]) { continue; } if ((measurebeats[i]+measurebeats[i+1]) == timesigbeats[i]) { // found a barline which splits a complete measure // into two pieces. control[i] = 1; control[i+1] = 0; i++; } } // if two (or more) non-controlling bars occur in a row, then // make them controlling: //for (i=0; i<control.getSize()-1; i++) { // if ((control[i] < 1) && (control[i+1] < 1)) { // while ((i < control.getSize()) && (control[i] < 1)) { // control[i++] = 1; // } // } //} for (i=0; i<control.getSize()-1; i++) { if ((control[i] == 0) && (control[i+1] < 0)) { control[i+1] = 1; } } // if a measure contains no beats, then it is not a controlling barline for (i=0; i<control.getSize(); i++) { if (measurebeats[i] == 0) { control[i] = 0; } } // if the first bar is not a pickup measure, but there is no // starting measure, then subtract one from the starting barline // count; int offset = 0; int dataq = 0; for (i=0; i<infile.getNumLines(); i++) { if (infile[i].isData()) { dataq = 1; continue; } if (infile[i].getType() == E_humrec_data_measure) { if ((measurebeats[0] > 0) && dataq) { offset = 1; } break; } } // if the last bar is incomplete, but the bar before it // is not incomplete, then allow barline on last measure, // excluding any ending barlines with no data after them. for (i=control.getSize()-1; i>=0; i--) { if (control[i] == 0) { continue; } if ((control[i] < 0) && (i > 0) && (control[i-1] > 0)) { control[i] = 1; } break; } if (allQ) { control.setAll(1); offset = 0; } // if there is no time data, just label each barline // as a new measure. if (infile[infile.getNumLines()-1].getAbsBeat() == 0.0) { for (i=0; i<control.getSize(); i++) { control[i] = 1; } // don't mark the last barline if there is no data // line after it. for (i=infile.getNumLines()-1; i>=0; i--) { if (infile[i].isData()) { break; } if (infile[i].isBarline()) { control.last() = -1; break; } } } // assign the measure numbers; int mnum = startnum + offset; for (i=0; i<measurenums.getSize(); i++) { if (control[i] == 1) { measurenums[i] = mnum++; } } if (debugQ) { cout << "cont\tnum\tbeats" << endl; for (i=0; i<control.getSize(); i++) { cout << control[i] << "\t" << measurenums[i] << "\t" << measurebeats[i] << "\t" << timesigbeats[i] << endl; } } int endingbarline = getEndingBarline(infile); // ready to print the new barline numbers int mindex = 0; for (i=0; i<infile.getNumLines(); i++) { if (infile[i].getType() != E_humrec_data_measure) { cout << infile[i] << "\n"; continue; } if (endingbarline == i) { printWithoutBarNumbers(infile[i]); } else if (measurenums[mindex] < 0) { printWithoutBarNumbers(infile[i]); } else { printWithBarNumbers(infile[i], measurenums[mindex]); } mindex++; } }
void convertHumdrumToEnp(ostream& out, HumdrumFile& infile) { infile.analyzeRhythm("4"); Array<int> kerntracks; getKernTracks(kerntracks, infile); Array<int> subtracks; getSubspines(subtracks, infile, kerntracks); Array<Array<char> > partnames; getPartNames(infile, partnames); Array<int> barlines; getBarlines(barlines, infile); checkMarks(infile, marks, markcolors); if (commentQ) { printHeaderComments(out, infile); } LEVEL = 0; // Print the outer score parentheses plineStart(out, LEVEL++, "("); if (labelQ) { out << ":begin :score"; } out << endl; printScoreInformation(out, infile); int i, j; int partnum = 0; for (i=kerntracks.getSize()-1; i>=0; i--) { partnum++; indent(out, LEVEL++); // print part-level parenthesis out << "("; if (labelQ) { out << ":begin :part" << partnum; } out << endl; int initialclef = CLEF_UNKNOWN; printInitialStaff(out, infile, kerntracks[i], initialclef); int initialkeysig = printKeySignature(out, infile, kerntracks[i], 0); printTimeSignature(out, infile, kerntracks[i], 0); printPart(out, infile, kerntracks[i], 0, barlines, initialkeysig, initialclef); // print voices/layers after the first one: for (j=1; j<subtracks[i]; j++) { printPart(out, infile, kerntracks[i], j, barlines, initialkeysig, initialclef); } plineStart(out, --LEVEL, ")"); // part-level parenthesis if (labelQ) { out << " ; end :part" << partnum; } out << endl; } plineStart(out, --LEVEL, ")"); if (labelQ) { out << " ; end :score"; // score level parenthesis } out << endl; if (commentQ) { printTrailerComments(out, infile); } }
void getTimings(HumdrumFile& infile, Array<double>& timings, Array<double>& tempo) { infile.analyzeRhythm("4"); int i; int j; timings.setSize(infile.getNumLines()); tempo.setSize(infile.getNumLines()); timings.setAll(-1.0); tempo.setAll(-1.0); double atime; int secondsQ = 0; // get the timing values from the **time spine. for (i=0; i<infile.getNumLines(); i++) { if (infile[i].getType() == E_humrec_interpretation) { for (j=0; j<infile[i].getFieldCount(); j++) { if (strcmp(infile[i].getExInterp(j), "**time") == 0) { if (strcmp(infile[i][j], "*u=sec") == 0) { // measuring time in seconds. secondsQ = 1; } else if (strcmp(infile[i][j], "*u=msec") == 0) { secondsQ = 0; } break; } } } if (infile[i].getType() != E_humrec_data) { continue; } for (j=0; j<infile[i].getFieldCount(); j++) { // just looking for the first **time spine for now... if (strcmp(infile[i].getExInterp(j), "**time") != 0) { continue; } if (strcmp(infile[i][j], ".") == 0) { timings[i] = -1.0; } else { if (sscanf(infile[i][j], "%lf", &atime) == 1) { timings[i] = atime; if (secondsQ) { // convert seconds measurements into milliseconds timings[i] *= 1000.0; } } else { timings[i] = -1.0; } } break; } } // the times have been extracted from the Humdrum data, so now // convert them into tempo markings. int lastindex = 0; double beatdur; double timedur; double atempo; for (i=0; i<infile.getNumLines(); i++) { if (timings[i] < 0.0) { continue; } beatdur = infile[i].getAbsBeat() - infile[lastindex].getAbsBeat(); timedur = (timings[i] - timings[lastindex])/1000.0; atempo = 60.0 * beatdur / timedur; tempo[lastindex] = atempo; if (roundQ) { tempo[lastindex] = (int)(tempo[lastindex] + 0.5); } lastindex = i; } // set all zero tempos to be the same as the previous // tempo marking. if (fillQ) { for (i=1; i<infile.getNumLines(); i++) { if (tempo[i] <= 0.0) { tempo[i] = tempo[i-1]; } } } }
void processRecords(HumdrumFile& infile, HumdrumFile& outfile) { infile.analyzeRhythm(); char buffer[10000] = {0}; int style; double duration; style = styles.extract(); duration = durations.extract(); double currbeat = 0; double targetbeat = 0; int lastline = 0; double currdur; int state = 0; for (int i=0; i<infile.getNumLines(); i++) { if (options.getBoolean("debug")) { cout << "processing line " << (i+1) << " of input ..." << endl; } if (infile[i].getType() != E_humrec_data) { outfile.appendLine(infile[i]); continue; } state = 0; currbeat = infile[i].getAbsBeat(); currdur = infile[i].getDuration(); while ((currbeat+currdur > targetbeat) || (fabs(currbeat-targetbeat) < 0.001)) { if (fabs(currbeat - targetbeat) < 0.0001) { createDataLine(buffer, infile, i, duration, style); outfile.appendLine(buffer); styles.insert(style); durations.insert(duration); style = styles.extract(); duration = durations.extract(); targetbeat += duration; } else if (currbeat+currdur > targetbeat) { if (state == 1) { createDataLine(buffer, infile, lastline, duration, style); } else { createDataLine(buffer, infile, i, duration, style); } outfile.appendLine(buffer); styles.insert(style); durations.insert(duration); style = styles.extract(); duration = durations.extract(); targetbeat += duration; } else { break; } } lastline = i; } }
void analyzeContinuously(HumdrumFile& infile, int windowsize, double stepsize, double* majorKey, double* minorKey) { Array<Array<double> > segments; infile.analyzeRhythm("4"); int segmentCount = int(infile.getTotalDuration() / stepsize + 0.5); if (segmentCount < windowsize) { cout << "Not enough data for requested analysis" << endl; return; } segments.setSize(segmentCount); segments.allowGrowth(0); int i; for (i=0; i<segments.getSize(); i++) { segments[i].setSize(12); segments[i].allowGrowth(0); segments[i].setAll(0); } loadHistograms(segments, infile, segmentCount); if (debugQ) { printHistogramTotals(segments); } Array<Array<double> > pitchhist; Array<Array<double> > correlations; pitchhist.setSize(segmentCount-windowsize); correlations.setSize(segmentCount-windowsize); pitchhist.allowGrowth(0); correlations.allowGrowth(0); for (i=0; i<segmentCount-windowsize; i++) { pitchhist[i].setSize(13); //last spot for best key pitchhist[i].allowGrowth(0); correlations[i].setSize(24); correlations[i].allowGrowth(0); } for (i=0; i<segmentCount - windowsize; i++) { createHistogram(pitchhist[i], i, windowsize, segments); identifyKeyDouble(pitchhist[i], correlations[i], majorKey, minorKey); } Array<double> measures; getLocations(measures, infile, segmentCount); cout << "**key\t**rval\t**conf\t**start\t**mid\t**end\n"; for (i=0; i<pitchhist.getSize(); i++) { printBestKey(int(pitchhist[i][12] + 0.5)); cout << "\t"; printCorrelation(correlations[i][int(pitchhist[i][12]+ 0.1)], roundQ); cout << "\t"; cout << getConfidence(correlations[i], int(pitchhist[i][12]+0.1)); cout << "\t"; cout << "=" << measures[i]; cout << "\t"; cout << "=" << int((measures[i] + measures[i+windowsize])/2+0.49); cout << "\t"; cout << "=" << measures[i+windowsize]; cout << endl; } cout << "*-\t*-\t*-\t*-\t*-\t*-\n"; }
int generatePicture(HumdrumFile& infile, Array<PixelRow>& picture, int style) { Array<char> marks; getMarkChars(marks, infile); PixelColor matchcolor(255,255,255); infile.analyzeRhythm("4"); int min = infile.getMinTimeBase(); double totaldur = infile.getTotalDuration(); int columns = (int)(totaldur * min / 4.0 + 0.5) + 5; if (columns > 50000) { cout << "Error: picture will be too big to generate" << endl; exit(1); } int factor = (int)(maxwidth / columns); if (factor <= 0) { factor = 1; } if (factor > maxfactor) { factor = maxfactor; } // set picture to black first. Black regions will be filled in // with the background later. picture.setSize(128); int i, j, k; PixelColor backcolor(bgcolor); for (i=0; i<picture.getSize(); i++) { picture[i].setSize(columns * factor); for (j=0; j<picture[i].getSize(); j++) { picture[i][j] = backcolor; // picture[i][j].setRed(0); // picture[i][j].setGreen(0); // picture[i][j].setBlue(0); } } // examine metric levels for metric coloration Array<int>rhylev; infile.analyzeMetricLevel(rhylev); for (i=0; i<rhylev.getSize(); i++) { // reverse sign so that long notes are positive. rhylev[i] = -rhylev[i]; } PixelColor color; int minpitch = 128; int maxpitch = -1; int pitch = 0; double duration = 0; double start = 0; char buffer[1024] = {0}; for (i=0; i<infile.getNumLines(); i++) { if (debugQ) { cout << "Processing input line " << i + 1 << '\t' << infile[i] << endl; } if (infile[i].isData()) { start = infile[i].getAbsBeat(); for (j=0; j<infile[i].getFieldCount(); j++) { if (strcmp(infile[i].getExInterp(j), "**kern") != 0) { continue; } // duration = Convert::kernToDuration(infile[i][j]); duration = infile.getTiedDuration(i, j); color = makeColor(infile, i, j, style, rhylev, infile[i].getPrimaryTrack(j)); for (k=0; k<infile[i].getTokenCount(j); k++) { infile[i].getToken(buffer, j, k); if (strchr(buffer, '_') != NULL) { continue; } if (strchr(buffer, ']') != NULL) { continue; } pitch = Convert::kernToMidiNoteNumber(buffer); if (pitch < 0) { // ignore rests continue; } if (pitch < minpitch) { minpitch = pitch; } if (pitch > maxpitch) { maxpitch = pitch; } if (isMatch(marks, buffer)) { placeNote(picture, pitch, start, duration, min, color, factor, 1); } else { placeNote(picture, pitch, start, duration, min, color, factor, 0); } } } } } gmaxpitch = maxpitch; gminpitch = minpitch; return factor; }
void analyzeTiming(HumdrumFile& infile, Array<double>& timings, Array<double>& tempo) { infile.analyzeRhythm("4"); timings.setSize(infile.getNumLines()); timings.setAll(0.0); tempo.setSize(infile.getNumLines()); tempo.setAll(dtempo); tempo[0] = dtempo; double currtempo = dtempo; double input = 0.0; int count; Array<double> tempoindicators; Array<int> tempoindex; tempoindicators.setSize(1000); tempoindicators.setSize(0); tempoindicators.setGrowth(1000); tempoindex.setSize(1000); tempoindex.setSize(0); tempoindex.setGrowth(1000); double ritard = -1.0; double accel = -2.0; int i; int j; for (i=1; i<infile.getNumLines(); i++) { // check for new tempo... if (infile[i].getType() == E_humrec_interpretation) { for (j=0; j<infile[i].getFieldCount(); j++) { if (strcmp(infile[i].getExInterp(j), "**kern") != 0) { continue; } if (strncmp(infile[i][j], "*MM", 3) == 0) { count = sscanf(infile[i][j], "*MM%lf", &input); if (count == 1) { currtempo = input; tempoindicators.append(currtempo); tempoindex.append(i); if (i > 0) { tempo[i-1] = currtempo; } tempo[i] = currtempo; } } else if (strcmp(infile[i][j], "*accel") == 0) { tempoindicators.append(accel); tempoindex.append(i); } else if (strcmp(infile[i][j], "*rit") == 0) { tempoindicators.append(ritard); tempoindex.append(i); } break; } } tempo[i] = currtempo; timings[i] = timings[i-1] + (infile[i].getAbsBeat() - infile[i-1].getAbsBeat()) * 60.0/currtempo; } if (!changeQ) { // do not adjust for *rit and *accel markers return; } // go back and geometrically interpolate the tempo markings // when there are *accel and *rit markers in the data. for (i=1; i<tempoindicators.getSize()-1; i++) { if ((tempoindicators[i] < 0) && (tempoindicators[i+1] > 0)) { interpolateGeometric(infile, tempo, tempoindex[i], tempoindex[i+1]); } } // the following code will have to be debugged (mostly for off-by-one // errors). // adjust the timing values double beatdiff; double increment = 1.0/32.0; double starttempo; double stoptempo; double timesum; double logtem1; double logtem2; double tfraction; double ftempo; double beatduration; int ntindex; double startbeat; double stopbeat; for (i=1; i<infile.getNumLines(); i++) { starttempo = tempo[i]; ntindex = getNextTempoIndex(infile, i); stoptempo = tempo[ntindex]; startbeat = infile[i-1].getAbsBeat(); stopbeat = infile[i].getAbsBeat(); beatduration = stopbeat - startbeat; beatdiff = beatduration; if (starttempo == stoptempo) { timings[i] = timings[i-1] + beatduration * 60/tempo[i]; } else { // calculate the time as the tempo changes logtem1 = log10(starttempo); logtem2 = log10(stoptempo); timesum = 0.0; while (beatdiff >= increment) { tfraction = ((beatduration - beatdiff) / beatduration); ftempo = pow(10.0, logtem1 + (logtem2 - logtem1) * tfraction); timesum += increment * 60/ftempo; beatdiff -= increment; } if (beatduration > 0.0) { tfraction = ((beatduration - beatdiff) / beatduration); ftempo = pow(10.0, logtem1 + (logtem2 - logtem1) * tfraction); timesum += beatdiff * 60/ftempo; } else { timesum = 0.0; } timings[i] = timings[i-1] + timesum; } } }
void processFile(HumdrumFile& infile, const string& filename) { int i; if (SEGMENTS && !summaryQ) { cout << "!!!!SEGMENT: " << infile.getFileName() << endl; } if (debugQ) { cout << "!! file: " << infile.getFileName() << endl; } if (validQ && !isValidFile(infile)) { return; } if (kernQ) { Array<int> ktracks; infile.getTracksByExInterp(ktracks, "**kern"); cout << ktracks.getSize() << endl; return; } if (mdurQ || summaryQ || nograceQ) { infile.analyzeRhythm("4"); } Array<int> analysis(infile.getNumLines()); analysis.setAll(0); analysis.allowGrowth(0); for (i=0; i<infile.getNumLines(); i++) { if (!infile[i].isData()) { continue; } analysis[i] = doAnalysis(infile, i); } if (summaryQ) { return; } // print analysis: int firstdata = 1; PerlRegularExpression pre; for (i=0; i<infile.getNumLines(); i++) { if (appendQ) { cout << infile[i]; } if (infile[i].isData()) { if (appendQ) { cout << '\t'; } if (measureQ && firstdata) { printMeasureData(analysis, infile, i); firstdata = 0; } else if (measureQ) { cout << "."; } else { if (nograceQ && (infile[i].getDuration() == 0)) { cout << "."; } else { cout << analysis[i]; } } if (prependQ) { cout << '\t'; } if (appendQ) { cout << '\n'; } } else if (infile[i].isInterpretation()) { if (appendQ) { cout << '\t'; } if (strcmp(infile[i][0], "*-") == 0) { cout << "*-"; } else if (strncmp(infile[i][0], "**", 2) == 0) { printExclusiveInterpretation(); } else { cout << "*"; } if (prependQ) { cout << '\t'; } if (appendQ) { cout << '\n'; } } else if (infile[i].isBarline()) { if (pre.search(infile[i][0], "\\d")) { firstdata = 1; } if (appendQ) { cout << '\t'; } cout << infile[i][0]; if (prependQ) { cout << '\t'; } if (appendQ) { cout << '\n'; } } else if (infile[i].isLocalComment()) { if (appendQ) { cout << '\t'; } cout << "!"; if (prependQ) { cout << '\t'; } if (appendQ) { cout << '\n'; } } else { if (!(appendQ || prependQ)) { cout << infile[i]; } if (appendQ) { cout << '\n'; } } if (prependQ) { cout << infile[i]; } if (!appendQ) { cout << '\n'; } } }
void printTriadImage(HumdrumFile& infile, int rows, int cols) { Array<ChordQuality> cq; infile.analyzeSonorityQuality(cq); infile.analyzeRhythm("4"); Array<Array<int> > triads; triads.setSize(3); triads[0].setSize(cols); triads[0].setAll(24); triads[1].setSize(cols); triads[1].setAll(24); triads[2].setSize(cols); triads[2].setAll(24); colorindex[0] = "0 255 0"; // C major colorindex[1] = "38 255 140"; // C-sharp major colorindex[2] = "63 95 255"; // D major colorindex[3] = "228 19 83"; // E-flat major colorindex[4] = "255 0 0"; // E major colorindex[5] = "255 255 0"; // F major colorindex[6] = "192 255 0"; // F-sharp major colorindex[7] = "93 211 255"; // G major colorindex[8] = "129 50 255"; // A-flat major colorindex[9] = "205 41 255"; // A major colorindex[10] = "255 160 0"; // B-flat major colorindex[11] = "255 110 10"; // B major colorindex[12] = "0 161 0"; // C minor colorindex[13] = "15 191 90"; // C-sharp minor colorindex[14] = "37 61 181"; // D minor colorindex[15] = "184 27 75"; // E-flat minor colorindex[16] = "175 0 0"; // E minor colorindex[17] = "220 200 0"; // F minor colorindex[18] = "140 200 0"; // F-sharp minor colorindex[19] = "65 163 181"; // G minor colorindex[20] = "100 28 181"; // G-sharp minor colorindex[21] = "136 13 181"; // A minor colorindex[22] = "181 93 20"; // B-flat minor colorindex[23] = "211 107 0"; // B minor colorindex[24] = "255 255 255"; // background colorindex[25] = "0 0 0"; // silence double start; double end; int inversion; int starti; int endi; int minQ; int majQ; int i, m, j, ii; int rootindex; for (i=0; i<infile.getNumLines(); i++) { if (!infile[i].isData()) { continue; } if (strcmp(cq[i].getTypeName(), "min") == 0) { minQ = 1; } else { minQ = 0; } if (strcmp(cq[i].getTypeName(), "maj") == 0) { majQ = 1; } else { majQ = 0; } if (!(majQ || minQ)) { continue; } start = infile[i].getAbsBeat(); end = start + infile[i].getDuration(); starti = int(start / infile.getTotalDuration() * cols + 0.5); endi = int(end / infile.getTotalDuration() * cols + 0.5); if (starti < 0) { starti = 0; } if (endi < 0) { endi = 0; } if (starti >= cols) { starti = cols-1; } if (endi >= cols) { endi = cols-1; } rootindex = Convert::base40ToMidiNoteNumber(cq[i].getRoot()); if (minQ) { rootindex += 12; } inversion = cq[i].getInversion(); for (ii=starti; ii<=endi; ii++) { triads[inversion][ii] = rootindex; } } int barheight = 0; int barwidth = 0; if (barlinesQ) { barheight = 11; barwidth = cols; } int legendheight = 0; int legendwidth = 0; if (legendQ) { legendheight = 100; legendwidth = cols; } int value = 24; Matrix<int> image(rows*2, cols, value); for (i=triads.getSize()-1; i>=0; i--) { int start = int(i/2.0 * rows); for (m=0; m<rows; m++) { ii = (int)(m + start); if (ii >= image.getRowCount()) { ii = image.getRowCount() - 1; } for (j=0; j<triads[i].getSize(); j++) { if (triads[i][j] < 24) { image.cell(ii,j) = triads[i][j]; } // cout << colorindex[triads[i][j]] << " "; //cout << triads[i][j] << " "; } //cout << "\n"; } } // print Image: cout << "P3\n"; cout << cols << " " << rows*2 + barheight + legendheight << "\n"; cout << "255\n"; for (i=image.getRowCount()-1; i>=0; i--) { for (j=0; j<image.getColumnCount(); j++) { cout << colorindex[image.cell(i,j)] << ' '; } cout << "\n"; } if (barlinesQ) { printBarlines(infile, barheight, barwidth); } if (legendQ) { printLegend(legendheight, legendwidth); } }
void doLinearInterpolation(HumdrumFile& infile) { infile.analyzeRhythm("4"); // extract the timing data using -1 for undefined Array<double> timings; Array<double> absbeat; timings.setSize(infile.getNumLines()); timings.setAll(INVALIDTIME); double atime; int i, j; for (i=0; i<infile.getNumLines(); i++) { if (infile[i].getType() != E_humrec_data) { continue; } for (j=0; j<infile[i].getFieldCount(); j++) { if (strcmp("**time", infile[i].getExInterp(j)) == 0) { if (strcmp(infile[i][j], ".") == 0) { timings[i] = UNKNOWNTIME; } else { sscanf(infile[i][j], "%lf", &atime); timings[i] = atime; } break; } } } int lasttimeindex = -1; for (i=0; i<timings.getSize(); i++) { if (timings[i] < 0) { continue; } if (lasttimeindex < 0) { lasttimeindex = i; continue; } interpolateTimings(timings, infile, lasttimeindex, i); lasttimeindex = i; } fixendingtimes(timings, infile); // now insert the interpolated timings back into the score. int tfound = 0; for (i=0; i<infile.getNumLines(); i++) { if (infile[i].getType() == E_humrec_data) { tfound = 0; for (j=0; j<infile[i].getFieldCount(); j++) { if ((tfound == 0) && (strcmp(infile[i].getExInterp(j), "**time") == 0)) { tfound = 1; if (timings[i] < 0) { cout << "0.0"; } else { cout << timings[i]; } } else { cout << infile[i][j]; } if (j < infile[i].getFieldCount() - 1) { cout << "\t"; } } cout << "\n"; } else { cout << infile[i] << "\n"; } } }
void processFileConvert(HumdrumFile& infile) { infile.analyzeRhythm("4"); PerlRegularExpression pre; RationalNumber absbeat; int fieldcount = 0; int i, j; char buffer[1024] = {0}; int trackline = 0; int dashQ = 0; for (i=0; i<infile.getNumLines(); i++) { if (infile[i].isData()) { fieldcount = infile[i].getFieldCount(); trackline = i; continue; } if (infile[i].isInterpretation()) { fieldcount = infile[i].getFieldCount(); for (j=0; j<infile[i].getFieldCount(); j++) { if (strcmp(infile[i][j], "*") == 0) { continue; } else if (strcmp(infile[i][j], "*^") == 0) { fieldcount++; trackline = i; } else if ((j > 0) && (strcmp(infile[i][j], "*v") == 0)) { if (strcmp(infile[i][j-1], "*v") == 0) { fieldcount--; trackline = i; } } // should check for *+, but not very common. } continue; } if (!infile[i].isGlobalComment()) { continue; } if (pre.search(infile[i][0], "^!!barline:.*absbeat\\s*=\\s*(\\d+)/(\\d+)")) { absbeat = atoi(pre.getSubmatch(1)); absbeat /= atoi(pre.getSubmatch(2)); if (pre.search(infile[i][0], "dash", "i")) { dashQ = 1; } else { dashQ = 0; } } else if (pre.search(infile[i][0], "^!!barline:.*absbeat\\s*=\\s*(\\d+)")) { absbeat = atoi(pre.getSubmatch(1)); if (pre.search(infile[i][0], "dash", "i")) { dashQ = 1; } else { dashQ = 0; } } else { continue; } buffer[0] = '\0'; for (j=0; j<fieldcount; j++) { strcat(buffer, "="); if (dashQ) { strcat(buffer, "."); } if (j < fieldcount - 1) { strcat(buffer, "\t"); } } infile[i].setLine(buffer); infile[i].setAbsBeatR(absbeat); cutNotesAcrossBarline(infile, i, trackline, fieldcount, absbeat); } cout << infile; }
void createJsonProll(HumdrumFile& infile) { infile.analyzeRhythm("4"); Array<int> ktracks; infile.getTracksByExInterp(ktracks, "**kern"); Array<int> rktracks(infile.getMaxTracks()+1); rktracks.allowGrowth(0); rktracks.setAll(-1); int i, j, k; for (i=0; i<ktracks.getSize(); i++) { rktracks[ktracks[i]] = i; } int ksize = ktracks.getSize(); stringstream* staves; staves = new stringstream[ksize]; char buffer[1024] = {0}; int b40; RationalNumber duration; int track; int tcount; Array<Array<char> > partnames(ktracks.getSize()); Array<int> partmax(ktracks.getSize()); Array<int> partmin(ktracks.getSize()); partmax.setAll(-10000); partmin.setAll(+10000); Array<int> noteinit(ktracks.getSize()); noteinit.setAll(0); for (i=0; i<infile.getNumLines(); i++) { if (!infile[i].isData()) { continue; } for (j=0; j<infile[i].getFieldCount(); j++) { if (!infile[i].isExInterp(j, "**kern")) { continue; } if (strcmp(infile[i][j], ".") == 0) { continue; } tcount = infile[i].getTokenCount(j); track = infile[i].getPrimaryTrack(j); for (k=0; k<tcount; k++) { infile[i].getToken(buffer, j, k); if (strchr(buffer, 'r') != NULL) { continue; } if (strchr(buffer, ']') != NULL) { continue; } if (strchr(buffer, '_') != NULL) { continue; } if (strcmp(buffer, ".") == 0) { continue; } b40 = Convert::kernToBase40(buffer); duration = infile.getTiedDurationR(i, j, k); if (noteinit[rktracks[track]] == 0) { noteinit[rktracks[track]] = 1; pi(staves[rktracks[track]], 4); staves[rktracks[track]] << "{\n"; } else { pi(staves[rktracks[track]], 4); staves[rktracks[track]] << "},\n"; pi(staves[rktracks[track]], 4); staves[rktracks[track]] << "{\n"; } printJsonNote(staves[rktracks[track]], b40, duration, buffer, infile, i, j, k); if (b40 > partmax[rktracks[track]]) { partmax[rktracks[track]] = b40; } if (b40 < partmin[rktracks[track]]) { partmin[rktracks[track]] = b40; } } } } printJsonHeader(infile, 0, ktracks, partmin, partmax); pi(cout, 2); cout << "[\n"; pi(cout, 2); cout << "{\n"; int pindex = 0; for (i=ktracks.getSize()-1; i>=0; i--) { pi(cout, 3); cout << "\"partindex\"\t:\t" << pindex++ << ",\n"; pi(cout, 3); cout << "\"notedata\"\t:\t" << "\n"; pi(cout, 4); cout << "[\n"; cout << staves[i].str(); pi(cout, 4); cout << "}\n"; pi(cout, 4); cout << "]\n"; if (i > 0) { pi(cout, 2); cout << "},\n"; pi(cout, 2); cout << "{\n"; } else { pi(cout, 2); cout << "}\n"; } } pi(cout, 2); cout << "]\n"; pi(cout, 0); cout << "}\n"; delete [] staves; }