예제 #1
0
//---------------------------------------------------------------------------------------
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();
        }
    }
}
예제 #2
0
//---------------------------------------------------------------------------------------
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);
	}
}
예제 #3
0
    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;
    }
예제 #4
0
//---------------------------------------------------------------------------------------
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());
    }
}
예제 #5
0
//---------------------------------------------------------------------------------------
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;
}
예제 #6
0
//---------------------------------------------------------------------------------------
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;
}
예제 #7
0
//---------------------------------------------------------------------------------------
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;
}
예제 #8
0
//---------------------------------------------------------------------------------------
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;
}
예제 #9
0
//---------------------------------------------------------------------------------------
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);
}
예제 #10
0
//---------------------------------------------------------------------------------------
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;
}
예제 #11
0
//---------------------------------------------------------------------------------------
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();
}