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.

739 lines
30KB

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