Browse Source

Cleanup, limit size for sync packet.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3934 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.8
sletz 15 years ago
parent
commit
f5ea7a7b92
3 changed files with 61 additions and 69 deletions
  1. +55
    -67
      common/JackNetInterface.cpp
  2. +3
    -1
      common/JackNetInterface.h
  3. +3
    -1
      macosx/iphone/main_slave.mm

+ 55
- 67
common/JackNetInterface.cpp View File

@@ -25,6 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
using namespace std; using namespace std;


#define PACKET_AVAILABLE_SIZE (fParams.fMtu - sizeof(packet_header_t)) #define PACKET_AVAILABLE_SIZE (fParams.fMtu - sizeof(packet_header_t))
#define HEADER_SIZE (sizeof(packet_header_t))


/* /*
TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames, TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames,
@@ -309,8 +310,8 @@ namespace Jack
assert ( fNetAudioPlaybackBuffer ); assert ( fNetAudioPlaybackBuffer );


//audio netbuffer length //audio netbuffer length
fAudioTxLen = sizeof ( packet_header_t ) + fNetAudioCaptureBuffer->GetSize();
fAudioRxLen = sizeof ( packet_header_t ) + fNetAudioPlaybackBuffer->GetSize();
fAudioTxLen = HEADER_SIZE + fNetAudioCaptureBuffer->GetSize();
fAudioRxLen = HEADER_SIZE + fNetAudioPlaybackBuffer->GetSize();
} }


void JackNetMasterInterface::Exit() void JackNetMasterInterface::Exit()
@@ -340,24 +341,23 @@ namespace Jack
int JackNetMasterInterface::Recv ( size_t size, int flags ) int JackNetMasterInterface::Recv ( size_t size, int flags )
{ {
int rx_bytes; int rx_bytes;
if ( ( ( rx_bytes = fSocket.Recv ( fRxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning )
{
if ((( rx_bytes = fSocket.Recv(fRxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
net_error_t error = fSocket.GetError(); net_error_t error = fSocket.GetError();
//no data isn't really a network error, so just return 0 avalaible read bytes //no data isn't really a network error, so just return 0 avalaible read bytes
if ( error == NET_NO_DATA )
if (error == NET_NO_DATA) {
return 0; return 0;
else if ( error == NET_CONN_ERROR )
{
} else if (error == NET_CONN_ERROR) {
//fatal connection issue, exit //fatal connection issue, exit
jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) );
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(); Exit();
// UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
ThreadExit(); ThreadExit();
} else {
jack_error ( "Error in master receive : %s", StrError(NET_ERROR_CODE));
} }
else
jack_error ( "Error in master receive : %s", StrError ( NET_ERROR_CODE ) );
} }
packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer); packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
@@ -371,20 +371,18 @@ namespace Jack
packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer); packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
PacketHeaderHToN(header, header); PacketHeaderHToN(header, header);
if ( ( ( tx_bytes = fSocket.Send ( fTxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning )
{
if (((tx_bytes = fSocket.Send(fTxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
net_error_t error = fSocket.GetError(); net_error_t error = fSocket.GetError();
if ( error == NET_CONN_ERROR )
{
if (error == NET_CONN_ERROR) {
//fatal connection issue, exit //fatal connection issue, exit
jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) );
jack_error ("'%s' : %s, exiting.", fParams.fName, StrError (NET_ERROR_CODE));
Exit(); Exit();
// UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
ThreadExit(); ThreadExit();
} else {
jack_error("Error in master send : %s", StrError(NET_ERROR_CODE));
} }
else
jack_error ( "Error in master send : %s", StrError ( NET_ERROR_CODE ) );
} }
return tx_bytes; return tx_bytes;
} }
@@ -404,9 +402,9 @@ namespace Jack
fTxHeader.fSubCycle = 0; fTxHeader.fSubCycle = 0;
fTxHeader.fDataType = 's'; fTxHeader.fDataType = 's';
fTxHeader.fIsLastPckt = ( fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0; fTxHeader.fIsLastPckt = ( fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0;
fTxHeader.fPacketSize = fParams.fMtu;
memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
return Send ( fTxHeader.fPacketSize, 0 );
fTxHeader.fPacketSize = HEADER_SIZE;
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
return Send(fTxHeader.fPacketSize, 0);
} }


int JackNetMasterInterface::DataSend() int JackNetMasterInterface::DataSend()
@@ -422,10 +420,10 @@ namespace Jack
for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ ) for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ )
{ {
fTxHeader.fSubCycle = subproc; fTxHeader.fSubCycle = subproc;
fTxHeader.fIsLastPckt = ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && (fParams.fSendAudioChannels == 0)) ? 1 : 0;
fTxHeader.fPacketSize = sizeof ( packet_header_t ) + fNetMidiCaptureBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize );
memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR )
fTxHeader.fIsLastPckt = (( subproc == (fTxHeader.fNMidiPckt - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize);
memcpy ( fTxBuffer, &fTxHeader, HEADER_SIZE);
if (Send (fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR; return SOCKET_ERROR;
} }
} }
@@ -436,14 +434,14 @@ namespace Jack
fTxHeader.fDataType = 'a'; fTxHeader.fDataType = 'a';
fTxHeader.fMidiDataSize = 0; fTxHeader.fMidiDataSize = 0;
fTxHeader.fNMidiPckt = 0; fTxHeader.fNMidiPckt = 0;
for ( subproc = 0; subproc < fNSubProcess; subproc++ )
for (subproc = 0; subproc < fNSubProcess; subproc++)
{ {
fTxHeader.fSubCycle = subproc; fTxHeader.fSubCycle = subproc;
fTxHeader.fIsLastPckt = ( subproc == ( fNSubProcess - 1 ) ) ? 1 : 0;
fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0;
fTxHeader.fPacketSize = fAudioTxLen; fTxHeader.fPacketSize = fAudioTxLen;
memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
fNetAudioCaptureBuffer->RenderFromJackPorts ( subproc );
if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR )
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
fNetAudioCaptureBuffer->RenderFromJackPorts(subproc);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR; return SOCKET_ERROR;
} }
} }
@@ -454,7 +452,7 @@ namespace Jack
int JackNetMasterInterface::SyncRecv() int JackNetMasterInterface::SyncRecv()
{ {
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
int rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
int rx_bytes = Recv(HEADER_SIZE, MSG_PEEK);
if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) ) if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) )
return rx_bytes; return rx_bytes;
@@ -485,13 +483,13 @@ namespace Jack
// - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth // - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth
// - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter // - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter
// - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it // - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it
if (fCycleOffset < 1) {
if (fCycleOffset < CYCLE_OFFSET_NORMAL) {
return 0; return 0;
} else { } else {
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); rx_bytes = Recv ( rx_head->fPacketSize, 0 );
} }
if (fCycleOffset != 1) {
if (fCycleOffset > CYCLE_OFFSET_NORMAL) {
jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
} }
break; break;
@@ -503,7 +501,7 @@ namespace Jack
// - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (fCycleOffset != 0) {
if (fCycleOffset > CYCLE_OFFSET_FAST) {
jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
} }
break; break;
@@ -526,7 +524,7 @@ namespace Jack
while ( !fRxHeader.fIsLastPckt ) 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 );
rx_bytes = Recv(HEADER_SIZE, MSG_PEEK);
if ( rx_bytes == SOCKET_ERROR ) if ( rx_bytes == SOCKET_ERROR )
return rx_bytes; return rx_bytes;
@@ -546,7 +544,7 @@ namespace Jack
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); rx_bytes = Recv ( rx_head->fPacketSize, 0 );
fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetMidiPlaybackBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) );
fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) if ( ++recvd_midi_pckt == rx_head->fNMidiPckt )
fNetMidiPlaybackBuffer->RenderToJackPorts(); fNetMidiPlaybackBuffer->RenderToJackPorts();
jumpcnt = 0; jumpcnt = 0;
@@ -732,29 +730,17 @@ namespace Jack
//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 )); memset(&net_params, 0, sizeof ( session_params_t ));
rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 ); rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 );
SessionParamsDisplay(&net_params);
jack_error ( "rx_bytes %d %d", rx_bytes, errno );
SessionParamsNToH(&net_params, &host_params); SessionParamsNToH(&net_params, &host_params);
if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) ) if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
{ {
jack_error ( "Can't receive : %s", StrError ( NET_ERROR_CODE ) ); jack_error ( "Can't receive : %s", StrError ( NET_ERROR_CODE ) );
return NET_RECV_ERROR; return NET_RECV_ERROR;
} }
for (int i = 0; i < 7; i++) {
jack_info ( " fPacketType %d", host_params.fPacketType[i]);
}
jack_info ( " received... host_params param %s %s %d %d", net_params.fPacketType, fParams.fPacketType, net_params.fPacketID, GetPacketType ( &host_params ));
SessionParamsDisplay(&host_params);
} }
while ( strcmp ( host_params.fPacketType, fParams.fPacketType ) && ( GetPacketType ( &host_params ) != SLAVE_SETUP ) ); while ( strcmp ( host_params.fPacketType, fParams.fPacketType ) && ( GetPacketType ( &host_params ) != SLAVE_SETUP ) );

jack_info ( "SLAVE_SETUP received..." );
//everything is OK, copy parameters //everything is OK, copy parameters
SessionParamsDisplay(&host_params);
fParams = host_params; fParams = host_params;


//set the new buffer sizes //set the new buffer sizes
@@ -810,8 +796,8 @@ namespace Jack
//fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );


//audio netbuffer length //audio netbuffer length
fAudioTxLen = sizeof ( packet_header_t ) + fNetAudioPlaybackBuffer->GetSize();
fAudioRxLen = sizeof ( packet_header_t ) + fNetAudioCaptureBuffer->GetSize();
fAudioTxLen = HEADER_SIZE + fNetAudioPlaybackBuffer->GetSize();
fAudioRxLen = HEADER_SIZE + fNetAudioCaptureBuffer->GetSize();
} }


int JackNetSlaveInterface::Recv ( size_t size, int flags ) int JackNetSlaveInterface::Recv ( size_t size, int flags )
@@ -867,7 +853,7 @@ namespace Jack
//receive sync (launch the cycle) //receive sync (launch the cycle)
do do
{ {
rx_bytes = Recv ( fParams.fMtu, 0 );
rx_bytes = Recv(HEADER_SIZE, 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 ) if ( rx_bytes == SOCKET_ERROR )
return rx_bytes; return rx_bytes;
@@ -889,7 +875,7 @@ namespace Jack


while ( !fRxHeader.fIsLastPckt ) while ( !fRxHeader.fIsLastPckt )
{ {
rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
rx_bytes = Recv(HEADER_SIZE, 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 ) if ( rx_bytes == SOCKET_ERROR )
@@ -902,7 +888,7 @@ namespace Jack
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); rx_bytes = Recv ( rx_head->fPacketSize, 0 );
fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetMidiCaptureBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) );
fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
// Last midi packet is received, so finish rendering... // Last midi packet is received, so finish rendering...
if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) if ( ++recvd_midi_pckt == rx_head->fNMidiPckt )
fNetMidiCaptureBuffer->RenderToJackPorts(); fNetMidiCaptureBuffer->RenderToJackPorts();
@@ -938,16 +924,18 @@ namespace Jack
int JackNetSlaveInterface::SyncSend() int JackNetSlaveInterface::SyncSend()
{ {
//tx header //tx header
if ( fParams.fSlaveSyncMode )
if ( fParams.fSlaveSyncMode ) {
fTxHeader.fCycle = fRxHeader.fCycle; fTxHeader.fCycle = fRxHeader.fCycle;
else
} else {
fTxHeader.fCycle++; fTxHeader.fCycle++;
}
fTxHeader.fSubCycle = 0; fTxHeader.fSubCycle = 0;
fTxHeader.fDataType = 's'; fTxHeader.fDataType = 's';
fTxHeader.fIsLastPckt = ( fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0; fTxHeader.fIsLastPckt = ( fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0;
fTxHeader.fPacketSize = fParams.fMtu;
memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
return Send ( fTxHeader.fPacketSize, 0 );
fTxHeader.fPacketSize = HEADER_SIZE;
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
return Send (fTxHeader.fPacketSize, 0);
} }


int JackNetSlaveInterface::DataSend() int JackNetSlaveInterface::DataSend()
@@ -963,10 +951,10 @@ namespace Jack
for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ ) for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ )
{ {
fTxHeader.fSubCycle = subproc; fTxHeader.fSubCycle = subproc;
fTxHeader.fIsLastPckt = ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && !fParams.fReturnAudioChannels ) ? 1 : 0;
fTxHeader.fPacketSize = sizeof ( packet_header_t ) + fNetMidiPlaybackBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize );
memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR )
fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNMidiPckt - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE+ fNetMidiPlaybackBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize);
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR; return SOCKET_ERROR;
} }
} }
@@ -980,11 +968,11 @@ namespace Jack
for ( subproc = 0; subproc < fNSubProcess; subproc++ ) for ( subproc = 0; subproc < fNSubProcess; subproc++ )
{ {
fTxHeader.fSubCycle = subproc; fTxHeader.fSubCycle = subproc;
fTxHeader.fIsLastPckt = ( subproc == ( fNSubProcess - 1 ) ) ? 1 : 0;
fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0;
fTxHeader.fPacketSize = fAudioTxLen; fTxHeader.fPacketSize = fAudioTxLen;
memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) );
fNetAudioPlaybackBuffer->RenderFromJackPorts ( subproc );
if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR )
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
fNetAudioPlaybackBuffer->RenderFromJackPorts (subproc);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR; return SOCKET_ERROR;
} }
} }


+ 3
- 1
common/JackNetInterface.h View File

@@ -212,7 +212,9 @@ namespace Jack
#define MASTER_INIT_TIMEOUT 1000000 // in usec #define MASTER_INIT_TIMEOUT 1000000 // in usec
#define SLAVE_INIT_TIMEOUT 2000000 // in usec #define SLAVE_INIT_TIMEOUT 2000000 // in usec


#define CYCLE_OFFSET_SLOW 2
#define CYCLE_OFFSET_FAST 0
#define CYCLE_OFFSET_NORMAL 1
#define CYCLE_OFFSET_SLOW 3
#define MAX_LATENCY CYCLE_OFFSET_SLOW * 4 #define MAX_LATENCY CYCLE_OFFSET_SLOW * 4


#endif #endif

+ 3
- 1
macosx/iphone/main_slave.mm View File

@@ -62,10 +62,12 @@ int main(int argc, char *argv[]) {
jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, WIFI_MTU, -1, JackSlowMode }; jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, WIFI_MTU, -1, JackSlowMode };
jack_master_t result; jack_master_t result;


if ((net = jack_net_slave_open("169.254.136.64", DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
//if ((net = jack_net_slave_open("169.254.121.189", DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
return -1; return -1;
} }
if ((adapter = jack_create_adapter(NUM_INPUT, if ((adapter = jack_create_adapter(NUM_INPUT,
NUM_OUTPUT, NUM_OUTPUT,
result.buffer_size, result.buffer_size,


Loading…
Cancel
Save