@@ -149,6 +149,8 @@ struct JackNetExtMaster : public JackNetMasterInterface { | |||
JackMidiBuffer** fMidiPlaybackBuffer; | |||
jack_master_t fRequest; | |||
int fPacketTimeOut; | |||
JackNetExtMaster(const char* ip, | |||
int port, | |||
@@ -472,7 +474,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { | |||
return SOCKET_ERROR; | |||
} | |||
//send data | |||
// send data | |||
if (DataSend() == SOCKET_ERROR) { | |||
return SOCKET_ERROR; | |||
} | |||
@@ -521,7 +523,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf | |||
JackMidiBuffer** fMidiPlaybackBuffer; | |||
int fConnectTimeOut; | |||
JackNetExtSlave(const char* ip, | |||
int port, | |||
const char* name, | |||
@@ -767,6 +769,12 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf | |||
bool Execute() | |||
{ | |||
try { | |||
/* | |||
Fist cycle use an INT_MAX time out, so that connection | |||
is considered established (with PACKET_TIMEOUT later on) | |||
when the first cycle has been done. | |||
*/ | |||
DummyProcess(); | |||
// keep running even in case of error | |||
while (fThread.GetStatus() == JackThread::kRunning) { | |||
if (Process() == SOCKET_ERROR) { | |||
@@ -821,6 +829,18 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf | |||
return DataSend(); | |||
} | |||
void DummyProcess() | |||
{ | |||
// First cycle with INT_MAX time out | |||
SetPackedTimeOut(INT_MAX); | |||
// One cycle | |||
Process(); | |||
// Then use PACKET_TIMEOUT for next cycles | |||
SetPackedTimeOut(PACKET_TIMEOUT); | |||
} | |||
int Process() | |||
{ | |||
@@ -52,7 +52,7 @@ namespace Jack | |||
fParams.fNetworkLatency = 2; | |||
fParams.fSampleEncoder = JackFloatEncoder; | |||
fClient = jack_client; | |||
// Possibly use env variable | |||
const char* default_udp_port = getenv("JACK_NETJACK_PORT"); | |||
udp_port = (default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT; | |||
@@ -262,10 +262,11 @@ namespace Jack | |||
{ | |||
try { | |||
// Keep running even in case of error | |||
while (fThread.GetStatus() == JackThread::kRunning) | |||
while (fThread.GetStatus() == JackThread::kRunning) { | |||
if (Process() == SOCKET_ERROR) { | |||
return false; | |||
} | |||
} | |||
return false; | |||
} catch (JackNetException& e) { | |||
// Otherwise just restart... | |||
@@ -50,7 +50,7 @@ namespace Jack | |||
//adapter thread | |||
JackThread fThread; | |||
//transport | |||
void EncodeTransportData(); | |||
void DecodeTransportData(); | |||
@@ -185,17 +185,20 @@ namespace Jack | |||
delete[] fMidiCapturePortList; | |||
delete[] fMidiPlaybackPortList; | |||
fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; | |||
fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels]; | |||
assert(fMidiCapturePortList); | |||
assert(fMidiPlaybackPortList); | |||
for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { | |||
fMidiCapturePortList[midi_port_index] = 0; | |||
if (fParams.fSendMidiChannels > 0) { | |||
fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; | |||
assert(fMidiCapturePortList); | |||
for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { | |||
fMidiCapturePortList[midi_port_index] = 0; | |||
} | |||
} | |||
for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { | |||
fMidiPlaybackPortList[midi_port_index] = 0; | |||
if (fParams.fReturnMidiChannels > 0) { | |||
fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels]; | |||
assert(fMidiPlaybackPortList); | |||
for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { | |||
fMidiPlaybackPortList[midi_port_index] = 0; | |||
} | |||
} | |||
// Register jack ports | |||
@@ -504,17 +507,17 @@ namespace Jack | |||
void JackNetDriver::EncodeTransportData() | |||
{ | |||
//is there a timebase master change ? | |||
// is there a timebase master change ? | |||
int refnum; | |||
bool conditional; | |||
fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional); | |||
if (refnum != fLastTimebaseMaster) { | |||
//timebase master has released its function | |||
// timebase master has released its function | |||
if (refnum == -1) { | |||
fReturnTransportData.fTimebaseMaster = RELEASE_TIMEBASEMASTER; | |||
jack_info("Sending a timebase master release request."); | |||
} else { | |||
//there is a new timebase master | |||
// there is a new timebase master | |||
fReturnTransportData.fTimebaseMaster = (conditional) ? CONDITIONAL_TIMEBASEMASTER : TIMEBASEMASTER; | |||
jack_info("Sending a %s timebase master request.", (conditional) ? "conditional" : "non-conditional"); | |||
} | |||
@@ -523,10 +526,10 @@ namespace Jack | |||
fReturnTransportData.fTimebaseMaster = NO_CHANGE; | |||
} | |||
//update transport state and position | |||
// update transport state and position | |||
fReturnTransportData.fState = fEngineControl->fTransport.Query(&fReturnTransportData.fPosition); | |||
//is it a new state (that the master need to know...) ? | |||
// is it a new state (that the master need to know...) ? | |||
fReturnTransportData.fNewState = ((fReturnTransportData.fState == JackTransportNetStarting) && | |||
(fReturnTransportData.fState != fLastTransportState) && | |||
(fReturnTransportData.fState != fSendTransportData.fState)); | |||
@@ -540,7 +543,7 @@ namespace Jack | |||
int JackNetDriver::Read() | |||
{ | |||
//buffers | |||
// buffers | |||
for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { | |||
fNetMidiCaptureBuffer->SetBuffer(midi_port_index, GetMidiInputBuffer(midi_port_index)); | |||
} | |||
@@ -584,7 +587,7 @@ namespace Jack | |||
#ifdef JACK_MONITOR | |||
fNetTimeMon->Add(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f); | |||
#endif | |||
//audio, midi or sync if driver is late | |||
// audio, midi or sync if driver is late | |||
switch (DataRecv()) { | |||
case SOCKET_ERROR: | |||
@@ -596,7 +599,7 @@ namespace Jack | |||
break; | |||
} | |||
//take the time at the beginning of the cycle | |||
// take the time at the beginning of the cycle | |||
JackDriver::CycleTakeBeginTime(); | |||
#ifdef JACK_MONITOR | |||
@@ -608,7 +611,7 @@ namespace Jack | |||
int JackNetDriver::Write() | |||
{ | |||
//buffers | |||
// buffers | |||
for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { | |||
fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, GetMidiOutputBuffer(midi_port_index)); | |||
} | |||
@@ -631,10 +634,9 @@ namespace Jack | |||
fNetTimeMon->AddLast(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f); | |||
#endif | |||
//sync | |||
EncodeSyncPacket(); | |||
//send sync | |||
// send sync | |||
if (SyncSend() == SOCKET_ERROR) { | |||
return SOCKET_ERROR; | |||
} | |||
@@ -643,7 +645,7 @@ namespace Jack | |||
fNetTimeMon->Add(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f); | |||
#endif | |||
//send data | |||
// send data | |||
if (DataSend() == SOCKET_ERROR) { | |||
return SOCKET_ERROR; | |||
} | |||
@@ -52,7 +52,7 @@ namespace Jack | |||
int fWantedMIDIPlaybackChannels; | |||
bool fAutoSave; | |||
//monitoring | |||
#ifdef JACK_MONITOR | |||
JackGnuPlotMonitor<float>* fNetTimeMon; | |||
@@ -63,6 +63,7 @@ namespace Jack | |||
fNetMidiPlaybackBuffer = NULL; | |||
memset(&fSendTransportData, 0, sizeof(net_transport_data_t)); | |||
memset(&fReturnTransportData, 0, sizeof(net_transport_data_t)); | |||
fPacketTimeOut = PACKET_TIMEOUT; | |||
} | |||
void JackNetInterface::FreeNetworkBuffers() | |||
@@ -255,7 +256,7 @@ namespace Jack | |||
void JackNetInterface::SetRcvTimeOut() | |||
{ | |||
if (!fSetTimeOut) { | |||
if (fSocket.SetTimeOut(PACKET_TIMEOUT) == SOCKET_ERROR) { | |||
if (fSocket.SetTimeOut(fPacketTimeOut) == SOCKET_ERROR) { | |||
jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE)); | |||
return; | |||
} | |||
@@ -854,6 +855,8 @@ namespace Jack | |||
int JackNetSlaveInterface::SyncRecv() | |||
{ | |||
SetRcvTimeOut(); | |||
int rx_bytes = 0; | |||
packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer); | |||
@@ -875,8 +878,6 @@ namespace Jack | |||
} | |||
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | |||
SetRcvTimeOut(); | |||
return rx_bytes; | |||
} | |||
@@ -49,6 +49,7 @@ namespace Jack | |||
protected: | |||
bool fSetTimeOut; | |||
int fPacketTimeOut; | |||
void Initialize(); | |||
@@ -112,6 +113,12 @@ namespace Jack | |||
int FinishRecv(NetAudioBuffer* buffer); | |||
void SetRcvTimeOut(); | |||
void SetPackedTimeOut(int time_out) | |||
{ | |||
// New time out | |||
fPacketTimeOut = time_out; | |||
fSetTimeOut = false; | |||
} | |||
NetAudioBuffer* AudioBufferFactory(int nports, char* buffer); | |||
@@ -62,7 +62,7 @@ namespace Jack | |||
for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { | |||
fMidiPlaybackPorts[port_index] = NULL; | |||
} | |||
//monitor | |||
#ifdef JACK_MONITOR | |||
fPeriodUsecs = (int)(1000000.f * ((float) fParams.fPeriodSize / (float) fParams.fSampleRate)); | |||
@@ -509,7 +509,7 @@ namespace Jack | |||
#endif | |||
} | |||
//encode the first packet | |||
// encode the first packet | |||
EncodeSyncPacket(); | |||
if (SyncSend() == SOCKET_ERROR) { | |||
@@ -520,7 +520,7 @@ namespace Jack | |||
fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f); | |||
#endif | |||
//send data | |||
// send data | |||
if (DataSend() == SOCKET_ERROR) { | |||
return SOCKET_ERROR; | |||
} | |||
@@ -529,7 +529,7 @@ namespace Jack | |||
fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f); | |||
#endif | |||
//receive sync | |||
// receive sync | |||
int res = SyncRecv(); | |||
switch (res) { | |||
@@ -542,7 +542,7 @@ namespace Jack | |||
break; | |||
default: | |||
//decode sync | |||
// Decode sync | |||
DecodeSyncPacket(); | |||
break; | |||
} | |||
@@ -551,7 +551,7 @@ namespace Jack | |||
fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f); | |||
#endif | |||
//receive data | |||
// receive data | |||
res = DataRecv(); | |||
switch (res) { | |||
@@ -60,7 +60,7 @@ namespace Jack | |||
//sync and transport | |||
int fLastTransportState; | |||
//monitoring | |||
#ifdef JACK_MONITOR | |||
jack_time_t fPeriodUsecs; | |||
@@ -148,6 +148,10 @@ main (int argc, char *argv[]) | |||
*/ | |||
//usleep(5*1000000); | |||
printf("Wait...\n"); | |||
//sleep(10); | |||
usleep(1000000); | |||
printf("Wait...OK\n"); | |||
while (1) { | |||
@@ -161,6 +165,8 @@ main (int argc, char *argv[]) | |||
printf("jack_net_master_send failure, exiting\n"); | |||
break; | |||
} | |||
usleep(10000); | |||
if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { | |||
printf("jack_net_master_recv failure, exiting\n"); | |||