From 840b47f8bf42c922ca3732183d76aa42280640d6 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 27 Jul 2011 20:33:50 +0000 Subject: [PATCH] Code factorization and cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4514 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackDummyDriver.cpp | 5 +- common/JackNetAPI.cpp | 25 ++- common/JackNetDriver.cpp | 41 ++-- common/JackNetDriver.h | 2 +- common/JackNetInterface.cpp | 30 +-- common/JackNetInterface.h | 7 +- common/JackNetOneDriver.h | 2 +- common/JackNetTool.cpp | 333 +++++++++++++++++++++++------- common/JackNetTool.h | 185 +++++++---------- common/JackPort.cpp | 1 + common/JackThreadedDriver.cpp | 3 +- common/JackThreadedDriver.h | 12 -- common/JackTools.h | 14 +- common/JackWaitThreadedDriver.cpp | 3 +- common/jack/net.h | 12 +- example-clients/alias.c | 4 +- example-clients/bufsize.c | 2 +- example-clients/capture_client.c | 18 +- example-clients/connect.c | 2 +- example-clients/freewheel.c | 4 +- example-clients/impulse_grabber.c | 14 +- example-clients/ipunload.c | 6 +- example-clients/lsp.c | 3 +- example-clients/metro.c | 30 ++- example-clients/midiseq.c | 8 +- example-clients/midisine.c | 12 +- example-clients/monitor_client.c | 2 +- example-clients/netmaster.c | 2 +- example-clients/netslave.c | 8 +- example-clients/showtime.c | 6 +- example-clients/zombie.c | 2 +- macosx/iphone/main_master.mm | 58 +++--- macosx/iphone/main_slave.mm | 3 +- 33 files changed, 517 insertions(+), 342 deletions(-) diff --git a/common/JackDummyDriver.cpp b/common/JackDummyDriver.cpp index 72d1b4d0..ec456ffb 100644 --- a/common/JackDummyDriver.cpp +++ b/common/JackDummyDriver.cpp @@ -57,7 +57,7 @@ int JackDummyDriver::Open(jack_nframes_t buffer_size, int buffer_size = lroundf((fWaitTime * fEngineControl->fSampleRate) / 1000000.0f); if (buffer_size > BUFFER_SIZE_MAX) { buffer_size = BUFFER_SIZE_MAX; - jack_error("Buffer size set to %d ", BUFFER_SIZE_MAX); + jack_error("Buffer size set to %d", BUFFER_SIZE_MAX); } SetBufferSize(buffer_size); return 0; @@ -156,8 +156,9 @@ extern "C" } } - if (wait_time == 0) // Not set + if (wait_time == 0) { // Not set wait_time = (unsigned long)((((float)period_size) / ((float)sample_rate)) * 1000000.0f); + } Jack::JackDriverClientInterface* driver = new Jack::JackThreadedDriver(new Jack::JackDummyDriver("system", "dummy_pcm", engine, table, wait_time)); if (driver->Open(period_size, sample_rate, 1, 1, capture_ports, playback_ports, monitor, "dummy", "dummy", 0, 0) == 0) { diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index b754d60e..caef0114 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -194,7 +194,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { } // Set a timeout on the multicast receive (the thread can now be cancelled) - if (fSocket.SetTimeOut(2000000) == SOCKET_ERROR) { + if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) { fprintf(stderr, "Can't set timeout : %s\n", StrError(NET_ERROR_CODE)); } @@ -630,7 +630,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf bool Init() { // Will do "something" on OSX only... - fThread.SetParams(UInt64(float(fParams.fPeriodSize)/float(fParams.fSampleRate)*1000000), 100 * 1000, 500 * 1000); + UInt64 period, constraint; + period = constraint = float(fParams.fPeriodSize) / float(fParams.fSampleRate) * 1000000; + UInt64 computation = JackTools::ComputationMicroSec(fParams.fPeriodSize); + fThread.SetParams(period, computation, constraint); + return (fThread.AcquireRealTime(80) == 0); // TODO: get a value from the server } @@ -639,8 +643,9 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf try { // Keep running even in case of error while (fThread.GetStatus() == JackThread::kRunning) { - if (Process() == SOCKET_ERROR) + if (Process() == SOCKET_ERROR) { return false; + } } return false; } catch (JackNetException& e) { @@ -661,10 +666,9 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf int Read() { - // Don't return -1 in case of sync recv failure - // we need the process to continue for network error detection + //receive sync (launch the cycle) if (SyncRecv() == SOCKET_ERROR) { - return 0; + return SOCKET_ERROR; } DecodeSyncPacket(); @@ -684,8 +688,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf int Process() { - // Read data from the network - // in case of fatal network error, stop the process + // Read data from the network, throw JackNetException in case of network error... if (Read() == SOCKET_ERROR) { return SOCKET_ERROR; } @@ -701,8 +704,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf (void**)fMidiPlaybackBuffer, fProcessArg); - // Then write data to network - // in case of failure, stop process + // Then write data to network, throw JackNetException in case of network error... if (Write() == SOCKET_ERROR) { return SOCKET_ERROR; } @@ -801,8 +803,9 @@ struct JackNetAdapter : public JackAudioAdapterInterface { AdaptRingBufferSize(); jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); } else { - if (fRingbufferCurSize > DEFAULT_RB_SIZE) + if (fRingbufferCurSize > DEFAULT_RB_SIZE) { fRingbufferCurSize = DEFAULT_RB_SIZE; + } jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); } diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 17840757..54b272af 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -261,57 +261,56 @@ namespace Jack //audio port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; - for (audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) - { + for (audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, audio_port_index + 1); snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, audio_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, - static_cast(port_flags), fEngineControl->fBufferSize, &port_index) < 0) - { + static_cast(port_flags), fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } + + //port latency port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - //port latency range.min = range.max = fEngineControl->fBufferSize; port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[audio_port_index] = port_index; jack_log("JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency()); } + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - for (audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) - { + for (audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, audio_port_index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d",fClientControl.fName, audio_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, - static_cast(port_flags), fEngineControl->fBufferSize, &port_index) < 0) - { + static_cast(port_flags), fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } + + //port latency port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - //port latency 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()); } + //midi port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; - for (midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) - { + for (midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, midi_port_index + 1); snprintf(name, sizeof (name) - 1, "%s:midi_capture_%d", fClientControl.fName, midi_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, - static_cast(port_flags), fEngineControl->fBufferSize, &port_index) < 0) - { + static_cast(port_flags), fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } - port = fGraphManager->GetPort(port_index); + //port latency + port = fGraphManager->GetPort(port_index); range.min = range.max = fEngineControl->fBufferSize; port->SetLatencyRange(JackCaptureLatency, &range); fMidiCapturePortList[midi_port_index] = port_index; @@ -319,18 +318,17 @@ namespace Jack } port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - for (midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) - { + for (midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, midi_port_index + 1); snprintf(name, sizeof(name) - 1, "%s:midi_playback_%d", fClientControl.fName, midi_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, - static_cast(port_flags), fEngineControl->fBufferSize, &port_index) < 0) - { + static_cast(port_flags), fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } - port = fGraphManager->GetPort(port_index); + //port latency + port = fGraphManager->GetPort(port_index); range.min = range.max = (fParams.fNetworkLatency * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); port->SetLatencyRange(JackPlaybackLatency, &range); fMidiPlaybackPortList[midi_port_index] = port_index; @@ -480,8 +478,9 @@ namespace Jack fReturnTransportData.fNewState = ((fReturnTransportData.fState == JackTransportNetStarting) && (fReturnTransportData.fState != fLastTransportState) && (fReturnTransportData.fState != fSendTransportData.fState)); - if (fReturnTransportData.fNewState) + if (fReturnTransportData.fNewState) { jack_info("Sending '%s'.", GetTransportState(fReturnTransportData.fState)); + } fLastTransportState = fReturnTransportData.fState; } diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index de1e8740..2f31abb0 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -74,7 +74,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, int network_latency, int celt_encoding); - ~JackNetDriver(); + virtual ~JackNetDriver(); int Open(jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 530b6e5a..3ffcbf98 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -318,6 +318,7 @@ namespace Jack case JackFloatEncoder: fNetAudioCaptureBuffer = new NetFloatAudioBuffer(&fParams, fParams.fSendAudioChannels, fTxData); + //fNetAudioCaptureBuffer = new NetFloatAudioBuffer1(&fParams, fParams.fSendAudioChannels, fTxData); break; case JackIntEncoder: @@ -340,6 +341,7 @@ namespace Jack case JackFloatEncoder: fNetAudioPlaybackBuffer = new NetFloatAudioBuffer(&fParams, fParams.fReturnAudioChannels, fRxData); + //fNetAudioPlaybackBuffer = new NetFloatAudioBuffer1(&fParams, fParams.fReturnAudioChannels, fRxData); break; case JackIntEncoder: @@ -476,7 +478,7 @@ namespace Jack bool JackNetMasterInterface::IsSynched() { - return (fCycleOffset <= fMaxCycleOffset); + return (fCurrentCycleOffset <= fMaxCycleOffset); } int JackNetMasterInterface::SyncSend() @@ -520,7 +522,7 @@ namespace Jack return SOCKET_ERROR; } - fCycleOffset = fTxHeader.fCycle - rx_head->fCycle; + fCurrentCycleOffset = fTxHeader.fCycle - rx_head->fCycle; */ // receive sync (launch the cycle) @@ -533,7 +535,7 @@ namespace Jack } while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's')); - fCycleOffset = fTxHeader.fCycle - rx_head->fCycle; + fCurrentCycleOffset = fTxHeader.fCycle - rx_head->fCycle; /* // Read active ports list @@ -542,8 +544,8 @@ namespace Jack } */ - if (fCycleOffset < fMaxCycleOffset) { - jack_info("Synching with latency = %d", fCycleOffset); + if (fCurrentCycleOffset < fMaxCycleOffset) { + jack_info("Synching with latency = %d", fCurrentCycleOffset); return 0; } else { rx_bytes = Recv(rx_head->fPacketSize, 0); @@ -592,13 +594,13 @@ namespace Jack void JackNetMasterInterface::EncodeSyncPacket() { // This method contains every step of sync packet informations coding - // first of all, reset sync packet + // first of all, clear sync packet memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams)); // then, first step : transport if (fParams.fTransportSync) { EncodeTransportData(); - TransportDataHToN(&fSendTransportData, &fSendTransportData); + TransportDataHToN(&fSendTransportData, &fSendTransportData); // copy to TxBuffer memcpy(fTxData, &fSendTransportData, sizeof(net_transport_data_t)); } @@ -676,10 +678,10 @@ namespace Jack } // Separate the connection protocol into two separated step - bool JackNetSlaveInterface::InitConnection(int time_out) + bool JackNetSlaveInterface::InitConnection(int time_out_sec) { jack_log("JackNetSlaveInterface::InitConnection()"); - uint try_count = (time_out > 0) ? ((1000000 * time_out) / SLAVE_INIT_TIMEOUT) : LONG_MAX; + uint try_count = (time_out_sec > 0) ? ((1000000 * time_out_sec) / SLAVE_INIT_TIMEOUT) : LONG_MAX; // set the parameters to send strcpy(fParams.fPacketType, "params"); @@ -800,7 +802,8 @@ namespace Jack bool JackNetSlaveInterface::SetParams() { jack_log("JackNetSlaveInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d", - fParams.fSendAudioChannels, fParams.fReturnAudioChannels, fParams.fSendMidiChannels, fParams.fReturnMidiChannels); + fParams.fSendAudioChannels, fParams.fReturnAudioChannels, + fParams.fSendMidiChannels, fParams.fReturnMidiChannels); JackNetInterface::SetParams(); @@ -823,6 +826,7 @@ namespace Jack case JackFloatEncoder: fNetAudioCaptureBuffer = new NetFloatAudioBuffer(&fParams, fParams.fSendAudioChannels, fRxData); + //fNetAudioCaptureBuffer = new NetFloatAudioBuffer1(&fParams, fParams.fSendAudioChannels, fRxData); break; case JackIntEncoder: @@ -845,6 +849,7 @@ namespace Jack case JackFloatEncoder: fNetAudioPlaybackBuffer = new NetFloatAudioBuffer(&fParams, fParams.fReturnAudioChannels, fTxData); + //fNetAudioPlaybackBuffer = new NetFloatAudioBuffer1(&fParams, fParams.fReturnAudioChannels, fTxData); break; case JackIntEncoder: @@ -1039,13 +1044,13 @@ namespace Jack void JackNetSlaveInterface::EncodeSyncPacket() { // This method contains every step of sync packet informations coding - // first of all, reset sync packet + // first of all, clear sync packet memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams)); // then first step : transport if (fParams.fTransportSync) { EncodeTransportData(); - TransportDataHToN(&fReturnTransportData, &fReturnTransportData); + TransportDataHToN(&fReturnTransportData, &fReturnTransportData); // copy to TxBuffer memcpy(fTxData, &fReturnTransportData, sizeof(net_transport_data_t)); } @@ -1083,7 +1088,6 @@ namespace Jack if (fNetAudioPlaybackBuffer) { fNetAudioPlaybackBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts); } - } } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index 95b85b20..ca76873c 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -127,7 +127,8 @@ namespace Jack protected: bool fRunning; - int fCycleOffset; + + int fCurrentCycleOffset; int fMaxCycleOffset; int fLastfCycleOffset; @@ -157,7 +158,7 @@ namespace Jack public: - JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0), fMaxCycleOffset(0), fLastfCycleOffset(0) + JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCurrentCycleOffset(0), fMaxCycleOffset(0), fLastfCycleOffset(0) {} JackNetMasterInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip) : JackNetInterface(params, socket, multicast_ip) @@ -179,7 +180,7 @@ namespace Jack static uint fSlaveCounter; bool Init(); - bool InitConnection(int time_out); + bool InitConnection(int time_out_sec); bool InitRendering(); net_status_t SendAvailableToMaster(long count = LONG_MAX); // long here (and not int...) diff --git a/common/JackNetOneDriver.h b/common/JackNetOneDriver.h index cb2c4383..5c1300c7 100644 --- a/common/JackNetOneDriver.h +++ b/common/JackNetOneDriver.h @@ -58,7 +58,7 @@ class JackNetOneDriver : public JackAudioDriver int sample_rate, int period_size, int resample_factor, const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val); - ~JackNetOneDriver(); + virtual ~JackNetOneDriver(); int Open(jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index c04d1c1b..0f79407b 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -101,8 +101,9 @@ namespace Jack fPortBuffer[port_index] = NULL; fNetBuffer = net_buffer; - fCycleSize = params->fMtu * (max(params->fSendMidiChannels, params->fReturnMidiChannels) * - params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t))); + fCycleSize = params->fMtu + * (max(params->fSendMidiChannels, params->fReturnMidiChannels) + * params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t))); } NetMidiBuffer::~NetMidiBuffer() @@ -137,10 +138,11 @@ namespace Jack { for (int port_index = 0; port_index < fNPorts; port_index++) { for (uint event = 0; event < fPortBuffer[port_index]->event_count; event++) { - if (fPortBuffer[port_index]->IsValid()) + if (fPortBuffer[port_index]->IsValid()) { jack_info("port %d : midi event %u/%u -> time : %u, size : %u", port_index + 1, event + 1, fPortBuffer[port_index]->event_count, fPortBuffer[port_index]->events[event].time, fPortBuffer[port_index]->events[event].size); + } } } } @@ -155,8 +157,9 @@ namespace Jack copy_size = sizeof(JackMidiBuffer) + fPortBuffer[port_index]->event_count * sizeof(JackMidiEvent); memcpy(fBuffer + pos, fPortBuffer[port_index], copy_size); pos += copy_size; - memcpy(fBuffer + pos, fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos), - fPortBuffer[port_index]->write_pos); + memcpy(fBuffer + pos, + fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos), + fPortBuffer[port_index]->write_pos); pos += fPortBuffer[port_index]->write_pos; JackMidiBuffer* midi_buffer = reinterpret_cast(write_pos); @@ -168,7 +171,7 @@ namespace Jack void NetMidiBuffer::RenderToJackPorts() { int pos = 0; - int copy_size; + size_t copy_size; for (int port_index = 0; port_index < fNPorts; port_index++) { JackMidiBuffer* midi_buffer = reinterpret_cast(fBuffer + pos); @@ -177,7 +180,8 @@ namespace Jack memcpy(fPortBuffer[port_index], fBuffer + pos, copy_size); pos += copy_size; memcpy(fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos), - fBuffer + pos, fPortBuffer[port_index]->write_pos); + fBuffer + pos, + fPortBuffer[port_index]->write_pos); pos += fPortBuffer[port_index]->write_pos; } } @@ -197,59 +201,291 @@ namespace Jack // net audio buffer ********************************************************************************* + //network<->buffer + + void NetAudioBuffer::ActivePortsToNetwork(uint32_t& port_num) + { + // Init active port count + port_num = 0; + short* active_port_address = (short*)fNetBuffer; + + for (int port_index = 0; port_index < fNPorts; port_index++) { + // Write the active port number + if (fPortBuffer[port_index]) { + *active_port_address = port_index; + active_port_address++; + port_num++; + assert(port_num < 512); + } + } + } + + void NetAudioBuffer::ActivePortsFromNetwork(uint32_t port_num) + { + short* active_port_address = (short*)fNetBuffer; + + for (int port_index = 0; port_index < fNPorts; port_index++) { + fPortBuffer[port_index] = NULL; + } + + for (uint port_index = 0; port_index < port_num; port_index++) { + // Use -1 when port is actually connected on other side + if (*active_port_address >= 0 && *active_port_address < fNPorts) { + fPortBuffer[*active_port_address] = (sample_t*)-1; + } else { + jack_error("ActivePortsFromNetwork: incorrect port = %d", *active_port_address); + } + active_port_address++; + } + } + + // Float NetFloatAudioBuffer::NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer) - : fPortBuffer(params, nports), fNetBuffer(net_buffer) - {} + : NetAudioBuffer(), fPortBuffer1(params, nports) + { + fNetBuffer = net_buffer; + } NetFloatAudioBuffer::~NetFloatAudioBuffer() {} size_t NetFloatAudioBuffer::GetCycleSize() { - return fPortBuffer.GetCycleSize(); + return fPortBuffer1.GetCycleSize(); } void NetFloatAudioBuffer::SetBuffer(int index, sample_t* buffer) { - fPortBuffer.SetBuffer(index, buffer); + fPortBuffer1.SetBuffer(index, buffer); } sample_t* NetFloatAudioBuffer::GetBuffer(int index) { - return fPortBuffer.GetBuffer(index); + return fPortBuffer1.GetBuffer(index); } void NetFloatAudioBuffer::RenderFromJackPorts() { - fPortBuffer.RenderFromJackPorts(); + fPortBuffer1.RenderFromJackPorts(); } void NetFloatAudioBuffer::RenderToJackPorts() { - fPortBuffer.RenderToJackPorts(); + fPortBuffer1.RenderToJackPorts(); } //network<->buffer int NetFloatAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num) { - return fPortBuffer.RenderFromNetwork(fNetBuffer, cycle, sub_cycle, copy_size, port_num); + return fPortBuffer1.RenderFromNetwork(fNetBuffer, cycle, sub_cycle, copy_size, port_num); } int NetFloatAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t& port_num) { - return fPortBuffer.RenderToNetwork(fNetBuffer, sub_cycle, port_num); + return fPortBuffer1.RenderToNetwork(fNetBuffer, sub_cycle, port_num); } void NetFloatAudioBuffer::ActivePortsToNetwork(char* net_buffer, uint32_t& port_num) { - fPortBuffer.ActivePortsToNetwork(net_buffer, port_num); + fPortBuffer1.ActivePortsToNetwork(net_buffer, port_num); } void NetFloatAudioBuffer::ActivePortsFromNetwork(char* net_buffer, uint32_t port_num) { - fPortBuffer.ActivePortsFromNetwork(net_buffer, port_num); + fPortBuffer1.ActivePortsFromNetwork(net_buffer, port_num); } + // New + + NetFloatAudioBuffer1::NetFloatAudioBuffer1(session_params_t* params, uint32_t nports, char* net_buffer) + : NetAudioBuffer() + { + fNetBuffer = net_buffer; + + fNPorts = nports; + fPeriodSize = params->fPeriodSize; + fPacketSize = params->fMtu - sizeof(packet_header_t); + + if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) { + fSubPeriodSize = params->fPeriodSize; + } else { + jack_nframes_t period = (int) powf(2.f,(int)(log(float(fPacketSize) + / (max(params->fReturnAudioChannels, params->fSendAudioChannels) + * sizeof(sample_t))) / log(2.))); + fSubPeriodSize = (period > fPeriodSize) ? fPeriodSize : period; + } + + fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t); + + fPortBuffer = new sample_t* [fNPorts]; + for (int port_index = 0; port_index < fNPorts; port_index++) { + fPortBuffer[port_index] = NULL; + } + + fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate); + fCycleSize = params->fMtu * (fPeriodSize / fSubPeriodSize); + + fLastSubCycle = -1; + } + + NetFloatAudioBuffer1::~NetFloatAudioBuffer1() + { + delete [] fPortBuffer; + } + + void NetFloatAudioBuffer1::SetBuffer(int index, sample_t* buffer) + { + //jack_info("NetFloatAudioBuffer1::SetBuffer %d %x", index, buffer); + fPortBuffer[index] = buffer; + } + + sample_t* NetFloatAudioBuffer1::GetBuffer(int index) + { + return fPortBuffer[index]; + } + + // needed size in bytes for an entire cycle + size_t NetFloatAudioBuffer1::GetCycleSize() + { + return fCycleSize; + } + + // cycle duration in sec + float NetFloatAudioBuffer1::GetCycleDuration() + { + return fCycleDuration; + } + + int NetFloatAudioBuffer1::GetNumPackets() + { + // Count active ports + int active_ports = 0; + for (int port_index = 0; port_index < fNPorts; port_index++) { + if (fPortBuffer[port_index]) active_ports++; + } + + if (active_ports == 0) { + fSubPeriodSize = fPeriodSize; + } else { + jack_nframes_t period = (int) powf(2.f, (int)(log(float(fPacketSize) / (active_ports * sizeof(sample_t))) / log(2.))); + fSubPeriodSize = (period > fPeriodSize) ? fPeriodSize : period; + } + + fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t) + sizeof(uint32_t); // The port number in coded on 4 bytes + + /* + jack_log("GetNumPackets packet = %d fPeriodSize = %d fSubPeriodSize = %d fSubPeriodBytesSize = %d", + fPeriodSize / fSubPeriodSize, fPeriodSize, fSubPeriodSize, fSubPeriodBytesSize); + */ + return fPeriodSize / fSubPeriodSize; // At least one packet + } + + //jack<->buffer + int NetFloatAudioBuffer1::RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num) + { + int res = 0; + + // Cleanup all JACK ports at the beginning of the cycle + if (sub_cycle == 0) { + for (int port_index = 0; port_index < fNPorts; port_index++) { + if (fPortBuffer[port_index]) { + memset(fPortBuffer[port_index], 0, fPeriodSize * sizeof(sample_t)); + } + } + } + + if (port_num > 0) { + + /// Setup rendering parameters + int sub_period_size, sub_period_bytes_size; + if (port_num == 0) { + sub_period_size = fPeriodSize; + } else { + jack_nframes_t period = (int) powf(2.f, (int)(log(float(fPacketSize) / (port_num * sizeof(sample_t))) / log(2.))); + sub_period_size = (period > fPeriodSize) ? fPeriodSize : period; + } + sub_period_bytes_size = sub_period_size * sizeof(sample_t) + sizeof(uint32_t); // The port number in coded on 4 bytes + + for (uint32_t port_index = 0; port_index < port_num; port_index++) { + // Only copy to active ports : read the active port number then audio data + uint32_t* active_port_address = (uint32_t*)(fNetBuffer + port_index * sub_period_bytes_size); + uint32_t active_port = (uint32_t)(*active_port_address); + if (fPortBuffer[port_index]) { + memcpy(fPortBuffer[active_port] + sub_cycle * sub_period_size, (char*)(active_port_address + 1), sub_period_bytes_size - sizeof(uint32_t)); + } + } + + if (sub_cycle != fLastSubCycle + 1) { + jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle); + res = NET_PACKET_ERROR; + } + + fLastSubCycle = sub_cycle; + } + + return res; + } + + int NetFloatAudioBuffer1::RenderToNetwork(int sub_cycle, uint32_t& port_num) + { + // Init active port count + port_num = 0; + + //jack_info("NetFloatAudioBuffer1::RenderToNetwork"); + + for (int port_index = 0; port_index < fNPorts; port_index++) { + // Only copy from active ports : write the active port number then audio data + if (fPortBuffer[port_index]) { + jack_info("NetFloatAudioBuffer1::RenderToNetwork %d", port_index); + uint32_t* active_port_address = (uint32_t*)(fNetBuffer + port_num * fSubPeriodBytesSize); + *active_port_address = port_index; + memcpy((char*)(active_port_address + 1), fPortBuffer[port_index] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize - sizeof(uint32_t)); + port_num++; + } + } + + return port_num * fSubPeriodBytesSize; + } + + //network<->buffer + /* + void NetFloatAudioBuffer1::ActivePortsToNetwork(uint32_t& port_num) + { + // Init active port count + port_num = 0; + short* active_port_address = (short*)fNetBuffer; + + for (int port_index = 0; port_index < fNPorts; port_index++) { + // Write the active port number + if (fPortBuffer[port_index]) { + *active_port_address = port_index; + active_port_address++; + port_num++; + assert(port_num < 512); + } + } + } + + void NetFloatAudioBuffer1::ActivePortsFromNetwork(uint32_t port_num) + { + short* active_port_address = (short*)fNetBuffer; + + for (int port_index = 0; port_index < fNPorts; port_index++) { + fPortBuffer[port_index] = NULL; + } + + for (uint port_index = 0; port_index < port_num; port_index++) { + // Use -1 when port is actually connected on other side + if (*active_port_address >= 0 && *active_port_address < fNPorts) { + fPortBuffer[*active_port_address] = (sample_t*)-1; + } else { + jack_error("ActivePortsFromNetwork: incorrect port = %d", *active_port_address); + } + active_port_address++; + } + } + */ + // Celt audio buffer ********************************************************************************* @@ -259,10 +495,10 @@ namespace Jack #define KPS_DIV 8 NetCeltAudioBuffer::NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps) - : fNetBuffer(net_buffer) { int res1, res2; + fNetBuffer = net_buffer; fNPorts = nports; fPeriodSize = params->fPeriodSize; @@ -496,12 +732,12 @@ namespace Jack #endif NetIntAudioBuffer::NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer) - : fNetBuffer(net_buffer) { int res1, res2; fNPorts = nports; fPeriodSize = params->fPeriodSize; + fNetBuffer = net_buffer; fPortBuffer = new sample_t* [fNPorts]; for (int port_index = 0; port_index < fNPorts; port_index++) { @@ -638,63 +874,6 @@ namespace Jack } } -// Buffered - -/* - NetBufferedAudioBuffer::NetBufferedAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer) - { - fMaxCycle = 0; - fNetBuffer = net_buffer; - - for (int i = 0; i < AUDIO_BUFFER_SIZE; i++) { - fPortBuffer[i].Init(params, nports); - } - - fJackPortBuffer = new sample_t* [nports]; - for (uint32_t port_index = 0; port_index < nports; port_index++) - fJackPortBuffer[port_index] = NULL; - } - - NetBufferedAudioBuffer::~NetBufferedAudioBuffer() - { - delete [] fJackPortBuffer; - } - - size_t NetBufferedAudioBuffer::GetCycleSize() - { - return fPortBuffer[0].GetCycleSize(); - } - - void NetBufferedAudioBuffer::SetBuffer(int index, sample_t* buffer) - { - fJackPortBuffer[index] = buffer; - } - - sample_t* NetBufferedAudioBuffer::GetBuffer(int index) - { - return fJackPortBuffer[index]; - } - - void NetBufferedAudioBuffer::RenderFromJackPorts (int sub_cycle) - { - fPortBuffer[0].RenderFromJackPorts(fNetBuffer, sub_cycle); // Always use first buffer... - } - - void NetBufferedAudioBuffer::RenderToJackPorts (int cycle, int sub_cycle) - { - if (cycle < fMaxCycle) { - jack_info("Wrong order fCycle %d sub_cycle %d fMaxCycle %d", cycle, sub_cycle, fMaxCycle); - } - fPortBuffer[cycle % AUDIO_BUFFER_SIZE].RenderToJackPorts(fNetBuffer, sub_cycle); - } - - void NetBufferedAudioBuffer::FinishRenderToJackPorts (int cycle) - { - fMaxCycle = std::max(fMaxCycle, cycle); - fPortBuffer[(cycle + 1) % AUDIO_BUFFER_SIZE].Copy(fJackPortBuffer); // Copy internal buffer in JACK ports - } - */ - // SessionParams ************************************************************************************ SERVER_EXPORT void SessionParamsHToN(session_params_t* src_params, session_params_t* dst_params) diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 085b0456..f81125f6 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -273,6 +273,13 @@ namespace Jack class SERVER_EXPORT NetAudioBuffer { + protected: + + int fNPorts; + int fLastSubCycle; + char* fNetBuffer; + sample_t** fPortBuffer; + public: NetAudioBuffer() @@ -301,6 +308,11 @@ namespace Jack virtual void SetBuffer(int index, sample_t* buffer) = 0; virtual sample_t* GetBuffer(int index) = 0; + + + virtual void ActivePortsToNetwork(uint32_t& port_num); + virtual void ActivePortsFromNetwork(uint32_t port_num); + }; /** @@ -519,7 +531,7 @@ namespace Jack struct JackOptimizedPortList : JackPortList { // Consuming port list is transmitted in the Sync packed - // "[---Header---|--active_port_num---audio data--|--active_port_num---audio data--]..." + // "[---Header---|--active_port_num (uint32_t) ---audio data--|--active_port_num (uint32_t) ---audio data--]..." JackOptimizedPortList(session_params_t* params, uint32_t nports) :JackPortList(params, nports) @@ -586,10 +598,10 @@ namespace Jack for (uint32_t port_index = 0; port_index < port_num; port_index++) { // Only copy to active ports : read the active port number then audio data - int* active_port_address = (int*)(net_buffer + port_index * sub_period_bytes_size); - int active_port = (int)(*active_port_address); + uint32_t* active_port_address = (uint32_t*)(net_buffer + port_index * sub_period_bytes_size); + uint32_t active_port = (uint32_t)(*active_port_address); if (fPortBuffer[port_index]) { - memcpy(fPortBuffer[active_port] + sub_cycle * sub_period_size, (char*)(active_port_address + 1), sub_period_bytes_size - sizeof(int)); + memcpy(fPortBuffer[active_port] + sub_cycle * sub_period_size, (char*)(active_port_address + 1), sub_period_bytes_size - sizeof(uint32_t)); } } @@ -612,7 +624,7 @@ namespace Jack for (int port_index = 0; port_index < fNPorts; port_index++) { // Only copy from active ports : write the active port number then audio data if (fPortBuffer[port_index]) { - int* active_port_address = (int*)(net_buffer + port_num * fSubPeriodBytesSize); + uint32_t* active_port_address = (uint32_t*)(net_buffer + port_num * fSubPeriodBytesSize); *active_port_address = port_index; memcpy((char*)(active_port_address + 1), fPortBuffer[port_index] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize - sizeof(uint32_t)); port_num++; @@ -667,16 +679,15 @@ namespace Jack private: #ifdef OPTIMIZED_PROTOCOL - JackOptimizedPortList fPortBuffer; + JackOptimizedPortList fPortBuffer1; #else - JackPortList fPortBuffer; + JackPortList fPortBuffer1; #endif - char* fNetBuffer; public: NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); - ~NetFloatAudioBuffer(); + virtual ~NetFloatAudioBuffer(); // needed size in bytes for an entire cycle size_t GetCycleSize(); @@ -684,12 +695,12 @@ namespace Jack // cycle duration in sec float GetCycleDuration() { - return fPortBuffer.GetCycleDuration(); + return fPortBuffer1.GetCycleDuration(); } int GetNumPackets() { - return fPortBuffer.GetNumPackets(); + return fPortBuffer1.GetNumPackets(); } //jack<->buffer @@ -707,6 +718,59 @@ namespace Jack void ActivePortsToNetwork(char* net_buffer, uint32_t& port_num); }; + class SERVER_EXPORT NetFloatAudioBuffer1 : public NetAudioBuffer + { + + private: + + jack_nframes_t fPeriodSize; + jack_nframes_t fSubPeriodSize; + size_t fSubPeriodBytesSize; + //sample_t** fPortBuffer; + int fPacketSize; + //int fNPorts; + size_t fCycleSize; // needed size in bytes for an entire cycle + float fCycleDuration; // in sec + + //int fLastSubCycle; + + public: + + NetFloatAudioBuffer1(session_params_t* params, uint32_t nports, char* net_buffer); + virtual ~NetFloatAudioBuffer1(); + + // needed size in bytes for an entire cycle + size_t GetCycleSize(); + + // cycle duration in sec + float GetCycleDuration(); + + int GetNumPackets(); + + void SetBuffer(int index, sample_t* buffer); + sample_t* GetBuffer(int index); + + virtual void RenderFromJackPorts() + {} + + virtual void RenderToJackPorts() + { + // reset for next cycle + fLastSubCycle = -1; + } + + //jack<->buffer + int RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num); + int RenderToNetwork(int sub_cycle, uint32_t& port_num); + + /* + void ActivePortsToNetwork(uint32_t& port_num); + void ActivePortsFromNetwork(uint32_t port_num); + */ + + + }; + #if HAVE_CELT #include @@ -729,13 +793,9 @@ namespace Jack size_t fSubPeriodBytesSize; size_t fLastSubPeriodBytesSize; - sample_t** fPortBuffer; - char* fNetBuffer; + //sample_t** fPortBuffer; unsigned char** fCompressedBuffer; - int fNPorts; - int fLastSubCycle; - void FreeCelt(); public: @@ -772,21 +832,19 @@ namespace Jack jack_nframes_t fPeriodSize; int fNumPackets; + float fCycleDuration; // in sec size_t fCycleSize; // needed size in bytes for an entire cycle size_t fSubPeriodSize; size_t fSubPeriodBytesSize; + size_t fLastSubPeriodSize; size_t fLastSubPeriodBytesSize; - sample_t** fPortBuffer; - char* fNetBuffer; + //sample_t** fPortBuffer; short** fIntBuffer; - int fNPorts; - int fLastSubCycle; - public: NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); @@ -811,91 +869,6 @@ namespace Jack int RenderToNetwork(int sub_cycle, uint32_t& port_num); }; - /* - #define AUDIO_BUFFER_SIZE 8 - - struct JackPortListAllocate : public JackPortList { - - JackPortListAllocate() - { - fNPorts = 0; - fPeriodSize = 0; - fSubPeriodSize = 0; - fSubPeriodBytesSize = 0; - fPortBuffer = 0; - } - - ~JackPortListAllocate() - { - for (int port_index = 0; port_index < fNPorts; port_index++) - delete [] fPortBuffer[port_index]; - delete [] fPortBuffer; - } - - void Init(session_params_t* params, uint32_t nports) - { - fNPorts = nports; - fPeriodSize = params->fPeriodSize; - - if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) { - fSubPeriodSize = params->fPeriodSize; - } else { - jack_nframes_t period = (int) powf(2.f, (int)(log(float((params->fMtu - sizeof(packet_header_t))) - / (max(params->fReturnAudioChannels, params->fSendAudioChannels) * sizeof(sample_t))) / log(2.))); - fSubPeriodSize = (period > params->fPeriodSize) ? params->fPeriodSize : period; - } - - fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t); - fPortBuffer = new sample_t* [fNPorts]; - for (int port_index = 0; port_index < fNPorts; port_index++) - fPortBuffer[port_index] = new sample_t[fPeriodSize]; - } - - }; - - class SERVER_EXPORT NetBufferedAudioBuffer : public NetAudioBuffer - { - - private: - char* fNetBuffer; - JackPortListAllocate fPortBuffer[AUDIO_BUFFER_SIZE]; - sample_t** fJackPortBuffer; - int fMaxCycle; - - public: - NetBufferedAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); - ~NetBufferedAudioBuffer(); - - // needed syze in bytes ofr an entire cycle - size_t GetCycleSize(); - - // cycle duration in sec - float GetCycleDuration() - { - return fPortBuffer[0].GetCycleDuration(); - } - - //jack<->buffer - void RenderFromJackPorts(int sub_cycle); - void RenderToJackPorts(int cycle, int sub_cycle); - //void FinishRenderToJackPorts(int cycle); - - //network<->buffer - void RenderFromNetwork(int sub_cycle, size_t copy_size) - { - // TODO - } - int RenderToNetwork(int sub_cycle, size_t total_size) - { - // TODO - return 0; - } - - void SetBuffer(int index, sample_t* buffer); - sample_t* GetBuffer(int index); - }; - */ - //utility ************************************************************************************* //socket API management diff --git a/common/JackPort.cpp b/common/JackPort.cpp index 8e3be740..9bc53d83 100644 --- a/common/JackPort.cpp +++ b/common/JackPort.cpp @@ -35,6 +35,7 @@ JackPort::JackPort() bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags) { jack_port_type_id_t id = GetPortTypeId(port_type); + assert(id >= 0 && id <= PORT_TYPES_MAX); if (id == PORT_TYPES_MAX) return false; fTypeId = id; diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index 29fab30f..36a4c342 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -21,6 +21,7 @@ #include "JackSystemDeps.h" #include "JackThreadedDriver.h" #include "JackError.h" +#include "JackTools.h" #include "JackGlobals.h" #include "JackEngineControl.h" @@ -232,7 +233,7 @@ bool JackThreadedDriver::Init() jack_log("JackThreadedDriver::Init IsRealTime"); // Will do "something" on OSX only... GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; - GetEngineControl()->fComputation = ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000; + GetEngineControl()->fComputation = JackTools::ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireSelfRealTime error"); diff --git a/common/JackThreadedDriver.h b/common/JackThreadedDriver.h index 83d09faf..9d4876b1 100644 --- a/common/JackThreadedDriver.h +++ b/common/JackThreadedDriver.h @@ -110,18 +110,6 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi virtual bool Execute(); virtual bool Init(); - // For OSX only - int ComputationMicroSec(int buffer_size) - { - if (buffer_size < 128) { - return 500; - } else if (buffer_size < 256) { - return 300; - } else { - return 100; - } - } - }; } // end of namespace diff --git a/common/JackTools.h b/common/JackTools.h index 50451e04..4b312563 100644 --- a/common/JackTools.h +++ b/common/JackTools.h @@ -68,8 +68,20 @@ namespace Jack static void CleanupFiles ( const char* server_name ); static int GetTmpdir(); static void RewriteName ( const char* name, char* new_name ); - + static void ThrowJackNetException(); + + // For OSX only + static int ComputationMicroSec(int buffer_size) + { + if (buffer_size < 128) { + return 500; + } else if (buffer_size < 256) { + return 300; + } else { + return 100; + } + } }; /*! diff --git a/common/JackWaitThreadedDriver.cpp b/common/JackWaitThreadedDriver.cpp index d75ab3ae..f72a9e07 100644 --- a/common/JackWaitThreadedDriver.cpp +++ b/common/JackWaitThreadedDriver.cpp @@ -25,6 +25,7 @@ #include "JackEngineControl.h" #include "JackException.h" #include "JackError.h" +#include "JackTools.h" namespace Jack { @@ -47,7 +48,7 @@ bool JackWaitThreadedDriver::Execute() jack_log("JackWaitThreadedDriver::Init IsRealTime"); // Will do "something" on OSX only... GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; - GetEngineControl()->fComputation = ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000; + GetEngineControl()->fComputation = JackTools::ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireSelfRealTime error"); diff --git a/common/jack/net.h b/common/jack/net.h index f2093ba6..4217bccb 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -155,7 +155,7 @@ int jack_net_slave_deactivate(jack_net_slave_t* net); typedef int (*JackNetSlaveBufferSizeCallback)(jack_nframes_t nframes, void *arg); /** - * Prototype for SampleRate callback + * Prototype for SampleRate callback. * @param nframes sample rate * @param arg pointer to a client supplied structure supplied by jack_set_net_sample_rate_callback(). * @@ -184,7 +184,7 @@ int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveB int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg); /** - * Prototype for server Shutdown callback (if not set, the client will just restart, waiting for an available master again.) + * Prototype for server Shutdown callback (if not set, the client will just restart, waiting for an available master again). * @param arg pointer to a client supplied structure supplied by jack_set_net_shutdown_callback(). */ typedef void (*JackNetSlaveShutdownCallback)(void* data); @@ -200,8 +200,8 @@ typedef void (*JackNetSlaveShutdownCallback)(void* data); int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg); /** - * jack_net_master_t is an opaque type. You may only access it using the - * API provided. + * jack_net_master_t is an opaque type. + * You may only access it using the API provided. */ typedef struct _jack_net_master jack_net_master_t; @@ -217,7 +217,7 @@ typedef struct _jack_net_master jack_net_master_t; jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result); /** - * Close the network connection with the master machine. + * Close the network connection with the slave machine. * @param net the network connection to be closed * * @return 0 on success, otherwise a non-zero error code @@ -225,7 +225,7 @@ jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* na int jack_net_master_close(jack_net_master_t* net); /** - * Receive sync and data from the network + * Receive sync and data from the network. * @param net the network connection * @param audio_input number of audio inputs * @param audio_input_buffer an array of audio input buffers diff --git a/example-clients/alias.c b/example-clients/alias.c index 87a19b88..cb2b3f99 100644 --- a/example-clients/alias.c +++ b/example-clients/alias.c @@ -55,7 +55,7 @@ main (int argc, char *argv[]) int option_index; extern int optind; jack_port_t* port; - + struct option long_options[] = { { "unalias", 0, 0, 'u' }, { "help", 0, 0, 'h' }, @@ -129,5 +129,5 @@ main (int argc, char *argv[]) jack_client_close (client); return ret; - + } diff --git a/example-clients/bufsize.c b/example-clients/bufsize.c index c6407c20..3e176a89 100644 --- a/example-clients/bufsize.c +++ b/example-clients/bufsize.c @@ -103,7 +103,7 @@ int main(int argc, char *argv[]) jack_on_shutdown(client, jack_shutdown, 0); if (just_print_bufsize) { - fprintf(stdout, "%d\n", jack_get_buffer_size( client ) ); + fprintf(stdout, "%d %d\n", jack_get_buffer_size(client), jack_get_sample_rate(client)); rc=0; } else diff --git a/example-clients/capture_client.c b/example-clients/capture_client.c index 72a2467f..08585051 100644 --- a/example-clients/capture_client.c +++ b/example-clients/capture_client.c @@ -1,7 +1,7 @@ /* Copyright (C) 2001 Paul Davis Copyright (C) 2003 Jack O'Quin - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -100,7 +100,7 @@ disk_thread (void *arg) info->status = EIO; /* write failed */ goto done; } - + if (++total_captured >= info->duration) { printf ("disk thread finished\n"); goto done; @@ -116,7 +116,7 @@ disk_thread (void *arg) free (framebuf); return 0; } - + static int process (jack_nframes_t nframes, void *arg) { @@ -168,10 +168,10 @@ setup_disk_thread (jack_thread_info_t *info) { SF_INFO sf_info; int short_mask; - + sf_info.samplerate = jack_get_sample_rate (info->client); sf_info.channels = info->channels; - + switch (info->bitdepth) { case 8: short_mask = SF_FORMAT_PCM_U8; break; @@ -183,7 +183,7 @@ setup_disk_thread (jack_thread_info_t *info) break; default: short_mask = SF_FORMAT_PCM_16; break; - } + } sf_info.format = SF_FORMAT_WAV|short_mask; if ((info->sf = sf_open (info->path, SFM_WRITE, &sf_info)) == NULL) { @@ -253,7 +253,7 @@ setup_ports (int sources, char *source_names[], jack_thread_info_t *info) fprintf (stderr, "cannot connect input port %s to %s\n", jack_port_name (ports[i]), source_names[i]); jack_client_close (info->client); exit (1); - } + } } info->can_process = 1; /* process() can start, now */ @@ -315,7 +315,7 @@ main (int argc, char *argv[]) } if ((client = jack_client_open ("jackrec", JackNullOption, NULL)) == 0) { - fprintf (stderr, "jack server not running?\n"); + fprintf (stderr, "JACK server not running?\n"); exit (1); } @@ -333,7 +333,7 @@ main (int argc, char *argv[]) } setup_ports (argc - optind, &argv[optind], &thread_info); - + /* install a signal handler to properly quits jack client */ signal(SIGQUIT, signal_handler); signal(SIGTERM, signal_handler); diff --git a/example-clients/connect.c b/example-clients/connect.c index 3c6de6b9..5ed112b0 100644 --- a/example-clients/connect.c +++ b/example-clients/connect.c @@ -133,7 +133,7 @@ main (int argc, char *argv[]) /* try to become a client of the JACK server */ if ((client = jack_client_open (my_name, options, &status, server_name)) == 0) { - fprintf (stderr, "jack server not running?\n"); + fprintf (stderr, "JACK server not running?\n"); return 1; } diff --git a/example-clients/freewheel.c b/example-clients/freewheel.c index c0892833..a59a8cec 100644 --- a/example-clients/freewheel.c +++ b/example-clients/freewheel.c @@ -2,7 +2,7 @@ * freewheel - start/stop JACK "freewheeling" mode * * Copyright (C) 2003 Paul Davis. - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -58,7 +58,7 @@ static void parse_arguments(int argc, char *argv[]) } } -int +int main (int argc, char *argv[]) { parse_arguments (argc, argv); diff --git a/example-clients/impulse_grabber.c b/example-clients/impulse_grabber.c index 0a1fd706..80006c0b 100644 --- a/example-clients/impulse_grabber.c +++ b/example-clients/impulse_grabber.c @@ -36,7 +36,7 @@ unsigned long response_duration; unsigned long response_pos; int grab_finished = 0; jack_client_t *client; - + static void signal_handler(int sig) { jack_client_close(client); @@ -60,7 +60,7 @@ process (jack_nframes_t nframes, void *arg) } if (response_pos >= response_duration) { grab_finished = 1; - } + } for (i=0; i #endif #include -#include +#include #include #include @@ -246,3 +246,4 @@ error: jack_client_close (client); exit (0); } + diff --git a/example-clients/metro.c b/example-clients/metro.c index d2daaa7f..973c7095 100644 --- a/example-clients/metro.c +++ b/example-clients/metro.c @@ -1,6 +1,6 @@ /* Copyright (C) 2002 Anthony Van Groningen - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -69,18 +69,21 @@ usage () } static void -process_silence (jack_nframes_t nframes) +process_silence (jack_nframes_t nframes) { sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes); memset (buffer, 0, sizeof (jack_default_audio_sample_t) * nframes); } +jack_nframes_t last_time; +jack_time_t last_micro_time; + static void -process_audio (jack_nframes_t nframes) +process_audio (jack_nframes_t nframes) { sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes); jack_nframes_t frames_left = nframes; - + while (wave_length - offset < frames_left) { memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * (wave_length - offset)); frames_left -= wave_length - offset; @@ -90,6 +93,13 @@ process_audio (jack_nframes_t nframes) memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * frames_left); offset += frames_left; } + + jack_nframes_t cur_time = jack_frame_time(client); + jack_time_t cur_micro_time = jack_get_time(); + + printf("jack_frame_timed %lld micro %lld delta %d\n", cur_time, (cur_micro_time - last_micro_time), cur_time - last_time); + last_time = cur_time; + last_micro_time = cur_micro_time; } static int @@ -141,7 +151,7 @@ main (int argc, char *argv[]) {"verbose", 0, 0, 'v'}, {0, 0, 0, 0} }; - + while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { case 'f': @@ -193,7 +203,7 @@ main (int argc, char *argv[]) transport_aware = 1; break; default: - fprintf (stderr, "unknown option %c\n", opt); + fprintf (stderr, "unknown option %c\n", opt); case 'h': usage (); return -1; @@ -211,7 +221,7 @@ main (int argc, char *argv[]) strcpy (client_name, "metro"); } if ((client = jack_client_open (client_name, JackNoStartServer, &status)) == 0) { - fprintf (stderr, "jack server not running?\n"); + fprintf (stderr, "JACK server not running?\n"); return 1; } jack_set_process_callback (client, process, 0); @@ -259,7 +269,7 @@ main (int argc, char *argv[]) fprintf (stderr, "cannot activate client\n"); goto error; } - + /* install a signal handler to properly quits jack client */ #ifdef WIN32 signal(SIGINT, signal_handler); @@ -280,9 +290,9 @@ main (int argc, char *argv[]) sleep(1); #endif }; - + jack_client_close(client); - + error: free(amp); free(wave); diff --git a/example-clients/midiseq.c b/example-clients/midiseq.c index 10a37b2a..60b3e483 100644 --- a/example-clients/midiseq.c +++ b/example-clients/midiseq.c @@ -1,6 +1,6 @@ /* Copyright (C) 2004 Ian Esten - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -93,7 +93,7 @@ int main(int narg, char **args) } if((client = jack_client_open (args[1], JackNullOption, NULL)) == 0) { - fprintf (stderr, "jack server not running?\n"); + fprintf (stderr, "JACK server not running?\n"); return 1; } jack_set_process_callback (client, process, 0); @@ -117,7 +117,7 @@ int main(int narg, char **args) fprintf (stderr, "cannot activate client"); return 1; } - + /* install a signal handler to properly quits jack client */ signal(SIGQUIT, signal_handler); signal(SIGTERM, signal_handler); @@ -128,7 +128,7 @@ int main(int narg, char **args) while (1) { sleep(1); }; - + jack_client_close(client); exit (0); } diff --git a/example-clients/midisine.c b/example-clients/midisine.c index 89ff7f75..ce830019 100644 --- a/example-clients/midisine.c +++ b/example-clients/midisine.c @@ -1,6 +1,6 @@ /* Copyright (C) 2004 Ian Esten - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -76,7 +76,7 @@ static int process(jack_nframes_t nframes, void *arg) if ((in_event.time == i) && (event_index < event_count)) { if (((*(in_event.buffer) & 0xf0)) == 0x90) - { + { /* note on */ note = *(in_event.buffer + 1); if (*(in_event.buffer + 2) == 0) { @@ -99,7 +99,7 @@ static int process(jack_nframes_t nframes, void *arg) ramp = (ramp > 1.0) ? ramp - 2.0 : ramp; out[i] = note_on*sin(2*M_PI*ramp); } - return 0; + return 0; } static int srate(jack_nframes_t nframes, void *arg) @@ -118,10 +118,10 @@ int main(int narg, char **args) { if ((client = jack_client_open("midisine", JackNullOption, NULL)) == 0) { - fprintf(stderr, "jack server not running?\n"); + fprintf(stderr, "JACK server not running?\n"); return 1; } - + calc_note_frqs(jack_get_sample_rate (client)); jack_set_process_callback (client, process, 0); @@ -138,7 +138,7 @@ int main(int narg, char **args) fprintf(stderr, "cannot activate client"); return 1; } - + /* install a signal handler to properly quits jack client */ signal(SIGQUIT, signal_handler); signal(SIGTERM, signal_handler); diff --git a/example-clients/monitor_client.c b/example-clients/monitor_client.c index 0a89b17c..36f61d6f 100644 --- a/example-clients/monitor_client.c +++ b/example-clients/monitor_client.c @@ -42,7 +42,7 @@ main (int argc, char *argv[]) } if ((client = jack_client_open ("input monitoring", JackNullOption, NULL)) == 0) { - fprintf (stderr, "jack server not running?\n"); + fprintf (stderr, "JACK server not running?\n"); return 1; } diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c index be7eb0e6..c9dd42ae 100644 --- a/example-clients/netmaster.c +++ b/example-clients/netmaster.c @@ -108,7 +108,7 @@ main (int argc, char *argv[]) printf("Waiting for a slave...\n"); if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_master", &request, &result)) == 0) { - fprintf(stderr, "jack server not running?\n"); + fprintf(stderr, "NetJack master can not be opened\n"); return 1; } diff --git a/example-clients/netslave.c b/example-clients/netslave.c index 077ed314..fb34169e 100644 --- a/example-clients/netslave.c +++ b/example-clients/netslave.c @@ -120,13 +120,13 @@ main (int argc, char *argv[]) } } - jack_slave_t request = { audio_input, audio_output, 0, 0, DEFAULT_MTU, -1, 2 }; + jack_slave_t request = { audio_input, audio_output, 0, 0, DEFAULT_MTU, -1, JackFloatEncoder, 0, 2 }; jack_master_t result; printf("Waiting for a master...\n"); if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_slave", &request, &result)) == 0) { - fprintf(stderr, "jack server not running?\n"); + fprintf(stderr, "JACK server not running?\n"); return 1; } @@ -136,7 +136,7 @@ main (int argc, char *argv[]) jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); if (jack_net_slave_activate(net) != 0) { - fprintf(stderr, "Cannot sactivate client\n"); + fprintf(stderr, "Cannot activate slave client\n"); return 1; } @@ -164,5 +164,5 @@ main (int argc, char *argv[]) // Wait for application end jack_net_slave_deactivate(net); jack_net_slave_close(net); - exit (0); + exit(0); } diff --git a/example-clients/showtime.c b/example-clients/showtime.c index af413e89..fbbb94b7 100644 --- a/example-clients/showtime.c +++ b/example-clients/showtime.c @@ -34,7 +34,7 @@ showtime () transport_state = jack_transport_query (client, ¤t); frame_time = jack_frame_time (client); - + printf ("frame = %u frame_time = %u usecs = %lld \t", current.frame, frame_time, current.usecs); switch (transport_state) { @@ -81,7 +81,7 @@ main (int argc, char *argv[]) /* try to become a client of the JACK server */ if ((client = jack_client_open ("showtime", JackNullOption, NULL)) == 0) { - fprintf (stderr, "jack server not running?\n"); + fprintf (stderr, "JACK server not running?\n"); return 1; } @@ -103,7 +103,7 @@ main (int argc, char *argv[]) fprintf (stderr, "cannot activate client"); return 1; } - + while (1) { usleep (20); showtime (); diff --git a/example-clients/zombie.c b/example-clients/zombie.c index fb3cd24e..c982cfa8 100644 --- a/example-clients/zombie.c +++ b/example-clients/zombie.c @@ -54,7 +54,7 @@ main (int argc, char *argv[]) jack_client_t* client = NULL; /* try to become a client of the JACK server */ if ((client = jack_client_open ("zombie", JackNullOption, NULL)) == 0) { - fprintf (stderr, "jack server not running?\n"); + fprintf (stderr, "JACK server not running?\n"); goto error; } diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index 7ec618b3..ae71f227 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -24,7 +24,7 @@ int buffer_size = 1024; int sample_rate = 22050; //int sample_rate = 32000; -jack_master_t request = { buffer_size, sample_rate, "master" }; +jack_master_t request = { -1, -1, -1, -1, buffer_size, sample_rate, "master" }; jack_slave_t result; static void MixAudio(float** dst, float** src1, float** src2, int channels, int buffer_size) @@ -38,33 +38,33 @@ static void MixAudio(float** dst, float** src1, float** src2, int channels, int static void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg) { - int i; - + int i; + // Copy from iPod input to network buffers for (i = 0; i < result.audio_input; i++) { memcpy(audio_input_buffer[i], inputs[i], buffer_size * sizeof(float)); } - + /* // Copy from network out buffers to network in buffers (audio thru) for (i = 0; i < result.audio_input; i++) { memcpy(audio_input_buffer[i], audio_output_buffer[i], buffer_size * sizeof(float)); } */ - + // Mix iPod input and network in buffers to network out buffers //MixAudio(audio_input_buffer, inputs, audio_output_buffer, result.audio_input, buffer_size); - + // Send network buffers if (jack_net_master_send(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { printf("jack_net_master_send error..\n"); } - + // Recv network buffers if (jack_net_master_recv(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { printf("jack_net_master_recv error..\n"); } - + // Copy from network buffers to iPod output for (i = 0; i < result.audio_output; i++) { memcpy(outputs[i], audio_output_buffer[i], buffer_size * sizeof(float)); @@ -72,17 +72,17 @@ static void MasterAudioCallback(int frames, float** inputs, float** outputs, voi } int main(int argc, char *argv[]) { - + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int i; - + if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { printf("jack_net_master_open error..\n"); return -1; } - + TiPhoneCoreAudioRenderer audio_device(result.audio_input, result.audio_output); - + // Allocate buffers if (result.audio_input > 0) { audio_input_buffer = (float**)calloc(result.audio_input, sizeof(float*)); @@ -90,66 +90,66 @@ int main(int argc, char *argv[]) { audio_input_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); } } - + if (result.audio_output > 0) { audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*)); for (i = 0; i < result.audio_output; i++) { audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); } } - + if (audio_device.Open(buffer_size, sample_rate) < 0) { return -1; } - + audio_device.SetAudioCallback(MasterAudioCallback, NULL); - + if (audio_device.Start() < 0) { return -1; } - + /* // Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead... - // Run until interrupted - + // Run until interrupted + int wait_usec = (unsigned long)((((float)buffer_size) / ((float)sample_rate)) * 1000000.0f); - + while (1) { - + // Copy input to output for (i = 0; i < result.audio_input; i++) { memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); } - + if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { printf("jack_net_master_send error..\n"); } - + if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { printf("jack_net_master_recv error..\n"); } usleep(wait_usec); }; */ - + int retVal = UIApplicationMain(argc, argv, nil, nil); - + audio_device.Stop(); audio_device.Close(); - + // Wait for application end jack_net_master_close(net); - + for (i = 0; i < result.audio_input; i++) { free(audio_input_buffer[i]); } free(audio_input_buffer); - + for (i = 0; i < result.audio_output; i++) { free(audio_output_buffer[i]); } free(audio_output_buffer); - + [pool release]; return retVal; } diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index 9355772a..b9875c32 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -67,7 +67,7 @@ int main(int argc, char *argv[]) { //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPod", &request, &result)) == 0) { - printf("jack_net_slave_open error..\n"); + printf("jack_net_slave_open error...\n"); return -1; } @@ -86,6 +86,7 @@ int main(int argc, char *argv[]) { jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); if (jack_net_slave_activate(net) != 0) { + printf("Cannot activate slave client\n"); return -1; }