From 77d9ded01c30fdf482ad3c5810716429e36bf605 Mon Sep 17 00:00:00 2001 From: moret Date: Thu, 21 Aug 2008 13:40:30 +0000 Subject: [PATCH] Correct NetAdapter restart git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2793 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAdapter.cpp | 185 ++++++++++++++++++++--------------- common/JackNetAdapter.h | 4 + common/JackNetSocket.h | 28 +++--- common/JackNetTool.h | 2 +- windows/JackNetWinSocket.cpp | 2 +- 5 files changed, 125 insertions(+), 96 deletions(-) diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index f0dd8380..15cce024 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -60,43 +60,43 @@ namespace Jack param = ( const jack_driver_param_t* ) node->data; switch ( param->character ) { - case 'a' : - if ( strlen ( param->value.str ) < 16 ) - strcpy ( fMulticastIP, param->value.str ); - else - jack_error ( "Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP ); - break; - case 'p' : - fSocket.SetPort ( param->value.ui ); - break; - case 'M' : - fParams.fMtu = param->value.i; - break; - case 'C' : - fParams.fSendAudioChannels = param->value.i; - break; - case 'P' : - fParams.fReturnAudioChannels = param->value.i; - break; - case 'n' : - strncpy ( fParams.fName, param->value.str, JACK_CLIENT_NAME_SIZE ); - break; - case 't' : - fParams.fTransportSync = param->value.ui; - break; - case 'm' : - if ( strcmp ( param->value.str, "normal" ) == 0 ) - fParams.fNetworkMode = 'n'; - else if ( strcmp ( param->value.str, "slow" ) == 0 ) - fParams.fNetworkMode = 's'; - else if ( strcmp ( param->value.str, "fast" ) == 0 ) - fParams.fNetworkMode = 'f'; - else - jack_error ( "Unknown network mode, using 'normal' mode." ); - break; - case 'S' : - fParams.fSlaveSyncMode = 1; - break; + case 'a' : + if ( strlen ( param->value.str ) < 16 ) + strcpy ( fMulticastIP, param->value.str ); + else + jack_error ( "Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP ); + break; + case 'p' : + fSocket.SetPort ( param->value.ui ); + break; + case 'M' : + fParams.fMtu = param->value.i; + break; + case 'C' : + fParams.fSendAudioChannels = param->value.i; + break; + case 'P' : + fParams.fReturnAudioChannels = param->value.i; + break; + case 'n' : + strncpy ( fParams.fName, param->value.str, JACK_CLIENT_NAME_SIZE ); + break; + case 't' : + fParams.fTransportSync = param->value.ui; + break; + case 'm' : + if ( strcmp ( param->value.str, "normal" ) == 0 ) + fParams.fNetworkMode = 'n'; + else if ( strcmp ( param->value.str, "slow" ) == 0 ) + fParams.fNetworkMode = 's'; + else if ( strcmp ( param->value.str, "fast" ) == 0 ) + fParams.fNetworkMode = 'f'; + else + jack_error ( "Unknown network mode, using 'normal' mode." ); + break; + case 'S' : + fParams.fSlaveSyncMode = 1; + break; } } @@ -113,13 +113,16 @@ namespace Jack JackNetAdapter::~JackNetAdapter() { jack_log ( "JackNetAdapter::~JackNetAdapter" ); + int port_index; - if (fSoftCaptureBuffer) { + if ( fSoftCaptureBuffer ) + { for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) delete[] fSoftCaptureBuffer[port_index]; delete[] fSoftCaptureBuffer; } - if (fSoftPlaybackBuffer) { + if ( fSoftPlaybackBuffer ) + { for ( port_index = 0; port_index < fPlaybackChannels; port_index++ ) delete[] fSoftPlaybackBuffer[port_index]; delete[] fSoftPlaybackBuffer; @@ -129,43 +132,46 @@ namespace Jack int JackNetAdapter::Open() { jack_log ( "JackNetAdapter::Open" ); + jack_info ( "Net adapter started in %s mode %s Master's transport sync.", ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" ); - if (fThread.StartSync() < 0) { - jack_error("Cannot start netadapter thread"); + if ( fThread.StartSync() < 0 ) + { + jack_error ( "Cannot start netadapter thread" ); return -1; } - - fThread.AcquireRealTime(JackServer::fInstance->GetEngineControl()->fPriority); + + fThread.AcquireRealTime ( JackServer::fInstance->GetEngineControl()->fPriority - 1 ); return 0; - } + } int JackNetAdapter::Close() { - switch (fThread.GetStatus()) { - - // Kill the thread in Init phase + jack_log ( "JackNetAdapter::Close" ); + + switch ( fThread.GetStatus() ) + { + // Kill the thread in Init phase case JackThread::kStarting: case JackThread::kIniting: - if (fThread.Kill() < 0) { - jack_error("Cannot kill thread"); + if ( fThread.Kill() < 0 ) + { + jack_error ( "Cannot kill thread" ); return -1; } break; - - // Stop when the thread cycle is finished + // Stop when the thread cycle is finished case JackThread::kRunning: - if (fThread.Stop() < 0) { - jack_error("Cannot stop thread"); + if ( fThread.Stop() < 0 ) + { + jack_error ( "Cannot stop thread" ); return -1; } break; - default: break; } - fSocket.Close(); return 0; } @@ -224,7 +230,7 @@ namespace Jack e.PrintMessage(); jack_log ( "NetAdapter is restarted." ); fThread.DropRealTime(); - fThread.SetStatus(JackThread::kIniting); + fThread.SetStatus ( JackThread::kIniting ); if ( Init() ) { fThread.SetStatus ( JackThread::kRunning ); @@ -235,44 +241,63 @@ namespace Jack } } - int JackNetAdapter::Process() + int JackNetAdapter::Read() { - bool failure = false; - int port_index; - - //receive if ( SyncRecv() == SOCKET_ERROR ) return 0; - if ( DataRecv() == SOCKET_ERROR ) + return DataRecv(); + } + + int JackNetAdapter::Write() + { + if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; - //resample - jack_nframes_t time1, time2; - ResampleFactor ( time1, time2 ); + return DataSend(); + } + int JackNetAdapter::Process() + { + bool failure = false; + int port_index; + int rx_bytes, tx_bytes; - for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) - { - fCaptureRingBuffer[port_index]->SetRatio ( time1, time2 ); - if ( fCaptureRingBuffer[port_index]->WriteResample ( fSoftCaptureBuffer[port_index], fBufferSize ) < fBufferSize ) - failure = true; - } + //read data from the network + //in case of fatal network error, definitely stop the process + rx_bytes = Read(); + if ( rx_bytes == SOCKET_ERROR ) + return SOCKET_ERROR; - for ( port_index = 0; port_index < fPlaybackChannels; port_index++ ) + //if there is data to resample, + if ( rx_bytes ) { - fPlaybackRingBuffer[port_index]->SetRatio ( time2, time1 ); - if ( fPlaybackRingBuffer[port_index]->ReadResample ( fSoftPlaybackBuffer[port_index], fBufferSize ) < fBufferSize ) - failure = true; - } + //get the resample factor, + jack_nframes_t time1, time2; + ResampleFactor ( time1, time2 ); - //send - if ( SyncSend() == SOCKET_ERROR ) - return SOCKET_ERROR; + //resample input data, + for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) + { + fCaptureRingBuffer[port_index]->SetRatio ( time1, time2 ); + if ( fCaptureRingBuffer[port_index]->WriteResample ( fSoftCaptureBuffer[port_index], fBufferSize ) < fBufferSize ) + failure = true; + } + //and output data, + for ( port_index = 0; port_index < fPlaybackChannels; port_index++ ) + { + fPlaybackRingBuffer[port_index]->SetRatio ( time2, time1 ); + if ( fPlaybackRingBuffer[port_index]->ReadResample ( fSoftPlaybackBuffer[port_index], fBufferSize ) < fBufferSize ) + failure = true; + } + } - if ( DataSend() == SOCKET_ERROR ) + //then write data to network + //in case of failure, definitely stop process + if ( Write() == SOCKET_ERROR ) return SOCKET_ERROR; + //if there was any ringbuffer failure during resampling, reset if ( failure ) { jack_error ( "JackNetAdapter::Execute ringbuffer failure...reset." ); diff --git a/common/JackNetAdapter.h b/common/JackNetAdapter.h index 50069093..4faa4474 100644 --- a/common/JackNetAdapter.h +++ b/common/JackNetAdapter.h @@ -42,6 +42,7 @@ namespace Jack sample_t** fSoftCaptureBuffer; sample_t** fSoftPlaybackBuffer; + //adapter thread JackThread fThread; public: @@ -57,6 +58,9 @@ namespace Jack bool Init(); bool Execute(); + int Read(); + int Write(); + int Process(); }; } diff --git a/common/JackNetSocket.h b/common/JackNetSocket.h index 5a095b08..b7f7f3d5 100644 --- a/common/JackNetSocket.h +++ b/common/JackNetSocket.h @@ -29,20 +29,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { - //get host name********************************* - EXPORT int GetHostName ( char * name, int size ); - - //net errors *********************************** - enum _net_error - { - NET_CONN_ERROR = 10000, - NET_OP_ERROR, - NET_NO_DATA, - NET_NO_NETWORK, - NET_NO_ERROR - }; - - typedef enum _net_error net_error_t; + //get host name********************************* + EXPORT int GetHostName ( char * name, int size ); + + //net errors *********************************** + enum _net_error + { + NET_CONN_ERROR = 10000, + NET_OP_ERROR, + NET_NO_DATA, + NET_NO_NETWORK, + NET_NO_ERROR + }; + + typedef enum _net_error net_error_t; } #endif diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 7155521b..51fac4e1 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -70,7 +70,7 @@ namespace Jack uint32_t fPeriodSize; //period size uint32_t fFramesPerPacket; //complete frames per packet uint32_t fBitdepth; //samples bitdepth (unused) - uint32_t fSlaveSyncMode; //is the slave in sync mode ? + uint32_t fSlaveSyncMode; //is the slave in sync mode ? char fNetworkMode; //fast, normal or slow mode }; diff --git a/windows/JackNetWinSocket.cpp b/windows/JackNetWinSocket.cpp index e8a64779..40042fa0 100644 --- a/windows/JackNetWinSocket.cpp +++ b/windows/JackNetWinSocket.cpp @@ -278,7 +278,7 @@ namespace Jack //tiemout************************************************************************************************************ int JackNetWinSocket::SetTimeOut ( int usec ) { - jack_log ( "JackNetWinSocket::SetTimeout %d usec", usec ); + jack_log ( "JackNetWinSocket::SetTimeout %d usec", usec ); //negative timeout, or exceeding 10s, return if ( ( usec < 0 ) || ( usec > 10000000 ) )