void extractMetricSequence(Array<double>& metriclevels, HumdrumFile& hfile, int track) { Array<int> metlev; hfile.analyzeMetricLevel(metlev); int i, j; metriclevels.setSize(metlev.getSize()); metriclevels.setSize(1000); metriclevels.setSize(0); metriclevels.allowGrowth(); double level; for (i=0; i<hfile.getNumLines(); i++) { switch (hfile[i].getType()) { case E_humrec_data: for (j=0; j<hfile[i].getFieldCount(); j++) { if (hfile[i].getPrimaryTrack(j) != track) { continue; } if (strcmp(hfile[i][j], ".") == 0) { // ignore null tokens break; } if (strchr(hfile[i][j], '_') != NULL) { // ignore continuing ties break; } if (strchr(hfile[i][j], ']') != NULL) { // ignore ending ties break; } if (strchr(hfile[i][j], 'r') != NULL) { // ignore rests break; } level = -(double)metlev[i]; metriclevels.append(level); break; } break; } } }
void generateSwing(HumdrumFile& infile, Array<double>& timings, double amount) { int i; double fraction = amount / 100.0; Array<int> data; Array<int> nextdata; Array<int> lastdata; data.setSize(timings.getSize()); nextdata.setSize(timings.getSize()); lastdata.setSize(timings.getSize()); data.setAll(0); // nextdata.setAll(-1); nextdata.setAll(0); lastdata.setAll(0); for (i=0; i<infile.getNumLines(); i++) { if (infile[i].isData()) { data[i] = 1; } } int last = 0; for (i=0; i<data.getSize(); i++) { if (data[i]) { lastdata[i] = last; last = i; } } int next = 0; for (i=data.getSize()-1; i>= 0; i--) { if (data[i]) { nextdata[i] = next; next = i; } } Array<int> rhylev; infile.analyzeMetricLevel(rhylev); // switch sign for now so that eighth note level is -1. for (i=0; i<rhylev.getSize(); i++) { rhylev[i] = -rhylev[i]; } double newtime; for (i=0; i<infile.getNumLines(); i++) { if (!infile[i].isData()) { continue; } if (rhylev[i] == -1) { // if we are on an eighth note metric level if (rhylev[nextdata[i]] >= 0 && rhylev[lastdata[i]] >= 0) { // if the eighth note is surrounded by beat levels // then adjust the timing of the note newtime = timings[nextdata[i]] - timings[lastdata[i]]; newtime = newtime * fraction; newtime = newtime + timings[lastdata[i]]; // fix the ending case later: if (newtime >= timings[lastdata[i]]) { timings[i] = newtime; } } } } }
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; }