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; return -1;


// Set global parameters // Set global parameters
SetParams();
if (!SetParams())
return -1;
AllocPorts(); AllocPorts();
return 0; return 0;
} }
@@ -465,12 +467,12 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
int Open(jack_master_t* result) int Open(jack_master_t* result)
{ {
// Init network connection // Init network connection
if (!JackNetSlaveInterface::InitConnection()){
if (!JackNetSlaveInterface::InitConnection())
return -1; return -1;
}
// Then set global parameters // Then set global parameters
SetParams();
if (!SetParams())
return -1;
// Set result // Set result
if (result != NULL) { if (result != NULL) {
@@ -494,7 +496,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
return -1; return -1;
// Then set global parameters // Then set global parameters
SetParams();
if (!SetParams())
return -1;
// We need to notify possibly new buffer size and sample rate (see Execute) // We need to notify possibly new buffer size and sample rate (see Execute)
if (fBufferSizeCallback) if (fBufferSizeCallback)
@@ -514,6 +517,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
return 0; return 0;
} }



void AllocPorts() void AllocPorts()
{ {
unsigned int port_index; unsigned int port_index;
@@ -939,7 +943,7 @@ SERVER_EXPORT void jack_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); 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); va_end(ap);
} }




+ 3
- 2
common/JackNetDriver.cpp View File

@@ -142,11 +142,12 @@ namespace Jack
( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" ); ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" );


//init network //init network
if ( !JackNetSlaveInterface::Init() )
if (!JackNetSlaveInterface::Init())
return false; return false;


//set global parameters //set global parameters
SetParams();
if (!SetParams())
return false;
//allocate midi ports lists //allocate midi ports lists
fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels];


+ 111
- 136
common/JackNetInterface.cpp View File

@@ -89,88 +89,45 @@ namespace Jack
delete fNetMidiPlaybackBuffer; 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() int JackNetInterface::SetNetBufferSize()
{ {
float audio_size, midi_size;
int bufsize;
//audio //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
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 = 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); jack_log("SetNetBufferSize bufsize = %d", bufsize);


//tx buffer //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; return SOCKET_ERROR;


//rx buffer //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 SOCKET_ERROR;


return 0; 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 //TX header init
strcpy ( fTxHeader.fPacketType, "header" ); strcpy ( fTxHeader.fPacketType, "header" );
fTxHeader.fID = fParams.fID; fTxHeader.fID = fParams.fID;
fTxHeader.fCycle = 0; fTxHeader.fCycle = 0;
fTxHeader.fSubCycle = 0; fTxHeader.fSubCycle = 0;
fTxHeader.fMidiDataSize = 0;
fTxHeader.fBitdepth = fParams.fBitdepth; fTxHeader.fBitdepth = fParams.fBitdepth;
fTxHeader.fIsLastPckt = 0; fTxHeader.fIsLastPckt = 0;


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


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


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


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

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


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


float time = 0; float time = 0;
//slow or normal mode, short timeout on recv (2 audio subcycles) //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 //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" ); jack_log ( "JackNetMasterInterface::SetParams" );


@@ -303,6 +252,28 @@ namespace Jack
assert ( fNetAudioCaptureBuffer ); assert ( fNetAudioCaptureBuffer );
assert ( fNetAudioPlaybackBuffer ); 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() void JackNetMasterInterface::Exit()
@@ -402,18 +373,21 @@ namespace Jack
int JackNetMasterInterface::DataSend() int JackNetMasterInterface::DataSend()
{ {
uint subproc; uint subproc;
uint data_size;
//midi //midi
if ( fParams.fSendMidiChannels > 0) if ( fParams.fSendMidiChannels > 0)
{ {
//set global header fields and get the number of midi packets //set global header fields and get the number of midi packets
fTxHeader.fDataType = 'm'; 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.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); memcpy ( fTxBuffer, &fTxHeader, HEADER_SIZE);
if (Send (fTxHeader.fPacketSize, 0) == SOCKET_ERROR) if (Send (fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR; return SOCKET_ERROR;
@@ -424,15 +398,15 @@ namespace Jack
if ( fParams.fSendAudioChannels > 0) if ( fParams.fSendAudioChannels > 0)
{ {
fTxHeader.fDataType = 'a'; 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.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); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
fNetAudioCaptureBuffer->RenderFromJackPorts(subproc);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR; return SOCKET_ERROR;
} }
@@ -506,8 +480,8 @@ namespace Jack
int JackNetMasterInterface::DataRecv() int JackNetMasterInterface::DataRecv()
{ {
int rx_bytes = 0; int rx_bytes = 0;
int last_cycle = 0;
uint recvd_midi_pckt = 0; uint recvd_midi_pckt = 0;
uint recvd_audio_pckt = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
@@ -530,34 +504,30 @@ namespace Jack
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 - HEADER_SIZE); 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(); fNetMidiPlaybackBuffer->RenderToJackPorts();
break; break;


case 'a': //audio case 'a': //audio
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (!IsNextPacket()) {
jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName);
}
fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; 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; break;


case 's': //sync case 's': //sync
jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName); 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; return 0;
} }
} }
} }
// Finish rendering (copy to JACK ports)
fNetAudioPlaybackBuffer->FinishRenderToJackPorts(last_cycle);
return rx_bytes; return rx_bytes;
} }
@@ -727,18 +697,11 @@ namespace Jack
SessionParamsDisplay(&host_params); SessionParamsDisplay(&host_params);
fParams = 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 //connect the socket
if ( fSocket.Connect() == SOCKET_ERROR ) { if ( fSocket.Connect() == SOCKET_ERROR ) {
jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) ); jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) );
return NET_CONNECT_ERROR; return NET_CONNECT_ERROR;
} }

return NET_CONNECTED; return NET_CONNECTED;
} }


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


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


@@ -783,6 +746,21 @@ namespace Jack
assert ( fNetAudioCaptureBuffer ); assert ( fNetAudioCaptureBuffer );
assert ( fNetAudioPlaybackBuffer ); 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 ) int JackNetSlaveInterface::Recv ( size_t size, int flags )
@@ -852,8 +830,9 @@ namespace Jack
int JackNetSlaveInterface::DataRecv() int JackNetSlaveInterface::DataRecv()
{ {
int rx_bytes = 0; int rx_bytes = 0;
int last_cycle = 0;
//int last_cycle = 0;
uint recvd_midi_pckt = 0; uint recvd_midi_pckt = 0;
uint recvd_audio_pckt = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );


@@ -876,33 +855,29 @@ namespace Jack
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); 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->fNumPacket )
fNetMidiCaptureBuffer->RenderToJackPorts(); fNetMidiCaptureBuffer->RenderToJackPorts();
break; break;


case 'a': //audio case 'a': //audio
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (!IsNextPacket()) {
jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName);
}
fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; 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; break;


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


//midi //midi
if (fParams.fReturnMidiChannels > 0) if (fParams.fReturnMidiChannels > 0)
{ {
//set global header fields and get the number of midi packets //set global header fields and get the number of midi packets
fTxHeader.fDataType = 'm'; 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.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); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR; return SOCKET_ERROR;
@@ -950,15 +926,14 @@ namespace Jack
if ( fParams.fReturnAudioChannels > 0) if ( fParams.fReturnAudioChannels > 0)
{ {
fTxHeader.fDataType = 'a'; 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.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); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
fNetAudioPlaybackBuffer->RenderFromJackPorts (subproc);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR; return SOCKET_ERROR;
} }


+ 5
- 9
common/JackNetInterface.h View File

@@ -35,8 +35,7 @@ namespace Jack
session_params_t fParams; session_params_t fParams;
JackNetSocket fSocket; JackNetSocket fSocket;
char fMulticastIP[32]; char fMulticastIP[32];
uint fNSubProcess;

//headers //headers
packet_header_t fTxHeader; packet_header_t fTxHeader;
packet_header_t fRxHeader; packet_header_t fRxHeader;
@@ -58,13 +57,10 @@ namespace Jack
NetAudioBuffer* fNetAudioPlaybackBuffer; NetAudioBuffer* fNetAudioPlaybackBuffer;


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

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


//transport //transport
@@ -103,7 +99,7 @@ namespace Jack


bool Init(); bool Init();
int SetRxTimeout(); int SetRxTimeout();
void SetParams();
bool SetParams();
void Exit(); void Exit();
@@ -149,7 +145,7 @@ namespace Jack
net_status_t SendAvailableToMaster(); net_status_t SendAvailableToMaster();
net_status_t SendStartToMaster(); net_status_t SendStartToMaster();
void SetParams();
bool SetParams();
int SyncRecv(); int SyncRecv();
int SyncSend(); int SyncSend();


+ 5
- 4
common/JackNetManager.cpp View File

@@ -113,11 +113,12 @@ namespace Jack
bool JackNetMaster::Init(bool auto_connect) bool JackNetMaster::Init(bool auto_connect)
{ {
//network init //network init
if ( !JackNetMasterInterface::Init() )
if (!JackNetMasterInterface::Init())
return false; return false;


//set global parameters //set global parameters
SetParams();
if (!SetParams())
return false;


//jack client and process //jack client and process
jack_status_t status; jack_status_t status;
@@ -415,7 +416,7 @@ namespace Jack
for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ ) for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
fNetMidiPlaybackBuffer->SetBuffer ( port_index, static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiPlaybackPorts[port_index], fNetMidiPlaybackBuffer->SetBuffer ( port_index, static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiPlaybackPorts[port_index],
fParams.fPeriodSize ) ) ); 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], fNetAudioPlaybackBuffer->SetBuffer ( port_index, static_cast<sample_t*> ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index],
fParams.fPeriodSize ) ) ); fParams.fPeriodSize ) ) );


@@ -601,7 +602,7 @@ namespace Jack
if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR ) if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR )
jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); 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 //main loop, wait for data, deal with it and wait again
do do


+ 51
- 17
common/JackNetTool.cpp View File

@@ -35,6 +35,9 @@ namespace Jack
for ( int port_index = 0; port_index < fNPorts; port_index++ ) for ( int port_index = 0; port_index < fNPorts; port_index++ )
fPortBuffer[port_index] = NULL; fPortBuffer[port_index] = NULL;
fNetBuffer = net_buffer; fNetBuffer = net_buffer;
fCycleSize = params->fMtu * (max(params->fSendMidiChannels, params->fReturnMidiChannels) *
params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t)));
} }


NetMidiBuffer::~NetMidiBuffer() NetMidiBuffer::~NetMidiBuffer()
@@ -47,6 +50,23 @@ namespace Jack
{ {
return fMaxBufsize; 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 ) void NetMidiBuffer::SetBuffer ( int index, JackMidiBuffer* buffer )
{ {
@@ -124,10 +144,8 @@ namespace Jack
return copy_size; return copy_size;
} }



// net audio buffer ********************************************************************************* // net audio buffer *********************************************************************************



NetSingleAudioBuffer::NetSingleAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) NetSingleAudioBuffer::NetSingleAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer )
: fPortBuffer(params, nports), fNetBuffer(net_buffer) : fPortBuffer(params, nports), fNetBuffer(net_buffer)
{} {}
@@ -139,6 +157,11 @@ namespace Jack
{ {
return fPortBuffer.GetSize(); return fPortBuffer.GetSize();
} }
size_t NetSingleAudioBuffer::GetCycleSize()
{
return fPortBuffer.GetCycleSize();
}


void NetSingleAudioBuffer::SetBuffer ( int index, sample_t* buffer ) void NetSingleAudioBuffer::SetBuffer ( int index, sample_t* buffer )
{ {
@@ -150,18 +173,30 @@ namespace Jack
return fPortBuffer.GetBuffer(index); 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 // Buffered


/*
NetBufferedAudioBuffer::NetBufferedAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) NetBufferedAudioBuffer::NetBufferedAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer )
{ {
fMaxCycle = 0; fMaxCycle = 0;
@@ -172,7 +207,7 @@ namespace Jack
} }
fJackPortBuffer = new sample_t* [nports]; 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; fJackPortBuffer[port_index] = NULL;
} }


@@ -185,6 +220,11 @@ namespace Jack
{ {
return fPortBuffer[0].GetSize(); return fPortBuffer[0].GetSize();
} }
size_t NetBufferedAudioBuffer::GetCycleSize()
{
return fPortBuffer[0].GetCycleSize();
}


void NetBufferedAudioBuffer::SetBuffer ( int index, sample_t* buffer ) void NetBufferedAudioBuffer::SetBuffer ( int index, sample_t* buffer )
{ {
@@ -214,6 +254,7 @@ namespace Jack
fMaxCycle = std::max(fMaxCycle, cycle); fMaxCycle = std::max(fMaxCycle, cycle);
fPortBuffer[(cycle + 1) % AUDIO_BUFFER_SIZE].Copy(fJackPortBuffer); // Copy internal buffer in JACK ports fPortBuffer[(cycle + 1) % AUDIO_BUFFER_SIZE].Copy(fJackPortBuffer); // Copy internal buffer in JACK ports
} }
*/


// SessionParams ************************************************************************************ // SessionParams ************************************************************************************


@@ -230,7 +271,6 @@ namespace Jack
dst_params->fReturnMidiChannels = htonl ( src_params->fReturnMidiChannels ); dst_params->fReturnMidiChannels = htonl ( src_params->fReturnMidiChannels );
dst_params->fSampleRate = htonl ( src_params->fSampleRate ); dst_params->fSampleRate = htonl ( src_params->fSampleRate );
dst_params->fPeriodSize = htonl ( src_params->fPeriodSize ); dst_params->fPeriodSize = htonl ( src_params->fPeriodSize );
dst_params->fFramesPerPacket = htonl ( src_params->fFramesPerPacket );
dst_params->fBitdepth = htonl ( src_params->fBitdepth ); dst_params->fBitdepth = htonl ( src_params->fBitdepth );
dst_params->fSlaveSyncMode = htonl ( src_params->fSlaveSyncMode ); dst_params->fSlaveSyncMode = htonl ( src_params->fSlaveSyncMode );
} }
@@ -248,7 +288,6 @@ namespace Jack
dst_params->fReturnMidiChannels = ntohl ( src_params->fReturnMidiChannels ); dst_params->fReturnMidiChannels = ntohl ( src_params->fReturnMidiChannels );
dst_params->fSampleRate = ntohl ( src_params->fSampleRate ); dst_params->fSampleRate = ntohl ( src_params->fSampleRate );
dst_params->fPeriodSize = ntohl ( src_params->fPeriodSize ); dst_params->fPeriodSize = ntohl ( src_params->fPeriodSize );
dst_params->fFramesPerPacket = ntohl ( src_params->fFramesPerPacket );
dst_params->fBitdepth = ntohl ( src_params->fBitdepth ); dst_params->fBitdepth = ntohl ( src_params->fBitdepth );
dst_params->fSlaveSyncMode = ntohl ( src_params->fSlaveSyncMode ); 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 ( "Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels );
jack_info ( "Sample rate : %u frames per second", params->fSampleRate ); jack_info ( "Sample rate : %u frames per second", params->fSampleRate );
jack_info ( "Period size : %u frames per period", params->fPeriodSize ); 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 ( "Bitdepth : %s", bitdepth );
jack_info ( "Slave mode : %s", ( params->fSlaveSyncMode ) ? "sync" : "async" ); jack_info ( "Slave mode : %s", ( params->fSlaveSyncMode ) ? "sync" : "async" );
jack_info ( "Network mode : %s", mode ); jack_info ( "Network mode : %s", mode );
@@ -338,9 +375,8 @@ namespace Jack
{ {
memcpy(dst_header, src_header, sizeof(packet_header_t)); memcpy(dst_header, src_header, sizeof(packet_header_t));
dst_header->fID = htonl ( src_header->fID ); dst_header->fID = htonl ( src_header->fID );
dst_header->fMidiDataSize = htonl ( src_header->fMidiDataSize );
dst_header->fBitdepth = htonl ( src_header->fBitdepth ); 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->fPacketSize = htonl ( src_header->fPacketSize );
dst_header->fCycle = htonl ( src_header->fCycle ); dst_header->fCycle = htonl ( src_header->fCycle );
dst_header->fSubCycle = htonl ( src_header->fSubCycle ); dst_header->fSubCycle = htonl ( src_header->fSubCycle );
@@ -351,9 +387,8 @@ namespace Jack
{ {
memcpy(dst_header, src_header, sizeof(packet_header_t)); memcpy(dst_header, src_header, sizeof(packet_header_t));
dst_header->fID = ntohl ( src_header->fID ); dst_header->fID = ntohl ( src_header->fID );
dst_header->fMidiDataSize = ntohl ( src_header->fMidiDataSize );
dst_header->fBitdepth = ntohl ( src_header->fBitdepth ); 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->fPacketSize = ntohl ( src_header->fPacketSize );
dst_header->fCycle = ntohl ( src_header->fCycle ); dst_header->fCycle = ntohl ( src_header->fCycle );
dst_header->fSubCycle = ntohl ( src_header->fSubCycle ); dst_header->fSubCycle = ntohl ( src_header->fSubCycle );
@@ -370,8 +405,7 @@ namespace Jack
jack_info ( "ID : %u", header->fID ); jack_info ( "ID : %u", header->fID );
jack_info ( "Cycle : %u", header->fCycle ); jack_info ( "Cycle : %u", header->fCycle );
jack_info ( "SubCycle : %u", header->fSubCycle ); 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 ( "Last packet : '%s'", ( header->fIsLastPckt ) ? "yes" : "no" );
jack_info ( "Bitdepth : %s", bitdepth ); jack_info ( "Bitdepth : %s", bitdepth );
jack_info ( "**********************************************" ); 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). 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 struct _session_params
{ {
@@ -87,7 +87,6 @@ namespace Jack
uint32_t fReturnMidiChannels; //number of slave->master midi channels uint32_t fReturnMidiChannels; //number of slave->master midi channels
uint32_t fSampleRate; //session sample rate uint32_t fSampleRate; //session sample rate
uint32_t fPeriodSize; //period size uint32_t fPeriodSize; //period size
uint32_t fFramesPerPacket; //complete frames per packet
uint32_t fBitdepth; //samples bitdepth (unused) uint32_t fBitdepth; //samples bitdepth (unused)
uint32_t fSlaveSyncMode; //is the slave in sync mode ? uint32_t fSlaveSyncMode; //is the slave in sync mode ?
char fNetworkMode; //fast, normal or slow mode char fNetworkMode; //fast, normal or slow mode
@@ -159,14 +158,11 @@ namespace Jack
char fDataStream; //s for send, r for return char fDataStream; //s for send, r for return
uint32_t fID; //unique ID of the slave uint32_t fID; //unique ID of the slave
uint32_t fBitdepth; //bitdepth of the data samples 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 fPacketSize; //packet size in bytes
uint32_t fCycle; //process cycle counter uint32_t fCycle; //process cycle counter
uint32_t fSubCycle; //midi/audio subcycle counter uint32_t fSubCycle; //midi/audio subcycle counter
uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n') 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 //net timebase master
@@ -199,8 +195,8 @@ namespace Jack
int32_t fState; //current cycle state int32_t fState; //current cycle state
jack_position_t fPosition; //current cycle position jack_position_t fPosition; //current cycle position
}; };
//midi data ***********************************************************************************
//midi data ***********************************************************************************


/** /**
\Brief Midi buffer and operations class \Brief Midi buffer and operations class
@@ -226,6 +222,8 @@ namespace Jack
char* fBuffer; char* fBuffer;
char* fNetBuffer; char* fNetBuffer;
JackMidiBuffer** fPortBuffer; JackMidiBuffer** fPortBuffer;
size_t fCycleSize; // needed size in bytes ofr an entire cycle


public: public:
NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer );
@@ -234,6 +232,11 @@ namespace Jack
void Reset(); void Reset();
size_t GetSize(); size_t GetSize();
// needed size in bytes for an entire cycle
size_t GetCycleSize();
int GetNumPackets();
//utility //utility
void DisplayEvents(); void DisplayEvents();
@@ -262,14 +265,21 @@ namespace Jack
virtual size_t GetSize() = 0; 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 //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 //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 void SetBuffer ( int index, sample_t* buffer ) = 0;
virtual sample_t* GetBuffer ( int index ) = 0; virtual sample_t* GetBuffer ( int index ) = 0;
@@ -292,16 +302,39 @@ namespace Jack
size_t fSubPeriodBytesSize; size_t fSubPeriodBytesSize;
sample_t** fPortBuffer; sample_t** fPortBuffer;
int fNPorts; 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) JackPortList(session_params_t* params, uint32_t nports)
{ {
fNPorts = nports; fNPorts = nports;
fPeriodSize = params->fPeriodSize; 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 ); fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t );
fPortBuffer = new sample_t* [fNPorts]; fPortBuffer = new sample_t* [fNPorts];
for ( int port_index = 0; port_index < fNPorts; port_index++ ) for ( int port_index = 0; port_index < fNPorts; port_index++ )
fPortBuffer[port_index] = NULL; fPortBuffer[port_index] = NULL;
fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate);
fCycleSize = params->fMtu * ( fPeriodSize / fSubPeriodBytesSize );
fLastSubCycle = -1;
}
int GetNumPackets()
{
return fPeriodSize / fSubPeriodSize;
} }
JackPortList() JackPortList()
@@ -338,7 +371,19 @@ namespace Jack
{ {
return fNPorts * fSubPeriodBytesSize; 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__ #ifdef __BIG_ENDIAN__


static inline float SwapFloat(float f) static inline float SwapFloat(float f)
@@ -357,40 +402,75 @@ namespace Jack
return dat2.f; 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* src = (float*)(net_buffer + port_index * fSubPeriodBytesSize);
float* dst = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); float* dst = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize);
for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) {
dst[sample] = SwapFloat(src[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 #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++ ) for ( int port_index = 0; port_index < fNPorts; port_index++ )
memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize ); 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 #endif
@@ -419,7 +499,15 @@ namespace Jack
{ {
fNPorts = nports; fNPorts = nports;
fPeriodSize = params->fPeriodSize; 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 ); fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t );
fPortBuffer = new sample_t* [fNPorts]; fPortBuffer = new sample_t* [fNPorts];
for ( int port_index = 0; port_index < fNPorts; port_index++ ) for ( int port_index = 0; port_index < fNPorts; port_index++ )
@@ -439,18 +527,36 @@ namespace Jack
~NetSingleAudioBuffer(); ~NetSingleAudioBuffer();


size_t GetSize(); 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 //jack<->buffer
void RenderFromJackPorts (int subcycle );
void RenderToJackPorts (int cycle, int subcycle);
int RenderFromJackPorts ();
int RenderToJackPorts ();


void SetBuffer ( int index, sample_t* buffer ); void SetBuffer ( int index, sample_t* buffer );
sample_t* GetBuffer ( int index ); 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 #define AUDIO_BUFFER_SIZE 8
/*
class SERVER_EXPORT NetBufferedAudioBuffer : public NetAudioBuffer class SERVER_EXPORT NetBufferedAudioBuffer : public NetAudioBuffer
{ {
@@ -465,14 +571,36 @@ namespace Jack
~NetBufferedAudioBuffer(); ~NetBufferedAudioBuffer();


size_t GetSize(); 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 //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 ); void SetBuffer ( int index, sample_t* buffer );
sample_t* GetBuffer ( int index ); sample_t* GetBuffer ( int index );
}; };
*/


//utility ************************************************************************************* //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) 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 // Process input, produce output
if (audio_input == audio_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) 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 //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_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.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; return -1;
} }
@@ -77,6 +77,7 @@ int main(int argc, char *argv[]) {
return -1; return -1;
} }
TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT);


jack_set_net_slave_process_callback(net, net_process, NULL); jack_set_net_slave_process_callback(net, net_process, NULL);


Loading…
Cancel
Save