Browse Source

Cleanup.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2782 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.90
moret 17 years ago
parent
commit
ccc98f27bf
6 changed files with 194 additions and 196 deletions
  1. +0
    -4
      common/JackNetDriver.cpp
  2. +147
    -77
      common/JackNetInterface.cpp
  3. +29
    -23
      common/JackNetInterface.h
  4. +9
    -10
      common/JackNetManager.cpp
  5. +9
    -72
      common/JackNetTool.cpp
  6. +0
    -10
      common/JackNetTool.h

+ 0
- 4
common/JackNetDriver.cpp View File

@@ -497,8 +497,6 @@ namespace Jack

EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params )
{
jack_log ( "driver_initialize : net" );

if ( SocketAPIInit() < 0 )
{
jack_error ( "Can't init Socket API, exiting..." );
@@ -564,8 +562,6 @@ namespace Jack
}
}

jack_info ( "mode : %c", network_mode );

Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver (
new Jack::JackNetDriver ( "system", "net_pcm", engine, table, multicast_ip, udp_port, mtu,
midi_input_ports, midi_output_ports, name, transport_sync, network_mode ) );


+ 147
- 77
common/JackNetInterface.cpp View File

@@ -58,8 +58,71 @@ namespace Jack
delete fNetMidiPlaybackBuffer;
}

jack_nframes_t JackNetInterface::SetFramesPerPacket()
{
if ( !fParams.fSendAudioChannels && !fParams.fReturnAudioChannels )
return ( fParams.fFramesPerPacket = fParams.fPeriodSize );
jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log ( ( fParams.fMtu - sizeof ( packet_header_t ) )
/ ( max ( fParams.fReturnAudioChannels, fParams.fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2 ) ) );
( period > fParams.fPeriodSize ) ? fParams.fFramesPerPacket = fParams.fPeriodSize : fParams.fFramesPerPacket = period;
return fParams.fFramesPerPacket;
}

int JackNetInterface::SetNetBufferSize()
{
float audio_size, midi_size;
int bufsize, res = 0;
//audio
audio_size = fParams.fMtu * ( fParams.fPeriodSize / fParams.fFramesPerPacket );
//midi
midi_size = fParams.fMtu * ( max ( fParams.fSendMidiChannels, fParams.fReturnMidiChannels ) *
fParams.fPeriodSize * sizeof ( sample_t ) / ( fParams.fMtu - sizeof ( packet_header_t ) ) );
//size of sync + audio + midi
bufsize = 2 * ( fParams.fMtu + ( int ) audio_size + ( int ) midi_size );

//tx buffer
if ( fSocket.SetOption ( SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR )
res = SOCKET_ERROR;

//rx buffer
if ( fSocket.SetOption ( SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR )
res = SOCKET_ERROR;

return res;
}

int JackNetInterface::GetNMidiPckt()
{
//even if there is no midi data, jack need an empty buffer to know there is no event to read
//99% of the cases : all data in one packet
if ( fTxHeader.fMidiDataSize <= ( fParams.fMtu - sizeof ( packet_header_t ) ) )
return 1;
//else, get the number of needed packets (simply slice the biiig buffer)
int npckt = fTxHeader.fMidiDataSize / ( fParams.fMtu - sizeof ( packet_header_t ) );
if ( fTxHeader.fMidiDataSize % ( fParams.fMtu - sizeof ( packet_header_t ) ) )
return ++npckt;
return npckt;
}

bool JackNetInterface::IsNextPacket()
{
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
//ignore first cycle
if ( fRxHeader.fCycle <= 1 )
return true;
//same PcktID (cycle), next SubPcktID (subcycle)
if ( ( fRxHeader.fSubCycle < ( fNSubProcess - 1 ) ) && ( rx_head->fCycle == fRxHeader.fCycle ) && ( rx_head->fSubCycle == ( fRxHeader.fSubCycle + 1 ) ) )
return true;
//next PcktID (cycle), SubPcktID reset to 1 (first subcyle)
if ( ( rx_head->fCycle == ( fRxHeader.fCycle + 1 ) ) && ( fRxHeader.fSubCycle == ( fNSubProcess - 1 ) ) && ( rx_head->fSubCycle == 0 ) )
return true;
//else, next is'nt next, return false
return false;
}

void JackNetInterface::SetParams()
{
SetFramesPerPacket();
fNSubProcess = fParams.fPeriodSize / fParams.fFramesPerPacket;

//TX header init
@@ -99,7 +162,6 @@ namespace Jack
session_params_t params;
uint attempt = 0;
int rx_bytes = 0;
int rx_bufsize = 0;

//socket
if ( fSocket.NewSocket() == SOCKET_ERROR )
@@ -140,23 +202,37 @@ namespace Jack
}

//set the new timeout for the socket
if ( SetRxTimeout ( &fSocket, &fParams ) == SOCKET_ERROR )
if ( SetRxTimeout() == SOCKET_ERROR )
{
jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) );
return false;
}

//set the new rx buffer size
rx_bufsize = GetNetBufferSize ( &fParams );
if ( fSocket.SetOption ( SOL_SOCKET, SO_RCVBUF, &rx_bufsize, sizeof ( rx_bufsize ) ) == SOCKET_ERROR )
if ( SetNetBufferSize() == SOCKET_ERROR )
{
jack_error ( "Can't set rx buffer size : %s", StrError ( NET_ERROR_CODE ) );
jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );
return false;
}

return true;
}

int JackNetMasterInterface::SetRxTimeout()
{
float time = 0;
//slow mode, very short timeout on recv
if ( fParams.fNetworkMode == 's' )
time = 1000000.f * ( static_cast<float> ( fParams.fFramesPerPacket ) / static_cast<float> ( fParams.fSampleRate ) );
//normal mode, short timeout on recv
else if ( fParams.fNetworkMode == 'n' )
time = 2000000.f * ( static_cast<float> ( fParams.fFramesPerPacket ) / static_cast<float> ( fParams.fSampleRate ) );
//fast mode, wait for the entire cycle duration
else if ( fParams.fNetworkMode == 'f' )
time = 750000.f * ( static_cast<float> ( fParams.fPeriodSize ) / static_cast<float> ( fParams.fSampleRate ) );
return fSocket.SetTimeOut ( static_cast<int> ( time ) );
}

void JackNetMasterInterface::SetParams()
{
jack_log ( "JackNetMasterInterface::SetParams" );
@@ -256,7 +332,7 @@ namespace Jack
//set global header fields and get the number of midi packets
fTxHeader.fDataType = 'm';
fTxHeader.fMidiDataSize = fNetMidiCaptureBuffer->RenderFromJackPorts();
fTxHeader.fNMidiPckt = GetNMidiPckt ( &fParams, fTxHeader.fMidiDataSize );
fTxHeader.fNMidiPckt = GetNMidiPckt();
for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ )
{
//fill the packet header fields
@@ -351,50 +427,46 @@ namespace Jack
uint midi_recvd_pckt = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );

if ( fParams.fReturnMidiChannels || fParams.fReturnAudioChannels )
while ( rx_head->fIsLastPckt != 'y' )
{
do
//how much data is queued on the rx buffer ?
rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
if ( rx_bytes == SOCKET_ERROR )
return rx_bytes;
//if no data,
if ( ( rx_bytes == 0 ) && ( ++jumpcnt == fNSubProcess ) )
{
//how much data is queued on the rx buffer ?
rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
if ( rx_bytes == SOCKET_ERROR )
return rx_bytes;
//if no data,
if ( ( rx_bytes == 0 ) && ( ++jumpcnt == fNSubProcess ) )
{
jack_error ( "No data from %s...", fParams.fName );
jumpcnt = 0;
}
//else if data is valid,
if ( rx_bytes && ( rx_head->fDataStream == 'r' ) && ( rx_head->fID == fParams.fID ) )
jack_error ( "No data from %s...", fParams.fName );
jumpcnt = 0;
}
//else if data is valid,
if ( rx_bytes && ( rx_head->fDataStream == 'r' ) && ( rx_head->fID == fParams.fID ) )
{
//read data
switch ( rx_head->fDataType )
{
//read data
switch ( rx_head->fDataType )
{
case 'm': //midi
Recv ( rx_head->fPacketSize, 0 );
fRxHeader.fCycle = rx_head->fCycle;
fNetMidiPlaybackBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) );
if ( ++midi_recvd_pckt == rx_head->fNMidiPckt )
fNetMidiPlaybackBuffer->RenderToJackPorts();
jumpcnt = 0;
break;
case 'a': //audio
Recv ( rx_head->fPacketSize, 0 );
if ( !IsNextPacket ( &fRxHeader, rx_head, fNSubProcess ) )
jack_error ( "Packet(s) missing from '%s'...", fParams.fName );
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fSubCycle );
jumpcnt = 0;
break;
case 's': //sync
if ( rx_head->fCycle == fTxHeader.fCycle )
return 0;
}
case 'm': //midi
Recv ( rx_head->fPacketSize, 0 );
fRxHeader.fCycle = rx_head->fCycle;
fNetMidiPlaybackBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) );
if ( ++midi_recvd_pckt == rx_head->fNMidiPckt )
fNetMidiPlaybackBuffer->RenderToJackPorts();
jumpcnt = 0;
break;
case 'a': //audio
Recv ( rx_head->fPacketSize, 0 );
if ( !IsNextPacket() )
jack_error ( "Packet(s) missing from '%s'...", fParams.fName );
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fSubCycle );
jumpcnt = 0;
break;
case 's': //sync
if ( rx_head->fCycle == fTxHeader.fCycle )
return 0;
}
}
while ( rx_head->fIsLastPckt != 'y' );
}
return rx_bytes;
}
@@ -462,6 +534,10 @@ namespace Jack
if ( fSocket.SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof ( loop ) ) == SOCKET_ERROR )
jack_error ( "Can't disable multicast loop : %s", StrError ( NET_ERROR_CODE ) );

//set the new rx buffer size
if ( SetNetBufferSize() == SOCKET_ERROR )
jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );

//send 'AVAILABLE' until 'SLAVE_SETUP' received
jack_info ( "Waiting for a master..." );
do
@@ -590,41 +666,36 @@ namespace Jack
int rx_bytes = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );

//audio, midi or sync if driver is late
if ( fParams.fSendMidiChannels || fParams.fSendAudioChannels )
while ( rx_head->fIsLastPckt != 'y' );
{
do
rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
//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 ) )
{
rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
//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 )
{
switch ( rx_head->fDataType )
{
case 'm': //midi
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
fRxHeader.fCycle = rx_head->fCycle;
fNetMidiCaptureBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) );
if ( ++recvd_midi_pckt == rx_head->fNMidiPckt )
fNetMidiCaptureBuffer->RenderToJackPorts();
break;
case 'a': //audio
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if ( !IsNextPacket ( &fRxHeader, rx_head, fNSubProcess ) )
jack_error ( "Packet(s) missing..." );
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fNetAudioCaptureBuffer->RenderToJackPorts ( rx_head->fSubCycle );
break;
case 's': //sync
jack_info ( "NetSlave : overloaded, skipping receive." );
return 0;
}
case 'm': //midi
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
fRxHeader.fCycle = rx_head->fCycle;
fNetMidiCaptureBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) );
if ( ++recvd_midi_pckt == rx_head->fNMidiPckt )
fNetMidiCaptureBuffer->RenderToJackPorts();
break;
case 'a': //audio
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if ( !IsNextPacket() )
jack_error ( "Packet(s) missing..." );
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fNetAudioCaptureBuffer->RenderToJackPorts ( rx_head->fSubCycle );
break;
case 's': //sync
jack_info ( "NetSlave : overloaded, skipping receive." );
return 0;
}
}
while ( rx_head->fIsLastPckt != 'y' );
}
fRxHeader.fCycle = rx_head->fCycle;
return 0;
@@ -654,7 +725,7 @@ namespace Jack
{
fTxHeader.fDataType = 'm';
fTxHeader.fMidiDataSize = fNetMidiPlaybackBuffer->RenderFromJackPorts();
fTxHeader.fNMidiPckt = GetNMidiPckt ( &fParams, fTxHeader.fMidiDataSize );
fTxHeader.fNMidiPckt = GetNMidiPckt();
for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ )
{
fTxHeader.fSubCycle = subproc;
@@ -687,4 +758,3 @@ namespace Jack
return 0;
}
}


+ 29
- 23
common/JackNetInterface.h View File

@@ -58,9 +58,14 @@ namespace Jack
int fAudioTxLen;
int fPayloadSize;

virtual void SetParams();
//utility methods
jack_nframes_t SetFramesPerPacket();
int SetNetBufferSize();
int GetNMidiPckt();
bool IsNextPacket();

//virtual methods : depends on the sub class master/slave
virtual void SetParams();
virtual bool Init() = 0;

virtual int SyncRecv() = 0;
@@ -81,63 +86,64 @@ namespace Jack
};

/**
\Brief This class describes the Net Interface for slaves (NetDriver and NetAdapter)
\Brief This class describes the Net Interface for masters (NetMaster)
*/

class EXPORT JackNetSlaveInterface : public JackNetInterface
class EXPORT JackNetMasterInterface : public JackNetInterface
{
protected:
bool fRunning;

bool Init();
net_status_t GetNetMaster();
net_status_t SendMasterStartSync();
int SetRxTimeout();
void SetParams();
void Exit();
int SyncRecv();
int SyncSend();
int DataRecv();
int DataSend();

int Recv ( size_t size, int flags );
int Send ( size_t size, int flags );
int Recv ( size_t size, int flags );

public:
JackNetSlaveInterface()
JackNetMasterInterface() : fRunning ( false )
{}
JackNetSlaveInterface ( const char* ip, int port ) : JackNetInterface ( ip, port )
JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip )
: JackNetInterface ( params, socket, multicast_ip )
{}
~JackNetMasterInterface()
{}
~JackNetSlaveInterface()
{
SocketAPIEnd();
}
};

/**
\Brief This class describes the Net Interface for masters (NetMaster)
\Brief This class describes the Net Interface for slaves (NetDriver and NetAdapter)
*/

class EXPORT JackNetMasterInterface : public JackNetInterface
class EXPORT JackNetSlaveInterface : public JackNetInterface
{
protected:
bool fRunning;

bool Init();
net_status_t GetNetMaster();
net_status_t SendMasterStartSync();
void SetParams();
void Exit();
int SyncRecv();
int SyncSend();
int DataRecv();
int DataSend();

int Send ( size_t size, int flags );
int Recv ( size_t size, int flags );
int Send ( size_t size, int flags );

public:
JackNetMasterInterface() : fRunning ( false )
{}
JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip )
: JackNetInterface ( params, socket, multicast_ip )
JackNetSlaveInterface()
{}
~JackNetMasterInterface()
JackNetSlaveInterface ( const char* ip, int port ) : JackNetInterface ( ip, port )
{}
~JackNetSlaveInterface()
{
SocketAPIEnd();
}
};
}



+ 9
- 10
common/JackNetManager.cpp View File

@@ -69,15 +69,15 @@ namespace Jack
plot_name += string ( ( fParams.fSlaveSyncMode ) ? "_sync" : "_async" );
switch ( fParams.fNetworkMode )
{
case 's' :
plot_name += string ( "_slow" );
break;
case 'n' :
plot_name += string ( "_normal" );
break;
case 'f' :
plot_name += string ( "_fast" );
break;
case 's' :
plot_name += string ( "_slow" );
break;
case 'n' :
plot_name += string ( "_normal" );
break;
case 'f' :
plot_name += string ( "_fast" );
break;
}
fNetTimeMon = new JackGnuPlotMonitor<float> ( 128, 4, plot_name );
string net_time_mon_fields[] =
@@ -482,7 +482,6 @@ namespace Jack
params.fSampleRate = jack_get_sample_rate ( fManagerClient );
params.fPeriodSize = jack_get_buffer_size ( fManagerClient );
params.fBitdepth = 0;
SetFramesPerPacket ( &params );
SetSlaveName ( params );

//create a new master and add it to the list


+ 9
- 72
common/JackNetTool.cpp View File

@@ -205,15 +205,15 @@ namespace Jack
char mode[8];
switch ( params->fNetworkMode )
{
case 's' :
strcpy ( mode, "slow" );
break;
case 'n' :
strcpy ( mode, "normal" );
break;
case 'f' :
strcpy ( mode, "fast" );
break;
case 's' :
strcpy ( mode, "slow" );
break;
case 'n' :
strcpy ( mode, "normal" );
break;
case 'f' :
strcpy ( mode, "fast" );
break;
}
jack_info ( "**************** Network parameters ****************" );
jack_info ( "Name : %s", params->fName );
@@ -349,67 +349,4 @@ namespace Jack
#endif
return 0;
}

EXPORT jack_nframes_t SetFramesPerPacket ( session_params_t* params )
{
if ( !params->fSendAudioChannels && !params->fReturnAudioChannels )
return ( params->fFramesPerPacket = params->fPeriodSize );
jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log ( ( params->fMtu - sizeof ( packet_header_t ) )
/ ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2 ) ) );
( period > params->fPeriodSize ) ? params->fFramesPerPacket = params->fPeriodSize : params->fFramesPerPacket = period;
return params->fFramesPerPacket;
}

EXPORT int GetNetBufferSize ( session_params_t* params )
{
//audio
float audio_size = params->fMtu * ( params->fPeriodSize / params->fFramesPerPacket );
//midi
float midi_size = params->fMtu * ( max ( params->fSendMidiChannels, params->fReturnMidiChannels ) *
params->fPeriodSize * sizeof ( sample_t ) / ( params->fMtu - sizeof ( packet_header_t ) ) );
//return : sizes of sync + audio + midi
return ( params->fMtu + ( int ) audio_size + ( int ) midi_size );
}

EXPORT int GetNMidiPckt ( session_params_t* params, size_t data_size )
{
//even if there is no midi data, jack need an empty buffer to know there is no event to read
//99% of the cases : all data in one packet
if ( data_size <= ( params->fMtu - sizeof ( packet_header_t ) ) )
return 1;
//else, get the number of needed packets (simply slice the biiig buffer)
int npckt = data_size / ( params->fMtu - sizeof ( packet_header_t ) );
if ( data_size % ( params->fMtu - sizeof ( packet_header_t ) ) )
return ++npckt;
return npckt;
}

EXPORT int SetRxTimeout ( JackNetSocket* socket, session_params_t* params )
{
float time;
//fast mode, wait for the entire cycle duration
if ( params->fNetworkMode == 'f' )
time = 900000.f * ( static_cast<float> ( params->fPeriodSize ) / static_cast<float> ( params->fSampleRate ) );
//normal or slow mode, short timeout on recv
else
time = 4000000.f * ( static_cast<float> ( params->fFramesPerPacket ) / static_cast<float> ( params->fSampleRate ) );
return socket->SetTimeOut ( static_cast<int> ( time ) );
}

// Packet *******************************************************************************************************

EXPORT bool IsNextPacket ( packet_header_t* previous, packet_header_t* next, uint subcycles )
{
//ignore first cycle
if ( previous->fCycle <= 1 )
return true;
//same PcktID (cycle), next SubPcktID (subcycle)
if ( ( previous->fSubCycle < ( subcycles - 1 ) ) && ( next->fCycle == previous->fCycle ) && ( next->fSubCycle == ( previous->fSubCycle + 1 ) ) )
return true;
//next PcktID (cycle), SubPcktID reset to 1 (first subcyle)
if ( ( next->fCycle == ( previous->fCycle + 1 ) ) && ( previous->fSubCycle == ( subcycles - 1 ) ) && ( next->fSubCycle == 0 ) )
return true;
//else, next is'nt next, return false
return false;
}
}

+ 0
- 10
common/JackNetTool.h View File

@@ -260,14 +260,4 @@ namespace Jack
EXPORT sync_packet_type_t GetPacketType ( session_params_t* params );
//set the packet type in a session parameters
EXPORT int SetPacketType ( session_params_t* params, sync_packet_type_t packet_type );
//step of network initialization
EXPORT jack_nframes_t SetFramesPerPacket ( session_params_t* params );
//step of network initialization
EXPORT int GetNetBufferSize ( session_params_t* params );
//get the midi packet number for a given cycle
EXPORT int GetNMidiPckt ( session_params_t* params, size_t data_size );
//set the recv timeout on a socket
EXPORT int SetRxTimeout ( JackNetSocket* socket, session_params_t* params );
//check if 'next' packet is really the next after 'previous'
EXPORT bool IsNextPacket ( packet_header_t* previous, packet_header_t* next, uint subcycles );
}

Loading…
Cancel
Save