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)