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