Browse Source

Support for partial buffers in libjacknet.

tags/v1.9.10
Stephane Letz 11 years ago
parent
commit
66b4bfd8bb
12 changed files with 207 additions and 74 deletions
  1. +86
    -27
      common/JackNetAPI.cpp
  2. +2
    -1
      common/JackNetAdapter.cpp
  3. +4
    -3
      common/JackNetDriver.cpp
  4. +10
    -4
      common/JackNetInterface.cpp
  5. +6
    -6
      common/JackNetInterface.h
  6. +2
    -1
      common/JackNetManager.cpp
  7. +2
    -0
      common/JackNetTool.cpp
  8. +2
    -1
      common/JackNetTool.h
  9. +19
    -20
      common/JackResampler.cpp
  10. +30
    -8
      common/JackResampler.h
  11. +29
    -2
      common/jack/net.h
  12. +15
    -1
      example-clients/netmaster.c

+ 86
- 27
common/JackNetAPI.cpp View File

@@ -63,7 +63,8 @@ extern "C"
jack_nframes_t buffer_size; jack_nframes_t buffer_size;
jack_nframes_t sample_rate; jack_nframes_t sample_rate;
char master_name[MASTER_NAME_SIZE]; char master_name[MASTER_NAME_SIZE];
int time_out;
int time_out;
int partial_cycle;


} jack_master_t; } 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_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_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 // NetJack adapter API


typedef struct _jack_adapter jack_adapter_t; typedef struct _jack_adapter jack_adapter_t;
@@ -146,6 +150,8 @@ struct JackNetExtMaster : public JackNetMasterInterface {
jack_master_t fRequest; jack_master_t fRequest;
int fPacketTimeOut; int fPacketTimeOut;
JackRingBuffer** fRingBuffer;


JackNetExtMaster(const char* ip, JackNetExtMaster(const char* ip,
int port, int port,
@@ -161,10 +167,19 @@ struct JackNetExtMaster : public JackNetMasterInterface {
fRequest.audio_input = request->audio_input; fRequest.audio_input = request->audio_input;
fRequest.audio_output = request->audio_output; fRequest.audio_output = request->audio_output;
fRequest.time_out = request->time_out; fRequest.time_out = request->time_out;
fRequest.partial_cycle = request->partial_cycle;
fRingBuffer = NULL;
} }


virtual ~JackNetExtMaster() virtual ~JackNetExtMaster()
{}
{
if (fRingBuffer) {
for (int i = 0; i < fParams.fReturnAudioChannels; i++) {
delete fRingBuffer[i];
}
delete [] fRingBuffer;
}
}


int Open(jack_slave_t* result) int Open(jack_slave_t* result)
{ {
@@ -257,6 +272,14 @@ struct JackNetExtMaster : public JackNetMasterInterface {
result->midi_output = fParams.fReturnMidiChannels; result->midi_output = fParams.fReturnMidiChannels;
result->mtu = fParams.fMtu; result->mtu = fParams.fMtu;
result->latency = fParams.fNetworkLatency; 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; return 0;


error: error:
@@ -332,10 +355,13 @@ struct JackNetExtMaster : public JackNetMasterInterface {
return 0; 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 { try {
if (frames < 0) frames = fParams.fPeriodSize;
int cycle_size;
assert(audio_input == fParams.fReturnAudioChannels); assert(audio_input == fParams.fReturnAudioChannels);


for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) { 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]); 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: case NET_SYNCHING:
// Data will not be received, so cleanup buffers... // Data will not be received, so cleanup buffers...
for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) { 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: case SOCKET_ERROR:
return res;
return res1;
case SYNC_PACKET_ERROR: case SYNC_PACKET_ERROR:
// since sync packet is incorrect, don't decode it and continue with data // since sync packet is incorrect, don't decode it and continue with data
@@ -365,11 +398,20 @@ struct JackNetExtMaster : public JackNetMasterInterface {
default: default:
// decode sync // decode sync
DecodeSyncPacket();
cycle_size;
DecodeSyncPacket(cycle_size);
break; 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) { } catch (JackNetException& e) {
jack_error("Lost connection"); 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 { try {
if (frames < 0) frames = fParams.fPeriodSize;
assert(audio_output == fParams.fSendAudioChannels); 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]); fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]);
} }
EncodeSyncPacket();
EncodeSyncPacket(frames);
// send sync // send sync
if (SyncSend() == SOCKET_ERROR) { if (SyncSend() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
@@ -402,7 +446,6 @@ struct JackNetExtMaster : public JackNetMasterInterface {
if (DataSend() == SOCKET_ERROR) { if (DataSend() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
} }
return 0; return 0;


} catch (JackNetException& e) { } catch (JackNetException& e) {
@@ -450,6 +493,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
void* fSampleRateArg; void* fSampleRateArg;


int fConnectTimeOut; int fConnectTimeOut;
int fCycleSize;
JackNetExtSlave(const char* ip, JackNetExtSlave(const char* ip,
int port, int port,
@@ -610,8 +654,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
return -1; return -1;
} }


// Set result
if (result != NULL) {
// Set result
if (result != NULL) {
result->buffer_size = fParams.fPeriodSize; result->buffer_size = fParams.fPeriodSize;
result->sample_rate = fParams.fSampleRate; result->sample_rate = fParams.fSampleRate;
result->audio_input = fParams.fSendAudioChannels; result->audio_input = fParams.fSendAudioChannels;
@@ -620,7 +664,10 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
result->midi_output = fParams.fReturnMidiChannels; result->midi_output = fParams.fReturnMidiChannels;
strcpy(result->master_name, fParams.fMasterNetName); strcpy(result->master_name, fParams.fMasterNetName);
} }

// By default fCycleSize is fPeriodSize
fCycleSize = fParams.fPeriodSize;
AllocPorts(); AllocPorts();
return 0; return 0;
} }
@@ -711,7 +758,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf


bool Execute() bool Execute()
{ {
try {
try {
/* /*
Fist cycle use an INT_MAX time out, so that connection Fist cycle use an INT_MAX time out, so that connection
is considered established (with PACKET_TIMEOUT later on) is considered established (with PACKET_TIMEOUT later on)
@@ -758,7 +805,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
default: default:
// decode sync // decode sync
DecodeSyncPacket();
DecodeSyncPacket(fCycleSize);
break; break;
} }


@@ -768,11 +815,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
} }
return res; return res;
} }
int Write() int Write()
{ {
EncodeSyncPacket();
EncodeSyncPacket(fCycleSize);
if (SyncSend() == SOCKET_ERROR) { if (SyncSend() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
} }
@@ -798,8 +845,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
if (Read() == SOCKET_ERROR) { if (Read() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
} }
fProcessCallback(fParams.fPeriodSize,
fProcessCallback(fCycleSize,
fParams.fSendAudioChannels, fParams.fSendAudioChannels,
fAudioCaptureBuffer, fAudioCaptureBuffer,
fParams.fSendMidiChannels, fParams.fSendMidiChannels,
@@ -809,7 +856,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
fParams.fReturnMidiChannels, fParams.fReturnMidiChannels,
(void**)fMidiPlaybackBuffer, (void**)fMidiPlaybackBuffer,
fProcessArg); fProcessArg);
// Then write data to network, throw JackNetException in case of network error... // Then write data to network, throw JackNetException in case of network error...
if (Write() == SOCKET_ERROR) { if (Write() == SOCKET_ERROR) {
return 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) 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; 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) 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; 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 // Adapter API


+ 2
- 1
common/JackNetAdapter.cpp View File

@@ -361,7 +361,8 @@ namespace Jack
default: default:
//decode sync //decode sync
DecodeSyncPacket();
int unused_cycle_size;
DecodeSyncPacket(unused_cycle_size);
break; break;
} }


+ 4
- 3
common/JackNetDriver.cpp View File

@@ -575,7 +575,8 @@ namespace Jack
default: default:
// decode sync // decode sync
DecodeSyncPacket();
int unused_cycle_size;
DecodeSyncPacket(unused_cycle_size);
break; break;
} }
@@ -724,8 +725,8 @@ Deactivated for now..
int mtu = DEFAULT_MTU; int mtu = DEFAULT_MTU;
// Desactivated for now... // Desactivated for now...
uint transport_sync = 0; 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_capture_ports = -1;
int audio_playback_ports = -1; int audio_playback_ports = -1;
int midi_input_ports = -1; int midi_input_ports = -1;


+ 10
- 4
common/JackNetInterface.cpp View File

@@ -544,7 +544,7 @@ namespace Jack
return rx_bytes; return rx_bytes;
} }


void JackNetMasterInterface::EncodeSyncPacket()
void JackNetMasterInterface::EncodeSyncPacket(int cycle_size)
{ {
// This method contains every step of sync packet informations coding // This method contains every step of sync packet informations coding
// first of all, clear sync packet // first of all, clear sync packet
@@ -565,9 +565,10 @@ namespace Jack
// Write active ports list // Write active ports list
fTxHeader.fActivePorts = (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->ActivePortsToNetwork(fTxData) : 0; 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 // This method contains every step of sync packet informations decoding process
@@ -590,6 +591,8 @@ namespace Jack
if (fNetAudioCaptureBuffer) { if (fNetAudioCaptureBuffer) {
fNetAudioCaptureBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts); fNetAudioCaptureBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
} }
cycle_size = rx_head->fCycleSize;
} }


// JackNetSlaveInterface ************************************************************************************************ // JackNetSlaveInterface ************************************************************************************************
@@ -946,7 +949,7 @@ namespace Jack
} }


// network sync------------------------------------------------------------------------ // network sync------------------------------------------------------------------------
void JackNetSlaveInterface::EncodeSyncPacket()
void JackNetSlaveInterface::EncodeSyncPacket(int cycle_size)
{ {
// This method contains every step of sync packet informations coding // This method contains every step of sync packet informations coding
// first of all, clear sync packet // first of all, clear sync packet
@@ -967,9 +970,10 @@ namespace Jack


// Write active ports list // Write active ports list
fTxHeader.fActivePorts = (fNetAudioCaptureBuffer) ? fNetAudioCaptureBuffer->ActivePortsToNetwork(fTxData) : 0; 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 // This method contains every step of sync packet informations decoding process
@@ -992,6 +996,8 @@ namespace Jack
if (fNetAudioPlaybackBuffer) { if (fNetAudioPlaybackBuffer) {
fNetAudioPlaybackBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts); fNetAudioPlaybackBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
} }
cycle_size = rx_head->fCycleSize;
} }


} }

+ 6
- 6
common/JackNetInterface.h View File

@@ -92,8 +92,8 @@ namespace Jack
virtual void DecodeTransportData() = 0; virtual void DecodeTransportData() = 0;


// sync packet // 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 SyncRecv() = 0;
virtual int SyncSend() = 0; virtual int SyncSend() = 0;
@@ -160,8 +160,8 @@ namespace Jack
int DataSend(); int DataSend();


// sync packet // 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 Send(size_t size, int flags);
int Recv(size_t size, int flags); int Recv(size_t size, int flags);
@@ -217,8 +217,8 @@ namespace Jack
int DataSend(); int DataSend();


// sync packet // 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 Recv(size_t size, int flags);
int Send(size_t size, int flags); int Send(size_t size, int flags);


+ 2
- 1
common/JackNetManager.cpp View File

@@ -543,7 +543,8 @@ namespace Jack
default: default:
// Decode sync // Decode sync
DecodeSyncPacket();
int unused_cycle_size;
DecodeSyncPacket(unused_cycle_size);
break; break;
} }




+ 2
- 0
common/JackNetTool.cpp View File

@@ -1216,6 +1216,7 @@ namespace Jack
dst_header->fActivePorts = htonl(src_header->fActivePorts); dst_header->fActivePorts = htonl(src_header->fActivePorts);
dst_header->fCycle = htonl(src_header->fCycle); dst_header->fCycle = htonl(src_header->fCycle);
dst_header->fSubCycle = htonl(src_header->fSubCycle); dst_header->fSubCycle = htonl(src_header->fSubCycle);
dst_header->fCycleSize = htonl(src_header->fCycleSize);
dst_header->fIsLastPckt = htonl(src_header->fIsLastPckt); dst_header->fIsLastPckt = htonl(src_header->fIsLastPckt);
} }


@@ -1230,6 +1231,7 @@ namespace Jack
dst_header->fActivePorts = ntohl(src_header->fActivePorts); dst_header->fActivePorts = ntohl(src_header->fActivePorts);
dst_header->fCycle = ntohl(src_header->fCycle); dst_header->fCycle = ntohl(src_header->fCycle);
dst_header->fSubCycle = ntohl(src_header->fSubCycle); dst_header->fSubCycle = ntohl(src_header->fSubCycle);
dst_header->fCycleSize = ntohl(src_header->fCycleSize);
dst_header->fIsLastPckt = ntohl(src_header->fIsLastPckt); dst_header->fIsLastPckt = ntohl(src_header->fIsLastPckt);
} }




+ 2
- 1
common/JackNetTool.h View File

@@ -38,7 +38,7 @@ using namespace std;
#endif #endif
#endif #endif


#define NETWORK_PROTOCOL 7
#define NETWORK_PROTOCOL 8


#define NET_SYNCHING 0 #define NET_SYNCHING 0
#define SYNC_PACKET_ERROR -2 #define SYNC_PACKET_ERROR -2
@@ -180,6 +180,7 @@ namespace Jack
uint32_t fActivePorts; //number of active ports uint32_t fActivePorts; //number of active ports
uint32_t fCycle; //process cycle counter uint32_t fCycle; //process cycle counter
uint32_t fSubCycle; //midi/audio subcycle 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') uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n')
} POST_PACKED_STRUCTURE; } POST_PACKED_STRUCTURE;




+ 19
- 20
common/JackResampler.cpp View File

@@ -24,45 +24,44 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack 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); 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) { if (fRingBuffer) {
jack_ringbuffer_free(fRingBuffer); jack_ringbuffer_free(fRingBuffer);
} }
} }


void JackResampler::Reset(unsigned int new_size)
void JackRingBuffer::Reset(unsigned int new_size)
{ {
fRingBufferSize = new_size; fRingBufferSize = new_size;
jack_ringbuffer_reset(fRingBuffer); jack_ringbuffer_reset(fRingBuffer);
jack_ringbuffer_reset_size(fRingBuffer, sizeof(jack_default_audio_sample_t) * fRingBufferSize); 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)); 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)); 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); 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)) { 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; return 0;
} else { } else {
jack_ringbuffer_read(fRingBuffer, (char*)buffer, frames * sizeof(jack_default_audio_sample_t)); 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); 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)) { 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; return 0;
} else { } else {
jack_ringbuffer_write(fRingBuffer, (char*)buffer, frames * sizeof(jack_default_audio_sample_t)); 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); 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) { 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; return 0;
} else { } else {
jack_ringbuffer_read(fRingBuffer, (char*)buffer, bytes); 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); 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) { 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; return 0;
} else { } else {
jack_ringbuffer_write(fRingBuffer, (char*)buffer, bytes); jack_ringbuffer_write(fRingBuffer, (char*)buffer, bytes);


+ 30
- 8
common/JackResampler.h View File

@@ -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: protected:


jack_ringbuffer_t* fRingBuffer; jack_ringbuffer_t* fRingBuffer;
double fRatio;
unsigned int fRingBufferSize; unsigned int fRingBufferSize;


public: public:


JackResampler();
virtual ~JackResampler();
JackRingBuffer(int size = DEFAULT_RB_SIZE);
virtual ~JackRingBuffer();


virtual void Reset(unsigned int new_size); 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 Read(jack_default_audio_sample_t* buffer, unsigned int frames);
virtual unsigned int Write(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 Read(void* buffer, unsigned int bytes);
virtual unsigned int Write(void* buffer, unsigned int bytes); virtual unsigned int Write(void* buffer, unsigned int bytes);


// in frames
virtual unsigned int ReadSpace(); virtual unsigned int ReadSpace();
virtual unsigned int WriteSpace(); virtual unsigned int WriteSpace();


@@ -71,6 +70,29 @@ class JackResampler
return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(float)) - (fRingBufferSize / 2); 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) void SetRatio(double ratio)
{ {
fRatio = Range(0.25, 4.0, ratio); fRatio = Range(0.25, 4.0, ratio);


+ 29
- 2
common/jack/net.h View File

@@ -75,6 +75,7 @@ typedef struct {
jack_nframes_t sample_rate; // master sample rate jack_nframes_t sample_rate; // master sample rate
char master_name[MASTER_NAME_SIZE]; // master machine name char master_name[MASTER_NAME_SIZE]; // master machine name
int time_out; // in second, -1 means infinite int time_out; // in second, -1 means infinite
int partial_cycle; // if 'true', partial cycle will be used


} jack_master_t; } 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); 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 net the network connection
* @param audio_input number of audio inputs * @param audio_input number of audio inputs
* @param audio_input_buffer an array of audio input buffers * @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); 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 net the network connection
* @param audio_output number of audio outputs * @param audio_output number of audio outputs
* @param audio_output_buffer an array of audio output buffers * @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); 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 // Experimental Adapter API


/** /**


+ 15
- 1
example-clients/netmaster.c View File

@@ -101,7 +101,7 @@ main (int argc, char *argv[])


int i; int i;
//jack_master_t request = { 4, 4, -1, -1, buffer_size, sample_rate, "master", -1 }; //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; jack_slave_t result;
float** audio_input_buffer; float** audio_input_buffer;
float** audio_output_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)); 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) { if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) {
printf("jack_net_master_send failure, exiting\n"); printf("jack_net_master_send failure, exiting\n");
break; break;
@@ -172,6 +173,19 @@ main (int argc, char *argv[])
printf("jack_net_master_recv failure, exiting\n"); printf("jack_net_master_recv failure, exiting\n");
break; 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); usleep(wait_usec);
}; };


Loading…
Cancel
Save