diff options
author | Stephane Letz <letz@grame.fr> | 2014-01-22 16:10:16 +0100 |
---|---|---|
committer | Stephane Letz <letz@grame.fr> | 2014-01-22 16:10:16 +0100 |
commit | 66b4bfd8bb3339cc62bfdf0f9d91969dc07b883e (patch) | |
tree | a4b3ca83f5388c255b193ee932571c91eb0c8dbc /common/JackNetAPI.cpp | |
parent | 7123ef156273db039e12e7ff2df3a6008e765baf (diff) | |
download | jack2-66b4bfd8bb3339cc62bfdf0f9d91969dc07b883e.tar.gz |
Support for partial buffers in libjacknet.
Diffstat (limited to 'common/JackNetAPI.cpp')
-rw-r--r-- | common/JackNetAPI.cpp | 113 |
1 files changed, 86 insertions, 27 deletions
diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 8fd34be3..62711c9b 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -63,7 +63,8 @@ extern "C" jack_nframes_t buffer_size; jack_nframes_t sample_rate; char master_name[MASTER_NAME_SIZE]; - int time_out; + int time_out; + int partial_cycle; } jack_master_t; @@ -112,6 +113,9 @@ extern "C" LIB_EXPORT int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); LIB_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer); + LIB_EXPORT int jack_net_master_recv_slice(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int frames); + LIB_EXPORT int jack_net_master_send_slice(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, int frames); + // NetJack adapter API typedef struct _jack_adapter jack_adapter_t; @@ -146,6 +150,8 @@ struct JackNetExtMaster : public JackNetMasterInterface { jack_master_t fRequest; int fPacketTimeOut; + + JackRingBuffer** fRingBuffer; JackNetExtMaster(const char* ip, int port, @@ -161,10 +167,19 @@ struct JackNetExtMaster : public JackNetMasterInterface { fRequest.audio_input = request->audio_input; fRequest.audio_output = request->audio_output; fRequest.time_out = request->time_out; + fRequest.partial_cycle = request->partial_cycle; + fRingBuffer = NULL; } virtual ~JackNetExtMaster() - {} + { + if (fRingBuffer) { + for (int i = 0; i < fParams.fReturnAudioChannels; i++) { + delete fRingBuffer[i]; + } + delete [] fRingBuffer; + } + } int Open(jack_slave_t* result) { @@ -257,6 +272,14 @@ struct JackNetExtMaster : public JackNetMasterInterface { result->midi_output = fParams.fReturnMidiChannels; result->mtu = fParams.fMtu; result->latency = fParams.fNetworkLatency; + + // Use ringbuffer in case of partial cycle and latency > 0 + if (fRequest.partial_cycle && result->latency > 0) { + fRingBuffer = new JackRingBuffer*[fParams.fReturnAudioChannels]; + for (int i = 0; i < fParams.fReturnAudioChannels; i++) { + fRingBuffer[i] = new JackRingBuffer(fRequest.buffer_size * result->latency * 2); + } + } return 0; error: @@ -332,10 +355,13 @@ struct JackNetExtMaster : public JackNetMasterInterface { return 0; } - int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) + int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int frames) { try { + + if (frames < 0) frames = fParams.fPeriodSize; + int cycle_size; assert(audio_input == fParams.fReturnAudioChannels); for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) { @@ -346,18 +372,25 @@ struct JackNetExtMaster : public JackNetMasterInterface { fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_input_buffer)[midi_port_index]); } - int res = SyncRecv(); - switch (res) { + int res1 = SyncRecv(); + switch (res1) { case NET_SYNCHING: // Data will not be received, so cleanup buffers... for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) { - memset(audio_input_buffer[audio_port_index], 0, sizeof(float) * fParams.fPeriodSize); + memset(audio_input_buffer[audio_port_index], 0, sizeof(float) * fParams.fPeriodSize); + } + // Possibly use ringbuffer... + if (fRingBuffer) { + for (int i = 0; i < audio_input; i++) { + fRingBuffer[i]->Write(audio_input_buffer[i], fParams.fPeriodSize); + fRingBuffer[i]->Read(audio_input_buffer[i], frames); + } } - return res; + return res1; case SOCKET_ERROR: - return res; + return res1; case SYNC_PACKET_ERROR: // since sync packet is incorrect, don't decode it and continue with data @@ -365,11 +398,20 @@ struct JackNetExtMaster : public JackNetMasterInterface { default: // decode sync - DecodeSyncPacket(); + cycle_size; + DecodeSyncPacket(cycle_size); break; } - return DataRecv(); + int res2 = DataRecv(); + // Possibly use ringbuffer... + if (res2 == 0 && fRingBuffer) { + for (int i = 0; i < audio_input; i++) { + fRingBuffer[i]->Write(audio_input_buffer[i], cycle_size); + fRingBuffer[i]->Read(audio_input_buffer[i], frames); + } + } + return res2; } catch (JackNetException& e) { jack_error("Lost connection"); @@ -377,9 +419,11 @@ struct JackNetExtMaster : public JackNetMasterInterface { } } - int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) + int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, int frames) { try { + + if (frames < 0) frames = fParams.fPeriodSize; assert(audio_output == fParams.fSendAudioChannels); @@ -391,8 +435,8 @@ struct JackNetExtMaster : public JackNetMasterInterface { fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]); } - EncodeSyncPacket(); - + EncodeSyncPacket(frames); + // send sync if (SyncSend() == SOCKET_ERROR) { return SOCKET_ERROR; @@ -402,7 +446,6 @@ struct JackNetExtMaster : public JackNetMasterInterface { if (DataSend() == SOCKET_ERROR) { return SOCKET_ERROR; } - return 0; } catch (JackNetException& e) { @@ -450,6 +493,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf void* fSampleRateArg; int fConnectTimeOut; + int fCycleSize; JackNetExtSlave(const char* ip, int port, @@ -610,8 +654,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf return -1; } - // Set result - if (result != NULL) { + // Set result + if (result != NULL) { result->buffer_size = fParams.fPeriodSize; result->sample_rate = fParams.fSampleRate; result->audio_input = fParams.fSendAudioChannels; @@ -620,7 +664,10 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf result->midi_output = fParams.fReturnMidiChannels; strcpy(result->master_name, fParams.fMasterNetName); } - + + // By default fCycleSize is fPeriodSize + fCycleSize = fParams.fPeriodSize; + AllocPorts(); return 0; } @@ -711,7 +758,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf bool Execute() { - try { + try { /* Fist cycle use an INT_MAX time out, so that connection is considered established (with PACKET_TIMEOUT later on) @@ -758,7 +805,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf default: // decode sync - DecodeSyncPacket(); + DecodeSyncPacket(fCycleSize); break; } @@ -768,11 +815,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf } return res; } - + int Write() { - EncodeSyncPacket(); - + EncodeSyncPacket(fCycleSize); + if (SyncSend() == SOCKET_ERROR) { return SOCKET_ERROR; } @@ -798,8 +845,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf if (Read() == SOCKET_ERROR) { return SOCKET_ERROR; } - - fProcessCallback(fParams.fPeriodSize, + + fProcessCallback(fCycleSize, fParams.fSendAudioChannels, fAudioCaptureBuffer, fParams.fSendMidiChannels, @@ -809,7 +856,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf fParams.fReturnMidiChannels, (void**)fMidiPlaybackBuffer, fProcessArg); - + // Then write data to network, throw JackNetException in case of network error... if (Write() == SOCKET_ERROR) { return SOCKET_ERROR; @@ -1068,13 +1115,25 @@ LIB_EXPORT int jack_net_master_close(jack_net_master_t* net) LIB_EXPORT int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) { JackNetExtMaster* master = (JackNetExtMaster*)net; - return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer); + return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer, -1); } LIB_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) { JackNetExtMaster* master = (JackNetExtMaster*)net; - return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer); + return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer, -1); +} + +LIB_EXPORT int jack_net_master_recv_slice(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int frames) +{ + JackNetExtMaster* master = (JackNetExtMaster*)net; + return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer, frames); +} + +LIB_EXPORT int jack_net_master_send_slice(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, int frames) +{ + JackNetExtMaster* master = (JackNetExtMaster*)net; + return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer, frames); } // Adapter API |