Exemple #1
0
bool LOS::importMidi(const QString name, bool merge)/*{{{*/
{
    bool popenFlag;
    FILE* fp = fileOpen(this, name, QString(".mid"), "r", popenFlag);
    if (fp == 0)
        return true;
    MidiFile mf(fp);
    bool rv = mf.read();
    popenFlag ? pclose(fp) : fclose(fp);
    if (rv)
    {
        QString s(tr("reading midifile\n  "));
        s += name;
        s += tr("\nfailed: ");
        s += mf.error();
        QMessageBox::critical(this, QString("LOS"), s);
        return rv;
    }
    //
    //  evaluate song Type (GM, XG, GS, unknown)
    //
    MType t = song->midiType();
    if (!merge)
    {
        t = mf.mtype();
        song->setMType(t);
    }
    MidiInstrument* instr = 0;
    for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i)
    {
        MidiInstrument* mi = *i;
        if ((mi->iname() == "GM" && ((t == MT_UNKNOWN) || (t == MIDI_TYPE_GM)))
                || ((mi->iname() == "GS") && (t == MT_GS))
                || ((mi->iname() == "XG") && (t == MT_XG)))
        {
            instr = mi;
            break;
        }
    }
    if (instr == 0)
    {
        // the standard instrument files (GM, GS, XG) must be present
        printf("no instrument, type %d\n", t);
        return true;
        //abort();
    }

    MidiFileTrackList* etl = mf.trackList();
    int division = mf.division();

    //
    // create MidiTrack and copy events to ->events()
    //    - combine note on/off events
    //    - calculate tick value for internal resolution
    //
    for (iMidiFileTrack t = etl->begin(); t != etl->end(); ++t)
    {
        MPEventList* el = &((*t)->events);
        if (el->empty())
            continue;
        //
        // if we split the track, SYSEX and META events go into
        // the first target track

        bool first = true;
        // somewhat silly and slooow:
        for (int port = 0; port < kMaxMidiPorts; ++port)
        {
            for (int channel = 0; channel < kMaxMidiChannels; ++channel)
            {
                //
                // check if there are any events for port/channel in track:
                //
                iMPEvent i;
                for (i = el->begin(); i != el->end(); ++i)
                {
                    MidiPlayEvent ev = *i;
                    if (ev.type() != ME_SYSEX && ev.type() != ME_META
                            && ev.channel() == channel && ev.port() == port)
                        break;
                }
                if (i == el->end())
                    continue;
                MidiTrack* track = new MidiTrack();
                if ((*t)->isDrumTrack)
                {
                    track->setType(Track::DRUM);
                }

                track->setOutChannel(channel);
                track->setOutPort(port);

                MidiPort* mport = &midiPorts[track->outPort()];
                // this overwrites any instrument set for this port:
                mport->setInstrument(instr);

                EventList* mel = track->events();
                //buildMidiEventList(mel, el, track, division, first);
                // Don't do loops.
                buildMidiEventList(mel, el, track, division, first, false);
                first = false;

                // Hmm. buildMidiEventList already takes care of this.
                // But it seems to work. How? Must test.
                if (channel == 9 && song->midiType() != MT_UNKNOWN)
                {
                    track->setType(Track::DRUM);
                    //
                    // remap drum pitch with drumInmap
                    //
                    EventList* tevents = track->events();
                    for (iEvent i = tevents->begin(); i != tevents->end(); ++i)
                    {
                        Event ev = i->second;
                        if (ev.isNote())
                        {
                            int pitch = drumInmap[ev.pitch()];
                            ev.setPitch(pitch);
                        }
                        else
                            if (ev.type() == Controller)
                        {
                            int ctl = ev.dataA();
                            MidiController *mc = mport->drumController(ctl);
                            if (mc)
                                ev.setA((ctl & ~0xff) | drumInmap[ctl & 0x7f]);
                        }
                    }
                }

                processTrack(track);

                song->insertTrack(track, -1);
            }
        }
        if (first)
        {
            //
            // track does only contain non-channel messages
            // (SYSEX or META)
            //
            MidiTrack* track = new MidiTrack();
            track->setOutChannel(0);
            track->setOutPort(0);
            EventList* mel = track->events();
            //buildMidiEventList(mel, el, track, division, true);
            // Do SysexMeta. Don't do loops.
            buildMidiEventList(mel, el, track, division, true, false);
            processTrack(track);
            song->insertTrack(track, -1);
        }
    }

    if (!merge)
    {
        TrackList* tl = song->tracks();
        if (!tl->empty())
        {
            Track* track = tl->front();
            track->setSelected(true);
        }
        song->initLen();

        int z, n;
        ///sigmap.timesig(0, z, n);
        sigmap.timesig(0, z, n);

        int tempo = tempomap.tempo(0);
        transport->setTimesig(z, n);
        transport->setTempo(tempo);

        bool masterF = !tempomap.empty();
        song->setMasterFlag(masterF);
        transport->setMasterFlag(masterF);

        song->updatePos();

        composer->reset();
        ///composer->setMode(int(song->midiType())); // p4.0.7 Tim
    }
    else
    {
        song->initLen();
    }

    return false;
}/*}}}*/
Exemple #2
0
bool LOS::importMidi(const QString name, bool merge)/*{{{*/
{
    bool popenFlag;
    FILE* fp = fileOpen(this, name, QString(".mid"), "r", popenFlag);
    if (fp == 0)
        return true;
    MidiFile mf(fp);
    bool rv = mf.read();
    popenFlag ? pclose(fp) : fclose(fp);
    if (rv)
    {
        QString s(tr("reading midifile\n  "));
        s += name;
        s += tr("\nfailed: ");
        s += mf.error();
        QMessageBox::critical(this, QString("LOS"), s);
        return rv;
    }
    //
    //  evaluate song Type (GM, XG, GS, unknown)
    //
    MType t = song->midiType();
    if (!merge)
    {
        t = mf.mtype();
        song->setMType(t);
    }
    MidiInstrument* instr = 0;
    for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i)
    {
        MidiInstrument* mi = *i;
        if ((mi->iname() == "GM" && ((t == MT_UNKNOWN) || (t == MIDI_TYPE_GM)))
                || ((mi->iname() == "GS") && (t == MT_GS))
                || ((mi->iname() == "XG") && (t == MT_XG)))
        {
            instr = mi;
            break;
        }
    }
    if (instr == 0)
    {
        // the standard instrument files (GM, GS, XG) must be present
        printf("no instrument, type %d\n", t);
        return true;
        //abort();
    }

    MidiFileTrackList* etl = mf.trackList();
    int division = mf.division();

    //
    // create MidiTrack and copy events to ->events()
    //    - combine note on/off events
    //    - calculate tick value for internal resolution
    //
    int mPort = getFreeMidiPort();
    for (iMidiFileTrack t = etl->begin(); t != etl->end(); ++t)
    {
        MPEventList* el = &((*t)->events);
        if (el->empty())
            continue;
        //
        // if we split the track, SYSEX and META events go into
        // the first target track

        bool first = true;
        // somewhat silly and slooow:
        QList<QPair<int, int> > eventChannelList;
        if(mPort >= 0 && mPort < kMaxMidiPorts)
        {
            for (int channel = 0; channel < kMaxMidiChannels; ++channel)
            {
                //
                // check if there are any events for port/channel in track:
                //
                iMPEvent i;
                for (i = el->begin(); i != el->end(); ++i)
                {
                    MidiPlayEvent ev = *i;
                    if (ev.type() != ME_SYSEX && ev.type() != ME_META && ev.channel() == channel)
                        break;
                }
                if (i == el->end())
                    continue;
                MidiTrack* track = new MidiTrack();
                track->setDefaultName();
                track->setMasterFlag(true);

                track->setOutChannel(channel);
                track->setOutPort(mPort);

                MidiPort* mport = &midiPorts[track->outPort()];
                // this overwrites any instrument set for this port:
                mport->setInstrument(instr);

                EventList* mel = track->events();
                buildMidiEventList(mel, el, track, division, first, false, false);

                first = false;

                processTrack(track);

                song->insertTrack(track, -1);
                //Create the Audio input side of the track
                Track* input = song->addTrackByName(QString("i").append(track->name()), Track::AUDIO_INPUT, -1, false, false);
                if(input)
                {
                    input->setMasterFlag(false);
                    input->setChainMaster(track->id());
                    track->addManagedTrack(input->id());
                }
            }
        }
        if (first)
        {
            //
            // track does only contain non-channel messages
            // (SYSEX or META)
            //
            MidiTrack* track = new MidiTrack();
            track->setDefaultName();
            track->setMasterFlag(true);
            track->setOutChannel(0);
            track->setOutPort(mPort);
            EventList* mel = track->events();
            //buildMidiEventList(mel, el, track, division, true);
            // Do SysexMeta. Don't do loops.
            buildMidiEventList(mel, el, track, division, true, false, false);
            processTrack(track);
            song->insertTrack(track, -1);
            //Create the Audio input side of the track
            Track* input = song->addTrackByName(QString("i").append(track->name()), Track::AUDIO_INPUT, -1, false, false);
            if(input)
            {
                input->setMasterFlag(false);
                input->setChainMaster(track->id());
                track->addManagedTrack(input->id());
            }
        }
        mPort++;
        //FIXME: Provice a non-iterative way to do this using the new losMidiPorts hash
        //Or maintain a list of configured or inuse ports
        while((&midiPorts[mPort])->device() && mPort < kMaxMidiPorts)
            mPort++;//Just incase we have a configured port after an empty one
    }

    if (!merge)
    {
        TrackList* tl = song->tracks();
        if (!tl->empty())
        {
            Track* track = tl->front();
            track->setSelected(true);
        }
        song->initLen();

        int z, n;
        sigmap.timesig(0, z, n);

        int tempo = tempomap.tempo(0);
        transport->setTimesig(z, n);
        transport->setTempo(tempo);

        bool masterF = !tempomap.empty();
        song->setMasterFlag(masterF);
        transport->setMasterFlag(masterF);

        song->updatePos();

        composer->reset();
    }
    else
    {
        song->initLen();
    }

    return false;
}/*}}}*/
Exemple #3
0
bool LOS::importMidi(const QString name, bool merge)/*{{{*/
{
    bool popenFlag;
    FILE* fp = fileOpen(this, name, QString(".mid"), "r", popenFlag);
    if (fp == 0)
        return true;
    MidiFile mf(fp);
    bool rv = mf.read();
    popenFlag ? pclose(fp) : fclose(fp);
    if (rv)
    {
        QString s(tr("reading midifile\n  "));
        s += name;
        s += tr("\nfailed: ");
        s += mf.error();
        QMessageBox::critical(this, QString("LOS"), s);
        return rv;
    }
    //
    //  evaluate song Type (GM, XG, GS, unknown)
    //
    MidiType t = song->midiType();
    if (!merge)
    {
        t = mf.midiType();
        song->setMidiType(t);
    }
    MidiInstrument* instr = 0;
    for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i)
    {
        MidiInstrument* mi = *i;
        if ((mi->iname() == "GM" && ((t == MIDI_TYPE_NULL) || (t == MIDI_TYPE_GM))) ||
            (mi->iname() == "GS" &&   t == MIDI_TYPE_GS) ||
            (mi->iname() == "XG" &&   t == MIDI_TYPE_XG))
        {
            instr = mi;
            break;
        }
    }
    if (instr == 0)
    {
        // the standard instrument files (GM, GS, XG) must be present
        printf("no instrument, type %d\n", t);
        return true;
        //abort();
    }

    MidiFileTrackList* etl = mf.trackList();
    int division = mf.division();

    //
    // create MidiTrack and copy events to ->events()
    //    - combine note on/off events
    //    - calculate tick value for internal resolution
    //
    int mPort = getFreeMidiPort();
    for (iMidiFileTrack t = etl->begin(); t != etl->end(); ++t)
    {
        MPEventList* el = &((*t)->events);
        if (el->empty())
            continue;
        //
        // if we split the track, SYSEX and META events go into
        // the first target track

        bool first = true;
        QList<QPair<int, int> > portChannelList;
        iMPEvent i;
        for(i = el->begin(); i != el->end(); i++)
        {
            if (i->type() != ME_SYSEX && i->type() != ME_META)
            {
                int chan = i->channel();
                int port = i->port();
                if(portChannelList.isEmpty() || !portChannelList.contains(qMakePair(chan, port)))
                {
                    portChannelList.append(qMakePair(chan, port));

                    MidiTrack* track = new MidiTrack();
                    track->setDefaultName();
                    track->setMasterFlag(true);

                    if(config.partColorNames[lastTrackPartColorIndex].contains("menu:", Qt::CaseSensitive))
                        lastTrackPartColorIndex ++;

                    track->setDefaultPartColor(lastTrackPartColorIndex);
                    lastTrackPartColorIndex ++;

                    if(lastTrackPartColorIndex == NUM_PARTCOLORS)
                        lastTrackPartColorIndex = 1;

                    //Set track channel so buildMidiEventList can match the event to a channel
                    track->setOutChannel(chan);
                    track->setOutPort(mPort);

                    MidiPort* mport = &midiPorts[track->outPort()];
                    // this overwrites any instrument set for this port:
                    mport->setInstrument(instr);

                    EventList* mel = track->events();
                    buildMidiEventList(mel, el, track, division, first, false, false);

                    first = false;

                    processTrack(track);

                    //Update track to channel 1
                    //99% of all midi we import will be alien to our setup anyway,
                    //so I'm making it easy for the user to just set the Instrument and go
                    track->setOutChannel(0);

                    song->insertTrack(track, -1);
                    mPort++;
                    //FIXME: Provice a non-iterative way to do this using the new losMidiPorts hash
                    //Or maintain a list of configured or inuse ports
                    while((&midiPorts[mPort])->device() && mPort < kMaxMidiPorts)
                        mPort++;//Just incase we have a configured port after an empty one
                }
            }
        }
        if (first)
        {
            //
            // track does only contain non-channel messages
            // (SYSEX or META)
            //
            MidiTrack* track = new MidiTrack();
            track->setDefaultName();
            track->setMasterFlag(true);
            track->setOutChannel(0);
            track->setOutPort(mPort);

            if(config.partColorNames[lastTrackPartColorIndex].contains("menu:", Qt::CaseSensitive))
                lastTrackPartColorIndex ++;

            track->setDefaultPartColor(lastTrackPartColorIndex);
            lastTrackPartColorIndex ++;

            if(lastTrackPartColorIndex == NUM_PARTCOLORS)
                lastTrackPartColorIndex = 1;

            EventList* mel = track->events();
            // Do SysexMeta. Don't do loops.
            // TODO: Properly support sysex dumps
            buildMidiEventList(mel, el, track, division, true, false, false);
            processTrack(track);
            song->insertTrack(track, -1);
            mPort++;
            while((&midiPorts[mPort])->device() && mPort < kMaxMidiPorts)
                mPort++;
        }
    }

    if (!merge)
    {
        MidiTrackList* tl = song->tracks();
        if (!tl->empty())
        {
            MidiTrack* track = tl->front();
            track->setSelected(true);
        }
        song->initLen();

        int z, n;
        sigmap.timesig(0, z, n);

        int tempo = tempomap.tempo(0);
        transport->setTimesig(z, n);
        transport->setTempo(tempo);

        bool masterF = !tempomap.empty();
        song->setMasterFlag(masterF);
        transport->setMasterFlag(masterF);

        song->updatePos();

        composer->reset();
    }
    else
    {
        song->initLen();
    }

    return false;
}/*}}}*/
Exemple #4
0
bool MusE::importMidi(const QString name, bool merge)
      {
      bool popenFlag;
      FILE* fp = MusEGui::fileOpen(this, name, QString(".mid"), "r", popenFlag);
      if (fp == 0)
            return true;
      MusECore::MidiFile mf(fp);
      bool rv = mf.read();
      popenFlag ? pclose(fp) : fclose(fp);
      if (rv) {
            QString s(tr("reading midifile\n  "));
            s += name;
            s += tr("\nfailed: ");
            s += mf.error();
            QMessageBox::critical(this, QString("MusE"), s);
            return rv;
            }
            
      MusECore::MidiFileTrackList* etl = mf.trackList();
      int division     = mf.division();

      // Find the default instrument, we may need it later...
      MusECore::MidiInstrument* def_instr = 0;
      if(!MusEGlobal::config.importMidiDefaultInstr.isEmpty())
      {
        for(MusECore::iMidiInstrument i = MusECore::midiInstruments.begin(); i != MusECore::midiInstruments.end(); ++i) 
        {
          if((*i)->iname() == MusEGlobal::config.importMidiDefaultInstr)   
          {
            def_instr = *i;
            break;
          }  
        }
      }
          
      //
      // Need to set up ports and instruments first
      //
      
      MusECore::MidiFilePortMap* usedPortMap = mf.usedPortMap();
      bool dev_changed = false;
      for(MusECore::iMidiFilePort imp = usedPortMap->begin(); imp != usedPortMap->end(); ++imp) 
      {
        MType midi_type = imp->second._midiType;
        QString instr_name = MusEGlobal::config.importInstrNameMetas ? imp->second._instrName : QString();
        MusECore::MidiInstrument* typed_instr = 0;
        MusECore::MidiInstrument* named_instr = 0;
        // Find a typed instrument and a named instrument, if requested
        for(MusECore::iMidiInstrument i = MusECore::midiInstruments.begin(); i != MusECore::midiInstruments.end(); ++i) 
        {
          MusECore::MidiInstrument* mi = *i;
          if(midi_type != MT_UNKNOWN && midi_type == mi->midiType())
            typed_instr = mi;
          if(!instr_name.isEmpty() && instr_name == mi->iname())
            named_instr = mi;
          if((typed_instr && named_instr) || ((typed_instr && instr_name.isEmpty()) || (named_instr && midi_type == MT_UNKNOWN)))
            break;  // Done searching
        }

        int port = imp->first;
        MusECore::MidiPort* mp = &MusEGlobal::midiPorts[port];
        MusECore::MidiDevice* md = mp->device();
        // Take care of assigning devices to empty ports here rather than in midifile.
        //if(MusEGlobal::config.importDevNameMetas)  // TODO
        {
          if(!md)
          {
            QString dev_name = imp->second._subst4DevName;
            md = MusEGlobal::midiDevices.find(dev_name); // Find any type of midi device - HW, synth etc.
            if(md)
            {
              // TEST: Hopefully shouldn't require any routing saves/restorations as in midi port config set device name...
              MusEGlobal::midiSeq->msgSetMidiDevice(mp, md);
              // TEST: Hopefully can get away with this ouside the loop below...
              //MusEGlobal::muse->changeConfig(true);     // save configuration file
              //MusEGlobal::audio->msgUpdateSoloStates();
              //MusEGlobal::song->update();
              dev_changed = true;
            }
            else
              printf("importMidi error: assign to empty port: device not found: %s\n", dev_name.toLatin1().constData());
          }
        }

        MusECore::MidiInstrument* instr = 0;
        // Priority is exact named instrument over a typed instrument.
        // This allows a named instrument plus a typed sysex, and the name will take priority. 
        // But it is possible that named mismatches may occur. So this named/typed order is user-selectable.
        if(named_instr && (!typed_instr || MusEGlobal::config.importInstrNameMetas))
        {
          instr = named_instr;
          if(MusEGlobal::debugMsg)
            printf("port:%d named instrument found:%s\n",
                    port, instr->iname().toLatin1().constData());
        }
        else if(typed_instr)
        {
        instr = typed_instr;
        if(MusEGlobal::debugMsg)
          printf("port:%d typed instrument found:%s\n",
                  port, instr->iname().toLatin1().constData());
        }
        else if(def_instr)
        {
          instr = def_instr;
          if(MusEGlobal::debugMsg)
            printf("port:%d no named or typed instrument found. Using default:%s\n",
                    port, instr->iname().toLatin1().constData());
        }
        else
        {
          instr = MusECore::genericMidiInstrument;
          if(MusEGlobal::debugMsg)
            printf("port:%d no named, typed, or default instrument found! Using:%s\n",
                    port, instr->iname().toLatin1().constData());
        }
        
        // If the instrument is one of the three standard GM, GS, or XG, mark the usedPort as "ch 10 is drums".
        // Otherwise it's anybody's guess what channel(s) drums are on.
        // Code is a bit HACKISH just to accomplish passing this bool value to the next stage, where tracks are created. 
        if(instr->midiType() != MT_UNKNOWN)
          imp->second._isStandardDrums = true;
          
        // Set the device's instrument - ONLY for non-synths because they provide their own. 
        if(!md || (md->deviceType() != MusECore::MidiDevice::SYNTH_MIDI))  
        {
          // this overwrites any instrument set for this port:
          if(mp->instrument() != instr)
            mp->setInstrument(instr);
        }
      }
      
      if(dev_changed)
      {
        // TEST: Hopefully can get away with this here instead of inside the loop above...
        // TEST: Are these really necessary as in midi port config set device name?
        MusEGlobal::muse->changeConfig(true);     // save configuration file 
        MusEGlobal::audio->msgUpdateSoloStates(); // 
        MusEGlobal::song->update();
      }
      
      //
      // create MidiTrack and copy events to ->events()
      //    - combine note on/off events
      //    - calculate tick value for internal resolution
      //
      for (MusECore::iMidiFileTrack t = etl->begin(); t != etl->end(); ++t) {
            MusECore::MPEventList& el  = ((*t)->events);
            if (el.empty())
                  continue;
            //
            // if we split the track, SYSEX and META events go into
            // the first target track

            bool first = true;
            
            // vastly changed by flo: replaced that silly loop
            // with that already_processed-set-check.
            // this makes stuff really fast :)
            
            MusECore::iMPEvent ev;
            set< pair<int,int> > already_processed;
            for (ev = el.begin(); ev != el.end(); ++ev)
            {
              if (ev->type() != MusECore::ME_SYSEX && ev->type() != MusECore::ME_META)
              {
                int channel=ev->channel();
                int port=ev->port();
                
                if (already_processed.find(pair<int,int>(channel, port)) == already_processed.end())
                {
                        already_processed.insert(pair<int,int>(channel, port));
                        
                        MusECore::MidiTrack* track = new MusECore::MidiTrack();
                        if ((*t)->_isDrumTrack)
                        {
                           if (MusEGlobal::config.importMidiNewStyleDrum)
                              track->setType(MusECore::Track::NEW_DRUM);
                           else
                              track->setType(MusECore::Track::DRUM);
                        }
                              
                        track->setOutChannel(channel);
                        track->setOutPort(port);

                        MusECore::MidiPort* mport = &MusEGlobal::midiPorts[port];
                        buildMidiEventList(&track->events, el, track, division, first, false); // Don't do loops.
                        first = false;

                        // Comment Added by T356.
                        // Hmm. buildMidiEventList already takes care of this. 
                        // But it seems to work. How? Must test. 
                        //if (channel == 9 && instr->midiType() != MT_UNKNOWN) {
                        MusECore::ciMidiFilePort imp = usedPortMap->find(port);
                        if(imp != usedPortMap->end() && imp->second._isStandardDrums && channel == 9) { // A bit HACKISH, see above
                           if (MusEGlobal::config.importMidiNewStyleDrum)
                              track->setType(MusECore::Track::NEW_DRUM);
                           else
                           {
                              track->setType(MusECore::Track::DRUM);
                              // remap drum pitch with drumOutmap (was: Inmap. flo93 thought this was wrong)
                              for (MusECore::iEvent i = track->events.begin(); i != track->events.end(); ++i) {
                                    MusECore::Event ev  = i->second;
                                    if (ev.isNote()) {
                                          int pitch = MusEGlobal::drumOutmap[ev.pitch()];
                                          ev.setPitch(pitch);
                                          }
                                    else
                                    if(ev.type() == MusECore::Controller)
                                    {
                                      int ctl = ev.dataA();
                                      MusECore::MidiController *mc = mport->drumController(ctl);
                                      if(mc)
                                        ev.setA((ctl & ~0xff) | MusEGlobal::drumOutmap[ctl & 0x7f]);
                                    }
                              }
                           }
                        }
                              
                        processTrack(track);
                        
                        MusEGlobal::song->insertTrack0(track, -1);
                }
              }
						}
						
            if (first) {
                  //
                  // track does only contain non-channel messages
                  // (SYSEX or META)
                  //
                  MusECore::MidiTrack* track = new MusECore::MidiTrack();
                  track->setOutChannel(0);
                  track->setOutPort(0);
                  buildMidiEventList(&track->events, el, track, division, true, false); // Do SysexMeta. Don't do loops.
                  processTrack(track);
                  MusEGlobal::song->insertTrack0(track, -1);
                  }
            }
            
      if (!merge) {
            MusECore::TrackList* tl = MusEGlobal::song->tracks();
            if (!tl->empty()) {
                  MusECore::Track* track = tl->front();
                  track->setSelected(true);
                  }
            MusEGlobal::song->initLen();

            int z, n;
            AL::sigmap.timesig(0, z, n);

            int tempo = MusEGlobal::tempomap.tempo(0);
            transport->setTimesig(z, n);
            transport->setTempo(tempo);

            bool masterF = !MusEGlobal::tempomap.empty();
            MusEGlobal::song->setMasterFlag(masterF);
            transport->setMasterFlag(masterF);

            MusEGlobal::song->updatePos();

            _arranger->reset();
            }
      else {
            MusEGlobal::song->initLen();
           }

      return false;
      }