19 #include "JackNetManager.h"    20 #include "JackArgParser.h"    21 #include "JackServerGlobals.h"    22 #include "JackLockedEngine.h"    31     JackNetMaster::JackNetMaster(JackNetSocket& socket, session_params_t& params, 
const char* multicast_ip)
    32             : JackNetMasterInterface(params, socket, multicast_ip)
    34         jack_log(
"JackNetMaster::JackNetMaster");
    37         fName = const_cast<char*>(fParams.fName);
    39         fSendTransportData.fState = -1;
    40         fReturnTransportData.fState = -1;
    41         fLastTransportState = -1;
    45         fAudioCapturePorts = 
new jack_port_t* [fParams.fSendAudioChannels];
    46         for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) {
    47             fAudioCapturePorts[port_index] = NULL;
    50         fAudioPlaybackPorts = 
new jack_port_t* [fParams.fReturnAudioChannels];
    51         for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) {
    52             fAudioPlaybackPorts[port_index] = NULL;
    56         fMidiCapturePorts = 
new jack_port_t* [fParams.fSendMidiChannels];
    57         for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) {
    58             fMidiCapturePorts[port_index] = NULL;
    61         fMidiPlaybackPorts = 
new jack_port_t* [fParams.fReturnMidiChannels];
    62         for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) {
    63             fMidiPlaybackPorts[port_index] = NULL;
    68         fPeriodUsecs = (int)(1000000.f * ((
float) fParams.fPeriodSize / (
float) fParams.fSampleRate));
    70         plot_name = string(fParams.fName);
    71         plot_name += string(
"_master");
    72         plot_name += string((fParams.fSlaveSyncMode) ? 
"_sync" : 
"_async");
    73         plot_name += string(
"_latency");
    74         fNetTimeMon = 
new JackGnuPlotMonitor<float>(128, 4, plot_name);
    75         string net_time_mon_fields[] =
    78             string(
"end of send"),
    80             string(
"end of cycle")
    82         string net_time_mon_options[] =
    84             string(
"set xlabel \"audio cycles\""),
    85             string(
"set ylabel \"% of audio cycle\"")
    87         fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 4);
    91     JackNetMaster::~JackNetMaster()
    93         jack_log(
"JackNetMaster::~JackNetMaster ID = %u", fParams.fID);
   100         delete[] fAudioCapturePorts;
   101         delete[] fAudioPlaybackPorts;
   102         delete[] fMidiCapturePorts;
   103         delete[] fMidiPlaybackPorts;
   110     bool JackNetMaster::Init(
bool auto_connect)
   113         if (!JackNetMasterInterface::Init()) {
   114             jack_error(
"JackNetMasterInterface::Init() error...");
   125         jack_status_t status;
   126         if ((fClient = 
jack_client_open(fName, JackNullOption, &status, NULL)) == NULL) {
   143         if (jack_set_latency_callback(fClient, LatencyCallback, 
this) < 0) {
   153         if (AllocPorts() != 0) {
   181     int JackNetMaster::AllocPorts()
   185         jack_log(
"JackNetMaster::AllocPorts");
   188         for (i = 0; i < fParams.fSendAudioChannels; i++) {
   189             snprintf(name, 
sizeof(name), 
"to_slave_%d", i+1);
   190             if ((fAudioCapturePorts[i] = 
jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0)) == NULL) {
   195         for (i = 0; i < fParams.fReturnAudioChannels; i++) {
   196             snprintf(name, 
sizeof(name), 
"from_slave_%d", i+1);
   197             if ((fAudioPlaybackPorts[i] = 
jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0)) == NULL) {
   203         for (i = 0; i < fParams.fSendMidiChannels; i++) {
   204             snprintf(name, 
sizeof(name), 
"midi_to_slave_%d", i+1);
   205             if ((fMidiCapturePorts[i] = 
jack_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0)) == NULL) {
   210         for (i = 0; i < fParams.fReturnMidiChannels; i++) {
   211             snprintf(name, 
sizeof(name), 
"midi_from_slave_%d", i+1);
   212             if ((fMidiPlaybackPorts[i] = 
jack_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE,  JackPortIsOutput | JackPortIsTerminal, 0)) == NULL) {
   219     void JackNetMaster::ConnectPorts()
   221         const char** ports = 
jack_get_ports(fClient, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput);
   223             for (
int i = 0; i < fParams.fSendAudioChannels && ports[i]; i++) {
   229         ports = 
jack_get_ports(fClient, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput);
   231             for (
int i = 0; i < fParams.fReturnAudioChannels && ports[i]; i++) {
   238     void JackNetMaster::FreePorts()
   240         jack_log(
"JackNetMaster::FreePorts ID = %u", fParams.fID);
   243         for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) {
   244             if (fAudioCapturePorts[port_index]) {
   248         for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) {
   249             if (fAudioPlaybackPorts[port_index]) {
   253         for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) {
   254             if (fMidiCapturePorts[port_index]) {
   258         for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) {
   259             if (fMidiPlaybackPorts[port_index]) {
   266     void JackNetMaster::EncodeTransportData()
   270         fSendTransportData.fTimebaseMaster = NO_CHANGE;
   273         fSendTransportData.fState = static_cast<uint>(
jack_transport_query(fClient, &fSendTransportData.fPosition));
   276         fSendTransportData.fNewState = ((fSendTransportData.fState != fLastTransportState) && (fSendTransportData.fState != fReturnTransportData.fState));
   277         if (fSendTransportData.fNewState) {
   278             jack_info(
"Sending '%s' to '%s' frame = %ld", GetTransportState(fSendTransportData.fState), fParams.fName, fSendTransportData.fPosition.
frame);
   280         fLastTransportState = fSendTransportData.fState;
   283     void JackNetMaster::DecodeTransportData()
   286         if (fReturnTransportData.fTimebaseMaster != NO_CHANGE) {
   289             switch (fReturnTransportData.fTimebaseMaster)
   291                 case RELEASE_TIMEBASEMASTER :
   296                         jack_info(
"'%s' isn't the timebase master anymore", fParams.fName);
   300                 case TIMEBASEMASTER :
   303                         jack_error(
"Can't set a new timebase master");
   305                         jack_info(
"'%s' is the new timebase master", fParams.fName);
   309                 case CONDITIONAL_TIMEBASEMASTER :
   311                     if (timebase != EBUSY) {
   313                             jack_error(
"Can't set a new timebase master");
   315                             jack_info(
"'%s' is the new timebase master", fParams.fName);
   322         if (fReturnTransportData.fNewState && (fReturnTransportData.fState != 
jack_transport_query(fClient, NULL))) {
   324             switch (fReturnTransportData.fState)
   326                 case JackTransportStopped :
   328                     jack_info(
"'%s' stops transport", fParams.fName);
   331                 case JackTransportStarting :
   335                     jack_info(
"'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.
frame);
   338                 case JackTransportNetStarting :
   339                     jack_info(
"'%s' is ready to roll...", fParams.fName);
   342                 case JackTransportRolling :
   343                     jack_info(
"'%s' is rolling", fParams.fName);
   349     void JackNetMaster::SetTimebaseCallback(jack_transport_state_t state, jack_nframes_t nframes, 
jack_position_t* pos, 
int new_pos, 
void* arg)
   351         static_cast<JackNetMaster*>(arg)->TimebaseCallback(pos);
   356         pos->
bar = fReturnTransportData.fPosition.
bar;
   357         pos->
beat = fReturnTransportData.fPosition.
beat;
   358         pos->
tick = fReturnTransportData.fPosition.
tick;
   359         pos->bar_start_tick = fReturnTransportData.fPosition.bar_start_tick;
   362         pos->ticks_per_beat = fReturnTransportData.fPosition.ticks_per_beat;
   363         pos->beats_per_minute = fReturnTransportData.fPosition.beats_per_minute;
   368     bool JackNetMaster::IsSlaveReadyToRoll()
   370         return (fReturnTransportData.fState == JackTransportNetStarting);
   373     int JackNetMaster::SetBufferSize(jack_nframes_t nframes, 
void* arg)
   375         JackNetMaster* obj = static_cast<JackNetMaster*>(arg);
   376         if (nframes != obj->fParams.fPeriodSize) {
   377             jack_error(
"Cannot currently handle buffer size change, so JackNetMaster proxy will be removed...");
   383     int JackNetMaster::SetSampleRate(jack_nframes_t nframes, 
void* arg)
   385         JackNetMaster* obj = static_cast<JackNetMaster*>(arg);
   386         if (nframes != obj->fParams.fSampleRate) {
   387             jack_error(
"Cannot currently handle sample rate change, so JackNetMaster proxy will be removed...");
   393     void JackNetMaster::LatencyCallback(jack_latency_callback_mode_t mode, 
void* arg)
   395         JackNetMaster* obj = static_cast<JackNetMaster*>(arg);
   400         for (
int i = 0; i < obj->fParams.fSendAudioChannels; i++) {
   402             range.
min = range.
max = float(obj->fParams.fNetworkLatency * port_latency) / 2.f;
   407         for (
int i = 0; i < obj->fParams.fReturnAudioChannels; i++) {
   409             range.
min = range.
max = float(obj->fParams.fNetworkLatency * port_latency) / 2.f + ((obj->fParams.fSlaveSyncMode) ? 0 : port_latency);
   414         for (
int i = 0; i < obj->fParams.fSendMidiChannels; i++) {
   416             range.
min = range.
max = float(obj->fParams.fNetworkLatency * port_latency) / 2.f;
   421         for (
int i = 0; i < obj->fParams.fReturnMidiChannels; i++) {
   423             range.
min = range.
max = obj->fParams.fNetworkLatency * port_latency + ((obj->fParams.fSlaveSyncMode) ? 0 : port_latency);
   429     int JackNetMaster::SetProcess(jack_nframes_t nframes, 
void* arg)
   432             return static_cast<JackNetMaster*>(arg)->Process();
   433         } 
catch (JackNetException& e) {
   438     void JackNetMaster::SetConnectCallback(jack_port_id_t a, jack_port_id_t b, 
int connect, 
void* arg)
   440         static_cast<JackNetMaster*>(arg)->ConnectCallback(a, b, connect);
   443     void JackNetMaster::ConnectCallback(jack_port_id_t a, jack_port_id_t b, 
int connect)
   445         jack_info(
"JackNetMaster::ConnectCallback a = %d b = %d connect = %d", a, b, connect);
   451     int JackNetMaster::Process()
   458         jack_time_t begin_time = GetMicroSeconds();
   463         for (
int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
   464             fNetMidiCaptureBuffer->SetBuffer(midi_port_index,
   466                                             fParams.fPeriodSize)));
   468         for (
int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
   470         #ifdef OPTIMIZED_PROTOCOL   471             if (fNetAudioCaptureBuffer->GetConnected(audio_port_index)) {
   473                 fNetAudioCaptureBuffer->SetBuffer(audio_port_index,
   475                                                 ? static_cast<sample_t*>(
jack_port_get_buffer(fAudioCapturePorts[audio_port_index], fParams.fPeriodSize))
   478                 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, NULL);
   481             fNetAudioCaptureBuffer->SetBuffer(audio_port_index,
   483                                             fParams.fPeriodSize)));
   488         for (
int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
   489             fNetMidiPlaybackBuffer->SetBuffer(midi_port_index,
   491                                                 fParams.fPeriodSize)));
   493         for (
int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
   495         #ifdef OPTIMIZED_PROTOCOL   497                 ? static_cast<sample_t*>(
jack_port_get_buffer(fAudioPlaybackPorts[audio_port_index], fParams.fPeriodSize))
   500                 memset(out, 0, 
sizeof(
float) * fParams.fPeriodSize);
   502             fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, out);
   504             sample_t* out = static_cast<sample_t*>(
jack_port_get_buffer(fAudioPlaybackPorts[audio_port_index], fParams.fPeriodSize));
   506                 memset(out, 0, 
sizeof(
float) * fParams.fPeriodSize);
   508             fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, out)));
   515         if (SyncSend() == SOCKET_ERROR) {
   520         fNetTimeMon->Add((((
float)(GetMicroSeconds() - begin_time)) / (
float) fPeriodUsecs) * 100.f);
   524         if (DataSend() == SOCKET_ERROR) {
   529         fNetTimeMon->Add((((
float)(GetMicroSeconds() - begin_time)) / (
float) fPeriodUsecs) * 100.f);
   533         int res = SyncRecv();
   540             case SYNC_PACKET_ERROR:
   547                 DecodeSyncPacket(unused_frames);
   552         fNetTimeMon->Add((((
float)(GetMicroSeconds() - begin_time)) / (
float) fPeriodUsecs) * 100.f);
   563             case DATA_PACKET_ERROR:
   565                 JackServerGlobals::fInstance->GetEngine()->NotifyClientXRun(ALL_CLIENTS);
   570         fNetTimeMon->AddLast((((
float)(GetMicroSeconds() - begin_time)) / (
float) fPeriodUsecs) * 100.f);
   575     void JackNetMaster::SaveConnections(connections_list_t& connections)
   578         for (
int i = 0; i < fParams.fSendAudioChannels; i++) {
   580             if (connected_port != NULL) {
   581                 for (
int port = 0; connected_port[port]; port++) {
   582                     connections.push_back(make_pair(connected_port[port], 
jack_port_name(fAudioCapturePorts[i])));
   585                 jack_free(connected_port);
   589         for (
int i = 0; i < fParams.fReturnAudioChannels; i++) {
   591             if (connected_port != NULL) {
   592                 for (
int port = 0; connected_port[port]; port++) {
   593                     connections.push_back(make_pair(
jack_port_name(fAudioPlaybackPorts[i]), connected_port[port]));
   596                 jack_free(connected_port);
   601         for (
int i = 0; i < fParams.fSendMidiChannels; i++) {
   603             if (connected_port != NULL) {
   604                 for (
int port = 0; connected_port[port]; port++) {
   605                     connections.push_back(make_pair(connected_port[port], 
jack_port_name(fMidiCapturePorts[i])));
   608                 jack_free(connected_port);
   612         for (
int i = 0; i < fParams.fReturnMidiChannels; i++) {
   614             if (connected_port != NULL) {
   615                 for (
int port = 0; connected_port[port]; port++) {
   616                     connections.push_back(make_pair(
jack_port_name(fMidiPlaybackPorts[i]), connected_port[port]));
   619                 jack_free(connected_port);
   624     void JackNetMaster::LoadConnections(
const connections_list_t& connections)
   626         list<pair<string, string> >::const_iterator it;
   627         for (it = connections.begin(); it != connections.end(); it++) {
   628             pair<string, string> connection = *it;
   629             jack_connect(fClient, connection.first.c_str(), connection.second.c_str());
   636     JackNetMasterManager::JackNetMasterManager(jack_client_t* client, 
const JSList* params) : fSocket()
   638         jack_log(
"JackNetMasterManager::JackNetMasterManager");
   644         fAutoConnect = 
false;
   653         const char* default_udp_port = getenv(
"JACK_NETJACK_PORT");
   654         fSocket.SetPort((default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT);
   656         const char* default_multicast_ip = getenv(
"JACK_NETJACK_MULTICAST");
   657         if (default_multicast_ip) {
   658             strcpy(fMulticastIP, default_multicast_ip);
   660             strcpy(fMulticastIP, DEFAULT_MULTICAST_IP);
   663         for (node = params; node; node = jack_slist_next(node)) {
   666             switch (param->character) {
   668                     if (strlen(param->value.str) < 32) {
   669                         strcpy(fMulticastIP, param->value.str);
   671                         jack_error(
"Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP);
   676                     fSocket.SetPort(param->value.ui);
   694             jack_error(
"Can't activate the NetManager client, transport disabled");
   699             jack_error(
"Can't create the NetManager control thread");
   703     JackNetMasterManager::~JackNetMasterManager()
   705         jack_log(
"JackNetMasterManager::~JackNetMasterManager");
   709     int JackNetMasterManager::CountIO(
const char* type, 
int flags)
   714             while (ports[count]) { count++; }
   720     void JackNetMasterManager::SetShutDown(
void* arg)
   722         static_cast<JackNetMasterManager*>(arg)->ShutDown();
   725     void JackNetMasterManager::ShutDown()
   727         jack_log(
"JackNetMasterManager::ShutDown");
   732         master_list_t::iterator it;
   733         for (it = fMasterList.begin(); it != fMasterList.end(); it++) {
   741     int JackNetMasterManager::SetSyncCallback(jack_transport_state_t state, 
jack_position_t* pos, 
void* arg)
   743         return static_cast<JackNetMasterManager*>(arg)->SyncCallback(state, pos);
   746     int JackNetMasterManager::SyncCallback(jack_transport_state_t state, 
jack_position_t* pos)
   751         for (it = fMasterList.begin(); it != fMasterList.end(); it++) {
   752             if (!(*it)->IsSlaveReadyToRoll()) {
   756         jack_log(
"JackNetMasterManager::SyncCallback returns '%s'", (res) ? 
"true" : 
"false");
   760     void* JackNetMasterManager::NetManagerThread(
void* arg)
   762         JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*>(arg);
   764         jack_info(
"Listening on '%s:%d'", master_manager->fMulticastIP, master_manager->fSocket.GetPort());
   765         master_manager->Run();
   769     void JackNetMasterManager::Run()
   771         jack_log(
"JackNetMasterManager::Run");
   776         session_params_t host_params;
   778         JackNetMaster* net_master;
   781         if (SocketAPIInit() < 0) {
   782             jack_error(
"Can't init Socket API, exiting...");
   787         if (fSocket.NewSocket() == SOCKET_ERROR) {
   788             jack_error(
"Can't create NetManager input socket : %s", StrError(NET_ERROR_CODE));
   793         if (fSocket.Bind() == SOCKET_ERROR) {
   794             jack_error(
"Can't bind NetManager socket : %s", StrError(NET_ERROR_CODE));
   800         if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) {
   801             jack_error(
"Can't join multicast group : %s", StrError(NET_ERROR_CODE));
   805         if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
   806             jack_error(
"Can't set local loop : %s", StrError(NET_ERROR_CODE));
   810         if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) {
   811             jack_error(
"Can't set timeout : %s", StrError(NET_ERROR_CODE));
   817             session_params_t net_params;
   818             rx_bytes = fSocket.CatchHost(&net_params, 
sizeof(session_params_t), 0);
   819             SessionParamsNToH(&net_params, &host_params);
   821             if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
   822                 jack_error(
"Error in receive : %s", StrError(NET_ERROR_CODE));
   823                 if (++attempt == 10) {
   824                     jack_error(
"Can't receive on the socket, exiting net manager");
   829             if (rx_bytes == 
sizeof(session_params_t)) {
   830                 switch (GetPacketType(&host_params))
   832                     case SLAVE_AVAILABLE:
   833                         if ((net_master = InitMaster(host_params))) {
   834                             SessionParamsDisplay(&net_master->fParams);
   841                         if (KillMaster(&host_params)) {
   853     JackNetMaster* JackNetMasterManager::InitMaster(session_params_t& params)
   855         jack_log(
"JackNetMasterManager::InitMaster slave : %s", params.fName);
   858         if (params.fProtocolVersion != NETWORK_PROTOCOL) {
   859             jack_error(
"Error : slave '%s' is running with a different protocol %d != %d", params.fName, params.fProtocolVersion, NETWORK_PROTOCOL);
   864         fSocket.GetName(params.fMasterNetName);
   865         params.fID = ++fGlobalID;
   869         if (params.fSendAudioChannels == -1) {
   870             params.fSendAudioChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput);
   871             jack_info(
"Takes physical %d audio input(s) for slave", params.fSendAudioChannels);
   874         if (params.fReturnAudioChannels == -1) {
   875             params.fReturnAudioChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput);
   876             jack_info(
"Takes physical %d audio output(s) for slave", params.fReturnAudioChannels);
   879         if (params.fSendMidiChannels == -1) {
   880             params.fSendMidiChannels = CountIO(JACK_DEFAULT_MIDI_TYPE, JackPortIsPhysical | JackPortIsOutput);
   881             jack_info(
"Takes physical %d MIDI input(s) for slave", params.fSendMidiChannels);
   884         if (params.fReturnMidiChannels == -1) {
   885             params.fReturnMidiChannels = CountIO(JACK_DEFAULT_MIDI_TYPE, JackPortIsPhysical | JackPortIsInput);
   886             jack_info(
"Takes physical %d MIDI output(s) for slave", params.fReturnMidiChannels);
   890         JackNetMaster* master = 
new JackNetMaster(fSocket, params, fMulticastIP);
   891         if (master->Init(fAutoConnect)) {
   892             fMasterList.push_back(master);
   893             if (fAutoSave && fMasterConnectionList.find(params.fName) != fMasterConnectionList.end()) {
   894                 master->LoadConnections(fMasterConnectionList[params.fName]);
   903     master_list_it_t JackNetMasterManager::FindMaster(uint32_t 
id)
   905         jack_log(
"JackNetMasterManager::FindMaster ID = %u", 
id);
   908         for (it = fMasterList.begin(); it != fMasterList.end(); it++) {
   909             if ((*it)->fParams.fID == 
id) {
   916     int JackNetMasterManager::KillMaster(session_params_t* params)
   918         jack_log(
"JackNetMasterManager::KillMaster ID = %u", params->fID);
   920         master_list_it_t master_it = FindMaster(params->fID);
   921         if (master_it != fMasterList.end()) {
   923                 fMasterConnectionList[params->fName].clear();
   924                 (*master_it)->SaveConnections(fMasterConnectionList[params->fName]);
   926             fMasterList.erase(master_it);
   947         desc = jack_driver_descriptor_construct(
"netmanager", JackDriverNone, 
"netjack multi-cast master component", &filler);
   949         strcpy(value.str, DEFAULT_MULTICAST_IP);
   950         jack_driver_descriptor_add_parameter(desc, &filler, 
"multicast-ip", 
'a', JackDriverParamString, &value, NULL, 
"Multicast address", NULL);
   952         value.i = DEFAULT_PORT;
   953         jack_driver_descriptor_add_parameter(desc, &filler, 
"udp-net-port", 
'p', JackDriverParamInt, &value, NULL, 
"UDP port", NULL);
   956         jack_driver_descriptor_add_parameter(desc, &filler, 
"auto-connect", 
'c', JackDriverParamBool, &value, NULL, 
"Auto connect netmaster to system ports", NULL);
   959         jack_driver_descriptor_add_parameter(desc, &filler, 
"auto-save", 
's', JackDriverParamBool, &value, NULL, 
"Save/restore netmaster connection state when restarted", NULL);
   964     SERVER_EXPORT 
int jack_internal_initialize(jack_client_t* jack_client, 
const JSList* params)
   966         if (master_manager) {
   972             return (master_manager) ? 0 : 1;
   976     SERVER_EXPORT 
int jack_initialize(jack_client_t* jack_client, 
const char* load_init)
   979         bool parse_params = 
true;
   984         if (parser.GetArgc() > 0) {
   985             parse_params = parser.ParseParams(desc, ¶ms);
   989             res = jack_internal_initialize(jack_client, params);
   990             parser.FreeParams(params);
   995     SERVER_EXPORT 
void jack_finish(
void* arg)
   997         if (master_manager) {
   998             jack_log(
"Unloading Master Manager");
   999             delete master_manager;
  1000             master_manager = NULL;
 
LIB_EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *)
LIB_EXPORT jack_port_t * jack_port_by_id(jack_client_t *client, jack_port_id_t port_id)
LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t *client, jack_position_t *pos)
LIB_EXPORT int jack_set_process_callback(jack_client_t *client, JackProcessCallback process_callback, void *arg)
LIB_EXPORT int jack_activate(jack_client_t *client)
SERVER_EXPORT void jack_error(const char *fmt,...)
LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
LIB_EXPORT int jack_connect(jack_client_t *, const char *source_port, const char *destination_port)
LIB_EXPORT jack_port_t * jack_port_register(jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size)
LIB_EXPORT int jack_release_timebase(jack_client_t *client)
LIB_EXPORT const char ** jack_port_get_all_connections(const jack_client_t *client, const jack_port_t *port)
SERVER_EXPORT void jack_info(const char *fmt,...)
LIB_EXPORT void jack_on_shutdown(jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg)
LIB_EXPORT jack_client_t * jack_client_open(const char *client_name, jack_options_t options, jack_status_t *status,...)
LIB_EXPORT char * jack_get_client_name(jack_client_t *client)
LIB_EXPORT void jack_transport_start(jack_client_t *client)
LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t *)
LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t *client, JackSampleRateCallback srate_callback, void *arg)
LIB_EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t)
LIB_EXPORT void jack_transport_stop(jack_client_t *client)
LIB_EXPORT int jack_client_create_thread(jack_client_t *client, jack_native_thread_t *thread, int priority, int realtime, thread_routine routine, void *arg)
LIB_EXPORT int jack_transport_reposition(jack_client_t *client, const jack_position_t *pos)
LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t *)
LIB_EXPORT int jack_set_timebase_callback(jack_client_t *client, int conditional, JackTimebaseCallback timebase_callback, void *arg)
LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t *client, JackBufferSizeCallback bufsize_callback, void *arg)
LIB_EXPORT int jack_set_sync_callback(jack_client_t *client, JackSyncCallback sync_callback, void *arg)
LIB_EXPORT int jack_port_connected(const jack_port_t *port)
LIB_EXPORT const char * jack_port_name(const jack_port_t *port)
LIB_EXPORT const char ** jack_get_ports(jack_client_t *, const char *port_name_pattern, const char *type_name_pattern, unsigned long flags)
LIB_EXPORT int jack_deactivate(jack_client_t *client)
SERVER_EXPORT void jack_log(const char *fmt,...)
LIB_EXPORT int jack_client_kill_thread(jack_client_t *client, jack_native_thread_t thread)
LIB_EXPORT int jack_client_close(jack_client_t *client)