📄 segmentmmapper.cpp
字号:
MappedEvent* bufPos = m_mmappedEventBuffer; for (int repeatNo = 0; repeatNo <= repeatCount; ++repeatNo) { Segment *triggered = 0; Segment::iterator *i = 0; for (Segment::iterator j = m_segment->begin(); m_segment->isBeforeEndMarker(j) || (i && *i != triggered->end()); ) { bool usingi = false; Segment::iterator *k = &j; if (i && *i != triggered->end() && (!m_segment->isBeforeEndMarker(j) || (**i)->getAbsoluteTime() < (*j)->getAbsoluteTime())) { k = i; usingi = true; } if (!usingi) { // don't permit nested triggered segments long triggerId = -1; (**k)->get <Int>(BaseProperties::TRIGGER_SEGMENT_ID, triggerId); if (triggerId >= 0) { TriggerSegmentRec *rec = comp.getTriggerSegmentRec(triggerId); if (rec && rec->getSegment()) { timeT performanceDuration = SegmentPerformanceHelper(*m_segment). getSoundingDuration(j); if (performanceDuration > 0) { mergeTriggerSegment(&triggered, *j, performanceDuration, rec); size_t sz = addMmappedSize(rec->getSegment()); size_t offset = bufPos - m_mmappedEventBuffer; setFileSize(sz); remap(sz); bufPos = m_mmappedEventBuffer + offset; } } if (triggered) { if (i) delete i; i = new Segment::iterator (triggered->findTime((*j)->getAbsoluteTime())); } // Use the next triggered event (presumably the // first of the current triggered segment) instead // of the one that triggered it ++j; // whatever happens, we don't want to write this one if (i && *i != triggered->end() && (!m_segment->isBeforeEndMarker(j) || ((**i)->getAbsoluteTime() < (*j)->getAbsoluteTime()))) { k = i; usingi = true; } else { // no joy at all continue; } } } // Ignore rests // if (!(**k)->isa(Note::EventRestType)) { SegmentPerformanceHelper helper (usingi ? *triggered : *m_segment); timeT playTime = helper.getSoundingAbsoluteTime(*k) + repeatNo * segmentDuration; if (playTime >= repeatEndTime) break; timeT playDuration = helper.getSoundingDuration(*k); // Ignore notes without duration -- they're probably in a tied // series but not as first note // if (playDuration > 0 || !(**k)->isa(Note::EventType)) { if (playTime + playDuration > repeatEndTime) playDuration = repeatEndTime - playTime; playTime = playTime + m_segment->getDelay(); eventTime = comp.getElapsedRealTime(playTime); // slightly quicker than calling helper.getRealSoundingDuration() duration = comp.getElapsedRealTime(playTime + playDuration) - eventTime; eventTime = eventTime + m_segment->getRealTimeDelay(); try { // Create mapped event in mmapped buffer. The // instrument will be extracted from the ControlBlock // by the sequencer, so we set it to zero here. MappedEvent *mE = new (bufPos) MappedEvent(0, ***k, // three stars! what an accolade eventTime, duration); mE->setTrackId(track->getId()); if (m_segment->getTranspose() != 0 && (**k)->isa(Note::EventType)) { mE->setPitch(mE->getPitch() + m_segment->getTranspose()); } ++bufPos; } catch (...) { SEQMAN_DEBUG << "SegmentMmapper::dump - caught exception while trying to create MappedEvent\n"; } } } ++*k; // increment either i or j, whichever one we just used } delete i; delete triggered; } // Store the number of events at the start of the shared memory region *(size_t *)m_mmappedRegion = (bufPos - m_mmappedEventBuffer); size_t coveredArea = (bufPos - m_mmappedEventBuffer) * sizeof(MappedEvent); memset(bufPos, 0, m_mmappedSize - coveredArea - sizeof(size_t)); ::msync(m_mmappedRegion, m_mmappedSize, MS_ASYNC);}voidSegmentMmapper::mergeTriggerSegment(Segment **target, Event *trigger, timeT evDuration, TriggerSegmentRec *rec){ if (!rec || !rec->getSegment() || rec->getSegment()->empty()) return ; if (!*target) *target = new Segment; timeT evTime = trigger->getAbsoluteTime(); timeT trStart = rec->getSegment()->getStartTime(); timeT trEnd = rec->getSegment()->getEndMarkerTime(); timeT trDuration = trEnd - trStart; if (trDuration == 0) return ; bool retune = false; std::string timeAdjust = BaseProperties::TRIGGER_SEGMENT_ADJUST_NONE; trigger->get <Bool> (BaseProperties::TRIGGER_SEGMENT_RETUNE, retune); trigger->get <String> (BaseProperties::TRIGGER_SEGMENT_ADJUST_TIMES, timeAdjust); long evPitch = rec->getBasePitch(); (void)trigger->get <Int>(BaseProperties::PITCH, evPitch); int pitchDiff = evPitch - rec->getBasePitch(); long evVelocity = rec->getBaseVelocity(); (void)trigger->get <Int>(BaseProperties::VELOCITY, evVelocity); int velocityDiff = evVelocity - rec->getBaseVelocity(); timeT offset = 0; if (timeAdjust == BaseProperties::TRIGGER_SEGMENT_ADJUST_SYNC_END) { offset = evDuration - trDuration; } for (Segment::iterator i = rec->getSegment()->begin(); rec->getSegment()->isBeforeEndMarker(i); ++i) { timeT t = (*i)->getAbsoluteTime() - trStart; timeT d = (*i)->getDuration(); if (evDuration != trDuration && timeAdjust == BaseProperties::TRIGGER_SEGMENT_ADJUST_SQUISH) { t = timeT(double(t * evDuration) / double(trDuration)); d = timeT(double(d * evDuration) / double(trDuration)); } t += evTime + offset; if (t < evTime) { if (t + d <= evTime) continue; else { d -= (evTime - t); t = evTime; } } if (timeAdjust == BaseProperties::TRIGGER_SEGMENT_ADJUST_SYNC_START) { if (t + d > evTime + evDuration) { if (t >= evTime + evDuration) continue; else { d = evTime + evDuration - t; } } } Event *newEvent = new Event(**i, t, d); if (retune && newEvent->has(BaseProperties::PITCH)) { int pitch = newEvent->get <Int>(BaseProperties::PITCH) + pitchDiff; if (pitch > 127) pitch = 127; if (pitch < 0) pitch = 0; newEvent->set <Int>(BaseProperties::PITCH, pitch); } if (newEvent->has(BaseProperties::VELOCITY)) { int velocity = newEvent->get <Int>(BaseProperties::VELOCITY) + velocityDiff; if (velocity > 127) velocity = 127; if (velocity < 0) velocity = 0; newEvent->set <Int>(BaseProperties::VELOCITY, velocity); } (*target)->insert(newEvent); }}unsigned int SegmentMmapper::getSegmentRepeatCount(){ int repeatCount = 0; timeT segmentStartTime = m_segment->getStartTime(); timeT segmentEndTime = m_segment->getEndMarkerTime(); timeT segmentDuration = segmentEndTime - segmentStartTime; timeT repeatEndTime = segmentEndTime; if (m_segment->isRepeating() && segmentDuration > 0) { repeatEndTime = m_segment->getRepeatEndTime(); repeatCount = 1 + (repeatEndTime - segmentEndTime) / segmentDuration; } return repeatCount;}size_t SegmentMmapper::addMmappedSize(Segment *s){ int repeatCount = getSegmentRepeatCount(); return m_mmappedSize + (repeatCount + 1) * s->size() * sizeof(MappedEvent);}size_t SegmentMmapper::computeMmappedSize(){ if (!m_segment) return 0; int repeatCount = getSegmentRepeatCount(); return (repeatCount + 1) * m_segment->size() * sizeof(MappedEvent);}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -