summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse/ChangeLog3
-rw-r--r--muse/muse/audio.cpp5
-rw-r--r--muse/muse/audio.h4
-rw-r--r--muse/muse/conf.cpp3
-rw-r--r--muse/muse/confmport.cpp180
-rw-r--r--muse/muse/driver/alsamidi.h9
-rw-r--r--muse/muse/driver/jack.cpp378
-rw-r--r--muse/muse/driver/jackmidi.cpp233
-rw-r--r--muse/muse/driver/jackmidi.h26
-rw-r--r--muse/muse/globals.h4
-rw-r--r--muse/muse/mididev.h6
-rw-r--r--muse/muse/route.cpp58
-rw-r--r--muse/muse/route.h1
-rw-r--r--muse/muse/seqmsg.cpp92
14 files changed, 736 insertions, 266 deletions
diff --git a/muse/ChangeLog b/muse/ChangeLog
index a5cd7d5e..7ed5c5fa 100644
--- a/muse/ChangeLog
+++ b/muse/ChangeLog
@@ -1,3 +1,6 @@
+15.10.2010
+ * Feature: Unified Jack midi devices in midi ports list. Can be both input and output, just like ALSA devices. (T356)
+ - Marked as p3.3.55
09.10.2010
* Fixed: Gluing of midi track parts, over tempo changes, caused incorrect note times and lengths. (T356)
- Fixed Song::cmdGluePart().
diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp
index 9a7029db..f38bcc9c 100644
--- a/muse/muse/audio.cpp
+++ b/muse/muse/audio.cpp
@@ -64,7 +64,7 @@ const char* seqMsgList[] = {
"SEQM_UPDATE_SOLO_STATES",
"MIDI_SHOW_INSTR_GUI",
"AUDIO_RECORD",
- "AUDIO_ROUTEADD", "AUDIO_ROUTEREMOVE",
+ "AUDIO_ROUTEADD", "AUDIO_ROUTEREMOVE", "AUDIO_REMOVEROUTES",
"AUDIO_VOL", "AUDIO_PAN",
"AUDIO_ADDPLUGIN",
"AUDIO_SET_SEG_SIZE",
@@ -625,6 +625,9 @@ void Audio::processMsg(AudioMsg* msg)
case AUDIO_ROUTEREMOVE:
removeRoute(msg->sroute, msg->droute);
break;
+ case AUDIO_REMOVEROUTES: // p3.3.55
+ removeAllRoutes(msg->sroute, msg->droute);
+ break;
case AUDIO_VOL:
msg->snode->setVolume(msg->dval);
break;
diff --git a/muse/muse/audio.h b/muse/muse/audio.h
index fb51ca03..ba188f8a 100644
--- a/muse/muse/audio.h
+++ b/muse/muse/audio.h
@@ -59,7 +59,7 @@ enum {
SEQM_UPDATE_SOLO_STATES,
MIDI_SHOW_INSTR_GUI,
AUDIO_RECORD,
- AUDIO_ROUTEADD, AUDIO_ROUTEREMOVE,
+ AUDIO_ROUTEADD, AUDIO_ROUTEREMOVE, AUDIO_REMOVEROUTES,
AUDIO_VOL, AUDIO_PAN,
AUDIO_ADDPLUGIN,
AUDIO_SET_SEG_SIZE,
@@ -223,6 +223,8 @@ class Audio {
bool sendMessage(AudioMsg* m, bool doUndo);
void msgRemoveRoute(Route, Route);
void msgRemoveRoute1(Route, Route);
+ void msgRemoveRoutes(Route, Route); // p3.3.55
+ void msgRemoveRoutes1(Route, Route); // p3.3.55
void msgAddRoute(Route, Route);
void msgAddRoute1(Route, Route);
void msgAddPlugin(AudioTrack*, int idx, PluginI* plugin);
diff --git a/muse/muse/conf.cpp b/muse/muse/conf.cpp
index d53b30b1..3bf13beb 100644
--- a/muse/muse/conf.cpp
+++ b/muse/muse/conf.cpp
@@ -276,7 +276,8 @@ static void readConfigMidiPort(Xml& xml)
{
if(debugMsg)
fprintf(stderr, "readConfigMidiPort: creating jack midi device %s\n", device.latin1());
- dev = MidiJackDevice::createJackMidiDevice(device, openFlags);
+ //dev = MidiJackDevice::createJackMidiDevice(device, openFlags);
+ dev = MidiJackDevice::createJackMidiDevice(device); // p3.3.55
}
if(debugMsg && !dev)
diff --git a/muse/muse/confmport.cpp b/muse/muse/confmport.cpp
index 77766116..b444a86a 100644
--- a/muse/muse/confmport.cpp
+++ b/muse/muse/confmport.cpp
@@ -55,7 +55,8 @@ extern std::vector<Synth*> synthis;
enum { DEVCOL_NO = 0, DEVCOL_GUI, DEVCOL_REC, DEVCOL_PLAY, DEVCOL_INSTR, DEVCOL_NAME,
//DEVCOL_STATE };
- DEVCOL_ROUTES, DEVCOL_STATE };
+ //DEVCOL_ROUTES, DEVCOL_STATE };
+ DEVCOL_INROUTES, DEVCOL_OUTROUTES, DEVCOL_STATE }; // p3.3.55
//---------------------------------------------------------
// mdevViewItemRenamed
@@ -154,6 +155,22 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
dev->setOpenFlags(openFlags);
midiSeq->msgSetMidiDevice(port, dev); // reopen device
item->setPixmap(DEVCOL_REC, openFlags & 2 ? *dotIcon : *dothIcon);
+
+ // p3.3.55
+ if(dev->deviceType() == MidiDevice::JACK_MIDI)
+ {
+ if(dev->openFlags() & 2)
+ {
+ //item->setPixmap(DEVCOL_INROUTES, *buttondownIcon);
+ item->setText(DEVCOL_INROUTES, tr("in"));
+ }
+ else
+ {
+ //item->setPixmap(DEVCOL_INROUTES, *buttondownIcon);
+ item->setText(DEVCOL_INROUTES, "");
+ }
+ }
+
//break;
return;
@@ -165,10 +182,28 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
dev->setOpenFlags(openFlags);
midiSeq->msgSetMidiDevice(port, dev); // reopen device
item->setPixmap(DEVCOL_PLAY, openFlags & 1 ? *dotIcon : *dothIcon);
+
+ // p3.3.55
+ if(dev->deviceType() == MidiDevice::JACK_MIDI)
+ {
+ if(dev->openFlags() & 1)
+ {
+ //item->setPixmap(DEVCOL_OUTROUTES, *buttondownIcon);
+ item->setText(DEVCOL_OUTROUTES, tr("out"));
+ }
+ else
+ {
+ //item->setPixmap(DEVCOL_OUTROUTES, *buttondownIcon);
+ item->setText(DEVCOL_OUTROUTES, "");
+ }
+ }
+
//break;
return;
- case DEVCOL_ROUTES:
+ //case DEVCOL_ROUTES:
+ case DEVCOL_INROUTES: // p3.3.55
+ case DEVCOL_OUTROUTES:
{
if(!checkAudioDevice())
return;
@@ -185,10 +220,13 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
if(dev->deviceType() != MidiDevice::JACK_MIDI)
return;
- if(!dev->rwFlags() & 3)
+ //if(!(dev->rwFlags() & 3))
+ //if(!(dev->rwFlags() & ((col == DEVCOL_OUTROUTES) ? 1 : 2))) // p3.3.55
+ if(!(dev->openFlags() & ((col == DEVCOL_OUTROUTES) ? 1 : 2)))
return;
- RouteList* rl = (dev->rwFlags() & 1) ? dev->outRoutes() : dev->inRoutes();
+ //RouteList* rl = (dev->rwFlags() & 1) ? dev->outRoutes() : dev->inRoutes();
+ RouteList* rl = (col == DEVCOL_OUTROUTES) ? dev->outRoutes() : dev->inRoutes(); // p3.3.55
QPopupMenu* pup = 0;
int gid = 0;
@@ -202,7 +240,9 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
gid = 0;
// Jack input ports if device is writable, and jack output ports if device is readable.
- sl = (dev->rwFlags() & 1) ? audioDevice->inputPorts(true, _showAliases) : audioDevice->outputPorts(true, _showAliases);
+ //sl = (dev->rwFlags() & 1) ? audioDevice->inputPorts(true, _showAliases) : audioDevice->outputPorts(true, _showAliases);
+ // p3.3.55
+ sl = (col == DEVCOL_OUTROUTES) ? audioDevice->inputPorts(true, _showAliases) : audioDevice->outputPorts(true, _showAliases);
//for (int i = 0; i < channel; ++i)
//{
@@ -224,7 +264,8 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
//int id = pup->insertItem(*ip, gid);
pup->insertItem(*ip, gid);
//Route dst(*ip, true, i);
- Route rt(*ip, (dev->rwFlags() & 1), -1, Route::JACK_ROUTE);
+ //Route rt(*ip, (dev->rwFlags() & 1), -1, Route::JACK_ROUTE);
+ Route rt(*ip, (col == DEVCOL_OUTROUTES), -1, Route::JACK_ROUTE); // p3.3.55
for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)
{
if (*ir == rt)
@@ -265,7 +306,8 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
QString s(pup->text(n));
- if(dev->rwFlags() & 1) // Writable
+ //if(dev->rwFlags() & 1) // Writable
+ if(col == DEVCOL_OUTROUTES) // Writable p3.3.55
{
Route srcRoute(dev, -1);
Route dstRoute(s, true, -1, Route::JACK_ROUTE);
@@ -284,7 +326,8 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
audio->msgAddRoute(srcRoute, dstRoute);
}
else
- if(dev->rwFlags() & 2) // Readable
+ //if(dev->rwFlags() & 2) // Readable
+ //if(col == DEVCOL_INROUTES) // Readable p3.3.55
{
Route srcRoute(s, false, -1, Route::JACK_ROUTE);
Route dstRoute(dev, -1);
@@ -342,8 +385,12 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
pup->setCheckable(true);
- pup->insertItem(tr("Create") + QT_TR_NOOP(" Jack") + tr(" input"), 0);
- pup->insertItem(tr("Create") + QT_TR_NOOP(" Jack") + tr(" output"), 1);
+ // Could do it this way...
+ //pup->insertItem(tr("Create") + QT_TR_NOOP(" Jack") + tr(" input"), 1);
+ //pup->insertItem(tr("Create") + QT_TR_NOOP(" Jack") + tr(" output"), 2);
+ //pup->insertItem(tr("Create") + QT_TR_NOOP(" Jack") + tr(" combo"), 0); // p3.3.55
+ // ... or keep it simple and let the user click on the green lights instead.
+ pup->insertItem(tr("Create") + QT_TR_NOOP(" Jack") + tr(" device"), 0); //
typedef std::map<std::string, int > asmap;
typedef std::map<std::string, int >::iterator imap;
@@ -352,9 +399,9 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
asmap mapJACK;
asmap mapSYNTH;
- int aix = 2;
- int jix = 0x10000000;
- int six = 0x20000000;
+ int aix = 0x10000000;
+ int jix = 0x20000000;
+ int six = 0x30000000;
for(iMidiDevice i = midiDevices.begin(); i != midiDevices.end(); ++i)
{
//devALSA = dynamic_cast<MidiAlsaDevice*>(*i);
@@ -385,7 +432,7 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
}
//int sz = midiDevices.size();
- if(!mapALSA.empty())
+ //if(!mapALSA.empty())
{
pup->insertSeparator();
pup->insertItem(new MenuTitleItem(QT_TR_NOOP("ALSA:")));
@@ -422,22 +469,22 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
}
}
- if(!mapJACK.empty())
+ if(!mapSYNTH.empty())
{
pup->insertSeparator();
- pup->insertItem(new MenuTitleItem(QT_TR_NOOP("JACK:")));
+ pup->insertItem(new MenuTitleItem(QT_TR_NOOP("SYNTH:")));
- for(imap i = mapJACK.begin(); i != mapJACK.end(); ++i)
+ for(imap i = mapSYNTH.begin(); i != mapSYNTH.end(); ++i)
{
int idx = i->second;
//if(idx > sz)
// continue;
QString s(i->first.c_str());
- MidiDevice* md = midiDevices.find(s, MidiDevice::JACK_MIDI);
+ MidiDevice* md = midiDevices.find(s, MidiDevice::SYNTH_MIDI);
if(md)
{
//if(!dynamic_cast<MidiJackDevice*>(md))
- if(md->deviceType() != MidiDevice::JACK_MIDI)
+ if(md->deviceType() != MidiDevice::SYNTH_MIDI)
continue;
//pup->insertItem(QT_TR_NOOP(md->name()), idx + 3);
@@ -457,24 +504,29 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
//}
}
}
- }
+ }
- if(!mapSYNTH.empty())
+ //if(!mapJACK.empty())
{
pup->insertSeparator();
- pup->insertItem(new MenuTitleItem(QT_TR_NOOP("SYNTH:")));
+ pup->insertItem(new MenuTitleItem(QT_TR_NOOP("JACK:")));
- for(imap i = mapSYNTH.begin(); i != mapSYNTH.end(); ++i)
+ //pup->insertItem(tr("<Create input>"), 1);
+ //pup->insertItem(tr("<Create output>"), 2);
+ //pup->insertItem(tr("<Create combo>"), 0); // p3.3.55
+ //pup->insertSeparator();
+
+ for(imap i = mapJACK.begin(); i != mapJACK.end(); ++i)
{
int idx = i->second;
//if(idx > sz)
// continue;
QString s(i->first.c_str());
- MidiDevice* md = midiDevices.find(s, MidiDevice::SYNTH_MIDI);
+ MidiDevice* md = midiDevices.find(s, MidiDevice::JACK_MIDI);
if(md)
{
//if(!dynamic_cast<MidiJackDevice*>(md))
- if(md->deviceType() != MidiDevice::SYNTH_MIDI)
+ if(md->deviceType() != MidiDevice::JACK_MIDI)
continue;
//pup->insertItem(QT_TR_NOOP(md->name()), idx + 3);
@@ -494,7 +546,7 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
//}
}
}
- }
+ }
n = pup->exec(ppt, 0);
if(n == -1)
@@ -507,21 +559,43 @@ void MPConfig::rbClicked(QListViewItem* item, const QPoint& cpt, int col)
//printf("MPConfig::rbClicked n:%d\n", n);
MidiDevice* sdev = 0;
- if(n < 2)
+ if(n < 0x10000000)
{
delete pup;
- if(n == 0)
- sdev = MidiJackDevice::createJackMidiDevice(QString(), 2); // 2: Readable.
- else
- if(n == 1)
- sdev = MidiJackDevice::createJackMidiDevice(QString(), 1); // 1:Writable.
+ //if(n == 0) // p3.3.55
+ // sdev = MidiJackDevice::createJackMidiDevice(QString(), 3); // 3:Readable/Writable.
+ //else
+ //if(n == 1)
+ // sdev = MidiJackDevice::createJackMidiDevice(QString(), 2); // 2: Readable.
+ //else
+ //if(n == 2)
+ // sdev = MidiJackDevice::createJackMidiDevice(QString(), 1); // 1:Writable.
+ if(n <= 2) // p3.3.55
+ {
+ sdev = MidiJackDevice::createJackMidiDevice();
+ if(sdev)
+ {
+ int of = 3;
+ switch(n)
+ {
+ case 0: of = 3; break;
+ case 1: of = 2; break;
+ case 2: of = 1; break;
+ }
+ sdev->setOpenFlags(of);
+ }
+ }
}
else
{
- int typ = MidiDevice::ALSA_MIDI;
- if(n >= 0x10000000)
+ int typ;
+ if(n < 0x20000000)
+ typ = MidiDevice::ALSA_MIDI;
+ else
+ if(n < 0x30000000)
typ = MidiDevice::JACK_MIDI;
- if(n >= 0x20000000)
+ else
+ //if(n < 0x40000000)
typ = MidiDevice::SYNTH_MIDI;
sdev = midiDevices.find(pup->text(n), typ);
@@ -600,7 +674,9 @@ void MPHeaderTip::maybeTip(const QPoint &pos)
case DEVCOL_PLAY: p = QHeader::tr("Enable writing"); break;
case DEVCOL_INSTR: p = QHeader::tr("Port instrument"); break;
case DEVCOL_NAME: p = QHeader::tr("Midi device name. Click to edit (Jack)"); break;
- case DEVCOL_ROUTES: p = QHeader::tr("Jack midi ports"); break;
+ //case DEVCOL_ROUTES: p = QHeader::tr("Jack midi ports"); break;
+ case DEVCOL_INROUTES: p = QHeader::tr("Connections from Jack Midi outputs"); break;
+ case DEVCOL_OUTROUTES: p = QHeader::tr("Connections to Jack Midi inputs"); break;
case DEVCOL_STATE: p = QHeader::tr("Device state"); break;
default: return;
}
@@ -630,8 +706,12 @@ QString MPWhatsThis::text(const QPoint& pos)
" this port number. Click to edit Jack midi name.");
case DEVCOL_INSTR:
return QHeader::tr("Instrument connected to port");
- case DEVCOL_ROUTES:
- return QHeader::tr("Jack midi ports");
+ //case DEVCOL_ROUTES:
+ // return QHeader::tr("Jack midi ports");
+ case DEVCOL_INROUTES:
+ return QHeader::tr("Connections from Jack Midi output ports");
+ case DEVCOL_OUTROUTES:
+ return QHeader::tr("Connections to Jack Midi input ports");
case DEVCOL_STATE:
return QHeader::tr("State: result of opening the device");
default:
@@ -661,7 +741,9 @@ MPConfig::MPConfig(QWidget* parent, char* name)
mdevView->addColumn(tr("O"));
mdevView->addColumn(tr("Instrument"), 120);
mdevView->addColumn(tr("Device Name"), 120);
- mdevView->addColumn(tr("Routing"), 80);
+ //mdevView->addColumn(tr("Routing"), 80);
+ mdevView->addColumn(tr("In routes"), 80);
+ mdevView->addColumn(tr("Out routes"), 80);
mdevView->addColumn(tr("State"));
mdevView->setFocusPolicy(NoFocus);
@@ -780,8 +862,24 @@ void MPConfig::songChanged(int flags)
//if(dev && dynamic_cast<MidiJackDevice*>(dev))
if(dev && dev->deviceType() == MidiDevice::JACK_MIDI)
{
- item->setPixmap(DEVCOL_ROUTES, *buttondownIcon);
- item->setText(DEVCOL_ROUTES, tr("routes"));
+ //item->setPixmap(DEVCOL_ROUTES, *buttondownIcon);
+ //item->setText(DEVCOL_ROUTES, tr("routes"));
+
+ // p3.3.55
+ if(dev->rwFlags() & 1)
+ //if(dev->openFlags() & 1)
+ {
+ item->setPixmap(DEVCOL_OUTROUTES, *buttondownIcon);
+ if(dev->openFlags() & 1)
+ item->setText(DEVCOL_OUTROUTES, tr("out"));
+ }
+ if(dev->rwFlags() & 2)
+ //if(dev->openFlags() & 2)
+ {
+ item->setPixmap(DEVCOL_INROUTES, *buttondownIcon);
+ if(dev->openFlags() & 2)
+ item->setText(DEVCOL_INROUTES, tr("in"));
+ }
}
mdevView->insertItem(item);
diff --git a/muse/muse/driver/alsamidi.h b/muse/muse/driver/alsamidi.h
index 6c19ff0d..455ab1df 100644
--- a/muse/muse/driver/alsamidi.h
+++ b/muse/muse/driver/alsamidi.h
@@ -34,10 +34,15 @@ class MidiAlsaDevice : public MidiDevice {
virtual bool putMidiEvent(const MidiPlayEvent&);
public:
- MidiAlsaDevice() {}
+ //MidiAlsaDevice() {} // p3.3.55 Removed
MidiAlsaDevice(const snd_seq_addr_t&, const QString& name);
virtual ~MidiAlsaDevice() {}
- virtual void* clientPort() { return (void*)&adr; }
+
+ //virtual void* clientPort() { return (void*)&adr; }
+ // p3.3.55
+ virtual void* inClientPort() { return (void*)&adr; } // For ALSA midi, in/out client ports are the same.
+ virtual void* outClientPort() { return (void*)&adr; } // That is, ALSA midi client ports can be both r/w.
+
virtual void writeRouting(int, Xml&) const;
virtual inline int deviceType() { return ALSA_MIDI; }
};
diff --git a/muse/muse/driver/jack.cpp b/muse/muse/driver/jack.cpp
index 2c5081fc..e23f2de8 100644
--- a/muse/muse/driver/jack.cpp
+++ b/muse/muse/driver/jack.cpp
@@ -704,19 +704,29 @@ void JackAudioDevice::connectJackMidiPorts()
if(md->deviceType() != MidiDevice::JACK_MIDI)
continue;
- void* port = md->clientPort();
+ //void* port = md->clientPort();
if(md->rwFlags() & 1)
{
- RouteList* rl = md->outRoutes();
- for (iRoute r = rl->begin(); r != rl->end(); ++r)
- connect(port, r->jackPort);
+ void* port = md->outClientPort(); // p3.3.55
+ if(port) //
+ {
+ RouteList* rl = md->outRoutes();
+ for (iRoute r = rl->begin(); r != rl->end(); ++r)
+ connect(port, r->jackPort);
+ }
}
- else
+
+ // else // p3.3.55 Removed
+
if(md->rwFlags() & 2)
{
- RouteList* rl = md->inRoutes();
- for (iRoute r = rl->begin(); r != rl->end(); ++r)
- connect(r->jackPort, port);
+ void* port = md->inClientPort(); // p3.3.55
+ if(port) //
+ {
+ RouteList* rl = md->inRoutes();
+ for (iRoute r = rl->begin(); r != rl->end(); ++r)
+ connect(r->jackPort, port);
+ }
}
}
@@ -1066,10 +1076,12 @@ void JackAudioDevice::graphChanged()
// continue;
//for (int channel = 0; channel < channels; ++channel)
//{
- jack_port_t* port = (jack_port_t*)md->clientPort();
- if (port == 0)
- continue;
- const char** ports = jack_port_get_all_connections(_client, port);
+
+ // p3.3.55 Removed
+ //jack_port_t* port = (jack_port_t*)md->clientPort();
+ //if (port == 0)
+ // continue;
+ //const char** ports = jack_port_get_all_connections(_client, port);
//---------------------------------------
// outputs
@@ -1077,87 +1089,95 @@ void JackAudioDevice::graphChanged()
if(md->rwFlags() & 1) // Writable
{
- RouteList* rl = md->outRoutes();
-
- //---------------------------------------
- // check for disconnects
- //---------------------------------------
-
- bool erased;
- // limit set to 20 iterations for disconnects, don't know how to make it go
- // the "right" amount
- for (int i = 0; i < 20 ; i++)
- {
- erased = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
- //if (irl->channel != channel)
- // continue;
- QString name = irl->name();
- const char* portName = name.latin1();
- bool found = false;
- const char** pn = ports;
- while (pn && *pn) {
- if (strcmp(*pn, portName) == 0) {
- found = true;
- break;
- }
- ++pn;
- }
- if (!found) {
- audio->msgRemoveRoute1(
- //Route(it, channel),
- //Route(mjd),
- Route(md, -1),
- //Route(portName, false, channel)
- //Route(portName, false, -1)
- Route(portName, false, -1, Route::JACK_ROUTE)
- );
- erased = true;
- break;
- }
- }
- if (!erased)
- break;
- }
-
- //---------------------------------------
- // check for connects
- //---------------------------------------
-
- if (ports)
+ // p3.3.55
+ jack_port_t* port = (jack_port_t*)md->outClientPort();
+ if(port != 0)
{
- const char** pn = ports;
- while (*pn) {
- bool found = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
- //if (irl->channel != channel)
- // continue;
- QString name = irl->name();
- const char* portName = name.latin1();
- if (strcmp(*pn, portName) == 0) {
- found = true;
- break;
- }
- }
- if (!found) {
- audio->msgAddRoute1(
- //Route(it, channel),
- //Route(mjd),
- Route(md, -1),
- //Route(*pn, false, channel)
- //Route(*pn, false, -1)
- Route(*pn, false, -1, Route::JACK_ROUTE)
- );
- }
- ++pn;
- }
-
- // p3.3.37
- //delete ports;
- //free(ports);
-
- //ports = NULL;
- }
+ //printf("graphChanged() valid out client port\n"); // p3.3.55
+
+ const char** ports = jack_port_get_all_connections(_client, port);
+
+ RouteList* rl = md->outRoutes();
+
+ //---------------------------------------
+ // check for disconnects
+ //---------------------------------------
+
+ bool erased;
+ // limit set to 20 iterations for disconnects, don't know how to make it go
+ // the "right" amount
+ for (int i = 0; i < 20 ; i++)
+ {
+ erased = false;
+ for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ //if (irl->channel != channel)
+ // continue;
+ QString name = irl->name();
+ //name += QString(JACK_MIDI_OUT_PORT_SUFFIX); // p3.3.55
+ const char* portName = name.latin1();
+ bool found = false;
+ const char** pn = ports;
+ while (pn && *pn) {
+ if (strcmp(*pn, portName) == 0) {
+ found = true;
+ break;
+ }
+ ++pn;
+ }
+ if (!found) {
+ audio->msgRemoveRoute1(
+ //Route(it, channel),
+ //Route(mjd),
+ Route(md, -1),
+ //Route(portName, false, channel)
+ //Route(portName, false, -1)
+ Route(portName, false, -1, Route::JACK_ROUTE)
+ );
+ erased = true;
+ break;
+ }
+ }
+ if (!erased)
+ break;
+ }
+
+ //---------------------------------------
+ // check for connects
+ //---------------------------------------
+
+ if (ports)
+ {
+ const char** pn = ports;
+ while (*pn) {
+ bool found = false;
+ for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ //if (irl->channel != channel)
+ // continue;
+ QString name = irl->name();
+ const char* portName = name.latin1();
+ if (strcmp(*pn, portName) == 0) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ audio->msgAddRoute1(
+ //Route(it, channel),
+ //Route(mjd),
+ Route(md, -1),
+ //Route(*pn, false, channel)
+ //Route(*pn, false, -1)
+ Route(*pn, false, -1, Route::JACK_ROUTE)
+ );
+ }
+ ++pn;
+ }
+
+ // p3.3.55
+ // Done with ports. Free them.
+ free(ports);
+ }
+ }
}
@@ -1167,88 +1187,100 @@ void JackAudioDevice::graphChanged()
if(md->rwFlags() & 2) // Readable
{
- RouteList* rl = md->inRoutes();
-
- //---------------------------------------
- // check for disconnects
- //---------------------------------------
-
- bool erased;
- // limit set to 20 iterations for disconnects, don't know how to make it go
- // the "right" amount
- for (int i = 0; i < 20 ; i++)
+ // p3.3.55
+ jack_port_t* port = (jack_port_t*)md->inClientPort();
+ if(port != 0)
{
- erased = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
- //if (irl->channel != channel)
- // continue;
- QString name = irl->name();
- const char* portName = name.latin1();
- bool found = false;
- const char** pn = ports;
- while (pn && *pn) {
- if (strcmp(*pn, portName) == 0) {
- found = true;
- break;
- }
- ++pn;
- }
- if (!found) {
- audio->msgRemoveRoute1(
- //Route(portName, false, channel),
- //Route(portName, false, -1),
- Route(portName, false, -1, Route::JACK_ROUTE),
- //Route(it, channel)
- //Route(mjd)
- Route(md, -1)
- );
- erased = true;
- break;
- }
- }
- if (!erased)
- break;
- }
-
- //---------------------------------------
- // check for connects
- //---------------------------------------
-
- if (ports)
- {
- const char** pn = ports;
- while (*pn) {
- bool found = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
- //if (irl->channel != channel)
- // continue;
- QString name = irl->name();
- const char* portName = name.latin1();
- if (strcmp(*pn, portName) == 0) {
- found = true;
- break;
- }
- }
- if (!found) {
- audio->msgAddRoute1(
- //Route(*pn, false, channel),
- //Route(*pn, false, -1),
- Route(*pn, false, -1, Route::JACK_ROUTE),
- //Route(it, channel)
- //Route(mjd)
- Route(md, -1)
- );
- }
- ++pn;
- }
- }
+ //printf("graphChanged() valid in client port\n"); // p3.3.55
+ const char** ports = jack_port_get_all_connections(_client, port);
+
+ RouteList* rl = md->inRoutes();
+
+ //---------------------------------------
+ // check for disconnects
+ //---------------------------------------
+
+ bool erased;
+ // limit set to 20 iterations for disconnects, don't know how to make it go
+ // the "right" amount
+ for (int i = 0; i < 20 ; i++)
+ {
+ erased = false;
+ for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ //if (irl->channel != channel)
+ // continue;
+ QString name = irl->name();
+ const char* portName = name.latin1();
+ bool found = false;
+ const char** pn = ports;
+ while (pn && *pn) {
+ if (strcmp(*pn, portName) == 0) {
+ found = true;
+ break;
+ }
+ ++pn;
+ }
+ if (!found) {
+ audio->msgRemoveRoute1(
+ //Route(portName, false, channel),
+ //Route(portName, false, -1),
+ Route(portName, false, -1, Route::JACK_ROUTE),
+ //Route(it, channel)
+ //Route(mjd)
+ Route(md, -1)
+ );
+ erased = true;
+ break;
+ }
+ }
+ if (!erased)
+ break;
+ }
+
+ //---------------------------------------
+ // check for connects
+ //---------------------------------------
+
+ if (ports)
+ {
+ const char** pn = ports;
+ while (*pn) {
+ bool found = false;
+ for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ //if (irl->channel != channel)
+ // continue;
+ QString name = irl->name();
+ const char* portName = name.latin1();
+ if (strcmp(*pn, portName) == 0) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ audio->msgAddRoute1(
+ //Route(*pn, false, channel),
+ //Route(*pn, false, -1),
+ Route(*pn, false, -1, Route::JACK_ROUTE),
+ //Route(it, channel)
+ //Route(mjd)
+ Route(md, -1)
+ );
+ }
+ ++pn;
+ }
+ // p3.3.55
+ // Done with ports. Free them.
+ free(ports);
+ }
+ }
}
- if(ports)
+
+ // p3.3.55 Removed.
+ //if(ports)
// Done with ports. Free them.
//delete ports;
- free(ports);
-
- ports = NULL;
+ // free(ports);
+ //ports = NULL;
}
}
@@ -1273,7 +1305,8 @@ void JackAudioDevice::registerClient()
// Added by Tim. p3.3.20
// Did not help. Seek during play: Jack keeps switching to STOP state after about 1-2 seconds timeout if sync is holding it up.
// Nothing in MusE seems to be telling it to stop.
- jack_set_sync_timeout(_client, 5000000); // Change default 2 to 5 second sync timeout because prefetch may be very slow esp. with resampling !
+ // NOTE: Update: It was a bug in QJackCtl. Fixed now.
+ //jack_set_sync_timeout(_client, 5000000); // Change default 2 to 5 second sync timeout because prefetch may be very slow esp. with resampling !
jack_on_shutdown(_client, processShutdown, 0);
jack_set_buffer_size_callback(_client, bufsize_callback, 0);
@@ -1379,6 +1412,8 @@ void JackAudioDevice::disconnect(void* src, void* dst)
if (JACK_DEBUG)
printf("JackAudioDevice::disconnect()\n");
if(!checkJackClient(_client)) return;
+ if(!src || !dst) // p3.3.55
+ return;
const char* sn = jack_port_name((jack_port_t*) src);
const char* dn = jack_port_name((jack_port_t*) dst);
if (sn == 0 || dn == 0) {
@@ -1907,6 +1942,7 @@ void JackAudioDevice::seekTransport(unsigned frame)
// Docs say when starting play, transport will roll anyway, ready or not (observed),
// but don't mention what should happen on seek during play.
// And setting the slow-sync timeout doesn't seem to do anything!
+ // NOTE: Update: It was a bug with QJackCtl. Fixed now.
//dummyState = tempState;
dummyState = Audio::STOP;
return;
diff --git a/muse/muse/driver/jackmidi.cpp b/muse/muse/driver/jackmidi.cpp
index 36d6a300..267c6728 100644
--- a/muse/muse/driver/jackmidi.cpp
+++ b/muse/muse/driver/jackmidi.cpp
@@ -135,14 +135,25 @@ bool JackMidiPortList::removeClientPort(jack_port_t* port)
//---------------------------------------------------------
// MidiJackDevice
+// in_jack_port or out_jack_port can be null
//---------------------------------------------------------
//MidiJackDevice::MidiJackDevice(const int& a, const QString& n)
-MidiJackDevice::MidiJackDevice(jack_port_t* jack_port, const QString& n)
+//MidiJackDevice::MidiJackDevice(jack_port_t* jack_port, const QString& n)
+// p3.3.55
+//MidiJackDevice::MidiJackDevice(jack_port_t* in_jack_port, jack_port_t* out_jack_port, const QString& n)
+MidiJackDevice::MidiJackDevice(const QString& n)
: MidiDevice(n)
{
//_client_jackport = 0;
- _client_jackport = jack_port;
+
+ //_client_jackport = jack_port;
+ // p3.3.55
+ //_in_client_jackport = in_jack_port;
+ //_out_client_jackport = out_jack_port;
+ _in_client_jackport = NULL;
+ _out_client_jackport = NULL;
+
//adr = a;
init();
}
@@ -152,8 +163,15 @@ MidiJackDevice::~MidiJackDevice()
#ifdef JACK_MIDI_DEBUG
printf("MidiJackDevice::~MidiJackDevice()\n");
#endif
- if(_client_jackport)
- audioDevice->unregisterPort(_client_jackport);
+
+ //if(_client_jackport)
+ // audioDevice->unregisterPort(_client_jackport);
+ // p3.3.55
+ if(_in_client_jackport)
+ audioDevice->unregisterPort(_in_client_jackport);
+ if(_out_client_jackport)
+ audioDevice->unregisterPort(_out_client_jackport);
+
//close();
}
@@ -179,7 +197,8 @@ int MidiJackDevice::selectWfd()
//---------------------------------------------------------
//QString MidiJackDevice::createJackMidiDevice(int rwflags) // 1:Writable 2: Readable. Do not mix.
-MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1:Writable 2: Readable. Do not mix.
+//MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1:Writable 2: Readable. Do not mix.
+MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // p3.3.55 1:Writable 2: Readable 3: Writable + Readable
{
/// _openFlags &= _rwFlags; // restrict to available bits
@@ -210,14 +229,36 @@ MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1
// }
//}
- jack_port_t* client_jackport = NULL;
+ //jack_port_t* client_jackport = NULL;
+ // p3.3.55
+ ///jack_port_t* in_client_jackport = NULL;
+ ///jack_port_t* out_client_jackport = NULL;
+
//char buf[80];
+
+ // p3.3.55
+ int ni = 0;
+ if(name.isEmpty())
+ {
+ for( ; ni < 65536; ++ni)
+ {
+ name.sprintf("jack-midi-%d", ni);
+ if(!midiDevices.find(name))
+ break;
+ }
+ }
+ if(ni >= 65536)
+ {
+ fprintf(stderr, "MusE: createJackMidiDevice failed! Can't find an unused midi device name 'jack-midi-[0-65535]'.\n");
+ return 0;
+ }
// If Jack port can receive data from us and we actually want to...
//if((pf & JackPortIsInput) && (_openFlags & 1))
- if(rwflags & 1)
- {
+ ///if(rwflags & 1)
+ ///{
+ /* p3.3.55 Removed.
if(name.isEmpty())
{
//snprintf(buf, 80, "muse-jack-midi-out-%d", _nextOutIdNum);
@@ -234,8 +275,10 @@ MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1
//client_jackport = (jack_port_t*)audioDevice->registerOutPort(buf, true);
if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO) // p3.3.52
{
- client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.latin1(), true);
- if(client_jackport)
+ //client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.latin1(), true);
+ out_client_jackport = (jack_port_t*)audioDevice->registerOutPort((name + QString("_out")).latin1(), true); // p3.3.55
+ //if(client_jackport)
+ if(out_client_jackport) // p3.3.55
break;
}
else
@@ -251,17 +294,27 @@ MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1
//name = QString(buf);
}
else
+ */
+
+ /*
{
if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO) // p3.3.52
{
- client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.latin1(), true);
- if(!client_jackport)
+ //client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.latin1(), true);
+ out_client_jackport = (jack_port_t*)audioDevice->registerOutPort((name + QString(JACK_MIDI_OUT_PORT_SUFFIX)).latin1(), true); // p3.3.55
+ //if(!client_jackport)
+ if(!out_client_jackport) // p3.3.55
{
- fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed creating output port name %s\n", name.latin1());
- return 0;
+ //fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed creating output port name %s\n", name.latin1());
+ fprintf(stderr, "MusE: createJackMidiDevice failed creating output port name %s\n", (name + QString(JACK_MIDI_OUT_PORT_SUFFIX)).latin1()); // p3.3.55
+
+ //return 0;
+ rwflags &= ~1; // p3.3.55 Remove the output r/w flag, but continue on...
}
}
}
+ */
+
/*
else
{
@@ -298,12 +351,14 @@ MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1
//else
// _nextOutIdNum++;
- }
- else // Note docs say it can't be both input and output.
+ ///}
+ //else // Note docs say it can't be both input and output. // p3.3.55 Removed
+
// If Jack port can send data to us and we actually want it...
//if((pf & JackPortIsOutput) && (_openFlags & 2))
- if(rwflags & 2)
- {
+ ///if(rwflags & 2)
+ ///{
+ /* p3.3.55 Removed.
if(name.isEmpty())
{
//snprintf(buf, 80, "muse-jack-midi-in-%d", _nextInIdNum);
@@ -320,8 +375,10 @@ MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1
//client_jackport = (jack_port_t*)audioDevice->registerInPort(buf, true);
if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO) // p3.3.52
{
- client_jackport = (jack_port_t*)audioDevice->registerInPort(name.latin1(), true);
- if(client_jackport)
+ //client_jackport = (jack_port_t*)audioDevice->registerInPort(name.latin1(), true);
+ in_client_jackport = (jack_port_t*)audioDevice->registerInPort(name.latin1(), true); // p3.3.55
+ //if(client_jackport)
+ if(in_client_jackport) // p3.3.55
break;
}
else
@@ -337,17 +394,26 @@ MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1
//name = QString(buf);
}
else
+ */
+
+ /*
{
if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO) // p3.3.52
{
- client_jackport = (jack_port_t*)audioDevice->registerInPort(name.latin1(), true);
- if(!client_jackport)
+ //client_jackport = (jack_port_t*)audioDevice->registerInPort(name.latin1(), true);
+ in_client_jackport = (jack_port_t*)audioDevice->registerInPort((name + QString(JACK_MIDI_IN_PORT_SUFFIX)).latin1(), true); // p3.3.55
+ //if(!client_jackport)
+ if(!in_client_jackport) // p3.3.55
{
- fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed creating input port name %s\n", name.latin1());
- return 0;
+ //fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed creating input port name %s\n", name.latin1());
+ fprintf(stderr, "MusE: createJackMidiDevice failed creating input port name %s\n", (name + QString(JACK_MIDI_IN_PORT_SUFFIX)).latin1());
+
+ //return 0;
+ rwflags &= ~2; // p3.3.55 Remove the input r/w flag, but continue on...
}
}
}
+ */
//client_jackport = (jack_port_t*)audioDevice->registerInPort(name.latin1(), true);
@@ -361,12 +427,15 @@ MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1
//else
// _nextInIdNum++;
- }
+ ///}
//if(client_jackport == NULL) // p3.3.52 Removed. Allow the device to be created even if Jack isn't running.
// return 0;
- MidiJackDevice* dev = new MidiJackDevice(client_jackport, name);
+ //MidiJackDevice* dev = new MidiJackDevice(client_jackport, name);
+ //MidiJackDevice* dev = new MidiJackDevice(in_client_jackport, out_client_jackport, name); // p3.3.55
+ //MidiJackDevice* dev = new MidiJackDevice(NULL, NULL, name); // p3.3.55
+ MidiJackDevice* dev = new MidiJackDevice(name); // p3.3.55
dev->setrwFlags(rwflags);
midiDevices.add(dev);
return dev;
@@ -382,8 +451,14 @@ void MidiJackDevice::setName(const QString& s)
printf("MidiJackDevice::setName %s new name:%s\n", name().latin1(), s.latin1());
#endif
_name = s;
- if(clientPort()) // p3.3.52 Added check.
- audioDevice->setPortName(clientPort(), s.latin1());
+
+ //if(clientPort()) // p3.3.52 Added check.
+ // audioDevice->setPortName(clientPort(), s.latin1());
+ // p3.3.55
+ if(inClientPort())
+ audioDevice->setPortName(inClientPort(), (s + QString(JACK_MIDI_IN_PORT_SUFFIX)).latin1());
+ if(outClientPort())
+ audioDevice->setPortName(outClientPort(), (s + QString(JACK_MIDI_OUT_PORT_SUFFIX)).latin1());
}
//---------------------------------------------------------
@@ -454,6 +529,84 @@ QString MidiJackDevice::open()
}
*/
+
+ QString s;
+ // p3.3.55 Moved from createJackMidiDevice()
+ if(_openFlags & 1)
+ {
+ if(!_out_client_jackport)
+ {
+ if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO)
+ {
+ s = name() + QString(JACK_MIDI_OUT_PORT_SUFFIX);
+ _out_client_jackport = (jack_port_t*)audioDevice->registerOutPort(s.latin1(), true);
+ if(!_out_client_jackport)
+ {
+ fprintf(stderr, "MusE: MidiJackDevice::open failed creating output port name %s\n", s.latin1());
+ _openFlags &= ~1; // Remove the flag, but continue on...
+ }
+ }
+ }
+ }
+ else
+ {
+ if(_out_client_jackport)
+ {
+ // We want to unregister the port (which will also disconnect it), AND remove Routes, and then NULL-ify _out_client_jackport.
+ // We could let our graph change callback (the gui thread one) remove the Routes (which it would anyway).
+ // But that happens later (gui thread) and it needs a valid _out_client_jackport,
+ // so use of a registration callback would be required to finally NULL-ify _out_client_jackport,
+ // and that would require some MidiDevice setter or re-scanner function.
+ // So instead, manually remove the Routes (in the audio thread), then unregister the port, then immediately NULL-ify _out_client_jackport.
+ // Our graph change callback (the gui thread one) will see a NULL _out_client_jackport
+ // so it cannot possibly remove the Routes, but that won't matter - we are removing them manually.
+ // This is the same technique that is used for audio elsewhere in the code, like Audio::msgSetChannels()
+ // (but not Song::connectJackRoutes() which keeps the Routes for when undoing deletion of a track).
+ //
+ // NOTE: TESTED: Possibly a bug in QJackCtl, with Jack-1 (not Jack-2 !):
+ // After toggling the input/output green lights in the midi ports list (which gets us here), intermittently
+ // qjackctl refuses to draw connections. It allows them to be made (MusE responds) but blanks them out immediately
+ // and does not show 'disconnect', as if it is not properly aware of the connections.
+ // But ALL else is OK - the connection is fine in MusE, verbose Jack messages show all went OK.
+ // Yes, there's no doubt the connections are being made.
+ // When I toggle the lights again (which kills, then recreates the ports here), the problem can disappear or come back again.
+ // Also once observed a weird double connection from the port to two different Jack ports but one of
+ // the connections should not have been there and kept toggling along with the other (like a 'ghost' connection).
+ audio->msgRemoveRoutes(Route(this, 0), Route()); // New function msgRemoveRoutes simply uses Routes, for their pointers.
+ audioDevice->unregisterPort(_out_client_jackport);
+ }
+ _out_client_jackport = NULL;
+ }
+
+ if(_openFlags & 2)
+ {
+ if(!_in_client_jackport)
+ {
+ if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO)
+ {
+ s = name() + QString(JACK_MIDI_IN_PORT_SUFFIX);
+ _in_client_jackport = (jack_port_t*)audioDevice->registerInPort(s.latin1(), true);
+ if(!_in_client_jackport)
+ {
+ fprintf(stderr, "MusE: MidiJackDevice::open failed creating input port name %s\n", s.latin1());
+ _openFlags &= ~2; // Remove the flag, but continue on...
+ }
+ }
+ }
+ }
+ else
+ {
+ if(_in_client_jackport)
+ {
+ audio->msgRemoveRoutes(Route(), Route(this, 0));
+ audioDevice->unregisterPort(_in_client_jackport);
+ }
+ _in_client_jackport = NULL;
+ }
+
+ //if(client_jackport == NULL) // p3.3.52 Removed. Allow the device to be created even if Jack isn't running.
+ // return 0;
+
_writeEnable = bool(_openFlags & 1);
_readEnable = bool(_openFlags & 2);
@@ -470,6 +623,11 @@ void MidiJackDevice::close()
printf("MidiJackDevice::close %s\n", name().latin1());
#endif
+ // p3.3.55 TODO: I don't really want to unregister the
+ // Jack midi ports because then we lose the connections
+ // to Jack every time we click the read/write lights
+ // or change a port's device.
+
/*
if(_client_jackport)
{
@@ -960,9 +1118,12 @@ void MidiJackDevice::collectMidiEvents()
if(!_readEnable)
return;
- if(!_client_jackport)
+ //if(!_client_jackport)
+ if(!_in_client_jackport) // p3.3.55
return;
- void* port_buf = jack_port_get_buffer(_client_jackport, segmentSize);
+
+ //void* port_buf = jack_port_get_buffer(_client_jackport, segmentSize);
+ void* port_buf = jack_port_get_buffer(_in_client_jackport, segmentSize); // p3.3.55
jack_midi_event_t event;
jack_nframes_t eventCount = jack_midi_get_event_count(port_buf);
@@ -1024,9 +1185,11 @@ bool MidiJackDevice::queueEvent(const MidiPlayEvent& e)
//if(debugMsg)
// printf("MidiJackDevice::queueEvent\n");
- if(!_client_jackport)
+ //if(!_client_jackport)
+ if(!_out_client_jackport) // p3.3.55
return false;
- void* pb = jack_port_get_buffer(_client_jackport, segmentSize);
+ //void* pb = jack_port_get_buffer(_client_jackport, segmentSize);
+ void* pb = jack_port_get_buffer(_out_client_jackport, segmentSize); // p3.3.55
//unsigned frameCounter = ->frameTime();
int frameOffset = audio->getFrameOffset();
@@ -1343,9 +1506,11 @@ void MidiJackDevice::processEvent(const MidiPlayEvent& event)
void MidiJackDevice::processMidi()
{
- if(!_client_jackport)
+ //if(!_client_jackport)
+ if(!_out_client_jackport) // p3.3.55
return;
- void* port_buf = jack_port_get_buffer(_client_jackport, segmentSize);
+ //void* port_buf = jack_port_get_buffer(_client_jackport, segmentSize);
+ void* port_buf = jack_port_get_buffer(_out_client_jackport, segmentSize); // p3.3.55
jack_midi_clear_buffer(port_buf);
while(!eventFifo.isEmpty())
diff --git a/muse/muse/driver/jackmidi.h b/muse/muse/driver/jackmidi.h
index 12b967a9..f7b5eb94 100644
--- a/muse/muse/driver/jackmidi.h
+++ b/muse/muse/driver/jackmidi.h
@@ -27,11 +27,11 @@ class Xml;
// Turn on to show multiple devices, work in progress,
// not working fully yet, can't seem to connect...
-#define JACK_MIDI_SHOW_MULTIPLE_DEVICES
+//#define JACK_MIDI_SHOW_MULTIPLE_DEVICES
// It appears one client port per remote port will be necessary.
// Jack doesn't seem to like manipulation of non-local ports buffers.
-#define JACK_MIDI_USE_MULTIPLE_CLIENT_PORTS
+//#define JACK_MIDI_USE_MULTIPLE_CLIENT_PORTS
/* jack-midi channels */
//#define JACK_MIDI_CHANNELS 32
@@ -98,7 +98,11 @@ class MidiJackDevice : public MidiDevice {
//static int _nextOutIdNum;
//static int _nextInIdNum;
- jack_port_t* _client_jackport;
+ //jack_port_t* _client_jackport;
+ // p3.3.55
+ jack_port_t* _in_client_jackport;
+ jack_port_t* _out_client_jackport;
+
//RouteList _routes;
virtual QString open();
@@ -115,11 +119,15 @@ class MidiJackDevice : public MidiDevice {
void eventReceived(jack_midi_event_t*);
public:
- MidiJackDevice() {}
+ //MidiJackDevice() {} // p3.3.55 Removed.
//MidiJackDevice(const int&, const QString& name);
- MidiJackDevice(jack_port_t* jack_port, const QString& name);
- static MidiDevice* createJackMidiDevice(QString /*name*/, int /*rwflags*/); // 1:Writable 2: Readable. Do not mix.
+ //MidiJackDevice(jack_port_t* jack_port, const QString& name);
+ //MidiJackDevice(jack_port_t* in_jack_port, jack_port_t* out_jack_port, const QString& name); // p3.3.55 In or out port can be null.
+ MidiJackDevice(const QString& name);
+
+ //static MidiDevice* createJackMidiDevice(QString /*name*/, int /*rwflags*/); // 1:Writable 2: Readable. Do not mix.
+ static MidiDevice* createJackMidiDevice(QString name = "", int rwflags = 3); // p3.3.55 1:Writable 2: Readable 3: Writable + Readable
virtual inline int deviceType() { return JACK_MIDI; }
@@ -138,7 +146,11 @@ class MidiJackDevice : public MidiDevice {
//virtual jack_port_t* jackPort() { return _jackport; }
//virtual jack_port_t* clientJackPort() { return _client_jackport; }
- virtual void* clientPort() { return (void*)_client_jackport; }
+
+ //virtual void* clientPort() { return (void*)_client_jackport; }
+ // p3.3.55
+ virtual void* inClientPort() { return (void*) _in_client_jackport; }
+ virtual void* outClientPort() { return (void*) _out_client_jackport; }
//RouteList* routes() { return &_routes; }
//bool noRoute() const { return _routes.empty(); }
diff --git a/muse/muse/globals.h b/muse/muse/globals.h
index e851264b..e3f13a06 100644
--- a/muse/muse/globals.h
+++ b/muse/muse/globals.h
@@ -181,6 +181,10 @@ extern RouteMenuMap gRoutingMenuMap;
// Whether the routes popup was shown by clicking the output routes button, or input routes button.
extern bool gIsOutRoutingPopupMenu;
+// p3.3.55
+#define JACK_MIDI_OUT_PORT_SUFFIX "_out"
+#define JACK_MIDI_IN_PORT_SUFFIX "_in"
+
extern uid_t euid, ruid;
extern void doSetuid();
extern void undoSetuid();
diff --git a/muse/muse/mididev.h b/muse/muse/mididev.h
index 1b2cf055..2bb5d727 100644
--- a/muse/muse/mididev.h
+++ b/muse/muse/mididev.h
@@ -71,7 +71,11 @@ class MidiDevice {
virtual int deviceType() = 0;
- virtual void* clientPort() { return 0; }
+ //virtual void* clientPort() { return 0; }
+ // p3.3.55
+ virtual void* inClientPort() { return 0; }
+ virtual void* outClientPort() { return 0; }
+
virtual QString open() = 0;
virtual void close() = 0;
virtual void writeRouting(int, Xml&) const { };
diff --git a/muse/muse/route.cpp b/muse/muse/route.cpp
index f0442547..55b30a7d 100644
--- a/muse/muse/route.cpp
+++ b/muse/muse/route.cpp
@@ -922,6 +922,36 @@ void removeRoute(Route src, Route dst)
}
//---------------------------------------------------------
+// removeAllRoutes
+// If src is valid, disconnects all output routes from it.
+// If dst is valid, disconnects all input routes to it.
+// src and dst Route are used SIMPLY because Route provides convenient way to
+// specify the different pointer types (track, port, jack)
+// This routine will ONLY look at the pointer, not the channel or port etc...
+// So far it only works with MidiDevice <-> Jack.
+//---------------------------------------------------------
+
+// p3.3.55
+void removeAllRoutes(Route src, Route dst)
+{
+ if(src.isValid())
+ {
+ if(src.type == Route::MIDI_DEVICE_ROUTE)
+ src.device->outRoutes()->clear();
+ else
+ printf("removeAllRoutes: source is not midi device\n");
+ }
+
+ if(dst.isValid())
+ {
+ if(dst.type == Route::MIDI_DEVICE_ROUTE)
+ dst.device->inRoutes()->clear();
+ else
+ printf("removeAllRoutes: dest is not midi device\n");
+ }
+}
+
+//---------------------------------------------------------
// track2name
// create string name representation for audio node
//---------------------------------------------------------
@@ -955,9 +985,14 @@ QString Route::name() const
{
if(device)
{
+ // p3.3.55 Removed for unified jack in/out devices, the actual port names are now different from device name.
+ // Like this: device: "MyJackDevice1" -> inport: "MyJackDevice1_in" outport: "MyJackDevice1_out"
+ /*
if(device->deviceType() == MidiDevice::JACK_MIDI)
return audioDevice->portName(device->clientPort());
else
+ */
+
//if(device->deviceType() == MidiDevice::ALSA_MIDI)
return device->name();
}
@@ -1553,7 +1588,17 @@ void Route::dump() const
if(device->deviceType() == MidiDevice::JACK_MIDI)
{
if(checkAudioDevice())
- printf("jack midi port device <%s> ", audioDevice->portName(device->clientPort()).latin1());
+ //printf("jack midi port device <%s> ", audioDevice->portName(device->clientPort()).latin1());
+ // p3.3.55
+ {
+ printf("jack midi device <%s> ", device->name().latin1());
+ if(device->inClientPort())
+ printf("input port <%s> ",
+ audioDevice->portName(device->inClientPort()).latin1());
+ if(device->outClientPort())
+ printf("output port <%s> ",
+ audioDevice->portName(device->outClientPort()).latin1());
+ }
}
else
if(device->deviceType() == MidiDevice::ALSA_MIDI)
@@ -1599,8 +1644,10 @@ bool Route::operator==(const Route& a) const
{
if (type == JACK_ROUTE)
{
- if (!checkAudioDevice()) return false;
- return audioDevice->portName(jackPort) == audioDevice->portName(a.jackPort);
+ //if (!checkAudioDevice()) return false;
+ //return audioDevice->portName(jackPort) == audioDevice->portName(a.jackPort);
+ // p3.3.55 Simplified.
+ return jackPort == a.jackPort;
}
else
if (type == MIDI_PORT_ROUTE) // p3.3.49
@@ -1610,6 +1657,9 @@ bool Route::operator==(const Route& a) const
else
if (type == MIDI_DEVICE_ROUTE)
{
+ // p3.3.55 Changed for unified jack in/out devices, the actual port names are now different from device name.
+ // Like this: device: "MyJackDevice1" -> inport: "MyJackDevice1_in" outport: "MyJackDevice1_out"
+ /*
if(device && a.device && device->deviceType() == a.device->deviceType())
{
if(device->deviceType() == MidiDevice::JACK_MIDI)
@@ -1625,6 +1675,8 @@ bool Route::operator==(const Route& a) const
if(device->deviceType() == MidiDevice::SYNTH_MIDI)
return device->name() == a.device->name();
}
+ */
+ return device == a.device;
}
}
}
diff --git a/muse/muse/route.h b/muse/muse/route.h
index 4cacac88..2f29bcf8 100644
--- a/muse/muse/route.h
+++ b/muse/muse/route.h
@@ -85,6 +85,7 @@ typedef RouteList::const_iterator ciRoute;
extern void addRoute(Route, Route);
extern void removeRoute(Route, Route);
+extern void removeAllRoutes(Route, Route); // p3.3.55
extern Route name2route(const QString&, bool dst, int rtype = -1);
extern bool checkRoute(const QString&, const QString&);
diff --git a/muse/muse/seqmsg.cpp b/muse/muse/seqmsg.cpp
index 58944552..83161996 100644
--- a/muse/muse/seqmsg.cpp
+++ b/muse/muse/seqmsg.cpp
@@ -89,7 +89,8 @@ void Audio::msgRemoveRoute(Route src, Route dst)
if(dst.device)
{
if(dst.device->deviceType() == MidiDevice::JACK_MIDI)
- audioDevice->disconnect(src.jackPort, dst.device->clientPort());
+ //audioDevice->disconnect(src.jackPort, dst.device->clientPort());
+ audioDevice->disconnect(src.jackPort, dst.device->inClientPort()); // p3.3.55
//else
//{
// TODO...
@@ -113,7 +114,8 @@ void Audio::msgRemoveRoute(Route src, Route dst)
if(src.device)
{
if(src.device->deviceType() == MidiDevice::JACK_MIDI)
- audioDevice->disconnect(src.device->clientPort(), dst.jackPort);
+ //audioDevice->disconnect(src.device->clientPort(), dst.jackPort);
+ audioDevice->disconnect(src.device->outClientPort(), dst.jackPort); // p3.3.55
//else
//{
// TODO...
@@ -141,6 +143,86 @@ void Audio::msgRemoveRoute1(Route src, Route dst)
}
//---------------------------------------------------------
+// msgRemoveRoutes
+//---------------------------------------------------------
+
+// p3.3.55
+void Audio::msgRemoveRoutes(Route src, Route dst)
+{
+ msgRemoveRoutes1(src, dst);
+
+ // TODO
+ /*
+ //if (!checkAudioDevice()) return;
+ if (src.type == Route::JACK_ROUTE)
+ {
+ if (!checkAudioDevice()) return;
+
+ //if(dst.type == Route::JACK_MIDI_ROUTE)
+ if(dst.type == Route::MIDI_DEVICE_ROUTE)
+ {
+ //MidiJackDevice* jmd = dynamic_cast<MidiJackDevice*>(dst.device);
+ //if(jmd)
+ if(dst.device)
+ {
+ if(dst.device->deviceType() == MidiDevice::JACK_MIDI)
+ //audioDevice->disconnect(src.jackPort, dst.device->clientPort());
+ audioDevice->disconnect(src.jackPort, dst.device->inClientPort());
+ //else
+ //{
+ // TODO...
+ //MidiAlsaDevice* amd = dynamic_cast<MidiAlsaDevice*>(dst.device);
+ //if(amd)
+ //}
+ }
+ }
+ else
+ audioDevice->disconnect(src.jackPort, ((AudioInput*)dst.track)->jackPort(dst.channel));
+ }
+ else if (dst.type == Route::JACK_ROUTE)
+ {
+ if (!checkAudioDevice()) return;
+
+ //if(src.type == Route::JACK_MIDI_ROUTE)
+ if(src.type == Route::MIDI_DEVICE_ROUTE)
+ {
+ //MidiJackDevice* jmd = dynamic_cast<MidiJackDevice*>(src.device);
+ //if(jmd)
+ if(src.device)
+ {
+ if(src.device->deviceType() == MidiDevice::JACK_MIDI)
+ //audioDevice->disconnect(src.device->clientPort(), dst.jackPort);
+ audioDevice->disconnect(src.device->outClientPort(), dst.jackPort);
+ //else
+ //{
+ // TODO...
+ //MidiAlsaDevice* amd = dynamic_cast<MidiAlsaDevice*>(src.device);
+ //if(amd)
+ //}
+ }
+ }
+ else
+ audioDevice->disconnect(((AudioOutput*)src.track)->jackPort(src.channel), dst.jackPort);
+ }
+
+ */
+}
+
+//---------------------------------------------------------
+// msgRemoveRoutes1
+//---------------------------------------------------------
+
+// p3.3.55
+void Audio::msgRemoveRoutes1(Route src, Route dst)
+ {
+ AudioMsg msg;
+ msg.id = AUDIO_REMOVEROUTES;
+ msg.sroute = src;
+ msg.droute = dst;
+ sendMsg(&msg);
+ }
+
+//---------------------------------------------------------
// msgAddRoute
//---------------------------------------------------------
@@ -159,7 +241,8 @@ void Audio::msgAddRoute(Route src, Route dst)
if(dst.device)
{
if(dst.device->deviceType() == MidiDevice::JACK_MIDI)
- audioDevice->connect(src.jackPort, dst.device->clientPort());
+ //audioDevice->connect(src.jackPort, dst.device->clientPort());
+ audioDevice->connect(src.jackPort, dst.device->inClientPort()); // p3.3.55
//else
//{
// TODO...
@@ -185,7 +268,8 @@ void Audio::msgAddRoute(Route src, Route dst)
if(src.device)
{
if(src.device->deviceType() == MidiDevice::JACK_MIDI)
- audioDevice->connect(src.device->clientPort(), dst.jackPort);
+ //audioDevice->connect(src.device->clientPort(), dst.jackPort);
+ audioDevice->connect(src.device->outClientPort(), dst.jackPort); // p3.3.55
//else
//{
// TODO...