From de39c62141f369fb53fff4641958ba6562e78322 Mon Sep 17 00:00:00 2001 From: Karl Linden Date: Sat, 26 Sep 2015 22:58:21 +0200 Subject: [PATCH 1/4] Check packages before anything else so use variables can be used in checks. This makes sure header checks work when the third party package is installed in a non-standard location, as long as a pkg-config file is found. --- wscript | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/wscript b/wscript index 561373df..07fe2dc3 100644 --- a/wscript +++ b/wscript @@ -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) From 15f0c485fe43537a63d6cf8b22039e0ae540f18b Mon Sep 17 00:00:00 2001 From: Karl Linden Date: Sat, 26 Sep 2015 23:01:54 +0200 Subject: [PATCH 2/4] Check for opus_custom.h instead of opus/opus_custom.h. This assures that the header can be found in a non-standard prefix, since the leading opus/ is added to the include path by the opus pkg-config file. --- wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wscript b/wscript index 07fe2dc3..9432f20c 100644 --- a/wscript +++ b/wscript @@ -433,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') From c75cc6e39873ffc4d2f57c152f8deefb8fd0c4d7 Mon Sep 17 00:00:00 2001 From: Karl Linden Date: Sat, 26 Sep 2015 23:53:39 +0200 Subject: [PATCH 3/4] Fix building with opus in non-standard prefix. This moves the opus parts of JackNetTool into JackNetOpus so opus headers are not undeliberately included from JackNetDriver (which is compiled without opus). All opus includes has got the opus/ prefix removed since it is added by the pkg-config opus file. Also the netone driver has to be compiled with opus. Lastly JackNetTool.h needed a header guard. --- common/JackNetInterface.cpp | 4 + common/JackNetOneDriver.cpp | 4 +- common/JackNetOpus.cpp | 243 ++++++++++++++++++++++++++++++++++++ common/JackNetOpus.h | 68 ++++++++++ common/JackNetTool.cpp | 222 -------------------------------- common/JackNetTool.h | 49 +------- common/netjack.h | 4 +- common/netjack_packet.c | 4 +- common/wscript | 6 + example-clients/netsource.c | 4 +- linux/wscript | 2 +- 11 files changed, 335 insertions(+), 275 deletions(-) create mode 100644 common/JackNetOpus.cpp create mode 100644 common/JackNetOpus.h diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index fdf94fa1..a1feb272 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -20,6 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackException.h" #include "JackError.h" +#if HAVE_OPUS +#include "JackNetOpus.h" +#endif + #include using namespace std; diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index a7fc083e..89dd9262 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -40,8 +40,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #endif #if HAVE_OPUS -#include -#include +#include +#include #endif #define MIN(x,y) ((x)<(y) ? (x) : (y)) diff --git a/common/JackNetOpus.cpp b/common/JackNetOpus.cpp new file mode 100644 index 00000000..1d595d23 --- /dev/null +++ b/common/JackNetOpus.cpp @@ -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; + } + } +} diff --git a/common/JackNetOpus.h b/common/JackNetOpus.h new file mode 100644 index 00000000..cc3dac44 --- /dev/null +++ b/common/JackNetOpus.h @@ -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 +#include + +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 diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 077b8cb2..8201f421 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -724,228 +724,6 @@ namespace Jack #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) { diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 33d586d2..8b1a76ac 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -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" @@ -406,50 +409,6 @@ namespace Jack int RenderToNetwork(int sub_cycle, uint32_t port_num); }; -#endif - -#if HAVE_OPUS - -#include -#include - - 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 @@ -509,3 +468,5 @@ namespace Jack SERVER_EXPORT const char* GetTransportState(int transport_state); SERVER_EXPORT void NetTransportDataDisplay(net_transport_data_t* data); } + +#endif diff --git a/common/netjack.h b/common/netjack.h index 45ebe372..b2bd1ce5 100644 --- a/common/netjack.h +++ b/common/netjack.h @@ -33,8 +33,8 @@ #endif #if HAVE_OPUS -#include -#include +#include +#include #endif #ifdef __cplusplus diff --git a/common/netjack_packet.c b/common/netjack_packet.c index cd3a8d6d..777e2f6f 100644 --- a/common/netjack_packet.c +++ b/common/netjack_packet.c @@ -73,8 +73,8 @@ #endif #if HAVE_OPUS -#include -#include +#include +#include #endif #include "netjack_packet.h" diff --git a/common/wscript b/common/wscript index fcf1d495..0c92939c 100644 --- a/common/wscript +++ b/common/wscript @@ -244,6 +244,9 @@ def build(bld): 'JackMidiWriteQueue.cpp' ] + if bld.env['OPUS']: + serverlib.source += ['JackNetOpus.cpp'] + if bld.env['IS_LINUX']: serverlib.source += [ '../posix/JackSocketServerChannel.cpp', @@ -317,6 +320,9 @@ def build(bld): 'JackGlobals.cpp', 'ringbuffer.c'] + 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") diff --git a/example-clients/netsource.c b/example-clients/netsource.c index 9386aecc..6d286e58 100644 --- a/example-clients/netsource.c +++ b/example-clients/netsource.c @@ -63,8 +63,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #endif #if HAVE_OPUS -#include -#include +#include +#include #endif #include diff --git a/linux/wscript b/linux/wscript index 968839ba..3ec6d8f9 100644 --- a/linux/wscript +++ b/linux/wscript @@ -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') From 413af62f77e259a0758d69266e027d3ee28dd366 Mon Sep 17 00:00:00 2001 From: Karl Linden Date: Sun, 27 Sep 2015 08:39:38 +0200 Subject: [PATCH 4/4] Fix building with celt in non-standard prefix. This moves the celt parts of JackNetTool into JackNetCelt so celt headers are not undeliberately included from JackNetDriver (which is compiled without celt). --- common/JackNetCelt.cpp | 268 ++++++++++++++++++++++++++++++++++++ common/JackNetCelt.h | 66 +++++++++ common/JackNetInterface.cpp | 4 + common/JackNetTool.cpp | 249 --------------------------------- common/JackNetTool.h | 42 ------ common/wscript | 4 + 6 files changed, 342 insertions(+), 291 deletions(-) create mode 100644 common/JackNetCelt.cpp create mode 100644 common/JackNetCelt.h diff --git a/common/JackNetCelt.cpp b/common/JackNetCelt.cpp new file mode 100644 index 00000000..968b2c99 --- /dev/null +++ b/common/JackNetCelt.cpp @@ -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; + } +} diff --git a/common/JackNetCelt.h b/common/JackNetCelt.h new file mode 100644 index 00000000..558f557b --- /dev/null +++ b/common/JackNetCelt.h @@ -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 + +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 diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index a1feb272..707a2443 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -20,6 +20,10 @@ 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 diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 8201f421..ab87f737 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -472,255 +472,6 @@ namespace Jack memcpy(net_buffer, fPortBuffer[active_port] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize - sizeof(int)); } -#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 diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 8b1a76ac..c0aef595 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -369,48 +369,6 @@ namespace Jack }; -#if HAVE_CELT - -#include - - 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 - class SERVER_EXPORT NetIntAudioBuffer : public NetAudioBuffer { private: diff --git a/common/wscript b/common/wscript index 0c92939c..b092ade1 100644 --- a/common/wscript +++ b/common/wscript @@ -244,6 +244,8 @@ def build(bld): 'JackMidiWriteQueue.cpp' ] + if bld.env['CELT']: + serverlib.source += ['JackNetCelt.cpp'] if bld.env['OPUS']: serverlib.source += ['JackNetOpus.cpp'] @@ -320,6 +322,8 @@ def build(bld): 'JackGlobals.cpp', 'ringbuffer.c'] + if bld.env['CELT']: + netlib.source += ['JackNetCelt.cpp'] if bld.env['OPUS']: netlib.source += ['JackNetOpus.cpp']