Esempio n. 1
0
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);
    }
}
Esempio n. 2
0
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;
}
Esempio n. 4
0
bool
operator<(const MappedEvent &a, const MappedEvent &b)
{
    return a.getEventTime() < b.getEventTime();
}