Browse Source

Merge 413af62f77 into 87ccc8a883

pull/145/merge
Karl Lindén 10 years ago
parent
commit
dcabf7979b
14 changed files with 694 additions and 578 deletions
  1. +268
    -0
      common/JackNetCelt.cpp
  2. +66
    -0
      common/JackNetCelt.h
  3. +8
    -0
      common/JackNetInterface.cpp
  4. +2
    -2
      common/JackNetOneDriver.cpp
  5. +243
    -0
      common/JackNetOpus.cpp
  6. +68
    -0
      common/JackNetOpus.h
  7. +0
    -471
      common/JackNetTool.cpp
  8. +5
    -86
      common/JackNetTool.h
  9. +2
    -2
      common/netjack.h
  10. +2
    -2
      common/netjack_packet.c
  11. +10
    -0
      common/wscript
  12. +2
    -2
      example-clients/netsource.c
  13. +1
    -1
      linux/wscript
  14. +17
    -12
      wscript

+ 268
- 0
common/JackNetCelt.cpp View File

@@ -0,0 +1,268 @@
/*
Copyright (C) 2008-2011 Romain Moret at Grame

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#include "JackNetCelt.h"
#include "JackError.h"

namespace Jack
{
#define KPS 32
#define KPS_DIV 8

NetCeltAudioBuffer::NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
:NetAudioBuffer(params, nports, net_buffer)
{
fCeltMode = new CELTMode*[fNPorts];
fCeltEncoder = new CELTEncoder*[fNPorts];
fCeltDecoder = new CELTDecoder*[fNPorts];

memset(fCeltMode, 0, fNPorts * sizeof(CELTMode*));
memset(fCeltEncoder, 0, fNPorts * sizeof(CELTEncoder*));
memset(fCeltDecoder, 0, fNPorts * sizeof(CELTDecoder*));

int error = CELT_OK;

for (int i = 0; i < fNPorts; i++) {
fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_mode_create err = %d", error);
goto error;
}

#if HAVE_CELT_API_0_11

fCeltEncoder[i] = celt_encoder_create_custom(fCeltMode[i], 1, &error);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_encoder_create_custom err = %d", error);
goto error;
}
celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));

fCeltDecoder[i] = celt_decoder_create_custom(fCeltMode[i], 1, &error);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_decoder_create_custom err = %d", error);
goto error;
}
celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));

#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8

fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_mode_create err = %d", error);
goto error;
}
celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));

fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_decoder_create err = %d", error);
goto error;
}
celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));

#else

fCeltEncoder[i] = celt_encoder_create(fCeltMode[i]);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_encoder_create err = %d", error);
goto error;
}
celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));

fCeltDecoder[i] = celt_decoder_create(fCeltMode[i]);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_decoder_create err = %d", error);
goto error;
}
celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));

#endif
}

{
fPeriodSize = params->fPeriodSize;

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

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

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

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

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

fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;

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

fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
fCycleBytesSize = params->fMtu * fNumPackets;

fLastSubCycle = -1;
return;
}

error:

FreeCelt();
throw std::bad_alloc();
}

NetCeltAudioBuffer::~NetCeltAudioBuffer()
{
FreeCelt();

for (int port_index = 0; port_index < fNPorts; port_index++) {
delete [] fCompressedBuffer[port_index];
}

delete [] fCompressedBuffer;
}

void NetCeltAudioBuffer::FreeCelt()
{
for (int i = 0; i < fNPorts; i++) {
if (fCeltEncoder[i]) {
celt_encoder_destroy(fCeltEncoder[i]);
}
if (fCeltDecoder[i]) {
celt_decoder_destroy(fCeltDecoder[i]);
}
if (fCeltMode[i]) {
celt_mode_destroy(fCeltMode[i]);
}
}

delete [] fCeltMode;
delete [] fCeltEncoder;
delete [] fCeltDecoder;
}

size_t NetCeltAudioBuffer::GetCycleSize()
{
return fCycleBytesSize;
}

float NetCeltAudioBuffer::GetCycleDuration()
{
return fCycleDuration;
}

int NetCeltAudioBuffer::GetNumPackets(int active_ports)
{
return fNumPackets;
}

int NetCeltAudioBuffer::RenderFromJackPorts(int nframes)
{
float buffer[BUFFER_SIZE_MAX];

for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) {
memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
} else {
memset(buffer, 0, fPeriodSize * sizeof(sample_t));
}
#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
//int res = celt_encode_float(fCeltEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedSizeByte);
int res = celt_encode_float(fCeltEncoder[port_index], buffer, nframes, fCompressedBuffer[port_index], fCompressedSizeByte);
#else
int res = celt_encode_float(fCeltEncoder[port_index], buffer, NULL, fCompressedBuffer[port_index], fCompressedSizeByte);
#endif
if (res != fCompressedSizeByte) {
jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
}
}

// All ports active
return fNPorts;
}

void NetCeltAudioBuffer::RenderToJackPorts(int nframes)
{
for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) {
#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
//int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], fPeriodSize);
int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], nframes);
#else
int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]);
#endif
if (res != CELT_OK) {
jack_error("celt_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
}
}
}

NextCycle();
}

//network<->buffer
int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
{
// Cleanup all JACK ports at the beginning of the cycle
if (sub_cycle == 0) {
Cleanup();
}

if (port_num > 0) {

int sub_period_bytes_size;

// Last packet of the cycle
if (sub_cycle == fNumPackets - 1) {
sub_period_bytes_size = fLastSubPeriodBytesSize;
} else {
sub_period_bytes_size = fSubPeriodBytesSize;
}

for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * sub_period_bytes_size, sub_period_bytes_size);
}
}

return CheckPacket(cycle, sub_cycle);
}

int NetCeltAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
{
int sub_period_bytes_size;

// Last packet of the cycle
if (sub_cycle == fNumPackets - 1) {
sub_period_bytes_size = fLastSubPeriodBytesSize;
} else {
sub_period_bytes_size = fSubPeriodBytesSize;
}

for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * sub_period_bytes_size, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, sub_period_bytes_size);
}
return fNPorts * sub_period_bytes_size;
}
}

+ 66
- 0
common/JackNetCelt.h View File

@@ -0,0 +1,66 @@
/*
Copyright (C) 2008-2011 Romain Moret at Grame

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef __JackNetCelt__
#define __JackNetCelt__

#include "JackNetTool.h"

#include <celt/celt.h>

namespace Jack
{
class SERVER_EXPORT NetCeltAudioBuffer : public NetAudioBuffer
{
private:

CELTMode** fCeltMode;
CELTEncoder** fCeltEncoder;
CELTDecoder** fCeltDecoder;

int fCompressedSizeByte;
unsigned char** fCompressedBuffer;

size_t fLastSubPeriodBytesSize;

void FreeCelt();

public:

NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps);
virtual ~NetCeltAudioBuffer();

// needed size in bytes for an entire cycle
size_t GetCycleSize();

// cycle duration in sec
float GetCycleDuration();
int GetNumPackets(int active_ports);

//jack<->buffer
int RenderFromJackPorts(int nframes);
void RenderToJackPorts(int nframes);

//network<->buffer
int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
int RenderToNetwork(int sub_cycle, uint32_t port_num);
};
}

#endif

+ 8
- 0
common/JackNetInterface.cpp View File

@@ -20,6 +20,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackException.h"
#include "JackError.h"

#if HAVE_CELT
#include "JackNetCelt.h"
#endif

#if HAVE_OPUS
#include "JackNetOpus.h"
#endif

#include <assert.h>

using namespace std;


+ 2
- 2
common/JackNetOneDriver.cpp View File

@@ -40,8 +40,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#endif

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

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


+ 243
- 0
common/JackNetOpus.cpp View File

@@ -0,0 +1,243 @@
/*
Copyright (C) 2008-2011 Romain Moret at Grame

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#include "JackNetOpus.h"
#include "JackError.h"

namespace Jack
{
#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)
{
fOpusMode = new OpusCustomMode*[fNPorts];
fOpusEncoder = new OpusCustomEncoder*[fNPorts];
fOpusDecoder = new OpusCustomDecoder*[fNPorts];
fCompressedSizesByte = new unsigned short[fNPorts];

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

int error = OPUS_OK;

for (int i = 0; i < fNPorts; i++) {
/* Allocate en/decoders */
fOpusMode[i] = opus_custom_mode_create(params->fSampleRate, params->fPeriodSize, &error);
if (error != OPUS_OK) {
jack_log("NetOpusAudioBuffer opus_custom_mode_create err = %d", error);
goto error;
}

fOpusEncoder[i] = opus_custom_encoder_create(fOpusMode[i], 1, &error);
if (error != OPUS_OK) {
jack_log("NetOpusAudioBuffer opus_custom_encoder_create err = %d", error);
goto error;
}

fOpusDecoder[i] = opus_custom_decoder_create(fOpusMode[i], 1, &error);
if (error != OPUS_OK) {
jack_log("NetOpusAudioBuffer opus_custom_decoder_create err = %d", error);
goto error;
}

opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_BITRATE(kbps*1024)); // bits per second
opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_COMPLEXITY(10));
opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
}

{
fCompressedMaxSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
fPeriodSize = params->fPeriodSize;
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[fCompressedMaxSizeByte];
memset(fCompressedBuffer[port_index], 0, fCompressedMaxSizeByte * sizeof(char));
}

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 = (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);

fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
fCycleBytesSize = params->fMtu * fNumPackets;

fLastSubCycle = -1;
return;
}

error:

FreeOpus();
throw std::bad_alloc();
}

NetOpusAudioBuffer::~NetOpusAudioBuffer()
{
FreeOpus();

for (int port_index = 0; port_index < fNPorts; port_index++) {
delete [] fCompressedBuffer[port_index];
}

delete [] fCompressedBuffer;
delete [] fCompressedSizesByte;
}

void NetOpusAudioBuffer::FreeOpus()
{
for (int i = 0; i < fNPorts; i++) {
if (fOpusEncoder[i]) {
opus_custom_encoder_destroy(fOpusEncoder[i]);
fOpusEncoder[i] = 0;
}
if (fOpusDecoder[i]) {
opus_custom_decoder_destroy(fOpusDecoder[i]);
fOpusDecoder[i] = 0;
}
if (fOpusMode[i]) {
opus_custom_mode_destroy(fOpusMode[i]);
fOpusMode[i] = 0;
}
}

delete [] fOpusEncoder;
delete [] fOpusDecoder;
delete [] fOpusMode;
}

size_t NetOpusAudioBuffer::GetCycleSize()
{
return fCycleBytesSize;
}

float NetOpusAudioBuffer::GetCycleDuration()
{
return fCycleDuration;
}

int NetOpusAudioBuffer::GetNumPackets(int active_ports)
{
return fNumPackets;
}

int NetOpusAudioBuffer::RenderFromJackPorts(int nframes)
{
float buffer[BUFFER_SIZE_MAX];

for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) {
memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
} else {
memset(buffer, 0, fPeriodSize * sizeof(sample_t));
}
int res = opus_custom_encode_float(fOpusEncoder[port_index], buffer, ((nframes == -1) ? fPeriodSize : nframes), fCompressedBuffer[port_index], fCompressedMaxSizeByte);
if (res < 0 || res >= 65535) {
jack_error("opus_custom_encode_float error res = %d", res);
fCompressedSizesByte[port_index] = 0;
} else {
fCompressedSizesByte[port_index] = res;
}
}

// All ports active
return fNPorts;
}

void NetOpusAudioBuffer::RenderToJackPorts(int nframes)
{
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], ((nframes == -1) ? fPeriodSize : nframes));
if (res < 0 || res != ((nframes == -1) ? fPeriodSize : nframes)) {
jack_error("opus_custom_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizesByte[port_index], res);
}
}
}

NextCycle();
}

//network<->buffer
int NetOpusAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
{
// Cleanup all JACK ports at the beginning of the cycle
if (sub_cycle == 0) {
Cleanup();
}

if (port_num > 0) {
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] = 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 {
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
}
}
}

return CheckPacket(cycle, sub_cycle);
}

int NetOpusAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
{
if (sub_cycle == 0) {
for (int port_index = 0; port_index < fNPorts; 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);
}
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 - CDO, fSubPeriodBytesSize);
}
return fNPorts * fSubPeriodBytesSize;
}
}
}

+ 68
- 0
common/JackNetOpus.h View File

@@ -0,0 +1,68 @@
/*
Copyright (C) 2008-2011 Romain Moret at Grame

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef __JackNetOpus__
#define __JackNetOpus__

#include "JackNetTool.h"

#include <opus.h>
#include <opus_custom.h>

namespace Jack
{
class SERVER_EXPORT NetOpusAudioBuffer : public NetAudioBuffer
{
private:

OpusCustomMode** fOpusMode;
OpusCustomEncoder** fOpusEncoder;
OpusCustomDecoder** fOpusDecoder;

int fCompressedMaxSizeByte;
unsigned short* fCompressedSizesByte;

size_t fLastSubPeriodBytesSize;

unsigned char** fCompressedBuffer;
void FreeOpus();

public:

NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps);
virtual ~NetOpusAudioBuffer();

// needed size in bytes for an entire cycle
size_t GetCycleSize();

// cycle duration in sec
float GetCycleDuration();
int GetNumPackets(int active_ports);

//jack<->buffer
int RenderFromJackPorts(int nframes);
void RenderToJackPorts(int nframes);

//network<->buffer
int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
int RenderToNetwork(int sub_cycle, uint32_t port_num);
};
}

#endif

+ 0
- 471
common/JackNetTool.cpp View File

@@ -473,478 +473,7 @@ namespace Jack
}

#endif
// Celt audio buffer *********************************************************************************

#if HAVE_CELT

#define KPS 32
#define KPS_DIV 8

NetCeltAudioBuffer::NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
:NetAudioBuffer(params, nports, net_buffer)
{
fCeltMode = new CELTMode*[fNPorts];
fCeltEncoder = new CELTEncoder*[fNPorts];
fCeltDecoder = new CELTDecoder*[fNPorts];

memset(fCeltMode, 0, fNPorts * sizeof(CELTMode*));
memset(fCeltEncoder, 0, fNPorts * sizeof(CELTEncoder*));
memset(fCeltDecoder, 0, fNPorts * sizeof(CELTDecoder*));

int error = CELT_OK;

for (int i = 0; i < fNPorts; i++) {
fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_mode_create err = %d", error);
goto error;
}

#if HAVE_CELT_API_0_11

fCeltEncoder[i] = celt_encoder_create_custom(fCeltMode[i], 1, &error);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_encoder_create_custom err = %d", error);
goto error;
}
celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));

fCeltDecoder[i] = celt_decoder_create_custom(fCeltMode[i], 1, &error);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_decoder_create_custom err = %d", error);
goto error;
}
celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));

#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8

fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_mode_create err = %d", error);
goto error;
}
celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));

fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_decoder_create err = %d", error);
goto error;
}
celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));

#else

fCeltEncoder[i] = celt_encoder_create(fCeltMode[i]);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_encoder_create err = %d", error);
goto error;
}
celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));

fCeltDecoder[i] = celt_decoder_create(fCeltMode[i]);
if (error != CELT_OK) {
jack_log("NetCeltAudioBuffer celt_decoder_create err = %d", error);
goto error;
}
celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));

#endif
}

{
fPeriodSize = params->fPeriodSize;

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

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

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

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

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

fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;

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

fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
fCycleBytesSize = params->fMtu * fNumPackets;

fLastSubCycle = -1;
return;
}

error:

FreeCelt();
throw std::bad_alloc();
}

NetCeltAudioBuffer::~NetCeltAudioBuffer()
{
FreeCelt();

for (int port_index = 0; port_index < fNPorts; port_index++) {
delete [] fCompressedBuffer[port_index];
}

delete [] fCompressedBuffer;
}

void NetCeltAudioBuffer::FreeCelt()
{
for (int i = 0; i < fNPorts; i++) {
if (fCeltEncoder[i]) {
celt_encoder_destroy(fCeltEncoder[i]);
}
if (fCeltDecoder[i]) {
celt_decoder_destroy(fCeltDecoder[i]);
}
if (fCeltMode[i]) {
celt_mode_destroy(fCeltMode[i]);
}
}

delete [] fCeltMode;
delete [] fCeltEncoder;
delete [] fCeltDecoder;
}

size_t NetCeltAudioBuffer::GetCycleSize()
{
return fCycleBytesSize;
}

float NetCeltAudioBuffer::GetCycleDuration()
{
return fCycleDuration;
}

int NetCeltAudioBuffer::GetNumPackets(int active_ports)
{
return fNumPackets;
}

int NetCeltAudioBuffer::RenderFromJackPorts(int nframes)
{
float buffer[BUFFER_SIZE_MAX];

for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) {
memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
} else {
memset(buffer, 0, fPeriodSize * sizeof(sample_t));
}
#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
//int res = celt_encode_float(fCeltEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedSizeByte);
int res = celt_encode_float(fCeltEncoder[port_index], buffer, nframes, fCompressedBuffer[port_index], fCompressedSizeByte);
#else
int res = celt_encode_float(fCeltEncoder[port_index], buffer, NULL, fCompressedBuffer[port_index], fCompressedSizeByte);
#endif
if (res != fCompressedSizeByte) {
jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
}
}

// All ports active
return fNPorts;
}

void NetCeltAudioBuffer::RenderToJackPorts(int nframes)
{
for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) {
#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
//int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], fPeriodSize);
int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], nframes);
#else
int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]);
#endif
if (res != CELT_OK) {
jack_error("celt_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
}
}
}

NextCycle();
}

//network<->buffer
int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
{
// Cleanup all JACK ports at the beginning of the cycle
if (sub_cycle == 0) {
Cleanup();
}

if (port_num > 0) {
int sub_period_bytes_size;
// Last packet of the cycle
if (sub_cycle == fNumPackets - 1) {
sub_period_bytes_size = fLastSubPeriodBytesSize;
} else {
sub_period_bytes_size = fSubPeriodBytesSize;
}
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * sub_period_bytes_size, sub_period_bytes_size);
}
}

return CheckPacket(cycle, sub_cycle);
}

int NetCeltAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
{
int sub_period_bytes_size;
// Last packet of the cycle
if (sub_cycle == fNumPackets - 1) {
sub_period_bytes_size = fLastSubPeriodBytesSize;
} else {
sub_period_bytes_size = fSubPeriodBytesSize;
}
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * sub_period_bytes_size, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, sub_period_bytes_size);
}
return fNPorts * sub_period_bytes_size;
}

#endif


#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)
:NetAudioBuffer(params, nports, net_buffer)
{
fOpusMode = new OpusCustomMode*[fNPorts];
fOpusEncoder = new OpusCustomEncoder*[fNPorts];
fOpusDecoder = new OpusCustomDecoder*[fNPorts];
fCompressedSizesByte = new unsigned short[fNPorts];

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

int error = OPUS_OK;
for (int i = 0; i < fNPorts; i++) {
/* Allocate en/decoders */
fOpusMode[i] = opus_custom_mode_create(params->fSampleRate, params->fPeriodSize, &error);
if (error != OPUS_OK) {
jack_log("NetOpusAudioBuffer opus_custom_mode_create err = %d", error);
goto error;
}

fOpusEncoder[i] = opus_custom_encoder_create(fOpusMode[i], 1, &error);
if (error != OPUS_OK) {
jack_log("NetOpusAudioBuffer opus_custom_encoder_create err = %d", error);
goto error;
}

fOpusDecoder[i] = opus_custom_decoder_create(fOpusMode[i], 1, &error);
if (error != OPUS_OK) {
jack_log("NetOpusAudioBuffer opus_custom_decoder_create err = %d", error);
goto error;
}

opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_BITRATE(kbps*1024)); // bits per second
opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_COMPLEXITY(10));
opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
}

{
fCompressedMaxSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
fPeriodSize = params->fPeriodSize;
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[fCompressedMaxSizeByte];
memset(fCompressedBuffer[port_index], 0, fCompressedMaxSizeByte * sizeof(char));
}

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 = (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);

fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
fCycleBytesSize = params->fMtu * fNumPackets;

fLastSubCycle = -1;
return;
}

error:

FreeOpus();
throw std::bad_alloc();
}

NetOpusAudioBuffer::~NetOpusAudioBuffer()
{
FreeOpus();

for (int port_index = 0; port_index < fNPorts; port_index++) {
delete [] fCompressedBuffer[port_index];
}

delete [] fCompressedBuffer;
delete [] fCompressedSizesByte;
}

void NetOpusAudioBuffer::FreeOpus()
{
for (int i = 0; i < fNPorts; i++) {
if (fOpusEncoder[i]) {
opus_custom_encoder_destroy(fOpusEncoder[i]);
fOpusEncoder[i] = 0;
}
if (fOpusDecoder[i]) {
opus_custom_decoder_destroy(fOpusDecoder[i]);
fOpusDecoder[i] = 0;
}
if (fOpusMode[i]) {
opus_custom_mode_destroy(fOpusMode[i]);
fOpusMode[i] = 0;
}
}

delete [] fOpusEncoder;
delete [] fOpusDecoder;
delete [] fOpusMode;
}

size_t NetOpusAudioBuffer::GetCycleSize()
{
return fCycleBytesSize;
}

float NetOpusAudioBuffer::GetCycleDuration()
{
return fCycleDuration;
}

int NetOpusAudioBuffer::GetNumPackets(int active_ports)
{
return fNumPackets;
}

int NetOpusAudioBuffer::RenderFromJackPorts(int nframes)
{
float buffer[BUFFER_SIZE_MAX];
for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) {
memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
} else {
memset(buffer, 0, fPeriodSize * sizeof(sample_t));
}
int res = opus_custom_encode_float(fOpusEncoder[port_index], buffer, ((nframes == -1) ? fPeriodSize : nframes), fCompressedBuffer[port_index], fCompressedMaxSizeByte);
if (res < 0 || res >= 65535) {
jack_error("opus_custom_encode_float error res = %d", res);
fCompressedSizesByte[port_index] = 0;
} else {
fCompressedSizesByte[port_index] = res;
}
}

// All ports active
return fNPorts;
}

void NetOpusAudioBuffer::RenderToJackPorts(int nframes)
{
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], ((nframes == -1) ? fPeriodSize : nframes));
if (res < 0 || res != ((nframes == -1) ? fPeriodSize : nframes)) {
jack_error("opus_custom_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizesByte[port_index], res);
}
}
}

NextCycle();
}

//network<->buffer
int NetOpusAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
{
// Cleanup all JACK ports at the beginning of the cycle
if (sub_cycle == 0) {
Cleanup();
}

if (port_num > 0) {
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] = 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 {
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
}
}
}

return CheckPacket(cycle, sub_cycle);
}

int NetOpusAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
{
if (sub_cycle == 0) {
for (int port_index = 0; port_index < fNPorts; 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);
}
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 - CDO, fSubPeriodBytesSize);
}
return fNPorts * fSubPeriodBytesSize;
}
}

#endif

NetIntAudioBuffer::NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
: NetAudioBuffer(params, nports, net_buffer)


+ 5
- 86
common/JackNetTool.h View File

@@ -17,6 +17,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef __JackNetTool__
#define __JackNetTool__

#include "JackMidiPort.h"
#include "JackTools.h"
#include "types.h"
@@ -366,92 +369,6 @@ namespace Jack

};

#if HAVE_CELT

#include <celt/celt.h>

class SERVER_EXPORT NetCeltAudioBuffer : public NetAudioBuffer
{
private:

CELTMode** fCeltMode;
CELTEncoder** fCeltEncoder;
CELTDecoder** fCeltDecoder;

int fCompressedSizeByte;
unsigned char** fCompressedBuffer;
size_t fLastSubPeriodBytesSize;

void FreeCelt();

public:

NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps);
virtual ~NetCeltAudioBuffer();

// needed size in bytes for an entire cycle
size_t GetCycleSize();

// cycle duration in sec
float GetCycleDuration();
int GetNumPackets(int active_ports);

//jack<->buffer
int RenderFromJackPorts(int nframes);
void RenderToJackPorts(int nframes);

//network<->buffer
int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
int RenderToNetwork(int sub_cycle, uint32_t port_num);
};

#endif

#if HAVE_OPUS

#include <opus/opus.h>
#include <opus/opus_custom.h>

class SERVER_EXPORT NetOpusAudioBuffer : public NetAudioBuffer
{
private:

OpusCustomMode** fOpusMode;
OpusCustomEncoder** fOpusEncoder;
OpusCustomDecoder** fOpusDecoder;

int fCompressedMaxSizeByte;
unsigned short* fCompressedSizesByte;
size_t fLastSubPeriodBytesSize;

unsigned char** fCompressedBuffer;
void FreeOpus();

public:

NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps);
virtual ~NetOpusAudioBuffer();

// needed size in bytes for an entire cycle
size_t GetCycleSize();

// cycle duration in sec
float GetCycleDuration();
int GetNumPackets(int active_ports);

//jack<->buffer
int RenderFromJackPorts(int nframes);
void RenderToJackPorts(int nframes);

//network<->buffer
int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
int RenderToNetwork(int sub_cycle, uint32_t port_num);
};

#endif

class SERVER_EXPORT NetIntAudioBuffer : public NetAudioBuffer
{
private:
@@ -509,3 +426,5 @@ namespace Jack
SERVER_EXPORT const char* GetTransportState(int transport_state);
SERVER_EXPORT void NetTransportDataDisplay(net_transport_data_t* data);
}

#endif

+ 2
- 2
common/netjack.h View File

@@ -33,8 +33,8 @@
#endif

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

#ifdef __cplusplus


+ 2
- 2
common/netjack_packet.c View File

@@ -73,8 +73,8 @@
#endif

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

#include "netjack_packet.h"


+ 10
- 0
common/wscript View File

@@ -244,6 +244,11 @@ def build(bld):
'JackMidiWriteQueue.cpp'
]

if bld.env['CELT']:
serverlib.source += ['JackNetCelt.cpp']
if bld.env['OPUS']:
serverlib.source += ['JackNetOpus.cpp']

if bld.env['IS_LINUX']:
serverlib.source += [
'../posix/JackSocketServerChannel.cpp',
@@ -317,6 +322,11 @@ def build(bld):
'JackGlobals.cpp',
'ringbuffer.c']

if bld.env['CELT']:
netlib.source += ['JackNetCelt.cpp']
if bld.env['OPUS']:
netlib.source += ['JackNetOpus.cpp']

if bld.env['IS_LINUX']:
netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../posix/JackPosixMutex.cpp', '../linux/JackLinuxTime.c']
netlib.env.append_value("CPPFLAGS", "-fvisibility=hidden")


+ 2
- 2
example-clients/netsource.c View File

@@ -63,8 +63,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#endif

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

#include <math.h>


+ 1
- 1
linux/wscript View File

@@ -89,6 +89,6 @@ def build(bld):

create_jack_driver_obj(bld, 'netone', [ '../common/JackNetOneDriver.cpp',
'../common/netjack.c',
'../common/netjack_packet.c' ], ["SAMPLERATE", "CELT"])
'../common/netjack_packet.c' ], ["SAMPLERATE", "CELT", "OPUS"])

create_jack_driver_obj(bld, 'proxy', '../common/JackProxyDriver.cpp')

+ 17
- 12
wscript View File

@@ -187,10 +187,23 @@ class AutoOption:
"""
all_found = True

# Use-variables that should be used when checking libraries, headers and
# programs. The list will be populated when looking for packages.
use = []

# check for packages
for package,uselib_store,atleast_version in self.packages:
try:
conf.check_cfg(package=package, uselib_store=uselib_store, atleast_version=atleast_version, args='--cflags --libs')
use.append(uselib_store)
except conf.errors.ConfigurationError:
all_found = False
self.packages_not_found.append([package,atleast_version])

# check for libraries
for lib,uselib_store in self.libs:
try:
conf.check_cc(lib=lib, uselib_store=uselib_store)
conf.check_cc(lib=lib, uselib_store=uselib_store, use=use)
except conf.errors.ConfigurationError:
all_found = False
self.libs_not_found.append(lib)
@@ -198,23 +211,15 @@ class AutoOption:
# check for headers
for header in self.headers:
try:
conf.check_cc(header_name=header)
conf.check_cc(header_name=header, use=use)
except conf.errors.ConfigurationError:
all_found = False
self.headers_not_found.append(header)

# check for packages
for package,uselib_store,atleast_version in self.packages:
try:
conf.check_cfg(package=package, uselib_store=uselib_store, atleast_version=atleast_version, args='--cflags --libs')
except conf.errors.ConfigurationError:
all_found = False
self.packages_not_found.append([package,atleast_version])

# check for programs
for program,var in self.programs:
try:
conf.find_program(program, var=var)
conf.find_program(program, var=var, use=use)
except conf.errors.ConfigurationError:
all_found = False
self.programs_not_found.append(program)
@@ -428,8 +433,8 @@ def options(opt):
celt = add_auto_option(opt, 'celt', help='Build with CELT')
celt.set_check_hook(check_for_celt, check_for_celt_error)
opus = add_auto_option(opt, 'opus', help='Build Opus netjack2')
opus.add_header('opus/opus_custom.h')
opus.add_package('opus', atleast_version='0.9.0')
opus.add_header('opus_custom.h')
samplerate = add_auto_option(opt, 'samplerate', help='Build with libsamplerate')
samplerate.add_package('samplerate')
sndfile = add_auto_option(opt, 'sndfile', help='Build with libsndfile')


Loading…
Cancel
Save