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.

810 lines
33KB

  1. /*
  2. Copyright (C) 2008-2011 Romain Moret at 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 "JackCompilerDeps.h"
  16. #include "driver_interface.h"
  17. #include "JackNetDriver.h"
  18. #include "JackEngineControl.h"
  19. #include "JackLockedEngine.h"
  20. #include "JackWaitThreadedDriver.h"
  21. using namespace std;
  22. namespace Jack
  23. {
  24. JackNetDriver::JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
  25. const char* ip, int udp_port, int mtu, int midi_input_ports, int midi_output_ports,
  26. char* net_name, uint transport_sync, int network_latency, int celt_encoding, int opus_encoding)
  27. : JackWaiterDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port)
  28. {
  29. jack_log("JackNetDriver::JackNetDriver ip %s, port %d", ip, udp_port);
  30. // Use the hostname if no name parameter was given
  31. if (strcmp(net_name, "") == 0) {
  32. GetHostName(net_name, JACK_CLIENT_NAME_SIZE);
  33. }
  34. fParams.fMtu = mtu;
  35. fWantedMIDICaptureChannels = midi_input_ports;
  36. fWantedMIDIPlaybackChannels = midi_output_ports;
  37. if (celt_encoding > 0) {
  38. fParams.fSampleEncoder = JackCeltEncoder;
  39. fParams.fKBps = celt_encoding;
  40. } else if (opus_encoding > 0) {
  41. fParams.fSampleEncoder = JackOpusEncoder;
  42. fParams.fKBps = opus_encoding;
  43. } else {
  44. fParams.fSampleEncoder = JackFloatEncoder;
  45. //fParams.fSampleEncoder = JackIntEncoder;
  46. }
  47. strcpy(fParams.fName, net_name);
  48. fSocket.GetName(fParams.fSlaveNetName);
  49. fParams.fTransportSync = transport_sync;
  50. fParams.fNetworkLatency = network_latency;
  51. fSendTransportData.fState = -1;
  52. fReturnTransportData.fState = -1;
  53. fLastTransportState = -1;
  54. fLastTimebaseMaster = -1;
  55. fMidiCapturePortList = NULL;
  56. fMidiPlaybackPortList = NULL;
  57. fWantedAudioCaptureChannels = -1;
  58. fWantedAudioPlaybackChannels = -1;
  59. #ifdef JACK_MONITOR
  60. fNetTimeMon = NULL;
  61. fRcvSyncUst = 0;
  62. #endif
  63. }
  64. JackNetDriver::~JackNetDriver()
  65. {
  66. delete[] fMidiCapturePortList;
  67. delete[] fMidiPlaybackPortList;
  68. #ifdef JACK_MONITOR
  69. delete fNetTimeMon;
  70. #endif
  71. }
  72. //open, close, attach and detach------------------------------------------------------
  73. int JackNetDriver::Open(jack_nframes_t buffer_size,
  74. jack_nframes_t samplerate,
  75. bool capturing,
  76. bool playing,
  77. int inchannels,
  78. int outchannels,
  79. bool monitor,
  80. const char* capture_driver_name,
  81. const char* playback_driver_name,
  82. jack_nframes_t capture_latency,
  83. jack_nframes_t playback_latency)
  84. {
  85. // Keep initial wanted values
  86. fWantedAudioCaptureChannels = inchannels;
  87. fWantedAudioPlaybackChannels = outchannels;
  88. return JackWaiterDriver::Open(buffer_size, samplerate,
  89. capturing, playing,
  90. inchannels, outchannels,
  91. monitor,
  92. capture_driver_name, playback_driver_name,
  93. capture_latency, playback_latency);
  94. }
  95. int JackNetDriver::Close()
  96. {
  97. #ifdef JACK_MONITOR
  98. if (fNetTimeMon) {
  99. fNetTimeMon->Save();
  100. }
  101. #endif
  102. FreeAll();
  103. return JackWaiterDriver::Close();
  104. }
  105. // Attach and Detach are defined as empty methods: port allocation is done when driver actually start (that is in Init)
  106. int JackNetDriver::Attach()
  107. {
  108. return 0;
  109. }
  110. int JackNetDriver::Detach()
  111. {
  112. return 0;
  113. }
  114. //init and restart--------------------------------------------------------------------
  115. /*
  116. JackNetDriver is wrapped in a JackWaitThreadedDriver decorator that behaves
  117. as a "dummy driver, until Init method returns.
  118. */
  119. bool JackNetDriver::Initialize()
  120. {
  121. jack_log("JackNetDriver::Initialize");
  122. SaveConnections(0);
  123. FreePorts();
  124. // New loading, but existing socket, restart the driver
  125. if (fSocket.IsSocket()) {
  126. jack_info("Restarting driver...");
  127. FreeAll();
  128. }
  129. // Set the parameters to send
  130. fParams.fSendAudioChannels = fWantedAudioCaptureChannels;
  131. fParams.fReturnAudioChannels = fWantedAudioPlaybackChannels;
  132. fParams.fSendMidiChannels = fWantedMIDICaptureChannels;
  133. fParams.fReturnMidiChannels = fWantedMIDIPlaybackChannels;
  134. fParams.fSlaveSyncMode = fEngineControl->fSyncMode;
  135. // Display some additional infos
  136. jack_info("NetDriver started in %s mode %s Master's transport sync.",
  137. (fParams.fSlaveSyncMode) ? "sync" : "async", (fParams.fTransportSync) ? "with" : "without");
  138. // Init network
  139. if (!JackNetSlaveInterface::Init()) {
  140. jack_error("Starting network fails...");
  141. return false;
  142. }
  143. // Set global parameters
  144. if (!SetParams()) {
  145. jack_error("SetParams error...");
  146. return false;
  147. }
  148. // If -1 at connection time for audio, in/out audio channels count is sent by the master
  149. fCaptureChannels = fParams.fSendAudioChannels;
  150. fPlaybackChannels = fParams.fReturnAudioChannels;
  151. // If -1 at connection time for MIDI, in/out MIDI channels count is sent by the master (in fParams struct)
  152. // Allocate midi ports lists
  153. delete[] fMidiCapturePortList;
  154. delete[] fMidiPlaybackPortList;
  155. fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels];
  156. fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels];
  157. assert(fMidiCapturePortList);
  158. assert(fMidiPlaybackPortList);
  159. for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
  160. fMidiCapturePortList[midi_port_index] = 0;
  161. }
  162. for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
  163. fMidiPlaybackPortList[midi_port_index] = 0;
  164. }
  165. // Register jack ports
  166. if (AllocPorts() != 0) {
  167. jack_error("Can't allocate ports.");
  168. return false;
  169. }
  170. // Init done, display parameters
  171. SessionParamsDisplay(&fParams);
  172. // Monitor
  173. #ifdef JACK_MONITOR
  174. string plot_name;
  175. // NetTimeMon
  176. plot_name = string(fParams.fName);
  177. plot_name += string("_slave");
  178. plot_name += (fEngineControl->fSyncMode) ? string("_sync") : string("_async");
  179. plot_name += string("_latency");
  180. fNetTimeMon = new JackGnuPlotMonitor<float>(128, 5, plot_name);
  181. string net_time_mon_fields[] =
  182. {
  183. string("sync decoded"),
  184. string("end of read"),
  185. string("start of write"),
  186. string("sync send"),
  187. string("end of write")
  188. };
  189. string net_time_mon_options[] =
  190. {
  191. string("set xlabel \"audio cycles\""),
  192. string("set ylabel \"% of audio cycle\"")
  193. };
  194. fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 5);
  195. #endif
  196. // Driver parametering
  197. JackTimedDriver::SetBufferSize(fParams.fPeriodSize);
  198. JackTimedDriver::SetSampleRate(fParams.fSampleRate);
  199. JackDriver::NotifyBufferSize(fParams.fPeriodSize);
  200. JackDriver::NotifySampleRate(fParams.fSampleRate);
  201. // Transport engine parametering
  202. fEngineControl->fTransport.SetNetworkSync(fParams.fTransportSync);
  203. RestoreConnections(0);
  204. return true;
  205. }
  206. void JackNetDriver::FreeAll()
  207. {
  208. FreePorts();
  209. delete[] fTxBuffer;
  210. delete[] fRxBuffer;
  211. delete fNetAudioCaptureBuffer;
  212. delete fNetAudioPlaybackBuffer;
  213. delete fNetMidiCaptureBuffer;
  214. delete fNetMidiPlaybackBuffer;
  215. delete[] fMidiCapturePortList;
  216. delete[] fMidiPlaybackPortList;
  217. fTxBuffer = NULL;
  218. fRxBuffer = NULL;
  219. fNetAudioCaptureBuffer = NULL;
  220. fNetAudioPlaybackBuffer = NULL;
  221. fNetMidiCaptureBuffer = NULL;
  222. fNetMidiPlaybackBuffer = NULL;
  223. fMidiCapturePortList = NULL;
  224. fMidiPlaybackPortList = NULL;
  225. #ifdef JACK_MONITOR
  226. delete fNetTimeMon;
  227. fNetTimeMon = NULL;
  228. #endif
  229. }
  230. void JackNetDriver::UpdateLatencies()
  231. {
  232. jack_latency_range_t input_range;
  233. jack_latency_range_t output_range;
  234. jack_latency_range_t monitor_range;
  235. for (int i = 0; i < fCaptureChannels; i++) {
  236. input_range.max = input_range.min = 0;
  237. fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range);
  238. }
  239. for (int i = 0; i < fPlaybackChannels; i++) {
  240. output_range.max = output_range.min = 0;
  241. fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range);
  242. if (fWithMonitorPorts) {
  243. monitor_range.min = monitor_range.max = 0;
  244. fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range);
  245. }
  246. }
  247. }
  248. //jack ports and buffers--------------------------------------------------------------
  249. int JackNetDriver::AllocPorts()
  250. {
  251. jack_log("JackNetDriver::AllocPorts fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
  252. /*
  253. fNetAudioCaptureBuffer fNetAudioPlaybackBuffer
  254. fSendAudioChannels fReturnAudioChannels
  255. fCapturePortList fPlaybackPortList
  256. fCaptureChannels ==> SLAVE ==> fPlaybackChannels
  257. "capture_" "playback_"
  258. */
  259. JackPort* port;
  260. jack_port_id_t port_index;
  261. char name[REAL_JACK_PORT_NAME_SIZE];
  262. char alias[REAL_JACK_PORT_NAME_SIZE];
  263. int audio_port_index;
  264. int midi_port_index;
  265. //audio
  266. for (audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) {
  267. snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, audio_port_index + 1);
  268. snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, audio_port_index + 1);
  269. if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE,
  270. CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
  271. jack_error("driver: cannot register port for %s", name);
  272. return -1;
  273. }
  274. port = fGraphManager->GetPort(port_index);
  275. port->SetAlias(alias);
  276. fCapturePortList[audio_port_index] = port_index;
  277. jack_log("JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency());
  278. }
  279. for (audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
  280. snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, audio_port_index + 1);
  281. snprintf(name, sizeof(name), "%s:playback_%d",fClientControl.fName, audio_port_index + 1);
  282. if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE,
  283. PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
  284. jack_error("driver: cannot register port for %s", name);
  285. return -1;
  286. }
  287. port = fGraphManager->GetPort(port_index);
  288. port->SetAlias(alias);
  289. fPlaybackPortList[audio_port_index] = port_index;
  290. jack_log("JackNetDriver::AllocPorts() fPlaybackPortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency());
  291. }
  292. //midi
  293. for (midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
  294. snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, midi_port_index + 1);
  295. snprintf(name, sizeof (name), "%s:midi_capture_%d", fClientControl.fName, midi_port_index + 1);
  296. if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE,
  297. CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
  298. jack_error("driver: cannot register port for %s", name);
  299. return -1;
  300. }
  301. port = fGraphManager->GetPort(port_index);
  302. fMidiCapturePortList[midi_port_index] = port_index;
  303. jack_log("JackNetDriver::AllocPorts() fMidiCapturePortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency());
  304. }
  305. for (midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
  306. snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, midi_port_index + 1);
  307. snprintf(name, sizeof(name), "%s:midi_playback_%d", fClientControl.fName, midi_port_index + 1);
  308. if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE,
  309. PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
  310. jack_error("driver: cannot register port for %s", name);
  311. return -1;
  312. }
  313. port = fGraphManager->GetPort(port_index);
  314. fMidiPlaybackPortList[midi_port_index] = port_index;
  315. jack_log("JackNetDriver::AllocPorts() fMidiPlaybackPortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency());
  316. }
  317. return 0;
  318. }
  319. int JackNetDriver::FreePorts()
  320. {
  321. jack_log("JackNetDriver::FreePorts");
  322. for (int audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) {
  323. if (fCapturePortList[audio_port_index] > 0) {
  324. fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[audio_port_index]);
  325. fCapturePortList[audio_port_index] = 0;
  326. }
  327. }
  328. for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
  329. if (fPlaybackPortList[audio_port_index] > 0) {
  330. fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[audio_port_index]);
  331. fPlaybackPortList[audio_port_index] = 0;
  332. }
  333. }
  334. for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
  335. if (fMidiCapturePortList && fMidiCapturePortList[midi_port_index] > 0) {
  336. fGraphManager->ReleasePort(fClientControl.fRefNum, fMidiCapturePortList[midi_port_index]);
  337. fMidiCapturePortList[midi_port_index] = 0;
  338. }
  339. }
  340. for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
  341. if (fMidiPlaybackPortList && fMidiPlaybackPortList[midi_port_index] > 0) {
  342. fEngine->PortUnRegister(fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index]);
  343. fMidiPlaybackPortList[midi_port_index] = 0;
  344. }
  345. }
  346. return 0;
  347. }
  348. void JackNetDriver::SaveConnections(int alias)
  349. {
  350. JackDriver::SaveConnections(alias);
  351. const char** connections;
  352. if (fMidiCapturePortList) {
  353. for (int i = 0; i < fParams.fSendMidiChannels; ++i) {
  354. if (fMidiCapturePortList[i] && (connections = fGraphManager->GetConnections(fMidiCapturePortList[i])) != 0) {
  355. for (int j = 0; connections[j]; j++) {
  356. JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
  357. fConnections.push_back(make_pair(port_id->GetType(), make_pair(fGraphManager->GetPort(fMidiCapturePortList[i])->GetName(), connections[j])));
  358. jack_info("Save connection: %s %s", fGraphManager->GetPort(fMidiCapturePortList[i])->GetName(), connections[j]);
  359. }
  360. free(connections);
  361. }
  362. }
  363. }
  364. if (fMidiPlaybackPortList) {
  365. for (int i = 0; i < fParams.fReturnMidiChannels; ++i) {
  366. if (fMidiPlaybackPortList[i] && (connections = fGraphManager->GetConnections(fMidiPlaybackPortList[i])) != 0) {
  367. for (int j = 0; connections[j]; j++) {
  368. JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
  369. fConnections.push_back(make_pair(port_id->GetType(), make_pair(connections[j], fGraphManager->GetPort(fMidiPlaybackPortList[i])->GetName())));
  370. jack_info("Save connection: %s %s", connections[j], fGraphManager->GetPort(fMidiPlaybackPortList[i])->GetName());
  371. }
  372. free(connections);
  373. }
  374. }
  375. }
  376. }
  377. JackMidiBuffer* JackNetDriver::GetMidiInputBuffer(int port_index)
  378. {
  379. return static_cast<JackMidiBuffer*>(fGraphManager->GetBuffer(fMidiCapturePortList[port_index], fEngineControl->fBufferSize));
  380. }
  381. JackMidiBuffer* JackNetDriver::GetMidiOutputBuffer(int port_index)
  382. {
  383. return static_cast<JackMidiBuffer*>(fGraphManager->GetBuffer(fMidiPlaybackPortList[port_index], fEngineControl->fBufferSize));
  384. }
  385. //transport---------------------------------------------------------------------------
  386. void JackNetDriver::DecodeTransportData()
  387. {
  388. //is there a new timebase master on the net master ?
  389. // - release timebase master only if it's a non-conditional request
  390. // - no change or no request : don't do anything
  391. // - conditional request : don't change anything too, the master will know if this slave is actually the timebase master
  392. int refnum;
  393. bool conditional;
  394. if (fSendTransportData.fTimebaseMaster == TIMEBASEMASTER) {
  395. fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional);
  396. if (refnum != -1) {
  397. fEngineControl->fTransport.ResetTimebase(refnum);
  398. }
  399. jack_info("The NetMaster is now the new timebase master.");
  400. }
  401. //is there a transport state change to handle ?
  402. if (fSendTransportData.fNewState &&(fSendTransportData.fState != fEngineControl->fTransport.GetState())) {
  403. switch (fSendTransportData.fState)
  404. {
  405. case JackTransportStopped :
  406. fEngineControl->fTransport.SetCommand(TransportCommandStop);
  407. jack_info("Master stops transport.");
  408. break;
  409. case JackTransportStarting :
  410. fEngineControl->fTransport.RequestNewPos(&fSendTransportData.fPosition);
  411. fEngineControl->fTransport.SetCommand(TransportCommandStart);
  412. jack_info("Master starts transport frame = %d", fSendTransportData.fPosition.frame);
  413. break;
  414. case JackTransportRolling :
  415. //fEngineControl->fTransport.SetCommand(TransportCommandStart);
  416. fEngineControl->fTransport.SetState(JackTransportRolling);
  417. jack_info("Master is rolling.");
  418. break;
  419. }
  420. }
  421. }
  422. void JackNetDriver::EncodeTransportData()
  423. {
  424. //is there a timebase master change ?
  425. int refnum;
  426. bool conditional;
  427. fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional);
  428. if (refnum != fLastTimebaseMaster) {
  429. //timebase master has released its function
  430. if (refnum == -1) {
  431. fReturnTransportData.fTimebaseMaster = RELEASE_TIMEBASEMASTER;
  432. jack_info("Sending a timebase master release request.");
  433. } else {
  434. //there is a new timebase master
  435. fReturnTransportData.fTimebaseMaster = (conditional) ? CONDITIONAL_TIMEBASEMASTER : TIMEBASEMASTER;
  436. jack_info("Sending a %s timebase master request.", (conditional) ? "conditional" : "non-conditional");
  437. }
  438. fLastTimebaseMaster = refnum;
  439. } else {
  440. fReturnTransportData.fTimebaseMaster = NO_CHANGE;
  441. }
  442. //update transport state and position
  443. fReturnTransportData.fState = fEngineControl->fTransport.Query(&fReturnTransportData.fPosition);
  444. //is it a new state (that the master need to know...) ?
  445. fReturnTransportData.fNewState = ((fReturnTransportData.fState == JackTransportNetStarting) &&
  446. (fReturnTransportData.fState != fLastTransportState) &&
  447. (fReturnTransportData.fState != fSendTransportData.fState));
  448. if (fReturnTransportData.fNewState) {
  449. jack_info("Sending '%s'.", GetTransportState(fReturnTransportData.fState));
  450. }
  451. fLastTransportState = fReturnTransportData.fState;
  452. }
  453. //driver processes--------------------------------------------------------------------
  454. int JackNetDriver::Read()
  455. {
  456. //buffers
  457. for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
  458. fNetMidiCaptureBuffer->SetBuffer(midi_port_index, GetMidiInputBuffer(midi_port_index));
  459. }
  460. for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
  461. #ifdef OPTIMIZED_PROTOCOL
  462. if (fGraphManager->GetConnectionsNum(fCapturePortList[audio_port_index]) > 0) {
  463. fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index));
  464. } else {
  465. fNetAudioCaptureBuffer->SetBuffer(audio_port_index, NULL);
  466. }
  467. #else
  468. fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index));
  469. #endif
  470. }
  471. #ifdef JACK_MONITOR
  472. fNetTimeMon->New();
  473. #endif
  474. switch (SyncRecv()) {
  475. case SOCKET_ERROR:
  476. return SOCKET_ERROR;
  477. case NET_PACKET_ERROR:
  478. // Since sync packet is incorrect, don't decode it and continue with data
  479. break;
  480. default:
  481. //decode sync
  482. DecodeSyncPacket();
  483. break;
  484. }
  485. #ifdef JACK_MONITOR
  486. // For timing
  487. fRcvSyncUst = GetMicroSeconds();
  488. #endif
  489. #ifdef JACK_MONITOR
  490. fNetTimeMon->Add(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f);
  491. #endif
  492. //audio, midi or sync if driver is late
  493. switch (DataRecv()) {
  494. case SOCKET_ERROR:
  495. return SOCKET_ERROR;
  496. case NET_PACKET_ERROR:
  497. jack_time_t cur_time = GetMicroSeconds();
  498. NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing...
  499. break;
  500. }
  501. //take the time at the beginning of the cycle
  502. JackDriver::CycleTakeBeginTime();
  503. #ifdef JACK_MONITOR
  504. fNetTimeMon->Add(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f);
  505. #endif
  506. return 0;
  507. }
  508. int JackNetDriver::Write()
  509. {
  510. //buffers
  511. for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
  512. fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, GetMidiOutputBuffer(midi_port_index));
  513. }
  514. for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
  515. #ifdef OPTIMIZED_PROTOCOL
  516. // Port is connected on other side...
  517. if (fNetAudioPlaybackBuffer->GetConnected(audio_port_index)
  518. && (fGraphManager->GetConnectionsNum(fPlaybackPortList[audio_port_index]) > 0)) {
  519. fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index));
  520. } else {
  521. fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL);
  522. }
  523. #else
  524. fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index));
  525. #endif
  526. }
  527. #ifdef JACK_MONITOR
  528. fNetTimeMon->AddLast(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f);
  529. #endif
  530. //sync
  531. EncodeSyncPacket();
  532. //send sync
  533. if (SyncSend() == SOCKET_ERROR) {
  534. return SOCKET_ERROR;
  535. }
  536. #ifdef JACK_MONITOR
  537. fNetTimeMon->Add(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f);
  538. #endif
  539. //send data
  540. if (DataSend() == SOCKET_ERROR) {
  541. return SOCKET_ERROR;
  542. }
  543. #ifdef JACK_MONITOR
  544. fNetTimeMon->AddLast(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f);
  545. #endif
  546. return 0;
  547. }
  548. //driver loader-----------------------------------------------------------------------
  549. #ifdef __cplusplus
  550. extern "C"
  551. {
  552. #endif
  553. SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor()
  554. {
  555. jack_driver_desc_t * desc;
  556. jack_driver_desc_filler_t filler;
  557. jack_driver_param_value_t value;
  558. desc = jack_driver_descriptor_construct("net", JackDriverMaster, "netjack slave backend component", &filler);
  559. strcpy(value.str, DEFAULT_MULTICAST_IP);
  560. jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address, or explicit IP of the master", NULL);
  561. value.i = DEFAULT_PORT;
  562. jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL);
  563. value.i = DEFAULT_MTU;
  564. jack_driver_descriptor_add_parameter(desc, &filler, "mtu", 'M', JackDriverParamInt, &value, NULL, "MTU to the master", NULL);
  565. value.i = -1;
  566. jack_driver_descriptor_add_parameter(desc, &filler, "input-ports", 'C', JackDriverParamInt, &value, NULL, "Number of audio input ports", "Number of audio input ports. If -1, audio physical input from the master");
  567. jack_driver_descriptor_add_parameter(desc, &filler, "output-ports", 'P', JackDriverParamInt, &value, NULL, "Number of audio output ports", "Number of audio output ports. If -1, audio physical output from the master");
  568. value.i = -1;
  569. jack_driver_descriptor_add_parameter(desc, &filler, "midi-in-ports", 'i', JackDriverParamInt, &value, NULL, "Number of midi input ports", "Number of MIDI input ports. If -1, MIDI physical input from the master");
  570. jack_driver_descriptor_add_parameter(desc, &filler, "midi-out-ports", 'o', JackDriverParamInt, &value, NULL, "Number of midi output ports", "Number of MIDI output ports. If -1, MIDI physical output from the master");
  571. #if HAVE_CELT
  572. value.i = -1;
  573. jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamInt, &value, NULL, "Set CELT encoding and number of kBits per channel", NULL);
  574. #endif
  575. #if HAVE_OPUS
  576. value.i = -1;
  577. jack_driver_descriptor_add_parameter(desc, &filler, "opus", 'O', JackDriverParamInt, &value, NULL, "Set Opus encoding and number of kBits per channel", NULL);
  578. #endif
  579. strcpy(value.str, "'hostname'");
  580. jack_driver_descriptor_add_parameter(desc, &filler, "client-name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL);
  581. /*
  582. Deactivated for now..
  583. value.ui = 0U;
  584. jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL);
  585. */
  586. value.ui = 5U;
  587. jack_driver_descriptor_add_parameter(desc, &filler, "latency", 'l', JackDriverParamUInt, &value, NULL, "Network latency", NULL);
  588. return desc;
  589. }
  590. SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
  591. {
  592. char multicast_ip[32];
  593. char net_name[JACK_CLIENT_NAME_SIZE + 1] = {0};
  594. int udp_port;
  595. int mtu = DEFAULT_MTU;
  596. // Desactivated for now...
  597. uint transport_sync = 0;
  598. jack_nframes_t period_size = 1024;
  599. jack_nframes_t sample_rate = 48000;
  600. int audio_capture_ports = -1;
  601. int audio_playback_ports = -1;
  602. int midi_input_ports = -1;
  603. int midi_output_ports = -1;
  604. int celt_encoding = -1;
  605. int opus_encoding = -1;
  606. bool monitor = false;
  607. int network_latency = 5;
  608. const JSList* node;
  609. const jack_driver_param_t* param;
  610. // Possibly use env variable for UDP port
  611. const char* default_udp_port = getenv("JACK_NETJACK_PORT");
  612. udp_port = (default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT;
  613. // Possibly use env variable for multicast IP
  614. const char* default_multicast_ip = getenv("JACK_NETJACK_MULTICAST");
  615. strcpy(multicast_ip, (default_multicast_ip) ? default_multicast_ip : DEFAULT_MULTICAST_IP);
  616. for (node = params; node; node = jack_slist_next(node)) {
  617. param = (const jack_driver_param_t*) node->data;
  618. switch (param->character)
  619. {
  620. case 'a' :
  621. assert(strlen(param->value.str) < 32);
  622. strcpy(multicast_ip, param->value.str);
  623. break;
  624. case 'p':
  625. udp_port = param->value.ui;
  626. break;
  627. case 'M':
  628. mtu = param->value.i;
  629. break;
  630. case 'C':
  631. audio_capture_ports = param->value.i;
  632. break;
  633. case 'P':
  634. audio_playback_ports = param->value.i;
  635. break;
  636. case 'i':
  637. midi_input_ports = param->value.i;
  638. break;
  639. case 'o':
  640. midi_output_ports = param->value.i;
  641. break;
  642. #if HAVE_CELT
  643. case 'c':
  644. celt_encoding = param->value.i;
  645. break;
  646. #endif
  647. #if HAVE_OPUS
  648. case 'O':
  649. opus_encoding = param->value.i;
  650. break;
  651. #endif
  652. case 'n' :
  653. strncpy(net_name, param->value.str, JACK_CLIENT_NAME_SIZE);
  654. break;
  655. /*
  656. Deactivated for now..
  657. case 't' :
  658. transport_sync = param->value.ui;
  659. break;
  660. */
  661. case 'l' :
  662. network_latency = param->value.ui;
  663. if (network_latency > NETWORK_MAX_LATENCY) {
  664. printf("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY);
  665. return NULL;
  666. }
  667. break;
  668. }
  669. }
  670. try {
  671. Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver(
  672. new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, mtu,
  673. midi_input_ports, midi_output_ports,
  674. net_name, transport_sync,
  675. network_latency, celt_encoding, opus_encoding));
  676. if (driver->Open(period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports, monitor, "from_master_", "to_master_", 0, 0) == 0) {
  677. return driver;
  678. } else {
  679. delete driver;
  680. return NULL;
  681. }
  682. } catch (...) {
  683. return NULL;
  684. }
  685. }
  686. #ifdef __cplusplus
  687. }
  688. #endif
  689. }