// // Programmer: Craig Stuart Sapp // Creation Date: Thu Apr 11 11:43:12 PDT 2002 // Last Modified: Fri Jun 12 22:58:34 PDT 2009 (renamed SigCollection class) // Filename: ...sig/examples/all/proll.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/proll.cpp // Syntax: C++; museinfo // // Description: Generate piano roll plots. // #include "humdrum.h" #include #include typedef SigCollection PixelRow; // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); void generateBackground (HumdrumFile& infile, int rfactor, Array& picturedata, Array& background); int generatePicture (HumdrumFile& infile, Array& picture, int style); void printPicture (Array& picturedata, Array& background, int rfactor, int cfactor, int minp, int maxp); void placeNote (Array& picture, int pitch, double start, double duration, int min, PixelColor& color, double factor); PixelColor makeColor (HumdrumFile& infile, int line, int spine, int style, Array& rhylev); // global variables Options options; // database for command-line arguments int debugQ = 0; // used with --debug option int maxwidth = 1000; // used with -w option int maxheight = 300; // used with -h option int rfactor = 1; int cfactor = 1; int gminpitch = 0; int gmaxpitch = 127; int maxfactor = 5; int measureQ = 1; // used with the -M option int keyboardQ = 1; // used with the -K option int style = 'H'; // used with the -s option const char* keyboardcolor = "151515"; // used with the -k option /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { checkOptions(options, argc, argv); Array picturedata; Array background; HumdrumFile infile; char* filenameIn = options.getArg(1); infile.read(filenameIn); int rfactor = generatePicture(infile, picturedata, style); generateBackground(infile, rfactor, picturedata, background); printPicture(picturedata, background, rfactor, cfactor, gminpitch, gmaxpitch); return 0; } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // printPicture -- // void printPicture(Array& picturedata, Array& background, int rfactor, int cfactor, int minp, int maxp) { if (minp > 0) { minp--; } if (maxp < 127) { maxp++; } int i, j; int m; int width = picturedata[0].getSize(); int height = (maxp - minp + 1); cfactor = (int)(maxheight / height); if (cfactor <= 0) { cfactor = 1; } if (cfactor > maxfactor) { cfactor = maxfactor; } PixelColor temp; PixelColor black(0,0,0); height = cfactor * height; cout << "P6\n" << width << " " << height << "\n255\n"; for (i=maxp; i>=minp; i--) { for (m=0; m 0) && (cfactor > 1) && (m == cfactor-1) && (picturedata[i-1][j] == picturedata[i][j])) { temp = picturedata[i][j] * 0.667; temp.writePpm6(cout); } else { picturedata[i][j].writePpm6(cout); } } } } } } ////////////////////////////// // // generatePicture -- create the picture. Returns the number of // pixel repetitions for each row's pixel. // int generatePicture(HumdrumFile& infile, Array& picture, int style) { 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; for (i=0; irhylev; infile.analyzeMetricLevel(rhylev); for (i=0; i maxpitch) { maxpitch = pitch; } placeNote(picture, pitch, start, duration, min, color, factor); } } } } gmaxpitch = maxpitch; gminpitch = minpitch; return factor; } ////////////////////////////// // // makeColor -- // PixelColor makeColor(HumdrumFile& infile, int line, int spine, int style, Array& rhylev) { PixelColor output; int trackCount; switch (toupper(style)) { case 'M': // color by metric position if (rhylev[line] >= 2) { output.setColor("red"); } else if (rhylev[line] == 1) { output.setColor("lightorange"); } else if (rhylev[line] == 0) { output.setColor("yellow"); } else if (rhylev[line] == -1) { output.setColor("green"); } else if (rhylev[line] == -2) { output.setColor("blue"); } else if (rhylev[line] <= -3) { output.setColor("violet"); } else { output.setColor("silver"); } break; case 'H': // color spines by hue default: trackCount = infile.getMaxTracks(); output.setHue(((int)infile[line].getTrack(spine))/(double)trackCount); } return output; } ////////////////////////////// // // placeNote -- draw a note in the picture area // void placeNote(Array& picture, int pitch, double start, double duration, int min, PixelColor& color, double factor) { int startindex = (int)(start * min / 4.0 * factor); int endindex = (int)((start + duration) * min / 4.0 * factor) - 1; PixelColor black(0,0,0); if (startindex-1 >= 0) { if (picture[pitch][startindex-1] == color) { picture[pitch][startindex-1] *= 0.667; } } for (int i=startindex; i<=endindex; i++) { if (picture[pitch][i] == black) { picture[pitch][i] = color; } else { picture[pitch][i] = (color + picture[pitch][i])/2; } } } ////////////////////////////// // // generateBackground -- create the picture. // void generateBackground(HumdrumFile& infile, int rfactor, Array& picturedata, Array& background) { background.setSize(picturedata.getSize()); int i, j; for (i=0; i