Exemplo n.º 1
0
TEST(TestMeiElement, GetPositionInDocument) {
    MeiElement* m = new MeiElement("mei");
    MeiElement *m1 = new MeiElement("music");
    string musicId = m1->getId();
    MeiElement *b1 = new MeiElement("body");
    MeiElement *s1 = new MeiElement("staff");
    MeiElement *n1 = new MeiElement("note");
    string nId = n1->getId();
    MeiElement *n2 = new MeiElement("note");
    MeiElement *n3 = new MeiElement("note");
    MeiElement *n4 = new MeiElement("note");    
    string n4Id = n4->getId();
    
    m->addChild(m1);
    m1->addChild(b1);
    b1->addChild(s1);
    s1->addChild(n1);
    s1->addChild(n2);
    s1->addChild(n3);
    
    MeiDocument* doc = new MeiDocument();
    doc->setRootElement(m);
    
    ASSERT_EQ(4, n1->getPositionInDocument());
    ASSERT_EQ(-1, n4->getPositionInDocument());
    
}
Exemplo n.º 2
0
TEST(TestMeiElement, TestAddChildWithParent) {
    MeiElement *p = new MeiElement("note");
    MeiElement *c1 = new Accid();
    
    p->addChild(c1);
    ASSERT_EQ(p, c1->getParent());
}
Exemplo n.º 3
0
TEST(TestMeiElement, TestPrintElement) {
    MeiElement *m = new MeiElement("mei");
    MeiElement *music = new MeiElement("music");
    MeiElement *body = new MeiElement("body");
    MeiElement *staff = new MeiElement("staff");
    Note *note = new Note();
    Note *note2 = new Note();
    
    MeiDocument *doc = new MeiDocument();
    doc->setRootElement(m);
    
    m->addChild(music);
    music->addChild(body);
    body->addChild(staff);
    staff->addChild(note);
    staff->addChild(note2);
    
    note->m_NoteVis.setHeadshape("diamond");
    note->m_Pitch.setPname("c");

    note2->m_Pitch.setPname("d");
    
    m->printElement();
    
    /* 
        The printElement method does not return anything, so the value of it can't really be tested.
        This test simply ensures that it is capable of being called without failing. 
        So we just assert that everything's OK here if we haven't segfaulted by now.
    */
    ASSERT_TRUE(true);
}
Exemplo n.º 4
0
TEST(TestMeiElement, TestAddAttributeByStrings) {
    MeiElement *p = new MeiElement("note");
    p->addAttribute("pname", "c");
    
    ASSERT_TRUE(p->hasAttribute("pname"));
    ASSERT_EQ("c", p->getAttribute("pname")->getValue());
}
Exemplo n.º 5
0
TEST(CmnModuleTest, TestTieMembership) {
    MeiDocument* doc = createMeiDocument();

    MeiElement* layer = doc->getElementById("id-layer");
    MeiElement* measure = doc->getElementById("id-measure");

    Note* n1 = new Note();
    Note* n2 = new Note();
    Note* n3 = new Note();
    Note* n4 = new Note();

    layer->addChild(n1);
    layer->addChild(n2);
    layer->addChild(n3);
    layer->addChild(n4);

    Tie* t1 = new Tie();
    measure->addChild(t1);

    t1->m_Startid.setStartid(n1->getId());
    t1->m_Startendid.setEndid(n4->getId());
    t1->m_Staffident.setStaff("staffname");
    
    vector<MeiElement*> members = t1->getMembers();
    ASSERT_EQ(4, members.size());
}
Exemplo n.º 6
0
TEST(TestMeiElement, TestSetDocument) {
    MeiElement *m = new MeiElement("mei");
    MeiDocument *doc = new MeiDocument();
    
    ASSERT_THROW(m->setDocument(doc), mei::DocumentRootNotSetException);
    
    doc->setRootElement(m);
    ASSERT_EQ(doc->getRootElement(), m);
}
Exemplo n.º 7
0
// If we get a pointer to an attribute, we can change it
TEST(TestMeiElement, TestChangeAttributeValue) {
    MeiElement *p = new MeiElement("note");
    MeiAttribute *attr1 = new MeiAttribute("pname", "c");
    p->addAttribute(attr1);
    
    vector<MeiAttribute*> atts = p->getAttributes();
    atts[0]->setValue("d");
    ASSERT_EQ("d", p->getAttribute("pname")->getValue());
}
Exemplo n.º 8
0
TEST(TestMeiDocument, SetsDefaultNamespace) {
    MeiDocument *doc = new MeiDocument();
    MeiElement *root = new MeiElement("mei");
    
    doc->setRootElement(root);
    
    ASSERT_TRUE(root->hasAttribute("xmlns"));
    ASSERT_EQ(root->getAttribute("xmlns")->getValue(), MEI_NS);
}
Exemplo n.º 9
0
TEST(TestMeiElement, TestRemoveAttribute) {
    MeiElement *p = new MeiElement("note");
    MeiAttribute *attr1 = new MeiAttribute("pname", "c");

    p->addAttribute(attr1);
    ASSERT_TRUE(p->hasAttribute("pname"));

    p->removeAttribute("pname");
    ASSERT_FALSE(p->hasAttribute("pname"));
}
Exemplo n.º 10
0
TEST(TestMeiElement, TestGetChildrenByName) {
    MeiElement *p = new MeiElement("note");
    MeiElement *c1 = new Accid();
    MeiElement *c2 = new Accid();
    MeiElement *c3 = new Note();
    vector<MeiElement*> chn;
    chn.push_back(c1);
    chn.push_back(c2);
    chn.push_back(c3);
    p->setChildren(chn);
    ASSERT_EQ(3, p->getChildren().size());
    vector<MeiElement*> get = p->getChildrenByName("accid");
    ASSERT_EQ(2, get.size());  
}
Exemplo n.º 11
0
TEST(TestMeiElement, TestConstGetChildren) {
    MeiElement *p = new MeiElement("note");
    MeiElement *c2 = new Accid();
    MeiElement *c3 = new Note();
    vector<MeiElement*> chn;
    chn.push_back(c2);
    chn.push_back(c3);
    p->setChildren(chn);

    vector<MeiElement*> get = p->getChildren();
    // Can't add a new element to the vector
    get.push_back(new mei::Artic());
    ASSERT_EQ(2, p->getChildren().size());
}
Exemplo n.º 12
0
TEST(TestMeiElement, TestConstGetAttributes) {
    MeiElement *p = new MeiElement("note");
    MeiAttribute *attr1 = new MeiAttribute("pname", "c");
    MeiAttribute *attr2 = new MeiAttribute("oct", "4");    
    
    p->addAttribute(attr1);
    p->addAttribute(attr2);
    
    vector<MeiAttribute*> atts = p->getAttributes();
    ASSERT_EQ(2, atts.size());
    
    // Adding to the returned vector doesn't affect the element
    atts.push_back(new MeiAttribute("stem.dir", "up"));
    ASSERT_EQ(2, p->getAttributes().size());
}
Exemplo n.º 13
0
TEST(TestMeiElement, TestDeleteChildren) {
    MeiElement *p = new MeiElement("note");
    MeiElement *c1 = new Accid();
    MeiElement *c2 = new Accid();
    MeiElement *c3 = new Note();
    vector<MeiElement*> chn;
    chn.push_back(c1);
    chn.push_back(c2);
    chn.push_back(c3);
    p->setChildren(chn);
    
    ASSERT_EQ(3, p->getChildren().size());
    p->deleteAllChildren();
    ASSERT_EQ(0, p->getChildren().size());
}
Exemplo n.º 14
0
// Adding an attribute to an element sets the attr's element.
TEST(TestMeiElement, TestAttributeLink) {
    MeiElement *p = new MeiElement("note");
    MeiAttribute *a = new MeiAttribute("pname", "c");
    p->addAttribute(a);
    ASSERT_EQ(p, a->getElement());

    // And when adding many attrs
    MeiAttribute *b = new MeiAttribute("pname", "d");
    MeiAttribute *c = new MeiAttribute("stem.dir", "down");
    vector<MeiAttribute*> atts;
    atts.push_back(b);
    atts.push_back(c);
    p->setAttributes(atts);
    ASSERT_EQ(2, p->getAttributes().size());
    ASSERT_EQ(p, b->getElement());
    ASSERT_EQ(p, c->getElement());
}
Exemplo n.º 15
0
TEST(TestMeiElement, TestLookBack) {
    MeiElement *m = new MeiElement("mei");
    MeiElement *music = new MeiElement("music");
    MeiElement *body = new MeiElement("body");
    MeiElement *staff = new MeiElement("staff");
    MeiElement *note = new MeiElement("note");
    
    MeiDocument *doc = new MeiDocument();
    doc->setRootElement(m);

    m->addChild(music);
    music->addChild(body);
    body->addChild(staff);
    staff->addChild(note);

    ASSERT_EQ(music->lookBack("mei"), m);
    ASSERT_EQ(staff->lookBack("mei"), m);
}
Exemplo n.º 16
0
TEST(TestMeiElement, TestGetSetParent) {
    MeiElement *s = new Staff();
    MeiElement *n = new Note();
    ASSERT_EQ(NULL, n->getParent());
    ASSERT_FALSE(s->hasParent());
    
    n->setParent(s);
    ASSERT_EQ(n->getParent()->getName(), "staff");
    
    MeiElement *ns = new Layer();
    n->setParent(ns);
    ASSERT_EQ(n->getParent()->getName(), "layer");
}
Exemplo n.º 17
0
TEST(TestMeiElement, TestRemoveChild) {
    MeiElement *p = new MeiElement("note");
    MeiElement *c1 = new Accid();

    p->addChild(c1);
    ASSERT_TRUE(p->hasChildren("accid"));
    ASSERT_EQ(1, p->getChildren().size());

    p->removeChild(c1);
    ASSERT_FALSE(p->hasChildren("accid"));
    ASSERT_EQ(0, p->getChildren().size());
}
Exemplo n.º 18
0
TEST(TestMeiElement, TestAddChild) {
    MeiElement *p = new MeiElement("note");
    MeiElement *c1 = new Accid();
    c1->addAttribute(new MeiAttribute("x", "y"));
    MeiElement *c2 = new Accid();

    ASSERT_EQ(0, p->getChildren().size());

    p->addChild(c1);
    ASSERT_TRUE(p->hasChildren("accid"));
    ASSERT_EQ(1, p->getChildren().size());

    p->addChild(c2);
    ASSERT_TRUE(p->hasChildren("accid"));
    ASSERT_EQ(2, p->getChildren().size());
}
Exemplo n.º 19
0
TEST(TestMeiElement, TestChangeChildValue) {
    MeiElement *p = new MeiElement("note");
    MeiElement *c = new Note();
    c->addAttribute(new MeiAttribute("pname", "c"));
    p->addChild(c);
    vector<MeiElement*> get = p->getChildren();
    get[0]->getAttribute("pname")->setValue("d");
    ASSERT_EQ("d", p->getChildren()[0]->getAttribute("pname")->getValue());
}
Exemplo n.º 20
0
TEST(TestMeiElement, TestHasChildren) {
    MeiElement *p = new Note();
    ASSERT_FALSE(p->hasChildren());
    
    p->addChild(new Accid());
    ASSERT_TRUE(p->hasChildren("accid"));
    ASSERT_TRUE(p->hasChildren());
    ASSERT_FALSE(p->hasChildren("artic"));
}
Exemplo n.º 21
0
TEST(TestMeiElement, TestRemoveManyChildren) {
    MeiDocument *doc = new MeiDocument();
    MeiElement *mei = new MeiElement("mei");
    MeiElement *sd1 = new MeiElement("staffDef");
    MeiElement *sd2 = new MeiElement("staffDef");
    MeiElement *sd3 = new MeiElement("staffDef");
    MeiElement *sd4 = new MeiElement("staffDef");
    MeiElement *sd5 = new MeiElement("staffDef");
    MeiElement *sd6 = new MeiElement("staffDef");
    
    doc->setRootElement(mei);
    
    MeiElement *music = new mei::MeiElement("music");
    MeiElement *scoreDef = new mei::MeiElement("scoreDef");
    
    mei->addChild(music);
    music->addChild(scoreDef);
    scoreDef->addChild(sd1);
    scoreDef->addChild(sd2);
    scoreDef->addChild(sd3);
    scoreDef->addChild(sd4);
    scoreDef->addChild(sd5);
    scoreDef->addChild(sd6);
    
    sd1->addAttribute("n", "1");
    sd2->addAttribute("n", "2");
    sd3->addAttribute("n", "3");
    sd4->addAttribute("n", "4");
    sd5->addAttribute("n", "5");
    sd6->addAttribute("n", "6");
    
    vector<MeiElement*> scoreDefs = doc->getRootElement()->getDescendantsByName("scoreDef");
    vector<MeiElement*> staffDefs = doc->getRootElement()->getDescendantsByName("staffDef");
    
    for (vector<MeiElement*>::iterator iter = staffDefs.begin(); iter != staffDefs.end(); ++iter) {
        if ((*iter)->getAttribute("n")->getValue() == "3" || (*iter)->getAttribute("n")->getValue() == "6") {
            (*iter)->getParent()->removeChild((*iter));
        }
    }
    ASSERT_EQ(4, music->getDescendantsByName("staffDef").size());
    
}
Exemplo n.º 22
0
TEST(TestMeiElement, TestGetSet) {
    MeiElement *p = new MeiElement("p");
    p->setValue("this is a sentence");
    ASSERT_EQ("this is a sentence", p->getValue());

    p->setTail("atail");

    // We know an id is 'm-<uuid>', so we can check the length
    ASSERT_EQ(38, p->getId().length());
    ASSERT_EQ("atail", p->getTail());
}
Exemplo n.º 23
0
TEST(TestMeiElement, TestAddAttribute) {
    MeiElement *p = new MeiElement("note");
    MeiAttribute *attr1 = new MeiAttribute("pname", "c");
    MeiAttribute *attr2 = new MeiAttribute("pname", "d");

    p->addAttribute(attr1);
    ASSERT_TRUE(p->hasAttribute("pname"));
    ASSERT_EQ("c", p->getAttribute("pname")->getValue());
    // Adding the same named attribute replaces it
    p->addAttribute(attr2);
    ASSERT_EQ("d", p->getAttribute("pname")->getValue());
}
Exemplo n.º 24
0
TEST(TestMeiElement, TestRemoveChildByName) {
    MeiElement *p = new MeiElement("note");
    MeiElement *c1 = new Accid();
    MeiElement *c2 = new Accid();
    MeiElement *c3 = new Note();

    vector<MeiElement*> chn;
    chn.push_back(c1);
    chn.push_back(c2);
    chn.push_back(c3);

    p->setChildren(chn);
    ASSERT_TRUE(p->hasChildren("accid"));
    ASSERT_EQ(3, p->getChildren().size());
    p->removeChildrenByName("accid");

    ASSERT_EQ(1, p->getChildren().size());
    ASSERT_FALSE(p->hasChildren("accid"));
    ASSERT_TRUE(p->hasChildren("note"));
}
Exemplo n.º 25
0
TEST(TestMeiElement, TestSetChildren) {
    MeiElement *p = new Note();
    MeiElement *ch1 = new Accid();
    MeiElement *ch2 = new mei::Dot();
    MeiElement *ch3 = new mei::Artic();
    
    p->addChild(ch1);
    ASSERT_EQ(1, p->getChildren().size());
    
    vector<MeiElement*> children;
    children.push_back(ch2);
    children.push_back(ch3);
    p->setChildren(children);
    ASSERT_EQ(2, p->getChildren().size());
    // Can't affect children by changing the initial vector
    children.push_back(new Accid());
    ASSERT_EQ(2, p->getChildren().size());
    
    p->addChild(ch1);
    ASSERT_EQ(3, p->getChildren().size());
}
Exemplo n.º 26
0
TEST(TestMeiElement, TestGetSetHasAttributes) {
    MeiElement *p = new MeiElement("note");

    MeiAttribute *attr1 = new MeiAttribute("pname", "c");
    MeiAttribute *attr2 = new MeiAttribute("stem.dir", "down");

    vector<MeiAttribute*> attrs;
    attrs.push_back(attr1);
    attrs.push_back(attr2);
    p->setAttributes(attrs);

    ASSERT_EQ(2, p->getAttributes().size());
    ASSERT_TRUE(p->hasAttribute("pname"));
    ASSERT_TRUE(p->hasAttribute("stem.dir"));
    ASSERT_EQ("c", p->getAttribute("pname")->getValue());
    
    // Adding a new attribute to the initial list doesn't
    // affect the attributes in the element
    attrs.push_back(new MeiAttribute("oct", "4"));
    ASSERT_EQ(2, p->getAttributes().size());
}
Exemplo n.º 27
0
TEST(TestMeiElement, TestMeiElementEquality) {
    MeiElement *p = new MeiElement("one");
    MeiElement *q = new MeiElement("two");
    MeiElement *r = new MeiElement(*p);
    MeiElement *s = new MeiElement(*p);
    
    // two elements with the same name and the same ID
    string pId = p->getId();
    r->setId(pId);
    ASSERT_EQ(*p, *r);

    // two elements with different names and the same ID
    q->setId(pId);
    ASSERT_NE(*p, *q);
    
    // two elements with the same name and different IDs
    ASSERT_NE(*p, *s);
}
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;
}
Exemplo n.º 29
0
TEST(TestMeiElement, TestGetNoAttribute) {
    MeiElement *p = new MeiElement("note");
    ASSERT_EQ(NULL, p->getAttribute("color"));
}
Exemplo n.º 30
0
TEST(TestMeiElement, TestConstructor) {
    MeiElement *m = new MeiElement("note");
    ASSERT_EQ("note", m->getName());
}