summaryrefslogtreecommitdiff
path: root/common/JackNetAPI.cpp
diff options
context:
space:
mode:
authorStephane Letz <letz@grame.fr>2014-01-22 16:10:16 +0100
committerStephane Letz <letz@grame.fr>2014-01-22 16:10:16 +0100
commit66b4bfd8bb3339cc62bfdf0f9d91969dc07b883e (patch)
treea4b3ca83f5388c255b193ee932571c91eb0c8dbc /common/JackNetAPI.cpp
parent7123ef156273db039e12e7ff2df3a6008e765baf (diff)
downloadjack2-66b4bfd8bb3339cc62bfdf0f9d91969dc07b883e.tar.gz
Support for partial buffers in libjacknet.
Diffstat (limited to 'common/JackNetAPI.cpp')
-rw-r--r--common/JackNetAPI.cpp113
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