Jack2 1.9.6

JackNetInterface.cpp

00001 /*
00002 Copyright (C) 2001 Paul Davis
00003 Copyright (C) 2008 Romain Moret at Grame
00004 
00005 This program is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU General Public License as published by
00007 the Free Software Foundation; either version 2 of the License, or
00008 (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 #include "JackNetInterface.h"
00021 #include "JackException.h"
00022 #include "JackPlatformPlug.h"
00023 #include <assert.h>
00024 
00025 using namespace std;
00026 
00027 /*  
00028  TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames, 
00029  probably also use BUFFER_SIZE_MAX in everything related to MIDI events 
00030  handling (see MidiBufferInit in JackMidiPort.cpp)
00031 */
00032 
00033 namespace Jack
00034 {
00035     // JackNetInterface*******************************************
00036 
00037     JackNetInterface::JackNetInterface() : fSocket()
00038     {
00039         fTxBuffer = NULL;
00040         fRxBuffer = NULL;
00041         fNetAudioCaptureBuffer = NULL;
00042         fNetAudioPlaybackBuffer = NULL;
00043         fNetMidiCaptureBuffer = NULL;
00044         fNetMidiPlaybackBuffer = NULL;
00045         memset(&fSendTransportData, 0, sizeof(net_transport_data_t));
00046         memset(&fReturnTransportData, 0, sizeof(net_transport_data_t));
00047     }
00048 
00049     JackNetInterface::JackNetInterface ( const char* multicast_ip, int port ) : fSocket ( multicast_ip, port )
00050     {
00051         strcpy(fMulticastIP, multicast_ip);
00052         fTxBuffer = NULL;
00053         fRxBuffer = NULL;
00054         fNetAudioCaptureBuffer = NULL;
00055         fNetAudioPlaybackBuffer = NULL;
00056         fNetMidiCaptureBuffer = NULL;
00057         fNetMidiPlaybackBuffer = NULL;
00058         memset(&fSendTransportData, 0, sizeof(net_transport_data_t));
00059         memset(&fReturnTransportData, 0, sizeof(net_transport_data_t));
00060     }
00061 
00062     JackNetInterface::JackNetInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) : fSocket ( socket )
00063     {
00064         fParams = params;
00065         strcpy(fMulticastIP, multicast_ip);
00066         fTxBuffer = NULL;
00067         fRxBuffer = NULL;
00068         fNetAudioCaptureBuffer = NULL;
00069         fNetAudioPlaybackBuffer = NULL;
00070         fNetMidiCaptureBuffer = NULL;
00071         fNetMidiPlaybackBuffer = NULL;
00072         memset(&fSendTransportData, 0, sizeof(net_transport_data_t));
00073         memset(&fReturnTransportData, 0, sizeof(net_transport_data_t));
00074     }
00075 
00076     JackNetInterface::~JackNetInterface()
00077     {
00078         jack_log ( "JackNetInterface::~JackNetInterface" );
00079 
00080         fSocket.Close();
00081         delete[] fTxBuffer;
00082         delete[] fRxBuffer;
00083         delete fNetAudioCaptureBuffer;
00084         delete fNetAudioPlaybackBuffer;
00085         delete fNetMidiCaptureBuffer;
00086         delete fNetMidiPlaybackBuffer;
00087     }
00088 
00089     void JackNetInterface::SetFramesPerPacket()
00090     {
00091         jack_log ( "JackNetInterface::SetFramesPerPacket" );
00092 
00093         if (fParams.fSendAudioChannels == 0 && fParams.fReturnAudioChannels == 0) {
00094             fParams.fFramesPerPacket = fParams.fPeriodSize;
00095         } else {
00096             jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ( fParams.fMtu - sizeof ( packet_header_t ) )
00097                                                / ( max ( fParams.fReturnAudioChannels, fParams.fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) );
00098             fParams.fFramesPerPacket = ( period > fParams.fPeriodSize ) ? fParams.fPeriodSize : period;
00099         }
00100     }
00101 
00102     int JackNetInterface::SetNetBufferSize()
00103     {
00104         jack_log ( "JackNetInterface::SetNetBufferSize" );
00105 
00106         float audio_size, midi_size;
00107         int bufsize;
00108         //audio
00109         audio_size = fParams.fMtu * ( fParams.fPeriodSize / fParams.fFramesPerPacket );
00110         //midi
00111         midi_size = fParams.fMtu * ( max ( fParams.fSendMidiChannels, fParams.fReturnMidiChannels ) *
00112                                      fParams.fPeriodSize * sizeof ( sample_t ) / ( fParams.fMtu - sizeof ( packet_header_t ) ) );
00113         //bufsize = sync + audio + midi
00114         bufsize = MAX_LATENCY * (fParams.fMtu + ( int ) audio_size + ( int ) midi_size);
00115 
00116         //tx buffer
00117         if ( fSocket.SetOption ( SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR )
00118             return SOCKET_ERROR;
00119 
00120         //rx buffer
00121         if ( fSocket.SetOption ( SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR )
00122             return SOCKET_ERROR;
00123 
00124         return 0;
00125     }
00126 
00127     int JackNetInterface::GetNMidiPckt()
00128     {
00129         //even if there is no midi data, jack need an empty buffer to know there is no event to read
00130         //99% of the cases : all data in one packet
00131         if ( fTxHeader.fMidiDataSize <= ( fParams.fMtu - sizeof ( packet_header_t ) ) )
00132             return 1;
00133         //else, get the number of needed packets (simply slice the biiig buffer)
00134         int npckt = fTxHeader.fMidiDataSize / ( fParams.fMtu - sizeof ( packet_header_t ) );
00135         if ( fTxHeader.fMidiDataSize % ( fParams.fMtu - sizeof ( packet_header_t ) ) )
00136             return ++npckt;
00137         return npckt;
00138     }
00139 
00140     bool JackNetInterface::IsNextPacket()
00141     {
00142         packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
00143         //ignore first cycle
00144         if ( fRxHeader.fCycle <= 1 ) {
00145             return true;
00146         }
00147         //same PcktID (cycle), next SubPcktID (subcycle)
00148         if ( ( fRxHeader.fSubCycle < ( fNSubProcess - 1 ) ) && ( rx_head->fCycle == fRxHeader.fCycle ) && ( rx_head->fSubCycle == ( fRxHeader.fSubCycle + 1 ) ) ) {
00149              return true;
00150         }
00151         //next PcktID (cycle), SubPcktID reset to 0 (first subcyle)
00152         if ( ( rx_head->fCycle == ( fRxHeader.fCycle + 1 ) ) && ( fRxHeader.fSubCycle == ( fNSubProcess - 1 ) ) && ( rx_head->fSubCycle == 0 ) ) {
00153             return true;
00154         }
00155         //else, packet(s) missing, return false
00156         return false;
00157     }
00158 
00159     void JackNetInterface::SetParams()
00160     {
00161         //number of audio subcycles (packets)
00162         fNSubProcess = fParams.fPeriodSize / fParams.fFramesPerPacket;
00163 
00164         //payload size
00165         fPayloadSize = fParams.fMtu - sizeof ( packet_header_t );
00166 
00167         //TX header init
00168         strcpy ( fTxHeader.fPacketType, "header" );
00169         fTxHeader.fID = fParams.fID;
00170         fTxHeader.fCycle = 0;
00171         fTxHeader.fSubCycle = 0;
00172         fTxHeader.fMidiDataSize = 0;
00173         fTxHeader.fBitdepth = fParams.fBitdepth;
00174         fTxHeader.fIsLastPckt = 0;
00175 
00176         //RX header init
00177         strcpy ( fRxHeader.fPacketType, "header" );
00178         fRxHeader.fID = fParams.fID;
00179         fRxHeader.fCycle = 0;
00180         fRxHeader.fSubCycle = 0;
00181         fRxHeader.fMidiDataSize = 0;
00182         fRxHeader.fBitdepth = fParams.fBitdepth;
00183         fRxHeader.fIsLastPckt = 0;
00184 
00185         //network buffers
00186         fTxBuffer = new char[fParams.fMtu];
00187         fRxBuffer = new char[fParams.fMtu];
00188         assert ( fTxBuffer );
00189         assert ( fRxBuffer );
00190 
00191         //net audio/midi buffers'addresses
00192         fTxData = fTxBuffer + sizeof ( packet_header_t );
00193         fRxData = fRxBuffer + sizeof ( packet_header_t );
00194     }
00195 
00196     // JackNetMasterInterface ************************************************************************************
00197 
00198     bool JackNetMasterInterface::Init()
00199     {
00200         jack_log ( "JackNetMasterInterface::Init, ID %u.", fParams.fID );
00201 
00202         session_params_t host_params;
00203         uint attempt = 0;
00204         int rx_bytes = 0;
00205 
00206         //socket
00207         if ( fSocket.NewSocket() == SOCKET_ERROR ) {
00208             jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) );
00209             return false;
00210         }
00211 
00212         //timeout on receive (for init)
00213         if ( fSocket.SetTimeOut ( MASTER_INIT_TIMEOUT ) < 0 )
00214             jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
00215             
00216         //connect
00217         if ( fSocket.Connect() == SOCKET_ERROR ) {
00218             jack_error ( "Can't connect : %s", StrError ( NET_ERROR_CODE ) );
00219             return false;
00220         }
00221 
00222         //set the number of complete audio frames we can put in a packet
00223         SetFramesPerPacket();
00224 
00225         //send 'SLAVE_SETUP' until 'START_MASTER' received
00226         jack_info ( "Sending parameters to %s ...", fParams.fSlaveNetName );
00227         do
00228         {
00229             session_params_t net_params;
00230             memset(&net_params, 0, sizeof ( session_params_t ));
00231             SetPacketType ( &fParams, SLAVE_SETUP );
00232             SessionParamsHToN(&fParams, &net_params);
00233             
00234             if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR )
00235                 jack_error ( "Error in send : ", StrError ( NET_ERROR_CODE ) );
00236                 
00237             memset(&net_params, 0, sizeof ( session_params_t ));
00238             if ( ( ( rx_bytes = fSocket.Recv ( &net_params, sizeof ( session_params_t ), 0 ) ) == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
00239             {
00240                 jack_error ( "Problem with network." );
00241                 return false;
00242             }
00243             
00244             SessionParamsNToH(&net_params, &host_params);
00245         }
00246         while ( ( GetPacketType ( &host_params ) != START_MASTER ) && ( ++attempt < SLAVE_SETUP_RETRY ) );
00247         if ( attempt == SLAVE_SETUP_RETRY ) {
00248             jack_error ( "Slave doesn't respond, exiting." );
00249             return false;
00250         }
00251 
00252         //set the new timeout for the socket
00253         if ( SetRxTimeout() == SOCKET_ERROR ) {
00254             jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) );
00255             return false;
00256         }
00257 
00258         //set the new rx buffer size
00259         if ( SetNetBufferSize() == SOCKET_ERROR ) {
00260             jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );
00261             return false;
00262         }
00263 
00264         return true;
00265     }
00266 
00267     int JackNetMasterInterface::SetRxTimeout()
00268     {
00269         jack_log ( "JackNetMasterInterface::SetRxTimeout" );
00270 
00271         float time = 0;
00272         //slow or normal mode, short timeout on recv (2 audio subcycles)
00273         if ( ( fParams.fNetworkMode == 's' ) || ( fParams.fNetworkMode == 'n' ) )
00274             time = 2000000.f * ( static_cast<float> ( fParams.fFramesPerPacket ) / static_cast<float> ( fParams.fSampleRate ) );
00275         //fast mode, wait for 75% of the entire cycle duration
00276         else if ( fParams.fNetworkMode == 'f' )
00277             time = 750000.f * ( static_cast<float> ( fParams.fPeriodSize ) / static_cast<float> ( fParams.fSampleRate ) );
00278         return fSocket.SetTimeOut ( static_cast<int> ( time ) );
00279     }
00280 
00281     void JackNetMasterInterface::SetParams()
00282     {
00283         jack_log ( "JackNetMasterInterface::SetParams" );
00284 
00285         JackNetInterface::SetParams();
00286 
00287         fTxHeader.fDataStream = 's';
00288         fRxHeader.fDataStream = 'r';
00289 
00290         //midi net buffers
00291         fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fTxData );
00292         fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fRxData );
00293         assert ( fNetMidiCaptureBuffer );
00294         assert ( fNetMidiPlaybackBuffer );
00295 
00296         //audio net buffers
00297         fNetAudioCaptureBuffer = new NetAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
00298         fNetAudioPlaybackBuffer = new NetAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
00299         assert ( fNetAudioCaptureBuffer );
00300         assert ( fNetAudioPlaybackBuffer );
00301 
00302         //audio netbuffer length
00303         fAudioTxLen = sizeof ( packet_header_t ) + fNetAudioCaptureBuffer->GetSize();
00304         fAudioRxLen = sizeof ( packet_header_t ) + fNetAudioPlaybackBuffer->GetSize();
00305     }
00306 
00307     void JackNetMasterInterface::Exit()
00308     {
00309         jack_log ( "JackNetMasterInterface::Exit, ID %u", fParams.fID );
00310 
00311         //stop process
00312         fRunning = false;
00313 
00314         //send a 'multicast euthanasia request' - new socket is required on macosx
00315         jack_info ( "Exiting '%s'", fParams.fName );
00316         SetPacketType ( &fParams, KILL_MASTER );
00317         JackNetSocket mcast_socket ( fMulticastIP, fSocket.GetPort() );
00318         
00319         session_params_t net_params;
00320         memset(&net_params, 0, sizeof ( session_params_t ));
00321         SessionParamsHToN(&fParams, &net_params);
00322 
00323         if ( mcast_socket.NewSocket() == SOCKET_ERROR )
00324             jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) );
00325         if ( mcast_socket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR )
00326             jack_error ( "Can't send suicide request : %s", StrError ( NET_ERROR_CODE ) );
00327             
00328         mcast_socket.Close();
00329     }
00330 
00331     int JackNetMasterInterface::Recv ( size_t size, int flags )
00332     {
00333         int rx_bytes;
00334         if ( ( ( rx_bytes = fSocket.Recv ( fRxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning )
00335         {
00336             net_error_t error = fSocket.GetError();
00337             //no data isn't really a network error, so just return 0 avalaible read bytes
00338             if ( error == NET_NO_DATA )
00339                 return 0;
00340             else if ( error == NET_CONN_ERROR )
00341             {
00342                 //fatal connection issue, exit
00343                 jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) );
00344                 //ask to the manager to properly remove the master
00345                 Exit();
00346                 
00347                 // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
00348                 ThreadExit();
00349             }
00350             else
00351                 jack_error ( "Error in master receive : %s", StrError ( NET_ERROR_CODE ) );
00352         }
00353         
00354         packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
00355         PacketHeaderNToH(header, header);
00356         return rx_bytes;
00357     }
00358     
00359     int JackNetMasterInterface::Send ( size_t size, int flags )
00360     {
00361         int tx_bytes;
00362         packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
00363         PacketHeaderHToN(header, header);
00364         
00365         if ( ( ( tx_bytes = fSocket.Send ( fTxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning )
00366         {
00367             net_error_t error = fSocket.GetError();
00368             if ( error == NET_CONN_ERROR )
00369             {
00370                 //fatal connection issue, exit
00371                 jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) );
00372                 Exit();
00373                 
00374                 // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
00375                 ThreadExit();
00376             }
00377             else
00378                 jack_error ( "Error in master send : %s", StrError ( NET_ERROR_CODE ) );
00379         }
00380         return tx_bytes;
00381     }
00382     
00383     bool JackNetMasterInterface::IsSynched()
00384     {
00385         if (fParams.fNetworkMode == 's') {
00386             return (fCycleOffset < 3);
00387         } else {
00388             return true;
00389         }
00390     }
00391     
00392     int JackNetMasterInterface::SyncSend()
00393     {
00394         fTxHeader.fCycle++;
00395         fTxHeader.fSubCycle = 0;
00396         fTxHeader.fDataType = 's';
00397         fTxHeader.fIsLastPckt = ( fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ?  1 : 0;
00398         fTxHeader.fPacketSize = fParams.fMtu;
00399         memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
00400         return Send ( fTxHeader.fPacketSize, 0 );
00401     }
00402 
00403     int JackNetMasterInterface::DataSend()
00404     {
00405         uint subproc;
00406         //midi
00407         if ( fParams.fSendMidiChannels > 0)
00408         {
00409             //set global header fields and get the number of midi packets
00410             fTxHeader.fDataType = 'm';
00411             fTxHeader.fMidiDataSize = fNetMidiCaptureBuffer->RenderFromJackPorts();
00412             fTxHeader.fNMidiPckt = GetNMidiPckt();
00413             for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ )
00414             {
00415                 fTxHeader.fSubCycle = subproc;
00416                 fTxHeader.fIsLastPckt = ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && (fParams.fSendAudioChannels == 0)) ? 1 : 0;
00417                 fTxHeader.fPacketSize = sizeof ( packet_header_t ) + fNetMidiCaptureBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize );
00418                 memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
00419                 if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR )
00420                     return SOCKET_ERROR;
00421             }
00422         }
00423 
00424         //audio
00425         if ( fParams.fSendAudioChannels > 0)
00426         {
00427             fTxHeader.fDataType = 'a';
00428             fTxHeader.fMidiDataSize = 0;
00429             fTxHeader.fNMidiPckt = 0;
00430             for ( subproc = 0; subproc < fNSubProcess; subproc++ )
00431             {
00432                 fTxHeader.fSubCycle = subproc;
00433                 fTxHeader.fIsLastPckt = ( subproc == ( fNSubProcess - 1 ) ) ? 1 : 0;
00434                 fTxHeader.fPacketSize = fAudioTxLen;
00435                 memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
00436                 fNetAudioCaptureBuffer->RenderFromJackPorts ( subproc );
00437                 if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR )
00438                     return SOCKET_ERROR;
00439             }
00440         }
00441 
00442         return 0;
00443     }
00444 
00445     int JackNetMasterInterface::SyncRecv()
00446     {
00447         packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
00448         int rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
00449         
00450         if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) )
00451             return rx_bytes;
00452 
00453         fCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
00454       
00455         switch ( fParams.fNetworkMode )
00456         {
00457             case 's' :
00458                 //slow mode : allow to use full bandwidth and heavy process on the slave
00459                 //  - extra latency is set to two cycles, one cycle for send/receive operations + one cycle for heavy process on the slave
00460                 //  - if the network is two fast, just wait the next cycle, this mode allows a shorter cycle duration for the master
00461                 //  - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer
00462                 //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process)
00463                 if (fCycleOffset < 2)
00464                      return 0;
00465                 else
00466                     rx_bytes = Recv ( rx_head->fPacketSize, 0 );
00467                     
00468                 if (fCycleOffset > 2) {
00469                     jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
00470                 }
00471                 break;
00472 
00473             case 'n' :
00474                 //normal use of the network :
00475                 //  - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth
00476                 //  - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter
00477                 //  - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it
00478                 if (fCycleOffset < 1)
00479                     return 0;
00480                 else
00481                     rx_bytes = Recv ( rx_head->fPacketSize, 0 );
00482                     
00483                 if (fCycleOffset != 1) 
00484                     jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
00485                 break;
00486 
00487             case 'f' :
00488                 //fast mode suppose the network bandwith is larger than required for the transmission (only a few channels for example)
00489                 //    - packets can be quickly received, quickly is here relative to the cycle duration
00490                 //    - here, receive data, we can't keep it queued on the rx buffer,
00491                 //    - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow
00492                 rx_bytes = Recv ( rx_head->fPacketSize, 0 );
00493                 
00494                 if (fCycleOffset != 0)
00495                     jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
00496                 break;
00497         }
00498 
00499         fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
00500         return rx_bytes;
00501     }
00502     
00503     int JackNetMasterInterface::DataRecv()
00504     {
00505         int rx_bytes = 0;
00506         uint jumpcnt = 0;
00507         uint recvd_midi_pckt = 0;
00508         uint recvd_audio_pckt = 0;
00509         packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
00510         
00511         while ( !fRxHeader.fIsLastPckt )
00512         {
00513             //how much data is queued on the rx buffer ?
00514             rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
00515               
00516             if ( rx_bytes == SOCKET_ERROR )
00517                 return rx_bytes;
00518             //if no data
00519             if ( ( rx_bytes == 0 ) && ( ++jumpcnt == fNSubProcess ) )
00520             {
00521                 jack_error ( "No data from %s...", fParams.fName );
00522                 jumpcnt = 0;
00523             }
00524             //else if data is valid,
00525             if ( rx_bytes && ( rx_head->fDataStream == 'r' ) && ( rx_head->fID == fParams.fID ) )
00526             {
00527                 //read data
00528                 switch ( rx_head->fDataType )
00529                 {
00530                     case 'm':   //midi
00531                         rx_bytes = Recv ( rx_head->fPacketSize, 0 );
00532                         fRxHeader.fCycle = rx_head->fCycle;
00533                         fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
00534                         fNetMidiPlaybackBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) );
00535                         if ( ++recvd_midi_pckt == rx_head->fNMidiPckt )
00536                             fNetMidiPlaybackBuffer->RenderToJackPorts();
00537                         jumpcnt = 0;
00538                         break;
00539 
00540                     case 'a':   //audio
00541                         rx_bytes = Recv ( rx_head->fPacketSize, 0 );
00542                         // SL: 25/01/09
00543                         // if ( !IsNextPacket() )
00544                         //    jack_error ( "Packet(s) missing from '%s'...", fParams.fName );
00545                         if (recvd_audio_pckt++ != rx_head->fSubCycle) {
00546                             jack_error("Packet(s) missing from '%s'...", fParams.fSlaveNetName);
00547                         }
00548                         fRxHeader.fCycle = rx_head->fCycle;
00549                         fRxHeader.fSubCycle = rx_head->fSubCycle;
00550                         fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
00551                         fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fSubCycle );
00552                         jumpcnt = 0;
00553                         break;
00554 
00555                     case 's':   //sync
00556                         /* SL: 25/01/09
00557                         if ( rx_head->fCycle == fTxHeader.fCycle )
00558                             return 0;
00559                         */
00560                         jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName);
00561                         return 0;
00562                 }
00563             }
00564         }
00565         return rx_bytes;
00566     }
00567     
00568     void JackNetMasterInterface::EncodeSyncPacket()
00569     {
00570         //this method contains every step of sync packet informations coding
00571         //first of all, reset sync packet
00572         memset ( fTxData, 0, fPayloadSize );
00573 
00574         //then, first step : transport
00575         if (fParams.fTransportSync) {
00576             EncodeTransportData();
00577             TransportDataHToN( &fSendTransportData,  &fSendTransportData);
00578             //copy to TxBuffer
00579             memcpy ( fTxData, &fSendTransportData, sizeof ( net_transport_data_t ) );
00580         }
00581         //then others (freewheel etc.)
00582         //...
00583     }
00584 
00585     void JackNetMasterInterface::DecodeSyncPacket()
00586     {
00587         //this method contains every step of sync packet informations decoding process
00588         //first : transport
00589         if (fParams.fTransportSync) {
00590             //copy received transport data to transport data structure
00591             memcpy ( &fReturnTransportData, fRxData, sizeof ( net_transport_data_t ) );
00592             TransportDataNToH( &fReturnTransportData,  &fReturnTransportData);
00593             DecodeTransportData();
00594         }
00595         //then others
00596         //...
00597     }
00598 
00599 // JackNetSlaveInterface ************************************************************************************************
00600 
00601     uint JackNetSlaveInterface::fSlaveCounter = 0;
00602 
00603     bool JackNetSlaveInterface::Init()
00604     {
00605         jack_log ( "JackNetSlaveInterface::Init()" );
00606 
00607         //set the parameters to send
00608         strcpy ( fParams.fPacketType, "params" );
00609         fParams.fProtocolVersion = SLAVE_PROTOCOL;
00610         SetPacketType ( &fParams, SLAVE_AVAILABLE );
00611 
00612         //init loop : get a master and start, do it until connection is ok
00613         net_status_t status;
00614         do
00615         {
00616             //first, get a master, do it until a valid connection is running
00617             do
00618             {
00619                 status = SendAvailableToMaster();
00620                 if ( status == NET_SOCKET_ERROR )
00621                     return false;
00622             }
00623             while ( status != NET_CONNECTED );
00624 
00625             //then tell the master we are ready
00626             jack_info ( "Initializing connection with %s...", fParams.fMasterNetName );
00627             status = SendStartToMaster();
00628             if ( status == NET_ERROR )
00629                 return false;
00630         }
00631         while ( status != NET_ROLLING );
00632 
00633         return true;
00634     }
00635     
00636     // Separate the connection protocol into two separated step
00637     
00638     bool JackNetSlaveInterface::InitConnection()
00639     {
00640         jack_log ( "JackNetSlaveInterface::InitConnection()" );
00641 
00642         //set the parameters to send
00643         strcpy (fParams.fPacketType, "params");
00644         fParams.fProtocolVersion = SLAVE_PROTOCOL;
00645         SetPacketType (&fParams, SLAVE_AVAILABLE);
00646 
00647         net_status_t status;
00648         do
00649         {
00650             //get a master
00651             status = SendAvailableToMaster();
00652             if (status == NET_SOCKET_ERROR)
00653                 return false;
00654         }
00655         while (status != NET_CONNECTED);
00656   
00657         return true;
00658     }
00659     
00660     bool JackNetSlaveInterface::InitRendering()
00661     {
00662         jack_log("JackNetSlaveInterface::InitRendering()");
00663 
00664         net_status_t status;
00665         do
00666         {
00667             //then tell the master we are ready
00668             jack_info("Initializing connection with %s...", fParams.fMasterNetName);
00669             status = SendStartToMaster();
00670             if (status == NET_ERROR)
00671                 return false;
00672         }
00673         while (status != NET_ROLLING);   
00674         
00675         return true;
00676     }
00677 
00678     net_status_t JackNetSlaveInterface::SendAvailableToMaster()
00679     {
00680         jack_log ( "JackNetSlaveInterface::SendAvailableToMaster()" );
00681         //utility
00682         session_params_t host_params;
00683         int rx_bytes = 0;
00684 
00685         //socket
00686         if ( fSocket.NewSocket() == SOCKET_ERROR ) {
00687             jack_error ( "Fatal error : network unreachable - %s", StrError ( NET_ERROR_CODE ) );
00688             return NET_SOCKET_ERROR;
00689         }
00690 
00691         //bind the socket
00692         if ( fSocket.Bind() == SOCKET_ERROR ) {
00693             jack_error ( "Can't bind the socket : %s", StrError ( NET_ERROR_CODE ) );
00694             return NET_SOCKET_ERROR;
00695         }
00696 
00697         //timeout on receive
00698         if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR ) 
00699             jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
00700 
00701         //disable local loop
00702         if ( fSocket.SetLocalLoop() == SOCKET_ERROR )
00703             jack_error ( "Can't disable multicast loop : %s", StrError ( NET_ERROR_CODE ) );
00704 
00705         //send 'AVAILABLE' until 'SLAVE_SETUP' received
00706         jack_info ( "Waiting for a master..." );
00707         do
00708         {
00709             //send 'available'
00710             session_params_t net_params;
00711             memset(&net_params, 0, sizeof ( session_params_t ));
00712             SessionParamsHToN(&fParams, &net_params);
00713             if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR )
00714                 jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) );
00715                 
00716             //filter incoming packets : don't exit while no error is detected
00717             memset(&net_params, 0, sizeof ( session_params_t ));
00718             rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 );
00719             SessionParamsNToH(&net_params, &host_params);
00720             if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
00721             {
00722                 jack_error ( "Can't receive : %s", StrError ( NET_ERROR_CODE ) );
00723                 return NET_RECV_ERROR;
00724             }
00725         }
00726         while ( strcmp ( host_params.fPacketType, fParams.fPacketType )  && ( GetPacketType ( &host_params ) != SLAVE_SETUP ) );
00727 
00728         //everything is OK, copy parameters
00729         fParams = host_params;
00730 
00731         //set the new buffer sizes
00732         if ( SetNetBufferSize() == SOCKET_ERROR ) {
00733             jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );
00734              return NET_SOCKET_ERROR;
00735         }
00736 
00737         //connect the socket
00738         if ( fSocket.Connect() == SOCKET_ERROR ) {
00739             jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) );
00740             return NET_CONNECT_ERROR;
00741         }
00742 
00743         return NET_CONNECTED;
00744     }
00745 
00746     net_status_t JackNetSlaveInterface::SendStartToMaster()
00747     {
00748         jack_log ( "JackNetSlaveInterface::SendStartToMaster" );
00749 
00750         //tell the master to start
00751         session_params_t net_params;
00752         memset(&net_params, 0, sizeof ( session_params_t ));
00753         SetPacketType ( &fParams, START_MASTER );
00754         SessionParamsHToN(&fParams, &net_params);
00755         if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR )
00756         {
00757             jack_error ( "Error in send : %s", StrError ( NET_ERROR_CODE ) );
00758             return ( fSocket.GetError() == NET_CONN_ERROR ) ? NET_ERROR : NET_SEND_ERROR;
00759         }
00760         return NET_ROLLING;
00761     }
00762 
00763     void JackNetSlaveInterface::SetParams()
00764     {
00765         jack_log ( "JackNetSlaveInterface::SetParams" );
00766 
00767         JackNetInterface::SetParams();
00768 
00769         fTxHeader.fDataStream = 'r';
00770         fRxHeader.fDataStream = 's';
00771 
00772         //midi net buffers
00773         fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fRxData );
00774         fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fTxData );
00775 
00776         //audio net buffers
00777         fNetAudioCaptureBuffer = new NetAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
00778         fNetAudioPlaybackBuffer = new NetAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
00779 
00780         //audio netbuffer length
00781         fAudioTxLen = sizeof ( packet_header_t ) + fNetAudioPlaybackBuffer->GetSize();
00782         fAudioRxLen = sizeof ( packet_header_t ) + fNetAudioCaptureBuffer->GetSize();
00783     }
00784 
00785     int JackNetSlaveInterface::Recv ( size_t size, int flags )
00786     {
00787         int rx_bytes = fSocket.Recv ( fRxBuffer, size, flags );
00788         //handle errors
00789         if ( rx_bytes == SOCKET_ERROR )
00790         {
00791             net_error_t error = fSocket.GetError();
00792             //no data isn't really an error in realtime processing, so just return 0
00793             if ( error == NET_NO_DATA )
00794                 jack_error ( "No data, is the master still running ?" );
00795             //if a network error occurs, this exception will restart the driver
00796             else if ( error == NET_CONN_ERROR )
00797             {
00798                 jack_error ( "Connection lost." );
00799                 throw JackNetException();
00800             }
00801             else
00802                 jack_error ( "Fatal error in slave receive : %s", StrError ( NET_ERROR_CODE ) );
00803         }
00804         
00805         packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
00806         PacketHeaderNToH(header, header);
00807         return rx_bytes;
00808     }
00809 
00810     int JackNetSlaveInterface::Send ( size_t size, int flags )
00811     {
00812         packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
00813         PacketHeaderHToN(header, header);
00814         int tx_bytes = fSocket.Send ( fTxBuffer, size, flags );
00815          
00816         //handle errors
00817         if ( tx_bytes == SOCKET_ERROR )
00818         {
00819             net_error_t error = fSocket.GetError();
00820             //if a network error occurs, this exception will restart the driver
00821             if ( error == NET_CONN_ERROR )
00822             {
00823                 jack_error ( "Connection lost." );
00824                 throw JackNetException();
00825             }
00826             else
00827                 jack_error ( "Fatal error in slave send : %s", StrError ( NET_ERROR_CODE ) );
00828         }
00829         return tx_bytes;
00830     }
00831 
00832     int JackNetSlaveInterface::SyncRecv()
00833     {
00834         int rx_bytes = 0;
00835         packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
00836         //receive sync (launch the cycle)
00837         do
00838         {
00839             rx_bytes = Recv ( fParams.fMtu, 0 );
00840             //connection issue, send will detect it, so don't skip the cycle (return 0)
00841             if ( rx_bytes == SOCKET_ERROR )
00842                 return rx_bytes;
00843         }
00844         while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's'));
00845         
00846         fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
00847         return rx_bytes;
00848     }
00849 
00850     int JackNetSlaveInterface::DataRecv()
00851     {
00852         uint recvd_midi_pckt = 0;
00853         uint recvd_audio_pckt = 0;
00854         int rx_bytes = 0;
00855         packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
00856 
00857         while ( !fRxHeader.fIsLastPckt )
00858         {
00859             rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
00860             //error here, problem with recv, just skip the cycle (return -1)
00861 
00862             if ( rx_bytes == SOCKET_ERROR )
00863                 return rx_bytes;
00864             if ( rx_bytes && ( rx_head->fDataStream == 's' ) && ( rx_head->fID == fParams.fID ) )
00865             {
00866                 switch ( rx_head->fDataType )
00867                 {
00868                     case 'm':   //midi
00869                         rx_bytes = Recv ( rx_head->fPacketSize, 0 );
00870                         fRxHeader.fCycle = rx_head->fCycle;
00871                         fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
00872                         fNetMidiCaptureBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) );
00873                         if ( ++recvd_midi_pckt == rx_head->fNMidiPckt )
00874                             fNetMidiCaptureBuffer->RenderToJackPorts();
00875                         break;
00876 
00877                     case 'a':   //audio
00878                         rx_bytes = Recv ( rx_head->fPacketSize, 0 );
00879                         //SL: 25/01/09
00880                         // if ( !IsNextPacket() )
00881                         //    jack_error ( "Packet(s) missing..." );
00882                         if (recvd_audio_pckt++ != rx_head->fSubCycle) {
00883                             jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName);
00884                         }
00885                         fRxHeader.fCycle = rx_head->fCycle;
00886                         fRxHeader.fSubCycle = rx_head->fSubCycle;
00887                         fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
00888                         fNetAudioCaptureBuffer->RenderToJackPorts ( rx_head->fSubCycle );
00889                         break;
00890 
00891                     case 's':   //sync
00892                         jack_info ( "NetSlave : overloaded, skipping receive." );
00893                         return 0;
00894                 }
00895             }
00896         }
00897         fRxHeader.fCycle = rx_head->fCycle;
00898         return 0;
00899     }
00900 
00901     int JackNetSlaveInterface::SyncSend()
00902     {
00903         //tx header
00904         if ( fParams.fSlaveSyncMode )
00905             fTxHeader.fCycle = fRxHeader.fCycle;
00906         else
00907             fTxHeader.fCycle++;
00908         fTxHeader.fSubCycle = 0;
00909         fTxHeader.fDataType = 's';
00910         fTxHeader.fIsLastPckt = ( fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ?  1 : 0;
00911         fTxHeader.fPacketSize = fParams.fMtu;
00912         memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
00913         return Send ( fTxHeader.fPacketSize, 0 );
00914     }
00915 
00916     int JackNetSlaveInterface::DataSend()
00917     {
00918         uint subproc;
00919 
00920         //midi
00921         if ( fParams.fReturnMidiChannels > 0)
00922         {
00923             fTxHeader.fDataType = 'm';
00924             fTxHeader.fMidiDataSize = fNetMidiPlaybackBuffer->RenderFromJackPorts();
00925             fTxHeader.fNMidiPckt = GetNMidiPckt();
00926             for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ )
00927             {
00928                 fTxHeader.fSubCycle = subproc;
00929                 fTxHeader.fIsLastPckt = ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && !fParams.fReturnAudioChannels ) ? 1 : 0;
00930                 fTxHeader.fPacketSize = sizeof ( packet_header_t ) + fNetMidiPlaybackBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize );
00931                 memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
00932                 if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR )
00933                     return SOCKET_ERROR;
00934             }
00935         }
00936 
00937         //audio
00938         if ( fParams.fReturnAudioChannels > 0)
00939         {
00940             fTxHeader.fDataType = 'a';
00941             fTxHeader.fMidiDataSize = 0;
00942             fTxHeader.fNMidiPckt = 0;
00943             for ( subproc = 0; subproc < fNSubProcess; subproc++ )
00944             {
00945                 fTxHeader.fSubCycle = subproc;
00946                 fTxHeader.fIsLastPckt = ( subproc == ( fNSubProcess - 1 ) ) ? 1 : 0;
00947                 fTxHeader.fPacketSize = fAudioTxLen;
00948                 memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
00949                 fNetAudioPlaybackBuffer->RenderFromJackPorts ( subproc );
00950                 if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR )
00951                     return SOCKET_ERROR;
00952             }
00953         }
00954         return 0;
00955     }
00956     
00957     //network sync------------------------------------------------------------------------
00958     void JackNetSlaveInterface::EncodeSyncPacket()
00959     {
00960         //this method contains every step of sync packet informations coding
00961         //first of all, reset sync packet
00962         memset ( fTxData, 0, fPayloadSize );
00963         //then first step : transport
00964         if (fParams.fTransportSync) {
00965             EncodeTransportData();
00966             TransportDataHToN( &fReturnTransportData,  &fReturnTransportData);
00967             //copy to TxBuffer
00968             memcpy ( fTxData, &fReturnTransportData, sizeof ( net_transport_data_t ) );
00969         }
00970         //then others
00971         //...
00972     }
00973     
00974     void JackNetSlaveInterface::DecodeSyncPacket()
00975     {
00976         //this method contains every step of sync packet informations decoding process
00977         //first : transport
00978         if (fParams.fTransportSync) {
00979             //copy received transport data to transport data structure
00980             memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) );
00981             TransportDataNToH( &fSendTransportData,  &fSendTransportData);
00982             DecodeTransportData();
00983         }
00984         //then others
00985         //...
00986     }
00987 
00988 }