2 Copyright (C) 2008-2011 Romain Moret at Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #include "JackNetInterface.h"
20 #include "JackException.h"
21 #include "JackError.h"
28 TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames,
29 probably also use BUFFER_SIZE_MAX in everything related to MIDI events
30 handling (see MidiBufferInit in JackMidiPort.cpp)
35 // JackNetInterface*******************************************
37 JackNetInterface::JackNetInterface() : fSocket()
42 JackNetInterface::JackNetInterface(const char* multicast_ip
, int port
) : fSocket(multicast_ip
, port
)
44 strcpy(fMulticastIP
, multicast_ip
);
48 JackNetInterface::JackNetInterface(session_params_t
& params
, JackNetSocket
& socket
, const char* multicast_ip
) : fSocket(socket
)
51 strcpy(fMulticastIP
, multicast_ip
);
55 void JackNetInterface::Initialize()
60 fNetAudioCaptureBuffer
= NULL
;
61 fNetAudioPlaybackBuffer
= NULL
;
62 fNetMidiCaptureBuffer
= NULL
;
63 fNetMidiPlaybackBuffer
= NULL
;
64 memset(&fSendTransportData
, 0, sizeof(net_transport_data_t
));
65 memset(&fReturnTransportData
, 0, sizeof(net_transport_data_t
));
66 fPacketTimeOut
= PACKET_TIMEOUT
* NETWORK_DEFAULT_LATENCY
;
69 void JackNetInterface::FreeNetworkBuffers()
71 delete fNetMidiCaptureBuffer
;
72 delete fNetMidiPlaybackBuffer
;
73 delete fNetAudioCaptureBuffer
;
74 delete fNetAudioPlaybackBuffer
;
75 fNetMidiCaptureBuffer
= NULL
;
76 fNetMidiPlaybackBuffer
= NULL
;
77 fNetAudioCaptureBuffer
= NULL
;
78 fNetAudioPlaybackBuffer
= NULL
;
81 JackNetInterface::~JackNetInterface()
83 jack_log("JackNetInterface::~JackNetInterface");
88 delete fNetAudioCaptureBuffer
;
89 delete fNetAudioPlaybackBuffer
;
90 delete fNetMidiCaptureBuffer
;
91 delete fNetMidiPlaybackBuffer
;
94 int JackNetInterface::SetNetBufferSize()
97 float audio_size
= (fNetAudioCaptureBuffer
)
98 ? fNetAudioCaptureBuffer
->GetCycleSize()
99 : (fNetAudioPlaybackBuffer
) ? fNetAudioPlaybackBuffer
->GetCycleSize() : 0;
100 jack_log("audio_size %f", audio_size
);
103 float midi_size
= (fNetMidiCaptureBuffer
)
104 ? fNetMidiCaptureBuffer
->GetCycleSize()
105 : (fNetMidiPlaybackBuffer
) ? fNetMidiPlaybackBuffer
->GetCycleSize() : 0;
106 jack_log("midi_size %f", midi_size
);
108 // bufsize = sync + audio + midi
109 int bufsize
= NETWORK_MAX_LATENCY
* (fParams
.fMtu
+ (int)audio_size
+ (int)midi_size
);
110 jack_log("SetNetBufferSize bufsize = %d", bufsize
);
113 if (fSocket
.SetOption(SOL_SOCKET
, SO_SNDBUF
, &bufsize
, sizeof(bufsize
)) == SOCKET_ERROR
) {
118 if (fSocket
.SetOption(SOL_SOCKET
, SO_RCVBUF
, &bufsize
, sizeof(bufsize
)) == SOCKET_ERROR
) {
125 bool JackNetInterface::SetParams()
128 memset(&fTxHeader
, 0, sizeof(fTxHeader
));
129 strcpy(fTxHeader
.fPacketType
, "header");
130 fTxHeader
.fID
= fParams
.fID
;
131 fTxHeader
.fCycle
= 0;
132 fTxHeader
.fSubCycle
= 0;
133 fTxHeader
.fIsLastPckt
= 0;
136 memset(&fRxHeader
, 0, sizeof(fTxHeader
));
137 strcpy(fRxHeader
.fPacketType
, "header");
138 fRxHeader
.fID
= fParams
.fID
;
139 fRxHeader
.fCycle
= 0;
140 fRxHeader
.fSubCycle
= 0;
141 fRxHeader
.fIsLastPckt
= 0;
144 fTxBuffer
= new char[fParams
.fMtu
];
145 fRxBuffer
= new char[fParams
.fMtu
];
149 // net audio/midi buffers'addresses
150 fTxData
= fTxBuffer
+ HEADER_SIZE
;
151 fRxData
= fRxBuffer
+ HEADER_SIZE
;
156 int JackNetInterface::MidiSend(NetMidiBuffer
* buffer
, int midi_channnels
, int audio_channels
)
158 if (midi_channnels
> 0) {
159 // set global header fields and get the number of midi packets
160 fTxHeader
.fDataType
= 'm';
161 uint data_size
= buffer
->RenderFromJackPorts();
162 fTxHeader
.fNumPacket
= buffer
->GetNumPackets(data_size
, PACKET_AVAILABLE_SIZE(&fParams
));
164 for (uint subproc
= 0; subproc
< fTxHeader
.fNumPacket
; subproc
++) {
165 fTxHeader
.fSubCycle
= subproc
;
166 fTxHeader
.fIsLastPckt
= ((subproc
== (fTxHeader
.fNumPacket
- 1)) && audio_channels
== 0) ? 1 : 0;
167 fTxHeader
.fPacketSize
= HEADER_SIZE
+ buffer
->RenderToNetwork(subproc
, data_size
);
168 memcpy(fTxBuffer
, &fTxHeader
, HEADER_SIZE
);
169 //PacketHeaderDisplay(&fTxHeader);
170 if (Send(fTxHeader
.fPacketSize
, 0) == SOCKET_ERROR
) {
178 int JackNetInterface::AudioSend(NetAudioBuffer
* buffer
, int audio_channels
)
181 if (audio_channels
> 0) {
182 fTxHeader
.fDataType
= 'a';
183 fTxHeader
.fActivePorts
= buffer
->RenderFromJackPorts(fTxHeader
.fFrames
);
184 fTxHeader
.fNumPacket
= buffer
->GetNumPackets(fTxHeader
.fActivePorts
);
186 for (uint subproc
= 0; subproc
< fTxHeader
.fNumPacket
; subproc
++) {
187 fTxHeader
.fSubCycle
= subproc
;
188 fTxHeader
.fIsLastPckt
= (subproc
== (fTxHeader
.fNumPacket
- 1)) ? 1 : 0;
189 fTxHeader
.fPacketSize
= HEADER_SIZE
+ buffer
->RenderToNetwork(subproc
, fTxHeader
.fActivePorts
);
190 memcpy(fTxBuffer
, &fTxHeader
, HEADER_SIZE
);
191 //PacketHeaderDisplay(&fTxHeader);
192 if (Send(fTxHeader
.fPacketSize
, 0) == SOCKET_ERROR
) {
200 int JackNetInterface::MidiRecv(packet_header_t
* rx_head
, NetMidiBuffer
* buffer
, uint
& recvd_midi_pckt
)
202 int rx_bytes
= Recv(rx_head
->fPacketSize
, 0);
203 fRxHeader
.fCycle
= rx_head
->fCycle
;
204 fRxHeader
.fIsLastPckt
= rx_head
->fIsLastPckt
;
205 buffer
->RenderFromNetwork(rx_head
->fSubCycle
, rx_bytes
- HEADER_SIZE
);
207 // Last midi packet is received, so finish rendering...
208 if (++recvd_midi_pckt
== rx_head
->fNumPacket
) {
209 buffer
->RenderToJackPorts();
211 //PacketHeaderDisplay(rx_head);
215 int JackNetInterface::AudioRecv(packet_header_t
* rx_head
, NetAudioBuffer
* buffer
)
217 int rx_bytes
= Recv(rx_head
->fPacketSize
, 0);
218 fRxHeader
.fCycle
= rx_head
->fCycle
;
219 fRxHeader
.fSubCycle
= rx_head
->fSubCycle
;
220 fRxHeader
.fIsLastPckt
= rx_head
->fIsLastPckt
;
221 fRxHeader
.fActivePorts
= rx_head
->fActivePorts
;
222 fRxHeader
.fFrames
= rx_head
->fFrames
;
223 rx_bytes
= buffer
->RenderFromNetwork(rx_head
->fCycle
, rx_head
->fSubCycle
, fRxHeader
.fActivePorts
);
225 // Last audio packet is received, so finish rendering...
226 if (fRxHeader
.fIsLastPckt
) {
227 buffer
->RenderToJackPorts(fRxHeader
.fFrames
);
229 //PacketHeaderDisplay(rx_head);
233 int JackNetInterface::FinishRecv(NetAudioBuffer
* buffer
)
236 buffer
->RenderToJackPorts(fRxHeader
.fFrames
);
238 jack_error("FinishRecv with null buffer...");
240 return DATA_PACKET_ERROR
;
243 NetAudioBuffer
* JackNetInterface::AudioBufferFactory(int nports
, char* buffer
)
245 switch (fParams
.fSampleEncoder
) {
247 case JackFloatEncoder
:
248 return new NetFloatAudioBuffer(&fParams
, nports
, buffer
);
251 return new NetIntAudioBuffer(&fParams
, nports
, buffer
);
254 case JackCeltEncoder
:
255 return new NetCeltAudioBuffer(&fParams
, nports
, buffer
, fParams
.fKBps
);
258 case JackOpusEncoder
:
259 return new NetOpusAudioBuffer(&fParams
, nports
, buffer
, fParams
.fKBps
);
263 throw std::bad_alloc();
266 void JackNetInterface::SetRcvTimeOut()
269 if (fSocket
.SetTimeOut(fPacketTimeOut
) == SOCKET_ERROR
) {
270 jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE
));
277 // JackNetMasterInterface ************************************************************************************
279 bool JackNetMasterInterface::Init()
281 jack_log("JackNetMasterInterface::Init : ID %u", fParams
.fID
);
283 session_params_t host_params
;
288 if (fSocket
.NewSocket() == SOCKET_ERROR
) {
289 jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE
));
293 // timeout on receive (for init)
294 if (fSocket
.SetTimeOut(MASTER_INIT_TIMEOUT
) < 0) {
295 jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE
));
299 if (fSocket
.Connect() == SOCKET_ERROR
) {
300 jack_error("Can't connect : %s", StrError(NET_ERROR_CODE
));
304 // send 'SLAVE_SETUP' until 'START_MASTER' received
305 jack_info("Sending parameters to %s...", fParams
.fSlaveNetName
);
308 session_params_t net_params
;
309 memset(&net_params
, 0, sizeof(session_params_t
));
310 SetPacketType(&fParams
, SLAVE_SETUP
);
311 SessionParamsHToN(&fParams
, &net_params
);
313 if (fSocket
.Send(&net_params
, sizeof(session_params_t
), 0) == SOCKET_ERROR
) {
314 jack_error("Error in send : %s", StrError(NET_ERROR_CODE
));
317 memset(&net_params
, 0, sizeof(session_params_t
));
318 if (((rx_bytes
= fSocket
.Recv(&net_params
, sizeof(session_params_t
), 0)) == SOCKET_ERROR
) && (fSocket
.GetError() != NET_NO_DATA
)) {
319 jack_error("Problem with network");
323 SessionParamsNToH(&net_params
, &host_params
);
325 while ((GetPacketType(&host_params
) != START_MASTER
) && (++attempt
< SLAVE_SETUP_RETRY
));
327 if (attempt
== SLAVE_SETUP_RETRY
) {
328 jack_error("Slave doesn't respond, exiting");
335 bool JackNetMasterInterface::SetParams()
337 jack_log("JackNetMasterInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
338 fParams
.fSendAudioChannels
, fParams
.fReturnAudioChannels
,
339 fParams
.fSendMidiChannels
, fParams
.fReturnMidiChannels
);
341 JackNetInterface::SetParams();
343 fTxHeader
.fDataStream
= 's';
344 fRxHeader
.fDataStream
= 'r';
346 fMaxCycleOffset
= fParams
.fNetworkLatency
;
349 if (fParams
.fSendMidiChannels
> 0) {
350 fNetMidiCaptureBuffer
= new NetMidiBuffer(&fParams
, fParams
.fSendMidiChannels
, fTxData
);
353 if (fParams
.fReturnMidiChannels
> 0) {
354 fNetMidiPlaybackBuffer
= new NetMidiBuffer(&fParams
, fParams
.fReturnMidiChannels
, fRxData
);
360 if (fParams
.fSendAudioChannels
> 0) {
361 fNetAudioCaptureBuffer
= AudioBufferFactory(fParams
.fSendAudioChannels
, fTxData
);
362 assert(fNetAudioCaptureBuffer
);
365 if (fParams
.fReturnAudioChannels
> 0) {
366 fNetAudioPlaybackBuffer
= AudioBufferFactory(fParams
.fReturnAudioChannels
, fRxData
);
367 assert(fNetAudioPlaybackBuffer
);
370 } catch (exception
&) {
371 jack_error("NetAudioBuffer on master allocation error...");
375 // set the new buffer size
376 if (SetNetBufferSize() == SOCKET_ERROR
) {
377 jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE
));
384 FreeNetworkBuffers();
388 void JackNetMasterInterface::Exit()
390 jack_log("JackNetMasterInterface::Exit, ID %u", fParams
.fID
);
395 // send a 'multicast euthanasia request' - new socket is required on macosx
396 jack_info("Exiting '%s' %s", fParams
.fName
, fMulticastIP
);
397 SetPacketType(&fParams
, KILL_MASTER
);
398 JackNetSocket
mcast_socket(fMulticastIP
, fSocket
.GetPort());
400 session_params_t net_params
;
401 memset(&net_params
, 0, sizeof(session_params_t
));
402 SessionParamsHToN(&fParams
, &net_params
);
404 if (mcast_socket
.NewSocket() == SOCKET_ERROR
) {
405 jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE
));
407 if (mcast_socket
.SendTo(&net_params
, sizeof(session_params_t
), 0, fMulticastIP
) == SOCKET_ERROR
) {
408 jack_error("Can't send suicide request : %s", StrError(NET_ERROR_CODE
));
411 mcast_socket
.Close();
414 void JackNetMasterInterface::FatalRecvError()
416 // fatal connection issue, exit
417 jack_error("Recv connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE
), fParams
.fName
);
418 // ask to the manager to properly remove the master
420 // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
424 void JackNetMasterInterface::FatalSendError()
426 // fatal connection issue, exit
427 jack_error("Send connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE
), fParams
.fName
);
428 // ask to the manager to properly remove the master
430 // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
434 int JackNetMasterInterface::Recv(size_t size
, int flags
)
438 if (((rx_bytes
= fSocket
.Recv(fRxBuffer
, size
, flags
)) == SOCKET_ERROR
) && fRunning
) {
442 packet_header_t
* header
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
443 PacketHeaderNToH(header
, header
);
447 int JackNetMasterInterface::Send(size_t size
, int flags
)
450 packet_header_t
* header
= reinterpret_cast<packet_header_t
*>(fTxBuffer
);
451 PacketHeaderHToN(header
, header
);
453 if (((tx_bytes
= fSocket
.Send(fTxBuffer
, size
, flags
)) == SOCKET_ERROR
) && fRunning
) {
459 int JackNetMasterInterface::SyncSend()
464 fTxHeader
.fSubCycle
= 0;
465 fTxHeader
.fDataType
= 's';
466 fTxHeader
.fIsLastPckt
= (fParams
.fSendMidiChannels
== 0 && fParams
.fSendAudioChannels
== 0) ? 1 : 0;
467 fTxHeader
.fPacketSize
= HEADER_SIZE
+ fTxHeader
.fActivePorts
* sizeof(int); // Data part is used to encode active ports
469 memcpy(fTxBuffer
, &fTxHeader
, HEADER_SIZE
);
470 //PacketHeaderDisplay(&fTxHeader);
471 return Send(fTxHeader
.fPacketSize
, 0);
474 int JackNetMasterInterface::DataSend()
476 if (MidiSend(fNetMidiCaptureBuffer
, fParams
.fSendMidiChannels
, fParams
.fSendAudioChannels
) == SOCKET_ERROR
) {
479 return AudioSend(fNetAudioCaptureBuffer
, fParams
.fSendAudioChannels
);
482 int JackNetMasterInterface::SyncRecv()
485 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
487 // receive sync (launch the cycle)
489 rx_bytes
= Recv(fParams
.fMtu
, MSG_PEEK
);
490 // connection issue (return -1)
491 if (rx_bytes
== SOCKET_ERROR
) {
495 while (strcmp(rx_head
->fPacketType
, "header") != 0);
496 //PacketHeaderDisplay(rx_head);
498 if (rx_head
->fDataType
!= 's') {
499 jack_error("Wrong packet type : %c", rx_head
->fDataType
);
500 // not the last packet..
501 fRxHeader
.fIsLastPckt
= 0;
502 return SYNC_PACKET_ERROR
;
505 fCurrentCycleOffset
= fTxHeader
.fCycle
- rx_head
->fCycle
;
507 if (fCurrentCycleOffset
< fMaxCycleOffset
&& !fSynched
) {
508 jack_info("Syncing with latency = %d", fCurrentCycleOffset
);
511 if (fCurrentCycleOffset
== fMaxCycleOffset
) {
512 // when the sync offset is reached
515 rx_bytes
= Recv(rx_head
->fPacketSize
, 0);
516 fRxHeader
.fIsLastPckt
= rx_head
->fIsLastPckt
;
521 int JackNetMasterInterface::DataRecv()
524 uint recvd_midi_pckt
= 0;
525 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
527 while (!fRxHeader
.fIsLastPckt
) {
528 // how much data is queued on the rx buffer ?
529 rx_bytes
= Recv(fParams
.fMtu
, MSG_PEEK
);
531 // error here, problem with recv, just skip the cycle (return -1)
532 if (rx_bytes
== SOCKET_ERROR
) {
536 if (rx_bytes
&& (rx_head
->fDataStream
== 'r') && (rx_head
->fID
== fParams
.fID
)) {
538 switch (rx_head
->fDataType
) {
541 rx_bytes
= MidiRecv(rx_head
, fNetMidiPlaybackBuffer
, recvd_midi_pckt
);
545 rx_bytes
= AudioRecv(rx_head
, fNetAudioPlaybackBuffer
);
549 jack_info("NetMaster : missing last data packet from '%s'", fParams
.fName
);
550 return FinishRecv(fNetAudioPlaybackBuffer
);
558 void JackNetMasterInterface::EncodeSyncPacket(int frames
)
560 // This method contains every step of sync packet information coding
561 // first of all, clear sync packet
562 memset(fTxData
, 0, PACKET_AVAILABLE_SIZE(&fParams
));
564 // Transport not used for now...
566 // then, first step : transport
567 if (fParams.fTransportSync) {
568 EncodeTransportData();
569 TransportDataHToN(&fSendTransportData, &fSendTransportData);
571 memcpy(fTxData, &fSendTransportData, sizeof(net_transport_data_t));
573 // then others (freewheel etc.)
577 // Write active ports list
578 fTxHeader
.fActivePorts
= (fNetAudioPlaybackBuffer
) ? fNetAudioPlaybackBuffer
->ActivePortsToNetwork(fTxData
) : 0;
579 fTxHeader
.fFrames
= frames
;
582 void JackNetMasterInterface::DecodeSyncPacket(int& frames
)
584 // This method contains every step of sync packet information decoding process
586 // Transport not used for now...
589 if (fParams.fTransportSync) {
590 // copy received transport data to transport data structure
591 memcpy(&fReturnTransportData, fRxData, sizeof(net_transport_data_t));
592 TransportDataNToH(&fReturnTransportData, &fReturnTransportData);
593 DecodeTransportData();
599 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
601 // Read active ports list
602 if (fNetAudioCaptureBuffer
) {
603 fNetAudioCaptureBuffer
->ActivePortsFromNetwork(fRxData
, rx_head
->fActivePorts
);
605 frames
= rx_head
->fFrames
;
608 // JackNetSlaveInterface ************************************************************************************************
610 uint
JackNetSlaveInterface::fSlaveCounter
= 0;
612 void JackNetSlaveInterface::InitAPI()
614 // open Socket API with the first slave
615 if (fSlaveCounter
++ == 0) {
616 if (SocketAPIInit() < 0) {
617 jack_error("Can't init Socket API, exiting...");
618 throw std::bad_alloc();
623 bool JackNetSlaveInterface::Init()
625 jack_log("JackNetSlaveInterface::Init()");
627 // set the parameters to send
628 strcpy(fParams
.fPacketType
, "params");
629 fParams
.fProtocolVersion
= NETWORK_PROTOCOL
;
630 SetPacketType(&fParams
, SLAVE_AVAILABLE
);
632 // init loop : get a master and start, do it until connection is ok
635 // first, get a master, do it until a valid connection is running
637 status
= SendAvailableToMaster();
638 if (status
== NET_SOCKET_ERROR
) {
642 while (status
!= NET_CONNECTED
);
644 // then tell the master we are ready
645 jack_info("Initializing connection with %s...", fParams
.fMasterNetName
);
646 status
= SendStartToMaster();
647 if (status
== NET_ERROR
) {
651 while (status
!= NET_ROLLING
);
656 // Separate the connection protocol into two separated step
657 bool JackNetSlaveInterface::InitConnection(int time_out_sec
)
659 jack_log("JackNetSlaveInterface::InitConnection time_out_sec = %d", time_out_sec
);
660 int try_count
= (time_out_sec
> 0) ? int((1000000.f
* float(time_out_sec
)) / float(SLAVE_INIT_TIMEOUT
)) : INT_MAX
;
662 // set the parameters to send
663 strcpy(fParams
.fPacketType
, "params");
664 fParams
.fProtocolVersion
= NETWORK_PROTOCOL
;
665 SetPacketType(&fParams
, SLAVE_AVAILABLE
);
667 return (SendAvailableToMaster(try_count
) == NET_CONNECTED
);
670 bool JackNetSlaveInterface::InitRendering()
672 jack_log("JackNetSlaveInterface::InitRendering()");
676 // then tell the master we are ready
677 jack_info("Initializing connection with %s...", fParams
.fMasterNetName
);
678 status
= SendStartToMaster();
679 if (status
== NET_ERROR
) {
683 while (status
!= NET_ROLLING
);
688 net_status_t
JackNetSlaveInterface::SendAvailableToMaster(int try_count
)
690 jack_log("JackNetSlaveInterface::SendAvailableToMaster try_count = %d", try_count
);
692 session_params_t host_params
;
696 if (fSocket
.NewSocket() == SOCKET_ERROR
) {
697 jack_error("Fatal error : network unreachable - %s", StrError(NET_ERROR_CODE
));
698 return NET_SOCKET_ERROR
;
701 if (fSocket
.IsLocal(fMulticastIP
)) {
702 jack_info("Local IP is used...");
705 if (fSocket
.Bind() == SOCKET_ERROR
) {
706 jack_error("Can't bind the socket : %s", StrError(NET_ERROR_CODE
));
707 return NET_SOCKET_ERROR
;
711 // timeout on receive (for init)
712 if (fSocket
.SetTimeOut(SLAVE_INIT_TIMEOUT
) == SOCKET_ERROR
) {
713 jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE
));
716 // disable local loop
717 if (fSocket
.SetLocalLoop() == SOCKET_ERROR
) {
718 jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE
));
721 // send 'AVAILABLE' until 'SLAVE_SETUP' received
722 jack_info("Waiting for a master...");
726 session_params_t net_params
;
727 memset(&net_params
, 0, sizeof(session_params_t
));
728 SessionParamsHToN(&fParams
, &net_params
);
729 if (fSocket
.SendTo(&net_params
, sizeof(session_params_t
), 0, fMulticastIP
) == SOCKET_ERROR
) {
730 jack_error("Error in data send : %s", StrError(NET_ERROR_CODE
));
733 // filter incoming packets : don't exit while no error is detected
734 memset(&net_params
, 0, sizeof(session_params_t
));
735 rx_bytes
= fSocket
.CatchHost(&net_params
, sizeof(session_params_t
), 0);
736 SessionParamsNToH(&net_params
, &host_params
);
737 if ((rx_bytes
== SOCKET_ERROR
) && (fSocket
.GetError() != NET_NO_DATA
)) {
738 jack_error("Can't receive : %s", StrError(NET_ERROR_CODE
));
739 return NET_RECV_ERROR
;
742 while (strcmp(host_params
.fPacketType
, fParams
.fPacketType
) && (GetPacketType(&host_params
) != SLAVE_SETUP
) && (--try_count
> 0));
744 // time out failure..
745 if (try_count
== 0) {
746 jack_error("Time out error in connect");
747 return NET_CONNECT_ERROR
;
750 // everything is OK, copy parameters
751 fParams
= host_params
;
753 // connect the socket
754 if (fSocket
.Connect() == SOCKET_ERROR
) {
755 jack_error("Error in connect : %s", StrError(NET_ERROR_CODE
));
756 return NET_CONNECT_ERROR
;
759 return NET_CONNECTED
;
762 net_status_t
JackNetSlaveInterface::SendStartToMaster()
764 jack_log("JackNetSlaveInterface::SendStartToMaster");
766 // tell the master to start
767 session_params_t net_params
;
768 memset(&net_params
, 0, sizeof(session_params_t
));
769 SetPacketType(&fParams
, START_MASTER
);
770 SessionParamsHToN(&fParams
, &net_params
);
771 if (fSocket
.Send(&net_params
, sizeof(session_params_t
), 0) == SOCKET_ERROR
) {
772 jack_error("Error in send : %s", StrError(NET_ERROR_CODE
));
773 return (fSocket
.GetError() == NET_CONN_ERROR
) ? NET_ERROR
: NET_SEND_ERROR
;
778 bool JackNetSlaveInterface::SetParams()
780 jack_log("JackNetSlaveInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
781 fParams
.fSendAudioChannels
, fParams
.fReturnAudioChannels
,
782 fParams
.fSendMidiChannels
, fParams
.fReturnMidiChannels
);
784 JackNetInterface::SetParams();
786 fTxHeader
.fDataStream
= 'r';
787 fRxHeader
.fDataStream
= 's';
790 if (fParams
.fSendMidiChannels
> 0) {
791 fNetMidiCaptureBuffer
= new NetMidiBuffer(&fParams
, fParams
.fSendMidiChannels
, fRxData
);
794 if (fParams
.fReturnMidiChannels
> 0) {
795 fNetMidiPlaybackBuffer
= new NetMidiBuffer(&fParams
, fParams
.fReturnMidiChannels
, fTxData
);
801 if (fParams
.fSendAudioChannels
> 0) {
802 fNetAudioCaptureBuffer
= AudioBufferFactory(fParams
.fSendAudioChannels
, fRxData
);
803 assert(fNetAudioCaptureBuffer
);
806 if (fParams
.fReturnAudioChannels
> 0) {
807 fNetAudioPlaybackBuffer
= AudioBufferFactory(fParams
.fReturnAudioChannels
, fTxData
);
808 assert(fNetAudioPlaybackBuffer
);
811 } catch (exception
&) {
812 jack_error("NetAudioBuffer on slave allocation error...");
816 // set the new buffer sizes
817 if (SetNetBufferSize() == SOCKET_ERROR
) {
818 jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE
));
825 FreeNetworkBuffers();
829 void JackNetSlaveInterface::FatalRecvError()
831 throw JackNetException("Recv connection lost error");
834 void JackNetSlaveInterface::FatalSendError()
836 throw JackNetException("Send connection lost error");
839 int JackNetSlaveInterface::Recv(size_t size
, int flags
)
841 int rx_bytes
= fSocket
.Recv(fRxBuffer
, size
, flags
);
844 if (rx_bytes
== SOCKET_ERROR
) {
848 packet_header_t
* header
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
849 PacketHeaderNToH(header
, header
);
853 int JackNetSlaveInterface::Send(size_t size
, int flags
)
855 packet_header_t
* header
= reinterpret_cast<packet_header_t
*>(fTxBuffer
);
856 PacketHeaderHToN(header
, header
);
857 int tx_bytes
= fSocket
.Send(fTxBuffer
, size
, flags
);
860 if (tx_bytes
== SOCKET_ERROR
) {
867 int JackNetSlaveInterface::SyncRecv()
872 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
874 // receive sync (launch the cycle)
876 rx_bytes
= Recv(fParams
.fMtu
, 0);
877 // connection issue (return -1)
878 if (rx_bytes
== SOCKET_ERROR
) {
882 while (strcmp(rx_head
->fPacketType
, "header") != 0);
884 if (rx_head
->fDataType
!= 's') {
885 jack_error("Wrong packet type : %c", rx_head
->fDataType
);
886 // not the last packet...
887 fRxHeader
.fIsLastPckt
= 0;
888 return SYNC_PACKET_ERROR
;
891 //PacketHeaderDisplay(rx_head);
892 fRxHeader
.fIsLastPckt
= rx_head
->fIsLastPckt
;
896 int JackNetSlaveInterface::DataRecv()
899 uint recvd_midi_pckt
= 0;
900 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
902 while (!fRxHeader
.fIsLastPckt
) {
903 // how much data is queued on the rx buffer ?
904 rx_bytes
= Recv(fParams
.fMtu
, MSG_PEEK
);
906 // error here, just skip the cycle (return -1)
907 if (rx_bytes
== SOCKET_ERROR
) {
911 if (rx_bytes
&& (rx_head
->fDataStream
== 's') && (rx_head
->fID
== fParams
.fID
)) {
913 switch (rx_head
->fDataType
) {
916 rx_bytes
= MidiRecv(rx_head
, fNetMidiCaptureBuffer
, recvd_midi_pckt
);
920 rx_bytes
= AudioRecv(rx_head
, fNetAudioCaptureBuffer
);
924 jack_info("NetSlave : missing last data packet");
925 return FinishRecv(fNetAudioCaptureBuffer
);
930 fRxHeader
.fCycle
= rx_head
->fCycle
;
934 int JackNetSlaveInterface::SyncSend()
937 if (fParams
.fSlaveSyncMode
) {
938 fTxHeader
.fCycle
= fRxHeader
.fCycle
;
942 fTxHeader
.fSubCycle
= 0;
943 fTxHeader
.fDataType
= 's';
944 fTxHeader
.fIsLastPckt
= (fParams
.fReturnMidiChannels
== 0 && fParams
.fReturnAudioChannels
== 0) ? 1 : 0;
945 fTxHeader
.fPacketSize
= HEADER_SIZE
+ fTxHeader
.fActivePorts
* sizeof(int); // Data part is used to encode active ports
947 memcpy(fTxBuffer
, &fTxHeader
, HEADER_SIZE
);
948 //PacketHeaderDisplay(&fTxHeader);
949 return Send(fTxHeader
.fPacketSize
, 0);
952 int JackNetSlaveInterface::DataSend()
954 if (MidiSend(fNetMidiPlaybackBuffer
, fParams
.fReturnMidiChannels
, fParams
.fReturnAudioChannels
) == SOCKET_ERROR
) {
957 return AudioSend(fNetAudioPlaybackBuffer
, fParams
.fReturnAudioChannels
);
960 // network sync------------------------------------------------------------------------
961 void JackNetSlaveInterface::EncodeSyncPacket(int frames
)
963 // This method contains every step of sync packet information coding
964 // first of all, clear sync packet
965 memset(fTxData
, 0, PACKET_AVAILABLE_SIZE(&fParams
));
967 // then first step : transport
968 // Transport is not used for now...
970 if (fParams.fTransportSync) {
971 EncodeTransportData();
972 TransportDataHToN(&fReturnTransportData, &fReturnTransportData);
974 memcpy(fTxData, &fReturnTransportData, sizeof(net_transport_data_t));
980 // Write active ports list
981 fTxHeader
.fActivePorts
= (fNetAudioCaptureBuffer
) ? fNetAudioCaptureBuffer
->ActivePortsToNetwork(fTxData
) : 0;
982 fTxHeader
.fFrames
= frames
;
985 void JackNetSlaveInterface::DecodeSyncPacket(int& frames
)
987 // This method contains every step of sync packet information decoding process
989 // Transport not used for now...
992 if (fParams.fTransportSync) {
993 // copy received transport data to transport data structure
994 memcpy(&fSendTransportData, fRxData, sizeof(net_transport_data_t));
995 TransportDataNToH(&fSendTransportData, &fSendTransportData);
996 DecodeTransportData();
1002 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
1004 // Read active ports list
1005 if (fNetAudioPlaybackBuffer
) {
1006 fNetAudioPlaybackBuffer
->ActivePortsFromNetwork(fRxData
, rx_head
->fActivePorts
);
1009 frames
= rx_head
->fFrames
;