Browse Source

Code factorization and cleanup.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4505 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.8
sletz 14 years ago
parent
commit
a09a1a5c8a
8 changed files with 431 additions and 274 deletions
  1. +1
    -4
      common/JackLibClient.cpp
  2. +88
    -60
      common/JackNetAPI.cpp
  3. +10
    -5
      common/JackNetAdapter.cpp
  4. +16
    -16
      common/JackNetDriver.cpp
  5. +225
    -115
      common/JackNetInterface.cpp
  6. +56
    -50
      common/JackNetInterface.h
  7. +12
    -9
      common/JackShmMem.h
  8. +23
    -15
      macosx/coreaudio/JackCoreAudioAdapter.cpp

+ 1
- 4
common/JackLibClient.cpp View File

@@ -100,11 +100,8 @@ int JackLibClient::Open(const char* server_name, const char* name, int uuid, jac
JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName);
fClientControl.SetShmIndex(shared_client, fServerName);
JackGlobals::fVerbose = GetEngineControl()->fVerbose;
} catch (int n) {
jack_error("Map shared memory segments exception %d", n);
goto error;
} catch (...) {
jack_error("Unknown error...");
jack_error("Map shared memory segments exception");
goto error;
}



+ 88
- 60
common/JackNetAPI.cpp View File

@@ -40,6 +40,7 @@ extern "C"
JackFloatEncoder = 0,
JackIntEncoder = 1,
JackCeltEncoder = 2,
JackMaxEncoder = 3
};

typedef struct {
@@ -50,9 +51,9 @@ extern "C"
int midi_output;
int mtu;
int time_out; // in millisecond, -1 means in infinite
int encoder;
int encoder; // one of JackNetEncoder
int kbps; // KB per second for CELT encoder
int latency;
int latency; // network cycles

} jack_slave_t;

@@ -183,16 +184,19 @@ struct JackNetExtMaster : public JackNetMasterInterface {
}

// Join multicast group
if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR)
fprintf(stderr, "Can't join multicast group : %s\n", StrError(NET_ERROR_CODE));
if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) {
fprintf(stderr, "Can't join multicast group : %s\n", StrError(NET_ERROR_CODE));
}

// Local loop
if (fSocket.SetLocalLoop() == SOCKET_ERROR)
if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
fprintf(stderr, "Can't set local loop : %s\n", StrError(NET_ERROR_CODE));
}

// Set a timeout on the multicast receive (the thread can now be cancelled)
if (fSocket.SetTimeOut(2000000) == SOCKET_ERROR)
if (fSocket.SetTimeOut(2000000) == SOCKET_ERROR) {
fprintf(stderr, "Can't set timeout : %s\n", StrError(NET_ERROR_CODE));
}

//main loop, wait for data, deal with it and wait again
//utility variables
@@ -271,12 +275,14 @@ struct JackNetExtMaster : public JackNetMasterInterface {
fSocket.Close();

// Network slave init
if (!JackNetMasterInterface::Init())
if (!JackNetMasterInterface::Init()) {
return -1;
}

// Set global parameters
if (!SetParams())
if (!SetParams()) {
return -1;
}

AllocPorts();
return 0;
@@ -369,8 +375,9 @@ struct JackNetExtMaster : public JackNetMasterInterface {
fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_input_buffer)[midi_port_index]);
}

if (SyncRecv() == SOCKET_ERROR)
if (SyncRecv() == SOCKET_ERROR) {
return 0;
}

DecodeSyncPacket();
return DataRecv();
@@ -384,22 +391,23 @@ struct JackNetExtMaster : public JackNetMasterInterface {
int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer)
{
try {
assert(audio_output == fParams.fSendAudioChannels);
assert(audio_output == fParams.fSendAudioChannels);

for (int audio_port_index = 0; audio_port_index < audio_output; audio_port_index++) {
fNetAudioCaptureBuffer->SetBuffer(audio_port_index, audio_output_buffer[audio_port_index]);
}
for (int audio_port_index = 0; audio_port_index < audio_output; audio_port_index++) {
fNetAudioCaptureBuffer->SetBuffer(audio_port_index, audio_output_buffer[audio_port_index]);
}

for (int midi_port_index = 0; midi_port_index < midi_output; midi_port_index++) {
fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]);
}
for (int midi_port_index = 0; midi_port_index < midi_output; midi_port_index++) {
fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]);
}

EncodeSyncPacket();
EncodeSyncPacket();

if (SyncSend() == SOCKET_ERROR)
return SOCKET_ERROR;
if (SyncSend() == SOCKET_ERROR) {
return SOCKET_ERROR;
}

return DataSend();
return DataSend();

} catch (JackNetException& e) {
jack_error("Connection lost.");
@@ -486,13 +494,20 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf

int Open(jack_master_t* result)
{
if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) {
printf("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY);
return -1;
}

// Init network connection
if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut))
if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
return -1;
}

// Then set global parameters
if (!SetParams())
if (!SetParams()) {
return -1;
}

// Set result
if (result != NULL) {
@@ -512,23 +527,28 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
int Restart()
{
// If shutdown cb is set, then call it
if (fShutdownCallback)
if (fShutdownCallback) {
fShutdownCallback(fShutdownArg);
}

// Init network connection
if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut))
if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
return -1;
}

// Then set global parameters
if (!SetParams())
if (!SetParams()) {
return -1;
}

// We need to notify possibly new buffer size and sample rate (see Execute)
if (fBufferSizeCallback)
if (fBufferSizeCallback) {
fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg);
}

if (fSampleRateCallback)
if (fSampleRateCallback) {
fSampleRateCallback(fParams.fSampleRate, fSampleRateArg);
}

AllocPorts();
return 0;
@@ -543,62 +563,58 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf

void AllocPorts()
{
int port_index;

// Set buffers
fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels];
for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) {
fAudioCaptureBuffer[port_index] = new float[fParams.fPeriodSize];
fNetAudioCaptureBuffer->SetBuffer(port_index, fAudioCaptureBuffer[port_index]);
for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
fAudioCaptureBuffer[audio_port_index] = new float[fParams.fPeriodSize];
fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]);
}

fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels];
for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) {
fMidiCaptureBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
fNetMidiCaptureBuffer->SetBuffer(port_index, fMidiCaptureBuffer[port_index]);
for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
fMidiCaptureBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]);
}

fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels];
for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) {
fAudioPlaybackBuffer[port_index] = new float[fParams.fPeriodSize];
fNetAudioPlaybackBuffer->SetBuffer(port_index, fAudioPlaybackBuffer[port_index]);
for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
fAudioPlaybackBuffer[audio_port_index] = new float[fParams.fPeriodSize];
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]);
}

fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels];
for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) {
fMidiPlaybackBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
fNetMidiPlaybackBuffer->SetBuffer(port_index, fMidiPlaybackBuffer[port_index]);
for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
fMidiPlaybackBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]);
}
}

void FreePorts()
{
int port_index;

if (fAudioCaptureBuffer) {
for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++)
delete[] fAudioCaptureBuffer[port_index];
for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++)
delete[] fAudioCaptureBuffer[audio_port_index];
delete[] fAudioCaptureBuffer;
fAudioCaptureBuffer = NULL;
}

if (fMidiCaptureBuffer) {
for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++)
delete[] (fMidiCaptureBuffer[port_index]);
for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++)
delete[] (fMidiCaptureBuffer[midi_port_index]);
delete[] fMidiCaptureBuffer;
fMidiCaptureBuffer = NULL;
}

if (fAudioPlaybackBuffer) {
for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++)
delete[] fAudioPlaybackBuffer[port_index];
for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++)
delete[] fAudioPlaybackBuffer[audio_port_index];
delete[] fAudioPlaybackBuffer;
fAudioPlaybackBuffer = NULL;
}

if (fMidiPlaybackBuffer) {
for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++)
delete[] fMidiPlaybackBuffer[port_index];
for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++)
delete[] fMidiPlaybackBuffer[midi_port_index];
delete[] fMidiPlaybackBuffer;
fMidiPlaybackBuffer = NULL;
}
@@ -647,8 +663,9 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
{
// Don't return -1 in case of sync recv failure
// we need the process to continue for network error detection
if (SyncRecv() == SOCKET_ERROR)
if (SyncRecv() == SOCKET_ERROR) {
return 0;
}

DecodeSyncPacket();
return DataRecv();
@@ -658,8 +675,9 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
{
EncodeSyncPacket();

if (SyncSend() == SOCKET_ERROR)
if (SyncSend() == SOCKET_ERROR) {
return SOCKET_ERROR;
}

return DataSend();
}
@@ -668,8 +686,9 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
{
// Read data from the network
// in case of fatal network error, stop the process
if (Read() == SOCKET_ERROR)
if (Read() == SOCKET_ERROR) {
return SOCKET_ERROR;
}

fProcessCallback(fParams.fPeriodSize,
fParams.fSendAudioChannels,
@@ -684,8 +703,9 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf

// Then write data to network
// in case of failure, stop process
if (Write() == SOCKET_ERROR)
if (Write() == SOCKET_ERROR) {
return SOCKET_ERROR;
}

return 0;
}
@@ -770,10 +790,12 @@ struct JackNetAdapter : public JackAudioAdapterInterface {
{
//ringbuffers

if (fCaptureChannels > 0)
if (fCaptureChannels > 0) {
fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
if (fPlaybackChannels > 0)
}
if (fPlaybackChannels > 0) {
fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
}

if (fAdaptative) {
AdaptRingBufferSize();
@@ -793,10 +815,12 @@ struct JackNetAdapter : public JackAudioAdapterInterface {
fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
}

if (fCaptureChannels > 0)
if (fCaptureChannels > 0) {
jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
if (fPlaybackChannels > 0)
}
if (fPlaybackChannels > 0) {
jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
}
}

virtual ~JackNetAdapter()
@@ -916,7 +940,11 @@ SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output,
jack_nframes_t adapted_buffer_size,
jack_nframes_t adapted_sample_rate)
{
return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate);
try {
return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate);
} catch (...) {
return NULL;
}
}

SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter)


+ 10
- 5
common/JackNetAdapter.cpp View File

@@ -96,6 +96,10 @@ namespace Jack
#endif
case 'l' :
fParams.fNetworkLatency = param->value.i;
if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) {
jack_error("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY);
throw std::bad_alloc();
}
break;
case 'q':
fQuality = param->value.ui;
@@ -268,20 +272,20 @@ namespace Jack
{
case JackTransportStopped :
jack_transport_stop(fJackClient);
jack_info("NetMaster : transport stops.");
jack_info("NetMaster : transport stops");
break;

case JackTransportStarting :
jack_transport_reposition(fJackClient, &fSendTransportData.fPosition);
jack_transport_start(fJackClient);
jack_info("NetMaster : transport starts.");
jack_info("NetMaster : transport starts");
break;

case JackTransportRolling :
// TODO, we need to :
// - find a way to call TransportEngine->SetNetworkSync()
// - turn the transport state to JackTransportRolling
jack_info("NetMaster : transport rolls.");
jack_info("NetMaster : transport rolls");
break;
}
}
@@ -404,8 +408,8 @@ extern "C"
value.ui = 1U;
jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL);

strcpy(value.str, "slow");
jack_driver_descriptor_add_parameter(desc, &filler, "mode", 'm', JackDriverParamString, &value, NULL, "Slow, Normal or Fast mode.", NULL);
value.ui = 2U;
jack_driver_descriptor_add_parameter(desc, &filler, "latency", 'l', JackDriverParamUInt, &value, NULL, "Network latency", NULL);

value.i = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL);
@@ -440,6 +444,7 @@ extern "C"
}

} catch (...) {
jack_info("NetAdapter allocation error");
return 1;
}
}


+ 16
- 16
common/JackNetDriver.cpp View File

@@ -35,8 +35,9 @@ namespace Jack
jack_log("JackNetDriver::JackNetDriver ip %s, port %d", ip, udp_port);

// Use the hostname if no name parameter was given
if (strcmp(net_name, "") == 0)
if (strcmp(net_name, "") == 0) {
GetHostName(net_name, JACK_CLIENT_NAME_SIZE);
}

fParams.fMtu = mtu;
fParams.fSendMidiChannels = midi_input_ports;
@@ -94,8 +95,9 @@ namespace Jack
int JackNetDriver::Close()
{
#ifdef JACK_MONITOR
if (fNetTimeMon)
if (fNetTimeMon) {
fNetTimeMon->Save();
}
#endif
FreeAll();
return JackDriver::Close();
@@ -420,8 +422,9 @@ namespace Jack
bool conditional;
if (fSendTransportData.fTimebaseMaster == TIMEBASEMASTER) {
fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional);
if (refnum != -1)
if (refnum != -1) {
fEngineControl->fTransport.ResetTimebase(refnum);
}
jack_info("The NetMaster is now the new timebase master.");
}

@@ -503,8 +506,9 @@ namespace Jack
#endif

//receive sync (launch the cycle)
if (SyncRecv() == SOCKET_ERROR)
if (SyncRecv() == SOCKET_ERROR) {
return 0;
}

#ifdef JACK_MONITOR
// For timing
@@ -564,16 +568,18 @@ namespace Jack
EncodeSyncPacket();

//send sync
if (SyncSend() == SOCKET_ERROR)
if (SyncSend() == SOCKET_ERROR) {
return SOCKET_ERROR;
}

#ifdef JACK_MONITOR
fNetTimeMon->Add(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f);
#endif

//send data
if (DataSend() == SOCKET_ERROR)
if (DataSend() == SOCKET_ERROR) {
return SOCKET_ERROR;
}

#ifdef JACK_MONITOR
fNetTimeMon->AddLast(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f);
@@ -699,16 +705,10 @@ namespace Jack
break;
case 'l' :
network_latency = param->value.ui;
/*
if (strcmp(param->value.str, "normal") == 0)
network_mode = 'n';
else if (strcmp(param->value.str, "slow") == 0)
network_mode = 's';
else if (strcmp(param->value.str, "fast") == 0)
network_mode = 'f';
else
jack_error("Unknown network mode, using 'normal' mode.");
*/
if (network_latency > NETWORK_MAX_LATENCY) {
printf("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY);
return NULL;
}
break;
}
}


+ 225
- 115
common/JackNetInterface.cpp View File

@@ -94,27 +94,27 @@ namespace Jack

int JackNetInterface::SetNetBufferSize()
{
//audio
// audio
float audio_size = (fNetAudioCaptureBuffer)
? fNetAudioCaptureBuffer->GetCycleSize()
: (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0;
? fNetAudioCaptureBuffer->GetCycleSize()
: (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0;
jack_log("audio_size %f", audio_size);

//midi
// midi
float midi_size = (fNetMidiCaptureBuffer)
? fNetMidiCaptureBuffer->GetCycleSize()
: (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0;
? fNetMidiCaptureBuffer->GetCycleSize()
: (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0;
jack_log("midi_size %f", midi_size);

//bufsize = sync + audio + midi
int bufsize = NETWORK_MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size);
// bufsize = sync + audio + midi
int bufsize = NETWORK_MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int)midi_size);
jack_log("SetNetBufferSize bufsize = %d", bufsize);

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

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

@@ -123,33 +123,108 @@ namespace Jack

bool JackNetInterface::SetParams()
{
//TX header init
// TX header init
strcpy(fTxHeader.fPacketType, "header");
fTxHeader.fID = fParams.fID;
fTxHeader.fCycle = 0;
fTxHeader.fSubCycle = 0;
fTxHeader.fIsLastPckt = 0;

//RX header init
// RX header init
strcpy(fRxHeader.fPacketType, "header");
fRxHeader.fID = fParams.fID;
fRxHeader.fCycle = 0;
fRxHeader.fSubCycle = 0;
fRxHeader.fIsLastPckt = 0;

//network buffers
// network buffers
fTxBuffer = new char[fParams.fMtu];
fRxBuffer = new char[fParams.fMtu];
assert(fTxBuffer);
assert(fRxBuffer);

//net audio/midi buffers'addresses
// net audio/midi buffers'addresses
fTxData = fTxBuffer + HEADER_SIZE;
fRxData = fRxBuffer + HEADER_SIZE;

return true;
}

int JackNetInterface::MidiSend(NetMidiBuffer* buffer, int midi_channnels, int audio_channels)
{
if (midi_channnels > 0) {
// set global header fields and get the number of midi packets
fTxHeader.fDataType = 'm';
uint data_size = buffer->RenderFromJackPorts();
fTxHeader.fNumPacket = buffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE);

for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
fTxHeader.fSubCycle = subproc;
// fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0;
fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && audio_channels == 0) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, data_size);
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR;
}
}
return 0;
}

int JackNetInterface::AudioSend(NetAudioBuffer* buffer, int audio_channels)
{
// audio
if (audio_channels > 0) {
fTxHeader.fDataType = 'a';
buffer->RenderFromJackPorts();
fTxHeader.fNumPacket = buffer->GetNumPackets();

for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
fTxHeader.fSubCycle = subproc;
fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, fTxHeader.fActivePorts);
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
// PacketHeaderDisplay(&fTxHeader);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR;
}
}
return 0;
}

int JackNetInterface::MidiRecv(packet_header_t* rx_head, NetMidiBuffer* buffer, uint& recvd_midi_pckt)
{
int rx_bytes = Recv(rx_head->fPacketSize, 0);
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
buffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
// Last midi packet is received, so finish rendering...
if (++recvd_midi_pckt == rx_head->fNumPacket)
buffer->RenderToJackPorts();
return rx_bytes;
}

int JackNetInterface::AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer)
{
int rx_bytes = Recv(rx_head->fPacketSize, 0);
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fRxHeader.fActivePorts = rx_head->fActivePorts;
rx_bytes = buffer->RenderFromNetwork(rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE, fRxHeader.fActivePorts);
// Last audio packet is received, so finish rendering...
if (fRxHeader.fIsLastPckt)
buffer->RenderToJackPorts();
return rx_bytes;
}

int JackNetInterface::FinishRecv(NetAudioBuffer* buffer)
{
// TODO : finish midi and audio rendering ?
buffer->RenderToJackPorts();
return NET_PACKET_ERROR;
}

// JackNetMasterInterface ************************************************************************************

bool JackNetMasterInterface::Init()
@@ -160,23 +235,23 @@ namespace Jack
uint attempt = 0;
int rx_bytes = 0;

//socket
// socket
if (fSocket.NewSocket() == SOCKET_ERROR) {
jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE));
return false;
}

//timeout on receive (for init)
// timeout on receive (for init)
if (fSocket.SetTimeOut(MASTER_INIT_TIMEOUT) < 0)
jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));

//connect
// connect
if (fSocket.Connect() == SOCKET_ERROR) {
jack_error("Can't connect : %s", StrError(NET_ERROR_CODE));
return false;
}

//send 'SLAVE_SETUP' until 'START_MASTER' received
// send 'SLAVE_SETUP' until 'START_MASTER' received
jack_info("Sending parameters to %s...", fParams.fSlaveNetName);
do
{
@@ -223,7 +298,9 @@ namespace Jack
fTxHeader.fDataStream = 's';
fRxHeader.fDataStream = 'r';

//midi net buffers
fMaxCycleOffset = fParams.fNetworkLatency;

// midi net buffers
if (fParams.fSendMidiChannels > 0)
fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fTxData);

@@ -232,7 +309,7 @@ namespace Jack

try {

//audio net buffers
// audio net buffers
if (fParams.fSendAudioChannels > 0) {

switch (fParams.fSampleEncoder) {
@@ -282,13 +359,13 @@ namespace Jack
return false;
}

//set the new timeout for the socket
// 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
// 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;
@@ -305,10 +382,10 @@ namespace Jack
{
jack_log("JackNetMasterInterface::Exit, ID %u", fParams.fID);

//stop process
// stop process
fRunning = false;

//send a 'multicast euthanasia request' - new socket is required on macosx
// send a 'multicast euthanasia request' - new socket is required on macosx
jack_info("Exiting '%s'", fParams.fName);
SetPacketType(&fParams, KILL_MASTER);
JackNetSocket mcast_socket(fMulticastIP, fSocket.GetPort());
@@ -327,9 +404,9 @@ namespace Jack

void JackNetMasterInterface::FatalError()
{
//fatal connection issue, exit
// fatal connection issue, exit
jack_error("'%s' : %s, exiting", fParams.fName, StrError(NET_ERROR_CODE));
//ask to the manager to properly remove the master
// ask to the manager to properly remove the master
Exit();
// UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
ThreadExit();
@@ -343,7 +420,7 @@ namespace Jack

/*
net_error_t error = fSocket.GetError();
//no data isn't really a network error, so just return 0 available read bytes
// no data isn't really a network error, so just return 0 available read bytes
if (error == NET_NO_DATA) {
return 0;
} else if (error == NET_CONN_ERROR) {
@@ -399,18 +476,19 @@ namespace Jack
fNetAudioPlaybackBuffer->ActivePortsToNetwork(fTxData, fTxHeader.fActivePorts);

memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
//PacketHeaderDisplay(&fTxHeader);
// PacketHeaderDisplay(&fTxHeader);
return Send(fTxHeader.fPacketSize, 0);
}

int JackNetMasterInterface::DataSend()
{
/*
uint subproc;
uint data_size;

//midi
// midi
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';
data_size = fNetMidiCaptureBuffer->RenderFromJackPorts();
fTxHeader.fNumPacket = fNetMidiCaptureBuffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE);
@@ -424,8 +502,13 @@ namespace Jack
return SOCKET_ERROR;
}
}
*/

if (MidiSend(fNetMidiCaptureBuffer, fParams.fSendMidiChannels, fParams.fSendAudioChannels) == SOCKET_ERROR)
return SOCKET_ERROR;

//audio
/*
// audio
if (fParams.fSendAudioChannels > 0) {
fTxHeader.fDataType = 'a';
fNetAudioCaptureBuffer->RenderFromJackPorts();
@@ -436,13 +519,14 @@ namespace Jack
fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->RenderToNetwork(subproc, fTxHeader.fActivePorts);
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
//PacketHeaderDisplay(&fTxHeader);
// PacketHeaderDisplay(&fTxHeader);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR;
}
}

return 0;
*/
return AudioSend(fNetAudioPlaybackBuffer, fParams.fSendAudioChannels);
}

int JackNetMasterInterface::SyncRecv()
@@ -477,21 +561,20 @@ namespace Jack
uint recvd_midi_pckt = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);

while (!fRxHeader.fIsLastPckt)
{
//how much data is queued on the rx buffer ?
while (!fRxHeader.fIsLastPckt) {
// how much data is queued on the rx buffer ?
rx_bytes = Recv(fParams.fMtu, MSG_PEEK);

//error here, problem with recv, just skip the cycle (return -1)
// error here, problem with recv, just skip the cycle (return -1)
if (rx_bytes == SOCKET_ERROR)
return rx_bytes;

if (rx_bytes && (rx_head->fDataStream == 'r') && (rx_head->fID == fParams.fID))
{
//read data
switch (rx_head->fDataType)
{
case 'm': //midi
if (rx_bytes && (rx_head->fDataStream == 'r') && (rx_head->fID == fParams.fID)) {
// read data
switch (rx_head->fDataType) {
case 'm': // midi
/*
rx_bytes = Recv(rx_head->fPacketSize, 0);
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
@@ -499,9 +582,12 @@ namespace Jack
// Last midi packet is received, so finish rendering...
if (++recvd_midi_pckt == rx_head->fNumPacket)
fNetMidiPlaybackBuffer->RenderToJackPorts();
*/
rx_bytes = MidiRecv(rx_head, fNetMidiPlaybackBuffer, recvd_midi_pckt);
break;

case 'a': //audio
case 'a': // audio
/*
rx_bytes = Recv(rx_head->fPacketSize, 0);
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
@@ -511,13 +597,18 @@ namespace Jack
// Last audio packet is received, so finish rendering...
if (fRxHeader.fIsLastPckt)
fNetAudioPlaybackBuffer->RenderToJackPorts();
*/
rx_bytes = AudioRecv(rx_head, fNetAudioPlaybackBuffer);
break;

case 's': //sync
case 's': // sync
jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName);
/*
// TODO : finish midi and audio rendering ?
fNetAudioPlaybackBuffer->RenderToJackPorts();
return NET_PACKET_ERROR;
*/
return FinishRecv(fNetAudioPlaybackBuffer);
}
}
}
@@ -527,35 +618,35 @@ namespace Jack

void JackNetMasterInterface::EncodeSyncPacket()
{
//this method contains every step of sync packet informations coding
//first of all, reset sync packet
// This method contains every step of sync packet informations coding
// first of all, reset sync packet
memset(fTxData, 0, PACKET_AVAILABLE_SIZE);

//then, first step : transport
// then, first step : transport
if (fParams.fTransportSync) {
// desactivated...
//EncodeTransportData();
// EncodeTransportData();
TransportDataHToN(&fSendTransportData, &fSendTransportData);
//copy to TxBuffer
// copy to TxBuffer
memcpy(fTxData, &fSendTransportData, sizeof(net_transport_data_t));
}
//then others (freewheel etc.)
//...
// then others (freewheel etc.)
// ...
}

void JackNetMasterInterface::DecodeSyncPacket()
{
//this method contains every step of sync packet informations decoding process
//first : transport
// This method contains every step of sync packet informations decoding process
// first : transport
if (fParams.fTransportSync) {
//copy received transport data to transport data structure
// copy received transport data to transport data structure
memcpy(&fReturnTransportData, fRxData, sizeof(net_transport_data_t));
TransportDataNToH(&fReturnTransportData, &fReturnTransportData);
// desactivated...
//DecodeTransportData();
// DecodeTransportData();
}
//then others
//...
// then others
// ...
}

// JackNetSlaveInterface ************************************************************************************************
@@ -566,15 +657,15 @@ namespace Jack
{
jack_log("JackNetSlaveInterface::Init()");

//set the parameters to send
// set the parameters to send
strcpy(fParams.fPacketType, "params");
fParams.fProtocolVersion = SLAVE_PROTOCOL;
SetPacketType(&fParams, SLAVE_AVAILABLE);

//init loop : get a master and start, do it until connection is ok
// init loop : get a master and start, do it until connection is ok
net_status_t status;
do {
//first, get a master, do it until a valid connection is running
// first, get a master, do it until a valid connection is running
do {
status = SendAvailableToMaster();
if (status == NET_SOCKET_ERROR)
@@ -582,7 +673,7 @@ namespace Jack
}
while (status != NET_CONNECTED);

//then tell the master we are ready
// then tell the master we are ready
jack_info("Initializing connection with %s...", fParams.fMasterNetName);
status = SendStartToMaster();
if (status == NET_ERROR)
@@ -597,16 +688,16 @@ namespace Jack
bool JackNetSlaveInterface::InitConnection(int time_out)
{
jack_log("JackNetSlaveInterface::InitConnection()");
unsigned int try_count = (time_out > 0) ? ((1000000 * time_out) / SLAVE_INIT_TIMEOUT) : LONG_MAX;
uint try_count = (time_out > 0) ? ((1000000 * time_out) / SLAVE_INIT_TIMEOUT) : LONG_MAX;

//set the parameters to send
// set the parameters to send
strcpy(fParams.fPacketType, "params");
fParams.fProtocolVersion = SLAVE_PROTOCOL;
SetPacketType(&fParams, SLAVE_AVAILABLE);

net_status_t status;
do {
//get a master
// get a master
status = SendAvailableToMaster(try_count);
if (status == NET_SOCKET_ERROR)
return false;
@@ -622,7 +713,7 @@ namespace Jack

net_status_t status;
do {
//then tell the master we are ready
// then tell the master we are ready
jack_info("Initializing connection with %s...", fParams.fMasterNetName);
status = SendStartToMaster();
if (status == NET_ERROR)
@@ -636,41 +727,41 @@ namespace Jack
net_status_t JackNetSlaveInterface::SendAvailableToMaster(long try_count)
{
jack_log("JackNetSlaveInterface::SendAvailableToMaster()");
//utility
// utility
session_params_t host_params;
int rx_bytes = 0;

//socket
// socket
if (fSocket.NewSocket() == SOCKET_ERROR) {
jack_error("Fatal error : network unreachable - %s", StrError(NET_ERROR_CODE));
return NET_SOCKET_ERROR;
}

//bind the socket
// bind the socket
if (fSocket.Bind() == SOCKET_ERROR) {
jack_error("Can't bind the socket : %s", StrError(NET_ERROR_CODE));
return NET_SOCKET_ERROR;
}

//timeout on receive
// timeout on receive
if (fSocket.SetTimeOut(SLAVE_INIT_TIMEOUT) == SOCKET_ERROR)
jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));

//disable local loop
// disable local loop
if (fSocket.SetLocalLoop() == SOCKET_ERROR)
jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE));

//send 'AVAILABLE' until 'SLAVE_SETUP' received
// send 'AVAILABLE' until 'SLAVE_SETUP' received
jack_info("Waiting for a master...");
do {
//send 'available'
// send 'available'
session_params_t net_params;
memset(&net_params, 0, sizeof(session_params_t));
SessionParamsHToN(&fParams, &net_params);
if (fSocket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR)
jack_error("Error in data send : %s", StrError(NET_ERROR_CODE));

//filter incoming packets : don't exit while no error is detected
// filter incoming packets : don't exit while no error is detected
memset(&net_params, 0, sizeof(session_params_t));
rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0);
SessionParamsNToH(&net_params, &host_params);
@@ -687,10 +778,10 @@ namespace Jack
return NET_CONNECT_ERROR;
}

//everything is OK, copy parameters
// everything is OK, copy parameters
fParams = host_params;

//connect the socket
// connect the socket
if (fSocket.Connect() == SOCKET_ERROR) {
jack_error("Error in connect : %s", StrError(NET_ERROR_CODE));
return NET_CONNECT_ERROR;
@@ -702,7 +793,7 @@ namespace Jack
{
jack_log("JackNetSlaveInterface::SendStartToMaster");

//tell the master to start
// tell the master to start
session_params_t net_params;
memset(&net_params, 0, sizeof(session_params_t));
SetPacketType(&fParams, START_MASTER);
@@ -724,7 +815,7 @@ namespace Jack
fTxHeader.fDataStream = 'r';
fRxHeader.fDataStream = 's';

//midi net buffers
// midi net buffers
if (fParams.fSendMidiChannels > 0)
fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fRxData);

@@ -733,7 +824,7 @@ namespace Jack

try {

//audio net buffers
// audio net buffers
if (fParams.fSendAudioChannels > 0) {

switch (fParams.fSampleEncoder) {
@@ -783,7 +874,7 @@ namespace Jack
return false;
}

//set the new buffer sizes
// set the new buffer sizes
if (SetNetBufferSize() == SOCKET_ERROR) {
jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
goto error;
@@ -799,14 +890,14 @@ namespace Jack
int JackNetSlaveInterface::Recv(size_t size, int flags)
{
int rx_bytes = fSocket.Recv(fRxBuffer, size, flags);
//handle errors
// handle errors
if (rx_bytes == SOCKET_ERROR) {
/*
net_error_t error = fSocket.GetError();
//no data isn't really an error in realtime processing, so just return 0
// no data isn't really an error in realtime processing, so just return 0
if (error == NET_NO_DATA) {
jack_error("No data, is the master still running ?");
//if a network error occurs, this exception will restart the driver
// if a network error occurs, this exception will restart the driver
} else if (error == NET_CONN_ERROR) {
FatalError();
} else {
@@ -833,11 +924,11 @@ namespace Jack
PacketHeaderHToN(header, header);
int tx_bytes = fSocket.Send(fTxBuffer, size, flags);

//handle errors
// handle errors
if (tx_bytes == SOCKET_ERROR) {
/*
net_error_t error = fSocket.GetError();
//if a network error occurs, this exception will restart the driver
// if a network error occurs, this exception will restart the driver
if (error == NET_CONN_ERROR) {
FatalError();
} else {
@@ -854,10 +945,10 @@ namespace Jack
int rx_bytes = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);

//receive sync (launch the cycle)
// receive sync (launch the cycle)
do {
rx_bytes = Recv(fParams.fMtu, 0);
//connection issue, send will detect it, so don't skip the cycle (return 0)
// connection issue, send will detect it, so don't skip the cycle (return 0)
if (rx_bytes == SOCKET_ERROR)
return rx_bytes;
}
@@ -878,17 +969,19 @@ namespace Jack
packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);

while (!fRxHeader.fIsLastPckt) {
//how much data is queued on the rx buffer ?
// how much data is queued on the rx buffer ?
rx_bytes = Recv(fParams.fMtu, MSG_PEEK);

//error here, problem with recv, just skip the cycle (return -1)
// error here, problem with recv, just skip the cycle (return -1)
if (rx_bytes == SOCKET_ERROR)
return rx_bytes;

if (rx_bytes && (rx_head->fDataStream == 's') && (rx_head->fID == fParams.fID)) {
switch (rx_head->fDataType)
{
case 'm': //midi
// read data
switch (rx_head->fDataType) {

case 'm': // midi
/*
rx_bytes = Recv(rx_head->fPacketSize, 0);
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
@@ -896,9 +989,12 @@ namespace Jack
// Last midi packet is received, so finish rendering...
if (++recvd_midi_pckt == rx_head->fNumPacket)
fNetMidiCaptureBuffer->RenderToJackPorts();
*/
rx_bytes = MidiRecv(rx_head, fNetMidiCaptureBuffer, recvd_midi_pckt);
break;

case 'a': //audio
case 'a': // audio
/*
rx_bytes = Recv(rx_head->fPacketSize, 0);
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
@@ -908,13 +1004,18 @@ namespace Jack
// Last audio packet is received, so finish rendering...
if (fRxHeader.fIsLastPckt)
fNetAudioCaptureBuffer->RenderToJackPorts();
*/
rx_bytes = AudioRecv(rx_head, fNetAudioCaptureBuffer);
break;

case 's': //sync
case 's': // sync
jack_info("NetSlave : overloaded, skipping receive");
/*
// TODO : finish midi and audio rendering ?
fNetAudioCaptureBuffer->RenderToJackPorts();
return NET_PACKET_ERROR;
*/
return FinishRecv(fNetAudioCaptureBuffer);
}
}
}
@@ -925,7 +1026,7 @@ namespace Jack

int JackNetSlaveInterface::SyncSend()
{
//tx header
// tx header
if (fParams.fSlaveSyncMode) {
fTxHeader.fCycle = fRxHeader.fCycle;
} else {
@@ -941,33 +1042,39 @@ namespace Jack
fNetAudioCaptureBuffer->ActivePortsToNetwork(fTxData, fTxHeader.fActivePorts);

memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
// PacketHeaderDisplay(&fTxHeader);
return Send(fTxHeader.fPacketSize, 0);
}

int JackNetSlaveInterface::DataSend()
{
/*
uint subproc, data_size;

//midi
// midi
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';
data_size = fNetMidiPlaybackBuffer->RenderFromJackPorts();
fTxHeader.fNumPacket = fNetMidiPlaybackBuffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE);

for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
fTxHeader.fSubCycle = subproc;
fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0;
// fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0;
fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && fParams.fReturnAudioChannels == 0) ? 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;
}
}
*/
if (MidiSend(fNetMidiPlaybackBuffer, fParams.fReturnMidiChannels, fParams.fReturnAudioChannels) == SOCKET_ERROR)
return SOCKET_ERROR;

//audio
/*
// audio
if (fParams.fReturnAudioChannels > 0) {

fTxHeader.fDataType = 'a';
fNetAudioPlaybackBuffer->RenderFromJackPorts();
fTxHeader.fNumPacket = fNetAudioPlaybackBuffer->GetNumPackets();
@@ -977,45 +1084,48 @@ namespace Jack
fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->RenderToNetwork(subproc, fTxHeader.fActivePorts);
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
//PacketHeaderDisplay(&fTxHeader);
// PacketHeaderDisplay(&fTxHeader);
if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
return SOCKET_ERROR;
}
}
return 0;
*/

return AudioSend(fNetAudioPlaybackBuffer, fParams.fReturnAudioChannels);
}

//network sync------------------------------------------------------------------------
// network sync------------------------------------------------------------------------
void JackNetSlaveInterface::EncodeSyncPacket()
{
//this method contains every step of sync packet informations coding
//first of all, reset sync packet
// This method contains every step of sync packet informations coding
// first of all, reset sync packet
memset(fTxData, 0, PACKET_AVAILABLE_SIZE);
//then first step : transport
// then first step : transport
if (fParams.fTransportSync) {
// desactivated...
//EncodeTransportData();
// EncodeTransportData();
TransportDataHToN(&fReturnTransportData, &fReturnTransportData);
//copy to TxBuffer
// copy to TxBuffer
memcpy(fTxData, &fReturnTransportData, sizeof(net_transport_data_t));
}
//then others
//...
// then others
// ...
}

void JackNetSlaveInterface::DecodeSyncPacket()
{
//this method contains every step of sync packet informations decoding process
//first : transport
// This method contains every step of sync packet informations decoding process
// first : transport
if (fParams.fTransportSync) {
//copy received transport data to transport data structure
// copy received transport data to transport data structure
memcpy(&fSendTransportData, fRxData, sizeof(net_transport_data_t));
TransportDataNToH(&fSendTransportData, &fSendTransportData);
// desactivated...
//DecodeTransportData();
// DecodeTransportData();
}
//then others
//...
// then others
// ...
}

}

+ 56
- 50
common/JackNetInterface.h View File

@@ -25,6 +25,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

namespace Jack
{

#define DEFAULT_MULTICAST_IP "225.3.19.154"
#define DEFAULT_PORT 19000
#define DEFAULT_MTU 1500

#define SLAVE_SETUP_RETRY 5

#define MASTER_INIT_TIMEOUT 1000000 // in usec
#define SLAVE_INIT_TIMEOUT 1000000 // in usec

#define NETWORK_MAX_LATENCY 10

/**
\Brief This class describes the basic Net Interface, used by both master and slave
*/
@@ -40,7 +52,7 @@ namespace Jack
JackNetSocket fSocket;
char fMulticastIP[32];

//headers
// headers
packet_header_t fTxHeader;
packet_header_t fRxHeader;

@@ -48,31 +60,31 @@ namespace Jack
net_transport_data_t fSendTransportData;
net_transport_data_t fReturnTransportData;

//network buffers
// network buffers
char* fTxBuffer;
char* fRxBuffer;
char* fTxData;
char* fRxData;

//jack buffers
// jack buffers
NetMidiBuffer* fNetMidiCaptureBuffer;
NetMidiBuffer* fNetMidiPlaybackBuffer;
NetAudioBuffer* fNetAudioCaptureBuffer;
NetAudioBuffer* fNetAudioPlaybackBuffer;

//utility methods
// utility methods
int SetNetBufferSize();
void FreeNetworkBuffers();

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

//transport
// transport
virtual void EncodeTransportData() = 0;
virtual void DecodeTransportData() = 0;

//sync packet
// sync packet
virtual void EncodeSyncPacket() = 0;
virtual void DecodeSyncPacket() = 0;

@@ -86,12 +98,20 @@ namespace Jack

virtual void FatalError() = 0;

int MidiSend(NetMidiBuffer* buffer, int midi_channnels, int audio_channels);
int AudioSend(NetAudioBuffer* buffer, int audio_channels);

int MidiRecv(packet_header_t* rx_head, NetMidiBuffer* buffer, uint& recvd_midi_pckt);
int AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer);

int FinishRecv(NetAudioBuffer* buffer);

public:

JackNetInterface();
JackNetInterface(const char* multicast_ip, int port);
JackNetInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip);

public:

virtual ~JackNetInterface();

};
@@ -122,7 +142,7 @@ namespace Jack
int DataRecv();
int DataSend();

//sync packet
// sync packet
void EncodeSyncPacket();
void DecodeSyncPacket();

@@ -134,12 +154,14 @@ namespace Jack
void FatalError();

public:

JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0), fMaxCycleOffset(0), fLastfCycleOffset(0)
{}
JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip )
: JackNetInterface ( params, socket, multicast_ip )
JackNetMasterInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip)
: JackNetInterface(params, socket, multicast_ip)
{}
~JackNetMasterInterface()

virtual~JackNetMasterInterface()
{}
};

@@ -169,62 +191,46 @@ namespace Jack
int DataRecv();
int DataSend();

//sync packet
// sync packet
void EncodeSyncPacket();
void DecodeSyncPacket();

int Recv ( size_t size, int flags );
int Send ( size_t size, int flags );
int Recv(size_t size, int flags);
int Send(size_t size, int flags);

void FatalError();

void InitAPI()
{
// open Socket API with the first slave
if (fSlaveCounter++ == 0) {
if (SocketAPIInit() < 0) {
jack_error("Can't init Socket API, exiting...");
throw std::bad_alloc();
}
}
}

public:

JackNetSlaveInterface() : JackNetInterface()
{
//open Socket API with the first slave
if ( fSlaveCounter++ == 0 )
{
if ( SocketAPIInit() < 0 )
{
jack_error ( "Can't init Socket API, exiting..." );
throw -1;
}
}
InitAPI();
}

JackNetSlaveInterface ( const char* ip, int port ) : JackNetInterface ( ip, port )
JackNetSlaveInterface(const char* ip, int port) : JackNetInterface(ip, port)
{
//open Socket API with the first slave
if ( fSlaveCounter++ == 0 )
{
if ( SocketAPIInit() < 0 )
{
jack_error ( "Can't init Socket API, exiting..." );
throw -1;
}
}
InitAPI();
}

~JackNetSlaveInterface()
virtual ~JackNetSlaveInterface()
{
//close Socket API with the last slave
if ( --fSlaveCounter == 0 )
// close Socket API with the last slave
if (--fSlaveCounter == 0) {
SocketAPIEnd();
}
}
};
}

#define DEFAULT_MULTICAST_IP "225.3.19.154"
#define DEFAULT_PORT 19000
#define DEFAULT_MTU 1500

#define SLAVE_SETUP_RETRY 5

#define MASTER_INIT_TIMEOUT 1000000 // in usec
#define SLAVE_INIT_TIMEOUT 1000000 // in usec

#define CYCLE_OFFSET_SLOW 10
#define NETWORK_MAX_LATENCY CYCLE_OFFSET_SLOW

#endif

+ 12
- 9
common/JackShmMem.h View File

@@ -156,11 +156,12 @@ class JackShmReadWritePtr
{
if (fInfo.index < 0 && index >= 0) {
jack_log("JackShmReadWritePtr::Init %ld %ld", index, fInfo.index);
if (jack_initialize_shm(server_name) < 0)
throw - 1;
if (jack_initialize_shm(server_name) < 0) {
throw std::bad_alloc();
}
fInfo.index = index;
if (jack_attach_lib_shm(&fInfo)) {
throw - 2;
throw std::bad_alloc();
}
GetShmAddress()->LockMemory();
}
@@ -237,11 +238,12 @@ class JackShmReadWritePtr1
{
if (fInfo.index < 0 && index >= 0) {
jack_log("JackShmReadWritePtr1::Init %ld %ld", index, fInfo.index);
if (jack_initialize_shm(server_name) < 0)
throw - 1;
if (jack_initialize_shm(server_name) < 0) {
throw std::bad_alloc();
}
fInfo.index = index;
if (jack_attach_lib_shm(&fInfo)) {
throw - 2;
throw std::bad_alloc();
}
/*
nobody else needs to access this shared memory any more, so
@@ -324,11 +326,12 @@ class JackShmReadPtr
{
if (fInfo.index < 0 && index >= 0) {
jack_log("JackShmPtrRead::Init %ld %ld", index, fInfo.index);
if (jack_initialize_shm(server_name) < 0)
throw - 1;
if (jack_initialize_shm(server_name) < 0) {
throw std::bad_alloc();
}
fInfo.index = index;
if (jack_attach_lib_shm_read(&fInfo)) {
throw - 2;
throw std::bad_alloc();
}
GetShmAddress()->LockMemory();
}


+ 23
- 15
macosx/coreaudio/JackCoreAudioAdapter.cpp View File

@@ -391,27 +391,35 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra
fPlaying = true;
}

if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName, fAdaptedSampleRate) < 0)
throw -1;
if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName, fAdaptedSampleRate) < 0) {
throw std::bad_alloc();
}

if (SetupChannels(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, true) < 0)
throw -1;
if (SetupChannels(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, true) < 0) {
throw std::bad_alloc();
}

if (SetupBufferSize(fAdaptedBufferSize) < 0)
throw -1;
if (SetupBufferSize(fAdaptedBufferSize) < 0) {
throw std::bad_alloc();
}

if (SetupSampleRate(fAdaptedSampleRate) < 0)
throw -1;
if (SetupSampleRate(fAdaptedSampleRate) < 0) {
throw std::bad_alloc();
}

if (OpenAUHAL(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, fAdaptedBufferSize, fAdaptedSampleRate) < 0)
throw -1;
if (OpenAUHAL(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, fAdaptedBufferSize, fAdaptedSampleRate) < 0) {
throw std::bad_alloc();
}

if (fCapturing && fCaptureChannels > 0)
if (SetupBuffers(fCaptureChannels) < 0)
throw -1;
if (fCapturing && fCaptureChannels > 0) {
if (SetupBuffers(fCaptureChannels) < 0) {
throw std::bad_alloc();
}
}

if (AddListeners() < 0)
throw -1;
if (AddListeners() < 0) {
throw std::bad_alloc();
}
}

OSStatus JackCoreAudioAdapter::GetDefaultDevice(AudioDeviceID* id)


Loading…
Cancel
Save