00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackDebugClient.h"
00021 #include "JackEngineControl.h"
00022 #include "JackException.h"
00023 #include "JackError.h"
00024 #include "JackTime.h"
00025 #include <iostream>
00026 #include <iomanip>
00027 #include <sstream>
00028 #include <fstream>
00029 #include <string>
00030 #include <time.h>
00031
00032 using namespace std;
00033
00034 namespace Jack
00035 {
00036
00037 JackDebugClient::JackDebugClient(JackClient * client)
00038 {
00039 fTotalPortNumber = 1;
00040 fOpenPortNumber = 0;
00041 fIsActivated = 0;
00042 fIsDeactivated = 0;
00043 fIsClosed = 0;
00044 fClient = client;
00045 fFreewheel = false;
00046 }
00047
00048 JackDebugClient::~JackDebugClient()
00049 {
00050 fTotalPortNumber--;
00051 *fStream << endl << endl << "----------------------------------- JackDebugClient summary ------------------------------- " << endl << endl;
00052 *fStream << "Client flags ( 1:yes / 0:no ) :" << endl;
00053 *fStream << setw(5) << "- Client call activated : " << fIsActivated << endl;
00054 *fStream << setw(5) << "- Client call deactivated : " << fIsDeactivated << endl;
00055 *fStream << setw(5) << "- Client call closed : " << fIsClosed << endl;
00056 *fStream << setw(5) << "- Total number of instantiated port : " << fTotalPortNumber << endl;
00057 *fStream << setw(5) << "- Number of port remaining open when exiting client : " << fOpenPortNumber << endl;
00058 if (fOpenPortNumber != 0)
00059 *fStream << "!!! WARNING !!! Some ports have not been unregistered ! Incorrect exiting !" << endl;
00060 if (fIsDeactivated != fIsActivated)
00061 *fStream << "!!! ERROR !!! Client seem to not perform symetric activation-deactivation ! (not the same number of activate and deactivate)" << endl;
00062 if (fIsClosed == 0)
00063 *fStream << "!!! ERROR !!! Client have not been closed with jack_client_close() !" << endl;
00064
00065 *fStream << endl << endl << "---------------------------- JackDebugClient detailed port summary ------------------------ " << endl << endl;
00066
00067 for (int i = 1; i <= fTotalPortNumber ; i++) {
00068 *fStream << endl << "Port index (internal debug test value) : " << i << endl;
00069 *fStream << setw(5) << "- Name : " << fPortList[i].name << endl;
00070 *fStream << setw(5) << "- idport : " << fPortList[i].idport << endl;
00071 *fStream << setw(5) << "- IsConnected : " << fPortList[i].IsConnected << endl;
00072 *fStream << setw(5) << "- IsUnregistered : " << fPortList[i].IsUnregistered << endl;
00073 if (fPortList[i].IsUnregistered == 0)
00074 *fStream << "!!! WARNING !!! Port have not been unregistered ! Incorrect exiting !" << endl;
00075 }
00076 *fStream << "delete object JackDebugClient : end of tracing" << endl;
00077 delete fStream;
00078 delete fClient;
00079 }
00080
00081 int JackDebugClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status)
00082 {
00083 int res = fClient->Open(server_name, name, uuid, options, status);
00084 char provstr[256];
00085 char buffer[256];
00086 time_t curtime;
00087 struct tm *loctime;
00088
00089 curtime = time (NULL);
00090
00091 loctime = localtime (&curtime);
00092 strftime (buffer, 256, "%I-%M", loctime);
00093 sprintf(provstr, "JackClientDebug-%s-%s.log", name, buffer);
00094 fStream = new ofstream(provstr, ios_base::ate);
00095 if (fStream->is_open()) {
00096 if (res == -1) {
00097 *fStream << "Trying to open client with name '" << name << "' with bad result (client not opened)." << res << endl;
00098 } else {
00099 *fStream << "Open client with name '" << name << "'." << endl;
00100 }
00101 } else {
00102 jack_log("JackDebugClient::Open : cannot open log file");
00103 }
00104 strcpy(fClientName, name);
00105 return res;
00106 }
00107
00108 int JackDebugClient::Close()
00109 {
00110 *fStream << "Client '" << fClientName << "' was closed" << endl;
00111 int res = fClient->Close();
00112 fIsClosed++;
00113 return res;
00114 }
00115
00116 void JackDebugClient::CheckClient(const char* function_name) const
00117 {
00118 *fStream << "CheckClient : " << function_name << ", calling thread : " << pthread_self() << endl;
00119
00120 if (fIsClosed > 0) {
00121 *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed " << "from " << function_name << endl;
00122 *fStream << "This is likely to cause crash !'" << endl;
00123 #ifdef __APPLE__
00124
00125 #endif
00126 }
00127 }
00128
00129 jack_native_thread_t JackDebugClient::GetThreadID()
00130 {
00131 CheckClient("GetThreadID");
00132 return fClient->GetThreadID();
00133 }
00134
00135 JackGraphManager* JackDebugClient::GetGraphManager() const
00136 {
00137 CheckClient("GetGraphManager");
00138 return fClient->GetGraphManager();
00139 }
00140 JackEngineControl* JackDebugClient::GetEngineControl() const
00141 {
00142 CheckClient("GetEngineControl");
00143 return fClient->GetEngineControl();
00144 }
00149 int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
00150 {
00151 CheckClient("ClientNotify");
00152 return fClient->ClientNotify( refnum, name, notify, sync, message, value1, value2);
00153 }
00154
00155 int JackDebugClient::Activate()
00156 {
00157 CheckClient("Activate");
00158 int res = fClient->Activate();
00159 fIsActivated++;
00160 if (fIsDeactivated)
00161 *fStream << "Client '" << fClientName << "' call activate a new time (it already call 'activate' previously)." << endl;
00162 *fStream << "Client '" << fClientName << "' Activated" << endl;
00163 if (res != 0)
00164 *fStream << "Client '" << fClientName << "' try to activate but server return " << res << " ." << endl;
00165 return res;
00166 }
00167
00168 int JackDebugClient::Deactivate()
00169 {
00170 CheckClient("Deactivate");
00171 int res = fClient->Deactivate();
00172 fIsDeactivated++;
00173 if (fIsActivated == 0)
00174 *fStream << "Client '" << fClientName << "' deactivate while it hasn't been previoulsy activated !" << endl;
00175 *fStream << "Client '" << fClientName << "' Deactivated" << endl;
00176 if (res != 0)
00177 *fStream << "Client '" << fClientName << "' try to deactivate but server return " << res << " ." << endl;
00178 return res;
00179 }
00180
00181
00182
00183
00184
00185 int JackDebugClient::PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size)
00186 {
00187 CheckClient("PortRegister");
00188 int res = fClient->PortRegister(port_name, port_type, flags, buffer_size);
00189 if (res <= 0) {
00190 *fStream << "Client '" << fClientName << "' try port register ('" << port_name << "') and server return error " << res << " ." << endl;
00191 } else {
00192 if (fTotalPortNumber < MAX_PORT_HISTORY) {
00193 fPortList[fTotalPortNumber].idport = res;
00194 strcpy(fPortList[fTotalPortNumber].name, port_name);
00195 fPortList[fTotalPortNumber].IsConnected = 0;
00196 fPortList[fTotalPortNumber].IsUnregistered = 0;
00197 } else {
00198 *fStream << "!!! WARNING !!! History is full : no more port history will be recorded." << endl;
00199 }
00200 fTotalPortNumber++;
00201 fOpenPortNumber++;
00202 *fStream << "Client '" << fClientName << "' port register with portname '" << port_name << " port " << res << "' ." << endl;
00203 }
00204 return res;
00205 }
00206
00207 int JackDebugClient::PortUnRegister(jack_port_id_t port_index)
00208 {
00209 CheckClient("PortUnRegister");
00210 int res = fClient->PortUnRegister(port_index);
00211 fOpenPortNumber--;
00212 int i;
00213 for (i = (fTotalPortNumber - 1); i >= 0; i--) {
00214 if (fPortList[i].idport == port_index) {
00215 if (fPortList[i].IsUnregistered != 0)
00216 *fStream << "!!! ERROR !!! : '" << fClientName << "' id deregistering port '" << fPortList[i].name << "' that have already been unregistered !" << endl;
00217 fPortList[i].IsUnregistered++;
00218 break;
00219 }
00220 }
00221 if (i == 0)
00222 *fStream << "JackClientDebug : PortUnregister : port " << port_index << " was not previously registered !" << endl;
00223 if (res != 0)
00224 *fStream << "Client '" << fClientName << "' try to do PortUnregister and server return " << res << endl;
00225 *fStream << "Client '" << fClientName << "' unregister port '" << port_index << "'." << endl;
00226 return res;
00227 }
00228
00229 int JackDebugClient::PortConnect(const char* src, const char* dst)
00230 {
00231 CheckClient("PortConnect");
00232 if (!fIsActivated)
00233 *fStream << "!!! ERROR !!! Trying to connect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl;
00234 int i;
00235 int res = fClient->PortConnect( src, dst);
00236 for (i = (fTotalPortNumber - 1); i >= 0; i--) {
00237 if (strcmp(fPortList[i].name, src) == 0) {
00238 if (fPortList[i].IsUnregistered != 0)
00239 *fStream << "!!! ERROR !!! Connecting port " << src << " previoulsy unregistered !" << endl;
00240 fPortList[i].IsConnected++;
00241 *fStream << "Connecting port " << src << " to " << dst << ". ";
00242 break;
00243 } else if (strcmp(fPortList[i].name, dst) == 0 ) {
00244 if (fPortList[i].IsUnregistered != 0)
00245 *fStream << "!!! ERROR !!! Connecting port " << dst << " previoulsy unregistered !" << endl;
00246 fPortList[i].IsConnected++;
00247 *fStream << "Connecting port " << src << " to " << dst << ". ";
00248 break;
00249 }
00250 }
00251 if (i == 0)
00252 *fStream << "JackClientDebug : PortConnect : port was not found in debug database !" << endl;
00253 if (res != 0)
00254 *fStream << "Client '" << fClientName << "' try to do PortConnect but server return " << res << " ." << endl;
00255
00256 return res;
00257 }
00258
00259 int JackDebugClient::PortDisconnect(const char* src, const char* dst)
00260 {
00261 CheckClient("PortDisconnect");
00262 if (!fIsActivated)
00263 *fStream << "!!! ERROR !!! Trying to disconnect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl;
00264 int res = fClient->PortDisconnect( src, dst);
00265 int i;
00266 for (i = (fTotalPortNumber - 1); i >= 0; i--) {
00267 if (strcmp(fPortList[i].name, src) == 0) {
00268 if (fPortList[i].IsUnregistered != 0)
00269 *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl;
00270 fPortList[i].IsConnected--;
00271 *fStream << "disconnecting port " << src << ". ";
00272 break;
00273 } else if (strcmp(fPortList[i].name, dst) == 0 ) {
00274 if (fPortList[i].IsUnregistered != 0)
00275 *fStream << "!!! ERROR !!! : Disonnecting port " << dst << " previoulsy unregistered !" << endl;
00276 fPortList[i].IsConnected--;
00277 *fStream << "disconnecting port " << dst << ". ";
00278 break;
00279 }
00280 }
00281 if (i == 0)
00282 *fStream << "JackClientDebug : PortDisConnect : port was not found in debug database !" << endl;
00283 if (res != 0)
00284 *fStream << "Client '" << fClientName << "' try to do PortDisconnect but server return " << res << " ." << endl;
00285
00286 return res;
00287 }
00288
00289 int JackDebugClient::PortDisconnect(jack_port_id_t src)
00290 {
00291 CheckClient("PortDisconnect");
00292 if (!fIsActivated)
00293 *fStream << "!!! ERROR !!! : Trying to disconnect port " << src << " while that client has not been activated !" << endl;
00294 int res = fClient->PortDisconnect(src);
00295 int i;
00296 for (i = (fTotalPortNumber - 1); i >= 0; i--) {
00297 if (fPortList[i].idport == src) {
00298 if (fPortList[i].IsUnregistered != 0)
00299 *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl;
00300 fPortList[i].IsConnected--;
00301 *fStream << "Disconnecting port " << src << ". " << endl;
00302 break;
00303 }
00304 }
00305 if (i == 0)
00306 *fStream << "JackClientDebug : PortDisconnect : port was not found in debug database !" << endl;
00307 if (res != 0)
00308 *fStream << "Client '" << fClientName << "' try to do PortDisconnect but server return " << res << " ." << endl;
00309
00310 return res;
00311 }
00312
00313 int JackDebugClient::PortIsMine(jack_port_id_t port_index)
00314 {
00315 CheckClient("PortIsMine");
00316 return fClient->PortIsMine(port_index);
00317 }
00318
00319
00320
00321
00322
00323 int JackDebugClient::SetBufferSize(jack_nframes_t buffer_size)
00324 {
00325 CheckClient("SetBufferSize");
00326 return fClient->SetBufferSize(buffer_size);
00327 }
00328
00329 int JackDebugClient::SetFreeWheel(int onoff)
00330 {
00331 CheckClient("SetFreeWheel");
00332 if (onoff && fFreewheel)
00333 *fStream << "!!! ERROR !!! : Freewheel setup seems incorrect : set = ON while FW is already ON " << endl;
00334 if (!onoff && !fFreewheel)
00335 *fStream << "!!! ERROR !!! : Freewheel setup seems incorrect : set = OFF while FW is already OFF " << endl;
00336 fFreewheel = onoff;
00337 return fClient->SetFreeWheel(onoff);
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347 void JackDebugClient::ShutDown()
00348 {
00349 fClient->ShutDown();
00350 }
00351
00352
00353
00354
00355
00356 int JackDebugClient::ReleaseTimebase()
00357 {
00358 CheckClient("ReleaseTimebase");
00359 return fClient->ReleaseTimebase();
00360 }
00361
00362 int JackDebugClient::SetSyncCallback(JackSyncCallback sync_callback, void* arg)
00363 {
00364 CheckClient("SetSyncCallback");
00365 return fClient->SetSyncCallback(sync_callback, arg);
00366 }
00367
00368 int JackDebugClient::SetSyncTimeout(jack_time_t timeout)
00369 {
00370 CheckClient("SetSyncTimeout");
00371 return fClient->SetSyncTimeout(timeout);
00372 }
00373
00374 int JackDebugClient::SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg)
00375 {
00376 CheckClient("SetTimebaseCallback");
00377 return fClient->SetTimebaseCallback( conditional, timebase_callback, arg);
00378 }
00379
00380 void JackDebugClient::TransportLocate(jack_nframes_t frame)
00381 {
00382 CheckClient("TransportLocate");
00383 fClient->TransportLocate(frame);
00384 }
00385
00386 jack_transport_state_t JackDebugClient::TransportQuery(jack_position_t* pos)
00387 {
00388 CheckClient("TransportQuery");
00389 return fClient->TransportQuery(pos);
00390 }
00391
00392 jack_nframes_t JackDebugClient::GetCurrentTransportFrame()
00393 {
00394 CheckClient("GetCurrentTransportFrame");
00395 return fClient->GetCurrentTransportFrame();
00396 }
00397
00398 int JackDebugClient::TransportReposition(jack_position_t* pos)
00399 {
00400 CheckClient("TransportReposition");
00401 return fClient->TransportReposition(pos);
00402 }
00403
00404 void JackDebugClient::TransportStart()
00405 {
00406 CheckClient("TransportStart");
00407 fClient->TransportStart();
00408 }
00409
00410 void JackDebugClient::TransportStop()
00411 {
00412 CheckClient("TransportStop");
00413 fClient->TransportStop();
00414 }
00415
00416
00417
00418
00419
00420 void JackDebugClient::OnShutdown(JackShutdownCallback callback, void *arg)
00421 {
00422 CheckClient("OnShutdown");
00423 fClient->OnShutdown(callback, arg);
00424 }
00425
00426 void JackDebugClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg)
00427 {
00428 CheckClient("OnInfoShutdown");
00429 fClient->OnInfoShutdown(callback, arg);
00430 }
00431
00432 int JackDebugClient::TimeCallback(jack_nframes_t nframes, void *arg)
00433 {
00434 JackDebugClient* client = (JackDebugClient*)arg;
00435 jack_time_t t1 = GetMicroSeconds();
00436 int res = client->fProcessTimeCallback(nframes, client->fProcessTimeCallbackArg);
00437 if (res == 0) {
00438 jack_time_t t2 = GetMicroSeconds();
00439 long delta = long((t2 - t1) - client->GetEngineControl()->fPeriodUsecs);
00440 if (delta > 0 && !client->fFreewheel)
00441 *client->fStream << "!!! ERROR !!! : Process overload of " << delta << " us" << endl;
00442 }
00443 return res;
00444 }
00445
00446 int JackDebugClient::SetProcessCallback(JackProcessCallback callback, void *arg)
00447 {
00448 CheckClient("SetProcessCallback");
00449 fProcessTimeCallback = callback;
00450 fProcessTimeCallbackArg = arg;
00451 return fClient->SetProcessCallback(TimeCallback, this);
00452 }
00453
00454 int JackDebugClient::SetXRunCallback(JackXRunCallback callback, void *arg)
00455 {
00456 CheckClient("SetXRunCallback");
00457 return fClient->SetXRunCallback(callback, arg);
00458 }
00459
00460 int JackDebugClient::SetInitCallback(JackThreadInitCallback callback, void *arg)
00461 {
00462 CheckClient("SetInitCallback");
00463 return fClient->SetInitCallback(callback, arg);
00464 }
00465
00466 int JackDebugClient::SetGraphOrderCallback(JackGraphOrderCallback callback, void *arg)
00467 {
00468 CheckClient("SetGraphOrderCallback");
00469 return fClient->SetGraphOrderCallback(callback, arg);
00470 }
00471
00472 int JackDebugClient::SetBufferSizeCallback(JackBufferSizeCallback callback, void *arg)
00473 {
00474 CheckClient("SetBufferSizeCallback");
00475 return fClient->SetBufferSizeCallback(callback, arg);
00476 }
00477
00478 int JackDebugClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback, void* arg)
00479 {
00480 CheckClient("SetClientRegistrationCallback");
00481 return fClient->SetClientRegistrationCallback(callback, arg);
00482 }
00483
00484 int JackDebugClient::SetFreewheelCallback(JackFreewheelCallback callback, void *arg)
00485 {
00486 CheckClient("SetFreewheelCallback");
00487 return fClient->SetFreewheelCallback(callback, arg);
00488 }
00489
00490 int JackDebugClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback, void *arg)
00491 {
00492 CheckClient("SetPortRegistrationCallback");
00493 return fClient->SetPortRegistrationCallback(callback, arg);
00494 }
00495
00496 int JackDebugClient::SetPortConnectCallback(JackPortConnectCallback callback, void *arg)
00497 {
00498 CheckClient("SetPortConnectCallback");
00499 return fClient->SetPortConnectCallback(callback, arg);
00500 }
00501
00502 int JackDebugClient::SetPortRenameCallback(JackPortRenameCallback callback, void *arg)
00503 {
00504 CheckClient("SetPortRenameCallback");
00505 return fClient->SetPortRenameCallback(callback, arg);
00506 }
00507
00508 int JackDebugClient::SetSessionCallback(JackSessionCallback callback, void *arg)
00509 {
00510 CheckClient("SetSessionCallback");
00511 return fClient->SetSessionCallback(callback, arg);
00512 }
00513
00514 int JackDebugClient::SetLatencyCallback(JackLatencyCallback callback, void *arg)
00515 {
00516 CheckClient("SetLatencyCallback");
00517 return fClient->SetLatencyCallback(callback, arg);
00518 }
00519
00520 jack_session_command_t* JackDebugClient::SessionNotify(const char* target, jack_session_event_type_t type, const char* path)
00521 {
00522 CheckClient("SessionNotify");
00523 return fClient->SessionNotify(target, type, path);
00524 }
00525
00526 int JackDebugClient::SessionReply(jack_session_event_t* ev)
00527 {
00528 CheckClient("SessionReply");
00529 return fClient->SessionReply(ev);
00530 }
00531
00532 char* JackDebugClient::GetUUIDForClientName(const char* client_name)
00533 {
00534 CheckClient("GetUUIDForClientName");
00535 return fClient->GetUUIDForClientName(client_name);
00536 }
00537
00538 char* JackDebugClient::GetClientNameByUUID(const char* uuid)
00539 {
00540 CheckClient("GetClientNameByUUID");
00541 return fClient->GetClientNameByUUID(uuid);
00542 }
00543
00544 int JackDebugClient::ReserveClientName(const char* client_name, const char* uuid)
00545 {
00546 CheckClient("ReserveClientName");
00547 return fClient->ReserveClientName(client_name, uuid);
00548 }
00549
00550 int JackDebugClient::ClientHasSessionCallback(const char* client_name)
00551 {
00552 CheckClient("ClientHasSessionCallback");
00553 return fClient->ClientHasSessionCallback(client_name);
00554 }
00555
00556 JackClientControl* JackDebugClient::GetClientControl() const
00557 {
00558 CheckClient("GetClientControl");
00559 return fClient->GetClientControl();
00560 }
00561
00562
00563 char* JackDebugClient::GetInternalClientName(int ref)
00564 {
00565 CheckClient("GetInternalClientName");
00566 return fClient->GetInternalClientName(ref);
00567 }
00568
00569 int JackDebugClient::InternalClientHandle(const char* client_name, jack_status_t* status)
00570 {
00571 CheckClient("InternalClientHandle");
00572 return fClient->InternalClientHandle(client_name, status);
00573 }
00574
00575 int JackDebugClient::InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va)
00576 {
00577 CheckClient("InternalClientLoad");
00578 return fClient->InternalClientLoad(client_name, options, status, va);
00579 }
00580
00581 void JackDebugClient::InternalClientUnload(int ref, jack_status_t* status)
00582 {
00583 CheckClient("InternalClientUnload");
00584 fClient->InternalClientUnload(ref, status);
00585 }
00586
00587 }
00588