//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Tue Mar 26 09:12:54 PST 2002
// Last Modified: Tue Mar 26 09:12:58 PST 2002
// Filename: ...sig/examples/all/scorepitch.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/score/scorepitch.cpp
// Syntax: C++; museinfo
//
// Description: Extract pitch information from a SCORE data file.
//
#include "museinfo.h"
#include "ScorePage.h"
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#ifndef OLDCPP
#include <fstream>
#else
#include <fstream.h>
#endif
// function declarations:
void extractPitches(ScorePage& score);
void printItem(ScoreRecord& record, int& clef, int& key);
void printKey(int key);
void printClef(int clef);
// interface variables:
Options options;
int verboseQ = 0; // Display debugging information
int rhythmQ = 1; // use with the -r option
int main(int argc, char** argv) {
options.define("v|verbose=b", "print debugging information");
options.define("R|no-rhythm=b", "don't display rhythm information");
options.process(argc, argv);
verboseQ = options.getBoolean("verbose");
rhythmQ = !options.getBoolean("no-rhythm");
if (options.getArgCount() == 0) {
cout << "Usage: " << argv[0] << " input.mus " << endl;
exit(1);
}
ScorePage score;
for (int i=1; i<=options.getArgCount(); i++) {
score.clear();
score.readFile(options.getArg(i), verboseQ);
extractPitches(score);
}
cout << flush;
return 0;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// extractPitches --
//
void extractPitches(ScorePage& score) {
score.analyzePitch();
int i, j;
int clef = -1000;
int key = -1000;
for (i=score.getMaxStaff(); i>=0; i--) {
if (verboseQ) {
cout << "Staff: " << i << "\titems: " << score.getStaffSize(i) << endl;
}
for (j=0; j<score.getStaffSize(i); j++) {
printItem(score.getStaff(i, j), clef, key);
}
if (score.getStaffSize(i) > 0) {
cout << "\n";
}
}
}
//////////////////////////////
//
// printItem -- print the given score item.
//
void printItem(ScoreRecord& record, int& clef, int& key) {
char pbuffer[32] = {0};
char dbuffer[32] = {0};
int tempkey;
int tempclef;
switch ((int)record.getPValue(1)) {
case S_Note:
cout << " ";
if (rhythmQ) {
if (record.getPValue(7) == 0.0 || record.getPValue(7) > 64.0) {
cout << "8";
} else {
cout << Convert::durationToKernRhythm(dbuffer, record.getPValue(7));
}
}
cout << Convert::base40ToKern(pbuffer, record.getPitch());
if (rhythmQ) {
if (record.getPValue(7) == 0.0 || record.getPValue(7) > 64.0) {
cout << "q";
}
}
break;
case S_Rest:
cout << " ";
if (rhythmQ) {
cout << Convert::durationToKernRhythm(dbuffer, record.getPValue(7));
}
cout << "r";
break;
case S_Barline:
cout << " =";
switch ((int)record.getPValue(5)) {
case 1: cout << "||"; break;
case 2: cout << "="; break;
case 3: cout << ":|!"; break;
case 4: cout << "!|:"; break;
case 5: cout << ":|!|:"; break;
case 6: cout << ":!!:"; break;
}
break;
case S_MeterSignature:
cout << " *M" << (int)record.getPValue(5)
<< "/" << (int)record.getPValue(6);
break;
case S_KeySignature:
tempkey = (int)record.getPValue(5);
if (key < -10 || key != tempkey) {
key = tempkey;
cout << " ";
printKey(key);
}
break;
case S_Clef:
tempclef = (int)record.getPValue(5);
if (clef < -10 || clef != tempclef) {
clef = tempclef;
cout << " ";
printClef(clef);
}
}
}
//////////////////////////////
//
// printClef -- print the **kern clef token.
// Ignoring Soprano, Baritone, and Mezzo-soprano clefs for now.
//
void printClef(int clef) {
switch (clef) {
case 0: cout << "*clefG2"; break; // treble
case 1: cout << "*clefF4"; break; // bass
case 2: cout << "*clefC3"; break; // alto
case 3: cout << "*clefC4"; break; // tenor
case 4: cout << "*clefX"; break; // percussion
}
}
//////////////////////////////
//
// printKey -- print the **kern key token.
//
void printKey(int key) {
switch (key) {
case -7: cout << "*k[b-e-a-d-g-c-f-]"; break;
case -6: cout << "*k[b-e-a-d-g-c-]"; break;
case -5: cout << "*k[b-e-a-d-g-]"; break;
case -4: cout << "*k[b-e-a-d-]"; break;
case -3: cout << "*k[b-e-a-]"; break;
case -2: cout << "*k[b-e-]"; break;
case -1: cout << "*k[b-]"; break;
case 0: cout << "*k[]"; break;
case 1: cout << "*k[f#]"; break;
case 2: cout << "*k[f#c#]"; break;
case 3: cout << "*k[f#c#g#]"; break;
case 4: cout << "*k[f#c#g#d#]"; break;
case 5: cout << "*k[f#c#g#d#a#]"; break;
case 6: cout << "*k[f#c#g#d#a#e#]"; break;
case 7: cout << "*k[f#c#g#d#a#e#b#]"; break;
}
}
// md5sum: 0429012f5b318ced9f67d5daa934c96e scorepitch.cpp [20050403]