Browse Source

Raise network protocol, major cleanup.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3939 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.8
sletz 15 years ago
parent
commit
3b009644a7
8 changed files with 357 additions and 217 deletions
  1. +10
    -6
      common/JackNetAPI.cpp
  2. +3
    -2
      common/JackNetDriver.cpp
  3. +111
    -136
      common/JackNetInterface.cpp
  4. +5
    -9
      common/JackNetInterface.h
  5. +5
    -4
      common/JackNetManager.cpp
  6. +51
    -17
      common/JackNetTool.cpp
  7. +167
    -39
      common/JackNetTool.h
  8. +5
    -4
      macosx/iphone/main_slave.mm

+ 10
- 6
common/JackNetAPI.cpp View File

@@ -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);
}



+ 3
- 2
common/JackNetDriver.cpp View File

@@ -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];


+ 111
- 136
common/JackNetInterface.cpp View File

@@ -89,88 +89,45 @@ namespace Jack
delete fNetMidiPlaybackBuffer;
}

void JackNetInterface::SetFramesPerPacket()
{
jack_log ( "JackNetInterface::SetFramesPerPacket" );

if (fParams.fSendAudioChannels == 0 && fParams.fReturnAudioChannels == 0) {
fParams.fFramesPerPacket = fParams.fPeriodSize;
} else {
jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float (PACKET_AVAILABLE_SIZE)
/ ( max ( fParams.fReturnAudioChannels, fParams.fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) );
fParams.fFramesPerPacket = ( period > fParams.fPeriodSize ) ? fParams.fPeriodSize : period;
}
}

int JackNetInterface::SetNetBufferSize()
{
float audio_size, midi_size;
int bufsize;
//audio
audio_size = fParams.fMtu * ( fParams.fPeriodSize / fParams.fFramesPerPacket );
float audio_size = (fNetAudioCaptureBuffer)
? fNetAudioCaptureBuffer->GetCycleSize()
: (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0;
jack_log ("audio_size %f", audio_size);
//midi
midi_size = fParams.fMtu * ( max ( fParams.fSendMidiChannels, fParams.fReturnMidiChannels ) *
fParams.fPeriodSize * sizeof(sample_t) / PACKET_AVAILABLE_SIZE);
float midi_size = (fNetMidiCaptureBuffer)
? fNetMidiCaptureBuffer->GetCycleSize()
: (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0;
jack_log ("midi_size %f", midi_size);
//bufsize = sync + audio + midi
bufsize = MAX_LATENCY * (fParams.fMtu + ( int ) audio_size + ( int ) midi_size);
int bufsize = MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size);
jack_log("SetNetBufferSize bufsize = %d", bufsize);

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

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

return 0;
}

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 <= PACKET_AVAILABLE_SIZE) {
return 1;
} else { //get the number of needed packets (simply slice the biiig buffer)
return (fTxHeader.fMidiDataSize % PACKET_AVAILABLE_SIZE)
? (fTxHeader.fMidiDataSize / PACKET_AVAILABLE_SIZE + 1)
: fTxHeader.fMidiDataSize / PACKET_AVAILABLE_SIZE;
}
}

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 0 (first subcyle)
if ( ( rx_head->fCycle == ( fRxHeader.fCycle + 1 ) ) && ( fRxHeader.fSubCycle == ( fNSubProcess - 1 ) ) && ( rx_head->fSubCycle == 0 ) ) {
return true;
}
//else, packet(s) missing, return false
return false;
}

void JackNetInterface::SetParams()
bool JackNetInterface::SetParams()
{
//number of audio subcycles (packets)
fNSubProcess = fParams.fPeriodSize / fParams.fFramesPerPacket;

//TX header init
strcpy ( fTxHeader.fPacketType, "header" );
fTxHeader.fID = fParams.fID;
fTxHeader.fCycle = 0;
fTxHeader.fSubCycle = 0;
fTxHeader.fMidiDataSize = 0;
fTxHeader.fBitdepth = fParams.fBitdepth;
fTxHeader.fIsLastPckt = 0;

@@ -179,7 +136,6 @@ namespace Jack
fRxHeader.fID = fParams.fID;
fRxHeader.fCycle = 0;
fRxHeader.fSubCycle = 0;
fRxHeader.fMidiDataSize = 0;
fRxHeader.fBitdepth = fParams.fBitdepth;
fRxHeader.fIsLastPckt = 0;

@@ -192,6 +148,8 @@ namespace Jack
//net audio/midi buffers'addresses
fTxData = fTxBuffer + HEADER_SIZE;
fRxData = fRxBuffer + HEADER_SIZE;
return true;
}

// JackNetMasterInterface ************************************************************************************
@@ -220,11 +178,8 @@ namespace Jack
return false;
}

//set the number of complete audio frames we can put in a packet
SetFramesPerPacket();

//send 'SLAVE_SETUP' until 'START_MASTER' received
jack_info ( "Sending parameters to %s ...", fParams.fSlaveNetName );
jack_info ( "Sending parameters to %s...", fParams.fSlaveNetName );
do
{
session_params_t net_params;
@@ -250,18 +205,6 @@ namespace Jack
return false;
}

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

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

return true;
}

@@ -270,16 +213,22 @@ namespace Jack
jack_log ( "JackNetMasterInterface::SetRxTimeout" );

float time = 0;
//slow or normal mode, short timeout on recv (2 audio subcycles)
if ( ( fParams.fNetworkMode == 's' ) || ( fParams.fNetworkMode == 'n' ) )
time = 2000000.f * ( static_cast<float> ( fParams.fFramesPerPacket ) / static_cast<float> ( fParams.fSampleRate ) );
if ((fParams.fNetworkMode == 's') || (fParams.fNetworkMode == 'n')) {
time = 2000000.f * ((fNetAudioCaptureBuffer)
? fNetAudioCaptureBuffer->GetCycleDuration()
: (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleDuration() : 0);
}
//fast mode, wait for 75% of 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 ) );
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()
bool JackNetMasterInterface::SetParams()
{
jack_log ( "JackNetMasterInterface::SetParams" );

@@ -303,6 +252,28 @@ namespace Jack
assert ( fNetAudioCaptureBuffer );
assert ( fNetAudioPlaybackBuffer );
//set the new timeout for the socket
if ( SetRxTimeout() == SOCKET_ERROR ) {
jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) );
goto error;
}

//set the new rx buffer size
if ( SetNetBufferSize() == SOCKET_ERROR ) {
jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );
goto error;
}
return true;
error:
delete fNetMidiCaptureBuffer;
delete fNetMidiPlaybackBuffer;
delete fNetAudioCaptureBuffer;
delete fNetAudioPlaybackBuffer;
return false;
}

void JackNetMasterInterface::Exit()
@@ -402,18 +373,21 @@ namespace Jack
int JackNetMasterInterface::DataSend()
{
uint subproc;
uint data_size;
//midi
if ( fParams.fSendMidiChannels > 0)
{
//set global header fields and get the number of midi packets
fTxHeader.fDataType = 'm';
fTxHeader.fMidiDataSize = fNetMidiCaptureBuffer->RenderFromJackPorts();
fTxHeader.fNMidiPckt = GetNMidiPckt();
for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ )
data_size = fNetMidiCaptureBuffer->RenderFromJackPorts();
fTxHeader.fNumPacket = fNetMidiCaptureBuffer->GetNumPackets();
for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
{
fTxHeader.fSubCycle = subproc;
fTxHeader.fIsLastPckt = (( subproc == (fTxHeader.fNMidiPckt - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize);
fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, data_size);
memcpy ( fTxBuffer, &fTxHeader, HEADER_SIZE);
if (Send (fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR;
@@ -424,15 +398,15 @@ namespace Jack
if ( fParams.fSendAudioChannels > 0)
{
fTxHeader.fDataType = 'a';
fTxHeader.fMidiDataSize = 0;
fTxHeader.fNMidiPckt = 0;
for (subproc = 0; subproc < fNSubProcess; subproc++)
data_size = fNetAudioCaptureBuffer->RenderFromJackPorts();
fTxHeader.fNumPacket = fNetAudioCaptureBuffer->GetNumPackets();
for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++)
{
fTxHeader.fSubCycle = subproc;
fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->GetSize();
fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->RenderToNetwork(subproc, data_size);
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
fNetAudioCaptureBuffer->RenderFromJackPorts(subproc);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR;
}
@@ -506,8 +480,8 @@ namespace Jack
int JackNetMasterInterface::DataRecv()
{
int rx_bytes = 0;
int last_cycle = 0;
uint recvd_midi_pckt = 0;
uint recvd_audio_pckt = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
@@ -530,34 +504,30 @@ namespace Jack
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
// Last midi packet is received, so finish rendering...
if ( ++recvd_midi_pckt == rx_head->fNMidiPckt )
// Last midi packet is received, so finish rendering...
if (++recvd_midi_pckt == rx_head->fNumPacket)
fNetMidiPlaybackBuffer->RenderToJackPorts();
break;

case 'a': //audio
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (!IsNextPacket()) {
jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName);
}
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fCycle, rx_head->fSubCycle);
last_cycle = rx_head->fCycle;
fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
// Last audio packet is received, so finish rendering...
if (fRxHeader.fIsLastPckt)
fNetAudioPlaybackBuffer->RenderToJackPorts();
break;

case 's': //sync
jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName);
// Finish rendering (copy to JACK ports)
fNetAudioPlaybackBuffer->FinishRenderToJackPorts(last_cycle);
// TODO : finish midi and audio rendering ?
return 0;
}
}
}
// Finish rendering (copy to JACK ports)
fNetAudioPlaybackBuffer->FinishRenderToJackPorts(last_cycle);
return rx_bytes;
}
@@ -727,18 +697,11 @@ namespace Jack
SessionParamsDisplay(&host_params);
fParams = host_params;

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

//connect the socket
if ( fSocket.Connect() == SOCKET_ERROR ) {
jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) );
return NET_CONNECT_ERROR;
}

return NET_CONNECTED;
}

@@ -759,7 +722,7 @@ namespace Jack
return NET_ROLLING;
}

void JackNetSlaveInterface::SetParams()
bool JackNetSlaveInterface::SetParams()
{
jack_log ( "JackNetSlaveInterface::SetParams" );

@@ -783,6 +746,21 @@ namespace Jack
assert ( fNetAudioCaptureBuffer );
assert ( fNetAudioPlaybackBuffer );
//set the new buffer sizes
if ( SetNetBufferSize() == SOCKET_ERROR ) {
jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) );
goto error;
}
return true;
error:
delete fNetMidiCaptureBuffer;
delete fNetMidiPlaybackBuffer;
delete fNetAudioCaptureBuffer;
delete fNetAudioPlaybackBuffer;
return false;
}

int JackNetSlaveInterface::Recv ( size_t size, int flags )
@@ -852,8 +830,9 @@ namespace Jack
int JackNetSlaveInterface::DataRecv()
{
int rx_bytes = 0;
int last_cycle = 0;
//int last_cycle = 0;
uint recvd_midi_pckt = 0;
uint recvd_audio_pckt = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );

@@ -876,33 +855,29 @@ namespace Jack
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
// Last midi packet is received, so finish rendering...
if ( ++recvd_midi_pckt == rx_head->fNMidiPckt )
if ( ++recvd_midi_pckt == rx_head->fNumPacket )
fNetMidiCaptureBuffer->RenderToJackPorts();
break;

case 'a': //audio
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (!IsNextPacket()) {
jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName);
}
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetAudioCaptureBuffer->RenderToJackPorts ( rx_head->fCycle, rx_head->fSubCycle);
last_cycle = rx_head->fCycle;
fNetAudioCaptureBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
if (fRxHeader.fIsLastPckt) {
fNetAudioCaptureBuffer->RenderToJackPorts();
}
break;

case 's': //sync
jack_info ( "NetSlave : overloaded, skipping receive." );
// Finish rendering (copy to JACK ports)
fNetAudioCaptureBuffer->FinishRenderToJackPorts(last_cycle);
// TODO : finish midi and audio rendering ?
return 0;
}
}
}
// Finish rendering (copy to JACK ports)
fNetAudioCaptureBuffer->FinishRenderToJackPorts(last_cycle);
fRxHeader.fCycle = rx_head->fCycle;
return 0;
}
@@ -927,19 +902,20 @@ namespace Jack
int JackNetSlaveInterface::DataSend()
{
uint subproc;
uint data_size;

//midi
if (fParams.fReturnMidiChannels > 0)
{
//set global header fields and get the number of midi packets
fTxHeader.fDataType = 'm';
fTxHeader.fMidiDataSize = fNetMidiPlaybackBuffer->RenderFromJackPorts();
fTxHeader.fNMidiPckt = GetNMidiPckt();
for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ )
data_size = fNetMidiPlaybackBuffer->RenderFromJackPorts();
fTxHeader.fNumPacket = fNetMidiPlaybackBuffer->GetNumPackets();
for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
{
fTxHeader.fSubCycle = subproc;
fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNMidiPckt - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize);
fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, data_size);
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR;
@@ -950,15 +926,14 @@ namespace Jack
if ( fParams.fReturnAudioChannels > 0)
{
fTxHeader.fDataType = 'a';
fTxHeader.fMidiDataSize = 0;
fTxHeader.fNMidiPckt = 0;
for ( subproc = 0; subproc < fNSubProcess; subproc++ )
data_size = fNetAudioPlaybackBuffer->RenderFromJackPorts();
fTxHeader.fNumPacket = fNetAudioPlaybackBuffer->GetNumPackets();
for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ )
{
fTxHeader.fSubCycle = subproc;
fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->GetSize();
fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->RenderToNetwork(subproc, data_size);
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
fNetAudioPlaybackBuffer->RenderFromJackPorts (subproc);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR;
}


+ 5
- 9
common/JackNetInterface.h View File

@@ -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();


+ 5
- 4
common/JackNetManager.cpp View File

@@ -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


+ 51
- 17
common/JackNetTool.cpp View File

@@ -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 ( "**********************************************" );


+ 167
- 39
common/JackNetTool.h View File

@@ -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();
// cycle duration in sec
float GetCycleDuration()
{
return fPortBuffer[0].GetCycleDuration();
}
//jack<->buffer
void RenderFromJackPorts (int subcycle );
void RenderToJackPorts ( int cycle, int subcycle);
void FinishRenderToJackPorts (int cycle);
int RenderFromJackPorts (int subcycle );
int RenderToJackPorts ( int cycle, int subcycle);
//void FinishRenderToJackPorts (int cycle);
//network<->buffer
int RenderFromNetwork ( int subcycle, size_t copy_size )
{
// TODO
return 0;
}
int RenderToNetwork ( int subcycle, size_t total_size )
{
// TODO
return 0;
}

void SetBuffer ( int index, sample_t* buffer );
sample_t* GetBuffer ( int index );
};
*/

//utility *************************************************************************************



+ 5
- 4
macosx/iphone/main_slave.mm View File

@@ -33,7 +33,7 @@ static int net_process(jack_nframes_t buffer_size,
void* data)
{

//jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size);
jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size);
// Process input, produce output
if (audio_input == audio_output) {
@@ -47,7 +47,7 @@ static int net_process(jack_nframes_t buffer_size,

static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void* arg)
{
//jack_adapter_push_and_pull(adapter, inputs, outputs, frames);
jack_adapter_push_and_pull(adapter, inputs, outputs, frames);
}

//http://www.securityfocus.com/infocus/1884
@@ -62,8 +62,8 @@ int main(int argc, char *argv[]) {
jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, WIFI_MTU, -1, JackSlowMode };
jack_master_t result;

//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) {
if ((net = jack_net_slave_open("169.254.46.132", DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
//if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
return -1;
}
@@ -77,6 +77,7 @@ int main(int argc, char *argv[]) {
return -1;
}
TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT);

jack_set_net_slave_process_callback(net, net_process, NULL);


Loading…
Cancel
Save