diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index 99c42100..11f49750 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -28,6 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackLockedEngine.h" +#include "JackTime.h" #include #include @@ -471,27 +472,45 @@ bool JackDriver::Initialize() return true; } -void JackDriver::SaveConnections() +static string RemoveLast(const string& name) +{ + return name.substr(0, name.find_last_of(':')); // Remove end of name after last ":" +} + +void JackDriver::SaveConnections(int alias) { const char** connections; - fConnections.clear(); char alias1[REAL_JACK_PORT_NAME_SIZE]; char alias2[REAL_JACK_PORT_NAME_SIZE]; + char system_alias1[REAL_JACK_PORT_NAME_SIZE]; + char system_alias2[REAL_JACK_PORT_NAME_SIZE]; char* aliases[2]; + char* system_aliases[2]; aliases[0] = alias1; aliases[1] = alias2; - + + system_aliases[0] = system_alias1; + system_aliases[1] = system_alias2; + + fConnections.clear(); + for (int i = 0; i < fCaptureChannels; ++i) { if (fCapturePortList[i] && (connections = fGraphManager->GetConnections(fCapturePortList[i])) != 0) { - for (int j = 0; connections[j]; j++) { - /* + if (alias == 0) { + for (int j = 0; connections[j]; j++) { + fConnections.push_back(make_pair(fGraphManager->GetPort(fCapturePortList[i])->GetName(), connections[j])); + jack_info("Save connection: %s %s", fGraphManager->GetPort(fCapturePortList[i])->GetName(), connections[j]); + } + } else { fGraphManager->GetPort(fCapturePortList[i])->GetAliases(aliases); - fConnections.push_back(make_pair(aliases[0], connections[j])); - jack_info("Save connection: %s %s", aliases[0], connections[j]); - */ - fConnections.push_back(make_pair(string(fGraphManager->GetPort(fCapturePortList[i])->GetName()), string(connections[j]))); - jack_info("Save connection: %s %s", fGraphManager->GetPort(fCapturePortList[i])->GetName(), connections[j]); + string sub_name = RemoveLast(aliases[alias-1]); + for (int j = 0; connections[j]; j++) { + fGraphManager->GetPort(fGraphManager->GetPort(connections[j]))->GetAliases(system_aliases); + string sub_system_name = RemoveLast(system_aliases[alias-1]); + fConnections.push_back(make_pair(sub_name, sub_system_name)); + jack_info("Save connection: %s %s", sub_name.c_str(), sub_system_name.c_str()); + } } free(connections); } @@ -499,28 +518,80 @@ void JackDriver::SaveConnections() for (int i = 0; i < fPlaybackChannels; ++i) { if (fPlaybackPortList[i] && (connections = fGraphManager->GetConnections(fPlaybackPortList[i])) != 0) { - for (int j = 0; connections[j]; j++) { - /* + if (alias == 0) { + for (int j = 0; connections[j]; j++) { + fConnections.push_back(make_pair(fGraphManager->GetPort(fPlaybackPortList[i])->GetName(), connections[j])); + jack_info("Save connection: %s %s", fGraphManager->GetPort(fPlaybackPortList[i])->GetName(), connections[j]); + } + } else { fGraphManager->GetPort(fPlaybackPortList[i])->GetAliases(aliases); - fConnections.push_back(make_pair(connections[j], aliases[0])); - jack_info("Save connection: %s %s", connections[j], aliases[0]); - */ - fConnections.push_back(make_pair(string(connections[j]), string(fGraphManager->GetPort(fPlaybackPortList[i])->GetName()))); - jack_info("Save connection: %s %s", connections[j], fGraphManager->GetPort(fPlaybackPortList[i])->GetName()); + string sub_name = RemoveLast(aliases[alias-1]); + for (int j = 0; connections[j]; j++) { + fGraphManager->GetPort(fGraphManager->GetPort(connections[j]))->GetAliases(system_aliases); + string sub_system_name = RemoveLast(system_aliases[alias-1]); + fConnections.push_back(make_pair(sub_system_name, sub_name)); + jack_info("Save connection: %s %s", sub_system_name.c_str(), sub_name.c_str()); + } } free(connections); } } } -void JackDriver::RestoreConnections() +string JackDriver::MatchPortName(const char* name, const char** ports, int alias) { - list >::const_iterator it; + char alias1[REAL_JACK_PORT_NAME_SIZE]; + char alias2[REAL_JACK_PORT_NAME_SIZE]; + char* aliases[2]; + + aliases[0] = alias1; + aliases[1] = alias2; + + for (int i = 0; ports && ports[i]; ++i) { + fGraphManager->GetPort(fGraphManager->GetPort(ports[i]))->GetAliases(aliases); + if (string(aliases[alias-1]).find(name) != string::npos) { + return string(aliases[alias-1]); + } + } + + return ""; +} - for (it = fConnections.begin(); it != fConnections.end(); it++) { - pair connection = *it; - jack_info("Restore connection: %s %s", connection.first.c_str(), connection.second.c_str()); - fEngine->PortConnect(fClientControl.fRefNum, connection.first.c_str(), connection.second.c_str()); +void JackDriver::RestoreConnections(int alias, bool full_name) +{ + list >::const_iterator it; + + if (full_name) { + for (it = fConnections.begin(); it != fConnections.end(); it++) { + pair connection = *it; + jack_info("Restore connection: %s %s", connection.first.c_str(), connection.second.c_str()); + fEngine->PortConnect(fClientControl.fRefNum, connection.first.c_str(), connection.second.c_str()); + } + } else { + const char** inputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsInput); + const char** outputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsOutput); + + for (it = fConnections.begin(); it != fConnections.end(); it++) { + pair connection = *it; + string real_input = MatchPortName(connection.first.c_str(), outputs, alias); + string real_output = MatchPortName(connection.second.c_str(), inputs, alias); + if ((real_input != "") && (real_output != "")) { + jack_info("Restore connection: %s %s", real_input.c_str(), real_output.c_str()); + fEngine->PortConnect(fClientControl.fRefNum, real_input.c_str(), real_output.c_str()); + } + } + + // Wait for connection change + if (fGraphManager->IsPendingChange()) { + JackSleep(int(fEngineControl->fPeriodUsecs * 1.1f)); + } + + if (inputs) { + free(inputs); + } + if (outputs) { + free(outputs); + } } } @@ -534,5 +605,4 @@ int JackDriver::SuspendRefNum() return fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs); } - } // end of namespace diff --git a/common/JackDriver.h b/common/JackDriver.h index 3cc564b8..227eb843 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -182,8 +182,9 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface void NotifySampleRate(jack_nframes_t sample_rate); // SampleRate notification sent by the driver void NotifyFailure(int code, const char* reason); // Failure notification sent by the driver - virtual void SaveConnections(); - virtual void RestoreConnections(); + virtual void SaveConnections(int alias); + virtual void RestoreConnections(int alias, bool full_name = true); + std::string MatchPortName(const char* name, const char** ports, int alias); virtual int StartSlaves(); virtual int StopSlaves(); diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 0fe65fd1..90e0859f 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -110,7 +110,7 @@ namespace Jack bool JackNetDriver::Initialize() { jack_log("JackNetDriver::Initialize"); - SaveConnections(); + SaveConnections(0); FreePorts(); // New loading, but existing socket, restart the driver @@ -201,7 +201,7 @@ namespace Jack // Transport engine parametering fEngineControl->fTransport.SetNetworkSync(fParams.fTransportSync); - RestoreConnections(); + RestoreConnections(0); return true; } @@ -372,9 +372,9 @@ namespace Jack return 0; } - void JackNetDriver::SaveConnections() + void JackNetDriver::SaveConnections(int alias) { - JackDriver::SaveConnections(); + JackDriver::SaveConnections(alias); const char** connections; for (int i = 0; i < fParams.fSendMidiChannels; ++i) { diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index f664c2e1..015bef9c 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -63,7 +63,7 @@ namespace Jack JackMidiBuffer* GetMidiInputBuffer(int port_index); JackMidiBuffer* GetMidiOutputBuffer(int port_index); - void SaveConnections(); + void SaveConnections(int alias); void UpdateLatencies(); diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index dcefef44..1200d875 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -355,7 +355,7 @@ JackCoreMidiDriver::Attach() JackCoreMidiPort *port_obj; latency_range.max = latency; latency_range.min = latency; - + // Physical inputs for (int i = 0; i < num_physical_inputs; i++) { port_obj = physical_input_ports[i]; @@ -520,14 +520,16 @@ void JackCoreMidiDriver::Restart() { JackLock lock(this); - SaveConnections(); + // Use first alias + SaveConnections(1); Stop(); Detach(); CloseAux(); OpenAux(); Attach(); Start(); - RestoreConnections(); + // Use first alias and partial port naming + RestoreConnections(1, false); } void diff --git a/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp index ab6ada4c..4ed773f8 100644 --- a/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp @@ -49,9 +49,7 @@ JackCoreMidiVirtualInputPort(const char *alias_name, const char *client_name, size_t max_bytes, size_t max_messages): JackCoreMidiInputPort(time_ratio, max_bytes, max_messages) { - std::stringstream stream; - stream << "virtual" << (index + 1); - CFStringRef name = CFStringCreateWithCString(0, stream.str().c_str(), + CFStringRef name = CFStringCreateWithCString(0, "virtual", CFStringGetSystemEncoding()); if (! name) { throw std::bad_alloc(); diff --git a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp index e2cef747..0a87682e 100644 --- a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp @@ -35,9 +35,7 @@ JackCoreMidiVirtualOutputPort(const char *alias_name, const char *client_name, JackCoreMidiOutputPort(time_ratio, max_bytes, max_messages) { - std::stringstream stream; - stream << "virtual" << (index + 1); - CFStringRef name = CFStringCreateWithCString(0, stream.str().c_str(), + CFStringRef name = CFStringCreateWithCString(0, "virtual", CFStringGetSystemEncoding()); if (! name) { throw std::bad_alloc();