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.

458 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)
  67. {
  68. int Tidport;
  69. Tidport = fClient->Open(name);
  70. char provstr[256];
  71. char buffer[256];
  72. time_t curtime;
  73. struct tm *loctime;
  74. /* Get the current time. */
  75. curtime = time (NULL);
  76. /* Convert it to local time representation. */
  77. loctime = localtime (&curtime);
  78. strftime (buffer, 256, "%I-%M", loctime);
  79. sprintf(provstr, "JackClientDebug-%s-%s.log", name, buffer);
  80. fStream = new ofstream(provstr, ios_base::ate);
  81. if (fStream->is_open()) {
  82. if (Tidport == -1) {
  83. *fStream << "Trying to Open Client with name '" << name << "' with bad result (client not opened)." << Tidport << endl;
  84. } else {
  85. *fStream << "Open Client with name '" << name << "'." << endl;
  86. }
  87. } else {
  88. JackLog("JackDebugClient::Open : cannot open log file\n");
  89. }
  90. strcpy(fClientName, name);
  91. return Tidport;
  92. }
  93. int JackDebugClient::Close()
  94. {
  95. fIsClosed++;
  96. *fStream << "Client '" << fClientName << "' was Closed" << endl;
  97. return fClient->Close();
  98. }
  99. pthread_t JackDebugClient::GetThreadID()
  100. {
  101. return fClient->GetThreadID();
  102. }
  103. JackGraphManager* JackDebugClient::GetGraphManager() const
  104. {
  105. return fClient->GetGraphManager();
  106. }
  107. JackEngineControl* JackDebugClient::GetEngineControl() const
  108. {
  109. return fClient->GetEngineControl();
  110. }
  111. /*!
  112. \brief Notification received from the server.
  113. */
  114. int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, int value)
  115. {
  116. return fClient->ClientNotify( refnum, name, notify, sync, value);
  117. }
  118. int JackDebugClient::Activate()
  119. {
  120. int Tidport;
  121. Tidport = fClient->Activate();
  122. fIsActivated++;
  123. if (fIsDeactivated)
  124. *fStream << "Client '" << fClientName << "' call activate a new time (it already call 'activate' previously)." << endl;
  125. *fStream << "Client '" << fClientName << "' Activated" << endl;
  126. if (Tidport != 0)
  127. *fStream << "Client '" << fClientName << "' try to activate but server return " << Tidport << " ." << endl;
  128. return Tidport;
  129. }
  130. int JackDebugClient::Deactivate()
  131. {
  132. int Tidport;
  133. Tidport = fClient->Deactivate();
  134. fIsDeactivated++;
  135. if (fIsActivated == 0)
  136. *fStream << "Client '" << fClientName << "' deactivate while it hasn't been previoulsy activated !" << endl;
  137. *fStream << "Client '" << fClientName << "' Deactivated" << endl;
  138. if (Tidport != 0)
  139. *fStream << "Client '" << fClientName << "' try to deactivate but server return " << Tidport << " ." << endl;
  140. return Tidport;
  141. }
  142. //-----------------
  143. // Port management
  144. //-----------------
  145. int JackDebugClient::PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size)
  146. {
  147. int Tidport;
  148. Tidport = fClient->PortRegister(port_name, port_type, flags, buffer_size);
  149. if (Tidport <= 0) {
  150. *fStream << "Client '" << fClientName << "' try port Register ('" << port_name << "') and server return error " << Tidport << " ." << endl;
  151. } else {
  152. if (fTotalPortNumber < MAX_PORT_HISTORY) {
  153. fPortList[fTotalPortNumber].idport = Tidport;
  154. strcpy(fPortList[fTotalPortNumber].name, port_name);
  155. fPortList[fTotalPortNumber].IsConnected = 0;
  156. fPortList[fTotalPortNumber].IsUnregistrated = 0;
  157. } else {
  158. *fStream << "!!! WARNING !!! History is full : no more port history will be recorded." << endl;
  159. }
  160. fTotalPortNumber++;
  161. fOpenPortNumber++;
  162. *fStream << "Client '" << fClientName << "' port Register with portname '" << port_name << " port " << Tidport << "' ." << endl;
  163. }
  164. return Tidport;
  165. }
  166. int JackDebugClient::PortUnRegister(jack_port_id_t port_index)
  167. {
  168. int Tidport;
  169. Tidport = fClient->PortUnRegister(port_index);
  170. fOpenPortNumber--;
  171. int i;
  172. for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
  173. if (fPortList[i].idport == port_index) { // We found the last record
  174. if (fPortList[i].IsUnregistrated != 0)
  175. *fStream << "!!! ERROR !!! : '" << fClientName << "' id deregistering port '" << fPortList[i].name << "' that have already been unregistered !" << endl;
  176. fPortList[i].IsUnregistrated++;
  177. break;
  178. }
  179. }
  180. if (i == 0) // Port is not found
  181. *fStream << "JackClientDebug : PortUnregister : port " << port_index << " was not previously registered !" << endl;
  182. if (Tidport != 0)
  183. *fStream << "Client '" << fClientName << "' try to do PortUnregister and server return " << Tidport << " )." << endl;
  184. *fStream << "Client '" << fClientName << "' unregister port '" << port_index << "'." << endl;
  185. return Tidport;
  186. }
  187. int JackDebugClient::PortConnect(const char* src, const char* dst)
  188. {
  189. if (!(fIsActivated))
  190. *fStream << "!!! ERROR !!! Trying to connect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl;
  191. int Tidport;
  192. int i;
  193. Tidport = fClient->PortConnect( src, dst);
  194. for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
  195. if (strcmp(fPortList[i].name, src) == 0) { // We found the last record in sources
  196. if (fPortList[i].IsUnregistrated != 0)
  197. *fStream << "!!! ERROR !!! Connecting port " << src << " previoulsy unregistered !" << endl;
  198. fPortList[i].IsConnected++;
  199. *fStream << "Connecting port " << src << " to " << dst << ". ";
  200. break;
  201. } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest
  202. if (fPortList[i].IsUnregistrated != 0)
  203. *fStream << "!!! ERROR !!! Connecting port " << dst << " previoulsy unregistered !" << endl;
  204. fPortList[i].IsConnected++;
  205. *fStream << "Connecting port " << src << " to " << dst << ". ";
  206. break;
  207. }
  208. }
  209. if (i == 0) // Port is not found
  210. *fStream << "JackClientDebug : PortConnect : port was not found in debug database !" << endl;
  211. if (Tidport != 0)
  212. *fStream << "Client '" << fClientName << "' try to do PortConnect but server return " << Tidport << " ." << endl;
  213. //*fStream << "Client Port Connect done with names" << endl;
  214. return Tidport;
  215. }
  216. int JackDebugClient::PortDisconnect(const char* src, const char* dst)
  217. {
  218. if (!(fIsActivated))
  219. *fStream << "!!! ERROR !!! Trying to disconnect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl;
  220. int Tidport;
  221. Tidport = fClient->PortDisconnect( src, dst);
  222. int i;
  223. for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
  224. if (strcmp(fPortList[i].name, src) == 0) { // We found the record in sources
  225. if (fPortList[i].IsUnregistrated != 0)
  226. *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl;
  227. fPortList[i].IsConnected--;
  228. *fStream << "disconnecting port " << src << ". ";
  229. break;
  230. } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest
  231. if (fPortList[i].IsUnregistrated != 0)
  232. *fStream << "!!! ERROR !!! : Disonnecting port " << dst << " previoulsy unregistered !" << endl;
  233. fPortList[i].IsConnected--;
  234. *fStream << "disconnecting port " << dst << ". ";
  235. break;
  236. }
  237. }
  238. if (i == 0) // Port is not found
  239. *fStream << "JackClientDebug : PortDisConnect : port was not found in debug database !" << endl;
  240. if (Tidport != 0)
  241. *fStream << "Client '" << fClientName << "' try to do PortDisconnect but server return " << Tidport << " ." << endl;
  242. //*fStream << "Client Port Disconnect done." << endl;
  243. return Tidport;
  244. }
  245. int JackDebugClient::PortConnect(jack_port_id_t src, jack_port_id_t dst)
  246. {
  247. if (!(fIsActivated))
  248. *fStream << "!!! ERROR !!! : Trying to connect port " << src << " to " << dst << " while the client has not been activated !" << endl;
  249. int Tidport;
  250. Tidport = fClient->PortConnect(src, dst);
  251. int i;
  252. for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
  253. if (fPortList[i].idport == src) { // We found the record in sources
  254. if (fPortList[i].IsUnregistrated != 0)
  255. *fStream << "!!! ERROR !!! : Connecting port " << src << " previoulsy unregistered !" << endl;
  256. fPortList[i].IsConnected++;
  257. *fStream << "Connecting port " << src << ". ";
  258. break;
  259. } else if (fPortList[i].idport == dst) { // We found the record in dest
  260. if (fPortList[i].IsUnregistrated != 0)
  261. *fStream << "!!! ERROR !!! : Connecting port " << dst << " previoulsy unregistered !" << endl;
  262. fPortList[i].IsConnected++;
  263. *fStream << "Connecting port " << dst << ". ";
  264. break;
  265. }
  266. }
  267. if (i == 0) // Port is not found
  268. *fStream << "JackClientDebug : PortConnect : port was not found in debug database !" << endl;
  269. if (Tidport == -1)
  270. *fStream << "Client '" << fClientName << "' try to do Portconnect but server return " << Tidport << " ." << endl;
  271. //*fStream << "Client Port Connect with ID done." << endl;
  272. return Tidport;
  273. }
  274. int JackDebugClient::PortDisconnect(jack_port_id_t src)
  275. {
  276. if (!(fIsActivated))
  277. *fStream << "!!! ERROR !!! : Trying to disconnect port " << src << " while that client has not been activated !" << endl;
  278. int Tidport;
  279. Tidport = fClient->PortDisconnect(src);
  280. int i;
  281. for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
  282. if (fPortList[i].idport == src) { // We found the record in sources
  283. if (fPortList[i].IsUnregistrated != 0)
  284. *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl;
  285. fPortList[i].IsConnected--;
  286. *fStream << "Disconnecting port " << src << ". " << endl;
  287. break;
  288. }
  289. }
  290. if (i == 0) // Port is not found
  291. *fStream << "JackClientDebug : PortDisconnect : port was not found in debug database !" << endl;
  292. if (Tidport != 0)
  293. *fStream << "Client '" << fClientName << "' try to do PortDisconnect but server return " << Tidport << " ." << endl;
  294. //*fStream << "Client Port Disconnect with ID done." << endl;
  295. return Tidport;
  296. }
  297. int JackDebugClient::PortIsMine(jack_port_id_t port_index)
  298. {
  299. return fClient->PortIsMine(port_index);
  300. }
  301. //--------------------
  302. // Context management
  303. //--------------------
  304. int JackDebugClient::SetBufferSize(jack_nframes_t nframes)
  305. {
  306. return fClient->SetBufferSize(nframes);
  307. }
  308. int JackDebugClient::SetFreeWheel(int onoff)
  309. {
  310. return fClient->SetFreeWheel(onoff);
  311. }
  312. /*
  313. ShutDown is called:
  314. - from the RT thread when Execute method fails
  315. - possibly from a "closed" notification channel
  316. (Not needed since the synch object used (Sema of Fifo will fails when server quits... see ShutDown))
  317. */
  318. void JackDebugClient::ShutDown()
  319. {
  320. fClient->ShutDown();
  321. }
  322. //---------------------
  323. // Transport management
  324. //---------------------
  325. int JackDebugClient::ReleaseTimebase()
  326. {
  327. return fClient->ReleaseTimebase();
  328. }
  329. int JackDebugClient::SetSyncCallback(JackSyncCallback sync_callback, void* arg)
  330. {
  331. return fClient->SetSyncCallback(sync_callback, arg);
  332. }
  333. int JackDebugClient::SetSyncTimeout(jack_time_t timeout)
  334. {
  335. return fClient->SetSyncTimeout(timeout);
  336. }
  337. int JackDebugClient::SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg)
  338. {
  339. return fClient->SetTimebaseCallback( conditional, timebase_callback, arg);
  340. }
  341. int JackDebugClient::TransportLocate(jack_nframes_t frame)
  342. {
  343. return fClient->TransportLocate(frame);
  344. }
  345. jack_transport_state_t JackDebugClient::TransportQuery(jack_position_t* pos)
  346. {
  347. return fClient->TransportQuery(pos);
  348. }
  349. jack_nframes_t JackDebugClient::GetCurrentTransportFrame()
  350. {
  351. return fClient->GetCurrentTransportFrame();
  352. }
  353. int JackDebugClient::TransportReposition(jack_position_t* pos)
  354. {
  355. return fClient->TransportReposition(pos);
  356. }
  357. void JackDebugClient::TransportStart()
  358. {
  359. fClient->TransportStart();
  360. }
  361. void JackDebugClient::TransportStop()
  362. {
  363. fClient->TransportStop();
  364. }
  365. //---------------------
  366. // Callback management
  367. //---------------------
  368. void JackDebugClient::OnShutdown(JackShutdownCallback callback, void *arg)
  369. {
  370. fClient->OnShutdown(callback, arg);
  371. }
  372. int JackDebugClient::SetProcessCallback(JackProcessCallback callback, void *arg)
  373. {
  374. return fClient->SetProcessCallback( callback, arg);
  375. }
  376. int JackDebugClient::SetXRunCallback(JackXRunCallback callback, void *arg)
  377. {
  378. return fClient->SetXRunCallback(callback, arg);
  379. }
  380. int JackDebugClient::SetInitCallback(JackThreadInitCallback callback, void *arg)
  381. {
  382. return fClient->SetInitCallback(callback, arg);
  383. }
  384. int JackDebugClient::SetGraphOrderCallback(JackGraphOrderCallback callback, void *arg)
  385. {
  386. return fClient->SetGraphOrderCallback(callback, arg);
  387. }
  388. int JackDebugClient::SetBufferSizeCallback(JackBufferSizeCallback callback, void *arg)
  389. {
  390. return fClient->SetBufferSizeCallback(callback, arg);
  391. }
  392. int JackDebugClient::SetFreewheelCallback(JackFreewheelCallback callback, void *arg)
  393. {
  394. return fClient->SetFreewheelCallback(callback, arg);
  395. }
  396. int JackDebugClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback, void *arg)
  397. {
  398. return fClient->SetPortRegistrationCallback(callback, arg);
  399. }
  400. JackClientControl* JackDebugClient::GetClientControl() const
  401. {
  402. return fClient->GetClientControl();
  403. }
  404. } // end of namespace