Jack2 1.9.10

JackNetInterface.cpp

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 #include "JackNetInterface.h"
00020 #include "JackException.h"
00021 #include "JackError.h"
00022 
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         Initialize();
00040     }
00041 
00042     JackNetInterface::JackNetInterface(const char* multicast_ip, int port) : fSocket(multicast_ip, port)
00043     {
00044         strcpy(fMulticastIP, multicast_ip);
00045         Initialize();
00046     }
00047 
00048     JackNetInterface::JackNetInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip) : fSocket(socket)
00049     {
00050         fParams = params;
00051         strcpy(fMulticastIP, multicast_ip);
00052         Initialize();
00053     }
00054 
00055     void JackNetInterface::Initialize()
00056     {
00057         fSetTimeOut = false;
00058         fTxBuffer = NULL;
00059         fRxBuffer = NULL;
00060         fNetAudioCaptureBuffer = NULL;
00061         fNetAudioPlaybackBuffer = NULL;
00062         fNetMidiCaptureBuffer = NULL;
00063         fNetMidiPlaybackBuffer = NULL;
00064         memset(&fSendTransportData, 0, sizeof(net_transport_data_t));
00065         memset(&fReturnTransportData, 0, sizeof(net_transport_data_t));
00066         fPacketTimeOut = PACKET_TIMEOUT * NETWORK_DEFAULT_LATENCY;
00067     }
00068 
00069     void JackNetInterface::FreeNetworkBuffers()
00070     {
00071         delete fNetMidiCaptureBuffer;
00072         delete fNetMidiPlaybackBuffer;
00073         delete fNetAudioCaptureBuffer;
00074         delete fNetAudioPlaybackBuffer;
00075         fNetMidiCaptureBuffer = NULL;
00076         fNetMidiPlaybackBuffer = NULL;
00077         fNetAudioCaptureBuffer = NULL;
00078         fNetAudioPlaybackBuffer = NULL;
00079     }
00080 
00081     JackNetInterface::~JackNetInterface()
00082     {
00083         jack_log("JackNetInterface::~JackNetInterface");
00084 
00085         fSocket.Close();
00086         delete[] fTxBuffer;
00087         delete[] fRxBuffer;
00088         delete fNetAudioCaptureBuffer;
00089         delete fNetAudioPlaybackBuffer;
00090         delete fNetMidiCaptureBuffer;
00091         delete fNetMidiPlaybackBuffer;
00092     }
00093 
00094     int JackNetInterface::SetNetBufferSize()
00095     {
00096         // audio
00097         float audio_size = (fNetAudioCaptureBuffer)
00098                         ? fNetAudioCaptureBuffer->GetCycleSize()
00099                         : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0;
00100         jack_log("audio_size %f", audio_size);
00101 
00102         // midi
00103         float midi_size = (fNetMidiCaptureBuffer)
00104                         ? fNetMidiCaptureBuffer->GetCycleSize()
00105                         : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0;
00106         jack_log("midi_size %f", midi_size);
00107 
00108         // bufsize = sync + audio + midi
00109         int bufsize = NETWORK_MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int)midi_size);
00110         jack_log("SetNetBufferSize bufsize = %d", bufsize);
00111 
00112         // tx buffer
00113         if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) {
00114             return SOCKET_ERROR;
00115         }
00116 
00117         // rx buffer
00118         if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) {
00119             return SOCKET_ERROR;
00120         }
00121 
00122         return 0;
00123     }
00124 
00125     bool JackNetInterface::SetParams()
00126     {
00127         // TX header init
00128         strcpy(fTxHeader.fPacketType, "header");
00129         fTxHeader.fID = fParams.fID;
00130         fTxHeader.fCycle = 0;
00131         fTxHeader.fSubCycle = 0;
00132         fTxHeader.fIsLastPckt = 0;
00133 
00134         // RX header init
00135         strcpy(fRxHeader.fPacketType, "header");
00136         fRxHeader.fID = fParams.fID;
00137         fRxHeader.fCycle = 0;
00138         fRxHeader.fSubCycle = 0;
00139         fRxHeader.fIsLastPckt = 0;
00140 
00141         // network buffers
00142         fTxBuffer = new char[fParams.fMtu];
00143         fRxBuffer = new char[fParams.fMtu];
00144         assert(fTxBuffer);
00145         assert(fRxBuffer);
00146 
00147         // net audio/midi buffers'addresses
00148         fTxData = fTxBuffer + HEADER_SIZE;
00149         fRxData = fRxBuffer + HEADER_SIZE;
00150 
00151         return true;
00152     }
00153 
00154     int JackNetInterface::MidiSend(NetMidiBuffer* buffer, int midi_channnels, int audio_channels)
00155     {
00156         if (midi_channnels > 0) {
00157             // set global header fields and get the number of midi packets
00158             fTxHeader.fDataType = 'm';
00159             uint data_size = buffer->RenderFromJackPorts();
00160             fTxHeader.fNumPacket = buffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE(&fParams));
00161 
00162             for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
00163                 fTxHeader.fSubCycle = subproc;
00164                 fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && audio_channels == 0) ? 1 : 0;
00165                 fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, data_size);
00166                 memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
00167                 if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) {
00168                     return SOCKET_ERROR;
00169                 }
00170             }
00171         }
00172         return 0;
00173     }
00174 
00175     int JackNetInterface::AudioSend(NetAudioBuffer* buffer, int audio_channels)
00176     {
00177         // audio
00178         if (audio_channels > 0) {
00179             fTxHeader.fDataType = 'a';
00180             fTxHeader.fActivePorts = buffer->RenderFromJackPorts(fTxHeader.fFrames);
00181             fTxHeader.fNumPacket = buffer->GetNumPackets(fTxHeader.fActivePorts);
00182 
00183             for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
00184                 fTxHeader.fSubCycle = subproc;
00185                 fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
00186                 fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, fTxHeader.fActivePorts);
00187                 memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
00188                 //PacketHeaderDisplay(&fTxHeader);
00189                 if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) {
00190                     return SOCKET_ERROR;
00191                 }
00192             }
00193         }
00194         return 0;
00195     }
00196 
00197     int JackNetInterface::MidiRecv(packet_header_t* rx_head, NetMidiBuffer* buffer, uint& recvd_midi_pckt)
00198     {
00199         int rx_bytes = Recv(rx_head->fPacketSize, 0);
00200         fRxHeader.fCycle = rx_head->fCycle;
00201         fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
00202         buffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
00203         
00204         // Last midi packet is received, so finish rendering...
00205         if (++recvd_midi_pckt == rx_head->fNumPacket) {
00206             buffer->RenderToJackPorts();
00207         }
00208         return rx_bytes;
00209     }
00210 
00211     int JackNetInterface::AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer)
00212     {
00213         int rx_bytes = Recv(rx_head->fPacketSize, 0);
00214         fRxHeader.fCycle = rx_head->fCycle;
00215         fRxHeader.fSubCycle = rx_head->fSubCycle;
00216         fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
00217         fRxHeader.fActivePorts = rx_head->fActivePorts;
00218         fRxHeader.fFrames = rx_head->fFrames;
00219         rx_bytes = buffer->RenderFromNetwork(rx_head->fCycle, rx_head->fSubCycle, fRxHeader.fActivePorts);
00220         
00221         // Last audio packet is received, so finish rendering...
00222         if (fRxHeader.fIsLastPckt) {
00223             buffer->RenderToJackPorts(fRxHeader.fFrames);
00224         }
00225         return rx_bytes;
00226     }
00227 
00228     int JackNetInterface::FinishRecv(NetAudioBuffer* buffer)
00229     {
00230         if (buffer) {
00231             buffer->RenderToJackPorts(fRxHeader.fFrames);
00232         } else {
00233             jack_error("FinishRecv with null buffer...");
00234         }
00235         return DATA_PACKET_ERROR;
00236     }
00237 
00238     NetAudioBuffer* JackNetInterface::AudioBufferFactory(int nports, char* buffer)
00239     {
00240          switch (fParams.fSampleEncoder) {
00241 
00242             case JackFloatEncoder:
00243                 return new NetFloatAudioBuffer(&fParams, nports, buffer);
00244 
00245             case JackIntEncoder:
00246                 return new NetIntAudioBuffer(&fParams, nports, buffer);
00247 
00248             #if HAVE_CELT
00249             case JackCeltEncoder:
00250                 return new NetCeltAudioBuffer(&fParams, nports, buffer, fParams.fKBps);
00251             #endif
00252             #if HAVE_OPUS
00253             case JackOpusEncoder:
00254                 return new NetOpusAudioBuffer(&fParams, nports, buffer, fParams.fKBps);
00255             #endif
00256         }
00257         
00258         throw std::bad_alloc();
00259     }
00260     
00261     void JackNetInterface::SetRcvTimeOut()
00262     {
00263         if (!fSetTimeOut) {
00264             if (fSocket.SetTimeOut(fPacketTimeOut) == SOCKET_ERROR) {
00265                 jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE));
00266                 return;
00267             }
00268             fSetTimeOut = true;
00269         }
00270     }
00271 
00272     // JackNetMasterInterface ************************************************************************************
00273 
00274     bool JackNetMasterInterface::Init()
00275     {
00276         jack_log("JackNetMasterInterface::Init : ID %u", fParams.fID);
00277 
00278         session_params_t host_params;
00279         uint attempt = 0;
00280         int rx_bytes = 0;
00281 
00282         // socket
00283         if (fSocket.NewSocket() == SOCKET_ERROR) {
00284             jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE));
00285             return false;
00286         }
00287 
00288         // timeout on receive (for init)
00289         if (fSocket.SetTimeOut(MASTER_INIT_TIMEOUT) < 0) {
00290             jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE));
00291         }
00292 
00293         // connect
00294         if (fSocket.Connect() == SOCKET_ERROR) {
00295             jack_error("Can't connect : %s", StrError(NET_ERROR_CODE));
00296             return false;
00297         }
00298 
00299         // send 'SLAVE_SETUP' until 'START_MASTER' received
00300         jack_info("Sending parameters to %s...", fParams.fSlaveNetName);
00301         do
00302         {
00303             session_params_t net_params;
00304             memset(&net_params, 0, sizeof(session_params_t));
00305             SetPacketType(&fParams, SLAVE_SETUP);
00306             SessionParamsHToN(&fParams, &net_params);
00307 
00308             if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) {
00309                 jack_error("Error in send : %s", StrError(NET_ERROR_CODE));
00310             }
00311 
00312             memset(&net_params, 0, sizeof(session_params_t));
00313             if (((rx_bytes = fSocket.Recv(&net_params, sizeof(session_params_t), 0)) == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
00314                 jack_error("Problem with network");
00315                 return false;
00316             }
00317 
00318             SessionParamsNToH(&net_params, &host_params);
00319         }
00320         while ((GetPacketType(&host_params) != START_MASTER) && (++attempt < SLAVE_SETUP_RETRY));
00321         
00322         if (attempt == SLAVE_SETUP_RETRY) {
00323             jack_error("Slave doesn't respond, exiting");
00324             return false;
00325         }
00326 
00327         return true;
00328     }
00329 
00330     bool JackNetMasterInterface::SetParams()
00331     {
00332         jack_log("JackNetMasterInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
00333             fParams.fSendAudioChannels, fParams.fReturnAudioChannels,
00334             fParams.fSendMidiChannels, fParams.fReturnMidiChannels);
00335 
00336         JackNetInterface::SetParams();
00337 
00338         fTxHeader.fDataStream = 's';
00339         fRxHeader.fDataStream = 'r';
00340 
00341         fMaxCycleOffset = fParams.fNetworkLatency;
00342 
00343         // midi net buffers
00344         if (fParams.fSendMidiChannels > 0) {
00345             fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fTxData);
00346         }
00347 
00348         if (fParams.fReturnMidiChannels > 0) {
00349             fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fRxData);
00350         }
00351 
00352         try {
00353 
00354             // audio net buffers
00355             if (fParams.fSendAudioChannels > 0) {
00356                 fNetAudioCaptureBuffer = AudioBufferFactory(fParams.fSendAudioChannels, fTxData);
00357                 assert(fNetAudioCaptureBuffer);
00358             }
00359 
00360             if (fParams.fReturnAudioChannels > 0) {
00361                 fNetAudioPlaybackBuffer = AudioBufferFactory(fParams.fReturnAudioChannels, fRxData);
00362                 assert(fNetAudioPlaybackBuffer);
00363             }
00364 
00365         } catch (exception&) {
00366             jack_error("NetAudioBuffer on master allocation error...");
00367             return false;
00368         }
00369 
00370         // set the new buffer size
00371         if (SetNetBufferSize() == SOCKET_ERROR) {
00372             jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
00373             goto error;
00374         }
00375 
00376         return true;
00377 
00378     error:
00379         FreeNetworkBuffers();
00380         return false;
00381     }
00382 
00383     void JackNetMasterInterface::Exit()
00384     {
00385         jack_log("JackNetMasterInterface::Exit, ID %u", fParams.fID);
00386 
00387         // stop process
00388         fRunning = false;
00389 
00390         // send a 'multicast euthanasia request' - new socket is required on macosx
00391         jack_info("Exiting '%s' %s", fParams.fName, fMulticastIP);
00392         SetPacketType(&fParams, KILL_MASTER);
00393         JackNetSocket mcast_socket(fMulticastIP, fSocket.GetPort());
00394 
00395         session_params_t net_params;
00396         memset(&net_params, 0, sizeof(session_params_t));
00397         SessionParamsHToN(&fParams, &net_params);
00398 
00399         if (mcast_socket.NewSocket() == SOCKET_ERROR) {
00400             jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE));
00401         }
00402         if (mcast_socket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR) {
00403             jack_error("Can't send suicide request : %s", StrError(NET_ERROR_CODE));
00404         }
00405 
00406         mcast_socket.Close();
00407     }
00408 
00409     void JackNetMasterInterface::FatalRecvError()
00410     {
00411         // fatal connection issue, exit
00412         jack_error("Recv connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE), fParams.fName);
00413         // ask to the manager to properly remove the master
00414         Exit();
00415         // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
00416         ThreadExit();
00417     }
00418 
00419      void JackNetMasterInterface::FatalSendError()
00420     {
00421         // fatal connection issue, exit
00422         jack_error("Send connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE), fParams.fName);
00423         // ask to the manager to properly remove the master
00424         Exit();
00425         // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
00426         ThreadExit();
00427     }
00428 
00429     int JackNetMasterInterface::Recv(size_t size, int flags)
00430     {
00431         int rx_bytes;
00432 
00433         if (((rx_bytes = fSocket.Recv(fRxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
00434             FatalRecvError();
00435         }
00436   
00437         packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
00438         PacketHeaderNToH(header, header);
00439         return rx_bytes;
00440     }
00441 
00442     int JackNetMasterInterface::Send(size_t size, int flags)
00443     {
00444         int tx_bytes;
00445         packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
00446         PacketHeaderHToN(header, header);
00447 
00448         if (((tx_bytes = fSocket.Send(fTxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
00449             FatalSendError();
00450         }
00451         return tx_bytes;
00452     }
00453 
00454     int JackNetMasterInterface::SyncSend()
00455     {
00456         SetRcvTimeOut();
00457         
00458         fTxHeader.fCycle++;
00459         fTxHeader.fSubCycle = 0;
00460         fTxHeader.fDataType = 's';
00461         fTxHeader.fIsLastPckt = (fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0;
00462         fTxHeader.fPacketSize = fParams.fMtu;
00463 
00464         memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
00465         //PacketHeaderDisplay(&fTxHeader);
00466         return Send(fTxHeader.fPacketSize, 0);
00467     }
00468 
00469     int JackNetMasterInterface::DataSend()
00470     {
00471         if (MidiSend(fNetMidiCaptureBuffer, fParams.fSendMidiChannels, fParams.fSendAudioChannels) == SOCKET_ERROR) {
00472             return SOCKET_ERROR;
00473         }
00474         return AudioSend(fNetAudioCaptureBuffer, fParams.fSendAudioChannels);
00475     }
00476 
00477     int JackNetMasterInterface::SyncRecv()
00478     {
00479         int rx_bytes = 0;
00480         packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
00481 
00482         // receive sync (launch the cycle)
00483         do {
00484             rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
00485             // connection issue (return -1)
00486             if (rx_bytes == SOCKET_ERROR) {
00487                 return SOCKET_ERROR;
00488             }
00489         }
00490         while (strcmp(rx_head->fPacketType, "header") != 0);
00491         
00492         if (rx_head->fDataType != 's') {
00493             jack_error("Wrong packet type : %c", rx_head->fDataType);
00494             // not the last packet..
00495             fRxHeader.fIsLastPckt = 0;
00496             return SYNC_PACKET_ERROR;
00497         }
00498     
00499         fCurrentCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
00500 
00501         if (fCurrentCycleOffset < fMaxCycleOffset && !fSynched) {
00502             jack_info("Synching with latency = %d", fCurrentCycleOffset);
00503             return NET_SYNCHING;
00504         } else {
00505             if (fCurrentCycleOffset == fMaxCycleOffset) {
00506                 // when the sync offset is reached 
00507                 fSynched = true;
00508             }
00509             rx_bytes = Recv(rx_head->fPacketSize, 0);
00510             fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
00511             return rx_bytes;
00512         }
00513     }
00514 
00515     int JackNetMasterInterface::DataRecv()
00516     {
00517         int rx_bytes = 0;
00518         uint recvd_midi_pckt = 0;
00519         packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
00520      
00521         while (!fRxHeader.fIsLastPckt) {
00522             // how much data is queued on the rx buffer ?
00523             rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
00524          
00525             // error here, problem with recv, just skip the cycle (return -1)
00526             if (rx_bytes == SOCKET_ERROR) {
00527                 return rx_bytes;
00528             }
00529 
00530             if (rx_bytes && (rx_head->fDataStream == 'r') && (rx_head->fID == fParams.fID)) {
00531                 // read data
00532                 switch (rx_head->fDataType) {
00533 
00534                     case 'm':   // midi
00535                         rx_bytes = MidiRecv(rx_head, fNetMidiPlaybackBuffer, recvd_midi_pckt);
00536                         break;
00537 
00538                     case 'a':   // audio
00539                         rx_bytes = AudioRecv(rx_head, fNetAudioPlaybackBuffer);
00540                         break;
00541 
00542                     case 's':   // sync
00543                         jack_info("NetMaster : missing last data packet from '%s'", fParams.fName);
00544                         return FinishRecv(fNetAudioPlaybackBuffer);
00545                 }
00546             }
00547         }
00548    
00549         return rx_bytes;
00550     }
00551 
00552     void JackNetMasterInterface::EncodeSyncPacket(int frames)
00553     {
00554         // This method contains every step of sync packet informations coding
00555         // first of all, clear sync packet
00556         memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams));
00557     
00558         // Transport not used for now...
00559         /*
00560         // then, first step : transport
00561         if (fParams.fTransportSync) {
00562             EncodeTransportData();
00563             TransportDataHToN(&fSendTransportData, &fSendTransportData);
00564             // copy to TxBuffer
00565             memcpy(fTxData, &fSendTransportData, sizeof(net_transport_data_t));
00566         }
00567         // then others (freewheel etc.)
00568         // ...
00569         */
00570    
00571         // Write active ports list
00572         fTxHeader.fActivePorts = (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->ActivePortsToNetwork(fTxData) : 0;
00573         fTxHeader.fFrames = frames;
00574     }
00575 
00576     void JackNetMasterInterface::DecodeSyncPacket(int& frames)
00577     {
00578         // This method contains every step of sync packet informations decoding process
00579         
00580         // Transport not used for now...
00581         /*
00582         // first : transport
00583         if (fParams.fTransportSync) {
00584             // copy received transport data to transport data structure
00585             memcpy(&fReturnTransportData, fRxData, sizeof(net_transport_data_t));
00586             TransportDataNToH(&fReturnTransportData,  &fReturnTransportData);
00587             DecodeTransportData();
00588         }
00589         // then others
00590         // ...
00591         */
00592        
00593         packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
00594 
00595         // Read active ports list
00596         if (fNetAudioCaptureBuffer) {
00597             fNetAudioCaptureBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
00598         }
00599         frames = rx_head->fFrames;
00600     }
00601 
00602 // JackNetSlaveInterface ************************************************************************************************
00603 
00604     uint JackNetSlaveInterface::fSlaveCounter = 0;
00605 
00606     void JackNetSlaveInterface::InitAPI()
00607     {
00608         // open Socket API with the first slave
00609         if (fSlaveCounter++ == 0) {
00610             if (SocketAPIInit() < 0) {
00611                 jack_error("Can't init Socket API, exiting...");
00612                 throw std::bad_alloc();
00613             }
00614         }
00615     }
00616 
00617     bool JackNetSlaveInterface::Init()
00618     {
00619         jack_log("JackNetSlaveInterface::Init()");
00620 
00621         // set the parameters to send
00622         strcpy(fParams.fPacketType, "params");
00623         fParams.fProtocolVersion = NETWORK_PROTOCOL;
00624         SetPacketType(&fParams, SLAVE_AVAILABLE);
00625 
00626         // init loop : get a master and start, do it until connection is ok
00627         net_status_t status;
00628         do {
00629             // first, get a master, do it until a valid connection is running
00630             do {
00631                 status = SendAvailableToMaster();
00632                 if (status == NET_SOCKET_ERROR) {
00633                     return false;
00634                 }
00635             }
00636             while (status != NET_CONNECTED);
00637 
00638             // then tell the master we are ready
00639             jack_info("Initializing connection with %s...", fParams.fMasterNetName);
00640             status = SendStartToMaster();
00641             if (status == NET_ERROR) {
00642                 return false;
00643             }
00644         }
00645         while (status != NET_ROLLING);
00646 
00647         return true;
00648     }
00649 
00650     // Separate the connection protocol into two separated step
00651     bool JackNetSlaveInterface::InitConnection(int time_out_sec)
00652     {
00653         jack_log("JackNetSlaveInterface::InitConnection time_out_sec = %d", time_out_sec);
00654         int try_count = (time_out_sec > 0) ? int((1000000.f * float(time_out_sec)) / float(SLAVE_INIT_TIMEOUT)) : INT_MAX;
00655   
00656         // set the parameters to send
00657         strcpy(fParams.fPacketType, "params");
00658         fParams.fProtocolVersion = NETWORK_PROTOCOL;
00659         SetPacketType(&fParams, SLAVE_AVAILABLE);
00660 
00661         return (SendAvailableToMaster(try_count) == NET_CONNECTED);
00662     }
00663 
00664     bool JackNetSlaveInterface::InitRendering()
00665     {
00666         jack_log("JackNetSlaveInterface::InitRendering()");
00667 
00668         net_status_t status;
00669         do {
00670             // then tell the master we are ready
00671             jack_info("Initializing connection with %s...", fParams.fMasterNetName);
00672             status = SendStartToMaster();
00673             if (status == NET_ERROR) {
00674                 return false;
00675             }
00676         }
00677         while (status != NET_ROLLING);
00678 
00679         return true;
00680     }
00681 
00682     net_status_t JackNetSlaveInterface::SendAvailableToMaster(int try_count)
00683     {
00684         jack_log("JackNetSlaveInterface::SendAvailableToMaster try_count = %d", try_count);
00685         // utility
00686         session_params_t host_params;
00687         int rx_bytes = 0;
00688 
00689         // socket
00690         if (fSocket.NewSocket() == SOCKET_ERROR) {
00691             jack_error("Fatal error : network unreachable - %s", StrError(NET_ERROR_CODE));
00692             return NET_SOCKET_ERROR;
00693         }
00694 
00695         if (fSocket.IsLocal(fMulticastIP)) {
00696             jack_info("Local IP is used...");
00697         } else {
00698             // bind the socket
00699             if (fSocket.Bind() == SOCKET_ERROR) {
00700                 jack_error("Can't bind the socket : %s", StrError(NET_ERROR_CODE));
00701                 return NET_SOCKET_ERROR;
00702             }
00703         }
00704 
00705         // timeout on receive (for init)
00706         if (fSocket.SetTimeOut(SLAVE_INIT_TIMEOUT) == SOCKET_ERROR) {
00707             jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE));
00708         }
00709 
00710         // disable local loop
00711         if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
00712             jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE));
00713         }
00714 
00715         // send 'AVAILABLE' until 'SLAVE_SETUP' received
00716         jack_info("Waiting for a master...");
00717         
00718         do {
00719             // send 'available'
00720             session_params_t net_params;
00721             memset(&net_params, 0, sizeof(session_params_t));
00722             SessionParamsHToN(&fParams, &net_params);
00723             if (fSocket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR) {
00724                 jack_error("Error in data send : %s", StrError(NET_ERROR_CODE));
00725             }
00726 
00727             // filter incoming packets : don't exit while no error is detected
00728             memset(&net_params, 0, sizeof(session_params_t));
00729             rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0);
00730             SessionParamsNToH(&net_params, &host_params);
00731             if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
00732                 jack_error("Can't receive : %s", StrError(NET_ERROR_CODE));
00733                 return NET_RECV_ERROR;
00734             }
00735         }
00736         while (strcmp(host_params.fPacketType, fParams.fPacketType) && (GetPacketType(&host_params) != SLAVE_SETUP)  && (--try_count > 0));
00737     
00738         // time out failure..
00739         if (try_count == 0) {
00740             jack_error("Time out error in connect");
00741             return NET_CONNECT_ERROR;
00742         }
00743 
00744         // everything is OK, copy parameters
00745         fParams = host_params;
00746      
00747         // connect the socket
00748         if (fSocket.Connect() == SOCKET_ERROR) {
00749             jack_error("Error in connect : %s", StrError(NET_ERROR_CODE));
00750             return NET_CONNECT_ERROR;
00751         }
00752         
00753         return NET_CONNECTED;
00754     }
00755 
00756     net_status_t JackNetSlaveInterface::SendStartToMaster()
00757     {
00758         jack_log("JackNetSlaveInterface::SendStartToMaster");
00759 
00760         // tell the master to start
00761         session_params_t net_params;
00762         memset(&net_params, 0, sizeof(session_params_t));
00763         SetPacketType(&fParams, START_MASTER);
00764         SessionParamsHToN(&fParams, &net_params);
00765         if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) {
00766             jack_error("Error in send : %s", StrError(NET_ERROR_CODE));
00767             return (fSocket.GetError() == NET_CONN_ERROR) ? NET_ERROR : NET_SEND_ERROR;
00768         }
00769         return NET_ROLLING;
00770     }
00771 
00772     bool JackNetSlaveInterface::SetParams()
00773     {
00774         jack_log("JackNetSlaveInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
00775                 fParams.fSendAudioChannels, fParams.fReturnAudioChannels,
00776                 fParams.fSendMidiChannels, fParams.fReturnMidiChannels);
00777 
00778         JackNetInterface::SetParams();
00779 
00780         fTxHeader.fDataStream = 'r';
00781         fRxHeader.fDataStream = 's';
00782 
00783         // midi net buffers
00784         if (fParams.fSendMidiChannels > 0) {
00785             fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fRxData);
00786         }
00787 
00788         if (fParams.fReturnMidiChannels > 0) {
00789             fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fTxData);
00790         }
00791 
00792         try {
00793 
00794             // audio net buffers
00795             if (fParams.fSendAudioChannels > 0) {
00796                 fNetAudioCaptureBuffer = AudioBufferFactory(fParams.fSendAudioChannels, fRxData);
00797                 assert(fNetAudioCaptureBuffer);
00798             }
00799 
00800             if (fParams.fReturnAudioChannels > 0) {
00801                 fNetAudioPlaybackBuffer = AudioBufferFactory(fParams.fReturnAudioChannels, fTxData);
00802                 assert(fNetAudioPlaybackBuffer);
00803             }
00804 
00805         } catch (exception&) {
00806             jack_error("NetAudioBuffer on slave allocation error...");
00807             return false;
00808         }
00809 
00810         // set the new buffer sizes
00811         if (SetNetBufferSize() == SOCKET_ERROR) {
00812             jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
00813             goto error;
00814         }
00815 
00816         return true;
00817 
00818     error:
00819         FreeNetworkBuffers();
00820         return false;
00821     }
00822 
00823     void JackNetSlaveInterface::FatalRecvError()
00824     {
00825         throw JackNetException("Recv connection lost error");
00826     }
00827 
00828     void JackNetSlaveInterface::FatalSendError()
00829     {
00830         throw JackNetException("Send connection lost error");
00831     }
00832 
00833     int JackNetSlaveInterface::Recv(size_t size, int flags)
00834     {
00835         int rx_bytes = fSocket.Recv(fRxBuffer, size, flags);
00836         
00837         // handle errors
00838         if (rx_bytes == SOCKET_ERROR) {
00839             FatalRecvError();
00840         }
00841 
00842         packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
00843         PacketHeaderNToH(header, header);
00844         return rx_bytes;
00845     }
00846 
00847     int JackNetSlaveInterface::Send(size_t size, int flags)
00848     {
00849         packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
00850         PacketHeaderHToN(header, header);
00851         int tx_bytes = fSocket.Send(fTxBuffer, size, flags);
00852 
00853         // handle errors
00854         if (tx_bytes == SOCKET_ERROR) {
00855             FatalSendError();
00856         }
00857         
00858         return tx_bytes;
00859     }
00860 
00861     int JackNetSlaveInterface::SyncRecv()
00862     {
00863         SetRcvTimeOut();
00864         
00865         int rx_bytes = 0;
00866         packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
00867      
00868         // receive sync (launch the cycle)
00869         do {
00870             rx_bytes = Recv(fParams.fMtu, 0);
00871             // connection issue (return -1)
00872             if (rx_bytes == SOCKET_ERROR) {
00873                 return rx_bytes;
00874             }
00875         }
00876         while (strcmp(rx_head->fPacketType, "header") != 0);
00877         
00878         if (rx_head->fDataType != 's') {
00879             jack_error("Wrong packet type : %c", rx_head->fDataType);
00880             // not the last packet...
00881             fRxHeader.fIsLastPckt = 0;
00882             return SYNC_PACKET_ERROR;
00883         }
00884      
00885         fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
00886         return rx_bytes;
00887     }
00888 
00889     int JackNetSlaveInterface::DataRecv()
00890     {
00891         int rx_bytes = 0;
00892         uint recvd_midi_pckt = 0;
00893         packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
00894 
00895         while (!fRxHeader.fIsLastPckt) {
00896             // how much data is queued on the rx buffer ?
00897             rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
00898 
00899             // error here, just skip the cycle (return -1)
00900             if (rx_bytes == SOCKET_ERROR) {
00901                 return rx_bytes;
00902             }
00903 
00904             if (rx_bytes && (rx_head->fDataStream == 's') && (rx_head->fID == fParams.fID)) {
00905                 // read data
00906                 switch (rx_head->fDataType) {
00907 
00908                     case 'm':   // midi
00909                         rx_bytes = MidiRecv(rx_head, fNetMidiCaptureBuffer, recvd_midi_pckt);
00910                         break;
00911 
00912                     case 'a':   // audio
00913                         rx_bytes = AudioRecv(rx_head, fNetAudioCaptureBuffer);
00914                         break;
00915 
00916                     case 's':   // sync
00917                         jack_info("NetSlave : missing last data packet");
00918                         return FinishRecv(fNetAudioCaptureBuffer);
00919                 }
00920             }
00921         }
00922 
00923         fRxHeader.fCycle = rx_head->fCycle;
00924         return rx_bytes;
00925     }
00926 
00927     int JackNetSlaveInterface::SyncSend()
00928     {
00929         // tx header
00930         if (fParams.fSlaveSyncMode) {
00931             fTxHeader.fCycle = fRxHeader.fCycle;
00932         } else {
00933             fTxHeader.fCycle++;
00934         }
00935         fTxHeader.fSubCycle = 0;
00936         fTxHeader.fDataType = 's';
00937         fTxHeader.fIsLastPckt = (fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0;
00938         fTxHeader.fPacketSize = fParams.fMtu;
00939 
00940         memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
00941         //PacketHeaderDisplay(&fTxHeader);
00942         return Send(fTxHeader.fPacketSize, 0);
00943     }
00944 
00945     int JackNetSlaveInterface::DataSend()
00946     {
00947         if (MidiSend(fNetMidiPlaybackBuffer, fParams.fReturnMidiChannels, fParams.fReturnAudioChannels) == SOCKET_ERROR) {
00948             return SOCKET_ERROR;
00949         }
00950         return AudioSend(fNetAudioPlaybackBuffer, fParams.fReturnAudioChannels);
00951     }
00952 
00953     // network sync------------------------------------------------------------------------
00954     void JackNetSlaveInterface::EncodeSyncPacket(int frames)
00955     {
00956         // This method contains every step of sync packet informations coding
00957         // first of all, clear sync packet
00958         memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams));
00959 
00960         // then first step : transport
00961         // Transport is not used for now...
00962         /*
00963         if (fParams.fTransportSync) {
00964             EncodeTransportData();
00965             TransportDataHToN(&fReturnTransportData, &fReturnTransportData);
00966             // copy to TxBuffer
00967             memcpy(fTxData, &fReturnTransportData, sizeof(net_transport_data_t));
00968         }
00969         // then others
00970         // ...
00971         */
00972 
00973         // Write active ports list
00974         fTxHeader.fActivePorts = (fNetAudioCaptureBuffer) ? fNetAudioCaptureBuffer->ActivePortsToNetwork(fTxData) : 0;
00975         fTxHeader.fFrames = frames;
00976     }
00977 
00978     void JackNetSlaveInterface::DecodeSyncPacket(int& frames)
00979     {
00980         // This method contains every step of sync packet informations decoding process
00981         
00982         // Transport not used for now...
00983         /*
00984         // first : transport
00985         if (fParams.fTransportSync) {
00986             // copy received transport data to transport data structure
00987             memcpy(&fSendTransportData, fRxData, sizeof(net_transport_data_t));
00988             TransportDataNToH(&fSendTransportData, &fSendTransportData);
00989             DecodeTransportData();
00990         }
00991         // then others
00992         // ...
00993         */
00994        
00995         packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
00996 
00997         // Read active ports list
00998         if (fNetAudioPlaybackBuffer) {
00999             fNetAudioPlaybackBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
01000         }
01001         
01002         frames = rx_head->fFrames;
01003     }
01004 
01005 }