diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 9be49aa0..7088f7f4 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -59,7 +59,7 @@ extern "C" int time_out; // in millisecond, -1 means in infinite int encoder; int kbps; // KB per second for CELT encoder - char mode; + int latency; } jack_slave_t; @@ -251,7 +251,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { result->midi_input = fParams.fSendMidiChannels; result->midi_output = fParams.fReturnMidiChannels; result->mtu = fParams.fMtu; - result->mode = fParams.fNetworkMode; + result->latency = fParams.fNetworkLatency; return 0; error: @@ -472,7 +472,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf fParams.fReturnAudioChannels = request->audio_output; fParams.fSendMidiChannels = request->midi_input; fParams.fReturnMidiChannels = request->midi_output; - fParams.fNetworkMode = request->mode; + fParams.fNetworkLatency = request->latency; fParams.fSampleEncoder = request->encoder; fParams.fKBps = request->kbps; fParams.fSlaveSyncMode = 1; diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 7642fd58..438936c0 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -49,7 +49,7 @@ namespace Jack fParams.fSampleRate = sample_rate; fParams.fPeriodSize = buffer_size; fParams.fSlaveSyncMode = 1; - fParams.fNetworkMode = 's'; + fParams.fNetworkLatency = 2; fParams.fSampleEncoder = JackFloatEncoder; fJackClient = jack_client; @@ -94,16 +94,8 @@ namespace Jack } break; #endif - case 'm' : - if (strcmp(param->value.str, "normal") == 0) { - fParams.fNetworkMode = 'n'; - } else if (strcmp(param->value.str, "slow") == 0) { - fParams.fNetworkMode = 's'; - } else if (strcmp(param->value.str, "fast") == 0) { - fParams.fNetworkMode = 'f'; - } else { - jack_error("Unknown network mode, using 'normal' mode."); - } + case 'l' : + fParams.fNetworkLatency = param->value.i; break; case 'q': fQuality = param->value.ui; diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 2855fb17..aa9d7468 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -29,7 +29,7 @@ namespace Jack { JackNetDriver::JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, const char* ip, int udp_port, int mtu, int midi_input_ports, int midi_output_ports, - char* net_name, uint transport_sync, char network_mode, int celt_encoding) + char* net_name, uint transport_sync, int network_latency, int celt_encoding) : JackAudioDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port) { jack_log("JackNetDriver::JackNetDriver ip %s, port %d", ip, udp_port); @@ -50,7 +50,7 @@ namespace Jack strcpy(fParams.fName, net_name); fSocket.GetName(fParams.fSlaveNetName); fParams.fTransportSync = transport_sync; - fParams.fNetworkMode = network_mode; + fParams.fNetworkLatency = network_latency; fSendTransportData.fState = -1; fReturnTransportData.fState = -1; fLastTransportState = -1; @@ -185,20 +185,7 @@ namespace Jack plot_name = string(fParams.fName); plot_name += string("_slave"); plot_name += (fEngineControl->fSyncMode) ? string("_sync") : string("_async"); - switch (fParams.fNetworkMode) - { - case 's' : - plot_name += string("_slow"); - break; - - case 'n' : - plot_name += string("_normal"); - break; - - case 'f' : - plot_name += string("_fast"); - break; - } + plot_name += string("_latency"); fNetTimeMon = new JackGnuPlotMonitor(128, 5, plot_name); string net_time_mon_fields[] = { @@ -305,18 +292,7 @@ namespace Jack port = fGraphManager->GetPort(port_index); port->SetAlias(alias); //port latency - switch (fParams.fNetworkMode) - { - case 'f' : - range.min = range.max = (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize; - break; - case 'n' : - range.min = range.max = (fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); - break; - case 's' : - range.min = range.max = (2 * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); - break; - } + range.min = range.max = (fParams.fNetworkLatency * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[audio_port_index] = port_index; jack_log("JackNetDriver::AllocPorts() fPlaybackPortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency()); @@ -354,18 +330,7 @@ namespace Jack } port = fGraphManager->GetPort(port_index); //port latency - switch (fParams.fNetworkMode) - { - case 'f' : - range.min = range.max = (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize; - break; - case 'n' : - range.min = range.max = (fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); - break; - case 's' : - range.min = range.max = (2 * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); - break; - } + range.min = range.max = (fParams.fNetworkLatency * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); port->SetLatencyRange(JackPlaybackLatency, &range); fMidiPlaybackPortList[midi_port_index] = port_index; jack_log("JackNetDriver::AllocPorts() fMidiPlaybackPortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency()); @@ -658,8 +623,8 @@ namespace Jack 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); return desc; } @@ -679,7 +644,7 @@ namespace Jack int midi_output_ports = 0; int celt_encoding = -1; bool monitor = false; - char network_mode = 's'; + int network_latency = 2; const JSList* node; const jack_driver_param_t* param; @@ -732,7 +697,9 @@ namespace Jack case 't' : transport_sync = param->value.ui; break; - case 'm' : + 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) @@ -741,6 +708,7 @@ namespace Jack network_mode = 'f'; else jack_error("Unknown network mode, using 'normal' mode."); + */ break; } } @@ -751,7 +719,7 @@ namespace Jack new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, mtu, midi_input_ports, midi_output_ports, net_name, transport_sync, - network_mode, celt_encoding)); + network_latency, celt_encoding)); if (driver->Open(period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports, monitor, "from_master_", "to_master_", 0, 0) == 0) { return driver; } else { diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index f73337c7..8c0ff602 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -72,7 +72,7 @@ namespace Jack JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports, - char* net_name, uint transport_sync, char network_master_mode, int celt_encoding); + char* net_name, uint transport_sync, int network_latency, int celt_encoding); ~JackNetDriver(); int Open(jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index d8562a05..525b36c9 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -107,7 +107,7 @@ namespace Jack jack_log("midi_size %f", midi_size); //bufsize = sync + audio + midi - int bufsize = MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size); + int bufsize = NETWORK_MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size); jack_log("SetNetBufferSize bufsize = %d", bufsize); //tx buffer @@ -206,28 +206,6 @@ namespace Jack return true; } - /* - int JackNetMasterInterface::SetRxTimeout() - { - jack_log("JackNetMasterInterface::SetRxTimeout"); - - float time = 0; - - //slow or normal mode, short timeout on recv (2 audio subcycles) - if ((fParams.fNetworkMode == 's') || (fParams.fNetworkMode == 'n')) { - time = 2000000.f * ((fNetAudioCaptureBuffer) - ? fNetAudioCaptureBuffer->GetCycleDuration() - : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleDuration() : 0); - } - //fast mode, wait for 75% of the entire cycle duration - else if (fParams.fNetworkMode == 'f') { - time = 750000.f * (static_cast(fParams.fPeriodSize) / static_cast(fParams.fSampleRate)); - } - - return fSocket.SetTimeOut(static_cast(time)); - } - */ - int JackNetMasterInterface::SetRxTimeout() { jack_log("JackNetMasterInterface::SetRxTimeout"); @@ -405,11 +383,7 @@ namespace Jack bool JackNetMasterInterface::IsSynched() { - if (fParams.fNetworkMode == 's') { - return (fCycleOffset < (CYCLE_OFFSET_SLOW + 1)); - } else { - return true; - } + return (fCycleOffset <= fMaxCycleOffset); } int JackNetMasterInterface::SyncSend() @@ -487,58 +461,10 @@ namespace Jack if (fNetAudioCaptureBuffer) fNetAudioCaptureBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts); - switch (fParams.fNetworkMode) - { - case 's' : - //slow mode : allow to use full bandwidth and heavy process on the slave - // - extra latency is set to two cycles, one cycle for send/receive operations + one cycle for heavy process on the slave - // - if the network is two fast, just wait the next cycle, this mode allows a shorter cycle duration for the master - // - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer - //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process) - - if (fCycleOffset < CYCLE_OFFSET_SLOW) { - return 0; - } else { - rx_bytes = Recv(rx_head->fPacketSize, 0); - } - - /* - rx_bytes = Recv(rx_head->fPacketSize, 0); - - if (fCycleOffset != fLastfCycleOffset) - jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); - fLastfCycleOffset = fCycleOffset; - */ - - break; - - case 'n' : - //normal use of the network : - // - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth - // - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter - // - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it - if (fCycleOffset < CYCLE_OFFSET_NORMAL) { - return 0; - } else { - rx_bytes = Recv(rx_head->fPacketSize, 0); - } - - if (fCycleOffset > CYCLE_OFFSET_NORMAL) { - jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); - } - break; - - case 'f' : - //fast mode suppose the network bandwith is larger than required for the transmission (only a few channels for example) - // - packets can be quickly received, quickly is here relative to the cycle duration - // - here, receive data, we can't keep it queued on the rx buffer, - // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow - rx_bytes = Recv(rx_head->fPacketSize, 0); - - if (fCycleOffset > CYCLE_OFFSET_FAST) { - jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); - } - break; + if (fCycleOffset < fMaxCycleOffset) { + return 0; + } else { + rx_bytes = Recv(rx_head->fPacketSize, 0); } fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index 082292a2..04943160 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -107,6 +107,7 @@ namespace Jack bool fRunning; int fCycleOffset; + int fMaxCycleOffset; int fLastfCycleOffset; bool Init(); @@ -133,7 +134,7 @@ namespace Jack void FatalError(); public: - JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0), fLastfCycleOffset(0) + 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 ) @@ -223,10 +224,7 @@ namespace Jack #define MASTER_INIT_TIMEOUT 1000000 // in usec #define SLAVE_INIT_TIMEOUT 1000000 // in usec -#define CYCLE_OFFSET_FAST 0 -#define CYCLE_OFFSET_NORMAL 1 -#define CYCLE_OFFSET_SLOW 2 -//#define CYCLE_OFFSET_SLOW 30 -#define MAX_LATENCY CYCLE_OFFSET_SLOW * 4 +#define CYCLE_OFFSET_SLOW 10 +#define NETWORK_MAX_LATENCY CYCLE_OFFSET_SLOW #endif diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index a0c14de3..a7e0128f 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -64,18 +64,7 @@ namespace Jack plot_name = string ( fParams.fName ); plot_name += string ( "_master" ); plot_name += string ( ( fParams.fSlaveSyncMode ) ? "_sync" : "_async" ); - switch ( fParams.fNetworkMode ) - { - case 's' : - plot_name += string ( "_slow" ); - break; - case 'n' : - plot_name += string ( "_normal" ); - break; - case 'f' : - plot_name += string ( "_fast" ); - break; - } + plot_name += string ( "_latency" ); fNetTimeMon = new JackGnuPlotMonitor ( 128, 4, plot_name ); string net_time_mon_fields[] = { @@ -196,21 +185,8 @@ namespace Jack if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency - switch ( fParams.fNetworkMode ) - { - case 'f' : - range.min = range.max = (fParams.fSlaveSyncMode) ? 0 : port_latency; - jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range); - break; - case 'n' : - range.min = range.max = port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; - jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range); - break; - case 's' : - range.min = range.max = 2 * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; - jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range); - break; - } + range.min = range.max = fParams.fNetworkLatency * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; + jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range); } //midi @@ -229,21 +205,8 @@ namespace Jack if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency - switch ( fParams.fNetworkMode ) - { - case 'f' : - range.min = range.max = (fParams.fSlaveSyncMode) ? 0 : port_latency; - jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range); - break; - case 'n' : - range.min = range.max = port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; - jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range); - break; - case 's' : - range.min = range.max = 2 * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; - jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range); - break; - } + range.min = range.max = fParams.fNetworkLatency * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; + jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range); } return 0; } diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 791af963..ee2c3c62 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -690,6 +690,7 @@ namespace Jack dst_params->fPeriodSize = htonl(src_params->fPeriodSize); dst_params->fSampleEncoder = htonl(src_params->fSampleEncoder); dst_params->fSlaveSyncMode = htonl(src_params->fSlaveSyncMode); + dst_params->fNetworkLatency = htonl(src_params->fNetworkLatency); } SERVER_EXPORT void SessionParamsNToH(session_params_t* src_params, session_params_t* dst_params) @@ -707,6 +708,7 @@ namespace Jack dst_params->fPeriodSize = ntohl(src_params->fPeriodSize); dst_params->fSampleEncoder = ntohl(src_params->fSampleEncoder); dst_params->fSlaveSyncMode = ntohl(src_params->fSlaveSyncMode); + dst_params->fNetworkLatency = ntohl(src_params->fNetworkLatency); } SERVER_EXPORT void SessionParamsDisplay(session_params_t* params) @@ -725,19 +727,6 @@ namespace Jack break; } - char mode[8]; - switch (params->fNetworkMode) - { - case 's' : - strcpy(mode, "slow"); - break; - case 'n' : - strcpy(mode, "normal"); - break; - case 'f' : - strcpy(mode, "fast"); - break; - } jack_info("**************** Network parameters ****************"); jack_info("Name : %s", params->fName); jack_info("Protocol revision : %d", params->fProtocolVersion); @@ -750,6 +739,7 @@ namespace Jack jack_info("Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels); jack_info("Sample rate : %u frames per second", params->fSampleRate); jack_info("Period size : %u frames per period", params->fPeriodSize); + jack_info("Network latency : %u cycles", params->fNetworkLatency); switch (params->fSampleEncoder) { case (JackFloatEncoder): jack_info("SampleEncoder : %s", "Float"); @@ -763,7 +753,6 @@ namespace Jack break; }; jack_info("Slave mode : %s", (params->fSlaveSyncMode) ? "sync" : "async"); - jack_info("Network mode : %s", mode); jack_info("****************************************************"); } diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 375aa376..8c0631c8 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -101,7 +101,7 @@ namespace Jack uint32_t fSampleEncoder; //samples encoder uint32_t fKBps; //KB per second for CELT encoder uint32_t fSlaveSyncMode; //is the slave in sync mode ? - char fNetworkMode; //fast, normal or slow mode + uint32_t fNetworkLatency; //network latency }; //net status ********************************************************************************** diff --git a/common/jack/net.h b/common/jack/net.h index 001868be..f2093ba6 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -35,13 +35,6 @@ extern "C" #define SOCKET_ERROR -1 -enum JackNetMode { - - JackFastMode = 'f', - JackNormalMode = 'n', - JackSlowMode = 's', -}; - enum JackNetEncoder { JackFloatEncoder = 0, // Samples are transmitted as float @@ -59,7 +52,7 @@ typedef struct { int time_out; // in second, -1 means in infinite int encoder; // Encoder type (one of JackNetEncoder) int kbps; // KB per second for CELT encoder - char mode; // one of JackNetMode + int latency; // network latency } jack_slave_t; diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index b4ef278b..9355772a 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -21,18 +21,18 @@ int buffer_size; int sample_rate; static int net_process(jack_nframes_t buffer_size, - int audio_input, - float** audio_input_buffer, + int audio_input, + float** audio_input_buffer, int midi_input, void** midi_input_buffer, int audio_output, - float** audio_output_buffer, - int midi_output, - void** midi_output_buffer, + float** audio_output_buffer, + int midi_output, + void** midi_output_buffer, void* data) { jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); - + // Process input, produce output if (audio_input == audio_output) { // Copy net input to net output @@ -59,10 +59,10 @@ static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void #define WIFI_MTU 1500 int main(int argc, char *argv[]) { - + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - jack_slave_t request = { NUM_OUTPUT, NUM_INPUT, 0, 0, WIFI_MTU, -1, JackCeltEncoder, 128, JackSlowMode }; + + jack_slave_t request = { NUM_OUTPUT, NUM_INPUT, 0, 0, WIFI_MTU, -1, JackCeltEncoder, 128, 2 }; jack_master_t result; //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { @@ -70,41 +70,41 @@ int main(int argc, char *argv[]) { printf("jack_net_slave_open error..\n"); return -1; } - - if ((adapter = jack_create_adapter(NUM_INPUT, - NUM_OUTPUT, - result.buffer_size, - result.sample_rate, - result.buffer_size, + + if ((adapter = jack_create_adapter(NUM_INPUT, + NUM_OUTPUT, + result.buffer_size, + result.sample_rate, + result.buffer_size, result.sample_rate)) == 0) { return -1; } - + TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); - + jack_set_net_slave_process_callback(net, net_process, NULL); jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); - + if (jack_net_slave_activate(net) != 0) { return -1; } - + if (audio_device.Open(result.buffer_size, result.sample_rate) < 0) { return -1; } - + audio_device.SetAudioCallback(SlaveAudioCallback, NULL); - + if (audio_device.Start() < 0) { return -1; } - + int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; - + audio_device.Stop(); audio_device.Close(); - + // Wait for application end jack_net_slave_deactivate(net); jack_net_slave_close(net);