std::vector<Staff *> Measure::GetFirstStaffGrpStaves(ScoreDef *scoreDef) { assert(scoreDef); std::vector<Staff *> staves; std::vector<int>::iterator iter; std::vector<int> staffList; // First get all the staffGrps AttComparison matchType(STAFFGRP); ArrayOfObjects staffGrps; ArrayOfObjects::iterator staffGrpIter; scoreDef->FindAllChildByComparison(&staffGrps, &matchType); // Then the @n of each first staffDef for (staffGrpIter = staffGrps.begin(); staffGrpIter != staffGrps.end(); ++staffGrpIter) { StaffDef *staffDef = dynamic_cast<StaffDef *>((*staffGrpIter)->GetFirst(STAFFDEF)); if (staffDef) staffList.push_back(staffDef->GetN()); } // Get the corresponding staves in the measure for (iter = staffList.begin(); iter != staffList.end(); ++iter) { AttNIntegerComparison matchN(STAFF, *iter); Staff *staff = dynamic_cast<Staff *>(this->FindChildByComparison(&matchN, 1)); if (!staff) { // LogDebug("Staff with @n '%d' not found in measure '%s'", *iter, measure->GetUuid().c_str()); continue; } staves.push_back(staff); } if (staves.empty()) LogDebug("Empty @staff array"); return staves; }
bool DarmsInput::ImportString(std::string data_str) { int len, res; int pos = 0; const char *data = data_str.c_str(); len = data_str.length(); m_doc->Reset( Raw ); System *system = new System(); Page *page = new Page(); m_staff = new Staff( 1 ); m_measure = new Measure( true, 1 ); m_layer = new Layer( 1 ); m_current_tie = NULL; m_staff->AddLayer(m_layer); m_measure->AddStaff( m_staff ); system->AddMeasure( m_measure ); // do this the C style, char by char while (pos < len) { char c = data[pos]; if (c == '!') { LogDebug("DarmsInput: Global spec. at %i", pos); res = do_globalSpec(pos, data); if (res) pos = res; // if notehead type was specified in the !Nx option preserve it m_staff->notAnc = m_antique_notation; } else if (isdigit(c) || c == '-' ) { // check for '-' too as note positions can be negative //is number followed by '!' ? it is a clef if (data[pos + 1] == '!') { res = do_Clef(pos, data); if (res) pos = res; } else { // we assume it is a note res = do_Note(pos, data, false); if (res) pos = res; } } else if (c == 'R') { res = do_Note(pos, data, true); if (res) pos = res; } else { //if (!isspace(c)) //LogMessage("Other %c", c); } pos++; } // add miniaml scoreDef StaffGrp *staffGrp = new StaffGrp(); StaffDef *staffDef = new StaffDef(); staffDef->SetStaffNo( 1 ); staffGrp->AddStaffDef( staffDef ); m_doc->m_scoreDef.AddStaffGrp( staffGrp ); page->AddSystem( system ); m_doc->AddPage( page ); return true; }
void ScoreDef::Replace( StaffDef *newStaffDef ) { // first find the staffDef with the same @n StaffDef *staffDef = this->GetStaffDef( newStaffDef->GetStaffNo() ); // if found, replace attributes if (staffDef) { staffDef->ReplaceClef( newStaffDef->GetClefAttr() ); staffDef->ReplaceKeySig( newStaffDef->GetKeySigAttr() ); staffDef->ReplaceMensur( newStaffDef->GetMensurAttr() ); } }
StaffDef *ScoreDef::GetStaffDef( int n ) { StaffDef *staffDef = NULL; this->ResetList( this ); ListOfObjects::iterator iter; int i; for (iter = m_list.begin(), i = 0; iter != m_list.end(); ++iter, i++) { staffDef = dynamic_cast<StaffDef*>(*iter); if (staffDef && (staffDef->GetStaffNo() == n) ) { return staffDef; } } return staffDef; }
StaffDef *ScoreDef::GetStaffDef( int n ) { StaffDef *staffDef = NULL; this->ResetList( this ); ListOfObjects* childList = this->GetList(this); ListOfObjects::iterator iter; for (iter = childList->begin(); iter != childList->end(); ++iter) { staffDef = dynamic_cast<StaffDef*>(*iter); if (staffDef && (staffDef->GetN() == n) ) { return staffDef; } } return staffDef; }
int StaffGrp::OptimizeScoreDefEnd(FunctorParams *) { // OptimizeScoreDefParams *params = dynamic_cast<OptimizeScoreDefParams *>(functorParams); // assert(params); this->SetDrawingVisibility(OPTIMIZATION_HIDDEN); for (auto &child : m_children) { if (child->Is(STAFFDEF)) { StaffDef *staffDef = dynamic_cast<StaffDef *>(child); assert(staffDef); if (staffDef->GetDrawingVisibility() != OPTIMIZATION_HIDDEN) { this->SetDrawingVisibility(OPTIMIZATION_SHOW); break; } } else if (child->Is(STAFFGRP)) { StaffGrp *staffGrp = dynamic_cast<StaffGrp *>(child); assert(staffGrp); if (staffGrp->GetDrawingVisibility() != OPTIMIZATION_HIDDEN) { this->SetDrawingVisibility(OPTIMIZATION_SHOW); break; } } } if ((this->GetSymbol() == staffGroupingSym_SYMBOL_brace) && (this->GetDrawingVisibility() != OPTIMIZATION_HIDDEN)) { for (auto &child : m_children) { if (child->Is(STAFFDEF)) { StaffDef *staffDef = dynamic_cast<StaffDef *>(child); assert(staffDef); staffDef->SetDrawingVisibility(OPTIMIZATION_SHOW); } } } return FUNCTOR_CONTINUE; }
void ScoreDef::Replace( StaffDef *newStaffDef ) { // first find the staffDef with the same @n StaffDef *staffDef = this->GetStaffDef( newStaffDef->GetN() ); // if found, replace attributes if (staffDef) { staffDef->ReplaceClef( newStaffDef->GetClef() ); staffDef->ReplaceKeySig( newStaffDef->GetKeySig() ); staffDef->ReplaceMensur( newStaffDef->GetMensur() ); staffDef->ReplaceMeterSig( newStaffDef->GetMeterSig() ); // copy other attributes if present if ( newStaffDef->HasLabel() ) staffDef->SetLabel( newStaffDef->GetLabel() ); if ( newStaffDef->HasLabelAbbr() ) staffDef->SetLabelAbbr( newStaffDef->GetLabelAbbr() ); } }
Staff* CScribeToNeoScribeXML::Scribe2MEIXMLStaff(const CScribeReaderVisitable& scribe_data, const scribe_part& partit, StaffGrp* staffgrp, const int i) { std::string staffnum("s"); staffnum += std::to_string(i); //autogenerate staff ids //finish score definitions //add staff definition for current part //NB. look to alternatively embedding these in staffs StaffDef* staffdef = new StaffDef; //define staff from data staffgrp->addChild(staffdef); staffdef->addAttribute("id", staffnum); staffdef->addAttribute("lines", std::to_string(partit.initial_staff_data.staff_lines)); staffdef->addAttribute("label", CScribeCodes::voice_labels[partit.voice_type].c_str()); //define clef from data Clef* clef = new Clef; staffdef->addChild(clef); scribe_clef loc_clef; loc_clef.clef_line = partit.initial_staff_data.clef_line; loc_clef.clef = partit.initial_staff_data.clef; //convert scribe-based clef position to mei //int mei_clef_line = ((loc_clef.clef_line + 1)/2) - 1; = incorrect int mei_clef_line = 1 + (loc_clef.clef_line-3)/2; //4-line staves are numbered 3, 5, 7, 9 in scribe //if (partit->staff_lines<=4) mei_clef_line -= (5 - partit->staff_lines); clef->addAttribute("line", std::to_string(mei_clef_line)); //these need to be set for each staff/part clef->addAttribute("shape", std::string(&(partit.initial_staff_data.clef),1).c_str()); //the first event in stored memory should be the initial clef Staff* staff = new Staff; staff->addAttribute("id", staffnum); staff->addAttribute("source", partit.abbrev_ms); //folio on which part appears Pb* pb = new Pb; //new ELEMENT? staff->addChild(pb); pb->addAttribute("n", partit.folios); //first staff on which part appears Sb* sb = new Sb; sb->addAttribute("n", "0"); //set to "0" since this isn't encoded in scribe; data will need to be enhanced later staff->addChild(sb); coloration_type current_color = coloration_type::full_black; // this needs to be better handled with a default coloration in a part for (std::vector<scribe_row>::const_iterator rowit = partit.rows.begin(); rowit!=partit.rows.end(); rowit++) { if (rowit->is_comment) { //check it this is the correct way to handle a comment MeiCommentNode* comment = new MeiCommentNode; comment->setValue(rowit->comment); staff->addChild(comment); //NB. syl can have a type (eg. initial) attribute and also encode color as <rend> child element } else { //syllable container (holds syllables, notes, neumes, and ligatures) Syllable* syllable = new Syllable; //neumes.h staff->addChild(syllable); //add actual syllable if present if (!rowit->syllable.empty()) { Syl* syl = new Syl; syl->setValue(rowit->syllable); syllable->addChild(syl); } //extract events - notes, rests ligatures, uneumes and/or ligatures for (std::vector<scribe_event>::const_iterator eventit = rowit->events.begin(); eventit!=rowit->events.end(); eventit++ ) { current_color = eventit->local_coloration; //use temp TiXML pointer which is either syllable, uneume/ineume or ligature - add notes to this, but make sure that uneume/inueme/ligature pointer is preinserted into syllable //handle events for each row code_t event_type = scribe_data.GetCodes()->get_code_type(eventit->code);//codes->get_code_type(eventit->code); //foster parent will change roles according to child elements that need to be added MeiElement* foster = syllable; switch (event_type) { case code_t::ineume: { #ifdef IGNOREGAPS Ineume* ineume = new Ineume; //ineume->addAttribute("name", scribe_data.GetCodes()->code_to_name(eventit->code)); foster->addChild(ineume); foster = ineume; #else //this needs work, hence excluded if (!eventit->preceding_gap || foster->getChildren().empty()) { Ineume* ineume = new Ineume; //ineume->addAttribute("name", scribe_data.GetCodes()->code_to_name(eventit->code)); foster->addChild(ineume); foster = ineume; } else { MeiElement* lastNeume = foster->getChildren().back(); if (lastNeume->getName() == "ineume") { Ineume* newNeume = new Ineume(*dynamic_cast<Ineume*>(lastNeume)); /*for (std::vector<MeiElement*>::const_iterator child = lastNeume->getChildren().begin(); child!=lastNeume->getChildren().end(); child++ ) { MeiElement* clone = new MeiElement(**child); newNeume->addChild(clone); }*/ foster->removeChild(lastNeume); foster->addChild(newNeume); //delete lastNeume; foster = newNeume; } else foster = lastNeume; } #endif goto do_note; break; } case code_t::uneume: { Uneume* uneume = new Uneume; uneume->addAttribute("name", scribe_data.GetCodes()->code_to_name(eventit->code)); foster->addChild(uneume); foster = uneume; goto do_note; break; } case code_t::ligature: { Ligature* ligature = new Ligature; //mensural.h ligature->addAttribute("name", scribe_data.GetCodes()->code_to_name(eventit->code)); foster->addChild(ligature); foster = ligature; if (current_color!=coloration_type::full_black) { switch (current_color) { case full_red: ligature->addAttribute("color", "red"); break; case void_red: ligature->addAttribute("color", "red"); ligature->addAttribute("void", "true"); //this seems a sensible solution for this problem and a suitable additional attribute to the MEI description break; case void_black: ligature->addAttribute("void", "true"); //** break; case full_blue: ligature->addAttribute("color", "blue"); break; default: break; } } //goto do_note; //break; } case code_t::note: do_note: { for (auto i = eventit->pitch_num.begin(); i!=eventit->pitch_num.end(); i++) { int note_count = 1; MeiElement* temp_foster = foster; //handle note attributes according to type if ( foster->getName()=="ineume" ) { Uneume* temp_uneume = new Uneume; //handle ineumes //find uneume names temp_uneume->addAttribute("name", CScribeReaderVisitable::get_ineume_part(eventit->code, i - eventit->pitch_num.begin(), note_count)); foster->addChild(temp_uneume); temp_foster = temp_uneume; //allow notes to be children of uneume } else if ((eventit->code=="B" || eventit->code=="V" || eventit->code=="L") && eventit->pitch_num.size()>1 && scribe_data.GetType()==chant && i!=eventit->pitch_num.begin()) //codes like virga and punctum may be followed by several pitch numbers, indicating a sequence of simple neumes { Uneume* temp_uneume = new Uneume; temp_uneume->addAttribute("name", scribe_data.GetCodes()->code_to_name(eventit->code)); foster->getParent()->addChild(temp_uneume); //link to syllable element, not uneume! temp_foster = temp_uneume; } //also handle ligatures auto j = 0; //insert note or notes for unneumes in ineumes for (; j < note_count ; j++) { //convert note location to pitch name // need to handle dots as element rather than attribute? char pitch_name = loc_clef.get_pitch_name(*i); int octave = loc_clef.get_octave(*i); Note* note = new Note; if (foster->getName()=="syllable") { note->addAttribute("dur", scribe_data.GetCodes()->code_to_name(eventit->code)); } else if (foster->getName()=="ligature") { note->addAttribute("dur", scribe_data.get_ligature_part(eventit->code, j)); } note->addAttribute("pname", std::string(&pitch_name,1)); note->addAttribute("oct", std::to_string(octave)); int note_loc = *i - 3; //3 is bottom line in Scribe, 0 in MEI note->addAttribute("loc", std::to_string( note_loc )); if (current_color!=coloration_type::full_black) { switch (current_color) { case full_red: note->addAttribute("color", "red"); break; case void_red: note->addAttribute("color", "red"); note->addAttribute("void", "true"); //this seems a sensible solution for this problem and a suitable additional attribute to the MEI description break; case void_black: note->addAttribute("void", "true"); //** break; case full_blue: note->addAttribute("color", "blue"); break; default: break; } } temp_foster->addChild(note); } i+=j-1; } } break; //dot needs to be handled as a unique element in our extended definition /*Stinson, 7 July 2013: Further notes on DOT The code has two arguments: the first is the substantive position on the staff; the second refines that position up or down and is capable of five variants: 0 = exactly on the line or exactly in the middle of the space between the lines; -1 = 0.1 of the space between the lines below (or for +, above) the space or line; -2= 0.2 of the space below the normal position for that line or space; -3 = 0.3 below the normal position; -4 = 0.4 below the normal position. Only values between 0 and 4 are permitted as the second argument as 5 would be the equivalent of having the dot on the next numbered line or space, e.g. '7 -5', if it were permitted, would be the same as '6 0'.*/ case code_t::dot: { Dot* dot = new Dot; char pitch_name = loc_clef.get_pitch_name(eventit->pitch_num[0]); int octave = loc_clef.get_octave(eventit->pitch_num[0]); dot->addAttribute("ploc", std::string(&pitch_name,1)); dot->addAttribute("oloc", std::to_string(octave)); /*vo: records the vertical adjustment of a feature's programmatically-determined location in terms of staff interline distance; that is, in units of 1/2 the distance between adjacent staff lines. (MEI2013)*/ //only set for non-defult positions if (eventit->pitch_num[1]!=0) { float v_pos = eventit->pitch_num[1]/10.0*2; dot->addAttribute("vo", to_string_with_precision(v_pos,1)); } foster->addChild(dot); } break; case code_t::rest: { Rest* rest = new Rest; foster->addChild(rest); switch (*(eventit->code.c_str())) { //rests of type 'R' has two associated pitch numbers from which we might infer the type case generic_rest: { int end = eventit->pitch_num[0]; int start = eventit->pitch_num[1]; int rest_type = start-end; switch (rest_type) { case minim_rest: rest->addAttribute("type", "minima"); break; case semibreve_rest: rest->addAttribute("type", "semibrevis"); break; case breve_rest: rest->addAttribute("type", "brevis"); break; case long_rest: rest->addAttribute("type", "longa imperfecta"); break; case perf_long_rest: rest->addAttribute("type", "long perfecta"); break; default: break; } char ploc = loc_clef.get_pitch_name(start); rest->addAttribute("ploc", std::string(&ploc,1)); rest->addAttribute("oloc", std::to_string(loc_clef.get_octave(start))); break; //also process 'RSM', semiminim rest } //case semiminim_rest: //rest->SetAttribute("type", "semiminim"); // break; default: rest->addAttribute("type", scribe_data.GetCodes()->code_to_name(eventit->code)); if (!eventit->pitch_num.empty()) { char pitch_name = loc_clef.get_pitch_name(eventit->pitch_num[0]); int octave = loc_clef.get_octave(eventit->pitch_num[0]); rest->addAttribute("ploc", std::string(&pitch_name,1)); rest->addAttribute("oloc", std::to_string(octave)); } break; } } break; // non-standard mensuration signs case code_t::mensuration: { Mensur* mensuration_sign = new Mensur; foster->addChild(mensuration_sign); if (eventit->code == "MO" || eventit->code == "MC" || eventit->code == "MO." || eventit->code == "MC.") { char the_sign = eventit->code[1]; mensuration_sign->addAttribute("sign", std::string(&the_sign,1)); if (eventit->code.size()==3 && eventit->code[2]=='.') { mensuration_sign->addAttribute("dot", "true"); } //also able to set attribute 'orient' to reversed for reversed signs; and slash attribute for cut signs } if (eventit->code == ".D." || eventit->code == ".Q." || eventit->code == ".SI." || eventit->code == ".P." || eventit->code == ".N." || eventit->code == ".O." || eventit->code == ".I.") //also .SG.? { //these are wholly new to the MEI schema; the whole dot-letter-dot sign is encoded mensuration_sign->addAttribute("sign", eventit->code); } break; } case code_t::barline: { BarLine* barline = new BarLine; foster->addChild(barline); if (eventit->code == "QBAR") { barline->addAttribute("rend", "quarter"); //non-standard data type for rend. } if (eventit->code == "HBAR") { barline->addAttribute("rend", "half"); } if (eventit->code == "WBAR") { barline->addAttribute("rend", "single"); } if (eventit->code == "DBAR") { barline->addAttribute("rend", "dbl"); } //modern bar editorial - ignore? if (eventit->code == "MBAR") { barline->addAttribute("barplace", "takt"); barline->addAttribute("taktplace", std::string(9,1)); } //also able to see rend attribute break; } case code_t::clef: { //NB. old clefchange element superceded; clefGrp used for simultaneous clefs loc_clef.clef_line = *(eventit->pitch_num.begin()); loc_clef.clef = *(eventit->code.c_str()); Clef* clef = new Clef; clef->addAttribute("line", std::to_string( ((loc_clef.clef_line + 1)/2) - 1)); clef->addAttribute("shape", std::string(&(loc_clef.clef),1).c_str()); foster->addChild(clef); break; } //The MEI accidental names are not used: diesis, b-rotundum and b-quadratum are. Other variants may be added. All ms accidentials in Scribe (as they should be in NeoScribe) are independent elements case code_t::accidental: { Accid* accid = new Accid; accid->addAttribute("accidental", scribe_data.GetCodes()->code_to_name(eventit->code)); if (!eventit->pitch_num.empty()) { char ploc = loc_clef.get_pitch_name(eventit->pitch_num[0]); int oloc = loc_clef.get_octave(eventit->pitch_num[0]); accid->addAttribute("ploc", std::string(&ploc,1)); accid->addAttribute("oloc", std::to_string(oloc)); } foster->addChild(accid); break; } case code_t::other: //lucunae default: break; } } } } return staff; }
void PaeInput::parsePlainAndEasy(std::istream &infile) { // buffers char c_clef[1024] = {0}; char c_key[1024] = {0}; char c_keysig[1024] = {0}; char c_timesig[1024] = {0}; char c_alttimesig[1024] = {0}; char incipit[10001] = {0}; int in_beam = 0; std::string s_key; MeasureObject current_measure; NoteObject current_note; Clef *staffDefClef = NULL; std::vector<MeasureObject> staff; // read values while (!infile.eof()) { infile.getline(data_line, 10000); if (infile.eof()) { LogDebug("Truncated file or ending tag missing"); //exit(1); } getAtRecordKeyValue(data_key, data_value, data_line); if (strcmp(data_key,"end")==0) { break; } else if (strcmp(data_key,"clef")==0) { strcpy( c_clef, data_value ); } else if (strcmp(data_key,"key")==0) { strcpy( c_key, data_value ); } else if (strcmp(data_key,"keysig")==0) { strcpy( c_keysig, data_value ); } else if (strcmp(data_key,"timesig")==0) { strcpy( c_timesig, data_value ); } else if (strcmp(data_key,"alttimesig")==0) { strcpy( c_alttimesig, data_value ); } else if (strcmp(data_key,"data")==0) { strcpy( incipit, data_value ); } } if (strlen(c_clef)) { Clef *c = new Clef; getClefInfo(c_clef, c ); // do we need to put a default clef? if (!staffDefClef) staffDefClef = c; else current_measure.clef = c; } if (strlen(c_keysig)) { KeySig *k = new KeySig(); getKeyInfo( c_keysig, k); current_measure.key = k; } if (strlen(c_timesig)) { MeterSig *meter = new MeterSig; getTimeInfo( c_timesig, meter); // What about previous values? Potential memory leak? LP current_measure.meter = meter; } // read the incipit string size_t length = strlen(incipit); int i = 0; while(i < length) { // eat the input... if (incipit[i] == ' ') { // just skip i++; } // octaves if ((incipit[i] == '\'') || (incipit[i] == ',')) { i += getOctave( incipit, ¤t_note.octave, i ); } // rhythmic values else if (isdigit(incipit[i]) != 0) { i += getDurations( incipit, ¤t_measure, i ); } //accidentals (1 = n; 2 = x; 3 = xx; 4 = b; 5 = bb) else if (incipit[i] == 'n' || incipit[i] == 'x' || incipit[i] == 'b') { i += getAccidental( incipit, ¤t_note.accidental, i ); } // // beaming starts else if (incipit[i] == '{') { //current_note.beam = 1; current_note.beam = BEAM_INITIAL; in_beam++; } // beaming ends else if (incipit[i] == '}' && in_beam > 0) { current_measure.notes[current_measure.notes.size() - 1].beam = BEAM_TERMINAL; current_note.beam = 0; in_beam--; } // slurs are read when adding the note else if (incipit[i] == '+') { } // beginning tuplets & fermatas else if (incipit[i] == '(') { i += getTupletFermata( incipit, ¤t_note, i ); } // end of tuplets else if ((incipit[i] == ';') || (incipit[i] == ')')) { i += getTupletFermataEnd( incipit, ¤t_note, i ); } // trills are read when adding the note else if (incipit[i] == 't') { } //grace notes else if ((incipit[i] == 'g') || (incipit[i] == 'q')) { i += getGraceNote( incipit, ¤t_note, i ); } // end of appogiatura else if (incipit[i] == 'r') { current_note.appoggiatura = 0; // should not have to be done, but just in case } //note and rest // getNote also creates a new note object else if (((incipit[i]-'A'>=0) && (incipit[i]-'A'<7)) || (incipit[i]=='-')) { i += getNote( incipit, ¤t_note, ¤t_measure, i ); } // whole rest else if (incipit[i] == '=') { i += getWholeRest( incipit, ¤t_measure.wholerest, i ); } // abbreviation else if (incipit[i] == '!') { i += getAbbreviation( incipit, ¤t_measure, i ); } // measure repetition else if ((incipit[i] == 'i') && staff.size() > 0) { MeasureObject last_measure = staff[staff.size() - 1]; current_measure.notes = last_measure.notes; current_measure.wholerest = last_measure.wholerest; // if old measure does not end with a tie // force the first note of the newly copied measure to be without tie // this is to prevent copying tie closes which are invalid if (last_measure.notes.size() > 0 && last_measure.notes[last_measure.notes.capacity() - 1].tie == 0) current_measure.notes[0].tie = 0; } //barLine else if ((incipit[i] == ':') || (incipit[i] == '/')) { i += getBarline(incipit, ¤t_measure.barLine, i); current_measure.abbreviation_offset = 0; // just in case... staff.push_back( current_measure ); current_measure.reset(); } //clef change else if ((incipit[i] == '%') && (i+1 < length)) { Clef *c = new Clef; i += getClefInfo(incipit, c, i + 1); // if (!staffDefClef) { staffDefClef = c; } // If there are no notes yet in the measure // attach this clef change to the measure else if (current_measure.notes.size() == 0) { // If a clef was already assigned, remove it if (current_measure.clef) delete current_measure.clef; current_measure.clef = c; } else { // as above if (current_note.clef) delete current_note.clef; current_note.clef = c; } } //time signature change else if ((incipit[i] == '@') && (i+1 < length)) { MeterSig *meter = new MeterSig; i += getTimeInfo( incipit, meter, i + 1); if (current_measure.notes.size() == 0) { if (current_measure.meter) { delete current_measure.meter; } // When will this be deleted? Potential memory leak? LP current_measure.meter = meter; } else { if (current_note.meter) { delete current_note.meter; } current_note.meter = meter; } } //key signature change else if ((incipit[i] == '$') && (i+1 < length)) { KeySig *k = new KeySig; i += getKeyInfo( incipit, k, i + 1); if (current_measure.notes.size() == 0) { if (current_measure.key) delete current_measure.key; current_measure.key = k; } else { if (current_note.key) delete current_note.key; current_note.key = k; } } i++; } // we need to add the last measure if it has no barLine at the end if (current_measure.notes.size() != 0) { //current_measure.barLine = "=-"; staff.push_back( current_measure ); current_measure.notes.clear(); } m_doc->Reset( Raw ); Page *page = new Page(); System *system = new System(); int measure_count = 1; std::vector<MeasureObject>::iterator it; for ( it = staff.begin() ; it < staff.end(); it++ ) { m_staff = new Staff( 1 ); m_measure = new Measure( true, measure_count ); m_layer = new Layer( ); m_layer->SetN( 1 ); m_staff->AddLayer(m_layer); m_measure->AddStaff( m_staff ); system->AddMeasure( m_measure ); MeasureObject obj = *it; convertMeasure( &obj ); measure_count++; } // add miniaml scoreDef StaffGrp *staffGrp = new StaffGrp(); StaffDef *staffDef = new StaffDef(); staffDef->SetN( 1 ); staffDef->SetLines(5); if (staffDefClef) { staffDef->SetClefShape(staffDefClef->GetShape()); staffDef->SetClefLine(staffDefClef->GetLine()); staffDef->SetClefDis(staffDefClef->GetDis()); staffDef->SetClefDisPlace(staffDefClef->GetDisPlace()); delete staffDefClef; } staffGrp->AddStaffDef( staffDef ); m_doc->m_scoreDef.AddStaffGrp( staffGrp ); page->AddSystem( system ); m_doc->AddPage( page ); }
int Object::SetCurrentScoreDef( ArrayPtrVoid params ) { // param 0: the current scoreDef ScoreDef *currentScoreDef = static_cast<ScoreDef*>(params[0]); StaffDef **currentStaffDef = static_cast<StaffDef**>(params[1]); assert( currentScoreDef ); // starting a new page Page *page = dynamic_cast<Page*>(this); if ( page ) { if ( page->m_parent->GetChildIndex( page ) == 0 ) { currentScoreDef->SetRedrawFlags( true, true, true, true ); currentScoreDef->SetDrawLabels( true ); } else { currentScoreDef->SetRedrawFlags( true, true, false, false ); currentScoreDef->SetDrawLabels( false ); } page->m_drawingScoreDef = *currentScoreDef; return FUNCTOR_CONTINUE; } // starting a new system System *system = dynamic_cast<System*>(this); if ( system ) { currentScoreDef->SetRedrawFlags( true, true, false, false ); return FUNCTOR_CONTINUE; } // starting a new scoreDef ScoreDef *scoreDef= dynamic_cast<ScoreDef*>(this); if ( scoreDef ) { bool drawClef = false; bool drawKeySig = false; bool drawMensur = false; bool drawMeterSig = false; if (scoreDef->GetClef()) { currentScoreDef->ReplaceClef(scoreDef->GetClef()); drawClef = true; } if (scoreDef->GetKeySig()) { currentScoreDef->ReplaceKeySig(scoreDef->GetKeySig()); drawKeySig = true; } if (scoreDef->GetMensur()) { currentScoreDef->ReplaceMensur(scoreDef->GetMensur()); drawMensur = true; } if (scoreDef->GetMeterSig()) { currentScoreDef->ReplaceMeterSig(scoreDef->GetMeterSig()); drawMeterSig = true; } // Replace the current scoreDef with the new one, including its content (staffDef) currentScoreDef->Replace(scoreDef); currentScoreDef->SetRedrawFlags( drawClef, drawKeySig, drawMensur, drawMeterSig ); return FUNCTOR_CONTINUE; } // starting a new staffDef // Because staffDef have to be included in a scoreDef, a new staffDef was already // replaced by the new scoreDef (see above). Here we only need to reset the drawing flags StaffDef *staffDef= dynamic_cast<StaffDef*>(this); if ( staffDef ) { StaffDef *tmpStaffDef = currentScoreDef->GetStaffDef( staffDef->GetN() ); if (staffDef->GetClef()) { tmpStaffDef->SetDrawClef( true ); } if (staffDef->GetKeySig()) { tmpStaffDef->SetDrawKeySig( true ); } if (staffDef->GetMensur()) { tmpStaffDef->SetDrawMensur( true ); } if (staffDef->GetMeterSig()) { tmpStaffDef->SetDrawMeterSig( true ); } } // starting a new staff Staff *staff = dynamic_cast<Staff*>(this); if ( staff ) { (*currentStaffDef) = currentScoreDef->GetStaffDef( staff->GetN() ); return FUNCTOR_CONTINUE; } // starting a new layer Layer *layer = dynamic_cast<Layer*>(this); if ( layer ) { // setting the layer stem direction. Alternatively, this could be done in // View::DrawLayer. If this (and other things) is kept here, renaming the method to something more // generic (PrepareDrawing?) might be a good idea... if (layer->m_parent->GetChildCount() > 1) { if (layer->m_parent->GetChildIndex(layer)==0) { layer->SetDrawingStemDir(STEMDIRECTION_up); } else { layer->SetDrawingStemDir(STEMDIRECTION_down); } } layer->SetDrawingAndCurrentValues( currentScoreDef, (*currentStaffDef) ); return FUNCTOR_CONTINUE; } // starting a new clef Clef *clef = dynamic_cast<Clef*>(this); if ( clef ) { assert( *currentStaffDef ); (*currentStaffDef)->ReplaceClef( clef ); return FUNCTOR_CONTINUE; } // starting a new keysig KeySig *keysig = dynamic_cast<KeySig*>(this); if ( keysig ) { assert( *currentStaffDef ); (*currentStaffDef)->ReplaceKeySig( keysig ); return FUNCTOR_CONTINUE; } return FUNCTOR_CONTINUE; }