git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3939 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.8
@@ -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]; | |||
@@ -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; | |||
} | |||
@@ -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(); | |||
// 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 ************************************************************************************* | |||
@@ -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); | |||