Browse Source

Merge pull request #16 from x42/master

Opus Netjack integration
tags/1.9.9.5
Stéphane Letz 13 years ago
parent
commit
d3d49455b2
12 changed files with 429 additions and 33 deletions
  1. +6
    -1
      common/JackNetAPI.cpp
  2. +167
    -0
      common/JackNetOneDriver.cpp
  3. +6
    -0
      common/JackNetOneDriver.h
  4. +44
    -23
      common/JackNetTool.cpp
  5. +2
    -1
      common/JackNetTool.h
  6. +1
    -1
      common/jack/net.h
  7. +47
    -1
      common/netjack.c
  8. +8
    -0
      common/netjack.h
  9. +100
    -0
      common/netjack_packet.c
  10. +1
    -0
      common/netjack_packet.h
  11. +44
    -3
      example-clients/netsource.c
  12. +3
    -3
      example-clients/wscript

+ 6
- 1
common/JackNetAPI.cpp View File

@@ -37,7 +37,7 @@ extern "C"
JackFloatEncoder = 0, JackFloatEncoder = 0,
JackIntEncoder = 1, JackIntEncoder = 1,
JackCeltEncoder = 2, JackCeltEncoder = 2,
JackMaxEncoder = 3
JackOpusEncoder = 3
}; };


typedef struct { typedef struct {
@@ -551,6 +551,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
return -1; return -1;
} }
if ((fParams.fSampleEncoder == JackOpusEncoder) && (fParams.fKBps == 0)) {
jack_error("Opus encoder with 0 for kps...");
return -1;
}

// Check latency // Check latency
if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) { if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) {
jack_error("Error : network latency is limited to %d", NETWORK_MAX_LATENCY); jack_error("Error : network latency is limited to %d", NETWORK_MAX_LATENCY);


+ 167
- 0
common/JackNetOneDriver.cpp View File

@@ -39,6 +39,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <celt/celt.h> #include <celt/celt.h>
#endif #endif


#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#endif

#define MIN(x,y) ((x)<(y) ? (x) : (y)) #define MIN(x,y) ((x)<(y) ? (x) : (y))


using namespace std; using namespace std;
@@ -146,6 +151,13 @@ int JackNetOneDriver::AllocPorts()
#endif #endif
celt_mode_info(celt_mode, CELT_GET_LOOKAHEAD, &lookahead); celt_mode_info(celt_mode, CELT_GET_LOOKAHEAD, &lookahead);
netj.codec_latency = 2 * lookahead; netj.codec_latency = 2 * lookahead;
#endif
} else if (netj.bitdepth == OPUS_MODE) {
#if HAVE_OPUS
OpusCustomMode *opus_mode = opus_custom_mode_create(netj.sample_rate, netj.period_size, NULL); // XXX free me in the end
OpusCustomDecoder *decoder = opus_custom_decoder_create( opus_mode, 1, NULL );
opus_custom_decoder_init(decoder, opus_mode, 1);
netj.capture_srcs = jack_slist_append(netj.capture_srcs, decoder);
#endif #endif
} else { } else {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -191,6 +203,22 @@ int JackNetOneDriver::AllocPorts()
CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL); CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL);
netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode)); netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode));
#endif #endif
#endif
} else if (netj.bitdepth == OPUS_MODE) {
#if HAVE_OPUS
const int kbps = netj.resample_factor;
jack_error("NEW ONE OPUS ENCODER 128 <> %d!!", kbps);
int err;
OpusCustomMode *opus_mode = opus_custom_mode_create( netj.sample_rate, netj.period_size, &err ); // XXX free me in the end
if (err != OPUS_OK) { jack_error("opus mode failed"); }
OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, &err );
if (err != OPUS_OK) { jack_error("opus mode failed"); }
opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second
opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
opus_custom_encoder_init(oe, opus_mode, 1);
netj.playback_srcs = jack_slist_append(netj.playback_srcs, oe);
#endif #endif
} else { } else {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -450,6 +478,28 @@ JackNetOneDriver::FreePorts ()
celt_decoder_destroy(dec); celt_decoder_destroy(dec);
} }
netj.capture_srcs = NULL; netj.capture_srcs = NULL;
#endif
} else if (netj.bitdepth == OPUS_MODE) {
#if HAVE_OPUS
node = netj.playback_srcs;
while (node != NULL) {
JSList *this_node = node;
OpusCustomEncoder *enc = (OpusCustomEncoder *) node->data;
node = jack_slist_remove_link(node, this_node);
jack_slist_free_1(this_node);
opus_custom_encoder_destroy(enc);
}
netj.playback_srcs = NULL;

node = netj.capture_srcs;
while (node != NULL) {
JSList *this_node = node;
OpusCustomDecoder *dec = (OpusCustomDecoder *) node->data;
node = jack_slist_remove_link(node, this_node);
jack_slist_free_1(this_node);
opus_custom_decoder_destroy(dec);
}
netj.capture_srcs = NULL;
#endif #endif
} else { } else {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -724,6 +774,98 @@ JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSL
} }


#endif #endif

#if HAVE_OPUS
#define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
// render functions for Opus.
void
JackNetOneDriver::render_payload_to_jack_ports_opus (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
{
int chn = 0;
JSList *node = capture_ports;
JSList *src_node = capture_srcs;

unsigned char *packet_bufX = (unsigned char *)packet_payload;

while (node != NULL) {
jack_port_id_t port_index = (jack_port_id_t) (intptr_t)node->data;
JackPort *port = fGraphManager->GetPort(port_index);

jack_default_audio_sample_t* buf =
(jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);

const char *portname = port->GetType();

if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
// audio port, decode opus data.
OpusCustomDecoder *decoder = (OpusCustomDecoder*) src_node->data;
if( !packet_payload )
memset(buf, 0, nframes * sizeof(float));
else {
unsigned short len;
memcpy(&len, packet_bufX, CDO);
len = ntohs(len);
opus_custom_decode_float( decoder, packet_bufX + CDO, len, buf, nframes );
}

src_node = jack_slist_next (src_node);
} else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) {
// midi port, decode midi events
// convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_down / 2;
uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
if( packet_payload )
decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
}
packet_bufX = (packet_bufX + net_period_down);
node = jack_slist_next (node);
chn++;
}
}

void
JackNetOneDriver::render_jack_ports_to_payload_opus (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
{
int chn = 0;
JSList *node = playback_ports;
JSList *src_node = playback_srcs;

unsigned char *packet_bufX = (unsigned char *)packet_payload;

while (node != NULL) {
jack_port_id_t port_index = (jack_port_id_t) (intptr_t) node->data;
JackPort *port = fGraphManager->GetPort(port_index);

jack_default_audio_sample_t* buf =
(jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);

const char *portname = port->GetType();

if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
// audio port, encode opus data.

int encoded_bytes;
jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes);
memcpy(floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t));
OpusCustomEncoder *encoder = (OpusCustomEncoder*) src_node->data;
encoded_bytes = opus_custom_encode_float( encoder, floatbuf, nframes, packet_bufX + CDO, net_period_up - CDO );
unsigned short len = htons(encoded_bytes);
memcpy(packet_bufX, &len, CDO);
src_node = jack_slist_next( src_node );
} else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) {
// encode midi events from port to packet
// convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_up / 2;
uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
}
packet_bufX = (packet_bufX + net_period_up);
node = jack_slist_next (node);
chn++;
}
}
#endif

/* Wrapper functions with bitdepth argument... */ /* Wrapper functions with bitdepth argument... */
void void
JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats)
@@ -732,6 +874,11 @@ JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_paylo
if (bitdepth == CELT_MODE) if (bitdepth == CELT_MODE)
render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
else else
#endif
#if HAVE_OPUS
if (bitdepth == OPUS_MODE)
render_payload_to_jack_ports_opus (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
else
#endif #endif
render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats);
} }
@@ -743,6 +890,11 @@ JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_p
if (bitdepth == CELT_MODE) if (bitdepth == CELT_MODE)
render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
else else
#endif
#if HAVE_OPUS
if (bitdepth == OPUS_MODE)
render_jack_ports_to_payload_opus (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
else
#endif #endif
render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats);
} }
@@ -791,6 +943,10 @@ extern "C"
#if HAVE_CELT #if HAVE_CELT
value.ui = 0U; value.ui = 0U;
jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamUInt, &value, NULL, "Set CELT encoding and number of kbits per channel", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamUInt, &value, NULL, "Set CELT encoding and number of kbits per channel", NULL);
#endif
#if HAVE_OPUS
value.ui = 0U;
jack_driver_descriptor_add_parameter(desc, &filler, "opus", 'P', JackDriverParamUInt, &value, NULL, "Set Opus encoding and number of kbits per channel", NULL);
#endif #endif
value.ui = 0U; value.ui = 0U;
jack_driver_descriptor_add_parameter(desc, &filler, "bit-depth", 'b', JackDriverParamUInt, &value, NULL, "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "bit-depth", 'b', JackDriverParamUInt, &value, NULL, "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)", NULL);
@@ -904,6 +1060,17 @@ extern "C"
#endif #endif
break; break;


case 'P':
#if HAVE_OPUS
bitdepth = OPUS_MODE;
resample_factor = param->value.ui;
jack_error("OPUS: %d\n", resample_factor);
#else
jack_error("not built with Opus support");
return NULL;
#endif
break;

case 't': case 't':
handle_transport_sync = param->value.ui; handle_transport_sync = param->value.ui;
break; break;


+ 6
- 0
common/JackNetOneDriver.h View File

@@ -45,6 +45,12 @@ class JackNetOneDriver : public JackWaiterDriver
render_payload_to_jack_ports_celt(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes); render_payload_to_jack_ports_celt(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes);
void void
render_jack_ports_to_payload_celt(JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up); render_jack_ports_to_payload_celt(JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up);
#endif
#if HAVE_OPUS
void
render_payload_to_jack_ports_opus(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes);
void
render_jack_ports_to_payload_opus(JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up);
#endif #endif
void void
render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats);


+ 44
- 23
common/JackNetTool.cpp View File

@@ -710,6 +710,7 @@ namespace Jack
#endif #endif


#if HAVE_OPUS #if HAVE_OPUS
#define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)


NetOpusAudioBuffer::NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps) NetOpusAudioBuffer::NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
:NetAudioBuffer(params, nports, net_buffer) :NetAudioBuffer(params, nports, net_buffer)
@@ -717,10 +718,12 @@ namespace Jack
fOpusMode = new OpusCustomMode *[fNPorts]; fOpusMode = new OpusCustomMode *[fNPorts];
fOpusEncoder = new OpusCustomEncoder *[fNPorts]; fOpusEncoder = new OpusCustomEncoder *[fNPorts];
fOpusDecoder = new OpusCustomDecoder *[fNPorts]; fOpusDecoder = new OpusCustomDecoder *[fNPorts];
fCompressedSizesByte = new unsigned short [fNPorts];


memset(fOpusMode, 0, fNPorts * sizeof(OpusCustomMode*)); memset(fOpusMode, 0, fNPorts * sizeof(OpusCustomMode*));
memset(fOpusEncoder, 0, fNPorts * sizeof(OpusCustomEncoder*)); memset(fOpusEncoder, 0, fNPorts * sizeof(OpusCustomEncoder*));
memset(fOpusDecoder, 0, fNPorts * sizeof(OpusCustomDecoder*)); memset(fOpusDecoder, 0, fNPorts * sizeof(OpusCustomDecoder*));
memset(fCompressedSizesByte, 0, fNPorts * sizeof(int));


int error = OPUS_OK; int error = OPUS_OK;


@@ -753,25 +756,29 @@ namespace Jack
} }


{ {
fCompressedMaxSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
fPeriodSize = params->fPeriodSize; fPeriodSize = params->fPeriodSize;
fCompressedSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
jack_log("NetOpusAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte);
jack_log("NetOpusAudioBuffer fCompressedMaxSizeByte %d", fCompressedMaxSizeByte);


fCompressedBuffer = new unsigned char* [fNPorts]; fCompressedBuffer = new unsigned char* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte];
memset(fCompressedBuffer[port_index], 0, fCompressedSizeByte * sizeof(char));
fCompressedBuffer[port_index] = new unsigned char[fCompressedMaxSizeByte];
memset(fCompressedBuffer[port_index], 0, fCompressedMaxSizeByte * sizeof(char));
} }


int res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params);
int res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params);
int res1 = (fNPorts * fCompressedMaxSizeByte + CDO) % PACKET_AVAILABLE_SIZE(params);
int res2 = (fNPorts * fCompressedMaxSizeByte + CDO) / PACKET_AVAILABLE_SIZE(params);


fNumPackets = (res1) ? (res2 + 1) : res2; fNumPackets = (res1) ? (res2 + 1) : res2;


jack_log("NetOpusAudioBuffer res1 = %d res2 = %d", res1, res2); jack_log("NetOpusAudioBuffer res1 = %d res2 = %d", res1, res2);


fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;
fSubPeriodBytesSize = (fCompressedMaxSizeByte + CDO) / fNumPackets;
fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedMaxSizeByte + CDO) % fNumPackets;

if (fNumPackets == 1) {
fSubPeriodBytesSize = fLastSubPeriodBytesSize;
}


jack_log("NetOpusAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); jack_log("NetOpusAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);


@@ -797,6 +804,7 @@ namespace Jack
} }


delete [] fCompressedBuffer; delete [] fCompressedBuffer;
delete [] fCompressedSizesByte;
} }


void NetOpusAudioBuffer::FreeOpus() void NetOpusAudioBuffer::FreeOpus()
@@ -846,10 +854,12 @@ namespace Jack
} else { } else {
memset(buffer, 0, fPeriodSize * sizeof(sample_t)); memset(buffer, 0, fPeriodSize * sizeof(sample_t));
} }
int res = opus_custom_encode_float(fOpusEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedSizeByte);
if (res != fCompressedSizeByte) {
jack_error("opus_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
}
int res = opus_custom_encode_float(fOpusEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedMaxSizeByte);
if (res <0 || res >= 65535) {
fCompressedSizesByte[port_index] = 0;
} else {
fCompressedSizesByte[port_index] = res;
}
} }


// All ports active // All ports active
@@ -860,9 +870,9 @@ namespace Jack
{ {
for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) { if (fPortBuffer[port_index]) {
int res = opus_custom_decode_float(fOpusDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], fPeriodSize);
if (res != OPUS_OK) {
jack_error("opus_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
int res = opus_custom_decode_float(fOpusDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizesByte[port_index], fPortBuffer[port_index], fPeriodSize);
if (res < 0 || res != fPeriodSize) {
jack_error("opus_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizesByte[port_index], res);
} }
} }
} }
@@ -879,14 +889,19 @@ namespace Jack
} }


if (port_num > 0) { if (port_num > 0) {
// Last packet of the cycle
if (sub_cycle == fNumPackets - 1) {
if (sub_cycle == 0) {
for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize);
size_t len = *((size_t*)(fNetBuffer + port_index * fSubPeriodBytesSize));
fCompressedSizesByte[port_index] = ntohs(len);
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + CDO + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize - CDO);
}
} else if (sub_cycle == fNumPackets - 1) {
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize);
} }
} else { } else {
for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
} }
} }
} }
@@ -896,15 +911,21 @@ namespace Jack


int NetOpusAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num) int NetOpusAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
{ {
// Last packet of the cycle
if (sub_cycle == fNumPackets - 1) {
if (sub_cycle == 0) {
for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fLastSubPeriodBytesSize);
unsigned short len = htons(fCompressedSizesByte[port_index]);
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, &len, CDO);
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize + CDO, fCompressedBuffer[port_index], fSubPeriodBytesSize - CDO);
}
return fNPorts * fSubPeriodBytesSize;
} else if (sub_cycle == fNumPackets - 1) {
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fLastSubPeriodBytesSize);
} }
return fNPorts * fLastSubPeriodBytesSize; return fNPorts * fLastSubPeriodBytesSize;
} else { } else {
for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fSubPeriodBytesSize);
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fSubPeriodBytesSize);
} }
return fNPorts * fSubPeriodBytesSize; return fNPorts * fSubPeriodBytesSize;
} }


+ 2
- 1
common/JackNetTool.h View File

@@ -419,7 +419,8 @@ namespace Jack
OpusCustomEncoder** fOpusEncoder; OpusCustomEncoder** fOpusEncoder;
OpusCustomDecoder** fOpusDecoder; OpusCustomDecoder** fOpusDecoder;


int fCompressedSizeByte;
unsigned short *fCompressedSizesByte;
int fCompressedMaxSizeByte;
int fNumPackets; int fNumPackets;


size_t fLastSubPeriodBytesSize; size_t fLastSubPeriodBytesSize;


+ 1
- 1
common/jack/net.h View File

@@ -40,7 +40,7 @@ enum JackNetEncoder {
JackFloatEncoder = 0, // samples are transmitted as float JackFloatEncoder = 0, // samples are transmitted as float
JackIntEncoder = 1, // samples are transmitted as 16 bits integer JackIntEncoder = 1, // samples are transmitted as 16 bits integer
JackCeltEncoder = 2, // samples are transmitted using CELT codec (http://www.celt-codec.org/) JackCeltEncoder = 2, // samples are transmitted using CELT codec (http://www.celt-codec.org/)
JackOpusEncoder = 2, // samples are transmitted using OPUS codec (http://www.opus-codec.org/)
JackOpusEncoder = 3, // samples are transmitted using OPUS codec (http://www.opus-codec.org/)
}; };


typedef struct { typedef struct {


+ 47
- 1
common/netjack.c View File

@@ -368,6 +368,11 @@ void netjack_attach( netjack_driver_state_t *netj )
netj->codec_latency = 2 * lookahead; netj->codec_latency = 2 * lookahead;
#endif #endif
} }
if( netj->bitdepth == OPUS_MODE ) {
#if HAVE_OPUS
netj->opus_mode = opus_custom_mode_create(netj->sample_rate, netj->period_size, NULL);
#endif
}


if (netj->handle_transport_sync) if (netj->handle_transport_sync)
jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL); jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL);
@@ -397,6 +402,12 @@ void netjack_attach( netjack_driver_state_t *netj )
#else #else
netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) ); netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) );
#endif #endif
#endif
} else if( netj->bitdepth == OPUS_MODE ) {
#if HAVE_OPUS
OpusCustomDecoder *decoder = opus_custom_decoder_create( netj->opus_mode, 1, NULL );
opus_custom_decoder_init(decoder, netj->opus_mode, 1);
netj->capture_srcs = jack_slist_append(netj->capture_srcs, decoder );
#endif #endif
} else { } else {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -448,6 +459,20 @@ void netjack_attach( netjack_driver_state_t *netj )
CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) ); netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) );
#endif #endif
#endif
} else if( netj->bitdepth == OPUS_MODE ) {
#if HAVE_OPUS
const int kbps = netj->resample_factor;
jack_log( "OPUS %dkbps\n", kbps);

OpusCustomMode *opus_mode = opus_custom_mode_create( netj->sample_rate, netj->period_size, NULL ); // XXX free me in the end
OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, NULL );
opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second
opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
opus_custom_encoder_init(oe, opus_mode, 1);
netj->playback_srcs = jack_slist_append(netj->playback_srcs, oe );
#endif #endif
} else { } else {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -492,6 +517,12 @@ void netjack_detach( netjack_driver_state_t *netj )
CELTDecoder * decoder = node->data; CELTDecoder * decoder = node->data;
celt_decoder_destroy(decoder); celt_decoder_destroy(decoder);
} else } else
#endif
#if HAVE_OPUS
if ( netj->bitdepth == OPUS_MODE ) {
OpusCustomDecoder * decoder = node->data;
opus_custom_decoder_destroy(decoder);
} else
#endif #endif
{ {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -516,6 +547,12 @@ void netjack_detach( netjack_driver_state_t *netj )
CELTEncoder * encoder = node->data; CELTEncoder * encoder = node->data;
celt_encoder_destroy(encoder); celt_encoder_destroy(encoder);
} else } else
#endif
#if HAVE_OPUS
if ( netj->bitdepth == OPUS_MODE ) {
OpusCustomEncoder * encoder = node->data;
opus_custom_encoder_destroy(encoder);
} else
#endif #endif
{ {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -531,6 +568,10 @@ void netjack_detach( netjack_driver_state_t *netj )
if( netj->bitdepth == CELT_MODE ) if( netj->bitdepth == CELT_MODE )
celt_mode_destroy(netj->celt_mode); celt_mode_destroy(netj->celt_mode);
#endif #endif
#if HAVE_OPUS
if( netj->bitdepth == OPUS_MODE )
opus_custom_mode_destroy(netj->opus_mode);
#endif
} }




@@ -588,7 +629,7 @@ netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj,
netj->client = client; netj->client = client;




if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE)) {
if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE) && (bitdepth != OPUS_MODE)) {
jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth); jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth);
return NULL; return NULL;
} }
@@ -755,6 +796,11 @@ netjack_startup( netjack_driver_state_t *netj )


netj->net_period_down = netj->resample_factor; netj->net_period_down = netj->resample_factor;
netj->net_period_up = netj->resample_factor_up; netj->net_period_up = netj->resample_factor_up;
} else if( netj->bitdepth == OPUS_MODE ) {
// Opus mode.
// TODO: this is a hack. But i dont want to change the packet header, either
netj->net_period_down = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
netj->net_period_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
} else { } else {
netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor; netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor;
netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up; netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up;


+ 8
- 0
common/netjack.h View File

@@ -32,6 +32,11 @@
#include <celt/celt.h> #include <celt/celt.h>
#endif #endif


#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#endif

#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
@@ -111,6 +116,9 @@ extern "C"
struct _packet_cache * packcache; struct _packet_cache * packcache;
#if HAVE_CELT #if HAVE_CELT
CELTMode *celt_mode; CELTMode *celt_mode;
#endif
#if HAVE_OPUS
OpusCustomMode* opus_mode;
#endif #endif
}; };




+ 100
- 0
common/netjack_packet.c View File

@@ -72,6 +72,11 @@
#include <celt/celt.h> #include <celt/celt.h>
#endif #endif


#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#endif

#include "netjack_packet.h" #include "netjack_packet.h"
#include "JackError.h" #include "JackError.h"


@@ -129,6 +134,8 @@ int get_sample_size (int bitdepth)
//JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N? //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N?
if( bitdepth == CELT_MODE ) if( bitdepth == CELT_MODE )
return sizeof( unsigned char ); return sizeof( unsigned char );
if( bitdepth == OPUS_MODE )
return sizeof( unsigned char );
return sizeof (int32_t); return sizeof (int32_t);
} }


@@ -1347,6 +1354,91 @@ render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs
} }


#endif #endif

#if HAVE_OPUS
#define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
// render functions for Opus.
void
render_payload_to_jack_ports_opus (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
{
int chn = 0;
JSList *node = capture_ports;
JSList *src_node = capture_srcs;

unsigned char *packet_bufX = (unsigned char *)packet_payload;

while (node != NULL) {
jack_port_t *port = (jack_port_t *) node->data;
jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);

const char *porttype = jack_port_type (port);

if (jack_port_is_audio (porttype)) {
// audio port, decode opus data.
OpusCustomDecoder *decoder = (OpusCustomDecoder*) src_node->data;
if( !packet_payload )
memset(buf, 0, nframes * sizeof(float));
else {
unsigned short len;
memcpy(&len, packet_bufX, CDO);
len = ntohs(len);
opus_custom_decode_float( decoder, packet_bufX + CDO, len, buf, nframes );
}

src_node = jack_slist_next (src_node);
} else if (jack_port_is_midi (porttype)) {
// midi port, decode midi events
// convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_down / 2;
uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
if( packet_payload )
decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
}
packet_bufX = (packet_bufX + net_period_down);
node = jack_slist_next (node);
chn++;
}
}

void
render_jack_ports_to_payload_opus (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
{
int chn = 0;
JSList *node = playback_ports;
JSList *src_node = playback_srcs;

unsigned char *packet_bufX = (unsigned char *)packet_payload;

while (node != NULL) {
jack_port_t *port = (jack_port_t *) node->data;
jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
const char *porttype = jack_port_type (port);

if (jack_port_is_audio (porttype)) {
// audio port, encode opus data.

int encoded_bytes;
float *floatbuf = alloca (sizeof(float) * nframes );
memcpy( floatbuf, buf, nframes * sizeof(float) );
OpusCustomEncoder *encoder = (OpusCustomEncoder*) src_node->data;
encoded_bytes = opus_custom_encode_float( encoder, floatbuf, nframes, packet_bufX + CDO, net_period_up - CDO );
unsigned short len = htons(encoded_bytes);
memcpy(packet_bufX, &len, CDO);
src_node = jack_slist_next( src_node );
} else if (jack_port_is_midi (porttype)) {
// encode midi events from port to packet
// convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_up / 2;
uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
}
packet_bufX = (packet_bufX + net_period_up);
node = jack_slist_next (node);
chn++;
}
}
#endif

/* Wrapper functions with bitdepth argument... */ /* Wrapper functions with bitdepth argument... */
void void
render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats)
@@ -1358,6 +1450,10 @@ render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t
#if HAVE_CELT #if HAVE_CELT
else if (bitdepth == CELT_MODE) else if (bitdepth == CELT_MODE)
render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
#endif
#if HAVE_OPUS
else if (bitdepth == OPUS_MODE)
render_payload_to_jack_ports_opus (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
#endif #endif
else else
render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats);
@@ -1373,6 +1469,10 @@ render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *play
#if HAVE_CELT #if HAVE_CELT
else if (bitdepth == CELT_MODE) else if (bitdepth == CELT_MODE)
render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
#endif
#if HAVE_OPUS
else if (bitdepth == OPUS_MODE)
render_jack_ports_to_payload_opus (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
#endif #endif
else else
render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats);


+ 1
- 0
common/netjack_packet.h View File

@@ -40,6 +40,7 @@ extern "C"
// The Packet Header. // The Packet Header.


#define CELT_MODE 1000 // Magic bitdepth value that indicates CELT compression #define CELT_MODE 1000 // Magic bitdepth value that indicates CELT compression
#define OPUS_MODE 999 // Magic bitdepth value that indicates OPUS compression
#define MASTER_FREEWHEELS 0x80000000 #define MASTER_FREEWHEELS 0x80000000


typedef struct _jacknet_packet_header jacknet_packet_header; typedef struct _jacknet_packet_header jacknet_packet_header;


+ 44
- 3
example-clients/netsource.c View File

@@ -62,6 +62,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <celt/celt.h> #include <celt/celt.h>
#endif #endif


#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#endif

#include <math.h> #include <math.h>


JSList *capture_ports = NULL; JSList *capture_ports = NULL;
@@ -147,6 +152,16 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL ); CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL );
capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) );
#endif #endif
#endif
} else if (bitdepth == 999) {
#if HAVE_OPUS
int err;
OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate( client ), jack_get_buffer_size(client), &err);
if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); }
OpusCustomDecoder *decoder = opus_custom_decoder_create(opus_mode, 1, &err);
if (err != OPUS_OK) { printf("OPUS DECODER FAILED\n"); }
opus_custom_decoder_init(decoder, opus_mode, 1);
capture_srcs = jack_slist_append(capture_srcs, decoder);
#endif #endif
} else { } else {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -189,6 +204,22 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL ); CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL );
playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) );
#endif #endif
#endif
} else if( bitdepth == 999 ) {
#if HAVE_OPUS
const int kbps = factor;
printf("new opus encoder %d kbps\n", kbps);
int err;
OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate (client), jack_get_buffer_size(client), &err ); // XXX free me
if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); }
OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, &err );
if (err != OPUS_OK) { printf("OPUS ENCODER FAILED\n"); }
opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second
opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
opus_custom_encoder_init(oe, opus_mode, 1);
playback_srcs = jack_slist_append(playback_srcs, oe);
#endif #endif
} else { } else {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -269,7 +300,7 @@ process (jack_nframes_t nframes, void *arg)
uint32_t *rx_packet_ptr; uint32_t *rx_packet_ptr;
jack_time_t packet_recv_timestamp; jack_time_t packet_recv_timestamp;


if( bitdepth == 1000 )
if( bitdepth == 1000 || bitdepth == 999)
net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ; net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
else else
net_period = (float) nframes / (float) factor; net_period = (float) nframes / (float) factor;
@@ -519,6 +550,7 @@ printUsage ()
" -B <bind port> - reply port, for use in NAT environments\n" " -B <bind port> - reply port, for use in NAT environments\n"
" -b <bitdepth> - Set transport to use 16bit or 8bit\n" " -b <bitdepth> - Set transport to use 16bit or 8bit\n"
" -c <kbits> - Use CELT encoding with <kbits> kbits per channel\n" " -c <kbits> - Use CELT encoding with <kbits> kbits per channel\n"
" -P <kbits> - Use Opus encoding with <kbits> kbits per channel\n"
" -m <mtu> - Assume this mtu for the link\n" " -m <mtu> - Assume this mtu for the link\n"
" -R <N> - Redundancy: send out packets N times.\n" " -R <N> - Redundancy: send out packets N times.\n"
" -e - skip host-to-network endianness conversion\n" " -e - skip host-to-network endianness conversion\n"
@@ -564,7 +596,7 @@ main (int argc, char *argv[])
sprintf(client_name, "netjack"); sprintf(client_name, "netjack");
sprintf(peer_ip, "localhost"); sprintf(peer_ip, "localhost");


while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:")) != -1) {
while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:P:")) != -1) {
switch (c) { switch (c) {
case 'h': case 'h':
printUsage(); printUsage();
@@ -613,6 +645,15 @@ main (int argc, char *argv[])
#else #else
printf( "not built with celt support\n" ); printf( "not built with celt support\n" );
exit(10); exit(10);
#endif
break;
case 'P':
#if HAVE_OPUS
bitdepth = 999;
factor = atoi (optarg);
#else
printf( "not built with opus support\n" );
exit(10);
#endif #endif
break; break;
case 'm': case 'm':
@@ -689,7 +730,7 @@ main (int argc, char *argv[])


alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi); alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi);


if( bitdepth == 1000 )
if( bitdepth == 1000 || bitdepth == 999)
net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ; net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
else else
net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor);


+ 3
- 3
example-clients/wscript View File

@@ -126,12 +126,12 @@ def build(bld):


if bld.env['IS_LINUX'] or bld.env['IS_MACOSX']: if bld.env['IS_LINUX'] or bld.env['IS_MACOSX']:
prog = bld(features = 'c cprogram') prog = bld(features = 'c cprogram')
prog.includes = os_incdir + ['../common/jack', '../common']
prog.includes = os_incdir + ['.', '..', '../common/jack', '../common']
prog.source = ['netsource.c', '../common/netjack_packet.c'] prog.source = ['netsource.c', '../common/netjack_packet.c']
prog.env.append_value("CFLAGS", "-DNO_JACK_ERROR") prog.env.append_value("CFLAGS", "-DNO_JACK_ERROR")
prog.use = ['CELT', 'SAMPLERATE']
prog.use = ['clientlib']
prog.use = ['CELT', 'SAMPLERATE', 'OPUS', 'clientlib']
prog.target = 'jack_netsource' prog.target = 'jack_netsource'
prog.defines = ['HAVE_CONFIG_H']


if bld.env['IS_LINUX'] and bld.env['BUILD_EXAMPLE_ALSA_IO']: if bld.env['IS_LINUX'] and bld.env['BUILD_EXAMPLE_ALSA_IO']:
prog = bld(features = 'c cprogram') prog = bld(features = 'c cprogram')


Loading…
Cancel
Save