From e7239f09254bcbf38c6b637065a2a609633f8ba7 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Mon, 25 Mar 2013 15:13:27 +0100 Subject: [PATCH] Cleanup netjack2 code (in progress). --- common/JackNetAPI.cpp | 69 +++++++++++++++---- common/JackNetAdapter.cpp | 20 ++++++ common/JackNetDriver.cpp | 41 ++++++++--- common/JackNetInterface.cpp | 18 ++--- common/JackNetManager.cpp | 37 +++++++++- .../coremidi/JackCoreMidiVirtualInputPort.cpp | 9 +++ .../JackCoreMidiVirtualOutputPort.cpp | 9 +++ posix/JackNetUnixSocket.cpp | 4 +- 8 files changed, 174 insertions(+), 33 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 1ccc814e..4ffd3bb5 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -369,29 +369,33 @@ struct JackNetExtMaster : public JackNetMasterInterface { void FreePorts() { if (fAudioPlaybackBuffer) { - for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) + for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) { delete[] fAudioPlaybackBuffer[audio_port_index]; + } delete[] fAudioPlaybackBuffer; fAudioPlaybackBuffer = NULL; } if (fMidiPlaybackBuffer) { - for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) + for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { delete[] (fMidiPlaybackBuffer[midi_port_index]); + } delete[] fMidiPlaybackBuffer; fMidiPlaybackBuffer = NULL; } if (fAudioCaptureBuffer) { - for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) + for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) { delete[] fAudioCaptureBuffer[audio_port_index]; + } delete[] fAudioCaptureBuffer; fAudioCaptureBuffer = NULL; } if (fMidiCaptureBuffer) { - for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) + for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { delete[] fMidiCaptureBuffer[midi_port_index]; + } delete[] fMidiCaptureBuffer; fMidiCaptureBuffer = NULL; } @@ -399,7 +403,6 @@ struct JackNetExtMaster : public JackNetMasterInterface { int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) { - try { assert(audio_input == fParams.fReturnAudioChannels); @@ -412,23 +415,44 @@ struct JackNetExtMaster : public JackNetMasterInterface { fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_input_buffer)[midi_port_index]); } + /* + // TODO : use with netmaster/netdriver code //receive sync int res = SyncRecv(); if ((res == 0) || (res == SOCKET_ERROR)) { return res; } - + DecodeSyncPacket(); + */ + + int res = SyncRecv(); + switch (res) { + + case 0: + case SOCKET_ERROR: + return res; + + case NET_PACKET_ERROR: + // Since sync packet is incorrect, don't decode it and continue with data + break; + + default: + //decode sync + DecodeSyncPacket(); + break; + } + return DataRecv(); } catch (JackNetException& e) { - jack_error("Connection lost."); + jack_error("Lost connection"); return -1; } - } + } - int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) - { + int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) + { try { assert(audio_output == fParams.fSendAudioChannels); @@ -441,11 +465,11 @@ struct JackNetExtMaster : public JackNetMasterInterface { fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]); } - if (IsSynched()) { // only send if connection is "synched" EncodeSyncPacket(); + // send sync if (SyncSend() == SOCKET_ERROR) { return SOCKET_ERROR; } @@ -462,7 +486,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { return 0; } catch (JackNetException& e) { - jack_error("Connection lost."); + jack_error("Lost connection"); return -1; } } @@ -749,13 +773,34 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf int Read() { + // TODO : use with netmaster/netdriver code //receive sync (launch the cycle) + /* if (SyncRecv() == SOCKET_ERROR) { return SOCKET_ERROR; } DecodeSyncPacket(); return DataRecv(); + */ + + switch (SyncRecv()) { + + case SOCKET_ERROR: + return SOCKET_ERROR; + + case NET_PACKET_ERROR: + // Since sync packet is incorrect, don't decode it and continue with data + break; + + default: + //decode sync + //if there is an error, don't return -1, it will skip Write() and the network error probably won't be identified + DecodeSyncPacket(); + break; + } + + return DataRecv(); } int Write() diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 9be9aac3..a88a20f3 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -351,11 +351,31 @@ namespace Jack { //don't return -1 in case of sync recv failure //we need the process to continue for network error detection + /* if (SyncRecv() == SOCKET_ERROR) { return 0; } DecodeSyncPacket(); + */ + + //don't return -1 in case of sync recv failure + //we need the process to continue for network error detection + switch (SyncRecv()) { + + case SOCKET_ERROR: + return 0; + + case NET_PACKET_ERROR: + // Since sync packet is incorrect, don't decode it and continue with data + break; + + default: + //decode sync + DecodeSyncPacket(); + break; + } + return DataRecv(); } diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index d2269e5b..732b8462 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -507,10 +507,25 @@ namespace Jack fNetTimeMon->New(); #endif - //receive sync (launch the cycle) + switch (SyncRecv()) { + + case SOCKET_ERROR: + return SOCKET_ERROR; + + case NET_PACKET_ERROR: + // Since sync packet is incorrect, don't decode it and continue with data + break; + + default: + //decode sync + DecodeSyncPacket(); + break; + } + /* if (SyncRecv() == SOCKET_ERROR) { return SOCKET_ERROR; } + */ #ifdef JACK_MONITOR // For timing @@ -519,19 +534,30 @@ namespace Jack //decode sync //if there is an error, don't return -1, it will skip Write() and the network error probably won't be identified - DecodeSyncPacket(); + //DecodeSyncPacket(); #ifdef JACK_MONITOR fNetTimeMon->Add(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f); #endif //audio, midi or sync if driver is late - int res = DataRecv(); + switch (DataRecv()) { + + case SOCKET_ERROR: + return SOCKET_ERROR; + + case NET_PACKET_ERROR: + jack_time_t cur_time = GetMicroSeconds(); + NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... + break; + } + /* if (res == SOCKET_ERROR) { return SOCKET_ERROR; } else if (res == NET_PACKET_ERROR) { jack_time_t cur_time = GetMicroSeconds(); NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... } + */ //take the time at the beginning of the cycle JackDriver::CycleTakeBeginTime(); @@ -553,12 +579,9 @@ namespace Jack for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) { #ifdef OPTIMIZED_PROTOCOL // Port is connected on other side... - if (fNetAudioPlaybackBuffer->GetConnected(audio_port_index)) { - if (fGraphManager->GetConnectionsNum(fPlaybackPortList[audio_port_index]) > 0) { - fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index)); - } else { - fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL); - } + if (fNetAudioPlaybackBuffer->GetConnected(audio_port_index) + && (fGraphManager->GetConnectionsNum(fPlaybackPortList[audio_port_index]) > 0)) { + fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index)); } else { fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL); } diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 9f2cba0f..b8f4c380 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -381,7 +381,7 @@ namespace Jack fRunning = false; // send a 'multicast euthanasia request' - new socket is required on macosx - jack_info("Exiting '%s'", fParams.fName); + jack_info("Exiting '%s' %s", fParams.fName, fMulticastIP); SetPacketType(&fParams, KILL_MASTER); JackNetSocket mcast_socket(fMulticastIP, fSocket.GetPort()); @@ -488,8 +488,8 @@ namespace Jack while (strcmp(rx_head->fPacketType, "header") != 0); if (rx_head->fDataType != 's') { - jack_error("Wrong packet type : %c\n", rx_head->fDataType); - return -1; + jack_error("Wrong packet type : %c", rx_head->fDataType); + return NET_PACKET_ERROR; } fCurrentCycleOffset = fTxHeader.fCycle - rx_head->fCycle; @@ -532,7 +532,7 @@ namespace Jack break; case 's': // sync - jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName); + jack_info("NetMaster : missing last data packet from '%s'", fParams.fName); return FinishRecv(fNetAudioPlaybackBuffer); } } @@ -866,7 +866,7 @@ namespace Jack // 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 (return -1) if (rx_bytes == SOCKET_ERROR) { return rx_bytes; } @@ -874,8 +874,8 @@ namespace Jack while (strcmp(rx_head->fPacketType, "header") != 0); if (rx_head->fDataType != 's') { - jack_error("Wrong packet type : %c\n", rx_head->fDataType); - return -1; + jack_error("Wrong packet type : %c", rx_head->fDataType); + return NET_PACKET_ERROR; } fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; @@ -894,7 +894,7 @@ namespace Jack // 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, just skip the cycle (return -1) if (rx_bytes == SOCKET_ERROR) { return rx_bytes; } @@ -912,7 +912,7 @@ namespace Jack break; case 's': // sync - jack_info("NetSlave : overloaded, skipping receive"); + jack_info("NetSlave : missing last data packet"); return FinishRecv(fNetAudioCaptureBuffer); } } diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index cab14cd4..d9ae5de9 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -510,19 +510,39 @@ namespace Jack } //receive sync + /* int res = SyncRecv(); if ((res == 0) || (res == SOCKET_ERROR)) { return res; } + */ + + int res = SyncRecv(); + switch (res) { + + case 0: + case SOCKET_ERROR: + return res; + + case NET_PACKET_ERROR: + // Since sync packet is incorrect, don't decode it and continue with data + break; + + default: + //decode sync + DecodeSyncPacket(); + break; + } #ifdef JACK_MONITOR fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f); #endif //decode sync - DecodeSyncPacket(); + //DecodeSyncPacket(); //receive data + /* res = DataRecv(); if ((res == 0) || (res == SOCKET_ERROR)) { return res; @@ -530,6 +550,21 @@ namespace Jack // Well not a real XRun... JackServerGlobals::fInstance->GetEngine()->NotifyClientXRun(ALL_CLIENTS); } + */ + + //receive data + res = DataRecv(); + switch (res) { + + case 0: + case SOCKET_ERROR: + return res; + + case NET_PACKET_ERROR: + // Well not a real XRun... + JackServerGlobals::fInstance->GetEngine()->NotifyClientXRun(ALL_CLIENTS); + break; + } #ifdef JACK_MONITOR fNetTimeMon->AddLast((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f); diff --git a/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp index 111fbafb..ab6ada4c 100644 --- a/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp @@ -59,6 +59,15 @@ JackCoreMidiVirtualInputPort(const char *alias_name, const char *client_name, MIDIEndpointRef destination; OSStatus status = MIDIDestinationCreate(client, name, HandleInputEvent, this, &destination); + + /* + SInt32 value; + status = MIDIObjectGetIntegerProperty(destination, kMIDIPropertyUniqueID, &value); + if (status == noErr) { + jack_info("kMIDIPropertyUniqueID %d", value); + } + */ + CFRelease(name); if (status != noErr) { throw std::runtime_error(GetMacOSErrorString(status)); diff --git a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp index 69ead9d2..e2cef747 100644 --- a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp @@ -44,6 +44,15 @@ JackCoreMidiVirtualOutputPort(const char *alias_name, const char *client_name, } MIDIEndpointRef source; OSStatus status = MIDISourceCreate(client, name, &source); + + /* + SInt32 value; + status = MIDIObjectGetIntegerProperty(source, kMIDIPropertyUniqueID, &value); + if (status == noErr) { + jack_info("kMIDIPropertyUniqueID %d", value); + } + */ + CFRelease(name); if (status != noErr) { throw std::runtime_error(GetMacOSErrorString(status)); diff --git a/posix/JackNetUnixSocket.cpp b/posix/JackNetUnixSocket.cpp index f4a1b942..30ef62ac 100644 --- a/posix/JackNetUnixSocket.cpp +++ b/posix/JackNetUnixSocket.cpp @@ -335,12 +335,12 @@ namespace Jack jack_log("JackNetUnixSocket::SetTimeout %d usecs", us); struct timeval timeout; - //less than 1sec + //less than 1 sec if (us < 1000000) { timeout.tv_sec = 0; timeout.tv_usec = us; } else { - //more than 1sec + //more than 1 sec float sec = float(us) / 1000000.f; timeout.tv_sec = (int)sec; float usec = (sec - float(timeout.tv_sec)) * 1000000;