Jack2  1.9.12
JackNetInterface.cpp
1 /*
2 Copyright (C) 2008-2011 Romain Moret at Grame
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 
19 #include "JackNetInterface.h"
20 #include "JackException.h"
21 #include "JackError.h"
22 
23 #include <assert.h>
24 
25 using namespace std;
26 
27 /*
28  TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames,
29  probably also use BUFFER_SIZE_MAX in everything related to MIDI events
30  handling (see MidiBufferInit in JackMidiPort.cpp)
31 */
32 
33 namespace Jack
34 {
35  // JackNetInterface*******************************************
36 
37  JackNetInterface::JackNetInterface() : fSocket()
38  {
39  Initialize();
40  }
41 
42  JackNetInterface::JackNetInterface(const char* multicast_ip, int port) : fSocket(multicast_ip, port)
43  {
44  strcpy(fMulticastIP, multicast_ip);
45  Initialize();
46  }
47 
48  JackNetInterface::JackNetInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip) : fSocket(socket)
49  {
50  fParams = params;
51  strcpy(fMulticastIP, multicast_ip);
52  Initialize();
53  }
54 
55  void JackNetInterface::Initialize()
56  {
57  fSetTimeOut = false;
58  fTxBuffer = NULL;
59  fRxBuffer = NULL;
60  fNetAudioCaptureBuffer = NULL;
61  fNetAudioPlaybackBuffer = NULL;
62  fNetMidiCaptureBuffer = NULL;
63  fNetMidiPlaybackBuffer = NULL;
64  memset(&fSendTransportData, 0, sizeof(net_transport_data_t));
65  memset(&fReturnTransportData, 0, sizeof(net_transport_data_t));
66  fPacketTimeOut = PACKET_TIMEOUT * NETWORK_DEFAULT_LATENCY;
67  }
68 
69  void JackNetInterface::FreeNetworkBuffers()
70  {
71  delete fNetMidiCaptureBuffer;
72  delete fNetMidiPlaybackBuffer;
73  delete fNetAudioCaptureBuffer;
74  delete fNetAudioPlaybackBuffer;
75  fNetMidiCaptureBuffer = NULL;
76  fNetMidiPlaybackBuffer = NULL;
77  fNetAudioCaptureBuffer = NULL;
78  fNetAudioPlaybackBuffer = NULL;
79  }
80 
81  JackNetInterface::~JackNetInterface()
82  {
83  jack_log("JackNetInterface::~JackNetInterface");
84 
85  fSocket.Close();
86  delete[] fTxBuffer;
87  delete[] fRxBuffer;
88  delete fNetAudioCaptureBuffer;
89  delete fNetAudioPlaybackBuffer;
90  delete fNetMidiCaptureBuffer;
91  delete fNetMidiPlaybackBuffer;
92  }
93 
94  int JackNetInterface::SetNetBufferSize()
95  {
96  // audio
97  float audio_size = (fNetAudioCaptureBuffer)
98  ? fNetAudioCaptureBuffer->GetCycleSize()
99  : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0;
100  jack_log("audio_size %f", audio_size);
101 
102  // midi
103  float midi_size = (fNetMidiCaptureBuffer)
104  ? fNetMidiCaptureBuffer->GetCycleSize()
105  : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0;
106  jack_log("midi_size %f", midi_size);
107 
108  // bufsize = sync + audio + midi
109  int bufsize = NETWORK_MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int)midi_size);
110  jack_log("SetNetBufferSize bufsize = %d", bufsize);
111 
112  // tx buffer
113  if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) {
114  return SOCKET_ERROR;
115  }
116 
117  // rx buffer
118  if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) {
119  return SOCKET_ERROR;
120  }
121 
122  return 0;
123  }
124 
125  bool JackNetInterface::SetParams()
126  {
127  // TX header init
128  memset(&fTxHeader, 0, sizeof(fTxHeader));
129  strcpy(fTxHeader.fPacketType, "header");
130  fTxHeader.fID = fParams.fID;
131  fTxHeader.fCycle = 0;
132  fTxHeader.fSubCycle = 0;
133  fTxHeader.fIsLastPckt = 0;
134 
135  // RX header init
136  memset(&fRxHeader, 0, sizeof(fTxHeader));
137  strcpy(fRxHeader.fPacketType, "header");
138  fRxHeader.fID = fParams.fID;
139  fRxHeader.fCycle = 0;
140  fRxHeader.fSubCycle = 0;
141  fRxHeader.fIsLastPckt = 0;
142 
143  // network buffers
144  fTxBuffer = new char[fParams.fMtu];
145  fRxBuffer = new char[fParams.fMtu];
146  assert(fTxBuffer);
147  assert(fRxBuffer);
148 
149  // net audio/midi buffers'addresses
150  fTxData = fTxBuffer + HEADER_SIZE;
151  fRxData = fRxBuffer + HEADER_SIZE;
152 
153  return true;
154  }
155 
156  int JackNetInterface::MidiSend(NetMidiBuffer* buffer, int midi_channnels, int audio_channels)
157  {
158  if (midi_channnels > 0) {
159  // set global header fields and get the number of midi packets
160  fTxHeader.fDataType = 'm';
161  uint data_size = buffer->RenderFromJackPorts();
162  fTxHeader.fNumPacket = buffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE(&fParams));
163 
164  for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
165  fTxHeader.fSubCycle = subproc;
166  fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && audio_channels == 0) ? 1 : 0;
167  fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, data_size);
168  memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
169  //PacketHeaderDisplay(&fTxHeader);
170  if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) {
171  return SOCKET_ERROR;
172  }
173  }
174  }
175  return 0;
176  }
177 
178  int JackNetInterface::AudioSend(NetAudioBuffer* buffer, int audio_channels)
179  {
180  // audio
181  if (audio_channels > 0) {
182  fTxHeader.fDataType = 'a';
183  fTxHeader.fActivePorts = buffer->RenderFromJackPorts(fTxHeader.fFrames);
184  fTxHeader.fNumPacket = buffer->GetNumPackets(fTxHeader.fActivePorts);
185 
186  for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
187  fTxHeader.fSubCycle = subproc;
188  fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
189  fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, fTxHeader.fActivePorts);
190  memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
191  //PacketHeaderDisplay(&fTxHeader);
192  if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) {
193  return SOCKET_ERROR;
194  }
195  }
196  }
197  return 0;
198  }
199 
200  int JackNetInterface::MidiRecv(packet_header_t* rx_head, NetMidiBuffer* buffer, uint& recvd_midi_pckt)
201  {
202  int rx_bytes = Recv(rx_head->fPacketSize, 0);
203  fRxHeader.fCycle = rx_head->fCycle;
204  fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
205  buffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
206 
207  // Last midi packet is received, so finish rendering...
208  if (++recvd_midi_pckt == rx_head->fNumPacket) {
209  buffer->RenderToJackPorts();
210  }
211  //PacketHeaderDisplay(rx_head);
212  return rx_bytes;
213  }
214 
215  int JackNetInterface::AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer)
216  {
217  int rx_bytes = Recv(rx_head->fPacketSize, 0);
218  fRxHeader.fCycle = rx_head->fCycle;
219  fRxHeader.fSubCycle = rx_head->fSubCycle;
220  fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
221  fRxHeader.fActivePorts = rx_head->fActivePorts;
222  fRxHeader.fFrames = rx_head->fFrames;
223  rx_bytes = buffer->RenderFromNetwork(rx_head->fCycle, rx_head->fSubCycle, fRxHeader.fActivePorts);
224 
225  // Last audio packet is received, so finish rendering...
226  if (fRxHeader.fIsLastPckt) {
227  buffer->RenderToJackPorts(fRxHeader.fFrames);
228  }
229  //PacketHeaderDisplay(rx_head);
230  return rx_bytes;
231  }
232 
233  int JackNetInterface::FinishRecv(NetAudioBuffer* buffer)
234  {
235  if (buffer) {
236  buffer->RenderToJackPorts(fRxHeader.fFrames);
237  } else {
238  jack_error("FinishRecv with null buffer...");
239  }
240  return DATA_PACKET_ERROR;
241  }
242 
243  NetAudioBuffer* JackNetInterface::AudioBufferFactory(int nports, char* buffer)
244  {
245  switch (fParams.fSampleEncoder) {
246 
247  case JackFloatEncoder:
248  return new NetFloatAudioBuffer(&fParams, nports, buffer);
249 
250  case JackIntEncoder:
251  return new NetIntAudioBuffer(&fParams, nports, buffer);
252 
253  #if HAVE_CELT
254  case JackCeltEncoder:
255  return new NetCeltAudioBuffer(&fParams, nports, buffer, fParams.fKBps);
256  #endif
257  #if HAVE_OPUS
258  case JackOpusEncoder:
259  return new NetOpusAudioBuffer(&fParams, nports, buffer, fParams.fKBps);
260  #endif
261  }
262 
263  throw std::bad_alloc();
264  }
265 
266  void JackNetInterface::SetRcvTimeOut()
267  {
268  if (!fSetTimeOut) {
269  if (fSocket.SetTimeOut(fPacketTimeOut) == SOCKET_ERROR) {
270  jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE));
271  return;
272  }
273  fSetTimeOut = true;
274  }
275  }
276 
277  // JackNetMasterInterface ************************************************************************************
278 
279  bool JackNetMasterInterface::Init()
280  {
281  jack_log("JackNetMasterInterface::Init : ID %u", fParams.fID);
282 
283  session_params_t host_params;
284  uint attempt = 0;
285  int rx_bytes = 0;
286 
287  // socket
288  if (fSocket.NewSocket() == SOCKET_ERROR) {
289  jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE));
290  return false;
291  }
292 
293  // timeout on receive (for init)
294  if (fSocket.SetTimeOut(MASTER_INIT_TIMEOUT) < 0) {
295  jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE));
296  }
297 
298  // connect
299  if (fSocket.Connect() == SOCKET_ERROR) {
300  jack_error("Can't connect : %s", StrError(NET_ERROR_CODE));
301  return false;
302  }
303 
304  // send 'SLAVE_SETUP' until 'START_MASTER' received
305  jack_info("Sending parameters to %s...", fParams.fSlaveNetName);
306  do
307  {
308  session_params_t net_params;
309  memset(&net_params, 0, sizeof(session_params_t));
310  SetPacketType(&fParams, SLAVE_SETUP);
311  SessionParamsHToN(&fParams, &net_params);
312 
313  if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) {
314  jack_error("Error in send : %s", StrError(NET_ERROR_CODE));
315  }
316 
317  memset(&net_params, 0, sizeof(session_params_t));
318  if (((rx_bytes = fSocket.Recv(&net_params, sizeof(session_params_t), 0)) == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
319  jack_error("Problem with network");
320  return false;
321  }
322 
323  SessionParamsNToH(&net_params, &host_params);
324  }
325  while ((GetPacketType(&host_params) != START_MASTER) && (++attempt < SLAVE_SETUP_RETRY));
326 
327  if (attempt == SLAVE_SETUP_RETRY) {
328  jack_error("Slave doesn't respond, exiting");
329  return false;
330  }
331 
332  return true;
333  }
334 
335  bool JackNetMasterInterface::SetParams()
336  {
337  jack_log("JackNetMasterInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
338  fParams.fSendAudioChannels, fParams.fReturnAudioChannels,
339  fParams.fSendMidiChannels, fParams.fReturnMidiChannels);
340 
341  JackNetInterface::SetParams();
342 
343  fTxHeader.fDataStream = 's';
344  fRxHeader.fDataStream = 'r';
345 
346  fMaxCycleOffset = fParams.fNetworkLatency;
347 
348  // midi net buffers
349  if (fParams.fSendMidiChannels > 0) {
350  fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fTxData);
351  }
352 
353  if (fParams.fReturnMidiChannels > 0) {
354  fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fRxData);
355  }
356 
357  try {
358 
359  // audio net buffers
360  if (fParams.fSendAudioChannels > 0) {
361  fNetAudioCaptureBuffer = AudioBufferFactory(fParams.fSendAudioChannels, fTxData);
362  assert(fNetAudioCaptureBuffer);
363  }
364 
365  if (fParams.fReturnAudioChannels > 0) {
366  fNetAudioPlaybackBuffer = AudioBufferFactory(fParams.fReturnAudioChannels, fRxData);
367  assert(fNetAudioPlaybackBuffer);
368  }
369 
370  } catch (exception&) {
371  jack_error("NetAudioBuffer on master allocation error...");
372  return false;
373  }
374 
375  // set the new buffer size
376  if (SetNetBufferSize() == SOCKET_ERROR) {
377  jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
378  goto error;
379  }
380 
381  return true;
382 
383  error:
384  FreeNetworkBuffers();
385  return false;
386  }
387 
388  void JackNetMasterInterface::Exit()
389  {
390  jack_log("JackNetMasterInterface::Exit, ID %u", fParams.fID);
391 
392  // stop process
393  fRunning = false;
394 
395  // send a 'multicast euthanasia request' - new socket is required on macosx
396  jack_info("Exiting '%s' %s", fParams.fName, fMulticastIP);
397  SetPacketType(&fParams, KILL_MASTER);
398  JackNetSocket mcast_socket(fMulticastIP, fSocket.GetPort());
399 
400  session_params_t net_params;
401  memset(&net_params, 0, sizeof(session_params_t));
402  SessionParamsHToN(&fParams, &net_params);
403 
404  if (mcast_socket.NewSocket() == SOCKET_ERROR) {
405  jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE));
406  }
407  if (mcast_socket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR) {
408  jack_error("Can't send suicide request : %s", StrError(NET_ERROR_CODE));
409  }
410 
411  mcast_socket.Close();
412  }
413 
414  void JackNetMasterInterface::FatalRecvError()
415  {
416  // fatal connection issue, exit
417  jack_error("Recv connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE), fParams.fName);
418  // ask to the manager to properly remove the master
419  Exit();
420  // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
421  ThreadExit();
422  }
423 
424  void JackNetMasterInterface::FatalSendError()
425  {
426  // fatal connection issue, exit
427  jack_error("Send connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE), fParams.fName);
428  // ask to the manager to properly remove the master
429  Exit();
430  // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
431  ThreadExit();
432  }
433 
434  int JackNetMasterInterface::Recv(size_t size, int flags)
435  {
436  int rx_bytes;
437 
438  if (((rx_bytes = fSocket.Recv(fRxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
439  FatalRecvError();
440  }
441 
442  packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
443  PacketHeaderNToH(header, header);
444  return rx_bytes;
445  }
446 
447  int JackNetMasterInterface::Send(size_t size, int flags)
448  {
449  int tx_bytes;
450  packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
451  PacketHeaderHToN(header, header);
452 
453  if (((tx_bytes = fSocket.Send(fTxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
454  FatalSendError();
455  }
456  return tx_bytes;
457  }
458 
459  int JackNetMasterInterface::SyncSend()
460  {
461  SetRcvTimeOut();
462 
463  fTxHeader.fCycle++;
464  fTxHeader.fSubCycle = 0;
465  fTxHeader.fDataType = 's';
466  fTxHeader.fIsLastPckt = (fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0;
467  fTxHeader.fPacketSize = HEADER_SIZE + fTxHeader.fActivePorts * sizeof(int); // Data part is used to encode active ports
468 
469  memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
470  //PacketHeaderDisplay(&fTxHeader);
471  return Send(fTxHeader.fPacketSize, 0);
472  }
473 
474  int JackNetMasterInterface::DataSend()
475  {
476  if (MidiSend(fNetMidiCaptureBuffer, fParams.fSendMidiChannels, fParams.fSendAudioChannels) == SOCKET_ERROR) {
477  return SOCKET_ERROR;
478  }
479  return AudioSend(fNetAudioCaptureBuffer, fParams.fSendAudioChannels);
480  }
481 
482  int JackNetMasterInterface::SyncRecv()
483  {
484  int rx_bytes = 0;
485  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
486 
487  // receive sync (launch the cycle)
488  do {
489  rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
490  // connection issue (return -1)
491  if (rx_bytes == SOCKET_ERROR) {
492  return SOCKET_ERROR;
493  }
494  }
495  while (strcmp(rx_head->fPacketType, "header") != 0);
496  //PacketHeaderDisplay(rx_head);
497 
498  if (rx_head->fDataType != 's') {
499  jack_error("Wrong packet type : %c", rx_head->fDataType);
500  // not the last packet..
501  fRxHeader.fIsLastPckt = 0;
502  return SYNC_PACKET_ERROR;
503  }
504 
505  fCurrentCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
506 
507  if (fCurrentCycleOffset < fMaxCycleOffset && !fSynched) {
508  jack_info("Synching with latency = %d", fCurrentCycleOffset);
509  return NET_SYNCHING;
510  } else {
511  if (fCurrentCycleOffset == fMaxCycleOffset) {
512  // when the sync offset is reached
513  fSynched = true;
514  }
515  rx_bytes = Recv(rx_head->fPacketSize, 0);
516  fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
517  return rx_bytes;
518  }
519  }
520 
521  int JackNetMasterInterface::DataRecv()
522  {
523  int rx_bytes = 0;
524  uint recvd_midi_pckt = 0;
525  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
526 
527  while (!fRxHeader.fIsLastPckt) {
528  // how much data is queued on the rx buffer ?
529  rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
530 
531  // error here, problem with recv, just skip the cycle (return -1)
532  if (rx_bytes == SOCKET_ERROR) {
533  return rx_bytes;
534  }
535 
536  if (rx_bytes && (rx_head->fDataStream == 'r') && (rx_head->fID == fParams.fID)) {
537  // read data
538  switch (rx_head->fDataType) {
539 
540  case 'm': // midi
541  rx_bytes = MidiRecv(rx_head, fNetMidiPlaybackBuffer, recvd_midi_pckt);
542  break;
543 
544  case 'a': // audio
545  rx_bytes = AudioRecv(rx_head, fNetAudioPlaybackBuffer);
546  break;
547 
548  case 's': // sync
549  jack_info("NetMaster : missing last data packet from '%s'", fParams.fName);
550  return FinishRecv(fNetAudioPlaybackBuffer);
551  }
552  }
553  }
554 
555  return rx_bytes;
556  }
557 
558  void JackNetMasterInterface::EncodeSyncPacket(int frames)
559  {
560  // This method contains every step of sync packet informations coding
561  // first of all, clear sync packet
562  memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams));
563 
564  // Transport not used for now...
565  /*
566  // then, first step : transport
567  if (fParams.fTransportSync) {
568  EncodeTransportData();
569  TransportDataHToN(&fSendTransportData, &fSendTransportData);
570  // copy to TxBuffer
571  memcpy(fTxData, &fSendTransportData, sizeof(net_transport_data_t));
572  }
573  // then others (freewheel etc.)
574  // ...
575  */
576 
577  // Write active ports list
578  fTxHeader.fActivePorts = (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->ActivePortsToNetwork(fTxData) : 0;
579  fTxHeader.fFrames = frames;
580  }
581 
582  void JackNetMasterInterface::DecodeSyncPacket(int& frames)
583  {
584  // This method contains every step of sync packet informations decoding process
585 
586  // Transport not used for now...
587  /*
588  // first : transport
589  if (fParams.fTransportSync) {
590  // copy received transport data to transport data structure
591  memcpy(&fReturnTransportData, fRxData, sizeof(net_transport_data_t));
592  TransportDataNToH(&fReturnTransportData, &fReturnTransportData);
593  DecodeTransportData();
594  }
595  // then others
596  // ...
597  */
598 
599  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
600 
601  // Read active ports list
602  if (fNetAudioCaptureBuffer) {
603  fNetAudioCaptureBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
604  }
605  frames = rx_head->fFrames;
606  }
607 
608 // JackNetSlaveInterface ************************************************************************************************
609 
610  uint JackNetSlaveInterface::fSlaveCounter = 0;
611 
612  void JackNetSlaveInterface::InitAPI()
613  {
614  // open Socket API with the first slave
615  if (fSlaveCounter++ == 0) {
616  if (SocketAPIInit() < 0) {
617  jack_error("Can't init Socket API, exiting...");
618  throw std::bad_alloc();
619  }
620  }
621  }
622 
623  bool JackNetSlaveInterface::Init()
624  {
625  jack_log("JackNetSlaveInterface::Init()");
626 
627  // set the parameters to send
628  strcpy(fParams.fPacketType, "params");
629  fParams.fProtocolVersion = NETWORK_PROTOCOL;
630  SetPacketType(&fParams, SLAVE_AVAILABLE);
631 
632  // init loop : get a master and start, do it until connection is ok
633  net_status_t status;
634  do {
635  // first, get a master, do it until a valid connection is running
636  do {
637  status = SendAvailableToMaster();
638  if (status == NET_SOCKET_ERROR) {
639  return false;
640  }
641  }
642  while (status != NET_CONNECTED);
643 
644  // then tell the master we are ready
645  jack_info("Initializing connection with %s...", fParams.fMasterNetName);
646  status = SendStartToMaster();
647  if (status == NET_ERROR) {
648  return false;
649  }
650  }
651  while (status != NET_ROLLING);
652 
653  return true;
654  }
655 
656  // Separate the connection protocol into two separated step
657  bool JackNetSlaveInterface::InitConnection(int time_out_sec)
658  {
659  jack_log("JackNetSlaveInterface::InitConnection time_out_sec = %d", time_out_sec);
660  int try_count = (time_out_sec > 0) ? int((1000000.f * float(time_out_sec)) / float(SLAVE_INIT_TIMEOUT)) : INT_MAX;
661 
662  // set the parameters to send
663  strcpy(fParams.fPacketType, "params");
664  fParams.fProtocolVersion = NETWORK_PROTOCOL;
665  SetPacketType(&fParams, SLAVE_AVAILABLE);
666 
667  return (SendAvailableToMaster(try_count) == NET_CONNECTED);
668  }
669 
670  bool JackNetSlaveInterface::InitRendering()
671  {
672  jack_log("JackNetSlaveInterface::InitRendering()");
673 
674  net_status_t status;
675  do {
676  // then tell the master we are ready
677  jack_info("Initializing connection with %s...", fParams.fMasterNetName);
678  status = SendStartToMaster();
679  if (status == NET_ERROR) {
680  return false;
681  }
682  }
683  while (status != NET_ROLLING);
684 
685  return true;
686  }
687 
688  net_status_t JackNetSlaveInterface::SendAvailableToMaster(int try_count)
689  {
690  jack_log("JackNetSlaveInterface::SendAvailableToMaster try_count = %d", try_count);
691  // utility
692  session_params_t host_params;
693  int rx_bytes = 0;
694 
695  // socket
696  if (fSocket.NewSocket() == SOCKET_ERROR) {
697  jack_error("Fatal error : network unreachable - %s", StrError(NET_ERROR_CODE));
698  return NET_SOCKET_ERROR;
699  }
700 
701  if (fSocket.IsLocal(fMulticastIP)) {
702  jack_info("Local IP is used...");
703  } else {
704  // bind the socket
705  if (fSocket.Bind() == SOCKET_ERROR) {
706  jack_error("Can't bind the socket : %s", StrError(NET_ERROR_CODE));
707  return NET_SOCKET_ERROR;
708  }
709  }
710 
711  // timeout on receive (for init)
712  if (fSocket.SetTimeOut(SLAVE_INIT_TIMEOUT) == SOCKET_ERROR) {
713  jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE));
714  }
715 
716  // disable local loop
717  if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
718  jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE));
719  }
720 
721  // send 'AVAILABLE' until 'SLAVE_SETUP' received
722  jack_info("Waiting for a master...");
723 
724  do {
725  // send 'available'
726  session_params_t net_params;
727  memset(&net_params, 0, sizeof(session_params_t));
728  SessionParamsHToN(&fParams, &net_params);
729  if (fSocket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR) {
730  jack_error("Error in data send : %s", StrError(NET_ERROR_CODE));
731  }
732 
733  // filter incoming packets : don't exit while no error is detected
734  memset(&net_params, 0, sizeof(session_params_t));
735  rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0);
736  SessionParamsNToH(&net_params, &host_params);
737  if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
738  jack_error("Can't receive : %s", StrError(NET_ERROR_CODE));
739  return NET_RECV_ERROR;
740  }
741  }
742  while (strcmp(host_params.fPacketType, fParams.fPacketType) && (GetPacketType(&host_params) != SLAVE_SETUP) && (--try_count > 0));
743 
744  // time out failure..
745  if (try_count == 0) {
746  jack_error("Time out error in connect");
747  return NET_CONNECT_ERROR;
748  }
749 
750  // everything is OK, copy parameters
751  fParams = host_params;
752 
753  // connect the socket
754  if (fSocket.Connect() == SOCKET_ERROR) {
755  jack_error("Error in connect : %s", StrError(NET_ERROR_CODE));
756  return NET_CONNECT_ERROR;
757  }
758 
759  return NET_CONNECTED;
760  }
761 
762  net_status_t JackNetSlaveInterface::SendStartToMaster()
763  {
764  jack_log("JackNetSlaveInterface::SendStartToMaster");
765 
766  // tell the master to start
767  session_params_t net_params;
768  memset(&net_params, 0, sizeof(session_params_t));
769  SetPacketType(&fParams, START_MASTER);
770  SessionParamsHToN(&fParams, &net_params);
771  if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) {
772  jack_error("Error in send : %s", StrError(NET_ERROR_CODE));
773  return (fSocket.GetError() == NET_CONN_ERROR) ? NET_ERROR : NET_SEND_ERROR;
774  }
775  return NET_ROLLING;
776  }
777 
778  bool JackNetSlaveInterface::SetParams()
779  {
780  jack_log("JackNetSlaveInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
781  fParams.fSendAudioChannels, fParams.fReturnAudioChannels,
782  fParams.fSendMidiChannels, fParams.fReturnMidiChannels);
783 
784  JackNetInterface::SetParams();
785 
786  fTxHeader.fDataStream = 'r';
787  fRxHeader.fDataStream = 's';
788 
789  // midi net buffers
790  if (fParams.fSendMidiChannels > 0) {
791  fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fRxData);
792  }
793 
794  if (fParams.fReturnMidiChannels > 0) {
795  fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fTxData);
796  }
797 
798  try {
799 
800  // audio net buffers
801  if (fParams.fSendAudioChannels > 0) {
802  fNetAudioCaptureBuffer = AudioBufferFactory(fParams.fSendAudioChannels, fRxData);
803  assert(fNetAudioCaptureBuffer);
804  }
805 
806  if (fParams.fReturnAudioChannels > 0) {
807  fNetAudioPlaybackBuffer = AudioBufferFactory(fParams.fReturnAudioChannels, fTxData);
808  assert(fNetAudioPlaybackBuffer);
809  }
810 
811  } catch (exception&) {
812  jack_error("NetAudioBuffer on slave allocation error...");
813  return false;
814  }
815 
816  // set the new buffer sizes
817  if (SetNetBufferSize() == SOCKET_ERROR) {
818  jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
819  goto error;
820  }
821 
822  return true;
823 
824  error:
825  FreeNetworkBuffers();
826  return false;
827  }
828 
829  void JackNetSlaveInterface::FatalRecvError()
830  {
831  throw JackNetException("Recv connection lost error");
832  }
833 
834  void JackNetSlaveInterface::FatalSendError()
835  {
836  throw JackNetException("Send connection lost error");
837  }
838 
839  int JackNetSlaveInterface::Recv(size_t size, int flags)
840  {
841  int rx_bytes = fSocket.Recv(fRxBuffer, size, flags);
842 
843  // handle errors
844  if (rx_bytes == SOCKET_ERROR) {
845  FatalRecvError();
846  }
847 
848  packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
849  PacketHeaderNToH(header, header);
850  return rx_bytes;
851  }
852 
853  int JackNetSlaveInterface::Send(size_t size, int flags)
854  {
855  packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
856  PacketHeaderHToN(header, header);
857  int tx_bytes = fSocket.Send(fTxBuffer, size, flags);
858 
859  // handle errors
860  if (tx_bytes == SOCKET_ERROR) {
861  FatalSendError();
862  }
863 
864  return tx_bytes;
865  }
866 
867  int JackNetSlaveInterface::SyncRecv()
868  {
869  SetRcvTimeOut();
870 
871  int rx_bytes = 0;
872  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
873 
874  // receive sync (launch the cycle)
875  do {
876  rx_bytes = Recv(fParams.fMtu, 0);
877  // connection issue (return -1)
878  if (rx_bytes == SOCKET_ERROR) {
879  return rx_bytes;
880  }
881  }
882  while (strcmp(rx_head->fPacketType, "header") != 0);
883 
884  if (rx_head->fDataType != 's') {
885  jack_error("Wrong packet type : %c", rx_head->fDataType);
886  // not the last packet...
887  fRxHeader.fIsLastPckt = 0;
888  return SYNC_PACKET_ERROR;
889  }
890 
891  //PacketHeaderDisplay(rx_head);
892  fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
893  return rx_bytes;
894  }
895 
896  int JackNetSlaveInterface::DataRecv()
897  {
898  int rx_bytes = 0;
899  uint recvd_midi_pckt = 0;
900  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
901 
902  while (!fRxHeader.fIsLastPckt) {
903  // how much data is queued on the rx buffer ?
904  rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
905 
906  // error here, just skip the cycle (return -1)
907  if (rx_bytes == SOCKET_ERROR) {
908  return rx_bytes;
909  }
910 
911  if (rx_bytes && (rx_head->fDataStream == 's') && (rx_head->fID == fParams.fID)) {
912  // read data
913  switch (rx_head->fDataType) {
914 
915  case 'm': // midi
916  rx_bytes = MidiRecv(rx_head, fNetMidiCaptureBuffer, recvd_midi_pckt);
917  break;
918 
919  case 'a': // audio
920  rx_bytes = AudioRecv(rx_head, fNetAudioCaptureBuffer);
921  break;
922 
923  case 's': // sync
924  jack_info("NetSlave : missing last data packet");
925  return FinishRecv(fNetAudioCaptureBuffer);
926  }
927  }
928  }
929 
930  fRxHeader.fCycle = rx_head->fCycle;
931  return rx_bytes;
932  }
933 
934  int JackNetSlaveInterface::SyncSend()
935  {
936  // tx header
937  if (fParams.fSlaveSyncMode) {
938  fTxHeader.fCycle = fRxHeader.fCycle;
939  } else {
940  fTxHeader.fCycle++;
941  }
942  fTxHeader.fSubCycle = 0;
943  fTxHeader.fDataType = 's';
944  fTxHeader.fIsLastPckt = (fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0;
945  fTxHeader.fPacketSize = HEADER_SIZE + fTxHeader.fActivePorts * sizeof(int); // Data part is used to encode active ports
946 
947  memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
948  //PacketHeaderDisplay(&fTxHeader);
949  return Send(fTxHeader.fPacketSize, 0);
950  }
951 
952  int JackNetSlaveInterface::DataSend()
953  {
954  if (MidiSend(fNetMidiPlaybackBuffer, fParams.fReturnMidiChannels, fParams.fReturnAudioChannels) == SOCKET_ERROR) {
955  return SOCKET_ERROR;
956  }
957  return AudioSend(fNetAudioPlaybackBuffer, fParams.fReturnAudioChannels);
958  }
959 
960  // network sync------------------------------------------------------------------------
961  void JackNetSlaveInterface::EncodeSyncPacket(int frames)
962  {
963  // This method contains every step of sync packet informations coding
964  // first of all, clear sync packet
965  memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams));
966 
967  // then first step : transport
968  // Transport is not used for now...
969  /*
970  if (fParams.fTransportSync) {
971  EncodeTransportData();
972  TransportDataHToN(&fReturnTransportData, &fReturnTransportData);
973  // copy to TxBuffer
974  memcpy(fTxData, &fReturnTransportData, sizeof(net_transport_data_t));
975  }
976  // then others
977  // ...
978  */
979 
980  // Write active ports list
981  fTxHeader.fActivePorts = (fNetAudioCaptureBuffer) ? fNetAudioCaptureBuffer->ActivePortsToNetwork(fTxData) : 0;
982  fTxHeader.fFrames = frames;
983  }
984 
985  void JackNetSlaveInterface::DecodeSyncPacket(int& frames)
986  {
987  // This method contains every step of sync packet informations decoding process
988 
989  // Transport not used for now...
990  /*
991  // first : transport
992  if (fParams.fTransportSync) {
993  // copy received transport data to transport data structure
994  memcpy(&fSendTransportData, fRxData, sizeof(net_transport_data_t));
995  TransportDataNToH(&fSendTransportData, &fSendTransportData);
996  DecodeTransportData();
997  }
998  // then others
999  // ...
1000  */
1001 
1002  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
1003 
1004  // Read active ports list
1005  if (fNetAudioPlaybackBuffer) {
1006  fNetAudioPlaybackBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
1007  }
1008 
1009  frames = rx_head->fFrames;
1010  }
1011 
1012 }
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
SERVER_EXPORT void jack_info(const char *fmt,...)
Definition: JackError.cpp:100
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:108