// // Copyright 2002,2009 by Craig Stuart Sapp, All Rights Reserved. // Programmer: Craig Stuart Sapp // Creation Date: Mon Feb 11 19:48:50 PST 2002 // Last Modified: Sun Mar 24 12:10:00 PST 2002 (small changes for visual c++) // Last Modified: Sat Mar 21 14:28:55 PST 2009 // Filename: ...sig/src/sigInfo/ScoreRecordSimple.cpp // Web Address: http://sig.sapp.org/include/sigInfo/ScoreRecordSimple.cpp // Syntax: C++ // // Description: A SCORE item parameter class // #include "ScoreRecordSimple.h" #include "Convert.h" #include #include #include #ifndef OLDCPP #include #include #include #define SSTREAM stringstream #define CSTRING str().c_str() using namespace std; #else #include #include #ifdef VISUAL #include #else #include #endif #define SSTREAM strstream #define CSTRING str() #endif ////////////////////////////// // // ScoreRecordSimple::ScoreRecordSimple -- // ScoreRecordSimple::ScoreRecordSimple(void) { textdata.setSize(1); textdata.allowGrowth(0); textdata[0] = '\0'; textfont.setSize(1); textfont.allowGrowth(0); textfont[0] = '\0'; analysisData.setSize(3); analysisData.allowGrowth(0); analysisData.zero(); } ScoreRecordSimple::ScoreRecordSimple(ScoreRecordSimple& a) { serialnumber = a.serialnumber; textdata = a.textdata; textfont = a.textfont; analysisData = a.analysisData; pi = a.pi; } ////////////////////////////// // // ScoreRecordSimple::~ScoreRecordSimple -- // ScoreRecordSimple::~ScoreRecordSimple(void) { // do nothing textdata.setSize(0); textfont.setSize(0); } ////////////////////////////// // // ScoreRecordSimple::clear -- // void ScoreRecordSimple::clear(void) { textdata.setSize(1); textdata.allowGrowth(0); textdata[0] = '\0'; textfont.setSize(1); textfont.allowGrowth(0); textfont[0] = '\0'; analysisData.setSize(3); analysisData.allowGrowth(0); analysisData.zero(); pi.clear(); } ////////////////////////////// // // ScoreRecordSimple::printAscii -- print the parameter data in ASCII text // format. // default value: roundQ = 1 // default value: verboseQ = 0 // void ScoreRecordSimple::printAscii(ostream& out, int roundQ, int verboseQ) { if (getFixedSize() < 1) { return; } shrink(); union { float num; unsigned char ch[4]; } u; static char buffer[128] = {0}; double num; int i, j; int tcount = 0; int tcorr = 0; int bufflen; for (i=0; i= 0) { tcount++; if (tcorr > 0) { tcorr--; } else { out << ' '; } } if (getValue(i) < 10) { tcount++; if (tcorr > 0) { tcorr--; } else { out << ' '; } } out << buffer; if (i < getFixedSize()-1) { out << ' '; } if (i < getFixedSize()-1) { for (j=0; j<5 - bufflen - tcount; j++) { out << ' '; } out << ' '; } if (5 - bufflen - tcount < 0) { tcorr = -(5-bufflen-tcount); } break; case P3: tcount = 0; cout << setiosflags(ios::left); if (getValue(i) < 10.0) { out << ' '; tcount++; } if (getValue(i) < 100.0) { out << ' '; tcount++; } out << buffer; if (i= 0) { tcount++; if (tcorr > 0) { tcorr--; } else { out << ' '; } } if (fabs(getValue(i)) < 10) { tcount++; if (tcorr > 0) { tcorr--; } else { out << ' '; } } if (fabs(getValue(i)) < 100) { tcount++; if (tcorr > 0) { tcorr--; } else { out << ' '; } } out << buffer; if (i max) { cerr << "ERROR: Score Record too long" << endl; exit(1); } strcpy(buffer1, stream.CSTRING); char* ptr = strchr(buffer1, '\n'); if (ptr != NULL) { strcpy(buffer2, ptr+1); *ptr = '\0'; } else { buffer2[0] = '\0'; } //length = strlen(buffer1); //if (!isprint(buffer1[length-1])) { // buffer1[length-1] = '\0'; //} //buffer1[length-1] = '\0'; //buffer1[length-2] = '\0'; } ////////////////////////////// // // ScoreRecordSimple::writeBinary -- print the parameter data in Binary // format, as found in a SCORE .mus file where the number of numbers // to be written is given first. // int ScoreRecordSimple::writeBinary(ostream& out) { if (getFixedSize() < 1) { return 0; } shrink(); // WinScore can't understand data fields smaller than 3 if (getFixedSize() < 3) { setPValue(3, 0.0); } int i; if (getValue(0) == P1_Text) { // set the length of the text in P12 int textlen = strlen(getTextData()); int fontlen = strlen(getTextFont()); int totaltextlen = textlen + fontlen; setPValue(12, totaltextlen); if (getPValue(13) == 0.0) { setPValue(13, 0.0); // needed for .MUS files to parse in WinScore } int spaces = totaltextlen % 4; int charbytes = totaltextlen / 4; if (spaces != 0) { spaces = 4 - spaces; charbytes++; } writeLittleEndian(out, (float)(getFixedSize() + charbytes)); for (i=0; i 0) { instream.read(buffer, 4-extra); for (i=0; i<4-extra; i++) { if (buffer[i] != 0x20) { cout << "Error: non space character found" << endl; exit(1); } } } } else { // non-text data parameters for (i=1; i0; i--) { if (getValue(i) != 0.0) { break; } else { setFixedSize(i); } } } ////////////////////////////////////////////////////////////////////////// // // private functions // /////////////////////////////// // // ScoreRecordSimple::writeLittleEndian -- // void ScoreRecordSimple::writeLittleEndian(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); } /////////////////////////////// // // ScoreRecordSimple::readLittleEndian -- // float ScoreRecordSimple::readLittleEndian(istream& instream) { unsigned char byteinfo[4]; instream.read((char*)byteinfo, 4); union { float f; unsigned int i; } num; num.i = 0; num.i = byteinfo[3]; num.i = (num.i << 8) | byteinfo[2]; num.i = (num.i << 8) | byteinfo[1]; num.i = (num.i << 8) | byteinfo[0]; return num.f; } ////////////////////////////// // // ScoreRecordSimple::adjustBuffer -- remove all right hand zeros // void ScoreRecordSimple::adjustBuffer(char *buffer) { int len = strlen(buffer); int i; for (i=len-1; i>0; i--) { if (buffer[i] == '0') { buffer[i] = '\0'; len--; } else { break; } } // remove trailing decimal point as well for integers: if (buffer[len-1] == '.') { buffer[len-1] = ' '; } } ////////////////////////////// // // ScoreRecordSimple::getTextData -- return the Code items text data or an // empty string. // const char* ScoreRecordSimple::getTextData(void) { if (textdata.getSize() <= 0) { return ""; } else { return textdata.getBase(); } } ////////////////////////////// // // ScoreRecordSimple::setTextData -- set the Code items text data field. // void ScoreRecordSimple::setTextData(const char* buffer) { int length = strlen(buffer); textdata.setSize(length+1); strcpy(textdata.getBase(), buffer); } ////////////////////////////// // // ScoreRecordSimple::getTextFont -- return the Code items text data or an // empty string. // const char* ScoreRecordSimple::getTextFont(void) { if (textfont.getSize() <= 0) { return ""; } else { return textfont.getBase(); } } ////////////////////////////// // // ScoreRecordSimple::setTextFont -- set the Code items text data field. // void ScoreRecordSimple::setTextFont(const char* buffer) { int length = strlen(buffer); textfont.setSize(length+1); strcpy(textfont.getBase(), buffer); } ////////////////////////////// // // ScoreRecordSimple::getPitch -- // int ScoreRecordSimple::getPitch(void) { return (int)analysisData[0]; } ////////////////////////////// // // ScoreRecordSimple::setPitch -- // void ScoreRecordSimple::setPitch(int aPitch) { analysisData[0] = (float)aPitch; } ////////////////////////////// // // ScoreRecordSimple::getStartOffset -- get the starting time from the start // of the staff. // float ScoreRecordSimple::getStartOffset(void) { return analysisData[1]; } ////////////////////////////// // // ScoreRecordSimple::setStartOffset -- set the starting time from the start // of the staff // void ScoreRecordSimple::setStartOffset(float aDuration) { analysisData[1] = aDuration; } ////////////////////////////// // // ScoreRecordSimple::getVoice -- // int ScoreRecordSimple::getVoice(void) { return (int)analysisData[2]; } ////////////////////////////// // // ScoreRecordSimple::setVoice -- // void ScoreRecordSimple::setVoice(int aVoice) { analysisData[2] = (float)aVoice; } ////////////////////////////// // // ScoreRecordSimple::operator= -- // ScoreRecordSimple& ScoreRecordSimple::operator=(ScoreRecordSimple& a) { if (&a== this) { return *this; } serialnumber = a.serialnumber; textdata.setSize(a.textdata.getSize()); textfont.setSize(a.textfont.getSize()); int i; for (i=0; i