void MarkerMapper::fillBuffer() { resize(0); Composition& comp = m_doc->getComposition(); Composition::markercontainer &marks = comp.getMarkers(); for (Composition::markerconstiterator i = marks.begin(); i != marks.end(); ++i) { std::string metaMessage = (*i)->getName(); RealTime eventTime = comp.getElapsedRealTime((*i)->getTime()); #ifdef DEBUG_MARKER_MAPPER SEQUENCER_DEBUG << "MarkerMapper::fillBuffer inserting marker message" << metaMessage << "at" << eventTime << endl; #endif MappedEvent e; e.setType(MappedEvent::Marker); e.setEventTime(eventTime); e.addDataString(metaMessage); mapAnEvent(&e); } }
void MetronomeMapper::fillBuffer() { //RG_DEBUG << "fillBuffer(): instrument is " << m_metronome->getInstrument(); Q_ASSERT_X(capacity() >= static_cast<int>(m_ticks.size()), "MetronomeMapper::fillBuffer()", "Buffer capacity is too small."); Composition &composition = m_doc->getComposition(); const RealTime tickDuration(0, 100000000); int index = 0; // For each tick for (TickContainer::iterator tick = m_ticks.begin(); tick != m_ticks.end(); ++tick) { //RG_DEBUG << "fillBuffer(): velocity = " << int(velocity); RealTime eventTime = composition.getElapsedRealTime(tick->first); MappedEvent e; if (tick->second == MidiTimingClockTick) { e = MappedEvent(0, // Instrument ID is irrelevant MappedEvent::MidiSystemMessage); e.setData1(MIDI_TIMING_CLOCK); e.setEventTime(eventTime); } else { MidiByte velocity; MidiByte pitch; switch (tick->second) { case BarTick: velocity = m_metronome->getBarVelocity(); pitch = m_metronome->getBarPitch(); break; case BeatTick: velocity = m_metronome->getBeatVelocity(); pitch = m_metronome->getBeatPitch(); break; case SubBeatTick: velocity = m_metronome->getSubBeatVelocity(); pitch = m_metronome->getSubBeatPitch(); break; case MidiTimingClockTick: default: RG_WARNING << "fillBuffer(): Unexpected tick type"; } e = MappedEvent(m_metronome->getInstrument(), MappedEvent::MidiNoteOneShot, pitch, velocity, eventTime, tickDuration, RealTime::zeroTime); // audioStartMarker } // Add the event to the buffer. getBuffer()[index] = e; ++index; } //RG_DEBUG << "fillBuffer(): capacity: " << capacity(); //RG_DEBUG << " Total events written: " << index; resize(index); m_channelManager.reallocateEternalChannel(); m_channelManager.setDirty(); }
void MappedBufMetaIterator:: fetchEventsNoncompeting(MappedInserterBase &inserter, const RealTime& startTime, const RealTime& endTime) { #ifdef DEBUG_META_ITERATOR SEQUENCER_DEBUG << "MBMI::fetchEventsNoncompeting " << startTime << " -> " << endTime << endl; #endif Profiler profiler("MappedBufMetaIterator::fetchEventsNoncompeting", false); m_currentTime = endTime; // Activate segments that have anything playing during this // slice. We include segments that end exactly when we start, but // not segments that start exactly when we end. for (segmentiterators::iterator i = m_iterators.begin(); i != m_iterators.end(); ++i) { RealTime start, end; (*i)->getSegment()->getStartEnd(start, end); bool active = ((start < endTime) && (end >= startTime)); (*i)->setActive(active, startTime); } // State variable to allow the outer loop to run until the inner // loop has nothing to do. bool innerLoopHasMore = false; do { innerLoopHasMore = false; for (size_t i = 0; i < m_iterators.size(); ++i) { MappedEventBuffer::iterator *iter = m_iterators[i]; #ifdef DEBUG_META_ITERATOR SEQUENCER_DEBUG << "MBMI::fetchEventsNoncompeting : " << "checking segment #" << i << endl; #endif if (!iter->getActive()) { #ifdef DEBUG_META_ITERATOR SEQUENCER_DEBUG << "MBMI::fetchEventsNoncompeting : " << "no more events to get for this slice" << "in segment #" << i << endl; #endif continue; // skip this iterator } if (iter->atEnd()) { #ifdef DEBUG_META_ITERATOR SEQUENCER_DEBUG << "MBMI::fetchEventsNoncompeting : " << endTime << " reached end of segment #" << i << endl; #endif // Make this iterator abort early in future // iterations, since we know it's all done. iter->setInactive(); continue; } // This locks the iterator's buffer against writes, lest // writing cause reallocating the buffer while we are // holding a pointer into it. No function we call will // hold the `cur' pointer past its own scope, implying // that nothing holds it past an iteration of this loop, // which is this lock's scope. QReadLocker locker(iter->getLock()); MappedEvent *cur = iter->peek(); // We couldn't fetch an event or it failed a sanity check. // So proceed to the next iterator but keep looking at // this one - incrementing it does nothing useful, and it // might get more events. But don't set innerLoopHasMore, // lest we loop forever waiting for a valid event. if (!cur || !cur->isValid()) { continue; } // If we got this far, make the mapper ready. Do this // even if the note won't play during this slice, because // sometimes/always we prepare channels slightly ahead of // their first notes, to fix bug #1378 if (!iter->isReady()) { iter->makeReady(inserter, startTime); } if (cur->getEventTime() < endTime) { // Increment the iterator, since we're taking this // event. NB, in the other branch it is not yet used // so we leave `iter' where it is. ++(*iter); // If we got this far, we'll want to try the next // iteration, so note it. innerLoopHasMore = true; #ifdef DEBUG_META_ITERATOR SEQUENCER_DEBUG << "MBMI::fetchEventsNoncompeting : " << endTime << " seeing evt from segment #" << i << " : trackId: " << cur->getTrackId() << " channel: " << (unsigned int) cur->getRecordedChannel() << " - inst: " << cur->getInstrument() << " - type: " << cur->getType() << " - time: " << cur->getEventTime() << " - duration: " << cur->getDuration() << " - data1: " << (unsigned int)cur->getData1() << " - data2: " << (unsigned int)cur->getData2() << endl; #endif if(iter->shouldPlay(cur, startTime)) { iter->doInsert(inserter, *cur); #ifdef DEBUG_META_ITERATOR SEQUENCER_DEBUG << "Inserting event" << endl; #endif } else { #ifdef DEBUG_META_ITERATOR SEQUENCER_DEBUG << "Skipping event" << endl; #endif } } else { // This iterator has more events but they only sound // after the end of this slice, so it's done. iter->setInactive(); #ifdef DEBUG_META_ITERATOR SEQUENCER_DEBUG << "fetchEventsNoncompeting : Event is past end for segment #" << i << endl; #endif } } } while (innerLoopHasMore); return; }
bool operator<(const MappedEvent &a, const MappedEvent &b) { return a.getEventTime() < b.getEventTime(); }