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 diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index e6a7cc9f..50b764cd 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -361,7 +361,8 @@ namespace Jack default: //decode sync - DecodeSyncPacket(); + int unused_cycle_size; + DecodeSyncPacket(unused_cycle_size); break; } diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 0950019f..49a2cab7 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -575,7 +575,8 @@ namespace Jack default: // decode sync - DecodeSyncPacket(); + int unused_cycle_size; + DecodeSyncPacket(unused_cycle_size); break; } @@ -724,8 +725,8 @@ Deactivated for now.. int mtu = DEFAULT_MTU; // Desactivated for now... uint transport_sync = 0; - jack_nframes_t period_size = 1024; - jack_nframes_t sample_rate = 48000; + jack_nframes_t period_size = 1024; // to be used while waiting for master period_size + jack_nframes_t sample_rate = 48000; // to be used while waiting for master sample_rate int audio_capture_ports = -1; int audio_playback_ports = -1; int midi_input_ports = -1; diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index e60c8a7e..35278cfe 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -544,7 +544,7 @@ namespace Jack return rx_bytes; } - void JackNetMasterInterface::EncodeSyncPacket() + void JackNetMasterInterface::EncodeSyncPacket(int cycle_size) { // This method contains every step of sync packet informations coding // first of all, clear sync packet @@ -565,9 +565,10 @@ namespace Jack // Write active ports list fTxHeader.fActivePorts = (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->ActivePortsToNetwork(fTxData) : 0; + fTxHeader.fCycleSize = cycle_size; } - void JackNetMasterInterface::DecodeSyncPacket() + void JackNetMasterInterface::DecodeSyncPacket(int& cycle_size) { // This method contains every step of sync packet informations decoding process @@ -590,6 +591,8 @@ namespace Jack if (fNetAudioCaptureBuffer) { fNetAudioCaptureBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts); } + + cycle_size = rx_head->fCycleSize; } // JackNetSlaveInterface ************************************************************************************************ @@ -946,7 +949,7 @@ namespace Jack } // network sync------------------------------------------------------------------------ - void JackNetSlaveInterface::EncodeSyncPacket() + void JackNetSlaveInterface::EncodeSyncPacket(int cycle_size) { // This method contains every step of sync packet informations coding // first of all, clear sync packet @@ -967,9 +970,10 @@ namespace Jack // Write active ports list fTxHeader.fActivePorts = (fNetAudioCaptureBuffer) ? fNetAudioCaptureBuffer->ActivePortsToNetwork(fTxData) : 0; + fTxHeader.fCycleSize = cycle_size; } - void JackNetSlaveInterface::DecodeSyncPacket() + void JackNetSlaveInterface::DecodeSyncPacket(int& cycle_size) { // This method contains every step of sync packet informations decoding process @@ -992,6 +996,8 @@ namespace Jack if (fNetAudioPlaybackBuffer) { fNetAudioPlaybackBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts); } + + cycle_size = rx_head->fCycleSize; } } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index 1efa234e..1f33e266 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -92,8 +92,8 @@ namespace Jack virtual void DecodeTransportData() = 0; // sync packet - virtual void EncodeSyncPacket() = 0; - virtual void DecodeSyncPacket() = 0; + virtual void EncodeSyncPacket(int cycle_size = -1) = 0; + virtual void DecodeSyncPacket(int& cycle_size) = 0; virtual int SyncRecv() = 0; virtual int SyncSend() = 0; @@ -160,8 +160,8 @@ namespace Jack int DataSend(); // sync packet - void EncodeSyncPacket(); - void DecodeSyncPacket(); + void EncodeSyncPacket(int cycle_size = -1); + void DecodeSyncPacket(int& cycle_size); int Send(size_t size, int flags); int Recv(size_t size, int flags); @@ -217,8 +217,8 @@ namespace Jack int DataSend(); // sync packet - void EncodeSyncPacket(); - void DecodeSyncPacket(); + void EncodeSyncPacket(int cycle_size = -1); + void DecodeSyncPacket(int& cycle_size); int Recv(size_t size, int flags); int Send(size_t size, int flags); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 67564d6c..e1a72f2b 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -543,7 +543,8 @@ namespace Jack default: // Decode sync - DecodeSyncPacket(); + int unused_cycle_size; + DecodeSyncPacket(unused_cycle_size); break; } diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index e5f24aab..bfa09176 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -1216,6 +1216,7 @@ namespace Jack dst_header->fActivePorts = htonl(src_header->fActivePorts); dst_header->fCycle = htonl(src_header->fCycle); dst_header->fSubCycle = htonl(src_header->fSubCycle); + dst_header->fCycleSize = htonl(src_header->fCycleSize); dst_header->fIsLastPckt = htonl(src_header->fIsLastPckt); } @@ -1230,6 +1231,7 @@ namespace Jack dst_header->fActivePorts = ntohl(src_header->fActivePorts); dst_header->fCycle = ntohl(src_header->fCycle); dst_header->fSubCycle = ntohl(src_header->fSubCycle); + dst_header->fCycleSize = ntohl(src_header->fCycleSize); dst_header->fIsLastPckt = ntohl(src_header->fIsLastPckt); } diff --git a/common/JackNetTool.h b/common/JackNetTool.h index d2bfc316..99b720db 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -38,7 +38,7 @@ using namespace std; #endif #endif -#define NETWORK_PROTOCOL 7 +#define NETWORK_PROTOCOL 8 #define NET_SYNCHING 0 #define SYNC_PACKET_ERROR -2 @@ -180,6 +180,7 @@ namespace Jack uint32_t fActivePorts; //number of active ports uint32_t fCycle; //process cycle counter uint32_t fSubCycle; //midi/audio subcycle counter + int32_t fCycleSize; //process cycle size in frames uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n') } POST_PACKED_STRUCTURE; diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index a9183c42..04cc590d 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -24,45 +24,44 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -JackResampler::JackResampler() - :fRatio(1), fRingBufferSize(DEFAULT_RB_SIZE) +JackRingBuffer::JackRingBuffer(int size):fRingBufferSize(size) { fRingBuffer = jack_ringbuffer_create(sizeof(jack_default_audio_sample_t) * fRingBufferSize); - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(jack_default_audio_sample_t) * fRingBufferSize) / 2); + Reset(fRingBufferSize); } -JackResampler::~JackResampler() +JackRingBuffer::~JackRingBuffer() { if (fRingBuffer) { jack_ringbuffer_free(fRingBuffer); } } -void JackResampler::Reset(unsigned int new_size) +void JackRingBuffer::Reset(unsigned int new_size) { fRingBufferSize = new_size; jack_ringbuffer_reset(fRingBuffer); jack_ringbuffer_reset_size(fRingBuffer, sizeof(jack_default_audio_sample_t) * fRingBufferSize); - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(jack_default_audio_sample_t) * fRingBufferSize / 2)); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(jack_default_audio_sample_t) * new_size/2)); } -unsigned int JackResampler::ReadSpace() +unsigned int JackRingBuffer::ReadSpace() { return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(jack_default_audio_sample_t)); } -unsigned int JackResampler::WriteSpace() +unsigned int JackRingBuffer::WriteSpace() { return (jack_ringbuffer_write_space(fRingBuffer) / sizeof(jack_default_audio_sample_t)); } -unsigned int JackResampler::Read(jack_default_audio_sample_t* buffer, unsigned int frames) +unsigned int JackRingBuffer::Read(jack_default_audio_sample_t* buffer, unsigned int frames) { size_t len = jack_ringbuffer_read_space(fRingBuffer); - jack_log("JackResampler::Read input available = %ld", len / sizeof(jack_default_audio_sample_t)); + jack_log("JackRingBuffer::Read input available = %ld", len / sizeof(jack_default_audio_sample_t)); if (len < frames * sizeof(jack_default_audio_sample_t)) { - jack_error("JackResampler::Read : producer too slow, missing frames = %d", frames); + jack_error("JackRingBuffer::Read : producer too slow, missing frames = %d", frames); return 0; } else { jack_ringbuffer_read(fRingBuffer, (char*)buffer, frames * sizeof(jack_default_audio_sample_t)); @@ -70,13 +69,13 @@ unsigned int JackResampler::Read(jack_default_audio_sample_t* buffer, unsigned i } } -unsigned int JackResampler::Write(jack_default_audio_sample_t* buffer, unsigned int frames) +unsigned int JackRingBuffer::Write(jack_default_audio_sample_t* buffer, unsigned int frames) { size_t len = jack_ringbuffer_write_space(fRingBuffer); - jack_log("JackResampler::Write output available = %ld", len / sizeof(jack_default_audio_sample_t)); + jack_log("JackRingBuffer::Write output available = %ld", len / sizeof(jack_default_audio_sample_t)); if (len < frames * sizeof(jack_default_audio_sample_t)) { - jack_error("JackResampler::Write : consumer too slow, skip frames = %d", frames); + jack_error("JackRingBuffer::Write : consumer too slow, skip frames = %d", frames); return 0; } else { jack_ringbuffer_write(fRingBuffer, (char*)buffer, frames * sizeof(jack_default_audio_sample_t)); @@ -84,13 +83,13 @@ unsigned int JackResampler::Write(jack_default_audio_sample_t* buffer, unsigned } } -unsigned int JackResampler::Read(void* buffer, unsigned int bytes) +unsigned int JackRingBuffer::Read(void* buffer, unsigned int bytes) { size_t len = jack_ringbuffer_read_space(fRingBuffer); - jack_log("JackResampler::Read input available = %ld", len); + jack_log("JackRingBuffer::Read input available = %ld", len); if (len < bytes) { - jack_error("JackResampler::Read : producer too slow, missing bytes = %d", bytes); + jack_error("JackRingBuffer::Read : producer too slow, missing bytes = %d", bytes); return 0; } else { jack_ringbuffer_read(fRingBuffer, (char*)buffer, bytes); @@ -98,13 +97,13 @@ unsigned int JackResampler::Read(void* buffer, unsigned int bytes) } } -unsigned int JackResampler::Write(void* buffer, unsigned int bytes) +unsigned int JackRingBuffer::Write(void* buffer, unsigned int bytes) { size_t len = jack_ringbuffer_write_space(fRingBuffer); - jack_log("JackResampler::Write output available = %ld", len); + jack_log("JackRingBuffer::Write output available = %ld", len); if (len < bytes) { - jack_error("JackResampler::Write : consumer too slow, skip bytes = %d", bytes); + jack_error("JackRingBuffer::Write : consumer too slow, skip bytes = %d", bytes); return 0; } else { jack_ringbuffer_write(fRingBuffer, (char*)buffer, bytes); diff --git a/common/JackResampler.h b/common/JackResampler.h index 8dfbefce..f1f78a92 100644 --- a/common/JackResampler.h +++ b/common/JackResampler.h @@ -35,34 +35,33 @@ inline float Range(float min, float max, float val) } /*! -\brief Base class for Resampler. +\brief Base class for RingBuffer in frames. */ -class JackResampler +class JackRingBuffer { protected: jack_ringbuffer_t* fRingBuffer; - double fRatio; unsigned int fRingBufferSize; public: - JackResampler(); - virtual ~JackResampler(); + JackRingBuffer(int size = DEFAULT_RB_SIZE); + virtual ~JackRingBuffer(); virtual void Reset(unsigned int new_size); - virtual unsigned int ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames); - virtual unsigned int WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames); - + // in frames virtual unsigned int Read(jack_default_audio_sample_t* buffer, unsigned int frames); virtual unsigned int Write(jack_default_audio_sample_t* buffer, unsigned int frames); + // in bytes virtual unsigned int Read(void* buffer, unsigned int bytes); virtual unsigned int Write(void* buffer, unsigned int bytes); + // in frames virtual unsigned int ReadSpace(); virtual unsigned int WriteSpace(); @@ -71,6 +70,29 @@ class JackResampler return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(float)) - (fRingBufferSize / 2); } +}; + +/*! +\brief Base class for Resampler. +*/ + +class JackResampler : public JackRingBuffer +{ + + protected: + + double fRatio; + + public: + + JackResampler():JackRingBuffer(),fRatio(1) + {} + virtual ~JackResampler() + {} + + virtual unsigned int ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames); + virtual unsigned int WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames); + void SetRatio(double ratio) { fRatio = Range(0.25, 4.0, ratio); diff --git a/common/jack/net.h b/common/jack/net.h index 04afa01c..fdfcabe0 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -75,6 +75,7 @@ typedef struct { jack_nframes_t sample_rate; // master sample rate char master_name[MASTER_NAME_SIZE]; // master machine name int time_out; // in second, -1 means infinite + int partial_cycle; // if 'true', partial cycle will be used } jack_master_t; @@ -281,7 +282,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 (complete buffer). * @param net the network connection * @param audio_input number of audio inputs * @param audio_input_buffer an array of audio input buffers @@ -293,7 +294,20 @@ int jack_net_master_close(jack_net_master_t* net); int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); /** - * Send sync and data to the network. + * Receive sync and data from the network (incomplete buffer). + * @param net the network connection + * @param audio_input number of audio inputs + * @param audio_input_buffer an array of audio input buffers + * @param midi_input number of MIDI inputs + * @param midi_input_buffer an array of MIDI input buffers + * @param frames the number of frames to receive. + * + * @return zero on success, non-zero on error + */ +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); + +/** + * Send sync and data to the network (complete buffer). * @param net the network connection * @param audio_output number of audio outputs * @param audio_output_buffer an array of audio output buffers @@ -304,6 +318,19 @@ int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_ */ int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer); +/** + * Send sync and data to the network (incomplete buffer). + * @param net the network connection + * @param audio_output number of audio outputs + * @param audio_output_buffer an array of audio output buffers + * @param midi_output number of MIDI ouputs + * @param midi_output_buffer an array of MIDI output buffers + * @param frames the number of frames to send. + * + * @return zero on success, non-zero on error + */ +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); + // Experimental Adapter API /** diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c index 18b012d9..aed9a2fb 100644 --- a/example-clients/netmaster.c +++ b/example-clients/netmaster.c @@ -101,7 +101,7 @@ main (int argc, char *argv[]) int i; //jack_master_t request = { 4, 4, -1, -1, buffer_size, sample_rate, "master", -1 }; - jack_master_t request = { -1, -1, -1, -1, buffer_size, sample_rate, "master", 6 }; + jack_master_t request = { -1, -1, -1, -1, buffer_size, sample_rate, "master", 6, true }; jack_slave_t result; float** audio_input_buffer; float** audio_output_buffer; @@ -161,6 +161,7 @@ main (int argc, char *argv[]) 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 failure, exiting\n"); break; @@ -172,6 +173,19 @@ main (int argc, char *argv[]) printf("jack_net_master_recv failure, exiting\n"); break; } + */ + + if (jack_net_master_send_slice(net, result.audio_output, audio_output_buffer, 0, NULL, BUFFER_SIZE/2) < 0) { + printf("jack_net_master_send failure, exiting\n"); + break; + } + + usleep(10000); + + if (jack_net_master_recv_slice(net, result.audio_input, audio_input_buffer, 0, NULL, BUFFER_SIZE/2) < 0) { + printf("jack_net_master_recv failure, exiting\n"); + break; + } usleep(wait_usec); };