//--------------------------------------------------------------------------------------- void ImoTreeAlgoritms::remove_staffobj(Document* pDoc, ImoStaffObj* pSO) { //get and save relations vector<ImoId> relIds; ImoRelations* pRels = pSO->get_relations(); if (pRels) { list<ImoRelObj*>& relations = pRels->get_relations(); if (relations.size() > 0) { list<ImoRelObj*>::iterator it; for (it = relations.begin(); it != relations.end(); ++it) { relIds.push_back( (*it)->get_id() ); } } } //delete object ImoInstrument* pInstr = pSO->get_instrument(); pInstr->delete_staffobj(pSO); //ask relations to reorganize themselves if (relIds.size() > 0) { vector<ImoId>::iterator itV; for (itV = relIds.begin(); itV != relIds.end(); ++itV) { ImoRelObj* pRO = static_cast<ImoRelObj*>( pDoc->get_pointer_to_imo(*itV) ); if (pRO) pRO->reorganize_after_object_deletion(); } } }
//--------------------------------------------------------------------------------------- void SystemLayouter::add_initial_line_joining_all_staves_in_system() { //do not draw if 'hide staff lines' option enabled ImoOptionInfo* pOpt = m_pScore->get_option("StaffLines.Hide"); bool fDrawStafflines = (pOpt == NULL || pOpt->get_bool_value() == false); if (!fDrawStafflines) return; //do not draw if empty score with one instrument with one staff if (m_pScore->get_num_instruments() == 1) { ImoInstrument* pInstr = m_pScore->get_instrument(0); if (pInstr->get_num_staves() == 1 && m_pScoreMeter->is_empty_score()) return; } //do not draw if so asked when score meter was created (//TODO: what is this for?) if (m_pScoreMeter->must_draw_left_barline()) { InstrumentEngraver* pInstrEngrv = m_pPartsEngraver->get_engraver_for(0); ImoObj* pCreator = m_pScore->get_instrument(0); LUnits xPos = pInstrEngrv->get_staves_left(); LUnits yTop = pInstrEngrv->get_staves_top_line(); int iInstr = m_pScoreMeter->num_instruments() - 1; pInstrEngrv = m_pPartsEngraver->get_engraver_for(iInstr); LUnits yBottom = pInstrEngrv->get_staves_bottom_line(); BarlineEngraver engrv(m_libraryScope, m_pScoreMeter); Color color = Color(0,0,0); //TODO staff lines color? GmoShape* pLine = engrv.create_system_barline_shape(pCreator, xPos, yTop, yBottom, color); m_pBoxSystem->add_shape(pLine, GmoShape::k_layer_staff); } }
TEST_FIXTURE(MxlCompilerTestFixture, MxlCompilerFromFile_100) { //100 - compile raw xml file format Document doc(m_libraryScope); MxlCompiler compiler(m_libraryScope, &doc); string path = m_scores_path + "50000-hello-world.xml"; ImoObj* pRoot = compiler.compile_file(path); CHECK( compiler.get_file_locator() == path ); ImoDocument* pDoc = dynamic_cast<ImoDocument*>(pRoot); CHECK( pDoc && pDoc->get_version() == "0.0" ); CHECK( pDoc && pDoc->get_num_content_items() == 1 ); ImoScore* pScore = dynamic_cast<ImoScore*>( pDoc->get_content_item(0) ); CHECK( pScore != nullptr ); CHECK( pScore && pScore->get_num_instruments() == 1 ); CHECK( pScore && pScore->get_staffobjs_table() != nullptr ); ImoInstrument* pInstr = pScore->get_instrument(0); CHECK( pInstr != nullptr ); CHECK( pInstr && pInstr->get_num_staves() == 1 ); ImoMusicData* pMD = pInstr->get_musicdata(); CHECK( pMD != nullptr ); CHECK( pMD && pMD->get_num_items() == 5 ); ImoObj* pImo = pMD->get_first_child(); CHECK( pImo && pImo->is_clef() == true ); // cout << "Test: MxlCompilerFromFile_100" << endl; // cout << doc.to_string() << endl; if (pRoot && !pRoot->is_document()) delete pRoot; }
//--------------------------------------------------------------------------------------- void SystemLayouter::add_instruments_info() { int maxInstr = m_pScore->get_num_instruments() - 1; for (int i = 0; i <= maxInstr; i++) { ImoInstrument* pInstr = m_pScore->get_instrument(i); m_pBoxSystem->add_num_staves_for_instrument(pInstr->get_num_staves()); } }
//--------------------------------------------------------------------------------------- ImoObj* Linker::add_staff_info(ImoStaffInfo* pInfo) { if (m_pParent && m_pParent->is_instrument()) { ImoInstrument* pInstr = static_cast<ImoInstrument*>(m_pParent); pInstr->replace_staff_info(pInfo); return NULL; } return pInfo; }
//--------------------------------------------------------------------------------------- ImoObj* Linker::add_midi_info(ImoMidiInfo* pInfo) { if (m_pParent && m_pParent->is_instrument()) { ImoInstrument* pInstr = static_cast<ImoInstrument*>(m_pParent); pInstr->set_midi_info(pInfo); return NULL; } return pInfo; }
//--------------------------------------------------------------------------------------- ImoObj* Linker::add_text(ImoScoreText* pText) { if (m_pParent) { //compatibility with 1.5. Since 1.6 auxObjs can not be included //in musicData; they must go attached to an spacer. if (m_pParent->is_music_data()) { //musicData: create anchor (ImoSpacer) and attach to it ImoSpacer* pSpacer = static_cast<ImoSpacer*>( ImFactory::inject(k_imo_spacer, m_pDoc) ); pSpacer->add_attachment(m_pDoc, pText); add_staffobj(pSpacer); return pText; } //if language not set, use document language if (!pText->has_language()) pText->set_language( m_pDoc->get_language() ); if (m_pParent->is_instrument()) { ImoInstrument* pInstr = static_cast<ImoInstrument*>(m_pParent); //could be 'name' or 'abbrev' if (m_ldpChildType == k_name) pInstr->set_name(pText); else pInstr->set_abbrev(pText); return NULL; } if (m_pParent->is_instr_group()) { ImoInstrGroup* pGrp = static_cast<ImoInstrGroup*>(m_pParent); //could be 'name' or 'abbrev' if (m_ldpChildType == k_name) pGrp->set_name(pText); else pGrp->set_abbrev(pText); return NULL; } if (m_pParent->is_content()) { add_child(k_imo_content, pText); return pText; } return add_attachment(pText); } return pText; }
//--------------------------------------------------------------------------------------- void ScoreMeter::get_staff_spacing(ImoScore* pScore) { int instruments = pScore->get_num_instruments(); m_staffIndex.reserve(instruments); int staves = 0; for (int iInstr=0; iInstr < instruments; ++iInstr) { m_staffIndex[iInstr] = staves; ImoInstrument* pInstr = pScore->get_instrument(iInstr); int numStaves = pInstr->get_num_staves(); staves += numStaves; for (int iStaff=0; iStaff < numStaves; ++iStaff) m_lineSpace.push_back( pInstr->get_line_spacing_for_staff(iStaff) ); } m_numStaves = staves; }
//--------------------------------------------------------------------------------------- wxString IdfyTonalityCtrol::prepare_score(EClef nClef, EKeySignature nKey, ImoScore** pProblemScore) { //delete the previous score if (*pProblemScore) { delete *pProblemScore; *pProblemScore = NULL; } //determine tonic note // 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 6 6 6 6 6 // 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 string notes = "c2d2e2f2g2a2b2c3d3e3f3g3a3b3c4d4e4f4g4a4b4c5d5e5f5g5a5b5c6d6e6f6g6a6b6"; int nRoot = get_step_for_root_note(nKey)* 2 + 14; //note in octave 3 string note[16]; //4 notes per chord if (RandomGenerator::flip_coin()) { //Marcelo Galvez. Tónica en los extremos //I note[0] = notes.substr(nRoot, 2); //I note[1] = notes.substr(nRoot+8, 2); //V note[2] = notes.substr(nRoot+18, 2); //III note[3] = notes.substr(nRoot+28, 2); //I //IV note[4] = notes.substr(nRoot-8, 2); //IV note[5] = notes.substr(nRoot+10, 2); //VI note[6] = notes.substr(nRoot+20, 2); //IV note[7] = notes.substr(nRoot+28, 2); //I //V note[8] = notes.substr(nRoot-6, 2); //V note[9] = notes.substr(nRoot+8, 2); //V note[10] = notes.substr(nRoot+16, 2); //II note[11] = notes.substr(nRoot+26, 2); //VII } else { //Marcelo Galvez. Tónica en los extremos. Opción 2 //I note[0] = notes.substr(nRoot, 2); //I note[1] = notes.substr(nRoot+4, 2); //III note[2] = notes.substr(nRoot+22, 2); //V note[3] = notes.substr(nRoot+28, 2); //I //IV note[4] = notes.substr(nRoot-8, 2); //IV note[5] = notes.substr(nRoot+6, 2); //IV note[6] = notes.substr(nRoot+24, 2); //VI note[7] = notes.substr(nRoot+28, 2); //I //V note[8] = notes.substr(nRoot-6, 2); //V note[9] = notes.substr(nRoot+2, 2); //II note[10] = notes.substr(nRoot+22, 2); //V note[11] = notes.substr(nRoot+26, 2); //VII } //I note[12] = note[0]; //I note[13] = note[1]; //V note[14] = note[2]; //I note[15] = note[3]; //III // //Emilio Mesias // //I // note[0] = notes.substr(nRoot, 2); //I // note[1] = notes.substr(nRoot+8, 2); //V // note[2] = notes.substr(nRoot+14, 2); //I // note[3] = notes.substr(nRoot+18, 2); //III // //IV // note[4] = notes.substr(nRoot-8, 2); //IV // note[5] = notes.substr(nRoot, 2); //I // note[6] = notes.substr(nRoot+6, 2); //IV // note[7] = notes.substr(nRoot+10, 2); //VI // //V // note[8] = notes.substr(nRoot-6, 2); //V // note[9] = notes.substr(nRoot+2, 2); //II // note[10] = notes.substr(nRoot+8, 2); //V // note[11] = notes.substr(nRoot+12, 2); //VII // //I // note[12] = notes.substr(nRoot, 2); //I // note[13] = notes.substr(nRoot+8, 2); //V // note[14] = notes.substr(nRoot+14, 2); //I // note[15] = notes.substr(nRoot+18, 2); //III //create the score string sPattern; *pProblemScore = static_cast<ImoScore*>(ImFactory::inject(k_imo_score, m_pDoc)); (*pProblemScore)->set_long_option("Render.SpacingMethod", long(k_spacing_fixed)); ImoInstrument* pInstr = (*pProblemScore)->add_instrument(); // (g_pMidi->DefaultVoiceChannel(), g_pMidi->DefaultVoiceInstr(), ""); ImoSystemInfo* pInfo = (*pProblemScore)->get_first_system_info(); pInfo->set_top_system_distance( pInstr->tenths_to_logical(30) ); // 3 lines pInstr->add_staff(); //add second staff: five lines, standard size pInstr->add_clef( k_clef_G2, 1 ); pInstr->add_clef( k_clef_F4, 2 ); pInstr->add_key_signature( nKey ); pInstr->add_time_signature(2 ,4); //add A4 note pInstr->add_object("(n =a4 w p1)"); pInstr->add_barline(k_barline_simple); pInstr->add_object("(r w)"); // Loop to add chords int i=0; for (int iC=0; iC < 4; iC++) { pInstr->add_spacer(15); pInstr->add_barline(k_barline_simple); sPattern = "(chord (n " + note[i++] + " w p2)"; sPattern += "(n " + note[i++] + " w p2)"; for (int iN=2; iN < 4; iN++) sPattern += "(n " + note[i++] + " w p1)"; sPattern += ")"; pInstr->add_staff_objects( sPattern ); } pInstr->add_spacer(20); pInstr->add_barline(k_barline_end); (*pProblemScore)->close(); //for generating StaffObjs collection //return key signature name return get_key_signature_name(nKey); }
//--------------------------------------------------------------------------------------- LUnits SystemLayouter::engrave_prolog(int iInstr) { LUnits uPrologWidth = 0.0f; //AWARE when this method is invoked the paper position is at the left marging, //at the start of the new system. LUnits xStartPos = m_pagePos.x; //Save x to align all clefs //iterate over the collection of staff objects to draw current clef and key signature ImoInstrument* pInstr = m_pScore->get_instrument(iInstr); GmoBoxSystem* pBox = get_box_system(); int numStaves = pInstr->get_num_staves(); InstrumentEngraver* pInstrEngrv = m_pPartsEngraver->get_engraver_for(iInstr); for (int iStaff=0; iStaff < numStaves; ++iStaff) { LUnits xPos = xStartPos; m_pagePos.y = pInstrEngrv->get_top_line_of_staff(iStaff); int iStaffIndex = m_pScoreMeter->staff_index(iInstr, iStaff); ColStaffObjsEntry* pClefEntry = m_pSpAlgorithm->get_prolog_clef(m_iFirstCol, iStaffIndex); ColStaffObjsEntry* pKeyEntry = m_pSpAlgorithm->get_prolog_key(m_iFirstCol, iStaffIndex); ImoClef* pClef = pClefEntry ? static_cast<ImoClef*>(pClefEntry->imo_object()) : NULL; int clefType = pClef ? pClef->get_clef_type() : k_clef_undefined; //add clef shape if (pClefEntry) { if (pClef && pClef->is_visible()) { xPos += m_pScoreMeter->tenths_to_logical(LOMSE_SPACE_BEFORE_PROLOG, iInstr, iStaff); m_pagePos.x = xPos; GmoShape* pShape = m_pShapesCreator->create_staffobj_shape(pClef, iInstr, iStaff, m_pagePos, clefType); pShape->assign_id_as_prolog_shape(m_iSystem, iStaff, numStaves); pBox->add_shape(pShape, GmoShape::k_layer_notes); xPos += pShape->get_width(); } } //add key signature shape if (pKeyEntry) { ImoKeySignature* pKey = dynamic_cast<ImoKeySignature*>( pKeyEntry->imo_object() ); if (pKey && pKey->is_visible()) { xPos += m_pScoreMeter->tenths_to_logical(LOMSE_PROLOG_GAP_BEORE_KEY, iInstr, iStaff); m_pagePos.x = xPos; GmoShape* pShape = m_pShapesCreator->create_staffobj_shape(pKey, iInstr, iStaff, m_pagePos, clefType); pShape->assign_id_as_prolog_shape(m_iSystem, iStaff, numStaves); pBox->add_shape(pShape, GmoShape::k_layer_notes); xPos += pShape->get_width(); } } xPos += m_pScoreMeter->tenths_to_logical(LOMSE_SPACE_AFTER_PROLOG, iInstr, iStaff); uPrologWidth = max(uPrologWidth, xPos - xStartPos); } m_pagePos.x = xStartPos; //restore cursor set_prolog_width(uPrologWidth); return uPrologWidth; }
//--------------------------------------------------------------------------------------- wxString IdfyScalesCtrol::prepare_score(EClef nClef, EScaleType nType, ImoScore** pScore) { //create the scale Scale scale(m_fpRootNote, nType, m_nKey); ////dbg------------------------------------------------------ //g_pLogger->LogTrace("IdfyScalesCtrol", "nClef = %d, nType = %d, m_sRootNote='%s', m_nKey=%d", // nClef, nType, m_sRootNote.wx_str(), m_nKey ); ////end dbg------------------------------------------------ //delete the previous score if (*pScore) { delete *pScore; *pScore = NULL; } //create a score with the scale string sPattern; int nNumNotes = scale.get_num_notes(); *pScore = static_cast<ImoScore*>(ImFactory::inject(k_imo_score, m_pDoc)); (*pScore)->set_long_option("Render.SpacingMethod", long(k_spacing_fixed)); //if (nType == est_Chromatic) (*pScore)->set_long_option("Render.SpacingValue", 20L); ImoInstrument* pInstr = (*pScore)->add_instrument(); // (g_pMidi->DefaultVoiceChannel(), g_pMidi->DefaultVoiceInstr(), ""); ImoSystemInfo* pInfo = (*pScore)->get_first_system_info(); pInfo->set_top_system_distance( pInstr->tenths_to_logical(30) ); // 3 lines pInstr->add_clef( k_clef_G2 ); pInstr->add_key_signature( m_nKey ); pInstr->add_time_signature(4 ,4, k_no_visible ); int i = (m_fAscending ? 0 : nNumNotes-1); sPattern = "(n " + scale.rel_ldp_name_for_note(i) + " w)"; pInstr->add_object( sPattern ); pInstr->add_spacer(10); // 1 lines pInstr->add_barline(k_barline_simple, k_no_visible); //so accidentals doesn't affect a 2nd note for (i=1; i < nNumNotes; i++) { sPattern = "(n "; sPattern += scale.rel_ldp_name_for_note((m_fAscending ? i : nNumNotes-1-i)); sPattern += " w)"; // wxLogMessage("[] i=%d, pattern=%s", i, to_wx_string(sPattern).wx_str()); pInstr->add_object( sPattern ); pInstr->add_spacer(10); // 1 lines pInstr->add_barline(k_barline_simple, k_no_visible); //so accidentals doesn't affect a 2nd note } pInstr->add_barline(k_barline_end, k_no_visible); (*pScore)->close(); //(*pScore)->Dump("IdfyScalesCtrol.prepare_score.ScoreDump.txt"); //dbg //set metronome. As the problem score is built using whole notes, we will //set metronome at MM=400 so the resulting note rate will be 100. m_nPlayMM = 400; //return the scale name return scale.get_name(); }