diff options
| author | Werner Schweer <ws.seh.de> | 2006-10-25 21:19:08 +0000 | 
|---|---|---|
| committer | Werner Schweer <ws.seh.de> | 2006-10-25 21:19:08 +0000 | 
| commit | 0ea27d42f28aae554bb0b7ec35a4bab961d7fd98 (patch) | |
| tree | 767ce09c6aed898ea9794ae2a3076c814a3f3671 | |
| parent | 1fa1e5ede877626f6e29cfd42f4d9679723aa1ea (diff) | |
updates
| -rw-r--r-- | muse/ChangeLog | 2 | ||||
| -rw-r--r-- | muse/TODO | 4 | ||||
| -rw-r--r-- | muse/muse/audio.cpp | 22 | ||||
| -rw-r--r-- | muse/muse/conf.cpp | 10 | ||||
| -rw-r--r-- | muse/muse/driver/jack.cpp | 6 | ||||
| -rw-r--r-- | muse/muse/driver/port.h | 8 | ||||
| -rw-r--r-- | muse/muse/gconfig.cpp | 2 | ||||
| -rw-r--r-- | muse/muse/gconfig.h | 2 | ||||
| -rw-r--r-- | muse/muse/importmidi.cpp | 84 | ||||
| -rw-r--r-- | muse/muse/midi.cpp | 4 | ||||
| -rw-r--r-- | muse/muse/midioutport.cpp | 228 | ||||
| -rw-r--r-- | muse/muse/midioutport.h | 12 | ||||
| -rw-r--r-- | muse/muse/midiseq.cpp | 226 | ||||
| -rw-r--r-- | muse/muse/midiseq.h | 24 | ||||
| -rw-r--r-- | muse/muse/muse.cpp | 7 | ||||
| -rw-r--r-- | muse/muse/muse.h | 2 | ||||
| -rw-r--r-- | muse/muse/preferences.cpp | 12 | ||||
| -rw-r--r-- | muse/muse/preferences.ui | 40 | ||||
| -rw-r--r-- | muse/muse/route.cpp | 5 | ||||
| -rw-r--r-- | muse/muse/sync.cpp | 13 | 
20 files changed, 359 insertions, 354 deletions
| diff --git a/muse/ChangeLog b/muse/ChangeLog index 3056feb6..133527ea 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,3 +1,5 @@ +25.10 (ws) +      - make default path for midi- and wave import configurable  23.10 (ws)        - simple jack midi output now works  20.10 (ws) @@ -4,10 +4,6 @@  ----------------------------------------------------------------------------  BUGS -      - fix song len after importing midi -      - set song "dirty" after importing midi -      - update midi gm template -  	- updating the gui during midi recording is too slow;          a new, faster implementation is needed diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp index 53f72664..f8b5410b 100644 --- a/muse/muse/audio.cpp +++ b/muse/muse/audio.cpp @@ -38,8 +38,10 @@  #include "synth.h"  #include "midioutport.h"  #include "midiinport.h" +#include "midichannel.h" +#include "midictrl.h" +#include "sync.h" -extern double curTime();  extern bool initJackAudio();  Audio* audio; @@ -579,11 +581,9 @@ void Audio::seek(const Pos& p)        if (state != LOOP2 && !freewheel())              audioPrefetch->msgSeek(_pos.frame()); -      midiBusy = true; -      midiSeq->processSeek(); // handle stuck notes and set -                              // controller for new position -      midiBusy = false; - +      MidiOutPortList* ol = song->midiOutPorts(); +      for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i) +            (*i)->seek(_curTickPos, _pos.frame());        sendMsgToGui(MSG_SEEK);        } @@ -609,8 +609,10 @@ void Audio::startRolling()        state = PLAY;        sendMsgToGui(MSG_PLAY); -      midiSeq->msgStart(); - +      MidiOutPortList* ol = song->midiOutPorts(); +      for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i) +            (*i)->start(); +              if (precountEnableFlag           && song->click()           && !extSyncFlag @@ -650,7 +652,9 @@ void Audio::startRolling()  void Audio::stopRolling()        {        state = STOP; -      midiSeq->msgStop(); +      MidiOutPortList* ol = song->midiOutPorts(); +      for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i) +            (*i)->stop();  	recording    = false;        endRecordPos = _pos;        _bounce = 0; diff --git a/muse/muse/conf.cpp b/muse/muse/conf.cpp index 65b1c229..315f163f 100644 --- a/muse/muse/conf.cpp +++ b/muse/muse/conf.cpp @@ -260,6 +260,14 @@ void readConfiguration(QDomNode node)                    config.projectPath = s;              else if (tag == "templatePath")                    config.templatePath = s; +            else if (tag == "importMidiPath") { +                  config.importMidiPath = s; +                  lastMidiPath = museUser + "/" + s; +                  } +            else if (tag == "importWavePath") { +                  config.importWavePath = s; +                  lastWavePath = museUser + "/" + s; +                  }              else if (tag == "PianoRoll")                    PianoRoll::readConfiguration(node);              else if (tag == "DrumEdit") @@ -477,6 +485,8 @@ void MusE::writeGlobalConfiguration(Xml& xml) const        xml.intTag("createDefaultMidiInput", config.createDefaultMidiInput);        xml.strTag("projectPath", config.projectPath);        xml.strTag("templatePath", config.templatePath); +      xml.strTag("importMidiPath", config.importMidiPath); +      xml.strTag("importWavePath", config.importWavePath);        PianoRoll::writeConfiguration(xml);        DrumEdit::writeConfiguration(xml); diff --git a/muse/muse/driver/jack.cpp b/muse/muse/driver/jack.cpp index 34d33507..5e909cda 100644 --- a/muse/muse/driver/jack.cpp +++ b/muse/muse/driver/jack.cpp @@ -733,9 +733,9 @@ void JackAudio::seekTransport(unsigned frame)  Port JackAudio::findPort(const QString& name)        { -      Port p(jack_port_by_name(_client, name.toLatin1().data())); -// printf("Jack::findPort <%s>, %p\n", name.toLatin1().data(), p); -      return p; +      jack_port_t* port = jack_port_by_name(_client, name.toLatin1().data()); +// printf("Jack::findPort <%s>, %p\n", name.toLatin1().data(), port); +      return (port == 0) ? Port() : Port(port);        }  //--------------------------------------------------------- diff --git a/muse/muse/driver/port.h b/muse/muse/driver/port.h index 7386a7f3..8b1dab47 100644 --- a/muse/muse/driver/port.h +++ b/muse/muse/driver/port.h @@ -23,6 +23,10 @@  #include <jack/jack.h> +//--------------------------------------------------------- +//    Port +//--------------------------------------------------------- +  class Port {        enum { JACK_TYPE, ALSA_TYPE, ZERO_TYPE } type;        union { @@ -55,9 +59,9 @@ class Port {              else                     return true;              } -      unsigned char alsaPort() const { return _alsaPort; } +      unsigned char alsaPort() const   { return _alsaPort; }        unsigned char alsaClient() const { return _alsaClient; } -      jack_port_t* jackPort() const { return _jackPort; } +      jack_port_t* jackPort() const    { return _jackPort; }        };  #endif diff --git a/muse/muse/gconfig.cpp b/muse/muse/gconfig.cpp index 78d24194..3fb98749 100644 --- a/muse/muse/gconfig.cpp +++ b/muse/muse/gconfig.cpp @@ -123,4 +123,6 @@ GlobalConfigValues config = {        true,                         // createDefaultMidiInput        QString("MusE/projects"),     // projectPath        QString("MusE/templates"),    // templatePath +      QString("MusE/"),             // midi import path +      QString("MusE/"),             // wave import path        }; diff --git a/muse/muse/gconfig.h b/muse/muse/gconfig.h index 494ea6ff..58299403 100644 --- a/muse/muse/gconfig.h +++ b/muse/muse/gconfig.h @@ -124,6 +124,8 @@ struct GlobalConfigValues {        bool createDefaultMidiInput;        QString projectPath;        QString templatePath; +      QString importMidiPath; +      QString importWavePath;        };  extern GlobalConfigValues config; diff --git a/muse/muse/importmidi.cpp b/muse/muse/importmidi.cpp index 80dfa9fd..896cf5f3 100644 --- a/muse/muse/importmidi.cpp +++ b/muse/muse/importmidi.cpp @@ -127,9 +127,9 @@ void MusE::importMidi(const QString &file)        if (file.isEmpty()) {              fn = getOpenFileName(lastMidiPath, pattern, this,                 tr("MusE: Import Midi")); +            lastMidiPath = fn;              if (fn.isEmpty())                    return; -            lastMidiPath = fn;              }        else              fn = file; @@ -206,7 +206,7 @@ void MusE::importMidi(const QString &file)                    QString msg(tr("File <%1> read error"));                    QMessageBox::critical(this, header, msg.arg(s));                    } -            importMidi(fn, true); +            addMidiFile(fn);              tr_id->setChecked(config.transportVisible);              bt_id->setChecked(config.bigTimeVisible); @@ -282,21 +282,21 @@ void MusE::importMidi(const QString &file)              }        else {              // add to project -            importMidi(fn, true); +            addMidiFile(fn);              song->update(-1);              }        }  //--------------------------------------------------------- -//   importMidi +//   addMidiFile  //    return true on error  //--------------------------------------------------------- -bool MusE::importMidi(const QString name, bool merge) +void MusE::addMidiFile(const QString name)        {        QFile* fp = fileOpen(this, name, QString(".mid"), QIODevice::ReadOnly);        if (fp == 0) -            return true; +            return;        MidiFile mf;        bool rv = mf.read(fp);        fp->close(); @@ -308,7 +308,7 @@ bool MusE::importMidi(const QString name, bool merge)              s += tr("\nfailed: ");              s += mf.error();              QMessageBox::critical(this, QString("MusE"), s); -            return rv; +            return;              }        MidiFileTrackList* etl = mf.trackList();        int division           = mf.division(); @@ -316,7 +316,7 @@ bool MusE::importMidi(const QString name, bool merge)        MidiOutPort* outPort = 0;        MidiInPort* inPort = 0; -      if (!merge || song->midiOutPorts()->empty()) { +      if (song->midiOutPorts()->empty()) {              outPort = new MidiOutPort();              outPort->setDefaultName();              song->insertTrack0(outPort, -1); @@ -427,8 +427,9 @@ bool MusE::importMidi(const QString name, bool merge)                          continue;                    MidiTrack* track = new MidiTrack(); -//TODO3                  if ((*t)->isDrumTrack) -//                        track->setUseDrumMap(true); +                  MidiChannel* mc = outPort->channel(channel); +                  if ((*t)->isDrumTrack) +                        mc->setUseDrumMap(true);                    track->outRoutes()->push_back(Route(outPort->channel(channel), -1, Route::TRACK));                    if (inPort && config.connectToAllMidiTracks) {                          for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { @@ -446,19 +447,18 @@ bool MusE::importMidi(const QString name, bool merge)                          if (event.type() == Controller) {                                int ctrl = event.dataA();                                MidiInstrument* instr = outPort->instrument(); -                              MidiChannel* mc = outPort->channel(channel);                                mc->addMidiController(instr, ctrl);                                CVal val;                                val.i = event.dataB();                                mc->addControllerVal(ctrl, event.tick(), val);                                }                          } -#if 0 //TODO3                    if (channel == 9) { -                        track->setUseDrumMap(true); +                        mc->setUseDrumMap(true);                          //                          // remap drum pitch with drumInmap                          // +#if 0 //TODO                          EventList* tevents = track->events();                          for (iEvent i = tevents->begin(); i != tevents->end(); ++i) {                                Event ev  = i->second; @@ -467,8 +467,8 @@ bool MusE::importMidi(const QString name, bool merge)                                      ev.setPitch(pitch);                                      }                                } -                        }  #endif +                        }                    processTrack(track);                    if (track->name().isEmpty())                          track->setDefaultName(); @@ -490,40 +490,36 @@ bool MusE::importMidi(const QString name, bool merge)                    }              } -      if (!merge) { -            TrackList* tl = song->tracks(); -            if (!tl->empty()) { -                  Track* track = tl->front(); -                  track->setSelected(true); -                  } -            unsigned int l = 1; -            MidiTrackList* mtl = song->midis(); -            for (iMidiTrack t = mtl->begin(); t != mtl->end(); ++t) { -                  MidiTrack* track = *t; -                  PartList* parts = track->parts(); -                  for (iPart p = parts->begin(); p != parts->end(); ++p) { -                        unsigned last = p->second->tick() + p->second->lenTick(); -                        if (last > l) -                              l = last; -                        } +      TrackList* tl = song->tracks(); +      if (!tl->empty()) { +            Track* track = tl->front(); +            track->setSelected(true); +            } +      unsigned int l = 1; +      MidiTrackList* mtl = song->midis(); +      for (iMidiTrack t = mtl->begin(); t != mtl->end(); ++t) { +            MidiTrack* track = *t; +            PartList* parts = track->parts(); +            for (iPart p = parts->begin(); p != parts->end(); ++p) { +                  unsigned last = p->second->tick() + p->second->lenTick(); +                  if (last > l) +                        l = last;                    } -            song->setLen(l); - -            AL::TimeSignature sig = AL::sigmap.timesig(0); -            int z = sig.z; -            int n = sig.n; +            } +      song->setLen(l); +      AL::TimeSignature sig = AL::sigmap.timesig(0); +      int z = sig.z; +      int n = sig.n; -            transport->setTimesig(z, n); -//            int tempo = AL::tempomap.tempo(0); -//            transport->setTempo(tempo); +      transport->setTimesig(z, n); +//    int tempo = AL::tempomap.tempo(0); +//    transport->setTempo(tempo); -            bool masterF = !AL::tempomap.empty(); -            song->setMasterFlag(masterF); -            transport->setMasterFlag(masterF); +      bool masterF = !AL::tempomap.empty(); +      song->setMasterFlag(masterF); +      transport->setMasterFlag(masterF); -            song->updatePos(); -            } -      return false; +      song->updatePos();        }  //--------------------------------------------------------- diff --git a/muse/muse/midi.cpp b/muse/muse/midi.cpp index 3bab9108..47556328 100644 --- a/muse/muse/midi.cpp +++ b/muse/muse/midi.cpp @@ -641,10 +641,9 @@ void Audio::initDevices()  void Audio::processMidi()        { -      midiBusy = true;        MidiOutPortList* ol = song->midiOutPorts();        for (iMidiOutPort id = ol->begin(); id != ol->end(); ++id) { -            (*id)->process(_curTickPos, _nextTickPos); +            (*id)->process(_curTickPos, _nextTickPos, _pos.frame(), _pos.frame() + segmentSize);              }        MidiInPortList* il = song->midiInPorts(); @@ -664,6 +663,5 @@ void Audio::processMidi()                    }              port->afterProcess();              } -      midiBusy = false;        } diff --git a/muse/muse/midioutport.cpp b/muse/muse/midioutport.cpp index 845f6feb..371ce55a 100644 --- a/muse/muse/midioutport.cpp +++ b/muse/muse/midioutport.cpp @@ -21,6 +21,7 @@  #include "song.h"  #include "midiplugin.h"  #include "midictrl.h" +#include "al/al.h"  #include "al/tempo.h"  #include "al/xml.h"  #include "driver/mididev.h" @@ -28,6 +29,9 @@  #include "audio.h"  #include "midioutport.h"  #include "midichannel.h" +#include "midiseq.h" +#include "sync.h" +#include "gconfig.h"  //---------------------------------------------------------  //   MidiOutPort @@ -382,14 +386,18 @@ void MidiOutPort::playMidiEvent(MidiEvent* ev)              }        } -//--------------------------------------------------------- +//-------------------------------------------------------------------  //   process -//    "play" events for this process cycle -//    from/to are midi ticks -//    if (from != to)  then transport state is "playing" -//--------------------------------------------------------- - -void MidiOutPort::process(unsigned from, unsigned to) +//    Collect all midi events for the current process cycle and put +//    into _schedEvents queue. For note on events create the proper +//    note off events. The note off events maybe played after the +//    current process cycle. +//    From _schedEvents queue copy all events for the current cycle +//    to all output routes. Events routed to ALSA go into the  +//    _playEvents queue which is processed by the MidiSeq thread. +//------------------------------------------------------------------- + +void MidiOutPort::process(unsigned fromTick, unsigned toTick, unsigned, unsigned toFrame)        {        if (mute())              return; @@ -399,12 +407,12 @@ void MidiOutPort::process(unsigned from, unsigned to)              el.add(eventFifo.get());        // collect port controller -      if (from != to) { +      if (fromTick != toTick) {     // if rolling              CtrlList* cl = controller();              for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {                    Ctrl* c = ic->second; -                  iCtrlVal is = c->lower_bound(from); -                  iCtrlVal ie = c->lower_bound(to); +                  iCtrlVal is = c->lower_bound(fromTick); +                  iCtrlVal ie = c->lower_bound(toTick);                    for (iCtrlVal ic = is; ic != ie; ++ic) {                          unsigned frame = AL::tempomap.tick2frame(ic->first);                          Event ev(Controller); @@ -422,12 +430,12 @@ void MidiOutPort::process(unsigned from, unsigned to)              if (mc->mute() || mc->noInRoute())                    continue;              // collect channel controller -            if (from != to) { +            if (fromTick != toTick) {                    CtrlList* cl = mc->controller();                    for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {                          Ctrl* c = ic->second; -                        iCtrlVal is = c->lower_bound(from); -                        iCtrlVal ie = c->lower_bound(to); +                        iCtrlVal is = c->lower_bound(fromTick); +                        iCtrlVal ie = c->lower_bound(toTick);                          for (; is != ie; ++is) {                                unsigned frame = AL::tempomap.tick2frame(is->first);                                Event ev(Controller); @@ -445,7 +453,7 @@ void MidiOutPort::process(unsigned from, unsigned to)                    if (track->isMute())                          continue;                    MPEventList ell; -                  track->getEvents(from, to, 0, &ell); +                  track->getEvents(fromTick, toTick, 0, &ell);                    int velo = 0;                    for (iMPEvent i = ell.begin(); i != ell.end(); ++i) {                          MidiEvent ev(*i); @@ -460,29 +468,43 @@ void MidiOutPort::process(unsigned from, unsigned to)              }        addMidiMeter(portVelo); -      MPEventList ol; -      pipeline()->apply(from, to, &el, &ol); +      pipeline()->apply(fromTick, toTick, &el, &_schedEvents);        //        // route events to destination        // -      for (iMPEvent i = ol.begin(); i != ol.end(); ++i) { -            for (iRoute r = _outRoutes.begin(); r != _outRoutes.end(); ++r) { -                  switch (r->type) { -                        case Route::MIDIPORT: -                              _playEvents.add(*i);    // schedule -                              break; -                        case Route::SYNTIPORT:  -                              ((SynthI*)(r->track))->playEvents()->insert(*i); -                              break; -                        case Route::JACKMIDIPORT: -                              audioDriver->putEvent(jackPort(0), *i); -                              break; -                        default: -                              fprintf(stderr, "MidiOutPort::process(): invalid routetype\n"); -                              break; -                        } +      for (iMPEvent i = _schedEvents.begin(); i != _schedEvents.end(); ++i) { +            if (i->time() >= toFrame) { +                  _schedEvents.erase(_schedEvents.begin(), i); +                  break; +                  } +            routeEvent(*i); +            } +      } + +//--------------------------------------------------------- +//    routeEvent +//--------------------------------------------------------- + +void MidiOutPort::routeEvent(const MidiEvent& event) +      { +      for (iRoute r = _outRoutes.begin(); r != _outRoutes.end(); ++r) { +            switch (r->type) { +                  case Route::MIDIPORT: +                        midiBusy = true; +                        _playEvents.insert(event);    // schedule +                        midiBusy = false; +                        break; +                  case Route::SYNTIPORT:  +                        ((SynthI*)(r->track))->playEvents()->insert(event); +                        break; +                  case Route::JACKMIDIPORT: +                        audioDriver->putEvent(jackPort(0), event); +                        break; +                  default: +                        fprintf(stderr, "MidiOutPort::process(): invalid routetype\n"); +                        break;                    }              }        } @@ -506,3 +528,145 @@ void MidiOutPort::setSendSync(bool val)        _sendSync = val;        emit sendSyncChanged(val);        } + +//--------------------------------------------------------- +//    seek +//--------------------------------------------------------- + +void MidiOutPort::seek(unsigned tickPos, unsigned framePos) +      { +      if (genMCSync && sendSync()) { +            int beat = (tickPos * 4) / config.division; +            sendStop(); +            sendSongpos(beat); +            sendContinue(); +            } +      if (mute()) +            return; + +//    if (pos == 0 && !song->record()) +//          audio->initDevices(); + +      //--------------------------------------------------- +      //    stop all notes +      //--------------------------------------------------- + +      for (iMPEvent i = _schedEvents.begin(); i != _schedEvents.end(); ++i) { +            MidiEvent ev = *i; +            if (ev.isNoteOff()) { +                  ev.setTime(framePos); +                  routeEvent(ev); +                  } +            } +      _schedEvents.clear(); + +      //--------------------------------------------------- +      //    set all controller +      //--------------------------------------------------- + +      for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { +            MidiChannel* mc = channel(ch); +            if (mc->mute() || mc->noInRoute() || !mc->autoRead()) +                  continue; +            CtrlList* cll = mc->controller(); +            for (iCtrl ivl = cll->begin(); ivl != cll->end(); ++ivl) { +                  Ctrl* c   = ivl->second; +                  int val = c->value(tickPos).i; +                  if (val != CTRL_VAL_UNKNOWN && val != c->curVal().i) { +                        routeEvent(MidiEvent(0, ch, ME_CONTROLLER, c->id(), val)); +                        } +                  } +            } +      } + +//--------------------------------------------------------- +//   stop +//--------------------------------------------------------- + +void MidiOutPort::stop() +      { +      int frame = AL::tempomap.tick2frame(audio->curTickPos()); + +      //--------------------------------------------------- +      //    stop all notes +      //--------------------------------------------------- + +      for (iMPEvent i = _schedEvents.begin(); i != _schedEvents.end(); ++i) { +            MidiEvent ev = *i; +            if (ev.isNoteOff()) { +                  ev.setTime(frame); +                  routeEvent(ev); +                  } +            } +      _schedEvents.clear(); + +      //--------------------------------------------------- +      //    reset sustain +      //--------------------------------------------------- + +      for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { +            MidiChannel* mc = channel(ch); +            if (mc->noInRoute()) +                  continue; +            if (mc->hwCtrlState(CTRL_SUSTAIN) != CTRL_VAL_UNKNOWN) { +                  MidiEvent ev(0, 0, ME_CONTROLLER, CTRL_SUSTAIN, 0); +                  ev.setChannel(mc->channelNo()); +                  routeEvent(ev); +                  } +            } + +      if (sendSync()) { +            if (genMMC) { +                  unsigned char mmcPos[] = { +                        0x7f, 0x7f, 0x06, 0x44, 0x06, 0x01, +                        0, 0, 0, 0, 0 +                        }; +                  MTC mtc(double(frame) / double(AL::sampleRate)); +                  mmcPos[6] = mtc.h() | (AL::mtcType << 5); +                  mmcPos[7] = mtc.m(); +                  mmcPos[8] = mtc.s(); +                  mmcPos[9] = mtc.f(); +                  mmcPos[10] = mtc.sf(); +//TODO                  mp->sendSysex(mmcStopMsg, sizeof(mmcStopMsg)); +//                  mp->sendSysex(mmcPos, sizeof(mmcPos)); +                  } +            if (genMCSync) {         // Midi Clock +                  // send STOP and +                  // "set song position pointer" +//                  mp->sendStop(); +//                  mp->sendSongpos(audio->curTickPos() * 4 / config.division); +                  } +            } +      } + +//--------------------------------------------------------- +//   start +//--------------------------------------------------------- + +void MidiOutPort::start() +      { +#if 0 +      if (!(genMMC || genMCSync)) +            return; +      if (!sendSync()) +            return; +      if (genMMC) +            sendSysex(mmcDeferredPlayMsg, sizeof(mmcDeferredPlayMsg)); +      if (genMCSync) { +            if (audio->curTickPos()) +                  sendContinue(); +            else +                  sendStart(); +            } +#endif +      } + +//--------------------------------------------------------- +//   reset +//--------------------------------------------------------- + +void MidiOutPort::reset() +      { +      instrument()->reset(this); +      } + diff --git a/muse/muse/midioutport.h b/muse/muse/midioutport.h index 70e3c97c..3f376c43 100644 --- a/muse/muse/midioutport.h +++ b/muse/muse/midioutport.h @@ -33,10 +33,11 @@ class MidiOutPort : public MidiTrackBase {        MidiInstrument* _instrument;        MidiChannel* _channel[MIDI_CHANNELS]; -      bool _sendSync;   // this port sends mtc mmc events +      bool _sendSync;   // this port sends mtc/mmc events        int _deviceId;    // 0-126; 127 == all -      MPEventList _playEvents;   // scheduled events to play +      MPEventList _schedEvents;  // scheduled events by process() +      MPEventList _playEvents;   // event queue for MidiSeq        // fifo for midi events send from gui        // direct to midi port: @@ -72,7 +73,7 @@ class MidiOutPort : public MidiTrackBase {        MPEventList* playEvents()          { return &_playEvents;   } -      void process(unsigned from, unsigned to); +      void process(unsigned fromTick, unsigned toTick, unsigned fromFrame, unsigned toFrame);        void playMidiEvent(MidiEvent*); @@ -91,6 +92,11 @@ class MidiOutPort : public MidiTrackBase {        int deviceId() const      { return _deviceId; }        void setDeviceId(int val) { _deviceId = val; } + +      void seek(unsigned, unsigned); +      void stop(); +      void start(); +      void reset();        };  #endif diff --git a/muse/muse/midiseq.cpp b/muse/muse/midiseq.cpp index f569237d..028e0c0d 100644 --- a/muse/muse/midiseq.cpp +++ b/muse/muse/midiseq.cpp @@ -69,18 +69,9 @@ void MidiSeq::processMsg(const ThreadMsg* m)        {        AudioMsg* msg = (AudioMsg*)m;        switch (msg->id) { -            case MS_START: -                  processStart(); -                  break; -            case MS_STOP: -                  processStop(); -                  break;              case MS_SET_RTC:                    initRealtimeTimer();                    break; -            case SEQM_RESET_DEVICES: -                  resetDevices(); -                  break;              case SEQM_ADD_TRACK:                    song->insertTrack2(msg->track);                    updatePollFd(); @@ -98,9 +89,6 @@ void MidiSeq::processMsg(const ThreadMsg* m)              case SEQM_CHANGE_PART:                    song->cmdChangePart((Part*)msg->p1, (Part*)msg->p2);                    break; -            case SEQM_IDLE: -                  idle = msg->a; -                  break;              case SEQM_MOVE_TRACK:                    song->moveTrack((Track*)(msg->p1), (Track*)(msg->p2));                    break; @@ -114,198 +102,12 @@ void MidiSeq::processMsg(const ThreadMsg* m)        }  //--------------------------------------------------------- -//   processStart -//--------------------------------------------------------- - -void MidiSeq::processStart() -      { -      if (genMMC || genMCSync) { -            MidiOutPortList* ol = song->midiOutPorts(); -            for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i) { -                  MidiOutPort* mp = *i; -                  if (!mp->sendSync()) -                        continue; -                  if (genMMC) -                        mp->sendSysex(mmcDeferredPlayMsg, sizeof(mmcDeferredPlayMsg)); -                  if (genMCSync) { -                        if (audio->curTickPos()) -                              mp->sendContinue(); -                        else -                              mp->sendStart(); -                        } -                  } -            } -      } - -//--------------------------------------------------------- -//   processStop -//    synced with audio process() -//--------------------------------------------------------- - -void MidiSeq::processStop() -      { -      //--------------------------------------------------- -      //    stop stuck notes -      //--------------------------------------------------- - -      MidiOutPortList* ol = song->midiOutPorts(); -      for (iMidiOutPort id = ol->begin(); id != ol->end(); ++id) { -            MidiOutPort* md = *id; -            if (md->noOutRoute()) -                  continue; -            MPEventList* pel = md->playEvents(); -            for (iMPEvent i = pel->begin(); i != pel->end(); ++i) { -                  MidiEvent ev = *i; -                  if (ev.isNoteOff()) { -                        ev.setTime(0); -                        md->putEvent(ev); -                        } -                  } -            pel->clear(); -            } - -      //--------------------------------------------------- -      //    reset sustain -      //--------------------------------------------------- - -      MidiChannelList* mcl = song->midiChannel(); -      for (iMidiChannel i = mcl->begin(); i != mcl->end(); ++i) { -            MidiChannel* mc = *i; -            if (mc->noInRoute()) -                  continue; -            MidiOutPort* mp = mc->port(); -            if (mc->hwCtrlState(CTRL_SUSTAIN) != CTRL_VAL_UNKNOWN) { -                  MidiEvent ev(0, 0, ME_CONTROLLER, CTRL_SUSTAIN, 0); -                  ev.setChannel(mc->channelNo()); -                  mp->putEvent(ev); -                  } -            } - -      if (genMMC || genMCSync) { -            MidiOutPortList* ol = song->midiOutPorts(); -            for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i) { -                  MidiOutPort* mp = *i; -                  if (!mp->sendSync()) -                        continue; -                  if (genMMC) { -                        unsigned char mmcPos[] = { -                              0x7f, 0x7f, 0x06, 0x44, 0x06, 0x01, -                              0, 0, 0, 0, 0 -                              }; -                        int frame = AL::tempomap.tick2frame(audio->curTickPos()); -                        MTC mtc(double(frame) / double(AL::sampleRate)); -                        mmcPos[6] = mtc.h() | (AL::mtcType << 5); -                        mmcPos[7] = mtc.m(); -                        mmcPos[8] = mtc.s(); -                        mmcPos[9] = mtc.f(); -                        mmcPos[10] = mtc.sf(); -                        mp->sendSysex(mmcStopMsg, sizeof(mmcStopMsg)); -                        mp->sendSysex(mmcPos, sizeof(mmcPos)); -                        } -                  if (genMCSync) {         // Midi Clock -                        // send STOP and -                        // "set song position pointer" -                        mp->sendStop(); -                        mp->sendSongpos(audio->curTickPos() * 4 / config.division); -                        } -                  } -            } -      } - -//--------------------------------------------------------- -//   resetDevices -//--------------------------------------------------------- - -void MidiSeq::resetDevices() -      { -      MidiOutPortList* ol = song->midiOutPorts(); -      for (iMidiOutPort id = ol->begin(); id != ol->end(); ++id) { -            MidiOutPort* md = *id; -            MidiInstrument* instr = md->instrument(); -            instr->reset(md); -            } -      } - -//--------------------------------------------------------- -//   processSeek -//    synced with audio process() -//--------------------------------------------------------- - -void MidiSeq::processSeek() -      { -      int pos = audio->curTickPos(); -      if (genMCSync) { -            MidiOutPortList* ol = song->midiOutPorts(); -            for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i) { -                  MidiOutPort* mp = *i; -                  if (!mp->sendSync()) -                        continue; -                  int beat = (pos * 4) / config.division; -                  mp->sendStop(); -                  mp->sendSongpos(beat); -                  mp->sendContinue(); -                  } -            } - -//      if (pos == 0 && !song->record()) -//            audio->initDevices(); - -      //--------------------------------------------------- -      //    set all controller -      //--------------------------------------------------- - -      MidiOutPortList* opl = song->midiOutPorts(); - -      for (iMidiOutPort i = opl->begin(); i != opl->end(); ++i) { -            MidiOutPort* op = *i; -            if (op->mute()) -                  continue; -            MPEventList* el = op->playEvents(); -            if (audio->isPlaying()) { -                  // stop all notes -                  for (iMPEvent i = el->begin(); i != el->end(); ++i) { -                        MidiEvent ev = *i; -                        if (ev.isNoteOff()) { -                              ev.setTime(0); -                              op->putEvent(ev); -                              // el->add(ev); -                              } -                        } -                  el->clear(); -                  } -//            else -//                  el->erase(el->begin(), op->nextPlayEvent()); -            for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { -                  MidiChannel* mc = op->channel(ch); -                  if (mc->mute() || mc->noInRoute() || !mc->autoRead()) -                        continue; -                  CtrlList* cll = mc->controller(); -                  for (iCtrl ivl = cll->begin(); ivl != cll->end(); ++ivl) { -                        Ctrl* c   = ivl->second; -                        int val = c->value(pos).i; -                        if (val != CTRL_VAL_UNKNOWN && val != c->curVal().i) { -                              op->putEvent(MidiEvent(0, ch, ME_CONTROLLER, c->id(), val)); -                              } -                        } -                  } -//            op->setNextPlayEvent(op->playEvents()->begin()); -            } -      } - -//---------------------------------------------------------  //   MidiSeq  //---------------------------------------------------------  MidiSeq::MidiSeq(const char* name)     : Thread(name)        { -      idle      = false; -      midiClock = 0; -      mclock1 = 0.0; -      mclock2 = 0.0; -      songtick1 = songtick2 = 0; -      lastTempo = 0; -      storedtimediffs = 0;        timer = 0;        } @@ -346,10 +148,9 @@ void MidiSeq::threadStart(void*)                    printf("midi thread %d _NOT_ running SCHED_FIFO\n", getpid());              else if (debugMsg) {              	struct sched_param rt_param; -            	int rv;              	memset(&rt_param, 0, sizeof(sched_param));              	int type; -            	rv = pthread_getschedparam(pthread_self(), &type, &rt_param); +            	int rv = pthread_getschedparam(pthread_self(), &type, &rt_param);              	if (rv == -1)                    	perror("get scheduler parameter");                    printf("midiseq thread running SCHED_FIFO priority %d\n", @@ -454,13 +255,14 @@ bool MidiSeq::start(int prio)        return false;        } +#if 0  //---------------------------------------------------------  //   processMidiClock  //---------------------------------------------------------  void MidiSeq::processMidiClock()        { -/*      if (genMCSync) +      if (genMCSync)              midiPorts[txSyncPort].sendClock();        if (state == START_PLAY) {              // start play on sync @@ -477,16 +279,15 @@ void MidiSeq::processMidiClock()              rtcTickStart   = rtcTick - lrint(cpos * realRtcTicks);              endSlice       = playTickPos; -            recTick        = playTickPos;              lastTickPos    = playTickPos;              tempoSN = tempomap.tempoSN();              startRecordPos.setPosTick(playTickPos);              } -*/        midiClock += config.division/24;        } +#endif  //---------------------------------------------------------  //   midiTick @@ -509,26 +310,15 @@ void MidiSeq::processTimerTick()        timer->getTimerTicks();  // read elapsed rtc timer ticks -      if (idle) -            return; -        if (midiBusy) { -            // we hit audio: midiSeq->msgProcess              // miss this timer tick              return;              } -      unsigned curFrame = audioDriver->framePos(); - -/*      if (!extSyncFlag.value()) { -            int curTick = AL::tempomap.frame2tick(curFrame); -            if (curTick >= midiClock) -                  processMidiClock(); -            } -  */ -        // -      // play all events upto curFrame +      // schedule all events upto framePos-segmentSize +      // (previous segment)        // +      unsigned curFrame = audioDriver->framePos() - segmentSize;        MidiOutPortList* ol = song->midiOutPorts();        for (iMidiOutPort id = ol->begin(); id != ol->end(); ++id) {              MidiOutPort* mp = *id; @@ -555,7 +345,5 @@ void MidiSeq::msgMsg(int id)        Thread::sendMsg(&msg);        } -void MidiSeq::msgStop()         { msgMsg(MS_STOP); } -void MidiSeq::msgStart()        { msgMsg(MS_START); }  void MidiSeq::msgSetRtc()       { msgMsg(MS_SET_RTC); } diff --git a/muse/muse/midiseq.h b/muse/muse/midiseq.h index 8f29a292..91a90b1a 100644 --- a/muse/muse/midiseq.h +++ b/muse/muse/midiseq.h @@ -41,29 +41,23 @@ class MTC;  class MidiSeq : public Thread {        int realRtcTicks;        Timer* timer; -      int idle;        int midiClock;  /* Testing */ -      int recTick;            // ext sync tick position -      int lastTickPos;        // position of last sync tick +//      int lastTickPos;        // position of last sync tick        // run values: -      unsigned _midiTick; -      double mclock1, mclock2; -      double songtick1, songtick2; -      int recTick1, recTick2; -      int lastTempo; -      double timediff[24]; -      int storedtimediffs; +//      unsigned _midiTick; +//      double mclock1, mclock2; +//      double songtick1, songtick2; +//      int recTick1, recTick2; +//      int lastTempo; +//      double timediff[24]; +//      int storedtimediffs;  /* Testing */        bool initRealtimeTimer();        static void midiTick(void* p, void*);        void processTimerTick(); -      void processStart(); -      void processStop(); -      void resetDevices(); -      void processMidiClock();        virtual void processMsg(const ThreadMsg*);        void updatePollFd(); @@ -84,12 +78,10 @@ class MidiSeq : public Thread {        void msgMsg(int id);        void msgStart(); -      void msgStop();        void msgSetRtc();        void msgAddSynthI(SynthI* synth);        void msgRemoveSynthI(SynthI* synth); -      void processSeek();        };  extern MidiSeq* midiSeq; diff --git a/muse/muse/muse.cpp b/muse/muse/muse.cpp index 0b5a2967..25a0a1ff 100644 --- a/muse/muse/muse.cpp +++ b/muse/muse/muse.cpp @@ -2838,15 +2838,16 @@ int main(int argc, char* argv[])        {        museUser = QString(getenv("MUSEHOME"));        if (museUser.isEmpty()) -            museUser = QString(getenv("HOME")); +            museUser = QDir::homePath();        QString museGlobal;        const char* p = getenv("MUSE");        museGlobal = p ? p : INSTPREFIX;        museGlobalLib   =  museGlobal + "/lib/"   INSTALL_NAME;        museGlobalShare =  museGlobal + "/share/" INSTALL_NAME; - -      configName  = museUser + QString("/." INSTALL_NAME); +      configName      = museUser + QString("/." INSTALL_NAME); +      lastMidiPath    = museUser + "/" + ::config.importMidiPath; +      lastWavePath    = museUser + "/" + ::config.importWavePath;        srand(time(0));   // initialize random number generator        initMidiController(); diff --git a/muse/muse/muse.h b/muse/muse/muse.h index ee347719..5045df19 100644 --- a/muse/muse/muse.h +++ b/muse/muse/muse.h @@ -173,6 +173,7 @@ class MusE : public QMainWindow // , public Ui::MuseBase        bool leaveProject();        virtual void focusInEvent(QFocusEvent*); +      void addMidiFile(const QString name);     signals:        void configChanged(); @@ -276,7 +277,6 @@ class MusE : public QMainWindow // , public Ui::MuseBase        MusE();        Arranger* arranger;        QRect configGeometryMain; -      bool importMidi(const QString name, bool merge);        void kbAccel(int);        void changeConfig(bool writeFlag); diff --git a/muse/muse/preferences.cpp b/muse/muse/preferences.cpp index e2385155..52773b53 100644 --- a/muse/muse/preferences.cpp +++ b/muse/muse/preferences.cpp @@ -328,6 +328,8 @@ PreferencesDialog::PreferencesDialog(Arranger* a, QWidget* parent)        showSplash->setChecked(config->showSplashScreen);        projectPath->setText(config->projectPath);        templatePath->setText(config->templatePath); +      midiImportPath->setText(config->importMidiPath); +      waveImportPath->setText(config->importWavePath);        stopActive->setChecked(midiRCList.isActive(RC_STOP));        playActive->setChecked(midiRCList.isActive(RC_PLAY)); @@ -360,7 +362,6 @@ PreferencesDialog::PreferencesDialog(Arranger* a, QWidget* parent)        waveEditorWidth->setValue(WaveEdit::initWidth);        waveEditorHeight->setValue(WaveEdit::initHeight); -        connect(recordStop,         SIGNAL(clicked(bool)), SLOT(recordStopToggled(bool)));        connect(recordRecord,       SIGNAL(clicked(bool)), SLOT(recordRecordToggled(bool)));        connect(recordGotoLeftMark, SIGNAL(clicked(bool)), SLOT(recordGotoLeftMarkToggled(bool))); @@ -587,8 +588,13 @@ void PreferencesDialog::apply()        ::config.useJackFreewheelMode = freewheelMode->isChecked();        ::config.showSplashScreen = showSplash->isChecked(); -      ::config.projectPath = projectPath->text(); -      ::config.templatePath = templatePath->text(); +      ::config.projectPath    = projectPath->text(); +      ::config.templatePath   = templatePath->text(); +      ::config.importMidiPath = midiImportPath->text(); +      ::config.importWavePath = waveImportPath->text(); + +      lastMidiPath = museUser + "/" + ::config.importMidiPath; +      lastWavePath = museUser + "/" + ::config.importWavePath;        PianoRoll::initWidth  = pianorollWidth->value();        PianoRoll::initHeight = pianorollHeight->value(); diff --git a/muse/muse/preferences.ui b/muse/muse/preferences.ui index 7e690d89..c7adf58f 100644 --- a/muse/muse/preferences.ui +++ b/muse/muse/preferences.ui @@ -5,8 +5,8 @@     <rect>      <x>0</x>      <y>0</y> -    <width>731</width> -    <height>590</height> +    <width>665</width> +    <height>631</height>     </rect>    </property>    <property name="windowTitle" > @@ -22,7 +22,7 @@     <item>      <widget class="QTabWidget" name="tabWidget" >       <property name="currentIndex" > -      <number>6</number> +      <number>0</number>       </property>       <widget class="QWidget" name="tab" >        <attribute name="title" > @@ -139,16 +139,29 @@            <property name="spacing" >             <number>6</number>            </property> +          <item row="1" column="3" > +           <widget class="QLineEdit" name="waveImportPath" /> +          </item> +          <item row="0" column="3" > +           <widget class="QLineEdit" name="midiImportPath" /> +          </item>            <item row="1" column="1" >             <widget class="QLineEdit" name="templatePath" />            </item>            <item row="0" column="1" >             <widget class="QLineEdit" name="projectPath" />            </item> -          <item row="1" column="0" > -           <widget class="QLabel" name="label_35" > +          <item row="0" column="2" > +           <widget class="QLabel" name="label_36" >              <property name="text" > -             <string>Templates</string> +             <string>Midi Import</string> +            </property> +           </widget> +          </item> +          <item row="1" column="2" > +           <widget class="QLabel" name="label_37" > +            <property name="text" > +             <string>Wave Import</string>              </property>             </widget>            </item> @@ -159,6 +172,13 @@              </property>             </widget>            </item> +          <item row="1" column="0" > +           <widget class="QLabel" name="label_35" > +            <property name="text" > +             <string>Templates</string> +            </property> +           </widget> +          </item>           </layout>          </widget>         </item> @@ -2228,14 +2248,14 @@     <header>quantcombo.h</header>    </customwidget>    <customwidget> -   <class>RecordButton</class> +   <class>GreendotButton</class>     <extends>QToolButton</extends> -   <header>recordbutton.h</header> +   <header>greendotbutton.h</header>    </customwidget>    <customwidget> -   <class>GreendotButton</class> +   <class>RecordButton</class>     <extends>QToolButton</extends> -   <header>greendotbutton.h</header> +   <header>recordbutton.h</header>    </customwidget>    <customwidget>     <class>RasterCombo</class> diff --git a/muse/muse/route.cpp b/muse/muse/route.cpp index 39f9a802..8b4a9ca6 100644 --- a/muse/muse/route.cpp +++ b/muse/muse/route.cpp @@ -253,10 +253,13 @@ QString Route::name() const              case SYNTIPORT:                    return track2name(track);              case AUDIOPORT: -                  return audioDriver->portName(port);              case JACKMIDIPORT: +                  if (port.isZero()) +                        return QString("0");                    return audioDriver->portName(port);              case MIDIPORT: +                  if (port.isZero()) +                        return QString("0");                    return midiDriver->portName(port);              case AUXPLUGIN:                    return plugin->pluginInstance()->name(); diff --git a/muse/muse/sync.cpp b/muse/muse/sync.cpp index 98946a9b..2176453b 100644 --- a/muse/muse/sync.cpp +++ b/muse/muse/sync.cpp @@ -71,6 +71,7 @@ enum {  void MidiSeq::mmcInput(int id, int cmd, const Pos& pos)        { +#if 0        int rxDeviceId = 127;        if (!extSyncFlag || !acceptMMC || (id != 127 && id != rxDeviceId)) @@ -120,6 +121,7 @@ void MidiSeq::mmcInput(int id, int cmd, const Pos& pos)                    printf("MMC id %x cmd %x, unknown\n", id, cmd);                    break;              } +#endif        }  //--------------------------------------------------------- @@ -129,6 +131,7 @@ void MidiSeq::mmcInput(int id, int cmd, const Pos& pos)  void MidiSeq::mtcInputQuarter(int, unsigned char c)        { +#if 0        static int hour, min, sec, frame;        if (!extSyncFlag) @@ -186,6 +189,7 @@ void MidiSeq::mtcInputQuarter(int, unsigned char c)              mtcCurTime.incQuarter();              mtcSyncMsg(mtcCurTime, false);              } +#endif        }  //--------------------------------------------------------- @@ -195,6 +199,7 @@ void MidiSeq::mtcInputQuarter(int, unsigned char c)  void MidiSeq::mtcInputFull(const unsigned char* p, int n)        { +#if 0        if (debugSync)              printf("mtcInputFull\n");        if (!extSyncFlag) @@ -222,6 +227,7 @@ void MidiSeq::mtcInputFull(const unsigned char* p, int n)        mtcState = 0;        mtcValid = true;        mtcLost  = 0; +#endif        }  //--------------------------------------------------------- @@ -230,6 +236,7 @@ void MidiSeq::mtcInputFull(const unsigned char* p, int n)  void MidiSeq::nonRealtimeSystemSysex(const unsigned char* p, int n)        { +#if 0  //      int chan = p[2];        switch(p[3]) {              case 4: @@ -240,6 +247,7 @@ void MidiSeq::nonRealtimeSystemSysex(const unsigned char* p, int n)                    dump(p, n);                    break;             } +#endif        }  //--------------------------------------------------------- @@ -252,6 +260,7 @@ void MidiSeq::nonRealtimeSystemSysex(const unsigned char* p, int n)  void MidiSeq::setSongPosition(int port, int midiBeat)        { +#if 0        if (midiInputTrace)              printf("set song position port:%d %d\n", port, midiBeat);        if (!extSyncFlag) @@ -260,6 +269,7 @@ void MidiSeq::setSongPosition(int port, int midiBeat)        audioDriver->seekTransport(pos.frame());        if (debugSync)              printf("setSongPosition %d\n", pos.tick()); +#endif        }  //--------------------------------------------------------- @@ -269,6 +279,7 @@ void MidiSeq::setSongPosition(int port, int midiBeat)  void MidiSeq::realtimeSystemInput(int port, int c)        { +#if 0        if (midiInputTrace)              printf("realtimeSystemInput port:%d 0x%x\n", port+1, c); @@ -443,6 +454,7 @@ void MidiSeq::realtimeSystemInput(int port, int c)              case 0xff:  // system reset                    break;              } +#endif        } @@ -484,4 +496,3 @@ void MidiSeq::mtcSyncMsg(const MTC& /*mtc*/, bool /*seekFlag*/)  #endif        } - | 
