⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 notationgroup.cpp

📁 LINUX下的混音软件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    bool inside = false;    bool found = false;    for (NELIterator i = getInitialNote(); i != getContainer().end(); ++i) {        NotationElement* el = static_cast<NotationElement*>(*i);        if (el->isNote() &&                el->event()->has(BaseProperties::NOTE_TYPE) &&                el->event()->get                <Int>(BaseProperties::NOTE_TYPE) < Note::Crotchet &&                el->event()->has(BaseProperties::BEAMED_GROUP_ID) &&                el->event()->get<Int>(BaseProperties::BEAMED_GROUP_ID) == m_groupNo) {            if (found) return true; // a rest is wholly enclosed by beamed notes            inside = true;        }        if (el->isRest() && inside) found = true;        if (i == getFinalNote()) break;    }    return false;}NotationGroup::BeamNotationGroup::calculateBeam(NotationStaff &staff){    Beam beam;    beam.aboveNotes = !(m_weightAbove > m_weightBelow);    beam.startY = 0;    beam.gradient = 0;    beam.necessary = false;    NELIterator initialNote(getInitialNote()),    finalNote( getFinalNote());    if (initialNote == getContainer().end() ||            initialNote == finalNote) {        return beam; // no notes, or at most one: no case to answer    }    if ((*initialNote)->event()->has(NotationProperties::BEAM_ABOVE)) {        beam.aboveNotes = (*initialNote)->event()->get                          <Bool>                          (NotationProperties::BEAM_ABOVE);    }    timeT crotchet = Note(Note::Crotchet).getDuration();    beam.necessary =        (*initialNote)->getViewDuration() < crotchet        && (*finalNote)->getViewDuration() < crotchet        && (*finalNote)->getViewAbsoluteTime() >        (*initialNote)->getViewAbsoluteTime();    // We continue even if the beam is not necessary, because the    // same data is used to generate the tupling line in tupled    // groups that do not have beams    // if (!beam.necessary) return beam;    NotationChord initialChord(getContainer(), initialNote, &getQuantizer(),                               m_properties, m_clef, m_key),    finalChord(getContainer(), finalNote, &getQuantizer(),               m_properties, m_clef, m_key);    if (initialChord.getInitialElement() == finalChord.getInitialElement()) {        return beam;    }    int initialHeight, finalHeight, extremeHeight;    NELIterator extremeNote;    if (beam.aboveNotes) {        initialHeight = height(initialChord.getHighestNote());        finalHeight = height( finalChord.getHighestNote());        extremeHeight = height( getHighestNote());        extremeNote = getHighestNote();    } else {        initialHeight = height(initialChord.getLowestNote());        finalHeight = height( finalChord.getLowestNote());        extremeHeight = height( getLowestNote());        extremeNote = getLowestNote();    }    int diff = initialHeight - finalHeight;    if (diff < 0)        diff = -diff;    bool linear =        (beam.aboveNotes ?         (extremeHeight <= std::max(initialHeight, finalHeight)) :         (extremeHeight >= std::min(initialHeight, finalHeight)));    if (!linear) {        if (diff > 2)            diff = 1;        else            diff = 0;    }    // Now, we need to judge the height of the beam such that the    // nearest note of the whole group, the nearest note of the first    // chord and the nearest note of the final chord are all at least    // two note-body-heights away from it, and at least one of the    // start and end points is at least the usual note stem-length    // away from it.  This is a straight-line equation y = mx + c,    // where we have m and two x,y pairs and need to find c.    //!!! If we find that making one extreme a sensible distance from    //the note head makes the other extreme way too far away from it    //in the direction of the gradient, then we should flatten the    //gradient.  There may be a better heuristic for this.    int initialX = (int)(*initialNote)->getLayoutX();    int finalDX = (int) (*finalNote)->getLayoutX() - initialX;    int extremeDX = (int)(*extremeNote)->getLayoutX() - initialX;    int spacing = staff.getNotePixmapFactory(m_type == Grace).getLineSpacing();    beam.gradient = 0;    if (finalDX > 0) {        do {            if (diff == 0)                break;            else if (diff > 3)                diff = 3;            else                --diff;            beam.gradient = (diff * spacing * 100) / (finalDX * 2);        } while (beam.gradient > 18);    } else {        beam.gradient = 0;    }    if (initialHeight < finalHeight)        beam.gradient = -beam.gradient;    int finalY = staff.getLayoutYForHeight(finalHeight);    int extremeY = staff.getLayoutYForHeight(extremeHeight);    int c0 = staff.getLayoutYForHeight(initialHeight), c1, c2;    double dgrad = (double)beam.gradient / 100.0;    Equation::solve(Equation::C, extremeY, dgrad, extremeDX, c1);    Equation::solve(Equation::C, finalY, dgrad, finalDX, c2);    using std::max;    using std::min;    long shortestNoteType = Note::Quaver;    if (!(*getShortestElement())->event()->get            <Int>(BaseProperties::NOTE_TYPE,                  shortestNoteType)) {        NOTATION_DEBUG << "NotationGroup::calculateBeam: WARNING: Shortest element has no note-type; should this be possible?" << endl;        NOTATION_DEBUG << "(Event dump follows)" << endl;        (*getShortestElement())->event()->dump(std::cerr);    }    // minimal stem lengths at start, middle-extreme and end of beam    int sl = staff.getNotePixmapFactory(m_type == Grace).getStemLength();    int ml = spacing * 2;    int el = sl;    NOTATION_DEBUG << "c0: " << c0 << ", c1: " << c1 << ", c2: " << c2 << endl;    NOTATION_DEBUG << "sl: " << sl << ", ml: " << ml << ", el: " << el << endl;    // If the stems are down, we will need to ensure they end at    // heights lower than 0 if there's an internal rest -- likewise    // with stems up and an internal rest we need to ensure they end    // at higher than 8.    // [Avoid doing expensive haveInternalRest() test where possible]    if (beam.aboveNotes) {        int topY = staff.getLayoutYForHeight(8);        if ((c0 - sl > topY) || (c1 - ml > topY) || (c2 - el > topY)) {            if (haveInternalRest()) {                if (c0 - sl > topY)                    sl = c0 - topY;                if (c1 - ml > topY)                    ml = c1 - topY;                if (c2 - el > topY)                    el = c2 - topY;                NOTATION_DEBUG << "made internal rest adjustment for above notes" << endl;                NOTATION_DEBUG << "sl: " << sl << ", ml: " << ml << ", el: " << el << endl;            }        }    } else {        int bottomY = staff.getLayoutYForHeight(0);        if ((c0 + sl < bottomY) || (c1 + ml < bottomY) || (c2 + el < bottomY)) {            if (haveInternalRest()) {                if (c0 + sl < bottomY)                    sl = bottomY - c0;                if (c1 + ml < bottomY)                    ml = bottomY - c1;                if (c2 + el < bottomY)                    el = bottomY - c2;                NOTATION_DEBUG << "made internal rest adjustment for below notes" << endl;                NOTATION_DEBUG << "sl: " << sl << ", ml: " << ml << ", el: " << el << endl;            }        }    }    if (shortestNoteType < Note::Semiquaver) {        int off = spacing * (Note::Semiquaver - shortestNoteType);        sl += off;        el += off;    }    if (shortestNoteType < Note::Quaver) {        int off = spacing * (Note::Quaver - shortestNoteType);        ml += off;    }    int midY = staff.getLayoutYForHeight(4);    // ensure extended to middle line if necessary, and assign suitable stem length    if (beam.aboveNotes) {        if (c0 - sl > midY)            sl = c0 - midY;        if (c1 - ml > midY)            ml = c1 - midY;        if (c2 - el > midY)            el = c2 - midY;        if (extremeDX > 1.0 || extremeDX < -1.0) {            //	    beam.gradient = int(100 * double(c2 - c0) / double(extremeDX));        }        beam.startY = min(min(c0 - sl, c1 - ml), c2 - el);    } else {        if (c0 + sl < midY)            sl = midY - c0;        if (c1 + ml < midY)            ml = midY - c1;        if (c2 + el < midY)            el = midY - c2;        if (extremeDX > 1.0 || extremeDX < -1.0) {            //	    beam.gradient = int(100 * double(c2 - c0) / double(extremeDX));        }        beam.startY = max(max(c0 + sl, c1 + ml), c2 + el);    }    /*        NOTATION_DEBUG << "NotationGroup::calculateBeam: beam data:" << endl    		   << "gradient: " << beam.gradient << endl    		   << "(c0 " << c0 << ", c2 " << c2 << ", extremeDX " << extremeDX << ")" << endl    		   << "startY: " << beam.startY << endl    		   << "aboveNotes: " << beam.aboveNotes << endl    		   << "shortestNoteType: " << shortestNoteType << endl    		   << "necessary: " << beam.necessary << endl;    */     return beam;}voidNotationGroup::applyBeam(NotationStaff &staff){    //    NOTATION_DEBUG << "NotationGroup::applyBeam, group no is " << m_groupNo << endl;    /*        NOTATION_DEBUG << "\nNotationGroup::applyBeam" << endl;        NOTATION_DEBUG << "Group id: " << m_groupNo << ", type " << m_type << endl;        NOTATION_DEBUG << "Coverage:" << endl;        int i = 0;        for (NELIterator i = getInitialElement(); i != getContainer().end(); ++i) {    	(*i)->event()->dump(cerr);    	if (i == getFinalElement()) break;        }        {    	NELIterator i(getInitialNote());    	NOTATION_DEBUG << "Initial note: " << (i == getContainer().end() ? -1 : (*i)->event()->getAbsoluteTime()) << endl;        }        {    	NELIterator i(getFinalNote());    	NOTATION_DEBUG << "Final note: " << (i == getContainer().end() ? -1 : (*i)->event()->getAbsoluteTime()) << endl;        }        {    	NELIterator i(getHighestNote());    	NOTATION_DEBUG << "Highest note: " << (i == getContainer().end() ? -1 : (*i)->event()->getAbsoluteTime()) << endl;        }        {    	NELIterator i(getLowestNote());    	NOTATION_DEBUG << "Lowest note: " << (i == getContainer().end() ? -1 : (*i)->event()->getAbsoluteTime()) << endl;        }    */    Beam beam(calculateBeam(staff));    if (!beam.necessary) {        for (NELIterator i = getInitialNote(); i != getContainer().end(); ++i) {            (*i)->event()->unset(NotationProperties::BEAMED);            (*i)->event()->unset(m_properties.TUPLING_LINE_MY_Y);            if (i == getFinalNote())                break;        }        return ;    }    //    NOTATION_DEBUG << "NotationGroup::applyBeam: Beam is necessary" << endl;    NELIterator initialNote(getInitialNote()),    finalNote( getFinalNote());    int initialX = (int)(*initialNote)->getLayoutX();    timeT finalTime = (*finalNote)->getViewAbsoluteTime();    // For each chord in the group, we nominate the note head furthest    // from the beam as the primary note, the one that "owns" the stem    // and the section of beam up to the following chord.  For this    // note, we need to:    //    // * Set the start height, start x-coord and gradient of the beam    //   (we can't set the stem length for this note directly, because    //   we don't know its y-coordinate yet)    //    // * Set width of this section of beam    //    // * Set the number of beams required for the following note (one    //   slight complication here: a beamed group in which the very    //   first chord is shorter than the following one.  Here the first    //   chord needs to know it's the first, or else it can't draw the    //   part-beams immediately to its right correctly.)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -