Commit a09a1a5c authored by sletz's avatar sletz
Browse files

Code factorization and cleanup.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4505 0c269be4-1314-0410-8aa9-9f06e86f4224
parent b8c47e59
......@@ -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;
}
......
......@@ -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)
......
......@@ -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;
}
}
......
......@@ -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;
}
}
......
This diff is collapsed.
......@@ -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()