Commit 3b009644 authored by sletz's avatar sletz
Browse files

Raise network protocol, major cleanup.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3939 0c269be4-1314-0410-8aa9-9f06e86f4224
parent 2dcaaa51
......@@ -262,7 +262,9 @@ struct JackNetExtMaster : public JackNetMasterInterface {
return -1;
// Set global parameters
SetParams();
if (!SetParams())
return -1;
AllocPorts();
return 0;
}
......@@ -465,12 +467,12 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
int Open(jack_master_t* result)
{
// Init network connection
if (!JackNetSlaveInterface::InitConnection()){
if (!JackNetSlaveInterface::InitConnection())
return -1;
}
// Then set global parameters
SetParams();
if (!SetParams())
return -1;
// Set result
if (result != NULL) {
......@@ -494,7 +496,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
return -1;
// Then set global parameters
SetParams();
if (!SetParams())
return -1;
// We need to notify possibly new buffer size and sample rate (see Execute)
if (fBufferSizeCallback)
......@@ -514,6 +517,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
return 0;
}
void AllocPorts()
{
unsigned int port_index;
......@@ -939,7 +943,7 @@ SERVER_EXPORT void jack_log(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
//jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
va_end(ap);
}
......
......@@ -142,11 +142,12 @@ namespace Jack
( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" );
//init network
if ( !JackNetSlaveInterface::Init() )
if (!JackNetSlaveInterface::Init())
return false;
//set global parameters
SetParams();
if (!SetParams())
return false;
//allocate midi ports lists
fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels];
......
This diff is collapsed.
......@@ -35,8 +35,7 @@ namespace Jack
session_params_t fParams;
JackNetSocket fSocket;
char fMulticastIP[32];
uint fNSubProcess;
//headers
packet_header_t fTxHeader;
packet_header_t fRxHeader;
......@@ -58,13 +57,10 @@ namespace Jack
NetAudioBuffer* fNetAudioPlaybackBuffer;
//utility methods
void SetFramesPerPacket();
int SetNetBufferSize();
int GetNMidiPckt();
bool IsNextPacket();
//virtual methods : depends on the sub class master/slave
virtual void SetParams();
virtual bool SetParams();
virtual bool Init() = 0;
//transport
......@@ -103,7 +99,7 @@ namespace Jack
bool Init();
int SetRxTimeout();
void SetParams();
bool SetParams();
void Exit();
......@@ -149,7 +145,7 @@ namespace Jack
net_status_t SendAvailableToMaster();
net_status_t SendStartToMaster();
void SetParams();
bool SetParams();
int SyncRecv();
int SyncSend();
......
......@@ -113,11 +113,12 @@ namespace Jack
bool JackNetMaster::Init(bool auto_connect)
{
//network init
if ( !JackNetMasterInterface::Init() )
if (!JackNetMasterInterface::Init())
return false;
//set global parameters
SetParams();
if (!SetParams())
return false;
//jack client and process
jack_status_t status;
......@@ -415,7 +416,7 @@ namespace Jack
for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
fNetMidiPlaybackBuffer->SetBuffer ( port_index, static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiPlaybackPorts[port_index],
fParams.fPeriodSize ) ) );
for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
fNetAudioPlaybackBuffer->SetBuffer ( port_index, static_cast<sample_t*> ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index],
fParams.fPeriodSize ) ) );
......@@ -601,7 +602,7 @@ namespace Jack
if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR )
jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
jack_info ( "Waiting for a slave..." );
jack_log ( "sizeof (session_params_t) %d", sizeof (session_params_t) );
//main loop, wait for data, deal with it and wait again
do
......
......@@ -35,6 +35,9 @@ namespace Jack
for ( int port_index = 0; port_index < fNPorts; port_index++ )
fPortBuffer[port_index] = NULL;
fNetBuffer = net_buffer;
fCycleSize = params->fMtu * (max(params->fSendMidiChannels, params->fReturnMidiChannels) *
params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t)));
}
NetMidiBuffer::~NetMidiBuffer()
......@@ -47,6 +50,23 @@ namespace Jack
{
return fMaxBufsize;
}
size_t NetMidiBuffer::GetCycleSize()
{
return fCycleSize;
}
int NetMidiBuffer::GetNumPackets()
{
/*
return (data_size % PACKET_AVAILABLE_SIZE)
? (data_size / PACKET_AVAILABLE_SIZE + 1)
: data_size / PACKET_AVAILABLE_SIZE;
*/
//TODO
return 0;
}
void NetMidiBuffer::SetBuffer ( int index, JackMidiBuffer* buffer )
{
......@@ -124,10 +144,8 @@ namespace Jack
return copy_size;
}
// net audio buffer *********************************************************************************
NetSingleAudioBuffer::NetSingleAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer )
: fPortBuffer(params, nports), fNetBuffer(net_buffer)
{}
......@@ -139,6 +157,11 @@ namespace Jack
{
return fPortBuffer.GetSize();
}
size_t NetSingleAudioBuffer::GetCycleSize()
{
return fPortBuffer.GetCycleSize();
}
void NetSingleAudioBuffer::SetBuffer ( int index, sample_t* buffer )
{
......@@ -150,18 +173,30 @@ namespace Jack
return fPortBuffer.GetBuffer(index);
}
void NetSingleAudioBuffer::RenderFromJackPorts (int subcycle)
int NetSingleAudioBuffer::RenderFromJackPorts ()
{
fPortBuffer.RenderFromJackPorts(fNetBuffer, subcycle);
return fPortBuffer.RenderFromJackPorts();
}
void NetSingleAudioBuffer::RenderToJackPorts (int cycle, int subcycle)
int NetSingleAudioBuffer::RenderToJackPorts ()
{
return fPortBuffer.RenderToJackPorts();
}
//network<->buffer
int NetSingleAudioBuffer::RenderFromNetwork ( int cycle, int subcycle, size_t copy_size )
{
return fPortBuffer.RenderFromNetwork(fNetBuffer, cycle, subcycle, copy_size);
}
int NetSingleAudioBuffer::RenderToNetwork (int subcycle, size_t total_size )
{
fPortBuffer.RenderToJackPorts(fNetBuffer, subcycle);
return fPortBuffer.RenderToNetwork(fNetBuffer, subcycle, total_size);
}
// Buffered
/*
NetBufferedAudioBuffer::NetBufferedAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer )
{
fMaxCycle = 0;
......@@ -172,7 +207,7 @@ namespace Jack
}
fJackPortBuffer = new sample_t* [nports];
for ( int port_index = 0; port_index < nports; port_index++ )
for ( uint32_t port_index = 0; port_index < nports; port_index++ )
fJackPortBuffer[port_index] = NULL;
}
......@@ -185,6 +220,11 @@ namespace Jack
{
return fPortBuffer[0].GetSize();
}
size_t NetBufferedAudioBuffer::GetCycleSize()
{
return fPortBuffer[0].GetCycleSize();
}
void NetBufferedAudioBuffer::SetBuffer ( int index, sample_t* buffer )
{
......@@ -214,6 +254,7 @@ namespace Jack
fMaxCycle = std::max(fMaxCycle, cycle);
fPortBuffer[(cycle + 1) % AUDIO_BUFFER_SIZE].Copy(fJackPortBuffer); // Copy internal buffer in JACK ports
}
*/
// SessionParams ************************************************************************************
......@@ -230,7 +271,6 @@ namespace Jack
dst_params->fReturnMidiChannels = htonl ( src_params->fReturnMidiChannels );
dst_params->fSampleRate = htonl ( src_params->fSampleRate );
dst_params->fPeriodSize = htonl ( src_params->fPeriodSize );
dst_params->fFramesPerPacket = htonl ( src_params->fFramesPerPacket );
dst_params->fBitdepth = htonl ( src_params->fBitdepth );
dst_params->fSlaveSyncMode = htonl ( src_params->fSlaveSyncMode );
}
......@@ -248,7 +288,6 @@ namespace Jack
dst_params->fReturnMidiChannels = ntohl ( src_params->fReturnMidiChannels );
dst_params->fSampleRate = ntohl ( src_params->fSampleRate );
dst_params->fPeriodSize = ntohl ( src_params->fPeriodSize );
dst_params->fFramesPerPacket = ntohl ( src_params->fFramesPerPacket );
dst_params->fBitdepth = ntohl ( src_params->fBitdepth );
dst_params->fSlaveSyncMode = ntohl ( src_params->fSlaveSyncMode );
}
......@@ -282,8 +321,6 @@ namespace Jack
jack_info ( "Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels );
jack_info ( "Sample rate : %u frames per second", params->fSampleRate );
jack_info ( "Period size : %u frames per period", params->fPeriodSize );
jack_info ( "Frames per packet : %u", params->fFramesPerPacket );
jack_info ( "Packet per period : %u", (params->fFramesPerPacket != 0) ? params->fPeriodSize / params->fFramesPerPacket : 0);
jack_info ( "Bitdepth : %s", bitdepth );
jack_info ( "Slave mode : %s", ( params->fSlaveSyncMode ) ? "sync" : "async" );
jack_info ( "Network mode : %s", mode );
......@@ -338,9 +375,8 @@ namespace Jack
{
memcpy(dst_header, src_header, sizeof(packet_header_t));
dst_header->fID = htonl ( src_header->fID );
dst_header->fMidiDataSize = htonl ( src_header->fMidiDataSize );
dst_header->fBitdepth = htonl ( src_header->fBitdepth );
dst_header->fNMidiPckt = htonl ( src_header->fNMidiPckt );
dst_header->fNumPacket = htonl ( src_header->fNumPacket );
dst_header->fPacketSize = htonl ( src_header->fPacketSize );
dst_header->fCycle = htonl ( src_header->fCycle );
dst_header->fSubCycle = htonl ( src_header->fSubCycle );
......@@ -351,9 +387,8 @@ namespace Jack
{
memcpy(dst_header, src_header, sizeof(packet_header_t));
dst_header->fID = ntohl ( src_header->fID );
dst_header->fMidiDataSize = ntohl ( src_header->fMidiDataSize );
dst_header->fBitdepth = ntohl ( src_header->fBitdepth );
dst_header->fNMidiPckt = ntohl ( src_header->fNMidiPckt );
dst_header->fNumPacket = ntohl ( src_header->fNumPacket );
dst_header->fPacketSize = ntohl ( src_header->fPacketSize );
dst_header->fCycle = ntohl ( src_header->fCycle );
dst_header->fSubCycle = ntohl ( src_header->fSubCycle );
......@@ -370,8 +405,7 @@ namespace Jack
jack_info ( "ID : %u", header->fID );
jack_info ( "Cycle : %u", header->fCycle );
jack_info ( "SubCycle : %u", header->fSubCycle );
jack_info ( "Midi packets : %u", header->fNMidiPckt );
jack_info ( "Midi data size : %u", header->fMidiDataSize );
jack_info ( "Midi packets : %u", header->fNumPacket );
jack_info ( "Last packet : '%s'", ( header->fIsLastPckt ) ? "yes" : "no" );
jack_info ( "Bitdepth : %s", bitdepth );
jack_info ( "**********************************************" );
......
......@@ -67,8 +67,8 @@ namespace Jack
are kept in LITTLE_ENDIAN format (to avoid 2 conversions in the more common LITTLE_ENDIAN <==> LITTLE_ENDIAN connection case).
*/
#define MASTER_PROTOCOL 1
#define SLAVE_PROTOCOL 1
#define MASTER_PROTOCOL 2
#define SLAVE_PROTOCOL 2
struct _session_params
{
......@@ -87,7 +87,6 @@ namespace Jack
uint32_t fReturnMidiChannels; //number of slave->master midi channels
uint32_t fSampleRate; //session sample rate
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 ?
char fNetworkMode; //fast, normal or slow mode
......@@ -159,14 +158,11 @@ namespace Jack
char fDataStream; //s for send, r for return
uint32_t fID; //unique ID of the slave
uint32_t fBitdepth; //bitdepth of the data samples
uint32_t fMidiDataSize; //size of midi data in bytes
uint32_t fNMidiPckt; //number of midi packets of the cycle
uint32_t fNumPacket; //number of data packets of the cycle
uint32_t fPacketSize; //packet size in bytes
uint32_t fCycle; //process cycle counter
uint32_t fSubCycle; //midi/audio subcycle counter
uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n')
char fASyncWrongCycle; //is the current async cycle wrong (slave's side; 'y' or 'n')
char fFree[26]; //unused
};
//net timebase master
......@@ -199,8 +195,8 @@ namespace Jack
int32_t fState; //current cycle state
jack_position_t fPosition; //current cycle position
};
//midi data ***********************************************************************************
//midi data ***********************************************************************************
/**
\Brief Midi buffer and operations class
......@@ -226,6 +222,8 @@ namespace Jack
char* fBuffer;
char* fNetBuffer;
JackMidiBuffer** fPortBuffer;
size_t fCycleSize; // needed size in bytes ofr an entire cycle
public:
NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer );
......@@ -234,6 +232,11 @@ namespace Jack
void Reset();
size_t GetSize();
// needed size in bytes for an entire cycle
size_t GetCycleSize();
int GetNumPackets();
//utility
void DisplayEvents();
......@@ -262,14 +265,21 @@ namespace Jack
virtual size_t GetSize() = 0;
// needed syze in bytes ofr an entire cycle
virtual size_t GetCycleSize() = 0;
// cycle duration in sec
virtual float GetCycleDuration() = 0;
virtual int GetNumPackets() = 0;
//jack<->buffer
virtual void RenderFromJackPorts (int subcycle ) = 0;
virtual void RenderToJackPorts ( int cycle, int subcycle) = 0;
virtual void FinishRenderToJackPorts (int cycle) = 0;
virtual int RenderFromJackPorts () = 0;
virtual int RenderToJackPorts () = 0;
//network<->buffer
//int RenderFromNetwork ( int subcycle, size_t copy_size ) = 0;
//int RenderToNetwork ( int subcycle, size_t total_size ) = 0;
virtual int RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) = 0;
virtual int RenderToNetwork (int subcycle, size_t total_size ) = 0;
virtual void SetBuffer ( int index, sample_t* buffer ) = 0;
virtual sample_t* GetBuffer ( int index ) = 0;
......@@ -292,16 +302,39 @@ namespace Jack
size_t fSubPeriodBytesSize;
sample_t** fPortBuffer;
int fNPorts;
size_t fCycleSize; // needed size in bytes for an entire cycle
float fCycleDuration; // in dec
int fLastSubCycle;
JackPortList(session_params_t* params, uint32_t nports)
{
fNPorts = nports;
fPeriodSize = params->fPeriodSize;
fSubPeriodSize = params->fFramesPerPacket;
if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) {
fSubPeriodSize = params->fPeriodSize;
} else {
jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ((params->fMtu - sizeof(packet_header_t)))
/ ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) );
fSubPeriodSize = ( period > params->fPeriodSize ) ? params->fPeriodSize : period;
}
fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t );
fPortBuffer = new sample_t* [fNPorts];
for ( int port_index = 0; port_index < fNPorts; port_index++ )
fPortBuffer[port_index] = NULL;
fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate);
fCycleSize = params->fMtu * ( fPeriodSize / fSubPeriodBytesSize );
fLastSubCycle = -1;
}
int GetNumPackets()
{
return fPeriodSize / fSubPeriodSize;
}
JackPortList()
......@@ -338,7 +371,19 @@ namespace Jack
{
return fNPorts * fSubPeriodBytesSize;
}
// needed syze in bytes ofr an entire cycle
size_t GetCycleSize()
{
return fCycleSize;
}
// cycle duration in sec
float GetCycleDuration()
{
return fCycleDuration;
}
#ifdef __BIG_ENDIAN__
static inline float SwapFloat(float f)
......@@ -357,40 +402,75 @@ namespace Jack
return dat2.f;
}
void RenderFromJackPorts (char* net_buffer, int subcycle )
int RenderFromJackPorts ()
{
for ( int port_index = 0; port_index < fNPorts; port_index++ ) {
float* src = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize);
float* dst = (float*)(net_buffer + port_index * fSubPeriodBytesSize);
for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) {
dst[sample] = SwapFloat(src[sample]);
}
}
return fNPorts * fSubPeriodBytesSize; // in bytes
}
void RenderToJackPorts (char* net_buffer, int subcycle)
int RenderToJackPorts ()
{
for ( int port_index = 0; port_index < fNPorts; port_index++ ) {
return fPeriodSize * sizeof(sample_t); // in bytes TODO
}
//network<->buffer
int RenderFromNetwork (char* net_buffer, int cycle, int subcycle, size_t copy_size )
{
for ( int port_index = 0; port_index < fNPorts; port_index++ ) {
float* src = (float*)(net_buffer + port_index * fSubPeriodBytesSize);
float* dst = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize);
for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) {
dst[sample] = SwapFloat(src[sample]);
}
}
}
return copy_size;
}
int RenderToNetwork (char* net_buffer, int subcycle, size_t total_size )
{
for ( int port_index = 0; port_index < fNPorts; port_index++ ) {
float* src = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize);
float* dst = (float*)(net_buffer + port_index * fSubPeriodBytesSize);
for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) {
dst[sample] = SwapFloat(src[sample]);
}
}
return fNPorts * fSubPeriodBytesSize;
}
#else
void RenderFromJackPorts (char* net_buffer, int subcycle )
int RenderFromJackPorts ()
{
for ( int port_index = 0; port_index < fNPorts; port_index++ )
memcpy ( net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize );
return fNPorts * fSubPeriodBytesSize; // in bytes
}
void RenderToJackPorts (char* net_buffer, int subcycle)
int RenderToJackPorts ()
{
fLastSubCycle = -1;
return fPeriodSize * sizeof(sample_t); // in bytes; TODO
}
//network<->buffer
int RenderFromNetwork (char* net_buffer, int cycle, int subcycle, size_t copy_size )
{
for ( int port_index = 0; port_index < fNPorts; port_index++ )
memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize );
if (subcycle != fLastSubCycle + 1) {
jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle);
}
fLastSubCycle = subcycle;
return copy_size;
}
int RenderToNetwork (char* net_buffer,int subcycle, size_t total_size )
{
for ( int port_index = 0; port_index < fNPorts; port_index++ )
memcpy ( net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize );
return fNPorts * fSubPeriodBytesSize;
}
#endif
......@@ -419,7 +499,15 @@ namespace Jack
{
fNPorts = nports;
fPeriodSize = params->fPeriodSize;
fSubPeriodSize = params->fFramesPerPacket;
if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) {
fSubPeriodSize = params->fPeriodSize;
} else {
jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ((params->fMtu - sizeof(packet_header_t)))
/ ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) );
fSubPeriodSize = ( period > params->fPeriodSize ) ? params->fPeriodSize : period;
}
fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t );
fPortBuffer = new sample_t* [fNPorts];
for ( int port_index = 0; port_index < fNPorts; port_index++ )
......@@ -439,18 +527,36 @@ namespace Jack
~NetSingleAudioBuffer();
size_t GetSize();
// needed size in bytes for an entire cycle
size_t GetCycleSize();
// cycle duration in sec
float GetCycleDuration()
{
return fPortBuffer.GetCycleDuration();
}
int GetNumPackets()
{
return fPortBuffer.GetNumPackets();
}
//jack<->buffer
void RenderFromJackPorts (int subcycle );
void RenderToJackPorts (int cycle, int subcycle);
int RenderFromJackPorts ();
int RenderToJackPorts ();
void SetBuffer ( int index, sample_t* buffer );
sample_t* GetBuffer ( int index );
void FinishRenderToJackPorts (int cycle) {}
//network<->buffer
int RenderFromNetwork ( int cycle, int subcycle, size_t copy_size );
int RenderToNetwork (int subcycle, size_t total_size );
};
#define AUDIO_BUFFER_SIZE 8
/*
class SERVER_EXPORT NetBufferedAudioBuffer : public NetAudioBuffer
{
......@@ -465,14 +571,36 @@ namespace Jack
~NetBufferedAudioBuffer();
size_t GetSize();
// needed syze in bytes ofr an entire cycle
size_t GetCycleSize();