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

📄 lilypondexporter.cpp

📁 LINUX下的混音软件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                break;        }        // First tempo change may be before the first segment.        // Do not apply it before the first segment appears.        if (prevTempoChangeTime < compositionStartTime) {            prevTempoChangeTime = compositionStartTime;        }        writeSkip(m_composition->getTimeSignatureAt(prevTempoChangeTime),                  prevTempoChangeTime, compositionEndTime - prevTempoChangeTime, false, str);        str << std::endl;        str << indent(--col) << "}" << std::endl;    }    // open \score section    str << "\\score {" << std::endl;    // bind staffs with or without staff group bracket    str << indent(++col) // indent+	<< (m_exportStaffGroup == true ? "\\new StaffGroup " : "")	<< "<<" << std::endl;    // Make chords offset colliding notes by default    str << indent(++col) << "% force offset of colliding notes in chords:" << std::endl;    str << indent(col)    << "\\override Score.NoteColumn #\'force-hshift = #1.0" << std::endl;    int lastTrackIndex = -1;    int voiceCounter = 0;    // Write out all segments for each Track, in track order.    // This involves a hell of a lot of loops through all tracks    // and segments, but the time spent doing that should still    // be relatively small in the greater scheme.    Track *track = 0;    for (int trackPos = 0;            (track = m_composition->getTrackByPosition(trackPos)) != 0; ++trackPos) {        for (Composition::iterator i = m_composition->begin();                i != m_composition->end(); ++i) {            if ((*i)->getTrack() != track->getId())                continue;            emit setProgress(int(double(trackPos) /                                 double(m_composition->getNbTracks()) * 100.0));            rgapp->refreshGUI(50);                        bool currentSegmentSelected = false;            if ((m_exportSelection == EXPORT_SELECTED_SEGMENTS) && 		(m_view != NULL) && (m_view->haveSelection())) {            	//            	// Check whether the current segment is in the list of selected segments.            	//            	SegmentSelection selection = m_view->getSelection();                for (SegmentSelection::iterator it = selection.begin(); it != selection.end(); it++) {                    if ((*it) == (*i)) currentSegmentSelected = true;                }            } else if ((m_exportSelection == EXPORT_SELECTED_SEGMENTS) && (m_notationView != NULL)) {		currentSegmentSelected = m_notationView->hasSegment(*i);	    }	    // Check whether the track is a non-midi track.	    InstrumentId instrumentId = track->getInstrument();	    // very off the cuff tentative fix for #1836149; this is so obvious	    // a fix that I wonder why this <SoftSynthInstrumentBase was ever	    // written in the first place, and it makes me suspicous that I'm	    // missing the big picture somewhere.  Anyway, it seems to work:	    //bool isMidiTrack = (instrumentId >= MidiInstrumentBase && instrumentId) < SoftSynthInstrumentBase);	    bool isMidiTrack = instrumentId >= MidiInstrumentBase;                if (isMidiTrack && ( // Skip non-midi tracks.		(m_exportSelection == EXPORT_ALL_TRACKS) ||                 ((m_exportSelection == EXPORT_NONMUTED_TRACKS) && (!track->isMuted())) ||                ((m_exportSelection == EXPORT_SELECTED_TRACK) && (m_view != NULL) && (track->getId() == m_composition->getSelectedTrack())) ||                ((m_exportSelection == EXPORT_SELECTED_TRACK) && (m_notationView != NULL) && (track->getId() == m_notationView->getCurrentSegment()->getTrack())) ||                ((m_exportSelection == EXPORT_SELECTED_SEGMENTS) && (currentSegmentSelected)))) {                if ((int) (*i)->getTrack() != lastTrackIndex) {                    if (lastTrackIndex != -1) {                        // close the old track (Staff context)                        str << indent(--col) << ">> % Staff" << std::endl;  // indent-                    }                    lastTrackIndex = (*i)->getTrack();                    // avoid problem with <untitled> tracks yielding a                    // .ly file that jumbles all notes together on a                    // single staff...  every Staff context has to                    // have a unique name, even if the                    // Staff.instrument property is the same for                    // multiple staffs...                    // Added an option to merge staffs with the same, non-empty                    // name. This option makes it possible to produce staffs                    // with polyphonic, and polyrhytmic, music. Polyrhytmic                    // music in a single staff is typical in piano, or                    // guitar music. (hjj)                    // In the case of colliding note heads, user may define                    //  - DISPLACED_X -- for a note/chord                    //  - INVISIBLE -- for a rest                    std::ostringstream staffName;                    staffName << protectIllegalChars(m_composition->                                                     getTrackById(lastTrackIndex)->getLabel());                    if (!m_exportStaffMerge || staffName.str() == "") {                        str << std::endl << indent(col)                        << "\\context Staff = \"track "                        << (trackPos + 1) << "\" ";                    } else {                        str << std::endl << indent(col)                        << "\\context Staff = \"" << staffName.str()                        << "\" ";                    }                    str << "<< " << std::endl;		    // The octavation is omitted in the instrument name.		    // HJJ: Should it be automatically added to the clef: G^8 ?		    // What if two segments have different transpose in a track?                    std::ostringstream staffNameWithTranspose;		    staffNameWithTranspose << "\\markup { \\column { \"" << staffName.str() << " \"";		    if (((*i)->getTranspose() % 12) != 0) {			staffNameWithTranspose << " \\line { ";			switch ((*i)->getTranspose() % 12) {			case 1 : staffNameWithTranspose << "\"in D\" \\smaller \\flat"; break;			case 2 : staffNameWithTranspose << "\"in D\""; break;			case 3 : staffNameWithTranspose << "\"in E\" \\smaller \\flat"; break;			case 4 : staffNameWithTranspose << "\"in E\""; break;			case 5 : staffNameWithTranspose << "\"in F\""; break;			case 6 : staffNameWithTranspose << "\"in G\" \\smaller \\flat"; break;			case 7 : staffNameWithTranspose << "\"in G\""; break;			case 8 : staffNameWithTranspose << "\"in A\" \\smaller \\flat"; break;			case 9 : staffNameWithTranspose << "\"in A\""; break;			case 10 : staffNameWithTranspose << "\"in B\" \\smaller \\flat"; break;			case 11 : staffNameWithTranspose << "\"in B\""; break;			}			staffNameWithTranspose << " }";		    }		    staffNameWithTranspose << " } }";		    if (m_languageLevel < LILYPOND_VERSION_2_10) {			str << indent(++col) << "\\set Staff.instrument = " << staffNameWithTranspose.str() << std::endl;		    } else {			str << indent(++col) << "\\set Staff.instrumentName = " << staffNameWithTranspose.str() << std::endl;		    }                    if (m_exportMidi) {                        // Set midi instrument for the Staff                        std::ostringstream staffMidiName;                        Instrument *instr = m_studio->getInstrumentById(m_composition->getTrackById(lastTrackIndex)->getInstrument());                        staffMidiName << instr->getProgramName();                        str << indent(col) << "\\set Staff.midiInstrument = \"" << staffMidiName.str() << "\"" << std::endl;                    }		    // multi measure rests are used by default                    str << indent(col) << "\\set Score.skipBars = ##t" << std::endl;                    // turn off the stupid accidental cancelling business,                    // because we don't do that ourselves, and because my 11                    // year old son pointed out to me that it "Looks really                    // stupid.  Why is it cancelling out four flats and then                    // adding five flats back?  That's brain damaged."                    str << indent(col) << "\\set Staff.printKeyCancellation = ##f" << std::endl;                    str << indent(col) << "\\new Voice \\global" << std::endl;                    if (tempoCount > 0) {                        str << indent(col) << "\\new Voice \\globalTempo" << std::endl;                    }                }                // Temporary storage for non-atomic events (!BOOM)                // ex. Lilypond expects signals when a decrescendo starts                // as well as when it ends                eventendlist eventsInProgress;                eventstartlist eventsToStart;                // If the segment doesn't start at 0, add a "skip" to the start                // No worries about overlapping segments, because Voices can overlap                // voiceCounter is a hack because Lilypond does not by default make                // them unique                std::ostringstream voiceNumber;                voiceNumber << "voice " << ++voiceCounter;                str << std::endl << indent(col++) << "\\context Voice = \"" << voiceNumber.str()                << "\" {"; // indent+                str << std::endl << indent(col) << "\\override Voice.TextScript #'padding = #2.0";                str << std::endl << indent(col) << "\\override MultiMeasureRest #'expand-limit = 1" << std::endl;                SegmentNotationHelper helper(**i);                helper.setNotationProperties();                int firstBar = m_composition->getBarNumber((*i)->getStartTime());                if (firstBar > 0) {                    // Add a skip for the duration until the start of the first                    // bar in the segment.  If the segment doesn't start on a bar                    // line, an additional skip will be written (in the form of                    // a series of rests) at the start of writeBar, below.                    //!!! This doesn't cope correctly yet with time signature changes                    // during this skipped section.                    str << std::endl << indent(col);                    writeSkip(timeSignature, compositionStartTime, m_composition->getBarStart(firstBar) - compositionStartTime,                              false, str);                }                std::string lilyText = "";      // text events                std::string prevStyle = "";     // track note styles                Rosegarden::Key key;                bool haveRepeating = false;                bool haveAlternates = false;                bool nextBarIsAlt1 = false;                bool nextBarIsAlt2 = false;                bool prevBarWasAlt2 = false;                int MultiMeasureRestCount = 0;                bool nextBarIsDouble = false;                bool nextBarIsEnd = false;                bool nextBarIsDot = false;                for (int barNo = m_composition->getBarNumber((*i)->getStartTime());                        barNo <= m_composition->getBarNumber((*i)->getEndMarkerTime());                        ++barNo) {                    timeT barStart = m_composition->getBarStart(barNo);                    timeT barEnd = m_composition->getBarEnd(barNo);                    if (barStart < compositionStartTime) {                        barStart = compositionStartTime;                    }                    // open \repeat section if this is the first bar in the                    // repeat                    if ((*i)->isRepeating() && !haveRepeating) {                        haveRepeating = true;                        //!!! calculate the number of times this segment                        //repeats and make the following variable meaningful                        int numRepeats = 2;                        str << std::endl << indent(col++) << "\\repeat volta " << numRepeats << " {";                    }                    // open the \alternative section if this bar is alternative ending 1                    // ending (because there was an "Alt1" flag in the                    // previous bar to the left of where we are right now)                    //                    // Alt1 remains in effect until we run into Alt2, which                    // runs to the end of the segment                    if (nextBarIsAlt1 && haveRepeating) {                        str << std::endl << indent(--col) << "} \% repeat close (before alternatives) ";                        str << std::endl << indent(col++) << "\\alternative {";                        str << std::endl << indent(col++) << "{  \% open alternative 1 ";                        nextBarIsAlt1 = false;                        haveAlternates = true;                    } else if (nextBarIsAlt2 && haveRepeating) {                        if (!prevBarWasAlt2) {                            col--;                            str << std::endl << indent(--col) << "} \% close alternative 1 "                            << std::endl << indent(col++) << "{  \% open alternative 2";                            col++;                        }                        prevBarWasAlt2 = true;                    }                    // write out a bar's worth of events                    writeBar(*i, barNo, barStart, barEnd, col, key,                             lilyText,                             prevStyle, eventsInProgress, str,                             MultiMeasureRestCount,                              nextBarIsAlt1, nextBarIsAlt2, nextBarIsDouble, nextBarIsEnd, nextBarIsDot);                }                // close \repeat                if (haveRepeating) {                    // close \alternative section if present                    if (haveAlternates) {                        str << std::endl << indent(--col) << " } \% close alternative 2 ";                    }                    // close \repeat section in either case                    str << std::endl << indent(--col) << " } \% close "                    << (haveAlternates ? "alternatives" : "repeat");                }                // closing bar                if (((*i)->getEndMarkerTime() == compositionEndTime) && !haveRepeating) {                    str << std::endl << indent(col) << "\\bar \"|.\"";                }                // close Voice context                str << std::endl << indent(--col) << "} % Voice" << std::endl;  // indent-		//                // Write accumulated lyric events to the Lyric context, if desired.                //		// Sync the code below with LyricEditDialog::unparse() !!		//                if (m_exportLyrics) {		    for (long currentVerse = 0, lastVerse = 0;                          currentVerse <= lastVerse; 			 currentVerse++) {		        bool haveLyric = false;			bool firstNote = true;		        QString text = "";		        timeT lastTime = (*i)->getStartTime();		        int lastBarNo = m_composition->getBarNumber(lastTime);		        for (Segment::iterator j = (*i)->begin();		            (*i)->isBeforeEndMarker(j); ++j) {				            bool isNote = (*j)->isa(Note::EventType);		            bool isLyric = false;				            if (!isNote) {		                if ((*j)->isa(Text::EventType)) {		                    std::string textType;		                    if ((*j)->get		                            <String>(Text::TextTypePropertyName, textType) &&		                            textType == Text::Lyric) {		                        isLyric = true;		                    }		                }		            }				            if (!isNote && !isLyric) continue;				            timeT myTime = (*j)->getNotationAbsoluteTime();		            int myBarNo = m_composition->getBarNumber(myTime);					    if (isNote) {				if ((myTime > lastTime) || firstNote) {				    if (!haveLyric)					text += " _";				    lastTime = myTime;				    haveLyric = false;				    firstNote = false;				}

⌨️ 快捷键说明

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