📄 rg21loader.cpp
字号:
e->dump(std::cerr); } // other indications not handled yet return true;}void RG21Loader::closeIndication(){ if (m_tokens.count() < 3) return ; unsigned int indicationId = m_tokens[2].toUInt(); EventIdMap::iterator i = m_indicationsExtant.find(indicationId); RG_DEBUG << "rg21io: Indication close: indication id is " << indicationId << endl; // this is normal (for ties): if (i == m_indicationsExtant.end()) return ; Event *indicationEvent = i->second; m_indicationsExtant.erase(i); indicationEvent->set <Int> //!!! (Indication::IndicationDurationPropertyName, ("indicationduration", m_currentSegmentTime - indicationEvent->getAbsoluteTime());}void RG21Loader::closeGroup(){ if (m_groupType == GROUP_TYPE_TUPLED) { Segment::iterator i = m_currentSegment->end(); vector<Event *> toInsert; vector<Segment::iterator> toErase; if (i != m_currentSegment->begin()) { --i; long groupId; timeT prev = m_groupStartTime + m_groupTupledLength; while ((*i)->get <Int>(BEAMED_GROUP_ID, groupId) && groupId == m_groupId) { timeT absoluteTime = (*i)->getAbsoluteTime(); timeT offset = absoluteTime - m_groupStartTime; timeT intended = (offset * m_groupTupledLength) / m_groupUntupledLength; RG_DEBUG << "RG21Loader::closeGroup:" << " m_groupStartTime = " << m_groupStartTime << ", m_groupTupledLength = " << m_groupTupledLength << ", m_groupUntupledCount = " << m_groupUntupledCount << ", m_groupUntupledLength = " << m_groupUntupledLength << ", absoluteTime = " << (*i)->getAbsoluteTime() << ", offset = " << offset << ", intended = " << intended << ", new absolute time = " << (absoluteTime + intended - offset) << ", new duration = " << (prev - absoluteTime) << endl; absoluteTime = absoluteTime + intended - offset; Event *e(new Event(**i, absoluteTime, prev - absoluteTime)); prev = absoluteTime; // See comment in parseGroupStart e->set <Int>(BEAMED_GROUP_TUPLET_BASE, m_groupUntupledLength / m_groupUntupledCount); e->set <Int>(BEAMED_GROUP_TUPLED_COUNT, m_groupTupledLength * m_groupUntupledCount / m_groupUntupledLength); e->set <Int>(BEAMED_GROUP_UNTUPLED_COUNT, m_groupUntupledCount); // To change the time of an event, we need to erase & // re-insert it. But erasure will delete the event, and // if it's an indication event that will invalidate our // indicationsExtant entry. Hence this unpleasantness: if ((*i)->isa(Indication::EventType)) { long indicationId = 0; if ((*i)->get <Int>("indicationId", indicationId)) { EventIdMap::iterator ei = m_indicationsExtant.find(indicationId); if (ei != m_indicationsExtant.end()) { m_indicationsExtant.erase(ei); m_indicationsExtant[indicationId] = e; } } } toInsert.push_back(e); toErase.push_back(i); if (i == m_currentSegment->begin()) break; --i; } } for (unsigned int i = 0; i < toInsert.size(); ++i) { m_currentSegment->insert(toInsert[i]); } for (unsigned int i = 0; i < toErase.size(); ++i) { m_currentSegment->erase(toErase[i]); } m_currentSegmentTime = m_groupStartTime + m_groupTupledLength; } m_inGroup = false;}bool RG21Loader::parseBarType(){ if (m_tokens.count() < 5) return false; if (!m_composition) return false; int staffNo = m_tokens[1].toInt(); if (staffNo > 0) { RG_DEBUG << "RG21Loader::parseBarType: We don't support different time\n" << "signatures on different staffs; disregarding time signature for staff " << staffNo << endl; return true; } // barNo is a hex integer int barNo = m_tokens[2].toInt(0, 16); int numerator = m_tokens[4].toInt(); int denominator = m_tokens[5].toInt(); timeT sigTime = m_composition->getBarRange(barNo).first; TimeSignature timeSig(numerator, denominator); m_composition->addTimeSignature(sigTime, timeSig); return true;}bool RG21Loader::parseStaveType(){ //!!! tags & connected are not yet implemented if (m_tokens.count() < 9) return false; if (!m_composition) return false; bool isNumeric = false; int staffNo = m_tokens[1].toInt(&isNumeric); if (!isNumeric) return false; int programNo = m_tokens[8].toInt(); if (staffNo >= (int)m_composition->getMinTrackId() && staffNo <= (int)m_composition->getMaxTrackId()) { Track *track = m_composition->getTrackById(staffNo); if (track) { Instrument *instr = m_studio->assignMidiProgramToInstrument(programNo, false); if (instr) track->setInstrument(instr->getId()); } } return true;}timeT RG21Loader::convertRG21Duration(QStringList::Iterator& i){ QString durationString = (*i).lower(); ++i; if (durationString == "dotted") { durationString += ' '; durationString += (*i).lower(); ++i; } try { Note n(NotationStrings::getNoteForName(durationString)); return n.getDuration(); } catch (NotationStrings::MalformedNoteName m) { RG_DEBUG << "RG21Loader::convertRG21Duration: Bad duration: " << durationString << endl; return 0; }}void RG21Loader::closeSegment(){ if (m_currentSegment) { TrackId trackId = m_currentSegmentNb - 1; m_currentSegment->setTrack(trackId); Track *track = new Track (trackId, m_currentInstrumentId, trackId, qstrtostr(m_currentStaffName), false); m_currentInstrumentId = (++m_currentInstrumentId) % 16; m_composition->addTrack(track); m_composition->addSegment(m_currentSegment); m_currentSegment = 0; m_currentSegmentTime = 0; m_currentClef = Clef(Clef::Treble); } else { // ?? }}long RG21Loader::convertRG21Pitch(long pitch, int noteModifier){ Accidental accidental = (noteModifier & ModSharp) ? Sharp : (noteModifier & ModFlat) ? Flat : (noteModifier & ModNatural) ? Natural : NoAccidental; long rtn = Pitch::getPerformancePitchFromRG21Pitch (pitch, accidental, m_currentClef, m_currentKey); return rtn;}bool RG21Loader::readNextLine(){ bool inComment = false; do { inComment = false; m_currentLine = m_stream->readLine(); if (m_stream->eof()) return false; m_currentLine = m_currentLine.simplifyWhiteSpace(); if (m_currentLine[0] == '#' || m_currentLine.length() == 0) { inComment = true; continue; // skip comments } m_tokens = QStringList::split(' ', m_currentLine); } while (inComment); return true;}bool RG21Loader::load(const QString &fileName, Composition &comp){ m_composition = ∁ comp.clear(); QFile file(fileName); if (file.open(IO_ReadOnly)) { m_stream = new QTextStream(&file); } else { return false; } m_studio->unassignAllInstruments(); while (!m_stream->eof()) { if (!readNextLine()) break; QString firstToken = m_tokens.first(); if (firstToken == "Staves" || firstToken == "Staffs") { // nb staves m_nbStaves = m_tokens[1].toUInt(); } else if (firstToken == "Name") { // Staff name m_currentStaffName = m_tokens[1]; // we don't do anything with it yet m_currentSegment = new Segment; ++m_currentSegmentNb; } else if (firstToken == "Clef") { parseClef(); } else if (firstToken == "Key") { parseKey(); } else if (firstToken == "Metronome") { if (!readNextLine()) break; parseMetronome(); } else if (firstToken == ":") { // chord m_tokens.remove(m_tokens.begin()); // get rid of 1st token ':' parseChordItem(); } else if (firstToken == "Rest") { // rest if (!readNextLine()) break; parseRest(); } else if (firstToken == "Text") { if (!readNextLine()) break; parseText(); } else if (firstToken == "Group") { if (!readNextLine()) break; parseGroupStart(); } else if (firstToken == "Mark") { if (m_tokens[1] == "start") parseIndicationStart(); else if (m_tokens[1] == "end") closeIndication(); } else if (firstToken == "Bar") { parseBarType(); } else if (firstToken == "Stave") { parseStaveType(); } else if (firstToken == "End") { if (m_inGroup) closeGroup(); else closeSegment(); } else { RG_DEBUG << "RG21Loader::parse: Unsupported element type \"" << firstToken << "\", ignoring" << endl; } } delete m_stream; m_stream = 0; return true;}vector<string> RG21Loader::convertRG21ChordMods(int chordMods){ vector<string> marks; // bit laborious! if (chordMods & ModDot) marks.push_back(Staccato); if (chordMods & ModLegato) marks.push_back(Tenuto); if (chordMods & ModAccent) marks.push_back(Accent); if (chordMods & ModSfz) marks.push_back(Sforzando); if (chordMods & ModRfz) marks.push_back(Rinforzando); if (chordMods & ModTrill) marks.push_back(Trill); if (chordMods & ModTurn) marks.push_back(Turn); if (chordMods & ModPause) marks.push_back(Pause); return marks;}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -