jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

497 lines
17KB

  1. /*
  2. Copyright (C) 2004-2006 Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include "JackDebugClient.h"
  16. #include "JackError.h"
  17. #include <iostream>
  18. #include <iomanip>
  19. #include <sstream>
  20. #include <fstream>
  21. #include <string>
  22. #include <time.h>
  23. using namespace std;
  24. namespace Jack
  25. {
  26. JackDebugClient::JackDebugClient(JackClient * client)
  27. {
  28. fTotalPortNumber = 1; // The total number of port opened and maybe closed. Historical view.
  29. fOpenPortNumber = 0; // The current number of opened port.
  30. fIsActivated = 0;
  31. fIsDeactivated = 0;
  32. fIsClosed = 0;
  33. fClient = client;
  34. }
  35. JackDebugClient::~JackDebugClient()
  36. {
  37. fTotalPortNumber--; // fTotalPortNumber start at 1
  38. *fStream << endl << endl << "----------------------------------- JackDebugClient summary ------------------------------- " << endl << endl;
  39. *fStream << "Client flags ( 1:yes / 0:no ) :" << endl;
  40. *fStream << setw(5) << "- Client call activated : " << fIsActivated << endl;
  41. *fStream << setw(5) << "- Client call deactivated : " << fIsDeactivated << endl;
  42. *fStream << setw(5) << "- Client call closed : " << fIsClosed << endl;
  43. *fStream << setw(5) << "- Total number of instantiated port : " << fTotalPortNumber << endl;
  44. *fStream << setw(5) << "- Number of port remaining open when exiting client : " << fOpenPortNumber << endl;
  45. if (fOpenPortNumber != 0)
  46. *fStream << "!!! WARNING !!! Some ports have not been unregistrated ! Incorrect exiting !" << endl;
  47. if (fIsDeactivated != fIsActivated)
  48. *fStream << "!!! ERROR !!! Client seem do not perform symetric activation-deactivation ! (not the same number of activate and deactivate)" << endl;
  49. if (fIsClosed == 0)
  50. *fStream << "!!! ERROR !!! Client have not been closed with jack_client_close() !" << endl;
  51. *fStream << endl << endl << "---------------------------- JackDebugClient detailed port summary ------------------------ " << endl << endl;
  52. //for (int i = 0; i < fTotalPortNumber ; i++) {
  53. for (int i = 1; i <= fTotalPortNumber ; i++) {
  54. *fStream << endl << "Port index (internal debug test value) : " << i << endl;
  55. *fStream << setw(5) << "- Name : " << fPortList[i].name << endl;
  56. *fStream << setw(5) << "- idport : " << fPortList[i].idport << endl;
  57. *fStream << setw(5) << "- IsConnected : " << fPortList[i].IsConnected << endl;
  58. *fStream << setw(5) << "- IsUnregistrated : " << fPortList[i].IsUnregistrated << endl;
  59. if (fPortList[i].IsUnregistrated == 0)
  60. *fStream << "!!! WARNING !!! Port have not been unregistrated ! Incorrect exiting !" << endl;
  61. }
  62. *fStream << "delete object JackDebugClient : end of tracing" << endl;
  63. delete fStream;
  64. delete fClient;
  65. }
  66. int JackDebugClient::Open(const char* name, jack_options_t options, jack_status_t* status)
  67. {
  68. int res = fClient->Open(name, options, status);
  69. char provstr[256];
  70. char buffer[256];
  71. time_t curtime;
  72. struct tm *loctime;
  73. /* Get the current time. */
  74. curtime = time (NULL);
  75. /* Convert it to local time representation. */
  76. loctime = localtime (&curtime);
  77. strftime (buffer, 256, "%I-%M", loctime);
  78. sprintf(provstr, "JackClientDebug-%s-%s.log", name, buffer);
  79. fStream = new ofstream(provstr, ios_base::ate);
  80. if (fStream->is_open()) {
  81. if (res == -1) {
  82. *fStream << "Trying to open client with name '" << name << "' with bad result (client not opened)." << res << endl;
  83. } else {
  84. *fStream << "Open client with name '" << name << "'." << endl;
  85. }
  86. } else {
  87. JackLog("JackDebugClient::Open : cannot open log file\n");
  88. }
  89. strcpy(fClientName, name);
  90. return res;
  91. }
  92. int JackDebugClient::Close()
  93. {
  94. fIsClosed++;
  95. *fStream << "Client '" << fClientName << "' was closed" << endl;
  96. return fClient->Close();
  97. }
  98. void JackDebugClient::CheckClient() const
  99. {
  100. if (fIsClosed > 0) {
  101. *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed !" << endl;
  102. *fStream << "This is likely to cause crash !'" << endl;
  103. }
  104. }
  105. pthread_t JackDebugClient::GetThreadID()
  106. {
  107. CheckClient();
  108. return fClient->GetThreadID();
  109. }
  110. JackGraphManager* JackDebugClient::GetGraphManager() const
  111. {
  112. CheckClient();
  113. return fClient->GetGraphManager();
  114. }
  115. JackEngineControl* JackDebugClient::GetEngineControl() const
  116. {
  117. CheckClient();
  118. return fClient->GetEngineControl();
  119. }
  120. /*!
  121. \brief Notification received from the server.
  122. */
  123. int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, int value)
  124. {
  125. CheckClient();
  126. return fClient->ClientNotify( refnum, name, notify, sync, value);
  127. }
  128. int JackDebugClient::Activate()
  129. {
  130. CheckClient();
  131. int res = fClient->Activate();
  132. fIsActivated++;
  133. if (fIsDeactivated)
  134. *fStream << "Client '" << fClientName << "' call activate a new time (it already call 'activate' previously)." << endl;
  135. *fStream << "Client '" << fClientName << "' Activated" << endl;
  136. if (res != 0)
  137. *fStream << "Client '" << fClientName << "' try to activate but server return " << res << " ." << endl;
  138. return res;
  139. }
  140. int JackDebugClient::Deactivate()
  141. {
  142. CheckClient();
  143. int res = fClient->Deactivate();
  144. fIsDeactivated++;
  145. if (fIsActivated == 0)
  146. *fStream << "Client '" << fClientName << "' deactivate while it hasn't been previoulsy activated !" << endl;
  147. *fStream << "Client '" << fClientName << "' Deactivated" << endl;
  148. if (res != 0)
  149. *fStream << "Client '" << fClientName << "' try to deactivate but server return " << res << " ." << endl;
  150. return res;
  151. }
  152. //-----------------
  153. // Port management
  154. //-----------------
  155. int JackDebugClient::PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size)
  156. {
  157. CheckClient();
  158. int res = fClient->PortRegister(port_name, port_type, flags, buffer_size);
  159. if (res <= 0) {
  160. *fStream << "Client '" << fClientName << "' try port register ('" << port_name << "') and server return error " << res << " ." << endl;
  161. } else {
  162. if (fTotalPortNumber < MAX_PORT_HISTORY) {
  163. fPortList[fTotalPortNumber].idport = res;
  164. strcpy(fPortList[fTotalPortNumber].name, port_name);
  165. fPortList[fTotalPortNumber].IsConnected = 0;
  166. fPortList[fTotalPortNumber].IsUnregistrated = 0;
  167. } else {
  168. *fStream << "!!! WARNING !!! History is full : no more port history will be recorded." << endl;
  169. }
  170. fTotalPortNumber++;
  171. fOpenPortNumber++;
  172. *fStream << "Client '" << fClientName << "' port register with portname '" << port_name << " port " << res << "' ." << endl;
  173. }
  174. return res;
  175. }
  176. int JackDebugClient::PortUnRegister(jack_port_id_t port_index)
  177. {
  178. CheckClient();
  179. int res = fClient->PortUnRegister(port_index);
  180. fOpenPortNumber--;
  181. int i;
  182. for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
  183. if (fPortList[i].idport == port_index) { // We found the last record
  184. if (fPortList[i].IsUnregistrated != 0)
  185. *fStream << "!!! ERROR !!! : '" << fClientName << "' id deregistering port '" << fPortList[i].name << "' that have already been unregistered !" << endl;
  186. fPortList[i].IsUnregistrated++;
  187. break;
  188. }
  189. }
  190. if (i == 0) // Port is not found
  191. *fStream << "JackClientDebug : PortUnregister : port " << port_index << " was not previously registered !" << endl;
  192. if (res != 0)
  193. *fStream << "Client '" << fClientName << "' try to do PortUnregister and server return " << res << " )." << endl;
  194. *fStream << "Client '" << fClientName << "' unregister port '" << port_index << "'." << endl;
  195. return res;
  196. }
  197. int JackDebugClient::PortConnect(const char* src, const char* dst)
  198. {
  199. CheckClient();
  200. if (!fIsActivated)
  201. *fStream << "!!! ERROR !!! Trying to connect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl;
  202. int i;
  203. int res = fClient->PortConnect( src, dst);
  204. for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
  205. if (strcmp(fPortList[i].name, src) == 0) { // We found the last record in sources
  206. if (fPortList[i].IsUnregistrated != 0)
  207. *fStream << "!!! ERROR !!! Connecting port " << src << " previoulsy unregistered !" << endl;
  208. fPortList[i].IsConnected++;
  209. *fStream << "Connecting port " << src << " to " << dst << ". ";
  210. break;
  211. } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest
  212. if (fPortList[i].IsUnregistrated != 0)
  213. *fStream << "!!! ERROR !!! Connecting port " << dst << " previoulsy unregistered !" << endl;
  214. fPortList[i].IsConnected++;
  215. *fStream << "Connecting port " << src << " to " << dst << ". ";
  216. break;
  217. }
  218. }
  219. if (i == 0) // Port is not found
  220. *fStream << "JackClientDebug : PortConnect : port was not found in debug database !" << endl;
  221. if (res != 0)
  222. *fStream << "Client '" << fClientName << "' try to do PortConnect but server return " << res << " ." << endl;
  223. //*fStream << "Client Port Connect done with names" << endl;
  224. return res;
  225. }
  226. int JackDebugClient::PortDisconnect(const char* src, const char* dst)
  227. {
  228. CheckClient();
  229. if (!fIsActivated)
  230. *fStream << "!!! ERROR !!! Trying to disconnect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl;
  231. int res = fClient->PortDisconnect( src, dst);
  232. int i;
  233. for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
  234. if (strcmp(fPortList[i].name, src) == 0) { // We found the record in sources
  235. if (fPortList[i].IsUnregistrated != 0)
  236. *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl;
  237. fPortList[i].IsConnected--;
  238. *fStream << "disconnecting port " << src << ". ";
  239. break;
  240. } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest
  241. if (fPortList[i].IsUnregistrated != 0)
  242. *fStream << "!!! ERROR !!! : Disonnecting port " << dst << " previoulsy unregistered !" << endl;
  243. fPortList[i].IsConnected--;
  244. *fStream << "disconnecting port " << dst << ". ";
  245. break;
  246. }
  247. }
  248. if (i == 0) // Port is not found
  249. *fStream << "JackClientDebug : PortDisConnect : port was not found in debug database !" << endl;
  250. if (res != 0)
  251. *fStream << "Client '" << fClientName << "' try to do PortDisconnect but server return " << res << " ." << endl;
  252. //*fStream << "Client Port Disconnect done." << endl;
  253. return res;
  254. }
  255. int JackDebugClient::PortConnect(jack_port_id_t src, jack_port_id_t dst)
  256. {
  257. CheckClient();
  258. if (!fIsActivated)
  259. *fStream << "!!! ERROR !!! : Trying to connect port " << src << " to " << dst << " while the client has not been activated !" << endl;
  260. int res = fClient->PortConnect(src, dst);
  261. int i;
  262. for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
  263. if (fPortList[i].idport == src) { // We found the record in sources
  264. if (fPortList[i].IsUnregistrated != 0)
  265. *fStream << "!!! ERROR !!! : Connecting port " << src << " previoulsy unregistered !" << endl;
  266. fPortList[i].IsConnected++;
  267. *fStream << "Connecting port " << src << ". ";
  268. break;
  269. } else if (fPortList[i].idport == dst) { // We found the record in dest
  270. if (fPortList[i].IsUnregistrated != 0)
  271. *fStream << "!!! ERROR !!! : Connecting port " << dst << " previoulsy unregistered !" << endl;
  272. fPortList[i].IsConnected++;
  273. *fStream << "Connecting port " << dst << ". ";
  274. break;
  275. }
  276. }
  277. if (i == 0) // Port is not found
  278. *fStream << "JackClientDebug : PortConnect : port was not found in debug database !" << endl;
  279. if (res == -1)
  280. *fStream << "Client '" << fClientName << "' try to do Portconnect but server return " << res << " ." << endl;
  281. //*fStream << "Client Port Connect with ID done." << endl;
  282. return res;
  283. }
  284. int JackDebugClient::PortDisconnect(jack_port_id_t src)
  285. {
  286. CheckClient();
  287. if (!fIsActivated)
  288. *fStream << "!!! ERROR !!! : Trying to disconnect port " << src << " while that client has not been activated !" << endl;
  289. int res = fClient->PortDisconnect(src);
  290. int i;
  291. for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
  292. if (fPortList[i].idport == src) { // We found the record in sources
  293. if (fPortList[i].IsUnregistrated != 0)
  294. *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl;
  295. fPortList[i].IsConnected--;
  296. *fStream << "Disconnecting port " << src << ". " << endl;
  297. break;
  298. }
  299. }
  300. if (i == 0) // Port is not found
  301. *fStream << "JackClientDebug : PortDisconnect : port was not found in debug database !" << endl;
  302. if (res != 0)
  303. *fStream << "Client '" << fClientName << "' try to do PortDisconnect but server return " << res << " ." << endl;
  304. //*fStream << "Client Port Disconnect with ID done." << endl;
  305. return res;
  306. }
  307. int JackDebugClient::PortIsMine(jack_port_id_t port_index)
  308. {
  309. CheckClient();
  310. return fClient->PortIsMine(port_index);
  311. }
  312. //--------------------
  313. // Context management
  314. //--------------------
  315. int JackDebugClient::SetBufferSize(jack_nframes_t buffer_size)
  316. {
  317. CheckClient();
  318. return fClient->SetBufferSize(buffer_size);
  319. }
  320. int JackDebugClient::SetFreeWheel(int onoff)
  321. {
  322. CheckClient();
  323. return fClient->SetFreeWheel(onoff);
  324. }
  325. /*
  326. ShutDown is called:
  327. - from the RT thread when Execute method fails
  328. - possibly from a "closed" notification channel
  329. (Not needed since the synch object used (Sema of Fifo will fails when server quits... see ShutDown))
  330. */
  331. void JackDebugClient::ShutDown()
  332. {
  333. fClient->ShutDown();
  334. }
  335. //---------------------
  336. // Transport management
  337. //---------------------
  338. int JackDebugClient::ReleaseTimebase()
  339. {
  340. CheckClient();
  341. return fClient->ReleaseTimebase();
  342. }
  343. int JackDebugClient::SetSyncCallback(JackSyncCallback sync_callback, void* arg)
  344. {
  345. CheckClient();
  346. return fClient->SetSyncCallback(sync_callback, arg);
  347. }
  348. int JackDebugClient::SetSyncTimeout(jack_time_t timeout)
  349. {
  350. CheckClient();
  351. return fClient->SetSyncTimeout(timeout);
  352. }
  353. int JackDebugClient::SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg)
  354. {
  355. CheckClient();
  356. return fClient->SetTimebaseCallback( conditional, timebase_callback, arg);
  357. }
  358. int JackDebugClient::TransportLocate(jack_nframes_t frame)
  359. {
  360. CheckClient();
  361. return fClient->TransportLocate(frame);
  362. }
  363. jack_transport_state_t JackDebugClient::TransportQuery(jack_position_t* pos)
  364. {
  365. CheckClient();
  366. return fClient->TransportQuery(pos);
  367. }
  368. jack_nframes_t JackDebugClient::GetCurrentTransportFrame()
  369. {
  370. CheckClient();
  371. return fClient->GetCurrentTransportFrame();
  372. }
  373. int JackDebugClient::TransportReposition(jack_position_t* pos)
  374. {
  375. CheckClient();
  376. return fClient->TransportReposition(pos);
  377. }
  378. void JackDebugClient::TransportStart()
  379. {
  380. CheckClient();
  381. fClient->TransportStart();
  382. }
  383. void JackDebugClient::TransportStop()
  384. {
  385. CheckClient();
  386. fClient->TransportStop();
  387. }
  388. //---------------------
  389. // Callback management
  390. //---------------------
  391. void JackDebugClient::OnShutdown(JackShutdownCallback callback, void *arg)
  392. {
  393. CheckClient();
  394. fClient->OnShutdown(callback, arg);
  395. }
  396. int JackDebugClient::SetProcessCallback(JackProcessCallback callback, void *arg)
  397. {
  398. CheckClient();
  399. return fClient->SetProcessCallback( callback, arg);
  400. }
  401. int JackDebugClient::SetXRunCallback(JackXRunCallback callback, void *arg)
  402. {
  403. CheckClient();
  404. return fClient->SetXRunCallback(callback, arg);
  405. }
  406. int JackDebugClient::SetInitCallback(JackThreadInitCallback callback, void *arg)
  407. {
  408. CheckClient();
  409. return fClient->SetInitCallback(callback, arg);
  410. }
  411. int JackDebugClient::SetGraphOrderCallback(JackGraphOrderCallback callback, void *arg)
  412. {
  413. CheckClient();
  414. return fClient->SetGraphOrderCallback(callback, arg);
  415. }
  416. int JackDebugClient::SetBufferSizeCallback(JackBufferSizeCallback callback, void *arg)
  417. {
  418. CheckClient();
  419. return fClient->SetBufferSizeCallback(callback, arg);
  420. }
  421. int JackDebugClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback, void* arg)
  422. {
  423. CheckClient();
  424. return fClient->SetClientRegistrationCallback(callback, arg);
  425. }
  426. int JackDebugClient::SetFreewheelCallback(JackFreewheelCallback callback, void *arg)
  427. {
  428. CheckClient();
  429. return fClient->SetFreewheelCallback(callback, arg);
  430. }
  431. int JackDebugClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback, void *arg)
  432. {
  433. CheckClient();
  434. return fClient->SetPortRegistrationCallback(callback, arg);
  435. }
  436. JackClientControl* JackDebugClient::GetClientControl() const
  437. {
  438. CheckClient();
  439. return fClient->GetClientControl();
  440. }
  441. } // end of namespace