//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Tue May 4 19:08:22 PDT 2004
// Last Modified: Tue May 4 19:08:25 PDT 2004
// Filename: ...sig/examples/all/phraseadd.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/humdrum/phraseadd.cpp
// Syntax: C++; museinfo
//
// Description: Add phrases to monophonic music based on a arbitrary
// marker placed at the beginning of each phrase.
//
#include "humdrum.h"
#include <string.h>
#include <ctype.h>
#define SLURNONE 0
#define SLURSTART 1
#define SLURCONT 2
#define SLURSTOP 3
#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
#include <stdlib.h> /* for qsort and bsearch functions */
///////////////////////////////////////////////////////////////////////////
// function declarations
void checkOptions(Options& opts, int argc, char* argv[]);
void example(void);
void usage(const char* command);
void processFile(HumdrumFile& infile);
void getPitchesAndSlurs(HumdrumFile& infile, Array<int>& lines,
Array<int>& pitches, Array<int>& slurstate);
void printSlurCorrection(HumdrumRecord& line, int slurcorrection);
void printStringWithSlurEnding(const char* string);
void printStringWithSlurStart(const char* string, int correction);
void printFileWithSlurs(HumdrumFile& infile, Array<int>& lines,
Array<int>& slurstate);
// global variables
Options options; // database for command-line arguments
int testQ = 0; // used with -t option
char slurmarker = 'v'; // used with -s option
const char* filename = "";
///////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
HumdrumFile infile;
// process the command-line options
checkOptions(options, argc, argv);
infile.clear();
// if no command-line arguments read data file from standard input
int numinputs = options.getArgCount();
if (numinputs < 1) {
infile.read(cin);
} else {
filename = options.getArg(1);
infile.read(options.getArg(1));
}
processFile(infile);
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// processFile --
//
void processFile(HumdrumFile& infile) {
Array<int> lines;
Array<int> pitches;
Array<int> slurstate;
getPitchesAndSlurs(infile, lines, pitches, slurstate);
int i;
int corr = 0;
for (i=slurstate.getSize()-1; i>=0; i--) {
if (slurstate[i] != 0) {
corr++;
}
if ((i>0) && (slurstate[i] == SLURSTART)) {
slurstate[i-1] = SLURSTOP;
}
}
if (corr > 0) {
slurstate[slurstate.getSize()-1] = SLURSTOP;
}
if (testQ) {
if (corr) {
cout << filename << ": " << corr << " phrase markers\n";
exit(0);
} else {
exit(0);
}
}
if (corr) {
printFileWithSlurs(infile, lines, slurstate);
} else {
// no corrections needed
cout << infile;
}
}
//////////////////////////////
//
// printFileWithSlurs --
//
void printFileWithSlurs(HumdrumFile& infile, Array<int>& lines,
Array<int>& slurstate) {
int i;
int lindex = 0;
for (i=0; i<infile.getNumLines(); i++) {
if (infile[i].getType() != E_humrec_data) {
cout << infile[i] << "\n";
continue;
}
if (lindex >= lines.getSize()) {
cout << infile[i] << "\n";
continue;
}
if (lines[lindex] == i) {
if (slurstate[lindex]) {
// print a slur correction
printSlurCorrection(infile[i], slurstate[lindex]);
} else {
cout << infile[i] << "\n";
}
lindex++;
} else {
cout << infile[i] << "\n";
}
}
}
//////////////////////////////
//
// printSlurCorrection --
//
void printSlurCorrection(HumdrumRecord& line, int slurcorrection) {
int i;
for (i=0; i<line.getFieldCount(); i++) {
if (i != 0) {
// not processing anything but the first spine.
cout << "\t" << line[i];
continue;
}
if (slurcorrection == SLURSTOP) {
printStringWithSlurEnding(line[0]);
} else if (slurcorrection == SLURSTART) {
printStringWithSlurStart(line[0], slurcorrection);
} else {
cout << line[0];
}
}
cout << "\n";
}
//////////////////////////////
//
// printStringWithSlurStart --
//
void printStringWithSlurStart(const char* string, int correction) {
int i;
int len = strlen(string);
cout << "{";
for (i=0; i<len; i++) {
if (string[i] == slurmarker) {
continue;
}
if (string[i] == '{') {
continue;
}
cout << string[i];
}
}
//////////////////////////////
//
// printStringWithSlurEnding --
//
void printStringWithSlurEnding(const char* string) {
int i;
int len = strlen(string);
for (i=0; i<len; i++) {
if (string[i] == '}') continue;
if (string[i] == slurmarker) continue;
cout << string[i];
}
cout << "}";
}
//////////////////////////////
//
// getPitchesAndSlurs --
//
void getPitchesAndSlurs(HumdrumFile& infile, Array<int>& lines,
Array<int>& pitches, Array<int>& slurstate) {
int i;
int pitch;
int slurs;
lines.setSize(infile.getNumLines());
lines.setSize(0);
pitches.setSize(infile.getNumLines());
pitches.setSize(0);
slurstate.setSize(infile.getNumLines());
slurstate.setSize(0);
for (i=0; i<infile.getNumLines(); i++) {
if (infile[i].getType() != E_humrec_data) {
continue;
}
if (strcmp(infile[i][0], ".") == 0) {
// ignore null tokens.
continue;
}
if (strchr(infile[i][0], 'r') != NULL) {
// ignore rests
continue;
}
pitch = Convert::kernToBase40(infile[i][0]);
if (strchr(infile[i][0], slurmarker) != NULL) {
slurs = SLURSTART;
} else {
slurs = SLURNONE;
}
lines.append(i);
pitches.append(pitch);
slurstate.append(slurs);
}
}
//////////////////////////////
//
// checkOptions -- validate and process command-line options.
//
void checkOptions(Options& opts, int argc, char* argv[]) {
opts.define("t|test=b","check a file to see if it has unprocessed markers");
opts.define("s|slurmarker=s:v", "character used for slurmarker");
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, May 2004" << endl;
exit(0);
} else if (opts.getBoolean("version")) {
cout << argv[0] << ", version: 4 May 2004" << 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);
}
testQ = opts.getBoolean("test");
slurmarker = (opts.getString("slurmarker"))[0];
}
//////////////////////////////
//
// example -- example usage of the program
//
void example(void) {
cout <<
" \n"
<< endl;
}
//////////////////////////////
//
// usage -- gives the usage statement for the program
//
void usage(const char* command) {
cout <<
" \n"
<< endl;
}
// md5sum: 4412db1a53c2f89e78e1b11c2adcc89c phraseadd.cpp [20050403]