//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Wed Oct 15 04:30:17 PDT 2008
// Last Modified: Wed Oct 15 08:13:13 PDT 2008
// Filename: ...sig/examples/all/marcello1.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/humdrum/marcello1.cpp
// Syntax: C++; museinfo
//
// Description: Feature extractor which extract the metrical position
// of each beat, the number of events in the left hand,
// and the number of events in a beat for the right hand
// in piano music (two primary spines of music, the first
// **kern spine contains the left hand, the second **kern spine
// contains the right hand. Any primary **kern spines after
// the first two will be ignored.
#ifndef OLDCPP
#include <iostream>
using namespace std;
#else
#include <iostream.h>
#endif
#include "humdrum.h"
#define FIELDCOUNT 5
//////////////////////////////////////////////////////////////////////////
// function declarations:
void checkOptions(Options& opts, int argc, char** argv);
void example(void);
void usage(const char* command);
void countEvents(int& lh, int &rh, HumdrumFile& infile, int line);
void createAnalysisOne(ostream& out, HumdrumFile& infile);
// User interface variables:
Options options;
//////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv) {
// process the command-line options
checkOptions(options, argc, argv);
HumdrumFile infile;
infile.read(options.getArg(1));
createAnalysisOne(std::cout, infile);
return 0;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// createAnalysisOne -- print the metrical position, the number of
// events in the left hand (bottom staff), the number of events in
// the right hand (top staff).
//
void createAnalysisOne(ostream& out, HumdrumFile& infile) {
int i, j;
int absbeat = -1;
int lastabsbeat = -1;
int metrical = -1;
int lastmetrical = -1;
int lhcounter = -1;
int rhcounter = -1;
int rh;
int lh;
int datafound = 0;
int endofdata = -1;
int measureQ = 0;
int difference;
int measurenum;
char measure[32] = {0};
infile.analyzeRhythm("4");
for (i=0; i<infile.getNumLines(); i++) {
if (infile[i].getType() == E_humrec_bibliography) {
if (endofdata < 0) {
// only print the bibliographic records which start before
// end of the data. Ignore any bibliographic records at
// the end of the data until later.
out << infile[i] << "\n";
}
continue;
}
if (infile[i].getType() == E_humrec_interpretation) {
if (strncmp(infile[i][0], "**", 2) == 0) {
// store the of end of data location in the input file
// for printing bibliographic data after the end of the
// data in the original file.
endofdata = i;
}
}
if (infile[i].getType() == E_humrec_data_measure) {
measurenum = -1;
if (sscanf(infile[i][0], "=%d", &measurenum) == 1) {
sprintf(measure, "%d", measurenum);
} else {
measure[0] = '\0';
}
measureQ = 1;
}
if (infile[i].getType() != E_humrec_data) {
continue;
}
if (datafound == 0) {
out << "**kern\t**absbt\t**meter\t**lhcnt\t**rhcnt\n";
if (measureQ) {
out << "=" << measure;
for (j=1; j<FIELDCOUNT; j++) {
out << "\t=" << measure;
}
out << "\n";
measureQ = 0;
}
datafound = 1;
}
absbeat = int(infile[i].getAbsBeat() + 0.001);
metrical = int(infile[i].getBeat() + 0.001);
if (lastabsbeat < 0) {
lastabsbeat = absbeat;
lastmetrical = metrical;
lhcounter = 0;
rhcounter = 0;
} else if (absbeat != lastabsbeat) {
out << "4" << "\t"
<< lastabsbeat << "\t"
<< lastmetrical << "\t"
<< lhcounter << "\t"
<< rhcounter << endl;
difference = absbeat - lastabsbeat;
if (difference > 1) {
for (j=1; j<difference; j++) {
out << "4" << "\t"
<< lastabsbeat + j << "\t"
<< (((lastmetrical-1) + j)%3)+1 << "\t"
<< 0 << "\t"
<< 0 << endl;
}
}
if (measureQ) {
out << "=" << measure;
for (j=1; j<FIELDCOUNT; j++) {
out << "\t=" << measure;
}
out << "\n";
measureQ = 0;
}
lastabsbeat = absbeat;
lastmetrical = metrical;
lhcounter = 0;
rhcounter = 0;
}
countEvents(lh, rh, infile, i);
lhcounter += lh;
rhcounter += rh;
}
difference = int(infile.getTotalDuration()+0.99) - absbeat;
for (j=0; j<difference; j++) {
out << "4" << "\t"
<< absbeat + j << "\t"
<< (((lastmetrical-1) + j)%3)+1 << "\t"
<< 0 << "\t"
<< 0 << endl;
}
out << "==\t==\t==\t==\t==\n";
out << "*-\t*-\t*-\t*-\t*-\n";
// print Bibliographic records after the end of the data
if (endofdata < 0) {
// this should never occur.
return;
}
for (i=endofdata; i<infile.getNumLines(); i++) {
if (infile[i].getType() == E_humrec_bibliography) {
out << infile[i] << "\n";
}
}
}
//////////////////////////////
//
// countEvents -- count the number of events in the primary and
// secondary track for the current line. The number of
// events is the number of notes or chords found in sequence.
// (one chord counts is equal to one note). If notes are
// found in separate voices, they could be counted, or not.
// But currently they are not counted.
//
void countEvents(int& lh, int &rh, HumdrumFile& infile, int line) {
int i;
int trackindex;
int primary;
Array<int> trackfound;
trackfound.setSize(2);
trackfound.setAll(0);
Array<int> trackcounts;
trackcounts.setSize(2);
trackcounts.setAll(0);
for (i=0; i<infile[line].getFieldCount(); i++) {
if (infile[line].getExInterpNum(i) != E_KERN_EXINT) {
continue;
}
primary = infile[line].getPrimaryTrack(i);
if (trackfound[0] == 0) {
trackfound[0] = primary;
trackindex = 0;
} else if (trackfound[0] == primary) {
trackindex = 0;
} else if (trackfound[1] == 0) {
trackfound[1] = primary;
trackindex = 1;
} else if (trackfound[1] == primary) {
trackindex = 1;
} else {
break; // some other spine of **kern data other than the first two
}
if (strcmp(infile[line][i], ".") == 0) {
// don't count null tokens
continue;
}
if (strchr(infile[line][i], 'r') != NULL) {
// don't count rests
continue;
}
trackcounts[trackindex]++;
}
lh = trackcounts[0] ? 1 : 0;
rh = trackcounts[1] ? 1 : 0;
}
//////////////////////////////
//
// checkOptions --
//
void checkOptions(Options& opts, int argc, char* argv[]) {
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, October 2008" << endl;
exit(0);
} else if (opts.getBoolean("version")) {
cout << argv[0] << ", version: 15 October 2008" << 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 function calls to the program.
//
void example(void) {
}
//////////////////////////////
//
// usage -- command-line usage description and brief summary
//
void usage(const char* command) {
}
// md5sum: e4b0b470fd381c0e8bf1fedaa0428043 marcello1.cpp [20081017]