21 #include "JackSystemDeps.h" 22 #include "JackGraphManager.h" 23 #include "JackClientControl.h" 24 #include "JackEngineControl.h" 25 #include "JackGlobals.h" 26 #include "JackChannel.h" 27 #include "JackTransportEngine.h" 28 #include "driver_interface.h" 29 #include "JackLibGlobals.h" 40 #define IsRealTime() ((fProcess != NULL) | (fThreadFun != NULL) | (fSync != NULL) | (fTimebase != NULL)) 42 JackClient::JackClient(JackSynchro* table):fThread(this)
44 fSynchroTable = table;
52 fClientRegistration = NULL;
54 fPortRegistration = NULL;
64 fGraphOrderArg = NULL;
67 fInfoShutdownArg = NULL;
69 fBufferSizeArg = NULL;
71 fClientRegistrationArg = NULL;
72 fPortRegistrationArg = NULL;
73 fPortConnectArg = NULL;
74 fPortRenameArg = NULL;
81 fSessionReply = kPendingSessionReply;
84 JackClient::~JackClient()
87 void JackClient::ShutDown(jack_status_t code,
const char* message)
93 fInfoShutdown(code, message, fInfoShutdownArg);
96 }
else if (fShutdown) {
97 fShutdown(fShutdownArg);
102 int JackClient::Close()
104 jack_log(
"JackClient::Close ref = %ld", GetClientControl()->fRefNum);
112 fChannel->ClientClose(GetClientControl()->fRefNum, &result);
115 assert(JackGlobals::fSynchroMutex);
116 JackGlobals::fSynchroMutex->Lock();
117 fSynchroTable[GetClientControl()->fRefNum].Disconnect();
118 JackGlobals::fSynchroMutex->Unlock();
119 JackGlobals::fClientTable[GetClientControl()->fRefNum] = NULL;
123 bool JackClient::IsActive()
125 return (GetClientControl()) ? GetClientControl()->fActive :
false;
128 jack_native_thread_t JackClient::GetThreadID()
130 return fThread.GetThreadID();
140 if (!freewheel && !GetEngineControl()->fSyncMode) {
141 jack_log(
"JackClient::SetupDriverSync driver sem in flush mode");
142 for (
int i = 0; i < GetEngineControl()->fDriverNum; i++) {
143 fSynchroTable[i].SetFlush(
true);
146 jack_log(
"JackClient::SetupDriverSync driver sem in normal mode");
147 for (
int i = 0; i < GetEngineControl()->fDriverNum; i++) {
148 fSynchroTable[i].SetFlush(
false);
162 int JackClient::ClientNotify(
int refnum,
const char* name,
int notify,
int sync,
const char* message,
int value1,
int value2)
166 jack_log(
"JackClient::ClientNotify ref = %ld name = %s notify = %ld", refnum, name, notify);
172 res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2);
176 res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2);
179 case kActivateClient:
180 jack_log(
"JackClient::kActivateClient name = %s ref = %ld ", name, refnum);
194 jack_log(
"JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName, name);
195 if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) {
196 fClientRegistration(name, 1, fClientRegistrationArg);
201 jack_log(
"JackClient::kRemoveClient fName = %s name = %s", GetClientControl()->fName, name);
202 if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) {
203 fClientRegistration(name, 0, fClientRegistrationArg);
207 case kBufferSizeCallback:
208 jack_log(
"JackClient::kBufferSizeCallback buffer_size = %ld", value1);
210 res = fBufferSize(value1, fBufferSizeArg);
214 case kSampleRateCallback:
215 jack_log(
"JackClient::kSampleRateCallback sample_rate = %ld", value1);
217 res = fSampleRate(value1, fSampleRateArg);
221 case kGraphOrderCallback:
222 jack_log(
"JackClient::kGraphOrderCallback");
224 res = fGraphOrder(fGraphOrderArg);
228 case kStartFreewheelCallback:
229 jack_log(
"JackClient::kStartFreewheel");
230 SetupDriverSync(
true);
232 if (fThread.GetStatus() == JackThread::kRunning) {
233 fThread.DropRealTime();
236 fFreewheel(1, fFreewheelArg);
240 case kStopFreewheelCallback:
241 jack_log(
"JackClient::kStopFreewheel");
242 SetupDriverSync(
false);
244 fFreewheel(0, fFreewheelArg);
247 if (GetEngineControl()->fRealTime && fThread.GetStatus() == JackThread::kRunning) {
248 if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) {
249 jack_error(
"JackClient::AcquireRealTime error");
254 case kPortRegistrationOnCallback:
255 jack_log(
"JackClient::kPortRegistrationOn port_index = %ld", value1);
256 if (fPortRegistration) {
257 fPortRegistration(value1, 1, fPortRegistrationArg);
261 case kPortRegistrationOffCallback:
262 jack_log(
"JackClient::kPortRegistrationOff port_index = %ld ", value1);
263 if (fPortRegistration) {
264 fPortRegistration(value1, 0, fPortRegistrationArg);
268 case kPortConnectCallback:
269 jack_log(
"JackClient::kPortConnectCallback src = %ld dst = %ld", value1, value2);
271 fPortConnect(value1, value2, 1, fPortConnectArg);
275 case kPortDisconnectCallback:
276 jack_log(
"JackClient::kPortDisconnectCallback src = %ld dst = %ld", value1, value2);
278 fPortConnect(value1, value2, 0, fPortConnectArg);
282 case kPortRenameCallback:
283 jack_log(
"JackClient::kPortRenameCallback port = %ld", value1);
285 fPortRename(value1, message, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg);
290 jack_log(
"JackClient::kXRunCallback");
292 res = fXrun(fXrunArg);
296 case kShutDownCallback:
297 jack_log(
"JackClient::kShutDownCallback");
298 ShutDown(jack_status_t(value1), message);
301 case kSessionCallback:
302 jack_log(
"JackClient::kSessionCallback");
305 char uuid_buf[JACK_UUID_SIZE];
306 event->
type = (jack_session_event_type_t)value1;
307 event->session_dir = strdup(message);
308 event->command_line = NULL;
310 snprintf(uuid_buf,
sizeof(uuid_buf),
"%d", GetClientControl()->fSessionID);
311 event->client_uuid = strdup(uuid_buf);
312 fSessionReply = kPendingSessionReply;
314 fSession(event, fSessionArg);
319 case kLatencyCallback:
320 res = HandleLatencyCallback(value1);
328 int JackClient::HandleLatencyCallback(
int status)
330 jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency;
336 list<jack_port_id_t>::iterator it;
338 for (it = fPortList.begin(); it != fPortList.end(); it++) {
339 JackPort* port = GetGraphManager()->GetPort(*it);
340 if ((port->GetFlags() & JackPortIsOutput) && (mode == JackPlaybackLatency)) {
341 GetGraphManager()->RecalculateLatency(*it, mode);
343 if ((port->GetFlags() & JackPortIsInput) && (mode == JackCaptureLatency)) {
344 GetGraphManager()->RecalculateLatency(*it, mode);
354 if (mode == JackPlaybackLatency) {
357 for (it = fPortList.begin(); it != fPortList.end(); it++) {
358 JackPort* port = GetGraphManager()->GetPort(*it);
359 if (port->GetFlags() & JackPortIsOutput) {
361 port->GetLatencyRange(mode, &other_latency);
362 if (other_latency.
max > latency.
max) {
363 latency.
max = other_latency.
max;
365 if (other_latency.
min < latency.
min) {
366 latency.
min = other_latency.
min;
371 if (latency.
min == UINT32_MAX) {
377 for (it = fPortList.begin(); it != fPortList.end(); it++) {
378 JackPort* port = GetGraphManager()->GetPort(*it);
379 if (port->GetFlags() & JackPortIsInput) {
380 port->SetLatencyRange(mode, &latency);
384 if (mode == JackCaptureLatency) {
387 for (it = fPortList.begin(); it != fPortList.end(); it++) {
388 JackPort* port = GetGraphManager()->GetPort(*it);
389 if (port->GetFlags() & JackPortIsInput) {
391 port->GetLatencyRange(mode, &other_latency);
392 if (other_latency.
max > latency.
max) {
393 latency.
max = other_latency.
max;
395 if (other_latency.
min < latency.
min) {
396 latency.
min = other_latency.
min;
401 if (latency.
min == UINT32_MAX) {
407 for (it = fPortList.begin(); it != fPortList.end(); it++) {
408 JackPort* port = GetGraphManager()->GetPort(*it);
409 if (port->GetFlags() & JackPortIsOutput) {
410 port->SetLatencyRange(mode, &latency);
420 fLatency(mode, fLatencyArg);
437 if (StartThread() < 0) {
446 GetClientControl()->fActive =
true;
449 GetClientControl()->fTransportSync =
true;
450 GetClientControl()->fTransportTimebase =
true;
453 GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime();
454 fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result);
468 GetClientControl()->fActive =
false;
471 GetClientControl()->fTransportSync =
false;
472 GetClientControl()->fTransportTimebase =
false;
476 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
477 jack_log(
"JackClient::Deactivate res = %ld", result);
490 void JackClient::InitAux()
493 jack_log(
"JackClient::Init calling client thread init callback");
510 jack_log(
"JackClient::kBufferSizeCallback buffer_size = %ld", GetEngineControl()->fBufferSize);
512 fBufferSize(GetEngineControl()->fBufferSize, fBufferSizeArg);
519 if (!jack_tls_set(JackGlobals::fRealTimeThread,
this)) {
520 jack_error(
"Failed to set thread realtime key");
524 if (GetEngineControl()->fRealTime) {
525 set_threaded_log_function();
532 void JackClient::SetupRealTime()
534 jack_log(
"JackClient::Init : period = %ld computation = %ld constraint = %ld",
535 long(int64_t(GetEngineControl()->fPeriod) / 1000.0f),
536 long(int64_t(GetEngineControl()->fComputation) / 1000.0f),
537 long(int64_t(GetEngineControl()->fConstraint) / 1000.0f));
540 fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);
542 if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) {
543 jack_error(
"JackClient::AcquireSelfRealTime error");
547 int JackClient::StartThread()
549 if (fThread.StartSync() < 0) {
567 fThreadFun(fThreadFunArg);
574 void JackClient::DummyCycle()
580 inline void JackClient::ExecuteThread()
584 CycleSignalAux(CallProcessCallback());
588 inline jack_nframes_t JackClient::CycleWaitAux()
593 CallSyncCallbackAux();
594 return GetEngineControl()->fBufferSize;
597 inline void JackClient::CycleSignalAux(
int status)
600 CallTimebaseCallbackAux();
608 jack_nframes_t JackClient::CycleWait()
610 return CycleWaitAux();
613 void JackClient::CycleSignal(
int status)
615 CycleSignalAux(status);
618 inline int JackClient::CallProcessCallback()
620 return (fProcess != NULL) ? fProcess(GetEngineControl()->fBufferSize, fProcessArg) : 0;
623 inline bool JackClient::WaitSync()
626 if (GetGraphManager()->SuspendRefNum(GetClientControl(), fSynchroTable, 0x7FFFFFFF) < 0) {
634 inline void JackClient::SignalSync()
637 if (GetGraphManager()->ResumeRefNum(GetClientControl(), fSynchroTable) < 0) {
642 inline void JackClient::End()
644 jack_log(
"JackClient::Execute end name = %s", GetClientControl()->fName);
647 fThread.DropSelfRealTime();
648 GetClientControl()->fActive =
false;
649 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
653 inline void JackClient::Error()
655 jack_error(
"JackClient::Execute error name = %s", GetClientControl()->fName);
658 fThread.DropSelfRealTime();
659 GetClientControl()->fActive =
false;
660 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
661 ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE);
669 int JackClient::PortRegister(
const char* port_name,
const char* port_type,
unsigned long flags,
unsigned long buffer_size)
672 string port_short_name_str = string(port_name);
673 if (port_short_name_str.size() == 0) {
679 string port_full_name_str = string(GetClientControl()->fName) + string(
":") + port_short_name_str;
680 if (port_full_name_str.size() >= REAL_JACK_PORT_NAME_SIZE) {
681 jack_error(
"\"%s:%s\" is too long to be used as a JACK port name.\n" 682 "Please use %lu characters or less",
683 GetClientControl()->fName,
685 JACK_PORT_NAME_SIZE - 1);
690 jack_port_id_t port_index = NO_PORT;
691 fChannel->PortRegister(GetClientControl()->fRefNum, port_full_name_str.c_str(), port_type, flags, buffer_size, &port_index, &result);
694 jack_log(
"JackClient::PortRegister ref = %ld name = %s type = %s port_index = %ld", GetClientControl()->fRefNum, port_full_name_str.c_str(), port_type, port_index);
695 fPortList.push_back(port_index);
702 int JackClient::PortUnRegister(jack_port_id_t port_index)
704 jack_log(
"JackClient::PortUnRegister port_index = %ld", port_index);
705 list<jack_port_id_t>::iterator it = find(fPortList.begin(), fPortList.end(), port_index);
707 if (it != fPortList.end()) {
710 fChannel->PortUnRegister(GetClientControl()->fRefNum, port_index, &result);
713 jack_error(
"unregistering a port %ld that is not own by the client", port_index);
718 int JackClient::PortConnect(
const char* src,
const char* dst)
720 jack_log(
"JackClient::Connect src = %s dst = %s", src, dst);
721 if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) {
722 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
725 if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) {
726 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
730 fChannel->PortConnect(GetClientControl()->fRefNum, src, dst, &result);
734 int JackClient::PortDisconnect(
const char* src,
const char* dst)
736 jack_log(
"JackClient::Disconnect src = %s dst = %s", src, dst);
737 if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) {
738 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
741 if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) {
742 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
746 fChannel->PortDisconnect(GetClientControl()->fRefNum, src, dst, &result);
750 int JackClient::PortDisconnect(jack_port_id_t src)
752 jack_log(
"JackClient::PortDisconnect src = %ld", src);
754 fChannel->PortDisconnect(GetClientControl()->fRefNum, src, ALL_PORTS, &result);
758 int JackClient::PortIsMine(jack_port_id_t port_index)
760 JackPort* port = GetGraphManager()->GetPort(port_index);
761 return GetClientControl()->fRefNum == port->GetRefNum();
764 int JackClient::PortRename(jack_port_id_t port_index,
const char* name)
767 fChannel->PortRename(GetClientControl()->fRefNum, port_index, name, &result);
775 int JackClient::SetBufferSize(jack_nframes_t buffer_size)
778 fChannel->SetBufferSize(buffer_size, &result);
782 int JackClient::SetFreeWheel(
int onoff)
785 fChannel->SetFreewheel(onoff, &result);
789 int JackClient::ComputeTotalLatencies()
792 fChannel->ComputeTotalLatencies(&result);
800 inline int JackClient::ActivateAux()
803 if (IsActive() && fThread.GetStatus() != JackThread::kRunning) {
805 jack_log(
"JackClient::ActivateAux");
808 if (StartThread() < 0) {
813 GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime();
814 fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result);
822 int JackClient::ReleaseTimebase()
825 fChannel->ReleaseTimebase(GetClientControl()->fRefNum, &result);
827 GetClientControl()->fTransportTimebase =
false;
835 int JackClient::SetSyncCallback(JackSyncCallback sync_callback,
void* arg)
837 GetClientControl()->fTransportSync = (fSync != NULL);
839 fSync = sync_callback;
840 return ActivateAux();
843 int JackClient::SetTimebaseCallback(
int conditional, JackTimebaseCallback timebase_callback,
void* arg)
846 fChannel->SetTimebaseCallback(GetClientControl()->fRefNum, conditional, &result);
849 GetClientControl()->fTransportTimebase =
true;
850 fTimebase = timebase_callback;
852 return ActivateAux();
860 int JackClient::SetSyncTimeout(jack_time_t timeout)
862 GetEngineControl()->fTransport.SetSyncTimeout(timeout);
868 void JackClient::TransportLocate(jack_nframes_t frame)
872 pos.
valid = (jack_position_bits_t)0;
873 jack_log(
"JackClient::TransportLocate pos = %ld", pos.
frame);
874 GetEngineControl()->fTransport.RequestNewPos(&pos);
880 jack_log(
"JackClient::TransportReposition pos = %ld", pos->
frame);
881 if (tmp.
valid & ~JACK_POSITION_MASK) {
884 GetEngineControl()->fTransport.RequestNewPos(&tmp);
889 jack_transport_state_t JackClient::TransportQuery(
jack_position_t* pos)
891 return GetEngineControl()->fTransport.Query(pos);
894 jack_nframes_t JackClient::GetCurrentTransportFrame()
896 return GetEngineControl()->fTransport.GetCurrentFrame();
900 void JackClient::TransportStart()
902 GetEngineControl()->fTransport.SetCommand(TransportCommandStart);
906 void JackClient::TransportStop()
908 GetEngineControl()->fTransport.SetCommand(TransportCommandStop);
914 void JackClient::CallSyncCallback()
916 CallSyncCallbackAux();
919 inline void JackClient::CallSyncCallbackAux()
921 if (GetClientControl()->fTransportSync) {
923 JackTransportEngine& transport = GetEngineControl()->fTransport;
925 jack_transport_state_t transport_state = transport.GetState();
928 if (fSync(transport_state, cur_pos, fSyncArg)) {
929 GetClientControl()->fTransportState = JackTransportRolling;
930 GetClientControl()->fTransportSync =
false;
933 GetClientControl()->fTransportState = JackTransportRolling;
934 GetClientControl()->fTransportSync =
false;
939 void JackClient::CallTimebaseCallback()
941 CallTimebaseCallbackAux();
944 inline void JackClient::CallTimebaseCallbackAux()
946 JackTransportEngine& transport = GetEngineControl()->fTransport;
950 transport.GetTimebaseMaster(master, unused);
952 if (GetClientControl()->fRefNum == master && fTimebase) {
954 jack_transport_state_t transport_state = transport.GetState();
957 if (GetClientControl()->fTransportTimebase) {
958 fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos,
true, fTimebaseArg);
959 GetClientControl()->fTransportTimebase =
false;
960 }
else if (transport_state == JackTransportRolling) {
961 fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos,
false, fTimebaseArg);
964 transport.WriteNextStateStop(1);
972 void JackClient::OnShutdown(JackShutdownCallback callback,
void *arg)
975 jack_error(
"You cannot set callbacks on an active client");
978 GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL);
980 fShutdown = callback;
984 void JackClient::OnInfoShutdown(JackInfoShutdownCallback callback,
void *arg)
987 jack_error(
"You cannot set callbacks on an active client");
990 GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL);
991 fInfoShutdownArg = arg;
992 fInfoShutdown = callback;
996 int JackClient::SetProcessCallback(JackProcessCallback callback,
void *arg)
999 jack_error(
"You cannot set callbacks on an active client");
1001 }
else if (fThreadFun) {
1002 jack_error (
"A thread callback has already been setup, both models cannot be used at the same time!");
1006 fProcess = callback;
1011 int JackClient::SetXRunCallback(JackXRunCallback callback,
void *arg)
1014 jack_error(
"You cannot set callbacks on an active client");
1017 GetClientControl()->fCallback[kXRunCallback] = (callback != NULL);
1024 int JackClient::SetInitCallback(JackThreadInitCallback callback,
void *arg)
1027 jack_error(
"You cannot set callbacks on an active client");
1033 return JackMessageBuffer::fInstance->SetInitCallback(callback, arg);
1037 int JackClient::SetGraphOrderCallback(JackGraphOrderCallback callback,
void *arg)
1040 jack_error(
"You cannot set callbacks on an active client");
1043 GetClientControl()->fCallback[kGraphOrderCallback] = (callback != NULL);
1044 fGraphOrder = callback;
1045 fGraphOrderArg = arg;
1050 int JackClient::SetBufferSizeCallback(JackBufferSizeCallback callback,
void *arg)
1053 jack_error(
"You cannot set callbacks on an active client");
1056 GetClientControl()->fCallback[kBufferSizeCallback] = (callback != NULL);
1057 fBufferSizeArg = arg;
1058 fBufferSize = callback;
1063 int JackClient::SetSampleRateCallback(JackSampleRateCallback callback,
void *arg)
1066 jack_error(
"You cannot set callbacks on an active client");
1069 GetClientControl()->fCallback[kSampleRateCallback] = (callback != NULL);
1070 fSampleRateArg = arg;
1071 fSampleRate = callback;
1074 callback(GetEngineControl()->fSampleRate, arg);
1080 int JackClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback,
void* arg)
1083 jack_error(
"You cannot set callbacks on an active client");
1087 fClientRegistrationArg = arg;
1088 fClientRegistration = callback;
1093 int JackClient::SetFreewheelCallback(JackFreewheelCallback callback,
void *arg)
1096 jack_error(
"You cannot set callbacks on an active client");
1099 GetClientControl()->fCallback[kStartFreewheelCallback] = (callback != NULL);
1100 GetClientControl()->fCallback[kStopFreewheelCallback] = (callback != NULL);
1101 fFreewheelArg = arg;
1102 fFreewheel = callback;
1107 int JackClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback,
void *arg)
1110 jack_error(
"You cannot set callbacks on an active client");
1113 GetClientControl()->fCallback[kPortRegistrationOnCallback] = (callback != NULL);
1114 GetClientControl()->fCallback[kPortRegistrationOffCallback] = (callback != NULL);
1115 fPortRegistrationArg = arg;
1116 fPortRegistration = callback;
1121 int JackClient::SetPortConnectCallback(JackPortConnectCallback callback,
void *arg)
1124 jack_error(
"You cannot set callbacks on an active client");
1127 GetClientControl()->fCallback[kPortConnectCallback] = (callback != NULL);
1128 GetClientControl()->fCallback[kPortDisconnectCallback] = (callback != NULL);
1129 fPortConnectArg = arg;
1130 fPortConnect = callback;
1135 int JackClient::SetPortRenameCallback(JackPortRenameCallback callback,
void *arg)
1138 jack_error(
"You cannot set callbacks on an active client");
1141 GetClientControl()->fCallback[kPortRenameCallback] = (callback != NULL);
1142 fPortRenameArg = arg;
1143 fPortRename = callback;
1148 int JackClient::SetProcessThread(JackThreadCallback fun,
void *arg)
1151 jack_error(
"You cannot set callbacks on an active client");
1153 }
else if (fProcess) {
1154 jack_error(
"A process callback has already been setup, both models cannot be used at the same time!");
1158 fThreadFunArg = arg;
1166 jack_error(
"You cannot set callbacks on an active client");
1169 GetClientControl()->fCallback[kSessionCallback] = (callback != NULL);
1171 fSession = callback;
1176 int JackClient::SetLatencyCallback(JackLatencyCallback callback,
void *arg)
1179 jack_error(
"You cannot set callbacks on an active client");
1184 fLatency = callback;
1193 char* JackClient::GetInternalClientName(
int ref)
1195 char name_res[JACK_CLIENT_NAME_SIZE+1];
1197 fChannel->GetInternalClientName(GetClientControl()->fRefNum, ref, name_res, &result);
1198 return (result < 0) ? NULL : strdup(name_res);
1201 int JackClient::InternalClientHandle(
const char* client_name, jack_status_t* status)
1203 int int_ref, result = -1;
1204 fChannel->InternalClientHandle(GetClientControl()->fRefNum, client_name, (
int*)status, &int_ref, &result);
1208 int JackClient::InternalClientLoad(
const char* client_name, jack_options_t options, jack_status_t* status,
jack_varargs_t* va)
1210 if (strlen(client_name) >= JACK_CLIENT_NAME_SIZE) {
1211 jack_error (
"\"%s\" is too long for a JACK client name.\n" 1212 "Please use %lu characters or less.",
1213 client_name, JACK_CLIENT_NAME_SIZE);
1217 if (va->load_name && (strlen(va->load_name) >= JACK_PATH_MAX)) {
1218 jack_error(
"\"%s\" is too long for a shared object name.\n" 1219 "Please use %lu characters or less.",
1220 va->load_name, JACK_PATH_MAX);
1221 int my_status1 = *status | (JackFailure | JackInvalidOption);
1222 *status = (jack_status_t)my_status1;
1226 if (va->load_init && (strlen(va->load_init) >= JACK_LOAD_INIT_LIMIT)) {
1227 jack_error (
"\"%s\" is too long for internal client init " 1228 "string.\nPlease use %lu characters or less.",
1229 va->load_init, JACK_LOAD_INIT_LIMIT);
1230 int my_status1 = *status | (JackFailure | JackInvalidOption);
1231 *status = (jack_status_t)my_status1;
1235 int int_ref, result = -1;
1236 fChannel->InternalClientLoad(GetClientControl()->fRefNum, client_name, va->load_name, va->load_init, options, (
int*)status, &int_ref, -1, &result);
1240 void JackClient::InternalClientUnload(
int ref, jack_status_t* status)
1243 fChannel->InternalClientUnload(GetClientControl()->fRefNum, ref, (
int*)status, &result);
1250 jack_session_command_t* JackClient::SessionNotify(
const char* target, jack_session_event_type_t type,
const char* path)
1253 fChannel->SessionNotify(GetClientControl()->fRefNum, target, type, path, &res);
1260 strncpy(GetClientControl()->fSessionCommand, ev->
command_line,
sizeof(GetClientControl()->fSessionCommand));
1262 GetClientControl()->fSessionCommand[0] =
'\0';
1265 GetClientControl()->fSessionFlags = ev->
flags;
1267 jack_log(
"JackClient::SessionReply... we are here");
1268 if (fChannel->IsChannelThread()) {
1269 jack_log(
"JackClient::SessionReply... in callback reply");
1271 fSessionReply = kImmediateSessionReply;
1275 jack_log(
"JackClient::SessionReply... out of cb");
1278 fChannel->SessionReply(GetClientControl()->fRefNum, &result);
1282 char* JackClient::GetUUIDForClientName(
const char* client_name)
1284 char uuid_res[JACK_UUID_SIZE];
1286 fChannel->GetUUIDForClientName(GetClientControl()->fRefNum, client_name, uuid_res, &result);
1287 return (result) ? NULL : strdup(uuid_res);
1290 char* JackClient::GetClientNameByUUID(
const char* uuid)
1292 char name_res[JACK_CLIENT_NAME_SIZE + 1];
1294 fChannel->GetClientNameForUUID(GetClientControl()->fRefNum, uuid, name_res, &result);
1295 return (result) ? NULL : strdup(name_res);
1298 int JackClient::ReserveClientName(
const char* client_name,
const char* uuid)
1301 fChannel->ReserveClientName( GetClientControl()->fRefNum, client_name, uuid, &result);
1305 int JackClient::ClientHasSessionCallback(
const char* client_name)
1308 fChannel->ClientHasSessionCallback(client_name, &result);
jack_session_flags_t flags
virtual int Deactivate()
Need to stop thread after deactivating in the server.
virtual int ClientNotifyImp(int refnum, const char *name, int notify, int sync, const char *message, int value1, int value)
Notification received from the server.
SERVER_EXPORT void jack_error(const char *fmt,...)
jack_position_bits_t valid
virtual int Activate()
We need to start thread before activating in the server, otherwise the FW driver connected to the cli...
void SetupDriverSync(bool freewheel)
bool Init()
Called once when the thread starts.
enum JackSessionFlags jack_session_flags_t
jack_session_event_type_t type
SERVER_EXPORT void jack_log(const char *fmt,...)
void(* JackSessionCallback)(jack_session_event_t *event, void *arg)