//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Mon Jun 28 21:41:03 PDT 2010
// Last Modified: Mon Jun 28 21:41:06 PDT 2010
// Filename: ...sig/examples/all/joscor.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/humdrum/joscor.cpp
// Syntax: C++; museinfo
//
// Description: Generate score from monophonic parts.
//
#include "humdrum.h"
#include "PerlRegularExpression.h"
#include <math.h>
#include <string.h>
#include <ctype.h>
#ifndef OLDCPP
#include <sstream>
#define SSTREAM stringstream
#define CSTRING str().c_str()
using namespace std;
#else
#ifdef VISUAL
#include <strstrea.h> /* for windows 95 */
#else
#include <strstream.h>
#endif
#define SSTREAM strstream
#define CSTRING str()
#endif
// function declarations
void checkOptions(Options& opts, int argc, char* argv[]);
void example(void);
void usage(const char* command);
void getPageNumbers(Array<int>& pagenumber, HumdrumFile& infile,
const char* target);
void printInfo(Array<int>& pages, Array<int>& staff,
HumdrumFile& infile);
void getSystemNumber(Array<int>& systemnumber, Array<int>& pagenumber,
HumdrumFile& infile, const char* target);
void printPage(ostream& out, HumdrumFile& infile,
Array<int>& systemnumber, Array<int>& pagenumber,
int page);
void getClefState(Array<int>& meterline, Array<int>& meterspine,
HumdrumFile& infile, int startindex,
int stopindex);
int getStaffCount(HumdrumFile& infile, int line);
// global variables
Options options; // database for command-line arguments
///////////////////////////////////////////////////////////////////////////
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();
int i, j;
for (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));
}
// analyze the input file according to command-line options
infile.analyzeRhythm("4");
Array<int> pagenumber;
getPageNumbers(pagenumber, infile, "default");
Array<int> systemnumber;
getSystemNumber(systemnumber, pagenumber, infile, "default");
for (j=1; j<=pagenumber[infile.getNumLines()-1]; j++) {
printPage(cout, infile, systemnumber, pagenumber, j);
}
// printInfo(pagenumber, systemnumber, infile);
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// printPage --
//
void printPage(ostream& out, HumdrumFile& infile, Array<int>& systemnumber,
Array<int>& pagenumber, int page) {
int startline = -1;
int i;
for (i=0; i<infile.getNumLines(); i++) {
if (pagenumber[i] == page) {
startline = i;
break;
}
}
if (startline < 0) {
// page not found in file
return;
}
int staffcount = getStaffCount(infile, i);
int maxtracks = infile.getMaxTracks();
Array<int> meterline;
Array<int> meterspine;
meterline.setSize(maxtracks);
meterline.setAll(-1);
meterspine.setSize(maxtracks);
meterspine.setAll(-1);
meterline.allowGrowth(0);
meterspine.allowGrowth(0);
getClefState(meterline, meterspine, infile, 0, startline);
}
//////////////////////////////
//
// getClefState --
//
void getClefState(Array<int>& meterline, Array<int>& meterspine,
HumdrumFile& infile, int startindex, int stopindex) {
PerlRegularExpression pre;
int i, j;
for (i=startindex; i<=stopindex; i++) {
if (!infile[i].isInterpretation()) {
continue;
}
for (j=0; j<infile[i].getFieldCount(); j++) {
if (strcmp(infile[i].getExInterp(j), "**kern") != 0) {
continue;
}
if (pre.search(infile[i][j], "^\\*clef", "")) {
int ptrack = infile[i].getPrimaryTrack(j);
meterline[ptrack] = i;
meterspine[ptrack] = j;
}
}
}
}
//////////////////////////////
//
// getStaffCount -- return the number of **kern spines (different primary
// tracks) on the current line.
//
int getStaffCount(HumdrumFile& infile, int line) {
int j;
Array<int> primarystaff;
primarystaff.setSize(1000);
primarystaff.setAll(0);
int count = 0;
for (j=0; j<infile[line].getFieldCount(); j++) {
if (strcmp(infile[line].getExInterp(j), "**kern") != 0) {
continue;
}
if (primarystaff[infile[line].getPrimaryTrack(j)] != 0) {
continue;
}
primarystaff[infile[line].getPrimaryTrack(j)]++;
count++;
}
return count;
}
//////////////////////////////
//
// getSystemNumber --
//
void getSystemNumber(Array<int>& systemnumber, Array<int>& pagenumber,
HumdrumFile& infile, const char* target) {
systemnumber.setSize(infile.getNumLines());
systemnumber.setAll(0);
systemnumber.allowGrowth(0);
PerlRegularExpression pre;
char linesearch[1024] = {0};
strcpy(linesearch, "!!\\s*layout\\s*:\\s*linebreak\\s*:\\s*");
strcat(linesearch, target);
char pagesearch[1024] = {0};
strcpy(pagesearch, "!!\\s*layout\\s*:\\s*pagebreak\\s*:\\s*");
strcat(pagesearch, target);
int i;
int staff = 1;
for (i=infile.getNumLines()-1; i>=0; i--) {
if (pre.search(infile[i].getLine(), linesearch)) {
systemnumber[i] = staff;
staff++;
continue;
}
if (pre.search(infile[i].getLine(), pagesearch)) {
systemnumber[i] = staff;
staff = 1;
continue;
}
systemnumber[i] = staff;
}
}
//////////////////////////////
//
// printInfo -- debugging
//
void printInfo(Array& pages, Array& staff, HumdrumFile& infile) {
int i;
for (i=0; i<infile.getNumLines(); i++) {
cout << pages[i] << "\t" << staff[i] << "\t"
<< infile[i].getLine() << endl;
}
}
//////////////////////////////
//
// getPageNumbers -- calculate what page each line in the humdrum file
// belongs on.
//
void getPageNumbers(Array<int>& pagenumber, HumdrumFile& infile,
const char* target) {
pagenumber.setSize(infile.getNumLines());
pagenumber.setAll(0);
pagenumber.allowGrowth(0);
PerlRegularExpression pre;
char search[1024] = {0};
strcpy(search, "!!\\s*layout\\s*:\\s*pagebreak\\s*:\\s*");
strcat(search, target);
int page = 1;
int i;
for (i=0; i<infile.getNumLines(); i++) {
if (pre.search(infile[i].getLine(), search, "i")) {
if (infile[i].getAbsBeat() > 0) {
page++;
}
}
pagenumber[i] = page;
}
}
//////////////////////////////
//
// checkOptions -- validate and process command-line options.
//
void checkOptions(Options& opts, int argc, char* argv[]) {
opts.define("debug=b"); // determine bad input line num
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, June 2010" << endl;
exit(0);
} else if (opts.getBoolean("version")) {
cout << argv[0] << ", version: 28 June 2010" << 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 -- example usage of the quality program
//
void example(void) {
cout <<
" \n"
<< endl;
}
//////////////////////////////
//
// usage -- gives the usage statement for the meter program
//
void usage(const char* command) {
cout <<
" \n"
<< endl;
}
// md5sum: 517aaeb4325c043d909344d445e2357a joscor.cpp [20100702]