Jack2  1.9.12
JackNetTool.h
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 
20 #include "JackMidiPort.h"
21 #include "JackTools.h"
22 #include "types.h"
23 #include "transport.h"
24 #ifndef WIN32
25 #include <netinet/in.h>
26 #endif
27 #include <cmath>
28 
29 using namespace std;
30 
31 #ifndef htonll
32 #ifdef __BIG_ENDIAN__
33 #define htonll(x) (x)
34 #define ntohll(x) (x)
35 #else
36 #define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl(x >> 32))
37 #define ntohll(x) ((((uint64_t)ntohl(x)) << 32) + ntohl(x >> 32))
38 #endif
39 #endif
40 
41 #define NETWORK_PROTOCOL 8
42 
43 #define NET_SYNCHING 0
44 #define SYNC_PACKET_ERROR -2
45 #define DATA_PACKET_ERROR -3
46 
47 #define OPTIMIZED_PROTOCOL 1
48 
49 #define UDP_HEADER_SIZE 64 // 40 bytes for IP header in IPV6, 20 in IPV4, 8 for UDP, so take 64
50 #define HEADER_SIZE (sizeof(packet_header_t))
51 
52 #define PACKET_AVAILABLE_SIZE(params) ((params)->fMtu - UDP_HEADER_SIZE - HEADER_SIZE)
53 
54 namespace Jack
55 {
56  typedef struct _session_params session_params_t;
57  typedef struct _packet_header packet_header_t;
58  typedef struct _net_transport_data net_transport_data_t;
59  typedef struct sockaddr socket_address_t;
60  typedef struct in_addr address_t;
61  typedef jack_default_audio_sample_t sample_t;
62 
63  enum JackNetEncoder {
64 
65  JackFloatEncoder = 0,
66  JackIntEncoder = 1,
67  JackCeltEncoder = 2,
68  JackOpusEncoder = 3,
69  };
70 
71 //session params ******************************************************************************
72 
90  PRE_PACKED_STRUCTURE
92  {
93  char fPacketType[8]; //packet type ('param')
94  uint32_t fProtocolVersion; //version
95  int32_t fPacketID; //indicates the packet type
96  char fName[JACK_CLIENT_NAME_SIZE]; //slave's name
97  char fMasterNetName[JACK_SERVER_NAME_SIZE]; //master hostname (network)
98  char fSlaveNetName[JACK_SERVER_NAME_SIZE]; //slave hostname (network)
99  uint32_t fMtu; //connection mtu
100  uint32_t fID; //slave's ID
101  uint32_t fTransportSync; //is the transport synced ?
102  int32_t fSendAudioChannels; //number of master->slave channels
103  int32_t fReturnAudioChannels; //number of slave->master channels
104  int32_t fSendMidiChannels; //number of master->slave midi channels
105  int32_t fReturnMidiChannels; //number of slave->master midi channels
106  uint32_t fSampleRate; //session sample rate
107  uint32_t fPeriodSize; //period size
108  uint32_t fSampleEncoder; //samples encoder
109  uint32_t fKBps; //KB per second for CELT encoder
110  uint32_t fSlaveSyncMode; //is the slave in sync mode ?
111  uint32_t fNetworkLatency; //network latency
112  } POST_PACKED_STRUCTURE;
113 
114 //net status **********************************************************************************
115 
120  enum _net_status
121  {
122  NET_SOCKET_ERROR = 0,
123  NET_CONNECT_ERROR,
124  NET_ERROR,
125  NET_SEND_ERROR,
126  NET_RECV_ERROR,
127  NET_CONNECTED,
128  NET_ROLLING
129  };
130 
131  typedef enum _net_status net_status_t;
132 
133 //sync packet type ****************************************************************************
134 
139  enum _sync_packet_type
140  {
141  INVALID = 0, //...
142  SLAVE_AVAILABLE, //a slave is available
143  SLAVE_SETUP, //slave configuration
144  START_MASTER, //slave is ready, start master
145  START_SLAVE, //master is ready, activate slave
146  KILL_MASTER //master must stop
147  };
148 
149  typedef enum _sync_packet_type sync_packet_type_t;
150 
151 
152 //packet header *******************************************************************************
153 
173  PRE_PACKED_STRUCTURE
175  {
176  char fPacketType[8]; //packet type ('headr')
177  uint32_t fDataType; //'a' for audio, 'm' for midi and 's' for sync
178  uint32_t fDataStream; //'s' for send, 'r' for return
179  uint32_t fID; //unique ID of the slave
180  uint32_t fNumPacket; //number of data packets of the cycle
181  uint32_t fPacketSize; //packet size in bytes
182  uint32_t fActivePorts; //number of active ports
183  uint32_t fCycle; //process cycle counter
184  uint32_t fSubCycle; //midi/audio subcycle counter
185  int32_t fFrames; //process cycle size in frames (can be -1 to indicate entire buffer)
186  uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n')
187  } POST_PACKED_STRUCTURE;
188 
189 //net timebase master
190 
195  enum _net_timebase_master
196  {
197  NO_CHANGE = 0,
198  RELEASE_TIMEBASEMASTER = 1,
199  TIMEBASEMASTER = 2,
200  CONDITIONAL_TIMEBASEMASTER = 3
201  };
202 
203  typedef enum _net_timebase_master net_timebase_master_t;
204 
205 
206 //transport data ******************************************************************************
207 
212  PRE_PACKED_STRUCTURE
214  {
215  uint32_t fNewState; //is it a state change
216  uint32_t fTimebaseMaster; //is there a new timebase master
217  int32_t fState; //current cycle state
218  jack_position_t fPosition; //current cycle position
219  } POST_PACKED_STRUCTURE;
220 
221  //midi data ***********************************************************************************
222 
238  class SERVER_EXPORT NetMidiBuffer
239  {
240  private:
241 
242  int fNPorts;
243  size_t fMaxBufsize;
244  int fMaxPcktSize;
245 
246  char* fBuffer;
247  char* fNetBuffer;
248  JackMidiBuffer** fPortBuffer;
249 
250  size_t fCycleBytesSize; // needed size in bytes ofr an entire cycle
251 
252  public:
253 
254  NetMidiBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
255  ~NetMidiBuffer();
256 
257  void Reset();
258 
259  // needed size in bytes for an entire cycle
260  size_t GetCycleSize();
261  int GetNumPackets(int data_sizen, int max_size);
262 
263  void SetBuffer(int index, JackMidiBuffer* buffer);
264  JackMidiBuffer* GetBuffer(int index);
265 
266  //utility
267  void DisplayEvents();
268 
269  //jack<->buffer
270  int RenderFromJackPorts();
271  void RenderToJackPorts();
272 
273  //network<->buffer
274  void RenderFromNetwork(int sub_cycle, size_t copy_size);
275  int RenderToNetwork(int sub_cycle, size_t total_size);
276 
277  };
278 
279 // audio data *********************************************************************************
280 
281  class SERVER_EXPORT NetAudioBuffer
282  {
283 
284  protected:
285 
286  int fNPorts;
287  int fLastSubCycle;
288  int fNumPackets;
289 
290  char* fNetBuffer;
291  sample_t** fPortBuffer;
292  bool* fConnectedPorts;
293 
294  jack_nframes_t fPeriodSize;
295  jack_nframes_t fSubPeriodSize;
296  size_t fSubPeriodBytesSize;
297 
298  float fCycleDuration; // in sec
299  size_t fCycleBytesSize; // needed size in bytes for an entire cycle
300 
301  int CheckPacket(int cycle, int sub_cycle);
302  void NextCycle();
303  void Cleanup();
304 
305  public:
306 
307  NetAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
308  virtual ~NetAudioBuffer();
309 
310  bool GetConnected(int port_index) { return fConnectedPorts[port_index]; }
311  void SetConnected(int port_index, bool state) { fConnectedPorts[port_index] = state; }
312 
313  // needed syze in bytes ofr an entire cycle
314  virtual size_t GetCycleSize() = 0;
315 
316  // cycle duration in sec
317  virtual float GetCycleDuration() = 0;
318 
319  virtual int GetNumPackets(int active_ports) = 0;
320 
321  virtual void SetBuffer(int index, sample_t* buffer);
322  virtual sample_t* GetBuffer(int index);
323 
324  //jack<->buffer
325  virtual int RenderFromJackPorts(int nframes);
326  virtual void RenderToJackPorts(int nframes);
327 
328  //network<->buffer
329  virtual int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num) = 0;
330  virtual int RenderToNetwork(int sub_cycle, uint32_t port_num) = 0;
331 
332  virtual int ActivePortsToNetwork(char* net_buffer);
333  virtual void ActivePortsFromNetwork(char* net_buffer, uint32_t port_num);
334 
335  };
336 
337  class SERVER_EXPORT NetFloatAudioBuffer : public NetAudioBuffer
338  {
339 
340  private:
341 
342  int fPacketSize;
343 
344  void UpdateParams(int active_ports);
345 
346 
347  void RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle);
348  void RenderToNetwork(char* net_buffer, int active_port, int sub_cycle);
349 
350  public:
351 
352  NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
353  virtual ~NetFloatAudioBuffer();
354 
355  // needed size in bytes for an entire cycle
356  size_t GetCycleSize();
357 
358  // cycle duration in sec
359  float GetCycleDuration();
360  int GetNumPackets(int active_ports);
361 
362  //jack<->buffer
363  int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
364  int RenderToNetwork(int sub_cycle, uint32_t port_num);
365 
366  };
367 
368 #if HAVE_CELT
369 
370 #include <celt/celt.h>
371 
372  class SERVER_EXPORT NetCeltAudioBuffer : public NetAudioBuffer
373  {
374  private:
375 
376  CELTMode** fCeltMode;
377  CELTEncoder** fCeltEncoder;
378  CELTDecoder** fCeltDecoder;
379 
380  int fCompressedSizeByte;
381  unsigned char** fCompressedBuffer;
382 
383  size_t fLastSubPeriodBytesSize;
384 
385  void FreeCelt();
386 
387  public:
388 
389  NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps);
390  virtual ~NetCeltAudioBuffer();
391 
392  // needed size in bytes for an entire cycle
393  size_t GetCycleSize();
394 
395  // cycle duration in sec
396  float GetCycleDuration();
397  int GetNumPackets(int active_ports);
398 
399  //jack<->buffer
400  int RenderFromJackPorts(int nframes);
401  void RenderToJackPorts(int nframes);
402 
403  //network<->buffer
404  int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
405  int RenderToNetwork(int sub_cycle, uint32_t port_num);
406  };
407 
408 #endif
409 
410 #if HAVE_OPUS
411 
412 #include <opus/opus.h>
413 #include <opus/opus_custom.h>
414 
415  class SERVER_EXPORT NetOpusAudioBuffer : public NetAudioBuffer
416  {
417  private:
418 
419  OpusCustomMode** fOpusMode;
420  OpusCustomEncoder** fOpusEncoder;
421  OpusCustomDecoder** fOpusDecoder;
422 
423  int fCompressedMaxSizeByte;
424  unsigned short* fCompressedSizesByte;
425 
426  size_t fLastSubPeriodBytesSize;
427 
428  unsigned char** fCompressedBuffer;
429  void FreeOpus();
430 
431  public:
432 
433  NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps);
434  virtual ~NetOpusAudioBuffer();
435 
436  // needed size in bytes for an entire cycle
437  size_t GetCycleSize();
438 
439  // cycle duration in sec
440  float GetCycleDuration();
441  int GetNumPackets(int active_ports);
442 
443  //jack<->buffer
444  int RenderFromJackPorts(int nframes);
445  void RenderToJackPorts(int nframes);
446 
447  //network<->buffer
448  int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
449  int RenderToNetwork(int sub_cycle, uint32_t port_num);
450  };
451 
452 #endif
453 
454  class SERVER_EXPORT NetIntAudioBuffer : public NetAudioBuffer
455  {
456  private:
457 
458  int fCompressedSizeByte;
459 
460  size_t fLastSubPeriodBytesSize;
461 
462  short** fIntBuffer;
463 
464  public:
465 
466  NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
467  virtual ~NetIntAudioBuffer();
468 
469  // needed size in bytes for an entire cycle
470  size_t GetCycleSize();
471 
472  // cycle duration in sec
473  float GetCycleDuration();
474  int GetNumPackets(int active_ports);
475 
476  //jack<->buffer
477  int RenderFromJackPorts(int nframes);
478  void RenderToJackPorts(int nframes);
479 
480  //network<->buffer
481  int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
482  int RenderToNetwork(int sub_cycle, uint32_t port_num);
483  };
484 
485  //utility *************************************************************************************
486 
487  //socket API management
488  SERVER_EXPORT int SocketAPIInit();
489  SERVER_EXPORT int SocketAPIEnd();
490  //n<-->h functions
491  SERVER_EXPORT void SessionParamsHToN(session_params_t* src_params, session_params_t* dst_params);
492  SERVER_EXPORT void SessionParamsNToH(session_params_t* src_params, session_params_t* dst_params);
493  SERVER_EXPORT void PacketHeaderHToN(packet_header_t* src_header, packet_header_t* dst_header);
494  SERVER_EXPORT void PacketHeaderNToH(packet_header_t* src_header, packet_header_t* dst_header);
495  SERVER_EXPORT void MidiBufferHToN(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer);
496  SERVER_EXPORT void MidiBufferNToH(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer);
497  SERVER_EXPORT void TransportDataHToN(net_transport_data_t* src_params, net_transport_data_t* dst_params);
498  SERVER_EXPORT void TransportDataNToH(net_transport_data_t* src_params, net_transport_data_t* dst_params);
499  //display session parameters
500  SERVER_EXPORT void SessionParamsDisplay(session_params_t* params);
501  //display packet header
502  SERVER_EXPORT void PacketHeaderDisplay(packet_header_t* header);
503  //get the packet type from a sesion parameters
504  SERVER_EXPORT sync_packet_type_t GetPacketType(session_params_t* params);
505  //set the packet type in a session parameters
506  SERVER_EXPORT int SetPacketType(session_params_t* params, sync_packet_type_t packet_type);
507  //transport utility
508  SERVER_EXPORT const char* GetTransportState(int transport_state);
509  SERVER_EXPORT void NetTransportDataDisplay(net_transport_data_t* data);
510 }
Jack::_net_transport_data
Definition: JackNetTool.h:213
Jack::NetAudioBuffer
Definition: JackNetTool.h:281
_jack_position
Definition: types.h:554
Jack::_packet_header
Definition: JackNetTool.h:174
Jack::_session_params
This structure containes master/slave connection parameters, it's used to setup the whole system.
Definition: JackNetTool.h:91
Jack::NetMidiBuffer
Definition: JackNetTool.h:238
Jack::JackMidiBuffer
Definition: JackMidiPort.h:75
Jack::NetIntAudioBuffer
Definition: JackNetTool.h:454
Jack::NetFloatAudioBuffer
Definition: JackNetTool.h:337