Jack2: JackNetTool.h Source File

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
91 struct _session_params
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
174 struct _packet_header
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
213 struct _net_transport_data
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_position
Definition: types.h:554
Jack::NetFloatAudioBuffer
Definition: JackNetTool.h:337
Jack::_packet_header
Definition: JackNetTool.h:174
Jack::NetIntAudioBuffer
Definition: JackNetTool.h:454
Jack::JackMidiBuffer
Definition: JackMidiPort.h:75
Jack::NetMidiBuffer
Definition: JackNetTool.h:238
Jack::NetAudioBuffer
Definition: JackNetTool.h:281
Jack::_session_params
This structure containes master/slave connection parameters, it's used to setup the whole system.
Definition: JackNetTool.h:91
Jack::_net_transport_data
Definition: JackNetTool.h:213