|  |  | @@ -94,27 +94,27 @@ namespace Jack | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int JackNetInterface::SetNetBufferSize() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | //audio | 
		
	
		
			
			|  |  |  | // audio | 
		
	
		
			
			|  |  |  | float audio_size = (fNetAudioCaptureBuffer) | 
		
	
		
			
			|  |  |  | ? fNetAudioCaptureBuffer->GetCycleSize() | 
		
	
		
			
			|  |  |  | : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0; | 
		
	
		
			
			|  |  |  | ? fNetAudioCaptureBuffer->GetCycleSize() | 
		
	
		
			
			|  |  |  | : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0; | 
		
	
		
			
			|  |  |  | jack_log("audio_size %f", audio_size); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //midi | 
		
	
		
			
			|  |  |  | // midi | 
		
	
		
			
			|  |  |  | float midi_size = (fNetMidiCaptureBuffer) | 
		
	
		
			
			|  |  |  | ? fNetMidiCaptureBuffer->GetCycleSize() | 
		
	
		
			
			|  |  |  | : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0; | 
		
	
		
			
			|  |  |  | ? fNetMidiCaptureBuffer->GetCycleSize() | 
		
	
		
			
			|  |  |  | : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0; | 
		
	
		
			
			|  |  |  | jack_log("midi_size %f", midi_size); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //bufsize = sync + audio + midi | 
		
	
		
			
			|  |  |  | int bufsize = NETWORK_MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size); | 
		
	
		
			
			|  |  |  | // bufsize = sync + audio + midi | 
		
	
		
			
			|  |  |  | int bufsize = NETWORK_MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int)midi_size); | 
		
	
		
			
			|  |  |  | jack_log("SetNetBufferSize bufsize = %d", bufsize); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //tx buffer | 
		
	
		
			
			|  |  |  | // tx buffer | 
		
	
		
			
			|  |  |  | if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //rx buffer | 
		
	
		
			
			|  |  |  | // rx buffer | 
		
	
		
			
			|  |  |  | if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -123,33 +123,108 @@ namespace Jack | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | bool JackNetInterface::SetParams() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | //TX header init | 
		
	
		
			
			|  |  |  | // TX header init | 
		
	
		
			
			|  |  |  | strcpy(fTxHeader.fPacketType, "header"); | 
		
	
		
			
			|  |  |  | fTxHeader.fID = fParams.fID; | 
		
	
		
			
			|  |  |  | fTxHeader.fCycle = 0; | 
		
	
		
			
			|  |  |  | fTxHeader.fSubCycle = 0; | 
		
	
		
			
			|  |  |  | fTxHeader.fIsLastPckt = 0; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //RX header init | 
		
	
		
			
			|  |  |  | // RX header init | 
		
	
		
			
			|  |  |  | strcpy(fRxHeader.fPacketType, "header"); | 
		
	
		
			
			|  |  |  | fRxHeader.fID = fParams.fID; | 
		
	
		
			
			|  |  |  | fRxHeader.fCycle = 0; | 
		
	
		
			
			|  |  |  | fRxHeader.fSubCycle = 0; | 
		
	
		
			
			|  |  |  | fRxHeader.fIsLastPckt = 0; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //network buffers | 
		
	
		
			
			|  |  |  | // network buffers | 
		
	
		
			
			|  |  |  | fTxBuffer = new char[fParams.fMtu]; | 
		
	
		
			
			|  |  |  | fRxBuffer = new char[fParams.fMtu]; | 
		
	
		
			
			|  |  |  | assert(fTxBuffer); | 
		
	
		
			
			|  |  |  | assert(fRxBuffer); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //net audio/midi buffers'addresses | 
		
	
		
			
			|  |  |  | // net audio/midi buffers'addresses | 
		
	
		
			
			|  |  |  | fTxData = fTxBuffer + HEADER_SIZE; | 
		
	
		
			
			|  |  |  | fRxData = fRxBuffer + HEADER_SIZE; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return true; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int JackNetInterface::MidiSend(NetMidiBuffer* buffer, int midi_channnels, int audio_channels) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (midi_channnels > 0) { | 
		
	
		
			
			|  |  |  | // set global header fields and get the number of midi packets | 
		
	
		
			
			|  |  |  | fTxHeader.fDataType = 'm'; | 
		
	
		
			
			|  |  |  | uint data_size = buffer->RenderFromJackPorts(); | 
		
	
		
			
			|  |  |  | fTxHeader.fNumPacket = buffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) { | 
		
	
		
			
			|  |  |  | fTxHeader.fSubCycle = subproc; | 
		
	
		
			
			|  |  |  | // fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0; | 
		
	
		
			
			|  |  |  | fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && audio_channels == 0) ? 1 : 0; | 
		
	
		
			
			|  |  |  | fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, data_size); | 
		
	
		
			
			|  |  |  | memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); | 
		
	
		
			
			|  |  |  | if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int JackNetInterface::AudioSend(NetAudioBuffer* buffer, int audio_channels) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | // audio | 
		
	
		
			
			|  |  |  | if (audio_channels > 0) { | 
		
	
		
			
			|  |  |  | fTxHeader.fDataType = 'a'; | 
		
	
		
			
			|  |  |  | buffer->RenderFromJackPorts(); | 
		
	
		
			
			|  |  |  | fTxHeader.fNumPacket = buffer->GetNumPackets(); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) { | 
		
	
		
			
			|  |  |  | fTxHeader.fSubCycle = subproc; | 
		
	
		
			
			|  |  |  | fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0; | 
		
	
		
			
			|  |  |  | fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, fTxHeader.fActivePorts); | 
		
	
		
			
			|  |  |  | memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); | 
		
	
		
			
			|  |  |  | // PacketHeaderDisplay(&fTxHeader); | 
		
	
		
			
			|  |  |  | if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int JackNetInterface::MidiRecv(packet_header_t* rx_head, NetMidiBuffer* buffer, uint& recvd_midi_pckt) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | int rx_bytes = Recv(rx_head->fPacketSize, 0); | 
		
	
		
			
			|  |  |  | fRxHeader.fCycle = rx_head->fCycle; | 
		
	
		
			
			|  |  |  | fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | 
		
	
		
			
			|  |  |  | buffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); | 
		
	
		
			
			|  |  |  | // Last midi packet is received, so finish rendering... | 
		
	
		
			
			|  |  |  | if (++recvd_midi_pckt == rx_head->fNumPacket) | 
		
	
		
			
			|  |  |  | buffer->RenderToJackPorts(); | 
		
	
		
			
			|  |  |  | return rx_bytes; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int JackNetInterface::AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | int rx_bytes = Recv(rx_head->fPacketSize, 0); | 
		
	
		
			
			|  |  |  | fRxHeader.fCycle = rx_head->fCycle; | 
		
	
		
			
			|  |  |  | fRxHeader.fSubCycle = rx_head->fSubCycle; | 
		
	
		
			
			|  |  |  | fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | 
		
	
		
			
			|  |  |  | fRxHeader.fActivePorts = rx_head->fActivePorts; | 
		
	
		
			
			|  |  |  | rx_bytes = buffer->RenderFromNetwork(rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE, fRxHeader.fActivePorts); | 
		
	
		
			
			|  |  |  | // Last audio packet is received, so finish rendering... | 
		
	
		
			
			|  |  |  | if (fRxHeader.fIsLastPckt) | 
		
	
		
			
			|  |  |  | buffer->RenderToJackPorts(); | 
		
	
		
			
			|  |  |  | return rx_bytes; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int JackNetInterface::FinishRecv(NetAudioBuffer* buffer) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | // TODO : finish midi and audio rendering ? | 
		
	
		
			
			|  |  |  | buffer->RenderToJackPorts(); | 
		
	
		
			
			|  |  |  | return NET_PACKET_ERROR; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // JackNetMasterInterface ************************************************************************************ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | bool JackNetMasterInterface::Init() | 
		
	
	
		
			
				|  |  | @@ -160,23 +235,23 @@ namespace Jack | 
		
	
		
			
			|  |  |  | uint attempt = 0; | 
		
	
		
			
			|  |  |  | int rx_bytes = 0; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //socket | 
		
	
		
			
			|  |  |  | // socket | 
		
	
		
			
			|  |  |  | if (fSocket.NewSocket() == SOCKET_ERROR) { | 
		
	
		
			
			|  |  |  | jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | return false; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //timeout on receive (for init) | 
		
	
		
			
			|  |  |  | // timeout on receive (for init) | 
		
	
		
			
			|  |  |  | if (fSocket.SetTimeOut(MASTER_INIT_TIMEOUT) < 0) | 
		
	
		
			
			|  |  |  | jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //connect | 
		
	
		
			
			|  |  |  | // connect | 
		
	
		
			
			|  |  |  | if (fSocket.Connect() == SOCKET_ERROR) { | 
		
	
		
			
			|  |  |  | jack_error("Can't connect : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | return false; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //send 'SLAVE_SETUP' until 'START_MASTER' received | 
		
	
		
			
			|  |  |  | // send 'SLAVE_SETUP' until 'START_MASTER' received | 
		
	
		
			
			|  |  |  | jack_info("Sending parameters to %s...", fParams.fSlaveNetName); | 
		
	
		
			
			|  |  |  | do | 
		
	
		
			
			|  |  |  | { | 
		
	
	
		
			
				|  |  | @@ -223,7 +298,9 @@ namespace Jack | 
		
	
		
			
			|  |  |  | fTxHeader.fDataStream = 's'; | 
		
	
		
			
			|  |  |  | fRxHeader.fDataStream = 'r'; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //midi net buffers | 
		
	
		
			
			|  |  |  | fMaxCycleOffset = fParams.fNetworkLatency; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // midi net buffers | 
		
	
		
			
			|  |  |  | if (fParams.fSendMidiChannels > 0) | 
		
	
		
			
			|  |  |  | fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fTxData); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -232,7 +309,7 @@ namespace Jack | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | try { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //audio net buffers | 
		
	
		
			
			|  |  |  | // audio net buffers | 
		
	
		
			
			|  |  |  | if (fParams.fSendAudioChannels > 0) { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | switch (fParams.fSampleEncoder) { | 
		
	
	
		
			
				|  |  | @@ -282,13 +359,13 @@ namespace Jack | 
		
	
		
			
			|  |  |  | return false; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //set the new timeout for the socket | 
		
	
		
			
			|  |  |  | // set the new timeout for the socket | 
		
	
		
			
			|  |  |  | if (SetRxTimeout() == SOCKET_ERROR) { | 
		
	
		
			
			|  |  |  | jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | goto error; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //set the new rx buffer size | 
		
	
		
			
			|  |  |  | // set the new rx buffer size | 
		
	
		
			
			|  |  |  | if (SetNetBufferSize() == SOCKET_ERROR) { | 
		
	
		
			
			|  |  |  | jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | goto error; | 
		
	
	
		
			
				|  |  | @@ -305,10 +382,10 @@ namespace Jack | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | jack_log("JackNetMasterInterface::Exit, ID %u", fParams.fID); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //stop process | 
		
	
		
			
			|  |  |  | // stop process | 
		
	
		
			
			|  |  |  | fRunning = false; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //send a 'multicast euthanasia request' - new socket is required on macosx | 
		
	
		
			
			|  |  |  | // send a 'multicast euthanasia request' - new socket is required on macosx | 
		
	
		
			
			|  |  |  | jack_info("Exiting '%s'", fParams.fName); | 
		
	
		
			
			|  |  |  | SetPacketType(&fParams, KILL_MASTER); | 
		
	
		
			
			|  |  |  | JackNetSocket mcast_socket(fMulticastIP, fSocket.GetPort()); | 
		
	
	
		
			
				|  |  | @@ -327,9 +404,9 @@ namespace Jack | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | void JackNetMasterInterface::FatalError() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | //fatal connection issue, exit | 
		
	
		
			
			|  |  |  | // fatal connection issue, exit | 
		
	
		
			
			|  |  |  | jack_error("'%s' : %s, exiting", fParams.fName, StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | //ask to the manager to properly remove the master | 
		
	
		
			
			|  |  |  | // ask to the manager to properly remove the master | 
		
	
		
			
			|  |  |  | Exit(); | 
		
	
		
			
			|  |  |  | // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. | 
		
	
		
			
			|  |  |  | ThreadExit(); | 
		
	
	
		
			
				|  |  | @@ -343,7 +420,7 @@ namespace Jack | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | net_error_t error = fSocket.GetError(); | 
		
	
		
			
			|  |  |  | //no data isn't really a network error, so just return 0 available read bytes | 
		
	
		
			
			|  |  |  | // no data isn't really a network error, so just return 0 available read bytes | 
		
	
		
			
			|  |  |  | if (error == NET_NO_DATA) { | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } else if (error == NET_CONN_ERROR) { | 
		
	
	
		
			
				|  |  | @@ -399,18 +476,19 @@ namespace Jack | 
		
	
		
			
			|  |  |  | fNetAudioPlaybackBuffer->ActivePortsToNetwork(fTxData, fTxHeader.fActivePorts); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); | 
		
	
		
			
			|  |  |  | //PacketHeaderDisplay(&fTxHeader); | 
		
	
		
			
			|  |  |  | // PacketHeaderDisplay(&fTxHeader); | 
		
	
		
			
			|  |  |  | return Send(fTxHeader.fPacketSize, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int JackNetMasterInterface::DataSend() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | uint subproc; | 
		
	
		
			
			|  |  |  | uint data_size; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //midi | 
		
	
		
			
			|  |  |  | // midi | 
		
	
		
			
			|  |  |  | if (fParams.fSendMidiChannels > 0) { | 
		
	
		
			
			|  |  |  | //set global header fields and get the number of midi packets | 
		
	
		
			
			|  |  |  | // set global header fields and get the number of midi packets | 
		
	
		
			
			|  |  |  | fTxHeader.fDataType = 'm'; | 
		
	
		
			
			|  |  |  | data_size = fNetMidiCaptureBuffer->RenderFromJackPorts(); | 
		
	
		
			
			|  |  |  | fTxHeader.fNumPacket = fNetMidiCaptureBuffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE); | 
		
	
	
		
			
				|  |  | @@ -424,8 +502,13 @@ namespace Jack | 
		
	
		
			
			|  |  |  | return SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (MidiSend(fNetMidiCaptureBuffer, fParams.fSendMidiChannels, fParams.fSendAudioChannels) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //audio | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | // audio | 
		
	
		
			
			|  |  |  | if (fParams.fSendAudioChannels > 0) { | 
		
	
		
			
			|  |  |  | fTxHeader.fDataType = 'a'; | 
		
	
		
			
			|  |  |  | fNetAudioCaptureBuffer->RenderFromJackPorts(); | 
		
	
	
		
			
				|  |  | @@ -436,13 +519,14 @@ namespace Jack | 
		
	
		
			
			|  |  |  | fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0; | 
		
	
		
			
			|  |  |  | fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->RenderToNetwork(subproc, fTxHeader.fActivePorts); | 
		
	
		
			
			|  |  |  | memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); | 
		
	
		
			
			|  |  |  | //PacketHeaderDisplay(&fTxHeader); | 
		
	
		
			
			|  |  |  | // PacketHeaderDisplay(&fTxHeader); | 
		
	
		
			
			|  |  |  | if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | return AudioSend(fNetAudioPlaybackBuffer, fParams.fSendAudioChannels); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int JackNetMasterInterface::SyncRecv() | 
		
	
	
		
			
				|  |  | @@ -477,21 +561,20 @@ namespace Jack | 
		
	
		
			
			|  |  |  | uint recvd_midi_pckt = 0; | 
		
	
		
			
			|  |  |  | packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | while (!fRxHeader.fIsLastPckt) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | //how much data is queued on the rx buffer ? | 
		
	
		
			
			|  |  |  | while (!fRxHeader.fIsLastPckt) { | 
		
	
		
			
			|  |  |  | // how much data is queued on the rx buffer ? | 
		
	
		
			
			|  |  |  | rx_bytes = Recv(fParams.fMtu, MSG_PEEK); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //error here, problem with recv, just skip the cycle (return -1) | 
		
	
		
			
			|  |  |  | // error here, problem with recv, just skip the cycle (return -1) | 
		
	
		
			
			|  |  |  | if (rx_bytes == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return rx_bytes; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (rx_bytes && (rx_head->fDataStream == 'r') && (rx_head->fID == fParams.fID)) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | //read data | 
		
	
		
			
			|  |  |  | switch (rx_head->fDataType) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | case 'm':   //midi | 
		
	
		
			
			|  |  |  | if (rx_bytes && (rx_head->fDataStream == 'r') && (rx_head->fID == fParams.fID)) { | 
		
	
		
			
			|  |  |  | // read data | 
		
	
		
			
			|  |  |  | switch (rx_head->fDataType) { | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | case 'm':   // midi | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | rx_bytes = Recv(rx_head->fPacketSize, 0); | 
		
	
		
			
			|  |  |  | fRxHeader.fCycle = rx_head->fCycle; | 
		
	
		
			
			|  |  |  | fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | 
		
	
	
		
			
				|  |  | @@ -499,9 +582,12 @@ namespace Jack | 
		
	
		
			
			|  |  |  | // Last midi packet is received, so finish rendering... | 
		
	
		
			
			|  |  |  | if (++recvd_midi_pckt == rx_head->fNumPacket) | 
		
	
		
			
			|  |  |  | fNetMidiPlaybackBuffer->RenderToJackPorts(); | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | rx_bytes = MidiRecv(rx_head, fNetMidiPlaybackBuffer, recvd_midi_pckt); | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | case 'a':   //audio | 
		
	
		
			
			|  |  |  | case 'a':   // audio | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | rx_bytes = Recv(rx_head->fPacketSize, 0); | 
		
	
		
			
			|  |  |  | fRxHeader.fCycle = rx_head->fCycle; | 
		
	
		
			
			|  |  |  | fRxHeader.fSubCycle = rx_head->fSubCycle; | 
		
	
	
		
			
				|  |  | @@ -511,13 +597,18 @@ namespace Jack | 
		
	
		
			
			|  |  |  | // Last audio packet is received, so finish rendering... | 
		
	
		
			
			|  |  |  | if (fRxHeader.fIsLastPckt) | 
		
	
		
			
			|  |  |  | fNetAudioPlaybackBuffer->RenderToJackPorts(); | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | rx_bytes = AudioRecv(rx_head, fNetAudioPlaybackBuffer); | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | case 's':   //sync | 
		
	
		
			
			|  |  |  | case 's':   // sync | 
		
	
		
			
			|  |  |  | jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName); | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | // TODO : finish midi and audio rendering ? | 
		
	
		
			
			|  |  |  | fNetAudioPlaybackBuffer->RenderToJackPorts(); | 
		
	
		
			
			|  |  |  | return NET_PACKET_ERROR; | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | return FinishRecv(fNetAudioPlaybackBuffer); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -527,35 +618,35 @@ namespace Jack | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | void JackNetMasterInterface::EncodeSyncPacket() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | //this method contains every step of sync packet informations coding | 
		
	
		
			
			|  |  |  | //first of all, reset sync packet | 
		
	
		
			
			|  |  |  | // This method contains every step of sync packet informations coding | 
		
	
		
			
			|  |  |  | // first of all, reset sync packet | 
		
	
		
			
			|  |  |  | memset(fTxData, 0, PACKET_AVAILABLE_SIZE); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //then, first step : transport | 
		
	
		
			
			|  |  |  | // then, first step : transport | 
		
	
		
			
			|  |  |  | if (fParams.fTransportSync) { | 
		
	
		
			
			|  |  |  | // desactivated... | 
		
	
		
			
			|  |  |  | //EncodeTransportData(); | 
		
	
		
			
			|  |  |  | // EncodeTransportData(); | 
		
	
		
			
			|  |  |  | TransportDataHToN(&fSendTransportData,  &fSendTransportData); | 
		
	
		
			
			|  |  |  | //copy to TxBuffer | 
		
	
		
			
			|  |  |  | // copy to TxBuffer | 
		
	
		
			
			|  |  |  | memcpy(fTxData, &fSendTransportData, sizeof(net_transport_data_t)); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | //then others (freewheel etc.) | 
		
	
		
			
			|  |  |  | //... | 
		
	
		
			
			|  |  |  | // then others (freewheel etc.) | 
		
	
		
			
			|  |  |  | // ... | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | void JackNetMasterInterface::DecodeSyncPacket() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | //this method contains every step of sync packet informations decoding process | 
		
	
		
			
			|  |  |  | //first : transport | 
		
	
		
			
			|  |  |  | // This method contains every step of sync packet informations decoding process | 
		
	
		
			
			|  |  |  | // first : transport | 
		
	
		
			
			|  |  |  | if (fParams.fTransportSync) { | 
		
	
		
			
			|  |  |  | //copy received transport data to transport data structure | 
		
	
		
			
			|  |  |  | // copy received transport data to transport data structure | 
		
	
		
			
			|  |  |  | memcpy(&fReturnTransportData, fRxData, sizeof(net_transport_data_t)); | 
		
	
		
			
			|  |  |  | TransportDataNToH(&fReturnTransportData,  &fReturnTransportData); | 
		
	
		
			
			|  |  |  | // desactivated... | 
		
	
		
			
			|  |  |  | //DecodeTransportData(); | 
		
	
		
			
			|  |  |  | // DecodeTransportData(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | //then others | 
		
	
		
			
			|  |  |  | //... | 
		
	
		
			
			|  |  |  | // then others | 
		
	
		
			
			|  |  |  | // ... | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // JackNetSlaveInterface ************************************************************************************************ | 
		
	
	
		
			
				|  |  | @@ -566,15 +657,15 @@ namespace Jack | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | jack_log("JackNetSlaveInterface::Init()"); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //set the parameters to send | 
		
	
		
			
			|  |  |  | // set the parameters to send | 
		
	
		
			
			|  |  |  | strcpy(fParams.fPacketType, "params"); | 
		
	
		
			
			|  |  |  | fParams.fProtocolVersion = SLAVE_PROTOCOL; | 
		
	
		
			
			|  |  |  | SetPacketType(&fParams, SLAVE_AVAILABLE); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //init loop : get a master and start, do it until connection is ok | 
		
	
		
			
			|  |  |  | // init loop : get a master and start, do it until connection is ok | 
		
	
		
			
			|  |  |  | net_status_t status; | 
		
	
		
			
			|  |  |  | do { | 
		
	
		
			
			|  |  |  | //first, get a master, do it until a valid connection is running | 
		
	
		
			
			|  |  |  | // first, get a master, do it until a valid connection is running | 
		
	
		
			
			|  |  |  | do { | 
		
	
		
			
			|  |  |  | status = SendAvailableToMaster(); | 
		
	
		
			
			|  |  |  | if (status == NET_SOCKET_ERROR) | 
		
	
	
		
			
				|  |  | @@ -582,7 +673,7 @@ namespace Jack | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | while (status != NET_CONNECTED); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //then tell the master we are ready | 
		
	
		
			
			|  |  |  | // then tell the master we are ready | 
		
	
		
			
			|  |  |  | jack_info("Initializing connection with %s...", fParams.fMasterNetName); | 
		
	
		
			
			|  |  |  | status = SendStartToMaster(); | 
		
	
		
			
			|  |  |  | if (status == NET_ERROR) | 
		
	
	
		
			
				|  |  | @@ -597,16 +688,16 @@ namespace Jack | 
		
	
		
			
			|  |  |  | bool JackNetSlaveInterface::InitConnection(int time_out) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | jack_log("JackNetSlaveInterface::InitConnection()"); | 
		
	
		
			
			|  |  |  | unsigned int try_count = (time_out > 0) ? ((1000000 * time_out) / SLAVE_INIT_TIMEOUT) : LONG_MAX; | 
		
	
		
			
			|  |  |  | uint try_count = (time_out > 0) ? ((1000000 * time_out) / SLAVE_INIT_TIMEOUT) : LONG_MAX; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //set the parameters to send | 
		
	
		
			
			|  |  |  | // set the parameters to send | 
		
	
		
			
			|  |  |  | strcpy(fParams.fPacketType, "params"); | 
		
	
		
			
			|  |  |  | fParams.fProtocolVersion = SLAVE_PROTOCOL; | 
		
	
		
			
			|  |  |  | SetPacketType(&fParams, SLAVE_AVAILABLE); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | net_status_t status; | 
		
	
		
			
			|  |  |  | do { | 
		
	
		
			
			|  |  |  | //get a master | 
		
	
		
			
			|  |  |  | // get a master | 
		
	
		
			
			|  |  |  | status = SendAvailableToMaster(try_count); | 
		
	
		
			
			|  |  |  | if (status == NET_SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return false; | 
		
	
	
		
			
				|  |  | @@ -622,7 +713,7 @@ namespace Jack | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | net_status_t status; | 
		
	
		
			
			|  |  |  | do { | 
		
	
		
			
			|  |  |  | //then tell the master we are ready | 
		
	
		
			
			|  |  |  | // then tell the master we are ready | 
		
	
		
			
			|  |  |  | jack_info("Initializing connection with %s...", fParams.fMasterNetName); | 
		
	
		
			
			|  |  |  | status = SendStartToMaster(); | 
		
	
		
			
			|  |  |  | if (status == NET_ERROR) | 
		
	
	
		
			
				|  |  | @@ -636,41 +727,41 @@ namespace Jack | 
		
	
		
			
			|  |  |  | net_status_t JackNetSlaveInterface::SendAvailableToMaster(long try_count) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | jack_log("JackNetSlaveInterface::SendAvailableToMaster()"); | 
		
	
		
			
			|  |  |  | //utility | 
		
	
		
			
			|  |  |  | // utility | 
		
	
		
			
			|  |  |  | session_params_t host_params; | 
		
	
		
			
			|  |  |  | int rx_bytes = 0; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //socket | 
		
	
		
			
			|  |  |  | // socket | 
		
	
		
			
			|  |  |  | if (fSocket.NewSocket() == SOCKET_ERROR) { | 
		
	
		
			
			|  |  |  | jack_error("Fatal error : network unreachable - %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | return NET_SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //bind the socket | 
		
	
		
			
			|  |  |  | // bind the socket | 
		
	
		
			
			|  |  |  | if (fSocket.Bind() == SOCKET_ERROR) { | 
		
	
		
			
			|  |  |  | jack_error("Can't bind the socket : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | return NET_SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //timeout on receive | 
		
	
		
			
			|  |  |  | // timeout on receive | 
		
	
		
			
			|  |  |  | if (fSocket.SetTimeOut(SLAVE_INIT_TIMEOUT) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //disable local loop | 
		
	
		
			
			|  |  |  | // disable local loop | 
		
	
		
			
			|  |  |  | if (fSocket.SetLocalLoop() == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //send 'AVAILABLE' until 'SLAVE_SETUP' received | 
		
	
		
			
			|  |  |  | // send 'AVAILABLE' until 'SLAVE_SETUP' received | 
		
	
		
			
			|  |  |  | jack_info("Waiting for a master..."); | 
		
	
		
			
			|  |  |  | do { | 
		
	
		
			
			|  |  |  | //send 'available' | 
		
	
		
			
			|  |  |  | // send 'available' | 
		
	
		
			
			|  |  |  | session_params_t net_params; | 
		
	
		
			
			|  |  |  | memset(&net_params, 0, sizeof(session_params_t)); | 
		
	
		
			
			|  |  |  | SessionParamsHToN(&fParams, &net_params); | 
		
	
		
			
			|  |  |  | if (fSocket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | jack_error("Error in data send : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //filter incoming packets : don't exit while no error is detected | 
		
	
		
			
			|  |  |  | // filter incoming packets : don't exit while no error is detected | 
		
	
		
			
			|  |  |  | memset(&net_params, 0, sizeof(session_params_t)); | 
		
	
		
			
			|  |  |  | rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0); | 
		
	
		
			
			|  |  |  | SessionParamsNToH(&net_params, &host_params); | 
		
	
	
		
			
				|  |  | @@ -687,10 +778,10 @@ namespace Jack | 
		
	
		
			
			|  |  |  | return NET_CONNECT_ERROR; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //everything is OK, copy parameters | 
		
	
		
			
			|  |  |  | // everything is OK, copy parameters | 
		
	
		
			
			|  |  |  | fParams = host_params; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //connect the socket | 
		
	
		
			
			|  |  |  | // connect the socket | 
		
	
		
			
			|  |  |  | if (fSocket.Connect() == SOCKET_ERROR) { | 
		
	
		
			
			|  |  |  | jack_error("Error in connect : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | return NET_CONNECT_ERROR; | 
		
	
	
		
			
				|  |  | @@ -702,7 +793,7 @@ namespace Jack | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | jack_log("JackNetSlaveInterface::SendStartToMaster"); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //tell the master to start | 
		
	
		
			
			|  |  |  | // tell the master to start | 
		
	
		
			
			|  |  |  | session_params_t net_params; | 
		
	
		
			
			|  |  |  | memset(&net_params, 0, sizeof(session_params_t)); | 
		
	
		
			
			|  |  |  | SetPacketType(&fParams, START_MASTER); | 
		
	
	
		
			
				|  |  | @@ -724,7 +815,7 @@ namespace Jack | 
		
	
		
			
			|  |  |  | fTxHeader.fDataStream = 'r'; | 
		
	
		
			
			|  |  |  | fRxHeader.fDataStream = 's'; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //midi net buffers | 
		
	
		
			
			|  |  |  | // midi net buffers | 
		
	
		
			
			|  |  |  | if (fParams.fSendMidiChannels > 0) | 
		
	
		
			
			|  |  |  | fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fRxData); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -733,7 +824,7 @@ namespace Jack | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | try { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //audio net buffers | 
		
	
		
			
			|  |  |  | // audio net buffers | 
		
	
		
			
			|  |  |  | if (fParams.fSendAudioChannels > 0) { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | switch (fParams.fSampleEncoder) { | 
		
	
	
		
			
				|  |  | @@ -783,7 +874,7 @@ namespace Jack | 
		
	
		
			
			|  |  |  | return false; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //set the new buffer sizes | 
		
	
		
			
			|  |  |  | // set the new buffer sizes | 
		
	
		
			
			|  |  |  | if (SetNetBufferSize() == SOCKET_ERROR) { | 
		
	
		
			
			|  |  |  | jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE)); | 
		
	
		
			
			|  |  |  | goto error; | 
		
	
	
		
			
				|  |  | @@ -799,14 +890,14 @@ namespace Jack | 
		
	
		
			
			|  |  |  | int JackNetSlaveInterface::Recv(size_t size, int flags) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | int rx_bytes = fSocket.Recv(fRxBuffer, size, flags); | 
		
	
		
			
			|  |  |  | //handle errors | 
		
	
		
			
			|  |  |  | // handle errors | 
		
	
		
			
			|  |  |  | if (rx_bytes == SOCKET_ERROR) { | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | net_error_t error = fSocket.GetError(); | 
		
	
		
			
			|  |  |  | //no data isn't really an error in realtime processing, so just return 0 | 
		
	
		
			
			|  |  |  | // no data isn't really an error in realtime processing, so just return 0 | 
		
	
		
			
			|  |  |  | if (error == NET_NO_DATA) { | 
		
	
		
			
			|  |  |  | jack_error("No data, is the master still running ?"); | 
		
	
		
			
			|  |  |  | //if a network error occurs, this exception will restart the driver | 
		
	
		
			
			|  |  |  | // if a network error occurs, this exception will restart the driver | 
		
	
		
			
			|  |  |  | } else if (error == NET_CONN_ERROR) { | 
		
	
		
			
			|  |  |  | FatalError(); | 
		
	
		
			
			|  |  |  | } else { | 
		
	
	
		
			
				|  |  | @@ -833,11 +924,11 @@ namespace Jack | 
		
	
		
			
			|  |  |  | PacketHeaderHToN(header, header); | 
		
	
		
			
			|  |  |  | int tx_bytes = fSocket.Send(fTxBuffer, size, flags); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //handle errors | 
		
	
		
			
			|  |  |  | // handle errors | 
		
	
		
			
			|  |  |  | if (tx_bytes == SOCKET_ERROR) { | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | net_error_t error = fSocket.GetError(); | 
		
	
		
			
			|  |  |  | //if a network error occurs, this exception will restart the driver | 
		
	
		
			
			|  |  |  | // if a network error occurs, this exception will restart the driver | 
		
	
		
			
			|  |  |  | if (error == NET_CONN_ERROR) { | 
		
	
		
			
			|  |  |  | FatalError(); | 
		
	
		
			
			|  |  |  | } else { | 
		
	
	
		
			
				|  |  | @@ -854,10 +945,10 @@ namespace Jack | 
		
	
		
			
			|  |  |  | int rx_bytes = 0; | 
		
	
		
			
			|  |  |  | packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //receive sync (launch the cycle) | 
		
	
		
			
			|  |  |  | // receive sync (launch the cycle) | 
		
	
		
			
			|  |  |  | do { | 
		
	
		
			
			|  |  |  | rx_bytes = Recv(fParams.fMtu, 0); | 
		
	
		
			
			|  |  |  | //connection issue, send will detect it, so don't skip the cycle (return 0) | 
		
	
		
			
			|  |  |  | // connection issue, send will detect it, so don't skip the cycle (return 0) | 
		
	
		
			
			|  |  |  | if (rx_bytes == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return rx_bytes; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -878,17 +969,19 @@ namespace Jack | 
		
	
		
			
			|  |  |  | packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | while (!fRxHeader.fIsLastPckt) { | 
		
	
		
			
			|  |  |  | //how much data is queued on the rx buffer ? | 
		
	
		
			
			|  |  |  | // how much data is queued on the rx buffer ? | 
		
	
		
			
			|  |  |  | rx_bytes = Recv(fParams.fMtu, MSG_PEEK); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //error here, problem with recv, just skip the cycle (return -1) | 
		
	
		
			
			|  |  |  | // error here, problem with recv, just skip the cycle (return -1) | 
		
	
		
			
			|  |  |  | if (rx_bytes == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return rx_bytes; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (rx_bytes && (rx_head->fDataStream == 's') && (rx_head->fID == fParams.fID)) { | 
		
	
		
			
			|  |  |  | switch (rx_head->fDataType) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | case 'm':   //midi | 
		
	
		
			
			|  |  |  | // read data | 
		
	
		
			
			|  |  |  | switch (rx_head->fDataType) { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | case 'm':   // midi | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | rx_bytes = Recv(rx_head->fPacketSize, 0); | 
		
	
		
			
			|  |  |  | fRxHeader.fCycle = rx_head->fCycle; | 
		
	
		
			
			|  |  |  | fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | 
		
	
	
		
			
				|  |  | @@ -896,9 +989,12 @@ namespace Jack | 
		
	
		
			
			|  |  |  | // Last midi packet is received, so finish rendering... | 
		
	
		
			
			|  |  |  | if (++recvd_midi_pckt == rx_head->fNumPacket) | 
		
	
		
			
			|  |  |  | fNetMidiCaptureBuffer->RenderToJackPorts(); | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | rx_bytes = MidiRecv(rx_head, fNetMidiCaptureBuffer, recvd_midi_pckt); | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | case 'a':   //audio | 
		
	
		
			
			|  |  |  | case 'a':   // audio | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | rx_bytes = Recv(rx_head->fPacketSize, 0); | 
		
	
		
			
			|  |  |  | fRxHeader.fCycle = rx_head->fCycle; | 
		
	
		
			
			|  |  |  | fRxHeader.fSubCycle = rx_head->fSubCycle; | 
		
	
	
		
			
				|  |  | @@ -908,13 +1004,18 @@ namespace Jack | 
		
	
		
			
			|  |  |  | // Last audio packet is received, so finish rendering... | 
		
	
		
			
			|  |  |  | if (fRxHeader.fIsLastPckt) | 
		
	
		
			
			|  |  |  | fNetAudioCaptureBuffer->RenderToJackPorts(); | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | rx_bytes = AudioRecv(rx_head, fNetAudioCaptureBuffer); | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | case 's':   //sync | 
		
	
		
			
			|  |  |  | case 's':   // sync | 
		
	
		
			
			|  |  |  | jack_info("NetSlave : overloaded, skipping receive"); | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | // TODO : finish midi and audio rendering ? | 
		
	
		
			
			|  |  |  | fNetAudioCaptureBuffer->RenderToJackPorts(); | 
		
	
		
			
			|  |  |  | return NET_PACKET_ERROR; | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | return FinishRecv(fNetAudioCaptureBuffer); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -925,7 +1026,7 @@ namespace Jack | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int JackNetSlaveInterface::SyncSend() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | //tx header | 
		
	
		
			
			|  |  |  | // tx header | 
		
	
		
			
			|  |  |  | if (fParams.fSlaveSyncMode) { | 
		
	
		
			
			|  |  |  | fTxHeader.fCycle = fRxHeader.fCycle; | 
		
	
		
			
			|  |  |  | } else { | 
		
	
	
		
			
				|  |  | @@ -941,33 +1042,39 @@ namespace Jack | 
		
	
		
			
			|  |  |  | fNetAudioCaptureBuffer->ActivePortsToNetwork(fTxData, fTxHeader.fActivePorts); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); | 
		
	
		
			
			|  |  |  | // PacketHeaderDisplay(&fTxHeader); | 
		
	
		
			
			|  |  |  | return Send(fTxHeader.fPacketSize, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int JackNetSlaveInterface::DataSend() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | uint subproc, data_size; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //midi | 
		
	
		
			
			|  |  |  | // midi | 
		
	
		
			
			|  |  |  | if (fParams.fReturnMidiChannels > 0) { | 
		
	
		
			
			|  |  |  | //set global header fields and get the number of midi packets | 
		
	
		
			
			|  |  |  | // set global header fields and get the number of midi packets | 
		
	
		
			
			|  |  |  | fTxHeader.fDataType = 'm'; | 
		
	
		
			
			|  |  |  | data_size = fNetMidiPlaybackBuffer->RenderFromJackPorts(); | 
		
	
		
			
			|  |  |  | fTxHeader.fNumPacket = fNetMidiPlaybackBuffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) { | 
		
	
		
			
			|  |  |  | fTxHeader.fSubCycle = subproc; | 
		
	
		
			
			|  |  |  | fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0; | 
		
	
		
			
			|  |  |  | // fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0; | 
		
	
		
			
			|  |  |  | fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && fParams.fReturnAudioChannels == 0) ? 1 : 0; | 
		
	
		
			
			|  |  |  | fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, data_size); | 
		
	
		
			
			|  |  |  | memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); | 
		
	
		
			
			|  |  |  | if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | if (MidiSend(fNetMidiPlaybackBuffer, fParams.fReturnMidiChannels, fParams.fReturnAudioChannels) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //audio | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | // audio | 
		
	
		
			
			|  |  |  | if (fParams.fReturnAudioChannels > 0) { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | fTxHeader.fDataType = 'a'; | 
		
	
		
			
			|  |  |  | fNetAudioPlaybackBuffer->RenderFromJackPorts(); | 
		
	
		
			
			|  |  |  | fTxHeader.fNumPacket = fNetAudioPlaybackBuffer->GetNumPackets(); | 
		
	
	
		
			
				|  |  | @@ -977,45 +1084,48 @@ namespace Jack | 
		
	
		
			
			|  |  |  | fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0; | 
		
	
		
			
			|  |  |  | fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->RenderToNetwork(subproc, fTxHeader.fActivePorts); | 
		
	
		
			
			|  |  |  | memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); | 
		
	
		
			
			|  |  |  | //PacketHeaderDisplay(&fTxHeader); | 
		
	
		
			
			|  |  |  | // PacketHeaderDisplay(&fTxHeader); | 
		
	
		
			
			|  |  |  | if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) | 
		
	
		
			
			|  |  |  | return SOCKET_ERROR; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return AudioSend(fNetAudioPlaybackBuffer, fParams.fReturnAudioChannels); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //network sync------------------------------------------------------------------------ | 
		
	
		
			
			|  |  |  | // network sync------------------------------------------------------------------------ | 
		
	
		
			
			|  |  |  | void JackNetSlaveInterface::EncodeSyncPacket() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | //this method contains every step of sync packet informations coding | 
		
	
		
			
			|  |  |  | //first of all, reset sync packet | 
		
	
		
			
			|  |  |  | // This method contains every step of sync packet informations coding | 
		
	
		
			
			|  |  |  | // first of all, reset sync packet | 
		
	
		
			
			|  |  |  | memset(fTxData, 0, PACKET_AVAILABLE_SIZE); | 
		
	
		
			
			|  |  |  | //then first step : transport | 
		
	
		
			
			|  |  |  | // then first step : transport | 
		
	
		
			
			|  |  |  | if (fParams.fTransportSync) { | 
		
	
		
			
			|  |  |  | // desactivated... | 
		
	
		
			
			|  |  |  | //EncodeTransportData(); | 
		
	
		
			
			|  |  |  | // EncodeTransportData(); | 
		
	
		
			
			|  |  |  | TransportDataHToN(&fReturnTransportData,  &fReturnTransportData); | 
		
	
		
			
			|  |  |  | //copy to TxBuffer | 
		
	
		
			
			|  |  |  | // copy to TxBuffer | 
		
	
		
			
			|  |  |  | memcpy(fTxData, &fReturnTransportData, sizeof(net_transport_data_t)); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | //then others | 
		
	
		
			
			|  |  |  | //... | 
		
	
		
			
			|  |  |  | // then others | 
		
	
		
			
			|  |  |  | // ... | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | void JackNetSlaveInterface::DecodeSyncPacket() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | //this method contains every step of sync packet informations decoding process | 
		
	
		
			
			|  |  |  | //first : transport | 
		
	
		
			
			|  |  |  | // This method contains every step of sync packet informations decoding process | 
		
	
		
			
			|  |  |  | // first : transport | 
		
	
		
			
			|  |  |  | if (fParams.fTransportSync) { | 
		
	
		
			
			|  |  |  | //copy received transport data to transport data structure | 
		
	
		
			
			|  |  |  | // copy received transport data to transport data structure | 
		
	
		
			
			|  |  |  | memcpy(&fSendTransportData, fRxData, sizeof(net_transport_data_t)); | 
		
	
		
			
			|  |  |  | TransportDataNToH(&fSendTransportData,  &fSendTransportData); | 
		
	
		
			
			|  |  |  | // desactivated... | 
		
	
		
			
			|  |  |  | //DecodeTransportData(); | 
		
	
		
			
			|  |  |  | // DecodeTransportData(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | //then others | 
		
	
		
			
			|  |  |  | //... | 
		
	
		
			
			|  |  |  | // then others | 
		
	
		
			
			|  |  |  | // ... | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | } |