// // 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]