//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Mon Feb 11 22:32:39 PST 2002
// Last Modified: Mon Feb 11 22:32:42 PST 2002
// Filename: ...sig/examples/all/pmx2mus.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/score/pmx2mus.cpp
// Syntax: C++; museinfo
//
// Description: Convert SCORE PMX file into binary format.
//
#include "ScoreRecord.h"
#include "Options.h"
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#ifndef OLDCPP
#include <fstream>
using namespace std;
#else
#include <fstream.h>
#endif
// function declarations:
void convertFile(const char* filename);
void readScoreLine(istream& infile, ScoreRecord& record);
void writeLittleFloat(ostream& out, float number);
// interface variables:
Options options;
int verboseQ = 0; // used with the -v option
const char* outputfilename = ""; // used with the -o option
//////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv) {
options.define("v|verbose=b", "display debugging information in output");
options.define("o|output=s:", "output filename if specified");
options.process(argc, argv);
verboseQ = options.getBoolean("verbose");
outputfilename = options.getString("output");
if (options.getArgCount() == 1) {
convertFile(options.getArg(1));
} else if (options.getArgCount() > 1) {
for (int i=1; i<=options.getArgCount(); i++) {
if (verboseQ) {
cout << "processing file " << options.getArg(i) << "\n";
}
convertFile(options.getArg(i));
}
} else {
cout << "Usage: " << argv[0] << " input.mus " << endl;
exit(1);
}
return 0;
}
/////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// convertFile -- convert from binary to ASCII form.
//
void convertFile(const char* filename) {
int length = strlen(filename);
char ofilename[length + 100];
if (strlen(outputfilename) > 0) {
strcpy(ofilename, outputfilename);
} else {
strcpy(ofilename, filename);
char* ptr = strrchr(ofilename, '.');
if (ptr != NULL) {
ptr[0] = '\0';
strcat(ofilename, ".mus");
} else {
strcat(ofilename, ".mus");
}
}
#ifndef OLDCPP
fstream infile(filename, ios::in);
#ifdef VISUAL
fstream outfile(ofilename, ios::out | ios::binary);
#else
fstream outfile(ofilename, ios::out);
#endif
#else
fstream infile(filename, ios::in | ios::nocreate);
#ifdef VISUAL
fstream outfile(ofilename, ios::out | ios::noreplace | ios::binary);
#else
fstream outfile(ofilename, ios::out | ios::noreplace);
#endif
#endif
if (!infile.is_open()) {
cerr << "Error: cannot read file: " << filename << endl;
exit(1);
}
if (!outfile.is_open()) {
cerr << "Error: cannot write file: " << ofilename << endl;
exit(1);
}
// first write the number of numbers in the data file.
// use a dummy value of 0 for now
char dummy[2] = {0};
outfile.write(dummy, 2);
int writecount = 0; // number of numbers which have been read
ScoreRecord record;
while (!infile.eof()) {
readScoreLine(infile, record);
writecount += record.writeBinary(outfile);
}
// write the trailer
writeLittleFloat(outfile, 0.0); // end of data marker
union { float f; unsigned int i; } num;
num.i = 0x50504153;
writeLittleFloat(outfile, num.f);
writeLittleFloat(outfile, 3.0);
writeLittleFloat(outfile, 0.0);
writeLittleFloat(outfile, 5.0);
writeLittleFloat(outfile, -9999.0);
writecount += 6;
// go back an write the number of numbers written to the file
unsigned char sbyte;
outfile.seekg(0);
sbyte = writecount & 0xff;
outfile.write((char*)&sbyte, 1);
sbyte = (writecount >> 8) & 0xff;
outfile.write((char*)&sbyte, 1);
infile.close();
outfile.close();
}
//////////////////////////////
//
// readScoreLine -- read a PMX file for score data.
// ignore any lines of text which do not start with a number.
//
void readScoreLine(istream& infile, ScoreRecord& record) {
char buffer[1024] = {0};
infile.getline(buffer, 1000, '\n');
if (verboseQ) {
cout << "Read line: " << buffer << endl;
}
record.clear();
record.setAllocSize(100);
char* ptr = strtok(buffer, "\n\t ");
float number = 0.0;
int counter = 0;
if (ptr != NULL) {
number = strtod(ptr, NULL);
if (number == 0.0) {
return;
} else {
record.setValue(counter++, number);
ptr = strtok(NULL, "\n\t ");
while (ptr != NULL) {
number = strtod(ptr, NULL);
record.setValue(counter++, number);
ptr = strtok(NULL, "\n\t ");
}
}
}
}
///////////////////////////////
//
// writeLittleFloat --
//
void writeLittleFloat(ostream& out, float number) {
union { float f; unsigned int i; } num;
num.f = number;
char byteinfo[4];
byteinfo[0] = (char)( num.i & 0xff);
byteinfo[1] = (char)((num.i >> 8) & 0xff);
byteinfo[2] = (char)((num.i >> 16) & 0xff);
byteinfo[3] = (char)((num.i >> 24) & 0xff);
out.write(byteinfo, 4);
}
// md5sum: 3bbdd5b33a6f16a32236ff3341bc3b74 pmx2mus.cpp [20050403]