From 7209944860501af4868f166f4cff59559bdb567e Mon Sep 17 00:00:00 2001
From: Werner Schweer <ws.seh.de>
Date: Sun, 22 Oct 2006 20:16:27 +0000
Subject: updates

---
 muse/al/pos.cpp               |   8 ---
 muse/al/pos.h                 |   1 -
 muse/muse/audio.cpp           |   9 +--
 muse/muse/audioinput.cpp      |  69 +++----------------
 muse/muse/audioinput.h        |   7 --
 muse/muse/audiooutput.cpp     |  67 ++----------------
 muse/muse/audiooutput.h       |   8 ---
 muse/muse/audiotrack.cpp      |   5 +-
 muse/muse/driver/alsamidi.cpp |  25 ++-----
 muse/muse/driver/jack.cpp     |  36 ++++++----
 muse/muse/midi.cpp            |   2 +-
 muse/muse/midiinport.cpp      |  81 ++--------------------
 muse/muse/midiinport.h        |   8 ---
 muse/muse/midioutport.cpp     | 127 ++++++++--------------------------
 muse/muse/midioutport.h       |   8 ---
 muse/muse/mixer/astrip.cpp    |   8 +--
 muse/muse/muse.cpp            |   3 +-
 muse/muse/route.cpp           |  57 ++++++----------
 muse/muse/seqmsg.cpp          |   8 +--
 muse/muse/song.cpp            |  49 ++++----------
 muse/muse/song.h              |   2 -
 muse/muse/track.cpp           | 154 ++++++++++++++++++++++++++++++++++++++----
 muse/muse/track.h             |  19 +++++-
 muse/muse/wave.cpp            |   1 -
 muse/muse/wavetrack.cpp       |  11 ++-
 25 files changed, 291 insertions(+), 482 deletions(-)

diff --git a/muse/al/pos.cpp b/muse/al/pos.cpp
index eb3629c2..ffd29c3b 100644
--- a/muse/al/pos.cpp
+++ b/muse/al/pos.cpp
@@ -38,14 +38,6 @@ Pos::Pos()
       sn      = -1;
       }
 
-Pos::Pos(const Pos& p)
-      {
-      _type  = p._type;
-      sn     = p.sn;
-      _tick  = p._tick;
-      _frame = p._frame;
-      }
-
 Pos::Pos(unsigned t, TType timeType)
       {
  	_type = timeType;
diff --git a/muse/al/pos.h b/muse/al/pos.h
index a771fc4b..6d69cc52 100644
--- a/muse/al/pos.h
+++ b/muse/al/pos.h
@@ -48,7 +48,6 @@ class Pos {
 
    public:
       Pos();
-      Pos(const Pos&);
       Pos(int measure, int beat, int tick);
       Pos(int minute, int sec, int frame, int subframe);
       Pos(unsigned, TType type = TICKS);
diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp
index 9c384025..ce55f2bd 100644
--- a/muse/muse/audio.cpp
+++ b/muse/muse/audio.cpp
@@ -201,7 +201,7 @@ bool Audio::start()
                 for (iAudioInput i = itl->begin(); i != itl->end(); ++i) {
 //                      printf("reconnecting input %s\n", (*i)->name().toLatin1().data());
                       for (int x=0; x < (*i)->channels();x++)
-                          (*i)->setJackPort(x,0); // zero out the old connection
+                          (*i)->setJackPort(0, x); // zero out the old connection
                       (*i)->activate1();
                       }
 
@@ -209,7 +209,7 @@ bool Audio::start()
                 for (iAudioOutput i = otl->begin(); i != otl->end(); ++i) {
 //                      printf("reconnecting output %s\n", (*i)->name().toLatin1().data());
                       for (int x=0; x < (*i)->channels();x++)
-                          (*i)->setJackPort(x,0);  // zero out the old connection
+                          (*i)->setJackPort(0,x);  // zero out the old connection
                       (*i)->activate1();
                       }
                audioDriver->start(realTimePriority);
@@ -231,12 +231,14 @@ bool Audio::start()
 
 void Audio::stop()
       {
+#if 0
       MidiOutPortList* opl = song->midiOutPorts();
       for (iMidiOutPort i = opl->begin(); i != opl->end(); ++i)
             (*i)->deactivate();
       MidiInPortList* ipl = song->midiInPorts();
       for (iMidiInPort i = ipl->begin(); i != ipl->end(); ++i)
             (*i)->deactivate();
+#endif
       if (audioDriver)
           audioDriver->stop();
       }
@@ -473,7 +475,6 @@ void Audio::process(unsigned frames)
       _curReadIndex = -1;
       if (isPlaying() && !wl->empty()) {
    	      Fifo1* fifo = audioPrefetch->getFifo();
-// printf("process %3d\n", fifo->count());
       	if (fifo->count() == 0) {
             	printf("MusE::Audio: fifo underflow at 0x%x\n", _curTickPos);
                   audioPrefetch->msgTick();
@@ -526,7 +527,7 @@ void Audio::process(unsigned frames)
                   }
             if (recording && (_bounce == 0 || _bounce == 1))
                   audioWriteback->trigger();
-            _pos      += frames;
+            _pos       += frames;
             _curTickPos = _nextTickPos;
             }
       }
diff --git a/muse/muse/audioinput.cpp b/muse/muse/audioinput.cpp
index 8fb25947..92c0dfd8 100644
--- a/muse/muse/audioinput.cpp
+++ b/muse/muse/audioinput.cpp
@@ -32,8 +32,6 @@ AudioInput::AudioInput()
       {
       // set Default for Input Ports:
       _mute = true;
-      for (int i = 0; i < MAX_CHANNELS; ++i)
-            jackPorts[i] = 0;
       _channels = 0;
       setChannels(2);
       //
@@ -55,8 +53,8 @@ AudioInput::AudioInput()
 AudioInput::~AudioInput()
       {
       for (int i = 0; i < _channels; ++i) {
-            if (jackPorts[i])
-                  audioDriver->unregisterPort(jackPorts[i]);
+            if (jackPort(i))
+                  audioDriver->unregisterPort(jackPort(i));
             }
       // AudioInput does not own buffers (they are from JACK)
       // make sure ~AudioTrack() does not delete them:
@@ -87,57 +85,6 @@ void AudioInput::read(QDomNode node)
       setName(name());  // allocate jack ports
       }
 
-//---------------------------------------------------------
-//   activate1
-//    register jack port for every channel of this track
-//---------------------------------------------------------
-
-void AudioInput::activate1()
-      {
-      for (int i = 0; i < channels(); ++i) {
-            char buffer[128];
-            snprintf(buffer, 128, "%s-%d", _name.toAscii().data(), i);
-            // following happens on reconnect to JACK server:
-            if (jackPorts[i])
-                  printf("AudioInput::activate(): already active!\n");
-            jackPorts[i] = audioDriver->registerInPort(buffer, false);
-            }
-      }
-
-//---------------------------------------------------------
-//   activate2
-//    connect all routes to jack; can only be done if
-//    jack is activ running
-//---------------------------------------------------------
-
-void AudioInput::activate2()
-      {
-      if (audioState != AUDIO_RUNNING) {
-            printf("AudioInput::activate2(): no audio running !\n");
-            abort();
-            }
-      for (iRoute i = _inRoutes.begin(); i != _inRoutes.end(); ++i)
-            audioDriver->connect(i->port, jackPorts[i->channel]);
-      }
-
-//---------------------------------------------------------
-//   deactivate
-//---------------------------------------------------------
-
-void AudioInput::deactivate()
-      {
-      for (iRoute i = _inRoutes.begin(); i != _inRoutes.end(); ++i)
-            audioDriver->disconnect(i->port, jackPorts[i->channel]);
-      for (int i = 0; i < channels(); ++i) {
-            if (jackPorts[i]) {
-                  audioDriver->unregisterPort(jackPorts[i]);
-                  jackPorts[i] = 0;
-                  }
-            else
-                  printf("AudioInput::deactivate(): not active!\n");
-            }
-      }
-
 //---------------------------------------------------------
 //   setChannels
 //---------------------------------------------------------
@@ -157,11 +104,11 @@ void AudioInput::setName(const QString& s)
       {
       Track::setName(s);
       for (int i = 0; i < channels(); ++i) {
-            if (jackPorts[i]) {
+            if (jackPort(i)) {
                   char buffer[128];
                   snprintf(buffer, 128, "%s-%d", _name.toAscii().data(), i);
-                  if (jackPorts[i])
-                        audioDriver->setPortName(jackPorts[i], buffer);
+                  if (jackPort(i))
+                        audioDriver->setPortName(jackPort(i), buffer);
                   }
             }
       }
@@ -175,9 +122,9 @@ void AudioInput::collectInputData()
       {
       bufferEmpty = false;
       for (int ch = 0; ch < channels(); ++ch) {
-            void* jackPort = jackPorts[ch];
-            if (jackPort)
-                        buffer[ch] = audioDriver->getBuffer(jackPort, segmentSize);
+            Port port = jackPort(ch);
+            if (port)
+                  buffer[ch] = audioDriver->getBuffer(port, segmentSize);
             else {
                   printf("NO JACK PORT\n");
                   abort();
diff --git a/muse/muse/audioinput.h b/muse/muse/audioinput.h
index fbbff14b..682d1fee 100644
--- a/muse/muse/audioinput.h
+++ b/muse/muse/audioinput.h
@@ -30,7 +30,6 @@
 class AudioInput : public AudioTrack {
       Q_OBJECT
 
-      Port jackPorts[MAX_CHANNELS];
       void collectInputData();
 
    public:
@@ -38,15 +37,9 @@ class AudioInput : public AudioTrack {
       virtual ~AudioInput();
       virtual AudioInput* newTrack() const { return new AudioInput(); }
 
-      virtual void activate1();
-      virtual void activate2();
-      virtual void deactivate();
-
       virtual void read(QDomNode);
       virtual void write(Xml&) const;
       virtual void setName(const QString& s);
-      void* jackPort(int channel) { return jackPorts[channel]; }
-      void setJackPort(int channel, void*p) { jackPorts[channel] = p; }
       virtual void setChannels(int n);
       virtual bool hasAuxSend() const { return true; }
       };
diff --git a/muse/muse/audiooutput.cpp b/muse/muse/audiooutput.cpp
index 103a5d3e..ff057474 100644
--- a/muse/muse/audiooutput.cpp
+++ b/muse/muse/audiooutput.cpp
@@ -32,8 +32,6 @@
 AudioOutput::AudioOutput()
    : AudioTrack(AUDIO_OUTPUT)
       {
-      for (int i = 0; i < MAX_CHANNELS; ++i)
-            jackPorts[i] = 0;
       _channels = 0;
       setChannels(2);
 
@@ -57,8 +55,8 @@ AudioOutput::AudioOutput()
 AudioOutput::~AudioOutput()
       {
       for (int i = 0; i < _channels; ++i) {
-            if (jackPorts[i])
-                  audioDriver->unregisterPort(jackPorts[i]);
+            if (jackPort(i))
+                  audioDriver->unregisterPort(jackPort(i));
             }
       // AudioOutput does not own buffers (they are from JACK)
       // make sure ~AudioTrack() does not delete them:
@@ -108,8 +106,8 @@ void AudioOutput::setChannels(int n)
 void AudioOutput::silence(unsigned n)
       {
       for (int i = 0; i < channels(); ++i) {
-            if (jackPorts[i])
-                  buffer[i] = audioDriver->getBuffer(jackPorts[i], n);
+            if (jackPort(i))
+                  buffer[i] = audioDriver->getBuffer(jackPort(i), n);
             else {
                   printf("PANIC: silence(): no buffer from audio driver\n");
                   abort();
@@ -128,65 +126,14 @@ void AudioOutput::setName(const QString& s)
       {
       Track::setName(s);
       for (int i = 0; i < channels(); ++i) {
-            if (jackPorts[i]) {
+            if (jackPort(i)) {
                   char buffer[128];
                   snprintf(buffer, 128, "%s-%d", _name.toAscii().data(), i);
-                  audioDriver->setPortName(jackPorts[i], buffer);
+                  audioDriver->setPortName(jackPort(i), buffer);
                   }
             }
       }
 
-//---------------------------------------------------------
-//   activate1
-//---------------------------------------------------------
-
-void AudioOutput::activate1()
-      {
-      for (int i = 0; i < channels(); ++i) {
-            char buffer[128];
-            snprintf(buffer, 128, "%s-%d", _name.toAscii().data(), i);
-            if (jackPorts[i]) {
-                  printf("AudioOutput::activate(): already active!\n");
-                  }
-            else
-                  jackPorts[i] = audioDriver->registerOutPort(QString(buffer), false);
-            }
-      }
-
-//---------------------------------------------------------
-//   activate2
-//---------------------------------------------------------
-
-void AudioOutput::activate2()
-      {
-      if (audioState != AUDIO_RUNNING) {
-            printf("AudioOutput::activate2(): no audio running !\n");
-            abort();
-            }
-      for (iRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i)
-            audioDriver->connect(jackPorts[i->channel], i->port);
-      }
-
-//---------------------------------------------------------
-//   deactivate
-//---------------------------------------------------------
-
-void AudioOutput::deactivate()
-      {
-      for (iRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i) {
-            Route r = *i;
-            audioDriver->disconnect(jackPorts[i->channel], i->port);
-            }
-      for (int i = 0; i < channels(); ++i) {
-            if (jackPorts[i]) {
-                  audioDriver->unregisterPort(jackPorts[i]);
-                  jackPorts[i] = 0;
-                  }
-            else
-                  printf("AudioOutput::deactivate(): not active!\n");
-            }
-      }
-
 //---------------------------------------------------------
 //   stopRecording
 //    gui context
@@ -210,7 +157,7 @@ void AudioOutput::stopRecording(const Pos& /*s*/, const Pos& /*e*/)
 void AudioOutput::process()
       {
       for (int c = 0; c < channels(); ++c)
-            buffer[c] = audioDriver->getBuffer(jackPorts[c], segmentSize);
+            buffer[c] = audioDriver->getBuffer(jackPort(c), segmentSize);
 
       AudioTrack::process();
 
diff --git a/muse/muse/audiooutput.h b/muse/muse/audiooutput.h
index 062c9fde..ff385efe 100644
--- a/muse/muse/audiooutput.h
+++ b/muse/muse/audiooutput.h
@@ -30,22 +30,14 @@
 class AudioOutput : public AudioTrack {
       Q_OBJECT
 
-      Port jackPorts[MAX_CHANNELS];
-
    public:
       AudioOutput();
       virtual ~AudioOutput();
       virtual AudioOutput* newTrack() const { return new AudioOutput(); }
 
-      virtual void activate1();
-      virtual void activate2();
-      virtual void deactivate();
-
       virtual void read(QDomNode);
       virtual void write(Xml&) const;
       virtual void setName(const QString& s);
-      void* jackPort(int channel) { return jackPorts[channel]; }
-      void setJackPort(int channel, void*p) { jackPorts[channel] = p; }
       virtual void setChannels(int n);
 
       virtual bool canRecord() const { return true; }
diff --git a/muse/muse/audiotrack.cpp b/muse/muse/audiotrack.cpp
index c66ecbd9..e4ea6072 100644
--- a/muse/muse/audiotrack.cpp
+++ b/muse/muse/audiotrack.cpp
@@ -448,7 +448,10 @@ void AudioTrack::process()
       	      }
             }
 
-      double vol[channels()];
+      //
+      // TODO: we can only handle 1 or 2 channels
+      //
+      double vol[2];
       double _volume = _mute ? 0.0 : ctrlVal(AC_VOLUME).f;
       double _pan    = ctrlVal(AC_PAN).f;
       vol[0]         = _volume * (1.0 - _pan);
diff --git a/muse/muse/driver/alsamidi.cpp b/muse/muse/driver/alsamidi.cpp
index 744f0e67..e982d03a 100644
--- a/muse/muse/driver/alsamidi.cpp
+++ b/muse/muse/driver/alsamidi.cpp
@@ -362,18 +362,13 @@ void AlsaMidi::addConnection(snd_seq_connect_t* ev)
       MidiOutPortList* opl = song->midiOutPorts();
       for (iMidiOutPort i = opl->begin(); i != opl->end(); ++i) {
             MidiOutPort* oport = *i;
-            Port src = oport->alsaPort();
+            Port src = oport->alsaPort(0);
 
             if (equal(src, rs)) {
-                  RouteList* orl = oport->outRoutes();
-                  iRoute ir;
-                  for (ir = orl->begin(); ir != orl->end(); ++ir) {
-                        if (ir->port == rd)
-                              break;
-                        }
-                  if (ir == orl->end()) {
+                  Route r(rd, Route::MIDIPORT);
+                  if (oport->outRoutes()->indexOf(r) == -1) {
                         snd_seq_addr_t* adr = new snd_seq_addr_t(ev->dest);
-                        orl->push_back(Route(Port(adr), -1, Route::MIDIPORT));
+                        oport->outRoutes()->push_back(Route(Port(adr), -1, Route::MIDIPORT));
                         }
                   break;
                   }
@@ -385,16 +380,10 @@ void AlsaMidi::addConnection(snd_seq_connect_t* ev)
             Port dst = iport->alsaPort();
 
             if (equal(dst, rd)) {
-                  RouteList* irl = iport->inRoutes();
-                  iRoute ir;
-                  for (ir = irl->begin(); ir != irl->end(); ++ir) {
-                        Port src = ir->port;
-                        if (equal(src, rs))
-                              break;
-                        }
-                  if (ir == irl->end()) {
+                  Route r(rs, Route::MIDIPORT);
+                  if (iport->inRoutes()->indexOf(r) == -1) {
                         snd_seq_addr_t* adr = new snd_seq_addr_t(ev->sender);
-                        irl->push_back(Route(Port(adr), -1, Route::MIDIPORT));
+                        iport->inRoutes()->push_back(Route(Port(adr), -1, Route::MIDIPORT));
                         }
                   break;
                   }
diff --git a/muse/muse/driver/jack.cpp b/muse/muse/driver/jack.cpp
index aa970336..014bd20b 100644
--- a/muse/muse/driver/jack.cpp
+++ b/muse/muse/driver/jack.cpp
@@ -275,40 +275,48 @@ struct RouteRoute {
 
 void JackAudio::graphChanged()
       {
+      // under construction
+      return;
+
       QList<RouteRoute> rr;
       QList<RouteRoute> ra;
 
+printf("graphChanged\n");
       InputList* il = song->inputs();
       for (iAudioInput ii = il->begin(); ii != il->end(); ++ii) {
             AudioInput* it = *ii;
-            int channels = it->channels();
+            int channels   = it->channels();
+            RouteList* irl = it->inRoutes();
+
+printf("  inRoutes %d\n", irl->size());
+
             for (int channel = 0; channel < channels; ++channel) {
                   jack_port_t* port = (jack_port_t*)(it->jackPort(channel));
                   if (port == 0)
                         continue;
                   const char** ports = jack_port_get_all_connections(_client, port);
-                  RouteList* rl      = it->inRoutes();
+
                   //---------------------------------------
                   // check for disconnects
                   //---------------------------------------
 
-                  for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
-                        if (irl->channel != channel)
+                  foreach (Route r, *irl) {
+printf("  channel %d %d\n", r.channel, channel);
+                        if (r.channel != channel)
                               continue;
-                        Route r = *irl;
                         const char* name = jack_port_name((jack_port_t*)r.port);
-                        bool found = false;
-                        const char** pn = ports;
-                        while (pn && *pn) {
+printf("  port name <%s>\n", name);
+                        bool found      = false;
+                        for (const char** pn = ports; pn && *pn; ++pn) {
                               if (strcmp(*pn, name) == 0) {
+printf("  compare <%s><%s>\n", *pn, name);
                                     found = true;
                                     break;
                                     }
-                              ++pn;
                               }
                         if (!found) {
                               RouteRoute a;
-                              a.src = Route(irl->port, channel, Route::AUDIOPORT);
+                              a.src = Route(r.port, channel, Route::AUDIOPORT);
                               a.dst = Route(it, channel);
                               rr.append(a);
                               }
@@ -321,10 +329,10 @@ void JackAudio::graphChanged()
                   if (ports) {
                         for (const char** pn = ports; *pn; ++pn) {
                               bool found = false;
-                              for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
-                                    if (irl->channel != channel)
+                              foreach(Route r, *irl) {
+                                    if (r.channel != channel)
                                           continue;
-                                    const char* name = jack_port_name((jack_port_t*)irl->port);
+                                    const char* name = jack_port_name((jack_port_t*)r.port);
                                     if (strcmp(*pn, name) == 0) {
                                           found = true;
                                           break;
@@ -344,6 +352,7 @@ void JackAudio::graphChanged()
                   }
             }
 
+printf("  input: remove %d add %d routes\n", rr.size(), ra.size());
       foreach(RouteRoute a, rr) {
             audio->msgRemoveRoute1(a.src, a.dst);
             }
@@ -420,6 +429,7 @@ void JackAudio::graphChanged()
                         }
                   }
             }
+printf("  input: remove %d add %d routes\n", rr.size(), ra.size());
       foreach(RouteRoute a, rr)
             audio->msgRemoveRoute1(a.src, a.dst);
       foreach(RouteRoute a, ra)
diff --git a/muse/muse/midi.cpp b/muse/muse/midi.cpp
index 9cc71249..9741d9fb 100644
--- a/muse/muse/midi.cpp
+++ b/muse/muse/midi.cpp
@@ -799,7 +799,7 @@ void MidiOutPort::process(unsigned from, unsigned to, const Pos& pos, unsigned f
                                     break;
                                     }
 
-                              midiDriver->putEvent(_alsaPort, *ev);
+                              midiDriver->putEvent(alsaPort(), *ev);
                               _nextPlayEvent = ev;
                               _nextPlayEvent++;
                               }
diff --git a/muse/muse/midiinport.cpp b/muse/muse/midiinport.cpp
index 384ef418..2a67ea2e 100644
--- a/muse/muse/midiinport.cpp
+++ b/muse/muse/midiinport.cpp
@@ -35,8 +35,7 @@
 MidiInPort::MidiInPort()
    : MidiTrackBase(MIDI_IN)
       {
-      _alsaPort = 0;
-      _jackPort = 0;
+      _channels = 1;
       }
 
 //---------------------------------------------------------
@@ -45,10 +44,6 @@ MidiInPort::MidiInPort()
 
 MidiInPort::~MidiInPort()
       {
-      if (_alsaPort)
-            midiDriver->unregisterPort(_alsaPort);
-      if (_jackPort)
-            audioDriver->unregisterPort(_jackPort);
       }
 
 //---------------------------------------------------------
@@ -58,10 +53,10 @@ MidiInPort::~MidiInPort()
 void MidiInPort::setName(const QString& s)
       {
       Track::setName(s);
-      if (_alsaPort)
-            midiDriver->setPortName(_alsaPort, s);
-      if (_jackPort)
-            audioDriver->setPortName(_jackPort, s);
+      if (alsaPort(0))
+            midiDriver->setPortName(alsaPort(), s);
+      if (jackPort(0))
+            audioDriver->setPortName(jackPort(), s);
       }
 
 //---------------------------------------------------------
@@ -90,72 +85,6 @@ void MidiInPort::read(QDomNode node)
             }
       }
 
-//---------------------------------------------------------
-//   activate
-//---------------------------------------------------------
-
-void MidiInPort::activate1()
-      {
-      if (_alsaPort)
-            printf("MidiInPort::activate1(): alsa port already active!\n");
-      else
-            _alsaPort = midiDriver->registerOutPort(_name, true);
-      if (_jackPort)
-            printf("MidiInPort::activate1(): jack port already active!\n");
-      else
-            _jackPort = audioDriver->registerInPort(_name, true);
-      }
-
-//---------------------------------------------------------
-//   activate2
-//    connect all routes to jack; can only be done if
-//    jack is activ running
-//---------------------------------------------------------
-
-void MidiInPort::activate2()
-      {
-      if (audioState != AUDIO_RUNNING) {
-            printf("MidiInPort::activate2(): no audio running !\n");
-            abort();
-            }
-      for (iRoute i = _inRoutes.begin(); i != _inRoutes.end(); ++i) {
-            if (i->type == Route::JACKMIDIPORT)
-                  audioDriver->connect(i->port, _jackPort);
-            else if (i->type == Route::MIDIPORT)
-                  midiDriver->connect(i->port, _alsaPort);
-            else
-                  printf("MidiInPort::activate2(): bad route type\n");
-            }
-      }
-
-//---------------------------------------------------------
-//   deactivate
-//---------------------------------------------------------
-
-void MidiInPort::deactivate()
-      {
-      for (ciRoute i = _inRoutes.begin(); i != _inRoutes.end(); ++i) {
-            if (i->type == Route::JACKMIDIPORT)
-                  audioDriver->disconnect(i->port, _jackPort);
-            else if (i->type == Route::MIDIPORT)
-                  midiDriver->disconnect(i->port, _alsaPort);
-            else
-                  printf("MidiInPort::deactivate(): bad route type\n");
-            }
-      if (_jackPort) {
-            audioDriver->unregisterPort(_jackPort);
-            _jackPort = 0;
-            }
-      else
-            printf("MidiInPort::deactivate(): jack port not active!\n");
-      if (_alsaPort) {
-            midiDriver->unregisterPort(_alsaPort);
-            _alsaPort = 0;
-            }
-      else
-            printf("MidiInPort::deactivate(): alsa port not active!\n");
-      }
-
 //---------------------------------------------------------
 //   midiReceived
 //---------------------------------------------------------
diff --git a/muse/muse/midiinport.h b/muse/muse/midiinport.h
index a19393f9..d1c294eb 100644
--- a/muse/muse/midiinport.h
+++ b/muse/muse/midiinport.h
@@ -30,26 +30,18 @@
 class MidiInPort : public MidiTrackBase {
       Q_OBJECT
 
-      Port _alsaPort;
-      Port _jackPort;
-
       MPEventList _recordEvents;
 
    public:
       MidiInPort();
       ~MidiInPort();
 
-      virtual void activate1();
-      virtual void activate2();
-      virtual void deactivate();
       virtual void setName(const QString& s);
       virtual void write(Xml&) const;
       virtual void read(QDomNode);
       virtual Track* newTrack() const     { return new MidiInPort(); }
       virtual bool isMute() const         { return _mute; }
       virtual Part* newPart(Part*, bool)  { return 0; }
-      Port alsaPort() const               { return _alsaPort; }
-      Port jackPort() const               { return _jackPort; }
 
 #ifndef __APPLE__      
       void eventReceived(snd_seq_event_t*);
diff --git a/muse/muse/midioutport.cpp b/muse/muse/midioutport.cpp
index 23e079de..bdad88cc 100644
--- a/muse/muse/midioutport.cpp
+++ b/muse/muse/midioutport.cpp
@@ -38,12 +38,11 @@ MidiOutPort::MidiOutPort()
       _instrument = genericMidiInstrument;
       for (int ch = 0; ch < MIDI_CHANNELS; ++ch)
             _channel[ch] = new MidiChannel(this, ch);
-      _alsaPort       = 0;
-      _jackPort       = 0;
       _nextPlayEvent  = _playEvents.end();
       _sendSync       = false;
       _deviceId       = 127;        // all
       addMidiController(_instrument, CTRL_MASTER_VOLUME);
+      _channels = 1;
       }
 
 //---------------------------------------------------------
@@ -62,10 +61,6 @@ void MidiOutPort::playFifo()
 
 MidiOutPort::~MidiOutPort()
       {
-      if (_alsaPort)
-            midiDriver->unregisterPort(_alsaPort);
-      if (_jackPort)
-            audioDriver->unregisterPort(_jackPort);
       for (int ch = 0; ch < MIDI_CHANNEL; ++ch)
             delete _channel[ch];
       }
@@ -77,10 +72,10 @@ MidiOutPort::~MidiOutPort()
 void MidiOutPort::setName(const QString& s)
       {
       Track::setName(s);
-      if (_alsaPort)
-            midiDriver->setPortName(_alsaPort, s);
-      if (_jackPort)
-            audioDriver->setPortName(_jackPort, s);
+      if (alsaPort())
+            midiDriver->setPortName(alsaPort(), s);
+      if (jackPort())
+            audioDriver->setPortName(jackPort(), s);
       for (int ch = 0; ch < MIDI_CHANNELS; ++ch)
             _channel[ch]->setDefaultName();
       }
@@ -130,70 +125,6 @@ void MidiOutPort::read(QDomNode node)
             }
       }
 
-//---------------------------------------------------------
-//   activate
-//---------------------------------------------------------
-
-void MidiOutPort::activate1()
-      {
-      if (_jackPort)
-            printf("MidiOutPort::activate1(): jack port already active!\n");
-      else
-            _jackPort = audioDriver->registerOutPort(_name, true);
-      if (_alsaPort)
-            printf("MidiOutPort::activate1(): alsa port already active!\n");
-      else
-            _alsaPort = midiDriver->registerInPort(_name, true);
-      }
-
-//---------------------------------------------------------
-//   activate2
-//    connect all routes to jack; can only be done if
-//    jack is activ running
-//---------------------------------------------------------
-
-void MidiOutPort::activate2()
-      {
-      if (audioState != AUDIO_RUNNING) {
-            printf("MidiOutPort::activate2(): no audio running !\n");
-            abort();
-            }
-      for (iRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i) {
-            if (i->type == Route::JACKMIDIPORT)
-                  audioDriver->connect(_jackPort, i->port);
-            else if (i->type == Route::MIDIPORT)
-                  midiDriver->connect(_alsaPort, i->port);
-            else
-                  printf("MidiOutPort::activate2(): bad route type\n");
-            }
-      }
-
-//---------------------------------------------------------
-//   deactivate
-//---------------------------------------------------------
-
-void MidiOutPort::deactivate()
-      {
-      for (ciRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i) {
-            if (i->type ==Route::JACKMIDIPORT)
-                  audioDriver->disconnect(_jackPort, i->port);
-            else if (i->type == Route::MIDIPORT)
-                  midiDriver->disconnect(_alsaPort, i->port);
-            }
-      if (_jackPort) {
-            audioDriver->unregisterPort(_jackPort);
-            _jackPort = 0;
-            }
-      else
-            printf("MidiInPort::deactivate(): jack port not active!\n");
-      if (_alsaPort) {
-            midiDriver->unregisterPort(_alsaPort);
-            _alsaPort = 0;
-            }
-      else
-            printf("MidiInPort::deactivate(): alsa port not active!\n");
-      }
-
 //---------------------------------------------------------
 //   putEvent
 //    send event to midi driver
@@ -222,7 +153,7 @@ void MidiOutPort::putEvent(const MidiEvent& ev)
                   }
 
             if (a == CTRL_PITCH) {
-                  midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_PITCHBEND, b, 0));
+                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_PITCHBEND, b, 0));
                   return;
                   }
             if (a == CTRL_PROGRAM) {
@@ -232,10 +163,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));
+                              midiDriver->putEvent(alsaPort(), 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));
+                              midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, CTRL_LBANK, lb));
+                        midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_PROGRAM, pr, 0));
                         return;
 //                        }
                   }
@@ -247,63 +178,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);
+                  midiDriver->putEvent(alsaPort(), 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);
+                  midiDriver->putEvent(alsaPort(), 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));
+                  midiDriver->putEvent(alsaPort(), MidiEvent(0, chn, ME_CONTROLLER, ctrlH, dataH));
+                  midiDriver->putEvent(alsaPort(), 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));
+                  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));
                   }
             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));
+                  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));
                   }
             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));
+                  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));
                   }
             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));
+                  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));
                   }
             else {
                   printf("putEvent: unknown controller type 0x%x\n", a);
                   }
 #endif
             }
-      midiDriver->putEvent(_alsaPort, ev);
+      midiDriver->putEvent(alsaPort(), ev);
       }
 
 //---------------------------------------------------------
@@ -313,7 +244,7 @@ void MidiOutPort::putEvent(const MidiEvent& ev)
 void MidiOutPort::playEventList()
       {
       for (; _nextPlayEvent != _playEvents.end(); ++_nextPlayEvent)
-            midiDriver->putEvent(_alsaPort, *_nextPlayEvent);
+            midiDriver->putEvent(alsaPort(), *_nextPlayEvent);
       }
 
 //---------------------------------------------------------
diff --git a/muse/muse/midioutport.h b/muse/muse/midioutport.h
index 311b2bff..f90ad376 100644
--- a/muse/muse/midioutport.h
+++ b/muse/muse/midioutport.h
@@ -32,8 +32,6 @@ class MidiOutPort : public MidiTrackBase {
 
       MidiInstrument* _instrument;
       MidiChannel* _channel[MIDI_CHANNELS];
-      Port _alsaPort;
-      Port _jackPort;
 
       bool _sendSync;   // this port sends mtc mmc events
       int _deviceId;    // 0-126; 127 == all
@@ -54,10 +52,6 @@ class MidiOutPort : public MidiTrackBase {
       MidiOutPort();
       ~MidiOutPort();
 
-      virtual void activate1();
-      virtual void activate2();
-      virtual void deactivate();
-
       MidiChannel* channel(int n)         { return _channel[n]; }
 
       virtual void setName(const QString& s);
@@ -73,8 +67,6 @@ class MidiOutPort : public MidiTrackBase {
       bool guiVisible() const;
       bool hasGui() const;
 
-      Port alsaPort() const               { return _alsaPort; }
-      Port jackPort() const               { return _jackPort; }
       void putEvent(const MidiEvent&);
 
       MPEventList* playEvents()          { return &_playEvents;   }
diff --git a/muse/muse/mixer/astrip.cpp b/muse/muse/mixer/astrip.cpp
index fa145a31..754861f1 100644
--- a/muse/muse/mixer/astrip.cpp
+++ b/muse/muse/mixer/astrip.cpp
@@ -770,12 +770,8 @@ void AudioStrip::oRoutePressed()
                               action->setCheckable(true);
                               Route dst(ip.port, i, Route::AUDIOPORT);
                               action->setData(QVariant::fromValue(dst));
-                              for (iRoute ir = orl->begin(); ir != orl->end(); ++ir) {
-                                    if (*ir == dst) {
-                                          action->setChecked(true);
-                                          break;
-                                          }
-                                    }
+                              int idx = orl->indexOf(dst);
+                              action->setChecked(idx != -1);
                               }
                         }
                   }
diff --git a/muse/muse/muse.cpp b/muse/muse/muse.cpp
index 94c579e3..0b5a2967 100644
--- a/muse/muse/muse.cpp
+++ b/muse/muse/muse.cpp
@@ -267,9 +267,8 @@ bool MusE::seqStart()
       // do connections
       //
       TrackList* tl = song->tracks();
-      for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+      for (iTrack i = tl->begin(); i != tl->end(); ++i)
             (*i)->activate2();
-      	}
       return true;
       }
 
diff --git a/muse/muse/route.cpp b/muse/muse/route.cpp
index 70499e05..1589b480 100644
--- a/muse/muse/route.cpp
+++ b/muse/muse/route.cpp
@@ -98,9 +98,9 @@ bool addRoute(Route src, Route dst)
                   }
             src.channel = dst.channel;
             RouteList* inRoutes = dst.track->inRoutes();
-            for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i) {
-                  if (*i == src)    // route already there
-                        return true;
+            if (inRoutes->indexOf(src) != -1) {
+                  printf("  route already there 1\n");
+                  return true;
                   }
             inRoutes->push_back(src);
             }
@@ -117,9 +117,9 @@ bool addRoute(Route src, Route dst)
             RouteList* outRoutes = src.track->outRoutes();
             dst.channel = src.channel;
 
-            for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) {
-                  if (*i == dst)    // route already there
-                        return true;
+            if (outRoutes->indexOf(dst) != -1) {
+                  printf("  route already there 2\n");
+                  return true;
                   }
             outRoutes->push_back(dst);
             }
@@ -128,16 +128,12 @@ bool addRoute(Route src, Route dst)
             inRoutes->insert(inRoutes->begin(), src);
             }
       else {
-            RouteList* outRoutes = src.track->outRoutes();
-            for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) {
-                  if (*i == dst) {    // route already there
-                        printf("  route already there\n");
-                        return true;
-                        }
+            if (src.track->outRoutes()->indexOf(dst) != -1) {
+                  printf("  route already there 3\n");
+                  return true;
                   }
-            outRoutes->push_back(dst);
-            RouteList* inRoutes = dst.track->inRoutes();
-            inRoutes->insert(inRoutes->begin(), src);
+            src.track->outRoutes()->push_back(dst);
+            dst.track->inRoutes()->push_back(src);
             }
       return true;
       }
@@ -148,6 +144,9 @@ bool addRoute(Route src, Route dst)
 
 void removeRoute(Route src, Route dst)
       {
+//      printf("removeRoute %s.%d:<%s> %s.%d:<%s>\n",
+//         src.tname(), src.channel, src.name().toLatin1().data(),
+//         dst.tname(), dst.channel, dst.name().toLatin1().data());
       if (src.type == Route::AUDIOPORT || src.type == Route::MIDIPORT
          || src.type == Route::JACKMIDIPORT) {
             if (dst.type != Route::TRACK && dst.type != Route::SYNTIPORT) {
@@ -279,6 +278,8 @@ void Song::readRoute(QDomNode n)
             s.channel = d.channel;
       if (d.type == Route::AUDIOPORT)
             d.channel = s.channel;
+      if (s.type == Route::TRACK && s.track->type() == Track::MIDI_IN)
+            d.channel = s.channel;
       addRoute(s, d);
       }
 
@@ -371,7 +372,6 @@ void Route::read(QDomNode node)
       {
       QDomElement e = node.toElement();
       channel       = e.attribute("channel","0").toInt() - 1;
-//      int stream    = e.attribute("stream", "0").toInt();
       QString s     = e.attribute("name");
       QString st    = e.attribute("type", "TRACK");
 
@@ -396,6 +396,8 @@ void Route::read(QDomNode node)
                               }
                         }
                   }
+            if (track == 0)
+                  printf("Route::read(): track <%s> not found\n", s.toLatin1().data());
             }
       else if (st == "AUDIOPORT") {
             type = Route::AUDIOPORT;
@@ -453,6 +455,8 @@ void Route::read(QDomNode node)
                               break;
                         }
                   }
+            if (plugin == 0)
+                  printf("Route::read(): plugin <%s> not found\n", s.toLatin1().data());
             }
       else {
             printf("Route::read(): unknown type <%s>\n", st.toLatin1().data());
@@ -460,24 +464,3 @@ void Route::read(QDomNode node)
             }
       }
 
-//---------------------------------------------------------
-//   findTrack
-//---------------------------------------------------------
-
-Track* Song::findTrack(const QString& s) const
-      {
-      TrackList* tl = song->tracks();
-      for (iTrack i = tl->begin(); i != tl->end(); ++i) {
-            Track* track = *i;
-            if (track->name() == s)
-                  return track;
-            }
-      MidiChannelList* mc = song->midiChannel();
-      for (iMidiChannel i = mc->begin(); i != mc->end(); ++i) {
-            MidiChannel* t = *i;
-            if (t->name() == s)
-                  return t;
-            }
-      printf("track <%s> not found\n", s.toLatin1().data());
-      return 0;
-      }
diff --git a/muse/muse/seqmsg.cpp b/muse/muse/seqmsg.cpp
index 5a66c5f0..d3a5cd4c 100644
--- a/muse/muse/seqmsg.cpp
+++ b/muse/muse/seqmsg.cpp
@@ -211,7 +211,7 @@ void Audio::msgSetChannels(AudioTrack* node, int n)
                         if (i < n && ai->jackPort(i) == 0) {
                               char buffer[128];
                               snprintf(buffer, 128, "%s-%d", name.toLatin1().data(), i);
-                              ai->setJackPort(i, audioDriver->registerInPort(QString(buffer), false));
+                              ai->setJackPort(audioDriver->registerInPort(QString(buffer), false), i);
                               }
                         else if ((i >= n) && ai->jackPort(i)) {
                               RouteList* ir = node->inRoutes();
@@ -223,7 +223,7 @@ void Audio::msgSetChannels(AudioTrack* node, int n)
                                           }
                                     }
                               audioDriver->unregisterPort(ai->jackPort(i));
-                              ai->setJackPort(i, 0);
+                              ai->setJackPort(0, i);
                               }
                         }
                   }
@@ -234,7 +234,7 @@ void Audio::msgSetChannels(AudioTrack* node, int n)
                         if (i < n && jp == 0) {
                               char buffer[128];
                               snprintf(buffer, 128, "%s-%d", name.toLatin1().data(), i);
-                              ao->setJackPort(i, audioDriver->registerOutPort(QString(buffer), false));
+                              ao->setJackPort(audioDriver->registerOutPort(QString(buffer), false), i);
                               }
                         else if (i >= n && jp) {
                               RouteList* ir = node->outRoutes();
@@ -246,7 +246,7 @@ void Audio::msgSetChannels(AudioTrack* node, int n)
                                           }
                                     }
                               audioDriver->unregisterPort(jp);
-                              ao->setJackPort(i, 0);
+                              ao->setJackPort(0, i);
                               }
                         }
                   }
diff --git a/muse/muse/song.cpp b/muse/muse/song.cpp
index 33dc9346..d3bde0e3 100644
--- a/muse/muse/song.cpp
+++ b/muse/muse/song.cpp
@@ -226,23 +226,6 @@ void Song::deleteEvent(Event& event, Part* part)
       part->events()->erase(ev);
       }
 
-//---------------------------------------------------------
-//   findTrack
-//---------------------------------------------------------
-
-MidiTrack* Song::findTrack(const Part* part) const
-      {
-      for (ciMidiTrack t = _midis.begin(); t != _midis.end(); ++t) {
-            MidiTrack* track = *t;
-            PartList* pl = track->parts();
-            for (iPart p = pl->begin(); p != pl->end(); ++p) {
-                  if (part == p->second)
-                        return track;
-                  }
-            }
-      return 0;
-      }
-
 //---------------------------------------------------------
 //   setLoop
 //    set transport loop flag
@@ -1142,6 +1125,7 @@ void Song::clear(bool signal)
 
 //      for (iTrack i = _tracks.begin(); i != _tracks.end(); ++i)
 //            (*i)->deactivate();
+
       _selectedTrack = 0;
       _tracks.clear();
       _midis.clearDelete();
@@ -1650,18 +1634,11 @@ void Song::insertTrack1(Track* track, int idx)
       {
       iTrack i = _tracks.index2iterator(idx);
       _tracks.insert(i, track);
-      switch(track->type()) {
-            case Track::AUDIO_SOFTSYNTH:
-                  {
-                  SynthI* s = (SynthI*)track;
-                  Synth* sy = s->synth();
-                  if (!s->isActivated()) {
-                        s->initInstance(sy);
-                        }
-                  }
-                  break;
-            default:
-                  break;
+      if (track->type() == Track::AUDIO_SOFTSYNTH) {
+            SynthI* s = (SynthI*)track;
+            Synth* sy = s->synth();
+            if (!s->isActivated())
+                  s->initInstance(sy);
             }
       if (audioState == AUDIO_RUNNING) {
             track->activate1();
@@ -1724,7 +1701,6 @@ void Song::insertTrack2(Track* track)
       //
       //  connect routes
       //
-
       Route src(track);
       if (track->type() == Track::AUDIO_SOFTSYNTH)
             src.type = Route::SYNTIPORT;
@@ -1784,8 +1760,8 @@ void Song::removeTrack(Track* track)
 
 void Song::removeTrack1(Track* track)
       {
-      if (track->type() != Track::MIDI_OUT && track->type() != Track::MIDI_IN)
-            track->deactivate();
+//      if (track->type() != Track::MIDI_OUT && track->type() != Track::MIDI_IN)
+      track->deactivate();
       _tracks.erase(track);
       }
 
@@ -1804,11 +1780,9 @@ void Song::removeTrack2(Track* track)
                   _midis.erase(track);
                   break;
             case Track::MIDI_OUT:
-                  track->deactivate();
                   _midiOutPorts.erase(track);
                   break;
             case Track::MIDI_IN:
-//DEBUG                  track->deactivate();
                   _midiInPorts.erase(track);
                   break;
             case Track::MIDI_CHANNEL:
@@ -1859,8 +1833,13 @@ void Song::removeTrack2(Track* track)
             int idx = r.track->inRoutes()->indexOf(src);
             if (idx != -1)
                   r.track->inRoutes()->removeAt(idx);
-            else
+            else {
                   printf("Song::removeTrack2(): output route not found\n");
+                  src.dump();
+                  printf("  in route list:\n");
+                  foreach (const Route rr, *(r.track->inRoutes()))
+                        rr.dump();
+                  }
             }
       }
 
diff --git a/muse/muse/song.h b/muse/muse/song.h
index 798e61aa..7e64de2c 100644
--- a/muse/muse/song.h
+++ b/muse/muse/song.h
@@ -322,8 +322,6 @@ class Song : public QObject {
 //      void removeMarkedTracks();
       void changeTrackName(Track* track, const QString&);
 
-      MidiTrack* findTrack(const Part* part) const;
-      Track* findTrack(const QString& name) const;
       void swapTracks(int i1, int i2);
       void moveTrack(Track*, Track*);
       void insertTrack(Track*, int idx);
diff --git a/muse/muse/track.cpp b/muse/muse/track.cpp
index bead0655..7a55cd8d 100644
--- a/muse/muse/track.cpp
+++ b/muse/muse/track.cpp
@@ -33,6 +33,8 @@
 #include "gui.h"
 #include "midioutport.h"
 #include "midichannel.h"
+#include "driver/audiodev.h"
+#include "driver/mididev.h"
 
 // synchronize with TrackType!:
 
@@ -111,6 +113,8 @@ void Track::init()
             _meter[i]     = 0.0f;
             _peak[i]      = 0.0f;
             _peakTimer[i] = 0;
+            _alsaPort[i]  = 0;
+            _jackPort[i]  = 0;
             }
       }
 
@@ -132,6 +136,10 @@ Track::Track(Track::TrackType t)
 Track::~Track()
 	{
       delete _parts;
+      if (_alsaPort)
+            midiDriver->unregisterPort(_alsaPort);
+      if (_jackPort)
+            audioDriver->unregisterPort(_jackPort);
       }
 
 //---------------------------------------------------------
@@ -172,13 +180,32 @@ void Track::setDefaultName()
                   base = cname();
                   break;
             };
+      //
+      // create unique name
+      //
       base += " ";
       for (int i = 1; true; ++i) {
             QString n;
             n.setNum(i);
             QString s = base + n;
-            Track* track = song->findTrack(s);
-            if (track == 0) {
+            bool found = false;
+            TrackList* tl = song->tracks();
+            for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+                  Track* track = *i;
+                  if (track->name() == s) {
+                        found = true;
+                        break;
+                        }
+                  }
+            MidiChannelList* mc = song->midiChannel();
+            for (iMidiChannel i = mc->begin(); i != mc->end(); ++i) {
+                  MidiChannel* t = *i;
+                  if (t->name() == s) {
+                        found = true;
+                        break;
+                        }
+                  }
+            if (!found) {
                   setName(s);
                   break;
                   }
@@ -658,30 +685,34 @@ void Track::updateController()
 
 void Track::writeRouting(Xml& xml) const
       {
-      const RouteList* rl = &_inRoutes;
-      for (ciRoute r = rl->begin(); r != rl->end(); ++r) {
+      foreach(Route src, _inRoutes) {
+            Route dst((Track*)this);
             if (type() == AUDIO_INPUT || type() == MIDI_IN) {
                   xml.tag("Route");
-                  Route dst((Track*)this, r->channel);
-                  r->write(xml, "src");
+                  dst.channel = src.channel;
+                  src.write(xml, "src");
                   dst.write(xml, "dst");
                   xml.etag("Route");
                   }
-            if (r->type == Route::AUXPLUGIN) {
+            else if (src.type == Route::AUXPLUGIN) {
                   xml.tag("Route");
-                  Route dst((Track*)this);
-                  r->write(xml, "src");
+                  src.write(xml, "src");
                   dst.write(xml, "dst");
                   xml.etag("Route");
                   }
             }
-      for (ciRoute r = _outRoutes.begin(); r != _outRoutes.end(); ++r) {
+      foreach(Route r, _outRoutes) {
             Route src((Track*)this);
-            if (type() == AUDIO_OUTPUT)
-                  src.channel = r->channel;
+            Route dst(r);
+            if (type() == MIDI_IN) {
+                  src.channel = dst.channel;
+                  dst.channel = 0;
+                  }
+            else if (type() == AUDIO_OUTPUT)
+                  src.channel = r.channel;
             xml.tag("Route");
             src.write(xml, "src");
-            r->write(xml, "dst");
+            dst.write(xml, "dst");
             xml.etag("Route");
             }
       }
@@ -938,4 +969,101 @@ void Track::resetAllMeter()
             (*i)->resetMeter();
       }
 
+//---------------------------------------------------------
+//   activate
+//---------------------------------------------------------
+
+void Track::activate1()
+      {
+      if (isMidiTrack()) {
+            if (alsaPort(0))
+                  printf("Track::activate1() midi: alsa port already active!\n");
+            if (jackPort(0))
+                  printf("Track::activate1() midi: jack port already active!\n");
+            if (type() == MIDI_OUT) {
+                  _alsaPort[0] = midiDriver->registerInPort(_name, true);
+                  _jackPort[0] = audioDriver->registerOutPort(_name, true);
+                  }
+            else if (type() == MIDI_IN) {
+                  _alsaPort[0] = midiDriver->registerOutPort(_name, true);
+                  _jackPort[0] = audioDriver->registerInPort(_name, true);
+                  }
+            return;
+            }
+      for (int i = 0; i < channels(); ++i) {
+            if (jackPort(i))
+                  printf("Track::activate1(): already active!\n");
+            else {
+                  QString s(QString("%1-%2").arg(_name).arg(i));
+                  if (type() == AUDIO_OUTPUT)
+                        _jackPort[i] = audioDriver->registerOutPort(s, false);
+                  else if (type() == AUDIO_INPUT)
+                        _jackPort[i] = audioDriver->registerInPort(s, false);
+                  }
+            }
+      }
+
+//---------------------------------------------------------
+//   activate2
+//    connect all in/out routes
+//    connect to JACK only works if JACK is running
+//---------------------------------------------------------
+
+void Track::activate2()
+      {
+      if (audioState != AUDIO_RUNNING) {
+            printf("Track::activate2(): no audio running !\n");
+            abort();
+            }
+      foreach(Route r, _outRoutes) {
+            if (r.type == Route::JACKMIDIPORT)
+                  audioDriver->connect(_jackPort[0], r.port);
+            else if (r.type == Route::MIDIPORT)
+                  midiDriver->connect(_alsaPort[0], r.port);
+            }
+      foreach(Route r, _inRoutes) {
+            if (r.type == Route::JACKMIDIPORT)
+                  audioDriver->connect(r.port, _jackPort[0]);
+            else if (r.type == Route::MIDIPORT)
+                  midiDriver->connect(r.port, _alsaPort[0]);
+            }
+      }
+
+//---------------------------------------------------------
+//   deactivate
+//---------------------------------------------------------
+
+void Track::deactivate()
+      {
+      foreach (Route r, _outRoutes) {
+            if (r.type == Route::JACKMIDIPORT)
+                  audioDriver->disconnect(_jackPort[0], r.port);
+            else if (r.type == Route::AUDIOPORT)
+                  audioDriver->disconnect(_jackPort[r.channel], r.port);
+            else if (r.type == Route::MIDIPORT)
+                  midiDriver->disconnect(_alsaPort[0], r.port);
+            }
+      foreach (Route r, _inRoutes) {
+            if (r.type == Route::JACKMIDIPORT)
+                  audioDriver->disconnect(r.port, _jackPort[0]);
+            else if (r.type == Route::AUDIOPORT)
+                  audioDriver->disconnect(r.port, _jackPort[r.channel]);
+            else if (r.type == Route::MIDIPORT)
+                  midiDriver->disconnect(r.port, _alsaPort[0]);
+            }
+      for (int i = 0; i < channels(); ++i) {
+            if (_jackPort[i]) {
+                  audioDriver->unregisterPort(_jackPort[i]);
+                  _jackPort[i] = 0;
+                  }
+            else
+                  printf("Track::deactivate(): jack port not active!\n");
+            if (_alsaPort[i]) {
+                  midiDriver->unregisterPort(_alsaPort[i]);
+                  _alsaPort[i] = 0;
+                  }
+            else
+                  printf("Track::deactivate(): alsa port not active!\n");
+            }
+      }
 
diff --git a/muse/muse/track.h b/muse/muse/track.h
index 6d2bff17..278a2105 100644
--- a/muse/muse/track.h
+++ b/muse/muse/track.h
@@ -113,6 +113,7 @@ class Track : public QObject {
       TrackType _type;
       QString _comment;
       PartList* _parts;
+      Port _alsaPort[MAX_CHANNELS], _jackPort[MAX_CHANNELS];
 
       void init();
 
@@ -125,6 +126,8 @@ class Track : public QObject {
       bool _off;
       bool _monitor;
       int _channels;                // 1 - mono, 2 - stereo
+                                    // Note: midi out/in tracks have 
+                                    // 1 channel
       CtrlRecList _recEvents;       // recorded automation events
       double _meter[MAX_CHANNELS];
       double _peak[MAX_CHANNELS];
@@ -184,9 +187,9 @@ class Track : public QObject {
       //    (undo/redo)
       // connects/reconnects to the outside world
       //
-      virtual void activate1()   {}
-      virtual void activate2()   {}
-      virtual void deactivate()  {}
+      void activate1();
+      void activate2();
+      void deactivate();
 
       //----------------------------------------------------------
       //   controller handling
@@ -311,6 +314,16 @@ class Track : public QObject {
       bool noOutRoute() const  { return _outRoutes.empty(); }
       void writeRouting(Xml&) const;
 
+      Port alsaPort(int channel = 0) const    { return _alsaPort[channel]; }
+      Port jackPort(int channel = 0) const    { return _jackPort[channel]; }
+
+      void setAlsaPort(const Port& port, int channel = 0) { 
+            _alsaPort[channel] = port; 
+            }
+      void setJackPort(const Port& port, int channel = 0) { 
+            _jackPort[channel] = port; 
+            }
+
       struct ArrangerTrack arrangerTrack;
       ArrangerTrackList subtracks;
 
diff --git a/muse/muse/wave.cpp b/muse/muse/wave.cpp
index 280b291e..7ef0a665 100644
--- a/muse/muse/wave.cpp
+++ b/muse/muse/wave.cpp
@@ -616,7 +616,6 @@ size_t SndFile::read(int srcChannels, float** dst, size_t n)
       {
       float buffer[n * sfinfo.channels];
       size_t rn       = sf_readf_float(sfRT, buffer, n);
-//      sf_seek(sfRT, n, SEEK_CUR);   //libsndfile does not update position??
 
       float* src      = buffer;
       int dstChannels = sfinfo.channels;
diff --git a/muse/muse/wavetrack.cpp b/muse/muse/wavetrack.cpp
index 61688014..1f964789 100644
--- a/muse/muse/wavetrack.cpp
+++ b/muse/muse/wavetrack.cpp
@@ -82,15 +82,11 @@ void WaveTrack::fetchData(unsigned pos, unsigned samples, int widx)
       for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
             Part* part = ip->second;
 
-            // DEBUG
-            int type = int(part->type());
-            if (type != AL::FRAMES)
-                  printf("part has wrong type\n");
-
             if (part->mute())
                   continue;
             unsigned p_spos = part->frame();
-            if (pos + samples < p_spos)
+//            if (pos + samples < p_spos)
+            if (pos + samples <= p_spos)
                   break;
             unsigned p_epos = p_spos + part->lenFrame();
             if (pos >= p_epos)
@@ -101,7 +97,8 @@ void WaveTrack::fetchData(unsigned pos, unsigned samples, int widx)
                   Event& event    = ie->second;
 
                   unsigned e_spos = event.frame() + p_spos;
-                  if (pos + samples < e_spos)
+                  // if (pos + samples < e_spos)
+                  if (pos + samples <= e_spos)
                         break;
                   unsigned nn     = event.lenFrame();
                   unsigned e_epos = e_spos + nn;
-- 
cgit v1.2.3