From a0dd08c32ec4c848470bb71852a807a14672bbff Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 9 Sep 2012 19:27:25 +0200 Subject: [PATCH 1/5] pass Opus encoded-length along with payload Eventually unused data should not be transmitted. That will require dynamic package lengths which are not yet supported by netjack2 --- common/JackNetTool.cpp | 62 ++++++++++++++++++++++++++---------------- common/JackNetTool.h | 3 +- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index eb30cc18..33379651 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -710,6 +710,7 @@ namespace Jack #endif #if HAVE_OPUS +#define CDO (sizeof(size_t)) ///< compressed data offset (first 4 bytes are length) NetOpusAudioBuffer::NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps) :NetAudioBuffer(params, nports, net_buffer) @@ -717,10 +718,12 @@ namespace Jack fOpusMode = new OpusCustomMode *[fNPorts]; fOpusEncoder = new OpusCustomEncoder *[fNPorts]; fOpusDecoder = new OpusCustomDecoder *[fNPorts]; + fCompressedSizesByte = new size_t [fNPorts]; memset(fOpusMode, 0, fNPorts * sizeof(OpusCustomMode*)); memset(fOpusEncoder, 0, fNPorts * sizeof(OpusCustomEncoder*)); memset(fOpusDecoder, 0, fNPorts * sizeof(OpusCustomDecoder*)); + memset(fCompressedSizesByte, 0, fNPorts * sizeof(int)); int error = OPUS_OK; @@ -753,25 +756,29 @@ namespace Jack } { + fCompressedMaxSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8); 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]; 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; 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); @@ -797,6 +804,7 @@ namespace Jack } delete [] fCompressedBuffer; + delete [] fCompressedSizesByte; } void NetOpusAudioBuffer::FreeOpus() @@ -846,10 +854,7 @@ namespace Jack } else { 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); - } + fCompressedSizesByte[port_index] = opus_custom_encode_float(fOpusEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedMaxSizeByte); } // All ports active @@ -860,9 +865,9 @@ namespace Jack { for (int port_index = 0; port_index < fNPorts; 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 != fPeriodSize) { + jack_error("opus_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizesByte[port_index], res); } } } @@ -879,14 +884,19 @@ namespace Jack } 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++) { - memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize); + size_t len = *((size_t*)(fNetBuffer + port_index * fSubPeriodBytesSize)); + fCompressedSizesByte[port_index] = ntohl(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 { 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 +906,21 @@ namespace Jack 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++) { - memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fLastSubPeriodBytesSize); + size_t len = htonl(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; } else { 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; } diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 9e54c7b4..8c68c011 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -419,7 +419,8 @@ namespace Jack OpusCustomEncoder** fOpusEncoder; OpusCustomDecoder** fOpusDecoder; - int fCompressedSizeByte; + size_t *fCompressedSizesByte; + int fCompressedMaxSizeByte; int fNumPackets; size_t fLastSubPeriodBytesSize; From d94f5edb0375586314505219d4bebc78f1499e69 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 10 Sep 2012 15:24:37 +0200 Subject: [PATCH 2/5] netjack1/netone opus support --- common/JackNetAPI.cpp | 7 +- common/JackNetOneDriver.cpp | 167 ++++++++++++++++++++++++++++++++++++ common/JackNetOneDriver.h | 6 ++ common/jack/net.h | 2 +- common/netjack.c | 48 ++++++++++- common/netjack.h | 8 ++ common/netjack_packet.c | 100 +++++++++++++++++++++ common/netjack_packet.h | 1 + example-clients/netsource.c | 47 +++++++++- 9 files changed, 380 insertions(+), 6 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index cf670d7a..1ccc814e 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -37,7 +37,7 @@ extern "C" JackFloatEncoder = 0, JackIntEncoder = 1, JackCeltEncoder = 2, - JackMaxEncoder = 3 + JackOpusEncoder = 3 }; typedef struct { @@ -551,6 +551,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf return -1; } + if ((fParams.fSampleEncoder == JackOpusEncoder) && (fParams.fKBps == 0)) { + jack_error("Opus encoder with 0 for kps..."); + return -1; + } + // Check latency if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) { jack_error("Error : network latency is limited to %d", NETWORK_MAX_LATENCY); diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index fd213bac..b65783b7 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -39,6 +39,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #endif +#if HAVE_OPUS +#include +#include +#endif + #define MIN(x,y) ((x)<(y) ? (x) : (y)) using namespace std; @@ -146,6 +151,13 @@ int JackNetOneDriver::AllocPorts() #endif celt_mode_info(celt_mode, CELT_GET_LOOKAHEAD, &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 } else { #if HAVE_SAMPLERATE @@ -191,6 +203,22 @@ int JackNetOneDriver::AllocPorts() 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)); #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 } else { #if HAVE_SAMPLERATE @@ -450,6 +478,28 @@ JackNetOneDriver::FreePorts () celt_decoder_destroy(dec); } 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 } else { #if HAVE_SAMPLERATE @@ -724,6 +774,98 @@ JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSL } #endif + +#if HAVE_OPUS +// 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 { +#define CDO (sizeof(size_t)) ///< compressed data offset (first 4 bytes are length) + size_t len; + memcpy(&len, packet_bufX, sizeof(size_t)); + len = ntohl(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 ); + size_t len = htonl(encoded_bytes); + memcpy(packet_bufX, &len, sizeof(size_t)); + 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... */ 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) @@ -732,6 +874,11 @@ JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_paylo if (bitdepth == CELT_MODE) render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); 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 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) render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); 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 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 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); +#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 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); @@ -904,6 +1060,17 @@ extern "C" #endif 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': handle_transport_sync = param->value.ui; break; diff --git a/common/JackNetOneDriver.h b/common/JackNetOneDriver.h index 954a7cba..2b0e649b 100644 --- a/common/JackNetOneDriver.h +++ b/common/JackNetOneDriver.h @@ -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); 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); +#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 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); diff --git a/common/jack/net.h b/common/jack/net.h index ad7eb8ce..e8f554c6 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -40,7 +40,7 @@ enum JackNetEncoder { JackFloatEncoder = 0, // samples are transmitted as float JackIntEncoder = 1, // samples are transmitted as 16 bits integer 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 { diff --git a/common/netjack.c b/common/netjack.c index 74cdc5df..8eeb6237 100644 --- a/common/netjack.c +++ b/common/netjack.c @@ -368,6 +368,11 @@ void netjack_attach( netjack_driver_state_t *netj ) netj->codec_latency = 2 * lookahead; #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) 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 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) ); #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 } else { #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 ); netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) ); #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 } else { #if HAVE_SAMPLERATE @@ -492,6 +517,12 @@ void netjack_detach( netjack_driver_state_t *netj ) CELTDecoder * decoder = node->data; celt_decoder_destroy(decoder); } else +#endif +#if HAVE_OPUS + if ( netj->bitdepth == OPUS_MODE ) { + OpusCustomDecoder * decoder = node->data; + opus_custom_decoder_destroy(decoder); + } else #endif { #if HAVE_SAMPLERATE @@ -516,6 +547,12 @@ void netjack_detach( netjack_driver_state_t *netj ) CELTEncoder * encoder = node->data; celt_encoder_destroy(encoder); } else +#endif +#if HAVE_OPUS + if ( netj->bitdepth == OPUS_MODE ) { + OpusCustomEncoder * encoder = node->data; + opus_custom_encoder_destroy(encoder); + } else #endif { #if HAVE_SAMPLERATE @@ -531,6 +568,10 @@ void netjack_detach( netjack_driver_state_t *netj ) if( netj->bitdepth == CELT_MODE ) celt_mode_destroy(netj->celt_mode); #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; - 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); return NULL; } @@ -755,6 +796,11 @@ netjack_startup( netjack_driver_state_t *netj ) netj->net_period_down = netj->resample_factor; 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 { 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; diff --git a/common/netjack.h b/common/netjack.h index 2ff3c299..b21f5bde 100644 --- a/common/netjack.h +++ b/common/netjack.h @@ -32,6 +32,11 @@ #include #endif +#if HAVE_OPUS +#include +#include +#endif + #ifdef __cplusplus extern "C" { @@ -111,6 +116,9 @@ extern "C" struct _packet_cache * packcache; #if HAVE_CELT CELTMode *celt_mode; +#endif +#if HAVE_OPUS + OpusCustomMode* opus_mode; #endif }; diff --git a/common/netjack_packet.c b/common/netjack_packet.c index 6061db1f..5d1cd95e 100644 --- a/common/netjack_packet.c +++ b/common/netjack_packet.c @@ -72,6 +72,11 @@ #include #endif +#if HAVE_OPUS +#include +#include +#endif + #include "netjack_packet.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? if( bitdepth == CELT_MODE ) return sizeof( unsigned char ); + if( bitdepth == OPUS_MODE ) + return sizeof( unsigned char ); return sizeof (int32_t); } @@ -1347,6 +1354,91 @@ render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs } #endif + +#if HAVE_OPUS +// 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 { +#define CDO (sizeof(size_t)) ///< compressed data offset (first 4 bytes are length) + size_t len; + memcpy(&len, packet_bufX, sizeof(size_t)); + len = ntohl(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 ); + size_t len = htonl(encoded_bytes); + memcpy(packet_bufX, &len, sizeof(size_t)); + 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... */ 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) @@ -1358,6 +1450,10 @@ render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t #if HAVE_CELT else if (bitdepth == CELT_MODE) 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 else 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 else if (bitdepth == CELT_MODE) 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 else render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); diff --git a/common/netjack_packet.h b/common/netjack_packet.h index 1f88ae32..63fa7729 100644 --- a/common/netjack_packet.h +++ b/common/netjack_packet.h @@ -40,6 +40,7 @@ extern "C" // The Packet Header. #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 typedef struct _jacknet_packet_header jacknet_packet_header; diff --git a/example-clients/netsource.c b/example-clients/netsource.c index e2b916e0..9386aecc 100644 --- a/example-clients/netsource.c +++ b/example-clients/netsource.c @@ -62,6 +62,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #endif +#if HAVE_OPUS +#include +#include +#endif + #include 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 ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) ); #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 } else { #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 ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) ); #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 } else { #if HAVE_SAMPLERATE @@ -269,7 +300,7 @@ process (jack_nframes_t nframes, void *arg) uint32_t *rx_packet_ptr; 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) ; else net_period = (float) nframes / (float) factor; @@ -519,6 +550,7 @@ printUsage () " -B - reply port, for use in NAT environments\n" " -b - Set transport to use 16bit or 8bit\n" " -c - Use CELT encoding with kbits per channel\n" + " -P - Use Opus encoding with kbits per channel\n" " -m - Assume this mtu for the link\n" " -R - Redundancy: send out packets N times.\n" " -e - skip host-to-network endianness conversion\n" @@ -564,7 +596,7 @@ main (int argc, char *argv[]) sprintf(client_name, "netjack"); 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) { case 'h': printUsage(); @@ -613,6 +645,15 @@ main (int argc, char *argv[]) #else printf( "not built with celt support\n" ); 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 break; 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); - if( bitdepth == 1000 ) + if( bitdepth == 1000 || bitdepth == 999) net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ; else net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); From 3085ae19e9923ac4415d4348374c4a6c5c4838d2 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 10 Sep 2012 15:25:12 +0200 Subject: [PATCH 3/5] netjack1/2 Opus: use only 2bytes for encoded-length --- common/JackNetOneDriver.cpp | 12 ++++++------ common/JackNetTool.cpp | 17 +++++++++++------ common/JackNetTool.h | 2 +- common/netjack_packet.c | 12 ++++++------ 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index b65783b7..5f5f390a 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -776,6 +776,7 @@ JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSL #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) @@ -801,10 +802,9 @@ JackNetOneDriver::render_payload_to_jack_ports_opus (void *packet_payload, jack_ if( !packet_payload ) memset(buf, 0, nframes * sizeof(float)); else { -#define CDO (sizeof(size_t)) ///< compressed data offset (first 4 bytes are length) - size_t len; - memcpy(&len, packet_bufX, sizeof(size_t)); - len = ntohl(len); + unsigned short len; + memcpy(&len, packet_bufX, CDO); + len = ntohs(len); opus_custom_decode_float( decoder, packet_bufX + CDO, len, buf, nframes ); } @@ -849,8 +849,8 @@ JackNetOneDriver::render_jack_ports_to_payload_opus (JSList *playback_ports, JSL 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 ); - size_t len = htonl(encoded_bytes); - memcpy(packet_bufX, &len, sizeof(size_t)); + 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 diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 33379651..6bda460e 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -710,7 +710,7 @@ namespace Jack #endif #if HAVE_OPUS -#define CDO (sizeof(size_t)) ///< compressed data offset (first 4 bytes are length) +#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) :NetAudioBuffer(params, nports, net_buffer) @@ -718,7 +718,7 @@ namespace Jack fOpusMode = new OpusCustomMode *[fNPorts]; fOpusEncoder = new OpusCustomEncoder *[fNPorts]; fOpusDecoder = new OpusCustomDecoder *[fNPorts]; - fCompressedSizesByte = new size_t [fNPorts]; + fCompressedSizesByte = new unsigned short [fNPorts]; memset(fOpusMode, 0, fNPorts * sizeof(OpusCustomMode*)); memset(fOpusEncoder, 0, fNPorts * sizeof(OpusCustomEncoder*)); @@ -854,7 +854,12 @@ namespace Jack } else { memset(buffer, 0, fPeriodSize * sizeof(sample_t)); } - fCompressedSizesByte[port_index] = opus_custom_encode_float(fOpusEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedMaxSizeByte); + 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 @@ -866,7 +871,7 @@ namespace Jack for (int port_index = 0; port_index < fNPorts; port_index++) { if (fPortBuffer[port_index]) { int res = opus_custom_decode_float(fOpusDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizesByte[port_index], fPortBuffer[port_index], fPeriodSize); - if (res != fPeriodSize) { + if (res < 0 || res != fPeriodSize) { jack_error("opus_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizesByte[port_index], res); } } @@ -887,7 +892,7 @@ namespace Jack if (sub_cycle == 0) { for (int port_index = 0; port_index < fNPorts; port_index++) { size_t len = *((size_t*)(fNetBuffer + port_index * fSubPeriodBytesSize)); - fCompressedSizesByte[port_index] = ntohl(len); + 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) { @@ -908,7 +913,7 @@ namespace Jack { if (sub_cycle == 0) { for (int port_index = 0; port_index < fNPorts; port_index++) { - size_t len = htonl(fCompressedSizesByte[port_index]); + 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); } diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 8c68c011..c622acee 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -419,7 +419,7 @@ namespace Jack OpusCustomEncoder** fOpusEncoder; OpusCustomDecoder** fOpusDecoder; - size_t *fCompressedSizesByte; + unsigned short *fCompressedSizesByte; int fCompressedMaxSizeByte; int fNumPackets; diff --git a/common/netjack_packet.c b/common/netjack_packet.c index 5d1cd95e..a4e5b842 100644 --- a/common/netjack_packet.c +++ b/common/netjack_packet.c @@ -1356,6 +1356,7 @@ render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs #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) @@ -1378,10 +1379,9 @@ render_payload_to_jack_ports_opus (void *packet_payload, jack_nframes_t net_peri if( !packet_payload ) memset(buf, 0, nframes * sizeof(float)); else { -#define CDO (sizeof(size_t)) ///< compressed data offset (first 4 bytes are length) - size_t len; - memcpy(&len, packet_bufX, sizeof(size_t)); - len = ntohl(len); + unsigned short len; + memcpy(&len, packet_bufX, CDO); + len = ntohs(len); opus_custom_decode_float( decoder, packet_bufX + CDO, len, buf, nframes ); } @@ -1422,8 +1422,8 @@ render_jack_ports_to_payload_opus (JSList *playback_ports, JSList *playback_srcs 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 ); - size_t len = htonl(encoded_bytes); - memcpy(packet_bufX, &len, sizeof(size_t)); + 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 From abc1cab6aa7921596c0f9097a7399b81db64c4c0 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 10 Sep 2012 16:54:26 +0200 Subject: [PATCH 4/5] wscript: add header defines and libs for example-clients/netsource Thanks to nedko - closes #15 --- example-clients/wscript | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/example-clients/wscript b/example-clients/wscript index 0782bce0..5d8356e4 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -129,9 +129,10 @@ def build(bld): prog.includes = os_incdir + ['../common/jack', '../common'] prog.source = ['netsource.c', '../common/netjack_packet.c'] 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.defines = ['HAVE_CONFIG_H'] + prog.includes = os_incdir + ['.', '..', '../common/jack', '../common'] if bld.env['IS_LINUX'] and bld.env['BUILD_EXAMPLE_ALSA_IO']: prog = bld(features = 'c cprogram') From ce83a138935c610fb3f18d6eba6e3ad153e93155 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 10 Sep 2012 17:12:43 +0200 Subject: [PATCH 5/5] fix duplicate prog.includes --- example-clients/wscript | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example-clients/wscript b/example-clients/wscript index 5d8356e4..caa45499 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -126,13 +126,12 @@ def build(bld): if bld.env['IS_LINUX'] or bld.env['IS_MACOSX']: 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.env.append_value("CFLAGS", "-DNO_JACK_ERROR") prog.use = ['CELT', 'SAMPLERATE', 'OPUS', 'clientlib'] prog.target = 'jack_netsource' prog.defines = ['HAVE_CONFIG_H'] - prog.includes = os_incdir + ['.', '..', '../common/jack', '../common'] if bld.env['IS_LINUX'] and bld.env['BUILD_EXAMPLE_ALSA_IO']: prog = bld(features = 'c cprogram')