Browse Source

netjack1/netone opus support

tags/1.9.9.5
Robin Gareus 13 years ago
parent
commit
d94f5edb03
9 changed files with 380 additions and 6 deletions
  1. +6
    -1
      common/JackNetAPI.cpp
  2. +167
    -0
      common/JackNetOneDriver.cpp
  3. +6
    -0
      common/JackNetOneDriver.h
  4. +1
    -1
      common/jack/net.h
  5. +47
    -1
      common/netjack.c
  6. +8
    -0
      common/netjack.h
  7. +100
    -0
      common/netjack_packet.c
  8. +1
    -0
      common/netjack_packet.h
  9. +44
    -3
      example-clients/netsource.c

+ 6
- 1
common/JackNetAPI.cpp View File

@@ -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);


+ 167
- 0
common/JackNetOneDriver.cpp View File

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

#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#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;


+ 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);
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);


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

@@ -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 {


+ 47
- 1
common/netjack.c View File

@@ -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;


+ 8
- 0
common/netjack.h View File

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

#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#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
};



+ 100
- 0
common/netjack_packet.c View File

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

#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#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);


+ 1
- 0
common/netjack_packet.h View File

@@ -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;


+ 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>
#endif

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

#include <math.h>

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 <bind port> - reply port, for use in NAT environments\n"
" -b <bitdepth> - Set transport to use 16bit or 8bit\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"
" -R <N> - 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);


Loading…
Cancel
Save