summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
Diffstat (limited to 'muse2')
-rw-r--r--muse2/ChangeLog8
-rw-r--r--muse2/muse/app.cpp332
-rw-r--r--muse2/muse/arranger/tlist.cpp8
-rw-r--r--muse2/muse/audiotrack.cpp3
-rw-r--r--muse2/muse/ctrl/ctrledit.cpp22
-rw-r--r--muse2/muse/ctrl/ctrledit.h3
-rw-r--r--muse2/muse/midiport.cpp8
-rw-r--r--muse2/muse/mixer/amixer.cpp3
-rw-r--r--muse2/muse/mixer/astrip.cpp374
-rw-r--r--muse2/muse/mixer/mstrip.cpp5
-rw-r--r--muse2/muse/node.cpp26
-rw-r--r--muse2/muse/route.cpp67
-rw-r--r--muse2/muse/track.cpp78
-rw-r--r--muse2/muse/widgets/mtrackinfo.cpp15
-rw-r--r--muse2/muse/widgets/mtrackinfobase.ui18
15 files changed, 641 insertions, 329 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index 5006df0b..8bcfe6f0 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,11 @@
+09.01.2011:
+ - These changes marked as p4.0.14:
+ - Applied aux send fix AudioTrack::writeProperties() by Remon. Thanks. (Tim)
+ * Feature!: Complete soloing system (after 4 years). Support chaining Midi Port/Audio Out -> Audio In. (Tim)
+ Click on audio strip iR, or midi strip oR, or midi track info oR buttons to see new additions.
+ Tested thoroughly, but of course this major change needs wider testing.
+ TODO TODO: Fix trackinfo width (a minor button placement gui issue).
+ - Fixed very slow midi trackinfo property adjustments with mixer shown. In AudioMixerApp::songChanged(). (Tim)
04.01.2011:
- Added saving and restoring of pianoroll trackinfo h-splitter state. (Tim)
- Fixed multiple velocity controllers appearing on song reload. Tested OK. (Tim)
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp
index 1f2edc1a..2c4758a6 100644
--- a/muse2/muse/app.cpp
+++ b/muse2/muse/app.cpp
@@ -49,6 +49,7 @@
#include "transpose.h"
#include "waveedit.h"
#include "widgets/projectcreateimpl.h"
+#include "widgets/menutitleitem.h"
#ifdef DSSI_SUPPORT
#include "dssihost.h"
@@ -2188,7 +2189,7 @@ PopupMenu* MusE::getRoutingPopupMenu()
void MusE::updateRouteMenus(Track* track, QObject* master)
{
- // NOTE: The puropse of this routine is to make sure the items actually reflect
+ // NOTE: The purpose of this routine is to make sure the items actually reflect
// the routing status. And with MusE-1 QT3, it was also required to actually
// check the items since QT3 didn't do it for us.
// But now with MusE-2 and QT4, QT4 checks an item when it is clicked.
@@ -2218,9 +2219,84 @@ void MusE::updateRouteMenus(Track* track, QObject* master)
{
// p3.3.50 Ignore the 'toggle' items.
if(imm->second.type == Route::MIDI_PORT_ROUTE &&
- imm->first >= (MIDI_PORTS * MIDI_CHANNELS) && imm->first < (MIDI_PORTS * MIDI_CHANNELS + MIDI_PORTS))
+ //imm->first >= (MIDI_PORTS * MIDI_CHANNELS) && imm->first < (MIDI_PORTS * MIDI_CHANNELS + MIDI_PORTS))
+ imm->second.channel == (1 << MIDI_CHANNELS) - 1) // p4.0.14 See if all channels are set, rather than using ID.
continue;
+
+ // p4.0.14 TODO FIXME Couldn't quite figure out the logic yet. It should be possible (I hope).
+ // But not really required for now, as per above note.
+ if(gIsOutRoutingPopupMenu && track->isMidiTrack() &&
+ imm->second.type == Route::TRACK_ROUTE && imm->second.track->type() == Track::AUDIO_INPUT)
+ return;
+ #if 0
+ printf("imm route:\n"); // REMOVE Tim.
+ imm->second.dump();
+ if(track->isMidiTrack())
+ {
+ if(imm->second.type == Route::TRACK_ROUTE && imm->second.track->type() == Track::AUDIO_INPUT)
+ {
+ Route &aRoute = imm->second;
+ int chbit = aRoute.channel;
+ ///Route bRoute(track, chbit);
+ ///int mdidx = bRoute.midiPort;
+ int port = ((MidiTrack*)track)->outPort();
+ if(port < 0 || port >= MIDI_PORTS)
+ continue;
+ int tchbit = 1 << ((MidiTrack*)track)->outChannel();
+
+ MidiPort* mp = &midiPorts[port];
+
+ ///Route bRoute(port, chbit);
+
+ //int chmask = 0;
+ bool found = false;
+ RouteList* mprl = gIsOutRoutingPopupMenu ? mp->outRoutes() : mp->inRoutes();
+ iRoute ir = mprl->begin();
+ for(; ir != mprl->end(); ++ir)
+ {
+ printf("mp route:\n"); // REMOVE Tim.
+ ir->dump(); // REMOVE Tim.
+ ///if(aRoute.type == Route::TRACK_ROUTE) // Is the map route a track route?
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track == aRoute.track) // Is the track route a midi port route?
+ //&& (ir->channel & chbit) == chbit)
+ //&& (ir->channel & tchbit)) // Is the exact channel mask bit(s) set?
+ {
+ printf("track matches\n"); // REMOVE Tim.
+ if(ir->channel & tchbit)
+ {
+ found = true;
+ printf("found: bit matches\n"); // REMOVE Tim.
+ }
+ break;
+ }
+ }
+ ///else
+ ///if(*ir == aRoute)
+ ///{
+ //found = true;
+ /// break;
+ ///}
+ }
+ //pup->setItemChecked(imm->first, found);
+ //printf("MusE::updateRouteMenus setItemChecked\n");
+ // TODO: MusE-2: Convert this, fastest way is to change the routing map, otherwise this requires a lookup.
+ //if(pup->isItemChecked(imm->first) != (irl != rl->end()))
+ // pup->setItemChecked(imm->first, irl != rl->end());
+ QAction* act = pup->findActionFromData(imm->first);
+ //printf("set act checked to:%d\n", ir != mprl->end()); // REMOVE Tim.
+ //if(act && act->isChecked() != (ir != mprl->end()))
+ // act->setChecked(ir != mprl->end());
+ printf("set act checked to:%d\n", found); // REMOVE Tim.
+ if(act && act->isChecked() != found)
+ act->setChecked(found);
+
+ //return;
+ }
+ }
+ #endif
+
//bool found = false;
iRoute irl = rl->begin();
for(; irl != rl->end(); ++irl)
@@ -2278,6 +2354,69 @@ void MusE::routingPopupMenuActivated(Track* track, int n)
iRouteMenuMap imm = gRoutingMenuMap.find(n);
if(imm == gRoutingMenuMap.end())
return;
+
+ // Support Midi Port to Audio Input track routes. p4.0.14 Tim.
+ if(imm->second.type == Route::TRACK_ROUTE)
+ {
+ //if(gIsOutRoutingPopupMenu) // Try to avoid splitting like this.
+ {
+ Route &aRoute = imm->second;
+ int chbit = aRoute.channel;
+ int port = ((MidiTrack*)track)->outPort();
+ if(port < 0 || port >= MIDI_PORTS)
+ return;
+
+ MidiPort* mp = &midiPorts[port];
+ ///MidiDevice* md = mp->device();
+
+ // This is desirable, but could lead to 'hidden' routes unless we add more support
+ // such as removing the existing routes when user changes flags.
+ // So for now, just list all valid ports whether read or write.
+ ///if(!md)
+ /// return;
+ ///if(!(md->rwFlags() & (gIsOutRoutingPopupMenu ? 1 : 2)))
+ /// return;
+
+ //int channel = ((MidiTrack*)track->outChannel();
+ Route bRoute(port, chbit);
+
+ int chmask = 0;
+ RouteList* mprl = gIsOutRoutingPopupMenu ? mp->outRoutes() : mp->inRoutes();
+ iRoute ir = mprl->begin();
+ for (; ir != mprl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track == aRoute.track) // Is there already a route to this port?
+ {
+ chmask = ir->channel; // Grab the channel mask.
+ break;
+ }
+ }
+ //if (iir != rl->end())
+ if ((chmask & chbit) == chbit) // Is the channel's bit(s) set?
+ {
+ // disconnect
+ if(gIsOutRoutingPopupMenu)
+ audio->msgRemoveRoute(bRoute, aRoute);
+ else
+ audio->msgRemoveRoute(aRoute, bRoute);
+ }
+ else
+ {
+ // connect
+ if(gIsOutRoutingPopupMenu)
+ audio->msgAddRoute(bRoute, aRoute);
+ else
+ audio->msgAddRoute(aRoute, bRoute);
+ }
+
+ audio->msgUpdateSoloStates();
+ song->update(SC_ROUTE);
+
+ }
+ return;
+ }
+
+
if(imm->second.type != Route::MIDI_PORT_ROUTE)
return;
Route &aRoute = imm->second;
@@ -2580,45 +2719,71 @@ PopupMenu* MusE::prepareRoutingPopupMenu(Track* track, bool dst)
if(!track)
return 0;
- //QPoint ppt = QCursor::pos();
-
if(track->isMidiTrack())
{
+ RouteList* rl = dst ? track->outRoutes() : track->inRoutes();
+ //Route dst(track, -1);
- //QPoint ppt = parent->rect().bottomLeft();
-
- //if(dst)
- //{
- // TODO
+ PopupMenu* pup = getRoutingPopupMenu();
+ pup->disconnect();
+ //connect(pup, SIGNAL(activated(int)), SLOT(routingPopupMenuActivated(int)));
+ //connect(pup, SIGNAL(aboutToHide()), SLOT(routingPopupMenuAboutToHide()));
- //}
- //else
- //{
- RouteList* rl = dst ? track->outRoutes() : track->inRoutes();
- //Route dst(track, -1);
+ pup->clear();
+ gRoutingMenuMap.clear();
- PopupMenu* pup = getRoutingPopupMenu();
- pup->disconnect();
- //connect(pup, SIGNAL(activated(int)), SLOT(routingPopupMenuActivated(int)));
- //connect(pup, SIGNAL(aboutToHide()), SLOT(routingPopupMenuAboutToHide()));
+ int gid = 0;
+ QAction* act = 0;
+
+ if(dst)
+ {
+ // Support Midi Port to Audio Input track routes. p4.0.14 Tim.
+ int port = ((MidiTrack*)track)->outPort();
+ if(port >= 0 && port < MIDI_PORTS)
+ {
+ MidiPort* mp = &midiPorts[port];
+ RouteList* mprl = mp->outRoutes();
+ int chbits = 1 << ((MidiTrack*)track)->outChannel();
+ //MidiDevice* md = mp->device();
+ //if(!md)
+ // continue;
- int gid = 0;
- //int n;
- QAction* act = 0;
-
- // Routes can't be re-read until the message sent from msgAddRoute1()
- // has had time to be sent and actually affected the routes.
- ///_redisplay:
-
- pup->clear();
- gRoutingMenuMap.clear();
- gid = 0;
-
- //MidiInPortList* tl = song->midiInPorts();
- //for(iMidiInPort i = tl->begin();i != tl->end(); ++i)
+ pup->addSeparator();
+ pup->addAction(new MenuTitleItem(tr("Soloing chain"), pup));
+ PopupMenu* subp = new PopupMenu(pup);
+ subp->setTitle(tr("Audio returns"));
+ pup->addMenu(subp);
+
+ InputList* al = song->inputs();
+ for (iAudioInput i = al->begin(); i != al->end(); ++i)
+ {
+ Track* t = *i;
+ QString s(t->name());
+
+ act = subp->addAction(s);
+ act->setData(gid);
+ act->setCheckable(true);
+
+ Route r(t, chbits);
+
+ gRoutingMenuMap.insert( pRouteMenuMap(gid, r) );
+
+ for(iRoute ir = mprl->begin(); ir != mprl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track == t && (ir->channel & chbits))
+ {
+ act->setChecked(true);
+ break;
+ }
+ }
+ ++gid;
+ }
+ }
+ }
+ else
+ {
for(int i = 0; i < MIDI_PORTS; ++i)
{
- //MidiInPort* track = *i;
// NOTE: Could possibly list all devices, bypassing ports, but no, let's stick with ports.
MidiPort* mp = &midiPorts[i];
MidiDevice* md = mp->device();
@@ -2630,10 +2795,6 @@ PopupMenu* MusE::prepareRoutingPopupMenu(Track* track, bool dst)
//printf("MusE::prepareRoutingPopupMenu adding submenu portnum:%d\n", i);
- //QMenu* m = menu->addMenu(track->name());
- //QPopupMenu* subp = new QPopupMenu(parent);
- //PopupMenu* subp = new PopupMenu(this);
- //PopupMenu* subp = new PopupMenu();
PopupMenu* subp = new PopupMenu(pup);
subp->setTitle(md->name());
@@ -2656,101 +2817,46 @@ PopupMenu* MusE::prepareRoutingPopupMenu(Track* track, bool dst)
for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
{
- //QAction* a = m->addAction(QString("Channel %1").arg(ch+1));
- //subp->insertItem(QT_TRANSLATE_NOOP("@default", QString("Channel %1").arg(ch+1)), i * MIDI_CHANNELS + ch);
- gid = i * MIDI_CHANNELS + ch;
-
- //printf("MusE::prepareRoutingPopupMenu inserting gid:%d\n", gid);
-
act = subp->addAction(QString("Channel %1").arg(ch+1));
act->setCheckable(true);
act->setData(gid);
- //a->setCheckable(true);
- //Route src(track, ch, RouteNode::TRACK);
- //Route src(md, ch);
- //Route r = Route(src, dst);
- //a->setData(QVariant::fromValue(r));
- //a->setChecked(rl->indexOf(r) != -1);
- //Route srcRoute(md, ch);
- //Route srcRoute(i, ch); // p3.3.49 New: Midi port route.
int chbit = 1 << ch;
Route srcRoute(i, chbit); // p3.3.50 In accordance with new channel mask, use the bit position.
gRoutingMenuMap.insert( pRouteMenuMap(gid, srcRoute) );
- //for(iRoute ir = rl->begin(); ir != rl->end(); ++ir) // p3.3.50 Removed.
- //{
- //if(*ir == dst)
- // if(*ir == srcRoute)
- // {
- // subp->setItemChecked(id, true);
- // break;
- // }
- //}
if(chanmask & chbit) // p3.3.50 Is the channel already set? Show item check mark.
act->setChecked(true);
+
+ ++gid;
}
- //subp->insertItem(QString("Toggle all"), 1000+i);
- // p3.3.50 One route with all channel bits set.
- gid = MIDI_PORTS * MIDI_CHANNELS + i; // Make sure each 'toggle' item gets a unique id.
+ //gid = MIDI_PORTS * MIDI_CHANNELS + i; // Make sure each 'toggle' item gets a unique id.
act = subp->addAction(QString("Toggle all"));
//act->setCheckable(true);
act->setData(gid);
Route togRoute(i, (1 << MIDI_CHANNELS) - 1); // Set all channel bits.
gRoutingMenuMap.insert( pRouteMenuMap(gid, togRoute) );
-
+ ++gid;
pup->addMenu(subp);
}
-
- /*
- QPopupMenu* pup = new QPopupMenu(iR);
- pup->setCheckable(true);
- //MidiTrack* t = (MidiTrack*)track;
- RouteList* irl = track->inRoutes();
-
- MidiTrack* t = (MidiTrack*)track;
- int gid = 0;
- for (int i = 0; i < channel; ++i)
- {
- char buffer[128];
- snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().constData(), i+1);
- MenuTitleItem* titel = new MenuTitleItem(QString(buffer));
- pup->insertItem(titel);
-
- if (!checkAudioDevice()) return;
- std::list<QString> ol = audioDevice->outputPorts();
- for (std::list<QString>::iterator ip = ol.begin(); ip != ol.end(); ++ip) {
- int id = pup->insertItem(*ip, (gid * 16) + i);
- Route dst(*ip, true, i);
- ++gid;
- for (iRoute ir = irl->begin(); ir != irl->end(); ++ir) {
- if (*ir == dst) {
- pup->setItemChecked(id, true);
- break;
- }
- }
- }
- if (i+1 != channel)
- pup->addSeparator();
- }
- */
-
- if(pup->actions().isEmpty())
- {
- gRoutingPopupMenuMaster = 0;
- //pup->clear();
- //pup->disconnect();
- gRoutingMenuMap.clear();
- //oR->setDown(false);
- return 0;
- }
-
- gIsOutRoutingPopupMenu = dst;
- return pup;
+ }
+
+ if(pup->actions().isEmpty())
+ {
+ gRoutingPopupMenuMaster = 0;
+ //pup->clear();
+ //pup->disconnect();
+ gRoutingMenuMap.clear();
+ //oR->setDown(false);
+ return 0;
}
- return 0;
+ gIsOutRoutingPopupMenu = dst;
+ return pup;
+ }
+
+ return 0;
}
#if 0
@@ -3145,9 +3251,9 @@ void MusE::startPianoroll(PartList* pl, bool showDefaultCtrls)
{
PianoRoll* pianoroll = new PianoRoll(pl, this, 0, arranger->cursorValue());
- pianoroll->show();
if(showDefaultCtrls) // p4.0.12
pianoroll->addCtrl();
+ pianoroll->show();
toplevels.push_back(Toplevel(Toplevel::PIANO_ROLL, (unsigned long)(pianoroll), pianoroll));
connect(pianoroll, SIGNAL(deleted(unsigned long)), SLOT(toplevelDeleted(unsigned long)));
connect(muse, SIGNAL(configChanged()), pianoroll, SLOT(configChanged()));
@@ -3215,9 +3321,9 @@ void MusE::startDrumEditor(PartList* pl, bool showDefaultCtrls)
{
DrumEdit* drumEditor = new DrumEdit(pl, this, 0, arranger->cursorValue());
- drumEditor->show();
if(showDefaultCtrls) // p4.0.12
drumEditor->addCtrl();
+ drumEditor->show();
toplevels.push_back(Toplevel(Toplevel::DRUM, (unsigned long)(drumEditor), drumEditor));
connect(drumEditor, SIGNAL(deleted(unsigned long)), SLOT(toplevelDeleted(unsigned long)));
connect(muse, SIGNAL(configChanged()), drumEditor, SLOT(configChanged()));
diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp
index 02f742f7..e32d0010 100644
--- a/muse2/muse/arranger/tlist.cpp
+++ b/muse2/muse/arranger/tlist.cpp
@@ -1027,6 +1027,9 @@ void TList::mousePressEvent(QMouseEvent* ev)
//if(button == QMouseEvent::LeftButton)
// portsPopupMenu(t, x, t->y() - ypos);
+ audio->msgUpdateSoloStates(); // p4.0.14
+ //song->update(SC_ROUTE); //
+
break;
case COL_MUTE:
// p3.3.29
@@ -1141,7 +1144,10 @@ void TList::mousePressEvent(QMouseEvent* ev)
// may result in adding/removing mixer strip:
//song->update(-1);
//song->update(SC_CHANNELS);
- song->update(SC_MIDI_TRACK_PROP);
+ //song->update(SC_MIDI_TRACK_PROP);
+ audio->msgUpdateSoloStates(); // p4.0.14
+ //song->update(SC_MIDI_TRACK_PROP | SC_ROUTE); //
+ song->update(SC_MIDI_TRACK_PROP); //
}
}
else
diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp
index 7330e79e..19bbbaf1 100644
--- a/muse2/muse/audiotrack.cpp
+++ b/muse2/muse/audiotrack.cpp
@@ -860,7 +860,8 @@ void AudioTrack::writeProperties(int level, Xml& xml) const
if (hasAuxSend()) {
int naux = song->auxs()->size();
for (int idx = 0; idx < naux; ++idx) {
- QString s("<auxSend idx=%1>%2</auxSend>\n");
+ //QString s("<auxSend idx=%1>%2</auxSend>\n");
+ QString s("<auxSend idx=\"%1\">%2</auxSend>\n"); // Aux fix from Remon, thanks.
xml.nput(level, s.arg(idx).arg(_auxSend[idx]).toAscii().constData());
}
}
diff --git a/muse2/muse/ctrl/ctrledit.cpp b/muse2/muse/ctrl/ctrledit.cpp
index fe04844d..8842ba97 100644
--- a/muse2/muse/ctrl/ctrledit.cpp
+++ b/muse2/muse/ctrl/ctrledit.cpp
@@ -132,3 +132,25 @@ void CtrlEdit::setCanvasWidth(int w)
{
canvas->setFixedWidth(w);
}
+
+void CtrlEdit::setController(int n)
+{
+ canvas->setController(n);
+}
+
+void CtrlEdit::setController(const QString& name)
+{
+ int portno = canvas->track()->outPort();
+ MidiPort* port = &midiPorts[portno];
+ MidiInstrument* instr = port->instrument();
+ MidiControllerList* mcl = instr->controller();
+
+ for (iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
+ {
+ if (ci->second->name() == name)
+ {
+ canvas->setController(ci->second->num());
+ break;
+ }
+ }
+}
diff --git a/muse2/muse/ctrl/ctrledit.h b/muse2/muse/ctrl/ctrledit.h
index 61bf9b46..eec235b1 100644
--- a/muse2/muse/ctrl/ctrledit.h
+++ b/muse2/muse/ctrl/ctrledit.h
@@ -37,6 +37,8 @@ class CtrlEdit : public QWidget {
void setXPos(int val) { canvas->setXPos(val); }
void setXMag(int val) { canvas->setXMag(val); }
void setCanvasWidth(int w);
+ void setController(int /*n*/);
+
signals:
void timeChanged(unsigned);
void destroyedCtrl(CtrlEdit*);
@@ -48,6 +50,7 @@ class CtrlEdit : public QWidget {
bool expand = false, const char* name = 0);
void readStatus(Xml&);
void writeStatus(int, Xml&);
+ void setController(const QString& name);
};
#endif
diff --git a/muse2/muse/midiport.cpp b/muse2/muse/midiport.cpp
index 02fed8d1..16cfd429 100644
--- a/muse2/muse/midiport.cpp
+++ b/muse2/muse/midiport.cpp
@@ -62,7 +62,7 @@ MidiPort::MidiPort()
// to make midi mixer operational
//
for (int i = 0; i < MIDI_CHANNELS; ++i) {
- addManagedController(i, CTRL_PROGRAM);
+ addManagedController(i, CTRL_PROGRAM);
addManagedController(i, CTRL_VOLUME);
addManagedController(i, CTRL_PANPOT);
_automationType[i] = AUTO_READ;
@@ -1013,8 +1013,10 @@ void MidiPort::writeRouting(int level, Xml& xml) const
{
if(r->type == Route::TRACK_ROUTE && !r->name().isEmpty())
{
- //xml.tag(level++, "Route");
-
+ // Ignore Midi Port to Audio Input routes. Handled by Track route writer. p4.0.14 Tim.
+ if(r->track && r->track->type() == Track::AUDIO_INPUT)
+ continue;
+
s = QT_TRANSLATE_NOOP("@default", "Route");
if(r->channel != -1 && r->channel != 0)
s += QString(QT_TRANSLATE_NOOP("@default", " channelMask=\"%1\"")).arg(r->channel); // Use new channel mask.
diff --git a/muse2/muse/mixer/amixer.cpp b/muse2/muse/mixer/amixer.cpp
index 7fb406f3..e4a82ce8 100644
--- a/muse2/muse/mixer/amixer.cpp
+++ b/muse2/muse/mixer/amixer.cpp
@@ -538,7 +538,8 @@ void AudioMixerApp::songChanged(int flags)
action = STRIP_INSERTED;
else if (flags & SC_MIDI_TRACK_PROP)
action = UPDATE_MIDI;
- if (action != NO_UPDATE)
+ //if (action != NO_UPDATE)
+ if (action != NO_UPDATE && action != UPDATE_MIDI) // p4.0.14 Fix for very slow track prop adjusting.
updateMixer(action);
if (action != UPDATE_ALL) {
StripList::iterator si = stripList.begin();
diff --git a/muse2/muse/mixer/astrip.cpp b/muse2/muse/mixer/astrip.cpp
index 1317f63d..a680d302 100644
--- a/muse2/muse/mixer/astrip.cpp
+++ b/muse2/muse/mixer/astrip.cpp
@@ -68,6 +68,11 @@ QWidget* MenuTitleItem::createWidget(QWidget *parent)
{
QLabel* l = new QLabel(s, parent);
l->setAlignment(Qt::AlignCenter);
+ l->setAutoFillBackground(true);
+ //QPalette palette;
+ //palette.setColor(label->backgroundRole(), c);
+ //l->setPalette(palette);
+ l->setBackgroundRole(QPalette::Dark);
return l;
}
@@ -1542,6 +1547,181 @@ static int nonSyntiTrackAddSyntis(AudioTrack* t, PopupMenu* lb, int id, RouteMen
}
//---------------------------------------------------------
+// addMidiPorts
+//---------------------------------------------------------
+
+static int addMidiPorts(AudioTrack* t, PopupMenu* pup, int id, RouteMenuMap& mm, bool isOutput)
+{
+ QAction* act;
+ for(int i = 0; i < MIDI_PORTS; ++i)
+ {
+ MidiPort* mp = &midiPorts[i];
+ MidiDevice* md = mp->device();
+
+ // This is desirable, but could lead to 'hidden' routes unless we add more support
+ // such as removing the existing routes when user changes flags.
+ // So for now, just list all valid ports whether read or write.
+ if(!md)
+ continue;
+ //if(!(md->rwFlags() & (isOutput ? 1 : 2)))
+ // continue;
+
+ RouteList* rl = isOutput ? t->outRoutes() : t->inRoutes();
+
+ PopupMenu* subp = new PopupMenu(pup);
+ subp->setTitle(md->name());
+
+ int chanmask = 0;
+ // To reduce number of routes required, from one per channel to just one containing a channel mask.
+ // Look for the first route to this midi port. There should always be only a single route for each midi port, now.
+ for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == i)
+ {
+ // We have a route to the midi port. Grab the channel mask.
+ chanmask = ir->channel;
+ break;
+ }
+ }
+
+ for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ {
+ act = subp->addAction(QString("Channel %1").arg(ch+1));
+ act->setCheckable(true);
+ act->setData(id);
+
+ int chbit = 1 << ch;
+ Route srcRoute(i, chbit); // In accordance with new channel mask, use the bit position.
+
+ mm.insert( pRouteMenuMap(id, srcRoute) );
+
+ if(chanmask & chbit) // Is the channel already set? Show item check mark.
+ act->setChecked(true);
+
+ ++id;
+ }
+
+ //gid = MIDI_PORTS * MIDI_CHANNELS + i; // Make sure each 'toggle' item gets a unique id.
+ act = subp->addAction(QString("Toggle all"));
+ //act->setCheckable(true);
+ act->setData(id);
+ Route togRoute(i, (1 << MIDI_CHANNELS) - 1); // Set all channel bits.
+ mm.insert( pRouteMenuMap(id, togRoute) );
+ ++id;
+
+ pup->addMenu(subp);
+ }
+ return id;
+}
+
+//---------------------------------------------------------
+// routingPopupMenuActivated
+//---------------------------------------------------------
+
+void AudioStrip::routingPopupMenuActivated(QAction* act)
+{
+ if(!track || gRoutingPopupMenuMaster != this || track->isMidiTrack())
+ return;
+
+ PopupMenu* pup = muse->getRoutingPopupMenu();
+
+ if(pup->actions().isEmpty())
+ return;
+
+ AudioTrack* t = (AudioTrack*)track;
+ RouteList* rl = gIsOutRoutingPopupMenu ? t->outRoutes() : t->inRoutes();
+
+ int n = act->data().toInt();
+ if (n == -1)
+ return;
+
+ iRouteMenuMap imm = gRoutingMenuMap.find(n);
+ if(imm == gRoutingMenuMap.end())
+ return;
+
+ if(gIsOutRoutingPopupMenu)
+ {
+ Route srcRoute(t, imm->second.channel, imm->second.channels);
+ srcRoute.remoteChannel = imm->second.remoteChannel;
+
+ Route &dstRoute = imm->second;
+
+ // check if route src->dst exists:
+ iRoute irl = rl->begin();
+ for (; irl != rl->end(); ++irl) {
+ if (*irl == dstRoute)
+ break;
+ }
+ if (irl != rl->end()) {
+ // disconnect if route exists
+ audio->msgRemoveRoute(srcRoute, dstRoute);
+ }
+ else {
+ // connect if route does not exist
+ audio->msgAddRoute(srcRoute, dstRoute);
+ }
+ audio->msgUpdateSoloStates();
+ song->update(SC_ROUTE);
+ }
+ else
+ {
+ Route &srcRoute = imm->second;
+
+ // Support Midi Port to Audio Input routes. p4.0.14 Tim.
+ if(track->type() == Track::AUDIO_INPUT && srcRoute.type == Route::MIDI_PORT_ROUTE)
+ {
+ int chbit = srcRoute.channel;
+ Route dstRoute(t, chbit);
+ int mdidx = srcRoute.midiPort;
+ int chmask = 0;
+ iRoute iir = rl->begin();
+ for (; iir != rl->end(); ++iir)
+ {
+ if(iir->type == Route::MIDI_PORT_ROUTE && iir->midiPort == mdidx) // Is there already a route to this port?
+ {
+ chmask = iir->channel; // Grab the channel mask.
+ break;
+ }
+ }
+
+ if ((chmask & chbit) == chbit) // Is the channel's bit(s) set?
+ {
+ //printf("astrip: removing src route ch:%d dst route ch:%d\n", srcRoute.channel, dstRoute.channel);
+ audio->msgRemoveRoute(srcRoute, dstRoute);
+ }
+ else
+ {
+ //printf("astrip: adding src route ch:%d dst route ch:%d\n", srcRoute.channel, dstRoute.channel);
+ audio->msgAddRoute(srcRoute, dstRoute);
+ }
+
+ audio->msgUpdateSoloStates();
+ song->update(SC_ROUTE);
+ return;
+ }
+
+ Route dstRoute(t, imm->second.channel, imm->second.channels);
+ dstRoute.remoteChannel = imm->second.remoteChannel;
+
+ iRoute irl = rl->begin();
+ for (; irl != rl->end(); ++irl) {
+ if (*irl == srcRoute)
+ break;
+ }
+ if (irl != rl->end()) {
+ // disconnect
+ audio->msgRemoveRoute(srcRoute, dstRoute);
+ }
+ else {
+ // connect
+ audio->msgAddRoute(srcRoute, dstRoute);
+ }
+ audio->msgUpdateSoloStates();
+ song->update(SC_ROUTE);
+ }
+}
+
+//---------------------------------------------------------
// iRoutePressed
//---------------------------------------------------------
@@ -1564,7 +1744,7 @@ void AudioStrip::iRoutePressed()
QAction* act = 0;
int gid = 0;
- int id = 0;
+ //int id = 0;
pup->clear();
gRoutingMenuMap.clear();
@@ -1592,13 +1772,15 @@ void AudioStrip::iRoutePressed()
std::list<QString> ol = audioDevice->outputPorts();
for(std::list<QString>::iterator ip = ol.begin(); ip != ol.end(); ++ip)
{
- id = gid * 16 + i;
+ //id = gid * 16 + i; // IDs removed p4.0.14 Tim.
act = pup->addAction(*ip);
- act->setData(id);
+ //act->setData(id);
+ act->setData(gid);
act->setCheckable(true);
Route dst(*ip, true, i, Route::JACK_ROUTE);
- gRoutingMenuMap.insert( pRouteMenuMap(id, dst) );
+ //gRoutingMenuMap.insert( pRouteMenuMap(id, dst) );
+ gRoutingMenuMap.insert( pRouteMenuMap(gid, dst) );
++gid;
for(iRoute ir = irl->begin(); ir != irl->end(); ++ir)
{
@@ -1612,6 +1794,29 @@ void AudioStrip::iRoutePressed()
if(i+1 != channel)
pup->addSeparator();
}
+
+ // p4.0.14
+ //
+ // Display using separate menus for midi ports and audio outputs:
+ //
+ pup->addSeparator();
+ pup->addAction(new MenuTitleItem(tr("Soloing chain"), pup));
+ PopupMenu* subp = new PopupMenu(pup);
+ subp->setTitle(tr("Audio sends"));
+ pup->addMenu(subp);
+ gid = addOutPorts(t, subp, gid, gRoutingMenuMap, -1, -1, false);
+ subp = new PopupMenu(pup);
+ subp->setTitle(tr("Midi sends"));
+ pup->addMenu(subp);
+ addMidiPorts(t, subp, gid, gRoutingMenuMap, false);
+ //
+ // Display all in the same menu:
+ //
+ //pup->addAction(new MenuTitleItem(tr("Audio sends"), pup));
+ //gid = addOutPorts(t, pup, gid, gRoutingMenuMap, -1, -1, false);
+ //pup->addSeparator();
+ //pup->addAction(new MenuTitleItem(tr("Midi sends"), pup));
+ //addMidiPorts(t, pup, gid, gRoutingMenuMap, false);
}
break;
//case Track::AUDIO_OUTPUT:
@@ -1661,140 +1866,7 @@ void AudioStrip::iRoutePressed()
pup->popup(ppt);
iR->setDown(false);
}
-
-//---------------------------------------------------------
-// routingPopupMenuActivated
-//---------------------------------------------------------
-
-void AudioStrip::routingPopupMenuActivated(QAction* act)
-{
- if(!track || gRoutingPopupMenuMaster != this || track->isMidiTrack())
- return;
-
- PopupMenu* pup = muse->getRoutingPopupMenu();
-
- if(pup->actions().isEmpty())
- return;
-
- AudioTrack* t = (AudioTrack*)track;
- RouteList* rl = gIsOutRoutingPopupMenu ? t->outRoutes() : t->inRoutes();
-
- int n = act->data().toInt();
- if (n == -1)
- return;
- if(gIsOutRoutingPopupMenu)
- {
- if(track->type() == Track::AUDIO_OUTPUT)
- {
-
- int chan = n & 0xf;
-
- Route srcRoute(t, chan);
- Route dstRoute(act->text(), true, -1, Route::JACK_ROUTE);
- dstRoute.channel = chan;
-
- // check if route src->dst exists:
- iRoute irl = rl->begin();
- for (; irl != rl->end(); ++irl) {
- if (*irl == dstRoute)
- break;
- }
- if (irl != rl->end()) {
- // disconnect if route exists
- audio->msgRemoveRoute(srcRoute, dstRoute);
- }
- else {
- // connect if route does not exist
- audio->msgAddRoute(srcRoute, dstRoute);
- }
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
- return;
- }
-
- iRouteMenuMap imm = gRoutingMenuMap.find(n);
- if(imm == gRoutingMenuMap.end())
- return;
-
- Route srcRoute(t, imm->second.channel, imm->second.channels);
- srcRoute.remoteChannel = imm->second.remoteChannel;
-
- Route &dstRoute = imm->second;
-
- // check if route src->dst exists:
- iRoute irl = rl->begin();
- for (; irl != rl->end(); ++irl) {
- if (*irl == dstRoute)
- break;
- }
- if (irl != rl->end()) {
- // disconnect if route exists
- audio->msgRemoveRoute(srcRoute, dstRoute);
- }
- else {
- // connect if route does not exist
- audio->msgAddRoute(srcRoute, dstRoute);
- }
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
- }
- else
- {
- if(track->type() == Track::AUDIO_INPUT)
- {
- int chan = n & 0xf;
-
- Route srcRoute(act->text(), false, -1, Route::JACK_ROUTE);
- Route dstRoute(t, chan);
-
- srcRoute.channel = chan;
-
- iRoute irl = rl->begin();
- for(; irl != rl->end(); ++irl)
- {
- if(*irl == srcRoute)
- break;
- }
- if(irl != rl->end())
- // disconnect
- audio->msgRemoveRoute(srcRoute, dstRoute);
- else
- // connect
- audio->msgAddRoute(srcRoute, dstRoute);
-
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
- return;
- }
-
- iRouteMenuMap imm = gRoutingMenuMap.find(n);
- if(imm == gRoutingMenuMap.end())
- return;
-
- Route &srcRoute = imm->second;
-
- Route dstRoute(t, imm->second.channel, imm->second.channels);
- dstRoute.remoteChannel = imm->second.remoteChannel;
-
- iRoute irl = rl->begin();
- for (; irl != rl->end(); ++irl) {
- if (*irl == srcRoute)
- break;
- }
- if (irl != rl->end()) {
- // disconnect
- audio->msgRemoveRoute(srcRoute, dstRoute);
- }
- else {
- // connect
- audio->msgAddRoute(srcRoute, dstRoute);
- }
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
- }
-}
-
//---------------------------------------------------------
// oRoutePressed
//---------------------------------------------------------
@@ -1817,7 +1889,7 @@ void AudioStrip::oRoutePressed()
QAction* act = 0;
int gid = 0;
- int id = 0;
+ //int id = 0;
pup->clear();
gRoutingMenuMap.clear();
@@ -1845,13 +1917,15 @@ void AudioStrip::oRoutePressed()
std::list<QString> ol = audioDevice->inputPorts();
for(std::list<QString>::iterator ip = ol.begin(); ip != ol.end(); ++ip)
{
- id = gid * 16 + i;
+ //id = gid * 16 + i; // IDs removed p4.0.14 Tim.
act = pup->addAction(*ip);
- act->setData(id);
+ //act->setData(id);
+ act->setData(gid);
act->setCheckable(true);
Route dst(*ip, true, i, Route::JACK_ROUTE);
- gRoutingMenuMap.insert( pRouteMenuMap(id, dst) );
+ //gRoutingMenuMap.insert( pRouteMenuMap(id, dst) );
+ gRoutingMenuMap.insert( pRouteMenuMap(gid, dst) );
++gid;
for(iRoute ir = orl->begin(); ir != orl->end(); ++ir)
{
@@ -1865,6 +1939,24 @@ void AudioStrip::oRoutePressed()
if(i+1 != channel)
pup->addSeparator();
}
+
+ // p4.0.14
+ //
+ // Display using separate menu for audio inputs:
+ //
+ pup->addSeparator();
+ pup->addAction(new MenuTitleItem(tr("Soloing chain"), pup));
+ PopupMenu* subp = new PopupMenu(pup);
+ subp->setTitle(tr("Audio returns"));
+ pup->addMenu(subp);
+ gid = addInPorts(t, subp, gid, gRoutingMenuMap, -1, -1, true);
+ //
+ // Display all in the same menu:
+ //
+ //pup->addSeparator();
+ //MenuTitleItem* title = new MenuTitleItem(tr("Audio returns"), pup);
+ //pup->addAction(title);
+ //gid = addInPorts(t, pup, gid, gRoutingMenuMap, -1, -1, true);
}
break;
//case Track::AUDIO_INPUT:
diff --git a/muse2/muse/mixer/mstrip.cpp b/muse2/muse/mixer/mstrip.cpp
index abf37a28..f6e195b0 100644
--- a/muse2/muse/mixer/mstrip.cpp
+++ b/muse2/muse/mixer/mstrip.cpp
@@ -394,8 +394,9 @@ MidiStrip::MidiStrip(QWidget* parent, MidiTrack* t)
oR->setText(tr("oR"));
oR->setCheckable(false);
// TODO: Works OK, but disabled for now, until we figure out what to do about multiple out routes and display values...
- oR->setEnabled(false);
- oR->setToolTip(tr("output routing"));
+ // Enabled (for Midi Port to Audio Input routing). p4.0.14 Tim.
+ //oR->setEnabled(false);
+ //oR->setToolTip(tr("output routing"));
grid->addWidget(oR, _curGridRow++, 1);
connect(oR, SIGNAL(pressed()), SLOT(oRoutePressed()));
diff --git a/muse2/muse/node.cpp b/muse2/muse/node.cpp
index 8db0a3d3..114b03d3 100644
--- a/muse2/muse/node.cpp
+++ b/muse2/muse/node.cpp
@@ -208,9 +208,21 @@ void MidiTrack::updateSoloStates(bool noDec)
if(outPort() >= 0)
{
- MidiDevice *md = midiPorts[outPort()].device();
+ MidiPort* mp = &midiPorts[outPort()];
+ MidiDevice *md = mp->device();
if(md && md->isSynti())
((SynthI*)md)->updateInternalSoloStates();
+
+ // Support Midi Port -> Audio Input solo chains. p4.0.14 Tim.
+ const int chbits = 1 << outChannel();
+ const RouteList* rl = mp->outRoutes();
+ for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track && ir->track->type() == Track::AUDIO_INPUT && (ir->channel & chbits) )
+ {
+ ir->track->updateInternalSoloStates();
+ }
+ }
}
}
@@ -245,6 +257,18 @@ void AudioTrack::updateSoloStates(bool noDec)
{
if(ir->type == Route::TRACK_ROUTE)
ir->track->updateInternalSoloStates();
+ else
+ // Support Midi Port -> Audio Input solo chains. p4.0.14 Tim.
+ if(ir->type == Route::MIDI_PORT_ROUTE)
+ {
+ const MidiTrackList* ml = song->midis();
+ for(ciMidiTrack im = ml->begin(); im != ml->end(); ++im)
+ {
+ MidiTrack* mt = *im;
+ if(mt->outPort() == ir->midiPort && ((1 << mt->outChannel()) & ir->channel) )
+ mt->updateInternalSoloStates();
+ }
+ }
}
}
_tmpSoloChainDoIns = false;
diff --git a/muse2/muse/route.cpp b/muse2/muse/route.cpp
index 19f8d09f..92c32317 100644
--- a/muse2/muse/route.cpp
+++ b/muse2/muse/route.cpp
@@ -348,6 +348,59 @@ void addRoute(Route src, Route dst)
fprintf(stderr, "addRoute: source is midi port:%d, but destination is not track\n", src.midiPort);
return;
}
+
+ // p4.0.14
+ /*
+ if(dst.track->type() == Track::AUDIO_INPUT)
+ {
+ if(src.channel < 1 || src.channel >= (1 << MIDI_CHANNELS))
+ {
+ fprintf(stderr, "addRoute: source is midi port:%d, but channel mask:%d out of range\n", src.midiPort, src.channel);
+ return;
+ }
+
+ MidiPort *mp = &midiPorts[src.midiPort];
+ //src.channel = dst.channel = -1;
+ RouteList* outRoutes = mp->outRoutes();
+ iRoute ir = outRoutes->begin();
+ for ( ; ir != outRoutes->end(); ++ir)
+ {
+ //if (*i == dst) // route already there
+ ir->dump(); // REMOVE Tim.
+ if (ir->type == Route::TRACK_ROUTE && ir->track == dst.track) // Does a route to the track exist?
+ {
+ //#ifdef ROUTE_DEBUG
+ fprintf(stderr, "addRoute: src midi port:%d dst audio in track:%s out route already exists. ir->channel:%d |= dst.channel:%d\n",
+ src.midiPort, dst.track->name().toLatin1().constData(), ir->channel, dst.channel); // REMOVE Tim.
+ //#endif
+ ir->channel |= dst.channel; // Bitwise OR the desired channel bit with the existing bit mask.
+ break;
+ //return;
+ }
+ }
+ if(ir == outRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with.
+ outRoutes->push_back(dst);
+
+ RouteList* inRoutes = dst.track->inRoutes();
+
+ ir = inRoutes->begin();
+ for ( ; ir != inRoutes->end(); ++ir)
+ {
+ if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == src.midiPort) // Does a route to the midi port exist?
+ {
+ fprintf(stderr, "addRoute: src midi port:%d dst audio in track:%s in route already exists. ir->channel:%d |= src.channel:%d\n",
+ src.midiPort, dst.track->name().toLatin1().constData(), ir->channel, src.channel); // REMOVE Tim.
+ ir->channel |= src.channel; // Bitwise OR the desired channel bit with the existing bit mask.
+ break;
+ }
+ }
+ if(ir == inRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with.
+ inRoutes->push_back(src);
+
+ return;
+ }
+ */
+
if(dst.channel < 1 || dst.channel >= (1 << MIDI_CHANNELS))
{
fprintf(stderr, "addRoute: source is midi port:%d, but destination channel mask:%d out of range\n", src.midiPort, dst.channel);
@@ -752,14 +805,18 @@ void removeRoute(Route src, Route dst)
for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
{
//if (*i == dst)
- if (i->type == Route::TRACK_ROUTE && i->track == dst.track) // p3.3.50 Is there a route to the track?
+ if(i->type == Route::TRACK_ROUTE && i->track == dst.track) // p3.3.50 Is there a route to the track?
{
+ //printf("i->channel:%x dst.channel:%x\n", i->channel, dst.channel);
i->channel &= ~dst.channel; // p3.3.50 Unset the desired channel bits.
if(i->channel == 0) // Only if there are no channel bits set, erase the route.
+ {
+ //printf("erasing out route from midi port:%d\n", src.midiPort);
outRoutes->erase(i);
-
+ }
+
break; // For safety, keep looking and remove any more found.
- // No, must break, else crash. There should only be one route anyway...
+ // No, must break, else crash. There should only be one route anyway...
}
}
}
@@ -777,9 +834,9 @@ void removeRoute(Route src, Route dst)
i->channel &= ~src.channel; // p3.3.50 Unset the desired channel bits.
if(i->channel == 0) // Only if there are no channel bits set, erase the route.
inRoutes->erase(i);
-
+
break; // For safety, keep looking and remove any more found.
- // No, must break, else crash. There should only be one route anyway...
+ // No, must break, else crash. There should only be one route anyway...
}
}
}
diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp
index b4519d8d..5038820e 100644
--- a/muse2/muse/track.cpp
+++ b/muse2/muse/track.cpp
@@ -739,40 +739,43 @@ bool Track::readProperties(Xml& xml, const QString& tag)
void Track::writeRouting(int level, Xml& xml) const
{
QString s;
-
if (type() == Track::AUDIO_INPUT)
{
const RouteList* rl = &_inRoutes;
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
{
+ // Support Midi Port to Audio Input track routes. p4.0.14 Tim.
+ if(r->type == Route::MIDI_PORT_ROUTE)
+ {
+ s = QT_TRANSLATE_NOOP("@default", "Route");
+ if(r->channel != -1 && r->channel != 0)
+ s += QString(QT_TRANSLATE_NOOP("@default", " channelMask=\"%1\"")).arg(r->channel); // Use new channel mask.
+ xml.tag(level++, s.toLatin1().constData());
+
+ xml.tag(level, "source mport=\"%d\"/", r->midiPort);
+
+ s = QT_TRANSLATE_NOOP("@default", "dest");
+ s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(name()));
+ xml.tag(level, s.toLatin1().constData());
+
+ xml.etag(level--, "Route");
+ }
+ else
if(!r->name().isEmpty())
{
s = QT_TRANSLATE_NOOP("@default", "Route");
if(r->channel != -1)
s += QString(QT_TRANSLATE_NOOP("@default", " channel=\"%1\"")).arg(r->channel);
- ///Route dst(name(), true, r->channel);
- //xml.tag(level++, "Route");
xml.tag(level++, s.toAscii().constData());
// p3.3.38 New routing scheme.
- ///xml.strTag(level, "srcNode", r->name());
- //xml.tag(level, "source type=\"%d\" name=\"%s\"/", r->type, r->name().toLatin1().constData());
s = QT_TRANSLATE_NOOP("@default", "source");
if(r->type != Route::TRACK_ROUTE)
s += QString(QT_TRANSLATE_NOOP("@default", " type=\"%1\"")).arg(r->type);
- //s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(r->name());
s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(r->name()));
xml.tag(level, s.toAscii().constData());
- ///xml.strTag(level, "dstNode", dst.name());
-
- //if(r->channel != -1)
- // xml.tag(level, "dest type=\"%d\" channel=\"%d\" name=\"%s\"/", Route::TRACK_ROUTE, r->channel, name().toLatin1().constData());
- //else
- // xml.tag(level, "dest type=\"%d\" name=\"%s\"/", Route::TRACK_ROUTE, name().toLatin1().constData());
-
- //xml.tag(level, "dest name=\"%s\"/", name().toLatin1().constData());
xml.tag(level, "dest name=\"%s\"/", Xml::xmlString(name()).toLatin1().constData());
xml.etag(level--, "Route");
@@ -783,16 +786,13 @@ void Track::writeRouting(int level, Xml& xml) const
const RouteList* rl = &_outRoutes;
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
{
- //if(!r->name().isEmpty())
+ // p4.0.14 Ignore Audio Output to Audio Input routes.
+ // They are taken care of by Audio Input in the section above.
+ if(r->type == Route::TRACK_ROUTE && r->track && r->track->type() == Track::AUDIO_INPUT)
+ continue;
+
if(r->midiPort != -1 || !r->name().isEmpty()) // p3.3.49
{
- ///QString src(name());
- ///if (type() == Track::AUDIO_OUTPUT)
- ///{
- ///Route s(src, false, r->channel);
- ///src = s.name();
- ///}
-
s = QT_TRANSLATE_NOOP("@default", "Route");
if(r->type == Route::MIDI_PORT_ROUTE) // p3.3.50
{
@@ -809,45 +809,11 @@ void Track::writeRouting(int level, Xml& xml) const
if(r->remoteChannel != -1)
s += QString(QT_TRANSLATE_NOOP("@default", " remch=\"%1\"")).arg(r->remoteChannel);
- //xml.tag(level++, "Route");
xml.tag(level++, s.toAscii().constData());
- ///xml.strTag(level, "srcNode", src);
- //if(r->channel != -1)
-
// Allow for a regular mono or stereo track to feed a multi-channel synti.
- // thisChannel is the 'starting' channel of this source if feeding a regular track.
- //if(r->type == Route::TRACK_ROUTE && r->track->isSynti() && r->channel != -1)
- //if(isSynti() && r->thisChannel != -1)
- //xml.tag(level, "source type=\"%d\" channel=\"%d\" name=\"%s\"/", Route::TRACK_ROUTE, r->channel, name().toLatin1().constData());
- // xml.tag(level, "source type=\"%d\" channel=\"%d\" name=\"%s\"/", Route::TRACK_ROUTE, r->thisChannel, name().toLatin1().constData());
- //else
-
- //if(r->channel != -1)
- // xml.tag(level, "source type=\"%d\" channel=\"%d\" name=\"%s\"/", Route::TRACK_ROUTE, r->channel, name().toLatin1().constData());
- //else
- // xml.tag(level, "source type=\"%d\" name=\"%s\"/", Route::TRACK_ROUTE, name().toLatin1().constData());
- //xml.tag(level, "source name=\"%s\"/", name().toLatin1().constData());
xml.tag(level, "source name=\"%s\"/", Xml::xmlString(name()).toLatin1().constData());
- ///xml.strTag(level, "dstNode", r->name());
- //if(r->channel != -1)
- // xml.tag(level, "dest type=\"%d\" channel=\"%d\" name=\"%s\"/", r->type, r->channel, r->name().toLatin1().constData());
- //else
- // xml.tag(level, "dest type=\"%d\" name=\"%s\"/", r->type, r->name().toLatin1().constData());
-
- // Allow for a regular mono or stereo track to feed a multi-channel synti.
- // Channel is the 'starting' channel of the destination.
- //if(r->type == Route::TRACK_ROUTE && r->track->isSynti() && r->channel != -1)
-
- //if(r->type == Route::TRACK_ROUTE && r->track->type() == Track::AUDIO_SOFTSYNTH && r->remoteChannel != -1)
- // xml.tag(level, "dest type=\"%d\" channel=\"%d\" name=\"%s\"/", r->type, r->remoteChannel, r->name().toLatin1().constData());
- //else
- //if(r->type == Route::MIDI_DEVICE_ROUTE)
- // xml.tag(level, "dest devtype=\"%d\" name=\"%s\"/", r->device->deviceType(), r->name().toLatin1().constData());
- //else
- // xml.tag(level, "dest type=\"%d\" name=\"%s\"/", r->type, r->name().toLatin1().constData());
-
s = QT_TRANSLATE_NOOP("@default", "dest");
//if(r->type == Route::MIDI_DEVICE_ROUTE) // p3.3.49 Obsolete since 1.1-RC2
diff --git a/muse2/muse/widgets/mtrackinfo.cpp b/muse2/muse/widgets/mtrackinfo.cpp
index f9903037..04911b02 100644
--- a/muse2/muse/widgets/mtrackinfo.cpp
+++ b/muse2/muse/widgets/mtrackinfo.cpp
@@ -154,9 +154,10 @@ MidiTrackInfo::MidiTrackInfo(QWidget* parent, Track* sel_track) : QWidget(parent
connect(iRButton, SIGNAL(pressed()), SLOT(inRoutesPressed()));
// TODO: Works OK, but disabled for now, until we figure out what to do about multiple out routes and display values...
+ // Enabled (for Midi Port to Audio Input routing). p4.0.14 Tim.
//oRButton->setEnabled(false);
//oRButton->setVisible(false);
- //connect(oRButton, SIGNAL(pressed()), SLOT(outRoutesPressed()));
+ connect(oRButton, SIGNAL(pressed()), SLOT(outRoutesPressed()));
connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
connect(muse, SIGNAL(configChanged()), SLOT(configChanged()));
@@ -541,7 +542,10 @@ void MidiTrackInfo::iOutputChannelChanged(int channel)
// may result in adding/removing mixer strip:
//song->update(-1);
- song->update(SC_MIDI_TRACK_PROP);
+ //song->update(SC_MIDI_TRACK_PROP);
+ audio->msgUpdateSoloStates(); // p4.0.14
+ //song->update(SC_MIDI_TRACK_PROP | SC_ROUTE); //
+ song->update(SC_MIDI_TRACK_PROP); //
}
}
@@ -563,7 +567,10 @@ void MidiTrackInfo::iOutputPortChanged(int index)
track->setOutPortAndUpdate(index);
audio->msgIdle(false);
- song->update(SC_MIDI_TRACK_PROP);
+ //song->update(SC_MIDI_TRACK_PROP);
+ audio->msgUpdateSoloStates(); // p4.0.14
+ //song->update(SC_MIDI_TRACK_PROP | SC_ROUTE); //
+ song->update(SC_MIDI_TRACK_PROP); //
}
//---------------------------------------------------------
@@ -652,7 +659,7 @@ void MidiTrackInfo::outRoutesPressed()
connect(pup, SIGNAL(triggered(QAction*)), SLOT(routingPopupMenuActivated(QAction*)));
connect(pup, SIGNAL(aboutToHide()), muse, SLOT(routingPopupMenuAboutToHide()));
pup->popup(QCursor::pos());
- ///oRButton->setDown(false);
+ oRButton->setDown(false);
return;
}
diff --git a/muse2/muse/widgets/mtrackinfobase.ui b/muse2/muse/widgets/mtrackinfobase.ui
index 1649b1d5..3437b97e 100644
--- a/muse2/muse/widgets/mtrackinfobase.ui
+++ b/muse2/muse/widgets/mtrackinfobase.ui
@@ -131,11 +131,27 @@
<string>input routing</string>
</property>
<property name="text">
- <string>In</string>
+ <string>iR</string>
</property>
</widget>
</item>
<item>
+ <widget class="QToolButton" name="oRButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>output routing</string>
+ </property>
+ <property name="text">
+ <string>oR</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QLabel" name="iChanDetectLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">