diff options
| author | Werner Schweer <ws.seh.de> | 2006-10-23 12:36:58 +0000 | 
|---|---|---|
| committer | Werner Schweer <ws.seh.de> | 2006-10-23 12:36:58 +0000 | 
| commit | d3c3d0b05fb0ab210835c59707a49248e1262b8c (patch) | |
| tree | 229cf784c777f73a636cf899499b9ed5dac8406b | |
| parent | 782da3b949f8f0f2c0016187a2c88e665a762d7a (diff) | |
updates
| -rw-r--r-- | muse/muse/audio.cpp | 4 | ||||
| -rw-r--r-- | muse/muse/driver/alsamidi.h | 5 | ||||
| -rw-r--r-- | muse/muse/driver/audiodev.h | 3 | ||||
| -rw-r--r-- | muse/muse/driver/driver.h | 3 | ||||
| -rw-r--r-- | muse/muse/driver/dummyaudio.cpp | 1 | ||||
| -rw-r--r-- | muse/muse/driver/jack.cpp | 29 | ||||
| -rw-r--r-- | muse/muse/driver/jackaudio.h | 4 | ||||
| -rw-r--r-- | muse/muse/midi.cpp | 152 | ||||
| -rw-r--r-- | muse/muse/midieventbase.h (renamed from muse/muse/midievent.h) | 0 | ||||
| -rw-r--r-- | muse/muse/midioutport.cpp | 186 | ||||
| -rw-r--r-- | muse/muse/midioutport.h | 2 | ||||
| -rw-r--r-- | muse/muse/undo.cpp | 4 | 
12 files changed, 208 insertions, 185 deletions
diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp index ce55f2bd..e6e84ab6 100644 --- a/muse/muse/audio.cpp +++ b/muse/muse/audio.cpp @@ -460,7 +460,9 @@ void Audio::process(unsigned frames)                    }              } -      processMidi(frames); +      MidiOutPortList* mol = song->midiOutPorts(); +      for (iMidiOutPort i = mol->begin(); i != mol->end(); ++i) +            audioDriver->startMidiCycle(mol->jackPort(0));        GroupList* gl     = song->groups();        SynthIList* sl    = song->syntis(); diff --git a/muse/muse/driver/alsamidi.h b/muse/muse/driver/alsamidi.h index 9e5e54f5..b68c4783 100644 --- a/muse/muse/driver/alsamidi.h +++ b/muse/muse/driver/alsamidi.h @@ -40,6 +40,7 @@ class AlsaMidi : public Driver {        void removeConnection(snd_seq_connect_t* ev);        void addConnection(snd_seq_connect_t* ev); +      bool putEvent(snd_seq_event_t* event);     public:        AlsaMidi(); @@ -58,15 +59,13 @@ class AlsaMidi : public Driver {        virtual bool connect(Port, Port);        virtual bool disconnect(Port, Port); +      virtual void putEvent(Port, const MidiEvent&);        void getInputPollFd(struct pollfd**, int* n);        void getOutputPollFd(struct pollfd**, int* n);        void read(MidiSeq*);      // process events        void write(); - -      void putEvent(Port, const MidiEvent&); -      bool putEvent(snd_seq_event_t* event);        };  extern AlsaMidi alsaMidi; diff --git a/muse/muse/driver/audiodev.h b/muse/muse/driver/audiodev.h index 416f91c0..5196375c 100644 --- a/muse/muse/driver/audiodev.h +++ b/muse/muse/driver/audiodev.h @@ -37,7 +37,7 @@ class AudioDriver : public Driver {        virtual bool restart() { return false; }           // return true on error        virtual void stop () = 0;        virtual unsigned framePos() const = 0; -      virtual float* getBuffer(void* port, unsigned long nframes) = 0; +      virtual float* getBuffer(Port, unsigned long nframes) = 0;        virtual void registerClient() = 0;        virtual Port registerOutPort(const QString& name, bool midi) = 0;        virtual Port registerInPort(const QString& name, bool midi) = 0; @@ -49,6 +49,7 @@ class AudioDriver : public Driver {        virtual void seekTransport(unsigned frame) = 0;        virtual void setFreewheel(bool f) = 0;        virtual void graphChanged() {} +      virtual void startMidiCycle(Port) {}        };  #endif diff --git a/muse/muse/driver/driver.h b/muse/muse/driver/driver.h index bd6a826a..d7147b52 100644 --- a/muse/muse/driver/driver.h +++ b/muse/muse/driver/driver.h @@ -28,6 +28,8 @@ struct PortName {        QString name;        }; +class MidiEvent; +  //---------------------------------------------------------  //   Driver  //    abstract driver base class; used for midi and @@ -54,6 +56,7 @@ class Driver {        virtual bool connect(Port, Port) = 0;        virtual bool disconnect(Port, Port) = 0;        virtual bool equal(Port, Port) = 0; +      virtual void putEvent(Port, const MidiEvent&) = 0;        };  #endif diff --git a/muse/muse/driver/dummyaudio.cpp b/muse/muse/driver/dummyaudio.cpp index 2aa5a709..a55a69bb 100644 --- a/muse/muse/driver/dummyaudio.cpp +++ b/muse/muse/driver/dummyaudio.cpp @@ -143,6 +143,7 @@ class DummyAudio : public AudioDriver {        virtual bool equal(Port a, Port b) {              return a == b;              } +      virtual void putEvent(Port, const MidiEvent&) {}        };  DummyAudio* dummyAudio; diff --git a/muse/muse/driver/jack.cpp b/muse/muse/driver/jack.cpp index 2bccbfcf..57a5348f 100644 --- a/muse/muse/driver/jack.cpp +++ b/muse/muse/driver/jack.cpp @@ -794,3 +794,32 @@ bool initJackAudio()        return false;        } +//--------------------------------------------------------- +//   putEvent +//--------------------------------------------------------- + +void JackAudio::putEvent(Port p, const MidiEvent& e) +      { +      if (midiOutputTrace) { +            printf("MidiOut<%s>: jackMidi: ", portName(p).toLatin1().data()); +            e.dump(); +            } +      unsigned char* p = jack_midi_event_reserve(pb, pos, 3, segmentSize); +      if (p == 0) { +            fprintf(stderr, "JackMidi: buffer overflow, event lost\n"); +            return; +            } +      p[0] = e.dataA(); +      p[1] +      } + +//--------------------------------------------------------- +//    startMidiCycle +//--------------------------------------------------------- + +void JackAudio::startMidiCycle(Port port) +      { +      void* port_buf = jack_port_get_buffer(port, segmentSize); +      jack_midi_clear_buffer(port_buf, segmentSize); +      } + diff --git a/muse/muse/driver/jackaudio.h b/muse/muse/driver/jackaudio.h index 4b76cb80..c4d0cdaa 100644 --- a/muse/muse/driver/jackaudio.h +++ b/muse/muse/driver/jackaudio.h @@ -44,7 +44,7 @@ class JackAudio : public AudioDriver {        virtual void zeroClientPtr() { _client = 0; }        virtual unsigned framePos() const; -      virtual float* getBuffer(void* port, unsigned long nframes) { +      virtual float* getBuffer(Port port, unsigned long nframes) {              return (float*)jack_port_get_buffer((jack_port_t*)port, nframes);              } @@ -78,6 +78,8 @@ class JackAudio : public AudioDriver {              }        void graphChanged();        virtual bool equal(Port a, Port b) { return a == b; } +      virtual void putEvent(Port, const MidiEvent&); +      virutal void startMidiCycle(Port);        };  #endif diff --git a/muse/muse/midi.cpp b/muse/muse/midi.cpp index 9741d9fb..8e15b9d4 100644 --- a/muse/muse/midi.cpp +++ b/muse/muse/midi.cpp @@ -27,6 +27,7 @@  #include "midictrl.h"  #include "audio.h"  #include "driver/mididev.h" +#include "driver/audiodev.h"  #include "wave.h"  #include "synth.h"  #include "sync.h" @@ -666,154 +667,3 @@ void Audio::processMidi(unsigned frames)        midiBusy = false;        } -//--------------------------------------------------------- -//   process -//    "play" events for this process cycle -//    if (from != to)  then transport state is "playing" -//--------------------------------------------------------- - -void MidiOutPort::process(unsigned from, unsigned to, const Pos& pos, unsigned frames) -      { -      // -      // erase already played events: -      // -      _playEvents.erase(_playEvents.begin(), _nextPlayEvent); -      playFifo(); - -      if (mute()) -            return; - -      // collect port controller -      if (from != to) { -            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); -                  for (iCtrlVal ic = is; ic != ie; ++ic) { -                        unsigned frame = AL::tempomap.tick2frame(ic->first); -                        Event ev(Controller); -                        ev.setA(c->id()); -                        ev.setB(ic->second.i); -                        _playEvents.add(MidiEvent(frame, -1, ev)); -                        } -                  } -            } - -      int portVelo = 0; -      for (int ch = 0; ch < MIDI_CHANNELS; ++ch)  { -            MidiChannel* mc = channel(ch); - -            if (mc->mute() || mc->noInRoute()) -                  continue; -            // collect channel controller -            if (from != to) { -                  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); -                        for (; is != ie; ++is) { -                              unsigned frame = AL::tempomap.tick2frame(is->first); -                              Event ev(Controller); -                              ev.setA(c->id()); -                              ev.setB(is->second.i); -                              _playEvents.add(MidiEvent(frame, ch, ev)); -                              } -                        } -                  } - -            // Collect midievents from all input tracks for outport -            RouteList* rl = mc->inRoutes(); -            for (iRoute i = rl->begin(); i != rl->end(); ++i) { -                  MidiTrackBase* track = (MidiTrackBase*)i->track; -                  if (track->isMute()) -                        continue; -                  MPEventList el; -                  track->getEvents(from, to, 0, &el); -                  int velo = 0; -                  for (iMPEvent i = el.begin(); i != el.end(); ++i) { -                        MidiEvent ev = *i; -                        ev.setChannel(ch); -                        _playEvents.insert(ev); -                        if (ev.type() == ME_NOTEON) -                              velo += ev.dataB(); -                        } -                  mc->addMidiMeter(velo); -                  portVelo += velo; -                  } -            } -      addMidiMeter(portVelo); - -      // TODO: maybe this copying can be avoided -      // -      MPEventList il; -      for (iMPEvent i = _playEvents.begin(); i != _playEvents.end(); ++i) { -            il.add(*i); -            } -      _playEvents.clear(); -      pipeline()->apply(from, to, &il, &_playEvents); - -      _nextPlayEvent = _playEvents.begin(); - -      // -      // route events to destination -      // - -      if (_playEvents.empty()) -            return; - -      //printf("_playEvents.size() == %d\n", _playEvents.size()); -      unsigned endFrame = pos.frame() + frames + audio->getFrameOffset(); -      for (iRoute r = _outRoutes.begin(); r != _outRoutes.end(); ++r) { -            switch (r->type) { - -                  // -                  // Send events to software synthesizer -                  // -                  case Route::SYNTIPORT: { -                        SynthI* s       = (SynthI*)(r->track); -                        MPEventList* el = s->playEvents(); -                        iMPEvent is     = _playEvents.begin(); -                        iMPEvent ie     = _playEvents.end(); - -                        for (; is != ie; ++is) { -                              if ((from != to) && (is->time() >= endFrame)) { -                                    break; -                                    } - -                              el->insert(*is); -                              _nextPlayEvent = is; -                              _nextPlayEvent++; -                              } -                        } -                        break; - -                  // -                  // Send events to midi port -                  // -                  case Route::MIDIPORT: { -                        //playEventList(); -                        for (iMPEvent ev = _playEvents.begin(); ev != _playEvents.end(); ev++) { -                              if ((from != to) && (ev->time() >= endFrame)) { -                                    break; -                                    } - -                              midiDriver->putEvent(alsaPort(), *ev); -                              _nextPlayEvent = ev; -                              _nextPlayEvent++; -                              } -                        } -                        break; - - -                  // Invalid routetypes to send midi events to - should not happen -                  case Route::AUDIOPORT: -                  case Route::TRACK: -                  default: -                        printf("Error - invalid routetype\n"); -                        break; -                  } -            } -      } - diff --git a/muse/muse/midievent.h b/muse/muse/midieventbase.h index 93cb5529..93cb5529 100644 --- a/muse/muse/midievent.h +++ b/muse/muse/midieventbase.h diff --git a/muse/muse/midioutport.cpp b/muse/muse/midioutport.cpp index bdad88cc..3d96780f 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/tempo.h"  #include "al/xml.h"  #include "driver/mididev.h"  #include "driver/audiodev.h" @@ -153,7 +154,7 @@ void MidiOutPort::putEvent(const MidiEvent& ev)                    }              if (a == CTRL_PITCH) { -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_PITCHBEND, b, 0)); +                  routeEvent(MidiEvent(0, chn, ME_PITCHBEND, b, 0));                    return;                    }              if (a == CTRL_PROGRAM) { @@ -163,10 +164,10 @@ void MidiOutPort::putEvent(const MidiEvent& ev)                          int lb = (b >> 8) & 0xff;                          int pr = b & 0x7f;                          if (hb != 0xff) -                              midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_HBANK, hb)); +                              routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_HBANK, hb));                          if (lb != 0xff)                                midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_LBANK, lb)); -                        midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_PROGRAM, pr, 0)); +                        routeEvent(MidiEvent(0, chn, ME_PROGRAM, pr, 0));                          return;  //                        }                    } @@ -178,63 +179,63 @@ void MidiOutPort::putEvent(const MidiEvent& ev)                    sysex[4] = b & 0x7f;                    sysex[5] = (b >> 7) & 0x7f;                    MidiEvent e(ev.time(), ME_SYSEX, sysex, 6); -                  midiDriver->putEvent(alsaPort(), e); +                  routeEvent(e);                    return;                    }  #if 1 // if ALSA cannot handle RPN NRPN etc.              if (a < 0x1000) {          // 7 Bit Controller                    //putMidiEvent(MidiEvent(0, chn, ME_CONTROLLER, a, b)); -                  midiDriver->putEvent(alsaPort(), ev); +                  routeEvent(ev);                    }              else if (a < 0x20000) {     // 14 bit high resolution controller                    int ctrlH = (a >> 8) & 0x7f;                    int ctrlL = a & 0x7f;                    int dataH = (b >> 7) & 0x7f;                    int dataL = b & 0x7f; -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, ctrlH, dataH)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, ctrlL, dataL)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, ctrlH, dataH)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, ctrlL, dataL));                    }              else if (a < 0x30000) {     // RPN 7-Bit Controller                    int ctrlH = (a >> 8) & 0x7f;                    int ctrlL = a & 0x7f; -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, b)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, b));                    }              else if (a < 0x40000) {     // NRPN 7-Bit Controller                    int ctrlH = (a >> 8) & 0x7f;                    int ctrlL = a & 0x7f; -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, b)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, b));                    }              else if (a < 0x60000) {     // RPN14 Controller                    int ctrlH = (a >> 8) & 0x7f;                    int ctrlL = a & 0x7f;                    int dataH = (b >> 7) & 0x7f;                    int dataL = b & 0x7f; -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, dataH)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_LDATA, dataL)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, dataH)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_LDATA, dataL));                    }              else if (a < 0x70000) {     // NRPN14 Controller                    int ctrlH = (a >> 8) & 0x7f;                    int ctrlL = a & 0x7f;                    int dataH = (b >> 7) & 0x7f;                    int dataL = b & 0x7f; -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, dataH)); -                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_LDATA, dataL)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, dataH)); +                  routeEvent(MidiEvent(0, chn, ME_CONTROLLER, CTRL_LDATA, dataL));                    }              else {                    printf("putEvent: unknown controller type 0x%x\n", a);                    }  #endif              } -      midiDriver->putEvent(alsaPort(), ev); +      routeEvent(ev);        }  //--------------------------------------------------------- @@ -244,7 +245,7 @@ void MidiOutPort::putEvent(const MidiEvent& ev)  void MidiOutPort::playEventList()        {        for (; _nextPlayEvent != _playEvents.end(); ++_nextPlayEvent) -            midiDriver->putEvent(alsaPort(), *_nextPlayEvent); +            routeEvent(*_nextPlayEvent);        }  //--------------------------------------------------------- @@ -385,15 +386,13 @@ void MidiOutPort::playMidiEvent(MidiEvent* ev)        RouteList* orl = outRoutes();        bool sendToFifo = false;        for (iRoute i = orl->begin(); i != orl->end(); ++i) { -            if (i->type == Route::MIDIPORT) -                  sendToFifo = true; -            else if (i->type == Route::SYNTIPORT) { +            if (i->type == Route::SYNTIPORT) {                    SynthI* synti = (SynthI*)i->track;  	      	if (synti->eventFifo()->put(*ev))        	      	printf("MidiOut::playMidiEvent(): synti overflow, drop event\n");                    } -            else -                  printf("MidiOutPort::playMidiEvent: bad route type\n"); +            else  +                  sendToFifo = true;              }        if (sendToFifo) {  	      if (eventFifo.put(*ev)) @@ -402,6 +401,114 @@ void MidiOutPort::playMidiEvent(MidiEvent* ev)        }  //--------------------------------------------------------- +//   process +//    "play" events for this process cycle +//    if (from != to)  then transport state is "playing" +//--------------------------------------------------------- + +void MidiOutPort::process(unsigned from, unsigned to, const Pos& pos, unsigned frames) +      { +      // +      // erase already played events: +      // +      _playEvents.erase(_playEvents.begin(), _nextPlayEvent); +      playFifo(); + +      if (mute()) +            return; + +      // collect port controller +      if (from != to) { +            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); +                  for (iCtrlVal ic = is; ic != ie; ++ic) { +                        unsigned frame = AL::tempomap.tick2frame(ic->first); +                        Event ev(Controller); +                        ev.setA(c->id()); +                        ev.setB(ic->second.i); +                        _playEvents.add(MidiEvent(frame, -1, ev)); +                        } +                  } +            } + +      int portVelo = 0; +      for (int ch = 0; ch < MIDI_CHANNELS; ++ch)  { +            MidiChannel* mc = channel(ch); + +            if (mc->mute() || mc->noInRoute()) +                  continue; +            // collect channel controller +            if (from != to) { +                  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); +                        for (; is != ie; ++is) { +                              unsigned frame = AL::tempomap.tick2frame(is->first); +                              Event ev(Controller); +                              ev.setA(c->id()); +                              ev.setB(is->second.i); +                              _playEvents.add(MidiEvent(frame, ch, ev)); +                              } +                        } +                  } + +            // Collect midievents from all input tracks for outport +            RouteList* rl = mc->inRoutes(); +            for (iRoute i = rl->begin(); i != rl->end(); ++i) { +                  MidiTrackBase* track = (MidiTrackBase*)i->track; +                  if (track->isMute()) +                        continue; +                  MPEventList el; +                  track->getEvents(from, to, 0, &el); +                  int velo = 0; +                  for (iMPEvent i = el.begin(); i != el.end(); ++i) { +                        MidiEvent ev = *i; +                        ev.setChannel(ch); +                        _playEvents.insert(ev); +                        if (ev.type() == ME_NOTEON) +                              velo += ev.dataB(); +                        } +                  mc->addMidiMeter(velo); +                  portVelo += velo; +                  } +            } +      addMidiMeter(portVelo); + +      // TODO: maybe this copying can be avoided +      // +      MPEventList il; +      for (iMPEvent i = _playEvents.begin(); i != _playEvents.end(); ++i) { +            il.add(*i); +            } +      _playEvents.clear(); +      pipeline()->apply(from, to, &il, &_playEvents); + +      _nextPlayEvent = _playEvents.begin(); + +      // +      // route events to destination +      // + +      unsigned endFrame = pos.frame() + frames + audio->getFrameOffset(); +      iMPEvent is = _playEvents.begin(); +      iMPEvent ie = _playEvents.end(); + +      for (_nextPlayEvent = is; _nextPlayEvent != ie; _nextPlayEvent++) { +            if ((from != to) && (_nextPlayEvent->time() >= endFrame)) { +                  ++_nextPlayEvent;       // ?? +                  break; +                  } +            routeEvent(*_nextPlayEvent); +            } +      } + + +//---------------------------------------------------------  //   setInstrument  //--------------------------------------------------------- @@ -421,4 +528,27 @@ void MidiOutPort::setSendSync(bool val)        emit sendSyncChanged(val);        } +//--------------------------------------------------------- +//    routeEvent +//--------------------------------------------------------- + +void MidiOutPort::routeEvent(const MidiEvent& event) +      { +      for (iRoute r = _outRoutes.begin(); r != _outRoutes.end(); ++r) { +            switch (r->type) { +                  case Route::MIDIPORT: +                        midiDriver->putEvent(alsaPort(0), *_nextPlayEvent); +                        break; +                  case Route::SYNTIPORT:  +                        ((SynthI*)(r->track))->playEvents()->insert(*_nextPlayEvent); +                        break; +                  case Route::JACKMIDIPORT: +                        audioDriver->putEvent(jackPort(0), *_nextPlayEvent); +                        break; +                  default: +                        fprintf(stderr, "MidiOutPort::process(): invalid routetype\n"); +                        break; +                  } +            } +      } diff --git a/muse/muse/midioutport.h b/muse/muse/midioutport.h index f90ad376..9999a92d 100644 --- a/muse/muse/midioutport.h +++ b/muse/muse/midioutport.h @@ -44,6 +44,8 @@ class MidiOutPort : public MidiTrackBase {        MidiFifo eventFifo; +      void routeEvent(const MidiEvent&); +     signals:        void instrumentChanged();        void sendSyncChanged(bool); diff --git a/muse/muse/undo.cpp b/muse/muse/undo.cpp index 61d9c7e9..b65269f4 100644 --- a/muse/muse/undo.cpp +++ b/muse/muse/undo.cpp @@ -463,6 +463,10 @@ void Song::doUndo3()                          break;                    case UndoOp::DeleteTrack:                          emit trackAdded(i->track, i->id); +                        if (i->track->selected()) { +                              i->track->setSelected(false); +                              selectTrack(i->track); +                              }                          break;                    case UndoOp::ModifyPart:                          if (i->oPart->track() != i->nPart->track())  | 
