//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Wed May 23 15:07:46 PDT 2012
// Last Modified: Wed May 23 15:07:51 PDT 2012
// Filename: ...sig/examples/all/sinko.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/humdrum/sinko.cpp
// Syntax: C++; museinfo
//
// Description: Identify syncopations in a piano texture.
//
#include "humdrum.h"
#include "PerlRegularExpression.h"
#ifndef OLDCPP
#include <iostream>
#else
#include <iostream.h>
#endif
// function declarations
void checkOptions(Options& opts, int argc, char* argv[]);
void example(void);
void usage(const char* command);
void printLine(HumdrumFile& infile, int line, int measure,
int lh, int rh, int metlev, int trackcount);
void processRecords(HumdrumFile& infile);
int getKernTracks(HumdrumFile& infile);
// global variables
Options options; // database for command-line arguments
int emptyQ = 0; // used with -d option
///////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
HumdrumFile infile, outfile;
// process the command-line options
checkOptions(options, argc, argv);
// figure out the number of input files to process
int numinputs = options.getArgCount();
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();
processRecords(infile);
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// getKernTracks --
//
int getKernTracks(HumdrumFile& infile) {
Array<int> tracks;
infile.getTracksByExInterp(tracks, "**kern");
return tracks.getSize();
}
//////////////////////////////
//
// processRecords --
//
void processRecords(HumdrumFile& infile) {
PerlRegularExpression pre;
int i, j, track;
int lh, rh, state;
int measure = 0;
int kerntracks = getKernTracks(infile);
if (kerntracks > 2 || kerntracks < 1) {
cerr << "ERROR: there must be one or two **kern spines\n";
exit(1);
}
Array<int> metlev;
infile.analyzeMetricLevel(metlev);
if (kerntracks == 2) {
cout << "**bar\t**beat\t**mlev\t**LH\t**RH\n";
} else if (kerntracks == 1) {
cout << "**bar\t**beat\t**mlev\t**H\n";
}
for (i=0; i<infile.getNumLines(); i++) {
if (infile[i].isMeasure()) {
if (pre.search(infile[i][0], "=(\\d+)")) {
measure = atoi(pre.getSubmatch(1));
}
}
if (!infile[i].isData()) {
continue;
}
rh = 0;
lh = 0;
track = 0;
for (j=0; j<infile[i].getFieldCount(); j++) {
track = infile[i].getPrimaryTrack(j);
if (strcmp(infile[i][j], ".") == 0) {
state = 0;
} else if (strchr(infile[i][j], '_') != NULL) {
state = 0;
} else if (strchr(infile[i][j], ']') != NULL) {
state = 0;
} else if (strchr(infile[i][j], 'r') != NULL) {
state = 0;
} else {
state = 1;
}
if (track == 1) {
lh = state;
} else if (track == 2) {
rh = state;
}
}
printLine(infile, i, measure, lh, rh, metlev[i], kerntracks);
}
if (kerntracks == 2) {
cout << "*-\t*-\t*-\t*-\t*-\n";
} else {
cout << "*-\t*-\t*-\t*-\n";
}
}
//////////////////////////////
//
// printLine --
//
void printLine(HumdrumFile& infile, int line, int measure, int lh, int rh,
int metlev, int trackcount) {
if (emptyQ) {
if ((trackcount == 1) && (lh == 0)) {
return;
}
if ((trackcount == 2) && (lh == 0) && (rh == 0)) {
return;
}
}
cout << measure;
cout << "\t";
cout << infile[line].getBeat();
cout << "\t";
cout << metlev;
cout << "\t";
if (trackcount == 2) {
if (lh) { cout << "LH"; } else { cout << "."; }
cout << "\t";
if (rh) { cout << "RH"; } else { cout << "."; }
cout << endl;
} else {
if (lh) { cout << "H"; } else { cout << "."; }
cout << endl;
}
}
//////////////////////////////
//
// checkOptions -- validate and process command-line options.
//
void checkOptions(Options& opts, int argc, char* argv[]) {
opts.define("d|empty|no-empty|no-empties=b","do not display null tokens in hands");
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, Mar 2011" << endl;
exit(0);
} else if (opts.getBoolean("version")) {
cout << argv[0] << ", version: Nov 2000" << 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);
}
emptyQ = opts.getBoolean("empty");
}
//////////////////////////////
//
// example -- example usage of the sonority program
//
void example(void) {
cout <<
" \n"
"# example usage of the sonority program. \n"
"# analyze a Bach chorale for chord qualities: \n"
" sonority chor217.krn \n"
" \n"
"# display the chord analysis with original data: \n"
" sonority -a chor217.krn \n"
" \n"
"# display only the roots of chords: \n"
" sonority -r chor217.krn \n"
" \n"
<< endl;
}
//////////////////////////////
//
// usage -- gives the usage statement for the sonority program
//
void usage(const char* command) {
cout <<
" \n"
<< endl;
}
// md5sum: 65af416bcb15089e7bde541b923d0b97 sinko.cpp [20120614]