Jack2  1.9.10
JackNetTool.h
00001 /*
00002 Copyright (C) 2008-2011 Romain Moret at Grame
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation; either version 2 of the License, or
00007 (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 
00018 */
00019 
00020 #include "JackMidiPort.h"
00021 #include "JackTools.h"
00022 #include "types.h"
00023 #include "transport.h"
00024 #ifndef WIN32
00025 #include <netinet/in.h>
00026 #endif
00027 #include <cmath>
00028 
00029 using namespace std;
00030 
00031 #ifndef htonll
00032 #ifdef __BIG_ENDIAN__
00033 #define htonll(x) (x)
00034 #define ntohll(x) (x)
00035 #else
00036 #define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl(x >> 32))
00037 #define ntohll(x) ((((uint64_t)ntohl(x)) << 32) + ntohl(x >> 32))
00038 #endif
00039 #endif
00040 
00041 #define NETWORK_PROTOCOL 8
00042 
00043 #define NET_SYNCHING      0
00044 #define SYNC_PACKET_ERROR -2
00045 #define DATA_PACKET_ERROR -3
00046 
00047 #define OPTIMIZED_PROTOCOL 1
00048 
00049 #define HEADER_SIZE (sizeof(packet_header_t))
00050 #define PACKET_AVAILABLE_SIZE(params) ((params)->fMtu - sizeof(packet_header_t))
00051 
00052 namespace Jack
00053 {
00054     typedef struct _session_params session_params_t;
00055     typedef struct _packet_header packet_header_t;
00056     typedef struct _net_transport_data net_transport_data_t;
00057     typedef struct sockaddr socket_address_t;
00058     typedef struct in_addr address_t;
00059     typedef jack_default_audio_sample_t sample_t;
00060 
00061     enum JackNetEncoder {
00062 
00063         JackFloatEncoder = 0,
00064         JackIntEncoder = 1,
00065         JackCeltEncoder = 2,
00066         JackOpusEncoder = 3,
00067     };
00068 
00069 //session params ******************************************************************************
00070 
00088     PRE_PACKED_STRUCTURE
00089     struct _session_params
00090     {
00091         char fPacketType[8];                        //packet type ('param')
00092         uint32_t fProtocolVersion;                  //version
00093         int32_t fPacketID;                          //indicates the packet type
00094         char fName[JACK_CLIENT_NAME_SIZE];          //slave's name
00095         char fMasterNetName[JACK_SERVER_NAME_SIZE]; //master hostname (network)
00096         char fSlaveNetName[JACK_SERVER_NAME_SIZE];  //slave hostname (network)
00097         uint32_t fMtu;                              //connection mtu
00098         uint32_t fID;                               //slave's ID
00099         uint32_t fTransportSync;                    //is the transport synced ?
00100         int32_t fSendAudioChannels;                 //number of master->slave channels
00101         int32_t fReturnAudioChannels;               //number of slave->master channels
00102         int32_t fSendMidiChannels;                  //number of master->slave midi channels
00103         int32_t fReturnMidiChannels;                //number of slave->master midi channels
00104         uint32_t fSampleRate;                       //session sample rate
00105         uint32_t fPeriodSize;                       //period size
00106         uint32_t fSampleEncoder;                    //samples encoder
00107         uint32_t fKBps;                             //KB per second for CELT encoder
00108         uint32_t fSlaveSyncMode;                    //is the slave in sync mode ?
00109         uint32_t fNetworkLatency;                   //network latency
00110     } POST_PACKED_STRUCTURE;
00111 
00112 //net status **********************************************************************************
00113 
00118     enum  _net_status
00119     {
00120         NET_SOCKET_ERROR = 0,
00121         NET_CONNECT_ERROR,
00122         NET_ERROR,
00123         NET_SEND_ERROR,
00124         NET_RECV_ERROR,
00125         NET_CONNECTED,
00126         NET_ROLLING
00127     };
00128 
00129     typedef enum _net_status net_status_t;
00130 
00131 //sync packet type ****************************************************************************
00132 
00137     enum _sync_packet_type
00138     {
00139         INVALID = 0,        //...
00140         SLAVE_AVAILABLE,    //a slave is available
00141         SLAVE_SETUP,        //slave configuration
00142         START_MASTER,       //slave is ready, start master
00143         START_SLAVE,        //master is ready, activate slave
00144         KILL_MASTER         //master must stop
00145     };
00146 
00147     typedef enum _sync_packet_type sync_packet_type_t;
00148 
00149 
00150 //packet header *******************************************************************************
00151 
00171     PRE_PACKED_STRUCTURE
00172     struct _packet_header
00173     {
00174         char fPacketType[8];        //packet type ('headr')
00175         uint32_t fDataType;         //'a' for audio, 'm' for midi and 's' for sync
00176         uint32_t fDataStream;       //'s' for send, 'r' for return
00177         uint32_t fID;               //unique ID of the slave
00178         uint32_t fNumPacket;        //number of data packets of the cycle
00179         uint32_t fPacketSize;       //packet size in bytes
00180         uint32_t fActivePorts;      //number of active ports
00181         uint32_t fCycle;            //process cycle counter
00182         uint32_t fSubCycle;         //midi/audio subcycle counter
00183         int32_t fFrames;            //process cycle size in frames (can be -1 to indicate entire buffer)
00184         uint32_t fIsLastPckt;       //is it the last packet of a given cycle ('y' or 'n')
00185     } POST_PACKED_STRUCTURE;
00186 
00187 //net timebase master
00188 
00193     enum _net_timebase_master
00194     {
00195         NO_CHANGE = 0,
00196         RELEASE_TIMEBASEMASTER = 1,
00197         TIMEBASEMASTER = 2,
00198         CONDITIONAL_TIMEBASEMASTER = 3
00199     };
00200 
00201     typedef enum _net_timebase_master net_timebase_master_t;
00202 
00203 
00204 //transport data ******************************************************************************
00205 
00210     PRE_PACKED_STRUCTURE
00211     struct _net_transport_data
00212     {
00213         uint32_t fNewState;             //is it a state change
00214         uint32_t fTimebaseMaster;       //is there a new timebase master
00215         int32_t fState;                 //current cycle state
00216         jack_position_t fPosition;      //current cycle position
00217     } POST_PACKED_STRUCTURE;
00218 
00219  //midi data ***********************************************************************************
00220 
00236     class SERVER_EXPORT NetMidiBuffer
00237     {
00238         private:
00239 
00240             int fNPorts;
00241             size_t fMaxBufsize;
00242             int fMaxPcktSize;
00243 
00244             char* fBuffer;
00245             char* fNetBuffer;
00246             JackMidiBuffer** fPortBuffer;
00247 
00248             size_t fCycleBytesSize;  // needed size in bytes ofr an entire cycle
00249 
00250         public:
00251 
00252             NetMidiBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
00253             ~NetMidiBuffer();
00254 
00255             void Reset();
00256 
00257             // needed size in bytes for an entire cycle
00258             size_t GetCycleSize();
00259             int GetNumPackets(int data_sizen, int max_size);
00260 
00261             void SetBuffer(int index, JackMidiBuffer* buffer);
00262             JackMidiBuffer* GetBuffer(int index);
00263 
00264             //utility
00265             void DisplayEvents();
00266 
00267             //jack<->buffer
00268             int RenderFromJackPorts();
00269             void RenderToJackPorts();
00270 
00271             //network<->buffer
00272             void RenderFromNetwork(int sub_cycle, size_t copy_size);
00273             int RenderToNetwork(int sub_cycle, size_t total_size);
00274 
00275     };
00276 
00277 // audio data *********************************************************************************
00278 
00279     class SERVER_EXPORT NetAudioBuffer
00280     {
00281 
00282         protected:
00283 
00284             int fNPorts;
00285             int fLastSubCycle;
00286             int fNumPackets;
00287 
00288             char* fNetBuffer;
00289             sample_t** fPortBuffer;
00290             bool* fConnectedPorts;
00291 
00292             jack_nframes_t fPeriodSize;
00293             jack_nframes_t fSubPeriodSize;
00294             size_t fSubPeriodBytesSize;
00295 
00296             float fCycleDuration;       // in sec
00297             size_t fCycleBytesSize;     // needed size in bytes for an entire cycle
00298 
00299             int CheckPacket(int cycle, int sub_cycle);
00300             void NextCycle();
00301             void Cleanup();
00302 
00303         public:
00304 
00305             NetAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
00306             virtual ~NetAudioBuffer();
00307 
00308             bool GetConnected(int port_index) { return fConnectedPorts[port_index]; }
00309             void SetConnected(int port_index, bool state) { fConnectedPorts[port_index] = state; }
00310 
00311             // needed syze in bytes ofr an entire cycle
00312             virtual size_t GetCycleSize() = 0;
00313 
00314             // cycle duration in sec
00315             virtual float GetCycleDuration() = 0;
00316 
00317             virtual int GetNumPackets(int active_ports) = 0;
00318 
00319             virtual void SetBuffer(int index, sample_t* buffer);
00320             virtual sample_t* GetBuffer(int index);
00321 
00322             //jack<->buffer
00323             virtual int RenderFromJackPorts(int nframes);
00324             virtual void RenderToJackPorts(int nframes);
00325 
00326             //network<->buffer
00327             virtual int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num) = 0;
00328             virtual int RenderToNetwork(int sub_cycle, uint32_t port_num) = 0;
00329 
00330             virtual int ActivePortsToNetwork(char* net_buffer);
00331             virtual void ActivePortsFromNetwork(char* net_buffer, uint32_t port_num);
00332 
00333     };
00334 
00335     class SERVER_EXPORT NetFloatAudioBuffer : public NetAudioBuffer
00336     {
00337 
00338         private:
00339 
00340             int fPacketSize;
00341 
00342             void UpdateParams(int active_ports);
00343         
00344         
00345             void RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle);
00346             void RenderToNetwork(char* net_buffer, int active_port, int sub_cycle);
00347 
00348         public:
00349 
00350             NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
00351             virtual ~NetFloatAudioBuffer();
00352 
00353             // needed size in bytes for an entire cycle
00354             size_t GetCycleSize();
00355 
00356             // cycle duration in sec
00357             float GetCycleDuration();
00358             int GetNumPackets(int active_ports);
00359 
00360             //jack<->buffer
00361             int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
00362             int RenderToNetwork(int sub_cycle, uint32_t port_num);
00363 
00364     };
00365 
00366 #if HAVE_CELT
00367 
00368 #include <celt/celt.h>
00369 
00370     class SERVER_EXPORT NetCeltAudioBuffer : public NetAudioBuffer
00371     {
00372         private:
00373 
00374             CELTMode** fCeltMode;
00375             CELTEncoder** fCeltEncoder;
00376             CELTDecoder** fCeltDecoder;
00377 
00378             int fCompressedSizeByte;
00379             unsigned char** fCompressedBuffer;
00380    
00381             size_t fLastSubPeriodBytesSize;
00382 
00383             void FreeCelt();
00384 
00385         public:
00386 
00387             NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps);
00388             virtual ~NetCeltAudioBuffer();
00389 
00390             // needed size in bytes for an entire cycle
00391             size_t GetCycleSize();
00392 
00393              // cycle duration in sec
00394             float GetCycleDuration();
00395             int GetNumPackets(int active_ports);
00396 
00397             //jack<->buffer
00398             int RenderFromJackPorts(int nframes);
00399             void RenderToJackPorts(int nframes);
00400 
00401             //network<->buffer
00402             int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
00403             int RenderToNetwork(int sub_cycle, uint32_t port_num);
00404     };
00405 
00406 #endif
00407 
00408 #if HAVE_OPUS
00409 
00410 #include <opus/opus.h>
00411 #include <opus/opus_custom.h>
00412 
00413     class SERVER_EXPORT NetOpusAudioBuffer : public NetAudioBuffer
00414     {
00415         private:
00416 
00417             OpusCustomMode** fOpusMode;
00418             OpusCustomEncoder** fOpusEncoder;
00419             OpusCustomDecoder** fOpusDecoder;
00420 
00421             int fCompressedMaxSizeByte;
00422             unsigned short* fCompressedSizesByte;
00423    
00424             size_t fLastSubPeriodBytesSize;
00425 
00426             unsigned char** fCompressedBuffer;
00427             void FreeOpus();
00428 
00429         public:
00430 
00431             NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps);
00432             virtual ~NetOpusAudioBuffer();
00433 
00434             // needed size in bytes for an entire cycle
00435             size_t GetCycleSize();
00436 
00437              // cycle duration in sec
00438             float GetCycleDuration();
00439             int GetNumPackets(int active_ports);
00440 
00441             //jack<->buffer
00442             int RenderFromJackPorts(int nframes);
00443             void RenderToJackPorts(int nframes);
00444 
00445             //network<->buffer
00446             int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
00447             int RenderToNetwork(int sub_cycle, uint32_t  port_num);
00448     };
00449 
00450 #endif
00451 
00452     class SERVER_EXPORT NetIntAudioBuffer : public NetAudioBuffer
00453     {
00454         private:
00455 
00456             int fCompressedSizeByte;
00457  
00458             size_t fLastSubPeriodBytesSize;
00459 
00460             short** fIntBuffer;
00461 
00462         public:
00463 
00464             NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
00465             virtual ~NetIntAudioBuffer();
00466 
00467             // needed size in bytes for an entire cycle
00468             size_t GetCycleSize();
00469 
00470              // cycle duration in sec
00471             float GetCycleDuration();
00472             int GetNumPackets(int active_ports);
00473 
00474             //jack<->buffer
00475             int RenderFromJackPorts(int nframes);
00476             void RenderToJackPorts(int nframes);
00477 
00478             //network<->buffer
00479             int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
00480             int RenderToNetwork(int sub_cycle, uint32_t port_num);
00481     };
00482 
00483     //utility *************************************************************************************
00484 
00485     //socket API management
00486     SERVER_EXPORT int SocketAPIInit();
00487     SERVER_EXPORT int SocketAPIEnd();
00488     //n<-->h functions
00489     SERVER_EXPORT void SessionParamsHToN(session_params_t* src_params, session_params_t* dst_params);
00490     SERVER_EXPORT void SessionParamsNToH(session_params_t* src_params, session_params_t* dst_params);
00491     SERVER_EXPORT void PacketHeaderHToN(packet_header_t* src_header, packet_header_t* dst_header);
00492     SERVER_EXPORT void PacketHeaderNToH(packet_header_t* src_header, packet_header_t* dst_header);
00493     SERVER_EXPORT void MidiBufferHToN(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer);
00494     SERVER_EXPORT void MidiBufferNToH(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer);
00495     SERVER_EXPORT void TransportDataHToN(net_transport_data_t* src_params, net_transport_data_t* dst_params);
00496     SERVER_EXPORT void TransportDataNToH(net_transport_data_t* src_params, net_transport_data_t* dst_params);
00497     //display session parameters
00498     SERVER_EXPORT void SessionParamsDisplay(session_params_t* params);
00499     //display packet header
00500     SERVER_EXPORT void PacketHeaderDisplay(packet_header_t* header);
00501     //get the packet type from a sesion parameters
00502     SERVER_EXPORT sync_packet_type_t GetPacketType(session_params_t* params);
00503     //set the packet type in a session parameters
00504     SERVER_EXPORT int SetPacketType(session_params_t* params, sync_packet_type_t packet_type);
00505     //transport utility
00506     SERVER_EXPORT const char* GetTransportState(int transport_state);
00507     SERVER_EXPORT void NetTransportDataDisplay(net_transport_data_t* data);
00508 }