Logo Search packages:      
Sourcecode: rosegarden version File versions  Download package

void Rosegarden::RosegardenDocument::insertRecordedMidi ( const MappedEventList mc )

insert some recorded MIDI events into our recording Segment

Definition at line 1709 of file RosegardenDocument.cpp.

References Rosegarden::CurrentProgressDialog::freeze(), and Rosegarden::CurrentProgressDialog::thaw().

Referenced by Rosegarden::RosegardenMainWindow::slotUpdateCPUMeter().


                if (er == 0) er = *rates.begin();


                QMessageBox::information(dynamic_cast<QWidget *>(parent()), tr("Rosegarden"), tr("<h3>Incorrect audio sample rate</h3><p>This composition contains audio files that were recorded or imported with the audio server running at a different sample rate (%1 Hz) from the current JACK server sample rate (%2 Hz).</p><p>Rosegarden will play this composition at the correct speed, but any audio files in it will probably sound awful.</p><p>Please consider re-starting the JACK server at the correct rate (%3 Hz) and re-loading this composition before you do any more work with it.</p>").arg(er).arg(sr).arg(er));

                shownWarning = true;
            } else if (sr != 0 && mixed) {
                QMessageBox::information(dynamic_cast<QWidget *>(parent()), tr("Rosegarden"), tr("<h3>Inconsistent audio sample rates</h3><p>This composition contains audio files at more than one sample rate.</p><p>Rosegarden will play them at the correct speed, but any audio files that were recorded or imported at rates different from the current JACK server sample rate (%1 Hz) will probably sound awful.</p><p>Please see the audio file manager dialog for more details, and consider resampling any files that are at the wrong rate.</p>").arg(sr),
                                         tr("Inconsistent sample rates"),
                shownWarning = true;
            if (m_pluginManager && !handler.pluginsNotFound().empty()) {

                // We only warn if a plugin manager is present, so as
                // to avoid warnings when importing a studio from
                // another file (which is the normal case in which we
                // have no plugin manager).

                QString msg(tr("<h3>Plugins not found</h3><p>The following audio plugins could not be loaded:</p><ul>"));

                for (std::set<QString>::iterator i = handler.pluginsNotFound().begin();
                     i != handler.pluginsNotFound().end(); ++i) {
                    QString ident = *i;
                    QString type, soName, label;
                    PluginIdentifier::parseIdentifier(ident, type, soName, label);
                    QString pluginFileName = QFileInfo(soName).fileName();
                    msg += tr("<li>%1 (from %2)</li>").arg(label).arg(pluginFileName);
                msg += "</ul>";
                QMessageBox::information(dynamic_cast<QWidget *>(parent()), tr("Rosegarden"), msg);
                shownWarning = true;

            if (handler.isDeprecated() && !shownWarning) {
                QString msg(tr("This file contains one or more old element types that are now deprecated.\nSupport for these elements may disappear in future versions of Rosegarden.\nWe recommend you re-save this file from this version of Rosegarden to ensure that it can still be re-loaded in future versions."));
                slotDocumentModified(); // so file can be re-saved immediately
                QMessageBox::information(dynamic_cast<QWidget *>(parent()), tr("Rosegarden"), msg);


    if (handler.channelsWereRemapped()) {

                dynamic_cast<QWidget *>(parent()),
                tr("<qt><h2>Channels were remapped</h2><p>Beginning with version 10.02, Rosegarden no longer provides controls for changing the channel associated with each MIDI instrument.  Instead, each instrument uses the same channel as its instrument number.  For example, \"MIDI Input System Device #12\" always uses channel 12.</p><p>The file you just loaded contained instruments whose channels differed from the instrument numbers.  These channels have been reassigned so that instrument #1 will always use channel 1, regardless of what channel it might have used previously.  In most cases, you will experience no difference, but you may have to make some small changes to this file in order for it to play as intended.  We recommend that you save this file in order to avoid seeing this warning in the future.</p><p>We apologize for any inconvenience.</p></qt>"));


    return ok;

RosegardenDocument::insertRecordedMidi(const MappedEventList &mC)
    RG_DEBUG << "RosegardenDocument::insertRecordedMidi: " << mC.size() << " events" << endl;

    // Just create a new record Segment if we don't have one already.
    // Make sure we don't recreate the record segment if it's already
    // freed.

    //Track *midiRecordTrack = 0;

    const Composition::recordtrackcontainer &tr =

    bool haveMIDIRecordTrack = false;

    for (Composition::recordtrackcontainer::const_iterator i =
                tr.begin(); i != tr.end(); ++i) {
        TrackId tid = (*i);
        Track *track = getComposition().getTrackById(tid);
        if (track) {
            Instrument *instrument =
            if (instrument->getType() == Instrument::Midi ||
                    instrument->getType() == Instrument::SoftSynth) {
                haveMIDIRecordTrack = true;
                if (!m_recordMIDISegments[track->getInstrument()]) {

    if (!haveMIDIRecordTrack)
        return ;

    if (mC.size() > 0) {

        Event *rEvent = 0;
        timeT duration, absTime;
        timeT updateFrom = m_composition.getDuration();
        bool haveNotes = false;

        MappedEventList::const_iterator i;

        // process all the incoming MappedEvents
        int lenx = int(m_viewList.size());
        RosegardenMainViewWidget *v;
        int k = 0;
        for (i = mC.begin(); i != mC.end(); ++i) {

            if ((*i)->getRecordedDevice() == Device::CONTROL_DEVICE) {
                // send to GUI
                //QList<RosegardenMainViewWidget *>::iterator v;
                //for( v=m_viewList.begin(); v!=m_viewList.end(); v++ ) {
                for( k=0; k<lenx; k++){
                    v = m_viewList.value( k );

            absTime = m_composition.getElapsedTimeForRealTime((*i)->getEventTime());

            /* This is incorrect, unless the tempo at absTime happens to
               be the same as the tempo at zero and there are no tempo
               changes within the given duration after either zero or

               duration = m_composition.getElapsedTimeForRealTime((*i)->getDuration());
            duration = m_composition.
                       getElapsedTimeForRealTime((*i)->getEventTime() +
                                                 (*i)->getDuration()) - absTime;

            rEvent = 0;
            bool isNoteOn = false;
            int pitch = (*i)->getPitch();
            int channel = (*i)->getRecordedChannel();
            int device = (*i)->getRecordedDevice();

            switch ((*i)->getType()) {

            case MappedEvent::MidiNote:

                if ((*i)->getDuration() < RealTime::zeroTime) {

                    // it's a note-on; give it a default duration
                    // for insertion into the segment, and make a
                    // mental note to stick it in the note-on map
                    // for when we see the corresponding note-off

                    duration = Note(Note::Crotchet).getDuration();
                    isNoteOn = true;

                    rEvent = new Event(Note::EventType,

                    rEvent->set<Int>(PITCH, pitch);
                    rEvent->set<Int>(VELOCITY, (*i)->getVelocity());

                } else {

                    // it's a note-off

                    PitchMap *pm = &m_noteOnEvents[device][channel];
                    PitchMap::iterator mi = pm->find(pitch);

                    if (mi != pm->end()) {
                        // modify the previously held note-on event,
                        // instead of assigning to rEvent
                        NoteOnRecSet rec_vec = mi->second;
                        Event *oldEv = *rec_vec[0].m_segmentIterator;
                        Event *newEv = new Event
                            (*oldEv, oldEv->getAbsoluteTime(), duration);

                        newEv->set<Int>(RECORDED_CHANNEL, channel);
                        NoteOnRecSet *replaced =
                            replaceRecordedEvent(rec_vec, newEv);
                        delete replaced;
                        if (updateFrom > newEv->getAbsoluteTime()) {
                            updateFrom = newEv->getAbsoluteTime();
                        haveNotes = true;
                        delete newEv;
                        // at this point we could quantize the bar if we were
                        // tracking in a notation view
                    } else {
                        std::cerr << " WARNING: NOTE OFF received without corresponding NOTE ON" << std::endl;


            case MappedEvent::MidiPitchBend:
                rEvent = PitchBend
                         ((*i)->getData1(), (*i)->getData2()).getAsEvent(absTime);
                rEvent->set<Int>(RECORDED_CHANNEL, channel);

            case MappedEvent::MidiController:
                rEvent = Controller
                         ((*i)->getData1(), (*i)->getData2()).getAsEvent(absTime);
                rEvent->set<Int>(RECORDED_CHANNEL, channel);

            case MappedEvent::MidiProgramChange:
                RG_DEBUG << "RosegardenDocument::insertRecordedMidi()"
                         << " - got Program Change (unsupported)"
                         << endl;

            case MappedEvent::MidiKeyPressure:
                rEvent = KeyPressure
                         ((*i)->getData1(), (*i)->getData2()).getAsEvent(absTime);
                rEvent->set<Int>(RECORDED_CHANNEL, channel);

            case MappedEvent::MidiChannelPressure:
                rEvent = ChannelPressure
                rEvent->set<Int>(RECORDED_CHANNEL, channel);

            case MappedEvent::MidiSystemMessage:
                channel = -1;
                if ((*i)->getData1() == MIDI_SYSTEM_EXCLUSIVE) {
                    rEvent = SystemExclusive

Here is the call graph for this function:

Here is the caller graph for this function:

Generated by  Doxygen 1.6.0   Back to index