//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Wed Nov 29 19:55:27 PST 2000
// Last Modified: Wed Nov 29 19:55:30 PST 2000
// Filename: ...sig/examples/all/atakcent.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/humdrum/atakcent.cpp
// Syntax: C++; museinfo
//
// Description: Determination of attack accentuation.
//
//
#include "humdrum.h"
#include <string.h>
#include <ctype.h>
#include <stdio.h>
// function declarations
void checkOptions(Options& opts, int argc, char* argv[]);
int doublecompare(const void* a, const void* b);
void example(void);
void generateSummary(HumdrumFile& infile, Array<int>& atakcent);
void insertdata(double beat, int value,
Array<double>& beatlocation,
Array<int>& occurance, Array<int>& sum);
void intialize(Array<double>& beatlocation,
Array<int>& occurance, Array<int>& sum);
void printAnalysis(HumdrumFile& infile, Array<int>& atakcent);
void printSummary(double lasttop, double lastbottom,
Array<double>& beatlocation,
Array<int>& occurance, Array<int>& sum);
void usage(const char* command);
// global variables
Options options; // database for command-line arguments
int debugQ = 0; // used with the --debug option
int appendQ = 0; // used with the -a option
int compoundQ = 1; // used with the -c option
int summaryQ = 0; // used with the -s option
///////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
HumdrumFile infile;
Array<int> atakcent;
// 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.analyzeAttackAccentuation(atakcent);
if (summaryQ) {
generateSummary(infile, atakcent);
} else {
printAnalysis(infile, atakcent);
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// checkOptions -- validate and process command-line options.
//
void checkOptions(Options& opts, int argc, char* argv[]) {
opts.define("a|append=b", "append analysis to data in output");
opts.define("C|compound=b", "don't try to use compound meters");
opts.define("s|summary=b", "do a metrical summary");
opts.define("debug=b", "trace input parsing");
opts.define("author=b", "author of the program");
opts.define("version=b", "compilation information");
opts.define("example=b", "example usage");
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, Nov 2000" << 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);
}
debugQ = opts.getBoolean("debug");
appendQ = opts.getBoolean("append");
if (opts.getBoolean("compound")) {
compoundQ = 0;
} else {
compoundQ = 1;
}
summaryQ = opts.getBoolean("summary");
}
//////////////////////////////
//
// doublecompare -- compare two doubles for ordering
//
int doublecompare(const void* a, const void* b) {
if (*((double*)a) < *((double*)b)) {
return -1;
} else if (*((double*)a) > *((double*)b)) {
return 1;
} else {
return 0;
}
}
//////////////////////////////
//
// example -- example usage of the maxent program
//
void example(void) {
cout <<
" \n"
<< endl;
}
//////////////////////////////
//
// generateSummary --
//
void generateSummary(HumdrumFile& infile, Array& atakcent) {
int line;
Array<double> top;
Array<double> bottom;
double lasttop = -1.0;
double lastbottom = -1.0;
Array<double> beatlocation;
Array<int> occurance;
Array<int> sum;
infile.analyzeRhythm();
intialize(beatlocation, occurance, sum);
infile.analyzeMeter(top, bottom);
for (line=0; line<infile.getNumLines(); line++) {
if (infile[line].getType() != E_humrec_data) {
continue;
}
if (lasttop == -1.0) {
lasttop = top[line];
}
if (lastbottom == -1.0) {
lastbottom = bottom[line];
}
if ((lasttop != top[line]) || (lastbottom != bottom[line])) {
printSummary(lasttop, lastbottom, beatlocation, occurance, sum);
intialize(beatlocation, occurance, sum);
lasttop = top[line];
lastbottom = bottom[line];
}
insertdata(infile[line].getBeat(), atakcent[line], beatlocation,
occurance, sum);
}
printSummary(lasttop, lastbottom, beatlocation, occurance, sum);
}
//////////////////////////////
//
// insertdata --
//
void insertdata(double beat, int value, Array<double>& beatlocation,
Array<int>& occurance, Array<int>& sum) {
int i;
int foundQ = 0;
int index = -1;
for (i=0; i<beatlocation.getSize(); i++) {
if (beatlocation[i] == beat) {
foundQ = 1;
index = i;
break;
}
}
if (foundQ) {
occurance[index]++;
sum[index] += value;
} else {
int one = 1;
beatlocation.append(beat);
occurance.append(one);
sum.append(value);
}
}
//////////////////////////////
//
// initialize --
//
void intialize(Array<double>& beatlocation, Array<int>& occurance,
Array<int>& sum) {
beatlocation.setSize(0);
occurance.setSize(0);
sum.setSize(0);
beatlocation.allowGrowth(1);
occurance.allowGrowth(1);
sum.allowGrowth(1);
}
//////////////////////////////
//
// printAnalysis --
//
void printAnalysis(HumdrumFile& infile, Array& atakcent) {
int i;
if (appendQ) {
for (i=0; i<infile.getNumLines(); i++) {
switch (infile[i].getType()) {
case E_humrec_global_comment:
case E_humrec_bibliography:
case E_humrec_none:
case E_humrec_empty:
cout << infile[i].getLine() << "\n";
break;
case E_humrec_data:
cout << infile[i].getLine() << "\t";
cout << atakcent[i] << "\n";
break;
case E_humrec_data_comment:
if (infile[i].equalFieldsQ("**kern")) {
cout << infile[i].getLine() << "\t"
<< infile[i][0] << "\n";
} else {
cout << infile[i].getLine() << "\t!\n";
}
break;
case E_humrec_data_measure:
if (infile[i].equalFieldsQ("**kern")) {
cout << infile[i].getLine() << "\t"
<< infile[i][0] << "\n";
} else {
cout << infile[i].getLine() << "\t=\n";
}
break;
case E_humrec_data_interpretation:
if (strncmp(infile[i][0], "**", 2) == 0) {
cout << infile[i].getLine() << "\t";
cout << "**atakcent" << "\n";
} else if (infile[i].equalFieldsQ("**kern")) {
cout << infile[i].getLine() << "\t"
<< infile[i][0] << "\n";
} else {
cout << infile[i].getLine() << "\t*\n";
}
break;
}
}
} else {
for (i=0; i<infile.getNumLines(); i++) {
switch (infile[i].getType()) {
case E_humrec_global_comment:
case E_humrec_bibliography:
case E_humrec_none:
case E_humrec_empty:
cout << infile[i].getLine() << "\n";
break;
case E_humrec_data:
cout << atakcent[i] << "\n";
break;
case E_humrec_data_comment:
if (infile[i].equalFieldsQ("**kern")) {
cout << infile[i][0] << "\n";
} else {
// do nothing
}
break;
case E_humrec_data_measure:
if (infile[i].equalFieldsQ("**kern")) {
cout << infile[i][0] << "\n";
} else {
cout << "\t=\n";
}
break;
case E_humrec_data_interpretation:
if (strncmp(infile[i][0], "**", 2) == 0) {
cout << "**atakcent" << "\n";
} else if (infile[i].equalFieldsQ("**kern")) {
cout << infile[i][0] << "\n";
} else {
// do nothing
}
break;
}
}
}
}
//////////////////////////////
//
// printSummary --
//
void printSummary(double lasttop, double lastbottom,
Array<double>& beatlocation, Array<int>& occurance, Array<int>& sum) {
if (beatlocation.getSize() == 0) {
return;
}
Array<double> sortbeat = beatlocation;
qsort(sortbeat.getBase(), sortbeat.getSize(), sizeof(double),
doublecompare);
cout << "*M" << lasttop << "/" << 4.0/lastbottom << endl;
int index, sorti;
int i;
for (sorti=0; sorti<sortbeat.getSize(); sorti++) {
index = -1;
for (i=0; i<beatlocation.getSize(); i++) {
if (sortbeat[sorti] == beatlocation[i]) {
index = i;
break;
}
}
if (index == -1) {
cout << "Error printing summary" << endl;
exit(1);
}
cout << beatlocation[index] << "\t"
<< sum[index] << "\t"
<< occurance[index] << "\n";
}
}
//////////////////////////////
//
// usage -- gives the usage statement for the quality program
//
void usage(const char* command) {
cout <<
" \n"
<< endl;
}
// md5sum: 6667708dceea865e345b49b8229d7ea8 atakcent.cpp [20050403]