From 38f4e9ffcb31183ab168479d0f729bf65c83fdb2 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Sat, 9 Oct 2010 21:13:22 -0400 Subject: Renamed to Harmony Also a CELT update --- src/Makefile.am | 12 +-- src/framepack.c | 2 +- src/harmony.h | 102 +++++++++++++++++++ src/harmony_decoder.c | 212 +++++++++++++++++++++++++++++++++++++++ src/harmony_decoder.h | 51 ++++++++++ src/harmony_encoder.c | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/harmony_encoder.h | 58 +++++++++++ src/hybrid.h | 102 ------------------- src/hybrid_decoder.c | 212 --------------------------------------- src/hybrid_decoder.h | 51 ---------- src/hybrid_encoder.c | 270 -------------------------------------------------- src/hybrid_encoder.h | 58 ----------- src/test_harmony.c | 160 ++++++++++++++++++++++++++++++ src/test_hybrid.c | 160 ------------------------------ 14 files changed, 860 insertions(+), 860 deletions(-) create mode 100644 src/harmony.h create mode 100644 src/harmony_decoder.c create mode 100644 src/harmony_decoder.h create mode 100644 src/harmony_encoder.c create mode 100644 src/harmony_encoder.h delete mode 100644 src/hybrid.h delete mode 100644 src/hybrid_decoder.c delete mode 100644 src/hybrid_decoder.h delete mode 100644 src/hybrid_encoder.c delete mode 100644 src/hybrid_encoder.h create mode 100644 src/test_harmony.c delete mode 100644 src/test_hybrid.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 130fc361..f3f02400 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,12 +2,12 @@ INCLUDES = -I$(top_srcdir)/celt/libcelt/ -I$(top_srcdir)/silk/interface lib_LTLIBRARIES = libietfcodec.la -libietfcodec_la_SOURCES = hybrid_decoder.c hybrid_encoder.c +libietfcodec_la_SOURCES = harmony_decoder.c harmony_encoder.c -noinst_HEADERS = hybrid_decoder.h hybrid_encoder.h +noinst_HEADERS = harmony_decoder.h harmony_encoder.h -pkginclude_HEADERS = hybrid.h +pkginclude_HEADERS = harmony.h -noinst_PROGRAMS = test_hybrid -test_hybrid_SOURCES = test_hybrid.c $(top_srcdir)/silk/test/SKP_debug.c -test_hybrid_LDADD = libietfcodec.la $(top_builddir)/celt/libcelt/libcelt0.la $(top_builddir)/silk/libSKP_SILK_SDK.la +noinst_PROGRAMS = test_harmony +test_harmony_SOURCES = test_harmony.c $(top_srcdir)/silk/test/SKP_debug.c +test_harmony_LDADD = libietfcodec.la $(top_builddir)/celt/libcelt/libcelt0.la $(top_builddir)/silk/libSKP_SILK_SDK.la diff --git a/src/framepack.c b/src/framepack.c index 99434355..c7a84c0e 100644 --- a/src/framepack.c +++ b/src/framepack.c @@ -100,7 +100,7 @@ int count_frames(unsigned char *packet, int len) } #define MAX_FRAMES 256 -int hybrid_merge_packets(unsigned char **packets, int *plen, int nb_packets, +int harmony_merge_packets(unsigned char **packets, int *plen, int nb_packets, unsigned *output, int maxlen) { int i; diff --git a/src/harmony.h b/src/harmony.h new file mode 100644 index 00000000..ed8d1f34 --- /dev/null +++ b/src/harmony.h @@ -0,0 +1,102 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef HARMONY_H +#define HARMONY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) && defined(CELT_BUILD) +#define EXPORT __attribute__ ((visibility ("default"))) +#elif defined(WIN32) +#define EXPORT __declspec(dllexport) +#else +#define EXPORT +#endif + +#define __check_int(x) (((void)((x) == (int)0)), (int)(x)) +#define __check_int_ptr(ptr) ((ptr) + ((ptr) - (int*)(ptr))) + +#define MODE_SILK_ONLY 1000 +#define MODE_HYBRID 1001 +#define MODE_CELT_ONLY 1002 + +#define BANDWIDTH_NARROWBAND 1100 +#define BANDWIDTH_MEDIUMBAND 1101 +#define BANDWIDTH_WIDEBAND 1102 +#define BANDWIDTH_SUPERWIDEBAND 1103 +#define BANDWIDTH_FULLBAND 1104 + + + +#define HARMONY_SET_MODE_REQUEST 0 +#define HARMONY_SET_MODE(x) HARMONY_SET_MODE_REQUEST, __check_int(x) +#define HARMONY_GET_MODE_REQUEST 1 +#define HARMONY_GET_MODE(x) HARMONY_GET_MODE_REQUEST, __check_int_ptr(x) + +#define HARMONY_SET_BANDWIDTH_REQUEST 2 +#define HARMONY_SET_BANDWIDTH(x) HARMONY_SET_BANDWIDTH_REQUEST, __check_int(x) +#define HARMONY_GET_BANDWIDTH_REQUEST 3 +#define HARMONY_GET_BANDWIDTH(x) HARMONY_GET_BANDWIDTH_REQUEST, __check_int_ptr(x) + +#define HARMONY_SET_VBR_RATE_REQUEST 4 +#define HARMONY_SET_VBR_RATE(x) HARMONY_SET_VBR_RATE_REQUEST, __check_int(x) +#define HARMONY_GET_VBR_RATE_REQUEST 5 +#define HARMONY_GET_VBR_RATE(x) HARMONY_GET_VBR_RATE_REQUEST, __check_int_ptr(x) + +typedef struct HarmonyEncoder HarmonyEncoder; +typedef struct HarmonyDecoder HarmonyDecoder; + +HarmonyEncoder *harmony_encoder_create(int Fs); + +int harmony_encode(HarmonyEncoder *st, const short *pcm, int frame_size, + unsigned char *data, int bytes_per_packet); + +void harmony_encoder_destroy(HarmonyEncoder *st); + +void harmony_encoder_ctl(HarmonyEncoder *st, int request, ...); + +HarmonyDecoder *harmony_decoder_create(int Fs); + +int harmony_decode(HarmonyDecoder *st, const unsigned char *data, int len, + short *pcm, int frame_size); + +void harmony_decoder_ctl(HarmonyDecoder *st, int request, ...); + +void harmony_decoder_destroy(HarmonyDecoder *st); + +#ifdef __cplusplus +} +#endif + +#endif /* HARMONY_H */ diff --git a/src/harmony_decoder.c b/src/harmony_decoder.c new file mode 100644 index 00000000..7177d60e --- /dev/null +++ b/src/harmony_decoder.c @@ -0,0 +1,212 @@ +/* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include "harmony_decoder.h" +#include "entdec.h" +#include "modes.h" +#include "SKP_Silk_SDK_API.h" + + +HarmonyDecoder *harmony_decoder_create(int Fs) +{ + char *raw_state; + int ret, silkDecSizeBytes, celtDecSizeBytes; + CELTMode *celtMode; + HarmonyDecoder *st; + + /* We should not have to create a CELT mode for each encoder state */ + celtMode = celt_mode_create(Fs, Fs/50, NULL); + + /* Initialize SILK encoder */ + ret = SKP_Silk_SDK_Get_Decoder_Size( &silkDecSizeBytes ); + if( ret ) { + /* Handle error */ + } + celtDecSizeBytes = celt_decoder_get_size(celtMode, 1); + raw_state = calloc(sizeof(HarmonyDecoder)+silkDecSizeBytes+celtDecSizeBytes, 1); + st = (HarmonyDecoder*)raw_state; + st->silk_dec = (void*)(raw_state+sizeof(HarmonyDecoder)); + st->celt_dec = (CELTDecoder*)(raw_state+sizeof(HarmonyDecoder)+silkDecSizeBytes); + + st->Fs = Fs; + st->celt_mode = celtMode; + + /* Reset decoder */ + ret = SKP_Silk_SDK_InitDecoder( st->silk_dec ); + if( ret ) { + /* Handle error */ + } + + /* Initialize CELT decoder */ + st->celt_dec = celt_decoder_init(st->celt_dec, st->celt_mode, 1, NULL); + + return st; + +} +int harmony_decode(HarmonyDecoder *st, const unsigned char *data, + int len, short *pcm, int frame_size) +{ + int i, silk_ret=0, celt_ret=0; + ec_dec dec; + ec_byte_buffer buf; + SKP_SILK_SDK_DecControlStruct DecControl; + SKP_int16 silk_frame_size; + short pcm_celt[960]; + int audiosize; + + if (data != NULL) + { + /* Decoding mode/bandwidth/framesize from first byte */ + if (data[0]&0x80) + { + st->mode = MODE_CELT_ONLY; + st->bandwidth = BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3); + if (st->bandwidth == BANDWIDTH_MEDIUMBAND) + st->bandwidth = BANDWIDTH_NARROWBAND; + audiosize = ((data[0]>>3)&0x3); + audiosize = (st->Fs<mode = MODE_HYBRID; + st->bandwidth = (data[0]&0x10) ? BANDWIDTH_FULLBAND : BANDWIDTH_SUPERWIDEBAND; + audiosize = (data[0]&0x08) ? st->Fs/50 : st->Fs/100; + } else { + + st->mode = MODE_SILK_ONLY; + st->bandwidth = BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); + audiosize = ((data[0]>>3)&0x3); + if (audiosize == 3) + audiosize = st->Fs*60/1000; + else + audiosize = (st->Fs<mode, st->bandwidth, audiosize);*/ + + len -= 1; + data += 1; + ec_byte_readinit(&buf,(unsigned char*)data,len); + ec_dec_init(&dec,&buf); + } + + if (st->mode != MODE_CELT_ONLY) + { + DecControl.API_sampleRate = st->Fs; + + /* We Should eventually have to set the bandwidth here */ + + /* Call SILK encoder for the low band */ + silk_ret = SKP_Silk_SDK_Decode( st->silk_dec, &DecControl, data == NULL, &dec, len, pcm, &silk_frame_size ); + if (silk_ret) + { + fprintf (stderr, "SILK decode error\n"); + /* Handle error */ + } + } else { + for (i=0;imode == MODE_HYBRID) + { + /* This should be adjusted based on the SILK bandwidth */ + celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(17)); + } else { + celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(0)); + } + + if (st->mode != MODE_SILK_ONLY && st->bandwidth > BANDWIDTH_WIDEBAND) + { + if (st->bandwidth == BANDWIDTH_SUPERWIDEBAND) + celt_decoder_ctl(st->celt_dec, CELT_SET_END_BAND(20)); + else + celt_decoder_ctl(st->celt_dec, CELT_SET_END_BAND(21)); + /* Encode high band with CELT */ + celt_ret = celt_decode_with_ec(st->celt_dec, data, len, pcm_celt, frame_size, &dec); + for (i=0;imode = value; + } + break; + case HARMONY_GET_MODE_REQUEST: + { + int *value = va_arg(ap, int*); + *value = st->mode; + } + break; + case HARMONY_SET_BANDWIDTH_REQUEST: + { + int value = va_arg(ap, int); + st->bandwidth = value; + } + break; + case HARMONY_GET_BANDWIDTH_REQUEST: + { + int *value = va_arg(ap, int*); + *value = st->bandwidth; + } + break; + default: + fprintf(stderr, "unknown harmony_decoder_ctl() request: %d", request); + break; + } + + va_end(ap); +} + +void harmony_decoder_destroy(HarmonyDecoder *st) +{ + celt_mode_destroy(st->celt_mode); + + free(st); +} diff --git a/src/harmony_decoder.h b/src/harmony_decoder.h new file mode 100644 index 00000000..18f5c9ec --- /dev/null +++ b/src/harmony_decoder.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef HARMONY_DECODER_H +#define HARMONY_DECODER_H + +#include "celt.h" +#include "harmony.h" + +struct HarmonyDecoder { + CELTMode *celt_mode; + CELTDecoder *celt_dec; + void *silk_dec; + + int mode; + int bandwidth; + /* Sampling rate (at the API level) */ + int Fs; +}; + + +#endif /* HARMONY_DECODER_H */ + diff --git a/src/harmony_encoder.c b/src/harmony_encoder.c new file mode 100644 index 00000000..569eb7a3 --- /dev/null +++ b/src/harmony_encoder.c @@ -0,0 +1,270 @@ +/* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include "harmony_encoder.h" +#include "entenc.h" +#include "modes.h" +#include "SKP_Silk_SDK_API.h" + +HarmonyEncoder *harmony_encoder_create(int Fs) +{ + char *raw_state; + CELTMode *celtMode; + HarmonyEncoder *st; + int ret, silkEncSizeBytes, celtEncSizeBytes; + SKP_SILK_SDK_EncControlStruct encControl; + + /* We should not have to create a CELT mode for each encoder state */ + celtMode = celt_mode_create(Fs, Fs/50, NULL); + + /* Create SILK encoder */ + ret = SKP_Silk_SDK_Get_Encoder_Size( &silkEncSizeBytes ); + if( ret ) { + /* Handle error */ + } + celtEncSizeBytes = celt_encoder_get_size(celtMode, 1); + raw_state = calloc(sizeof(HarmonyEncoder)+silkEncSizeBytes+celtEncSizeBytes, 1); + st = (HarmonyEncoder*)raw_state; + st->silk_enc = (void*)(raw_state+sizeof(HarmonyEncoder)); + st->celt_enc = (CELTEncoder*)(raw_state+sizeof(HarmonyEncoder)+silkEncSizeBytes); + + st->Fs = Fs; + st->celt_mode = celtMode; + + /*encControl.API_sampleRate = st->Fs; + encControl.packetLossPercentage = 0; + encControl.useInBandFEC = 0; + encControl.useDTX = 0; + encControl.complexity = 2;*/ + ret = SKP_Silk_SDK_InitEncoder( st->silk_enc, &encControl ); + if( ret ) { + /* Handle error */ + } + + /* Create CELT encoder */ + /* Initialize CELT encoder */ + st->celt_enc = celt_encoder_init(st->celt_enc, st->celt_mode, 1, NULL); + + st->mode = MODE_HYBRID; + st->bandwidth = BANDWIDTH_FULLBAND; + st->vbr_rate = 0; + + return st; +} + +int harmony_encode(HarmonyEncoder *st, const short *pcm, int frame_size, + unsigned char *data, int bytes_per_packet) +{ + int i; + int ret=0; + SKP_int16 nBytes; + ec_enc enc; + ec_byte_buffer buf; + SKP_SILK_SDK_EncControlStruct encControl; + int framerate, period; + + bytes_per_packet -= 1; + data += 1; + ec_byte_writeinit_buffer(&buf, data, bytes_per_packet); + ec_enc_init(&enc,&buf); + + if (st->mode != MODE_CELT_ONLY) + { + /* Set Encoder parameters */ + encControl.API_sampleRate = st->Fs; + encControl.packetLossPercentage = 2; + encControl.useInBandFEC = 0; + encControl.useDTX = 0; + encControl.complexity = 2; + + if (st->vbr_rate != 0) + encControl.bitRate = (st->vbr_rate+6000)/2; + else { + encControl.bitRate = (bytes_per_packet*8*(celt_int32)st->Fs/frame_size+6000)/2; + if (st->Fs == 100 * frame_size) + encControl.bitRate -= 5000; + } + encControl.packetSize = frame_size; + + if (st->bandwidth == BANDWIDTH_NARROWBAND) + encControl.maxInternalSampleRate = 8000; + else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) + encControl.maxInternalSampleRate = 12000; + else + encControl.maxInternalSampleRate = 16000; + + /* Call SILK encoder for the low band */ + nBytes = bytes_per_packet; + ret = SKP_Silk_SDK_Encode( st->silk_enc, &encControl, pcm, frame_size, &enc, &nBytes ); + if( ret ) { + fprintf (stderr, "SILK encode error\n"); + /* Handle error */ + } + ret = (ec_enc_tell(&enc, 0)+7)>>3; + } + + if (st->mode == MODE_HYBRID) + { + /* This should be adjusted based on the SILK bandwidth */ + celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(17)); + } else { + celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0)); + } + + if (st->mode != MODE_SILK_ONLY && st->bandwidth > BANDWIDTH_WIDEBAND) + { + short pcm_buf[960]; + + if (st->bandwidth == BANDWIDTH_SUPERWIDEBAND) + celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(20)); + else + celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(21)); + + for (i=0;idelay_buffer[i]; + for (;icelt_enc, CELT_SET_PREDICTION(1)); + + if (st->vbr_rate != 0) + { + int tmp = (st->vbr_rate-6000)/2; + tmp = ((ec_enc_tell(&enc, 0)+4)>>3) + tmp * frame_size/(8*st->Fs); + if (tmp <= bytes_per_packet) + bytes_per_packet = tmp; + ec_byte_shrink(&buf, bytes_per_packet); + } + /* Encode high band with CELT */ + ret = celt_encode_with_ec(st->celt_enc, pcm_buf, NULL, frame_size, NULL, bytes_per_packet, &enc); + for (i=0;idelay_buffer[i] = pcm[frame_size-ENCODER_DELAY_COMPENSATION+i]; + } else { + ec_enc_done(&enc); + } + + /* Signalling the mode in the first byte */ + data--; + framerate = st->Fs/frame_size; + period = 0; + while (framerate < 400) + { + framerate <<= 1; + period++; + } + if (st->mode == MODE_SILK_ONLY) + { + data[0] = (st->bandwidth-BANDWIDTH_NARROWBAND)<<5; + data[0] |= (period-2)<<3; + } else if (st->mode == MODE_CELT_ONLY) + { + int tmp = st->bandwidth-BANDWIDTH_MEDIUMBAND; + if (tmp < 0) + tmp = 0; + data[0] = 0x80; + data[0] |= tmp << 5; + data[0] |= period<<3; + } else /* Harmony */ + { + data[0] = 0x60; + data[0] |= (st->bandwidth-BANDWIDTH_SUPERWIDEBAND)<<4; + data[0] |= (period-2)<<3; + } + /*printf ("%x\n", (int)data[0]);*/ + + return ret+1; +} + +void harmony_encoder_ctl(HarmonyEncoder *st, int request, ...) +{ + va_list ap; + + va_start(ap, request); + + switch (request) + { + case HARMONY_SET_MODE_REQUEST: + { + int value = va_arg(ap, int); + st->mode = value; + } + break; + case HARMONY_GET_MODE_REQUEST: + { + int *value = va_arg(ap, int*); + *value = st->mode; + } + break; + case HARMONY_SET_BANDWIDTH_REQUEST: + { + int value = va_arg(ap, int); + st->bandwidth = value; + } + break; + case HARMONY_GET_BANDWIDTH_REQUEST: + { + int *value = va_arg(ap, int*); + *value = st->bandwidth; + } + break; + case HARMONY_SET_VBR_RATE_REQUEST: + { + int value = va_arg(ap, int); + st->vbr_rate = value; + } + break; + case HARMONY_GET_VBR_RATE_REQUEST: + { + int *value = va_arg(ap, int*); + *value = st->vbr_rate; + } + break; + default: + fprintf(stderr, "unknown harmony_encoder_ctl() request: %d", request); + break; + } + + va_end(ap); +} + +void harmony_encoder_destroy(HarmonyEncoder *st) +{ + celt_mode_destroy(st->celt_mode); + free(st); +} + diff --git a/src/harmony_encoder.h b/src/harmony_encoder.h new file mode 100644 index 00000000..045d2733 --- /dev/null +++ b/src/harmony_encoder.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef HARMONY_ENCODER_H +#define HARMONY_ENCODER_H + +#include "celt.h" +#include "harmony.h" +#include "SKP_Silk_SDK_API.h" + +/* FIXME: This is only valid for 48 kHz */ +#define ENCODER_DELAY_COMPENSATION 130 + +struct HarmonyEncoder { + CELTMode *celt_mode; + CELTEncoder *celt_enc; + void *silk_enc; + + int mode; + int bandwidth; + int vbr_rate; + /* Sampling rate (at the API level) */ + int Fs; + + short delay_buffer[ENCODER_DELAY_COMPENSATION]; +}; + + +#endif /* HARMONY_ENCODER_H */ + diff --git a/src/hybrid.h b/src/hybrid.h deleted file mode 100644 index 541fca16..00000000 --- a/src/hybrid.h +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright (c) 2010 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef HYBRID_H -#define HYBRID_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__GNUC__) && defined(CELT_BUILD) -#define EXPORT __attribute__ ((visibility ("default"))) -#elif defined(WIN32) -#define EXPORT __declspec(dllexport) -#else -#define EXPORT -#endif - -#define __check_int(x) (((void)((x) == (int)0)), (int)(x)) -#define __check_int_ptr(ptr) ((ptr) + ((ptr) - (int*)(ptr))) - -#define MODE_SILK_ONLY 1000 -#define MODE_HYBRID 1001 -#define MODE_CELT_ONLY 1002 - -#define BANDWIDTH_NARROWBAND 1100 -#define BANDWIDTH_MEDIUMBAND 1101 -#define BANDWIDTH_WIDEBAND 1102 -#define BANDWIDTH_SUPERWIDEBAND 1103 -#define BANDWIDTH_FULLBAND 1104 - - - -#define HYBRID_SET_MODE_REQUEST 0 -#define HYBRID_SET_MODE(x) HYBRID_SET_MODE_REQUEST, __check_int(x) -#define HYBRID_GET_MODE_REQUEST 1 -#define HYBRID_GET_MODE(x) HYBRID_GET_MODE_REQUEST, __check_int_ptr(x) - -#define HYBRID_SET_BANDWIDTH_REQUEST 2 -#define HYBRID_SET_BANDWIDTH(x) HYBRID_SET_BANDWIDTH_REQUEST, __check_int(x) -#define HYBRID_GET_BANDWIDTH_REQUEST 3 -#define HYBRID_GET_BANDWIDTH(x) HYBRID_GET_BANDWIDTH_REQUEST, __check_int_ptr(x) - -#define HYBRID_SET_VBR_RATE_REQUEST 4 -#define HYBRID_SET_VBR_RATE(x) HYBRID_SET_VBR_RATE_REQUEST, __check_int(x) -#define HYBRID_GET_VBR_RATE_REQUEST 5 -#define HYBRID_GET_VBR_RATE(x) HYBRID_GET_VBR_RATE_REQUEST, __check_int_ptr(x) - -typedef struct HybridEncoder HybridEncoder; -typedef struct HybridDecoder HybridDecoder; - -HybridEncoder *hybrid_encoder_create(int Fs); - -int hybrid_encode(HybridEncoder *st, const short *pcm, int frame_size, - unsigned char *data, int bytes_per_packet); - -void hybrid_encoder_destroy(HybridEncoder *st); - -void hybrid_encoder_ctl(HybridEncoder *st, int request, ...); - -HybridDecoder *hybrid_decoder_create(int Fs); - -int hybrid_decode(HybridDecoder *st, const unsigned char *data, int len, - short *pcm, int frame_size); - -void hybrid_decoder_ctl(HybridDecoder *st, int request, ...); - -void hybrid_decoder_destroy(HybridDecoder *st); - -#ifdef __cplusplus -} -#endif - -#endif /* HYBRID_H */ diff --git a/src/hybrid_decoder.c b/src/hybrid_decoder.c deleted file mode 100644 index e0957017..00000000 --- a/src/hybrid_decoder.c +++ /dev/null @@ -1,212 +0,0 @@ -/* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited - Written by Jean-Marc Valin and Koen Vos */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include "hybrid_decoder.h" -#include "entdec.h" -#include "modes.h" -#include "SKP_Silk_SDK_API.h" - - -HybridDecoder *hybrid_decoder_create(int Fs) -{ - char *raw_state; - int ret, silkDecSizeBytes, celtDecSizeBytes; - CELTMode *celtMode; - HybridDecoder *st; - - /* We should not have to create a CELT mode for each encoder state */ - celtMode = celt_mode_create(Fs, Fs/50, NULL); - - /* Initialize SILK encoder */ - ret = SKP_Silk_SDK_Get_Decoder_Size( &silkDecSizeBytes ); - if( ret ) { - /* Handle error */ - } - celtDecSizeBytes = celt_decoder_get_size(celtMode, 1); - raw_state = calloc(sizeof(HybridDecoder)+silkDecSizeBytes+celtDecSizeBytes, 1); - st = (HybridDecoder*)raw_state; - st->silk_dec = (void*)(raw_state+sizeof(HybridDecoder)); - st->celt_dec = (CELTDecoder*)(raw_state+sizeof(HybridDecoder)+silkDecSizeBytes); - - st->Fs = Fs; - st->celt_mode = celtMode; - - /* Reset decoder */ - ret = SKP_Silk_SDK_InitDecoder( st->silk_dec ); - if( ret ) { - /* Handle error */ - } - - /* Initialize CELT decoder */ - st->celt_dec = celt_decoder_init(st->celt_dec, st->celt_mode, 1, NULL); - - return st; - -} -int hybrid_decode(HybridDecoder *st, const unsigned char *data, - int len, short *pcm, int frame_size) -{ - int i, silk_ret=0, celt_ret=0; - ec_dec dec; - ec_byte_buffer buf; - SKP_SILK_SDK_DecControlStruct DecControl; - SKP_int16 silk_frame_size; - short pcm_celt[960]; - int audiosize; - - if (data != NULL) - { - /* Decoding mode/bandwidth/framesize from first byte */ - if (data[0]&0x80) - { - st->mode = MODE_CELT_ONLY; - st->bandwidth = BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3); - if (st->bandwidth == BANDWIDTH_MEDIUMBAND) - st->bandwidth = BANDWIDTH_NARROWBAND; - audiosize = ((data[0]>>3)&0x3); - audiosize = (st->Fs<mode = MODE_HYBRID; - st->bandwidth = (data[0]&0x10) ? BANDWIDTH_FULLBAND : BANDWIDTH_SUPERWIDEBAND; - audiosize = (data[0]&0x08) ? st->Fs/50 : st->Fs/100; - } else { - - st->mode = MODE_SILK_ONLY; - st->bandwidth = BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); - audiosize = ((data[0]>>3)&0x3); - if (audiosize == 3) - audiosize = st->Fs*60/1000; - else - audiosize = (st->Fs<mode, st->bandwidth, audiosize);*/ - - len -= 1; - data += 1; - ec_byte_readinit(&buf,(unsigned char*)data,len); - ec_dec_init(&dec,&buf); - } - - if (st->mode != MODE_CELT_ONLY) - { - DecControl.API_sampleRate = st->Fs; - - /* We Should eventually have to set the bandwidth here */ - - /* Call SILK encoder for the low band */ - silk_ret = SKP_Silk_SDK_Decode( st->silk_dec, &DecControl, data == NULL, &dec, len, pcm, &silk_frame_size ); - if (silk_ret) - { - fprintf (stderr, "SILK decode error\n"); - /* Handle error */ - } - } else { - for (i=0;imode == MODE_HYBRID) - { - /* This should be adjusted based on the SILK bandwidth */ - celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(17)); - } else { - celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(0)); - } - - if (st->mode != MODE_SILK_ONLY && st->bandwidth > BANDWIDTH_WIDEBAND) - { - if (st->bandwidth == BANDWIDTH_SUPERWIDEBAND) - celt_decoder_ctl(st->celt_dec, CELT_SET_END_BAND(20)); - else - celt_decoder_ctl(st->celt_dec, CELT_SET_END_BAND(21)); - /* Encode high band with CELT */ - celt_ret = celt_decode_with_ec(st->celt_dec, data, len, pcm_celt, frame_size, &dec); - for (i=0;imode = value; - } - break; - case HYBRID_GET_MODE_REQUEST: - { - int *value = va_arg(ap, int*); - *value = st->mode; - } - break; - case HYBRID_SET_BANDWIDTH_REQUEST: - { - int value = va_arg(ap, int); - st->bandwidth = value; - } - break; - case HYBRID_GET_BANDWIDTH_REQUEST: - { - int *value = va_arg(ap, int*); - *value = st->bandwidth; - } - break; - default: - fprintf(stderr, "unknown hybrid_decoder_ctl() request: %d", request); - break; - } - - va_end(ap); -} - -void hybrid_decoder_destroy(HybridDecoder *st) -{ - celt_mode_destroy(st->celt_mode); - - free(st); -} diff --git a/src/hybrid_decoder.h b/src/hybrid_decoder.h deleted file mode 100644 index b5a54fb5..00000000 --- a/src/hybrid_decoder.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2010 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef HYBRID_DECODER_H -#define HYBRID_DECODER_H - -#include "celt.h" -#include "hybrid.h" - -struct HybridDecoder { - CELTMode *celt_mode; - CELTDecoder *celt_dec; - void *silk_dec; - - int mode; - int bandwidth; - /* Sampling rate (at the API level) */ - int Fs; -}; - - -#endif /* HYBRID_DECODER_H */ - diff --git a/src/hybrid_encoder.c b/src/hybrid_encoder.c deleted file mode 100644 index d931f079..00000000 --- a/src/hybrid_encoder.c +++ /dev/null @@ -1,270 +0,0 @@ -/* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited - Written by Jean-Marc Valin and Koen Vos */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include "hybrid_encoder.h" -#include "entenc.h" -#include "modes.h" -#include "SKP_Silk_SDK_API.h" - -HybridEncoder *hybrid_encoder_create(int Fs) -{ - char *raw_state; - CELTMode *celtMode; - HybridEncoder *st; - int ret, silkEncSizeBytes, celtEncSizeBytes; - SKP_SILK_SDK_EncControlStruct encControl; - - /* We should not have to create a CELT mode for each encoder state */ - celtMode = celt_mode_create(Fs, Fs/50, NULL); - - /* Create SILK encoder */ - ret = SKP_Silk_SDK_Get_Encoder_Size( &silkEncSizeBytes ); - if( ret ) { - /* Handle error */ - } - celtEncSizeBytes = celt_encoder_get_size(celtMode, 1); - raw_state = calloc(sizeof(HybridEncoder)+silkEncSizeBytes+celtEncSizeBytes, 1); - st = (HybridEncoder*)raw_state; - st->silk_enc = (void*)(raw_state+sizeof(HybridEncoder)); - st->celt_enc = (CELTEncoder*)(raw_state+sizeof(HybridEncoder)+silkEncSizeBytes); - - st->Fs = Fs; - st->celt_mode = celtMode; - - /*encControl.API_sampleRate = st->Fs; - encControl.packetLossPercentage = 0; - encControl.useInBandFEC = 0; - encControl.useDTX = 0; - encControl.complexity = 2;*/ - ret = SKP_Silk_SDK_InitEncoder( st->silk_enc, &encControl ); - if( ret ) { - /* Handle error */ - } - - /* Create CELT encoder */ - /* Initialize CELT encoder */ - st->celt_enc = celt_encoder_init(st->celt_enc, st->celt_mode, 1, NULL); - - st->mode = MODE_HYBRID; - st->bandwidth = BANDWIDTH_FULLBAND; - st->vbr_rate = 0; - - return st; -} - -int hybrid_encode(HybridEncoder *st, const short *pcm, int frame_size, - unsigned char *data, int bytes_per_packet) -{ - int i; - int ret=0; - SKP_int16 nBytes; - ec_enc enc; - ec_byte_buffer buf; - SKP_SILK_SDK_EncControlStruct encControl; - int framerate, period; - - bytes_per_packet -= 1; - data += 1; - ec_byte_writeinit_buffer(&buf, data, bytes_per_packet); - ec_enc_init(&enc,&buf); - - if (st->mode != MODE_CELT_ONLY) - { - /* Set Encoder parameters */ - encControl.API_sampleRate = st->Fs; - encControl.packetLossPercentage = 2; - encControl.useInBandFEC = 0; - encControl.useDTX = 0; - encControl.complexity = 2; - - if (st->vbr_rate != 0) - encControl.bitRate = (st->vbr_rate+6000)/2; - else { - encControl.bitRate = (bytes_per_packet*8*(celt_int32)st->Fs/frame_size+6000)/2; - if (st->Fs == 100 * frame_size) - encControl.bitRate -= 5000; - } - encControl.packetSize = frame_size; - - if (st->bandwidth == BANDWIDTH_NARROWBAND) - encControl.maxInternalSampleRate = 8000; - else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) - encControl.maxInternalSampleRate = 12000; - else - encControl.maxInternalSampleRate = 16000; - - /* Call SILK encoder for the low band */ - nBytes = bytes_per_packet; - ret = SKP_Silk_SDK_Encode( st->silk_enc, &encControl, pcm, frame_size, &enc, &nBytes ); - if( ret ) { - fprintf (stderr, "SILK encode error\n"); - /* Handle error */ - } - ret = (ec_enc_tell(&enc, 0)+7)>>3; - } - - if (st->mode == MODE_HYBRID) - { - /* This should be adjusted based on the SILK bandwidth */ - celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(17)); - } else { - celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0)); - } - - if (st->mode != MODE_SILK_ONLY && st->bandwidth > BANDWIDTH_WIDEBAND) - { - short pcm_buf[960]; - - if (st->bandwidth == BANDWIDTH_SUPERWIDEBAND) - celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(20)); - else - celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(21)); - - for (i=0;idelay_buffer[i]; - for (;icelt_enc, CELT_SET_PREDICTION(1)); - - if (st->vbr_rate != 0) - { - int tmp = (st->vbr_rate-6000)/2; - tmp = ((ec_enc_tell(&enc, 0)+4)>>3) + tmp * frame_size/(8*st->Fs); - if (tmp <= bytes_per_packet) - bytes_per_packet = tmp; - ec_byte_shrink(&buf, bytes_per_packet); - } - /* Encode high band with CELT */ - ret = celt_encode_with_ec(st->celt_enc, pcm_buf, NULL, frame_size, NULL, bytes_per_packet, &enc); - for (i=0;idelay_buffer[i] = pcm[frame_size-ENCODER_DELAY_COMPENSATION+i]; - } else { - ec_enc_done(&enc); - } - - /* Signalling the mode in the first byte */ - data--; - framerate = st->Fs/frame_size; - period = 0; - while (framerate < 400) - { - framerate <<= 1; - period++; - } - if (st->mode == MODE_SILK_ONLY) - { - data[0] = (st->bandwidth-BANDWIDTH_NARROWBAND)<<5; - data[0] |= (period-2)<<3; - } else if (st->mode == MODE_CELT_ONLY) - { - int tmp = st->bandwidth-BANDWIDTH_MEDIUMBAND; - if (tmp < 0) - tmp = 0; - data[0] = 0x80; - data[0] |= tmp << 5; - data[0] |= period<<3; - } else /* Hybrid */ - { - data[0] = 0x60; - data[0] |= (st->bandwidth-BANDWIDTH_SUPERWIDEBAND)<<4; - data[0] |= (period-2)<<3; - } - /*printf ("%x\n", (int)data[0]);*/ - - return ret+1; -} - -void hybrid_encoder_ctl(HybridEncoder *st, int request, ...) -{ - va_list ap; - - va_start(ap, request); - - switch (request) - { - case HYBRID_SET_MODE_REQUEST: - { - int value = va_arg(ap, int); - st->mode = value; - } - break; - case HYBRID_GET_MODE_REQUEST: - { - int *value = va_arg(ap, int*); - *value = st->mode; - } - break; - case HYBRID_SET_BANDWIDTH_REQUEST: - { - int value = va_arg(ap, int); - st->bandwidth = value; - } - break; - case HYBRID_GET_BANDWIDTH_REQUEST: - { - int *value = va_arg(ap, int*); - *value = st->bandwidth; - } - break; - case HYBRID_SET_VBR_RATE_REQUEST: - { - int value = va_arg(ap, int); - st->vbr_rate = value; - } - break; - case HYBRID_GET_VBR_RATE_REQUEST: - { - int *value = va_arg(ap, int*); - *value = st->vbr_rate; - } - break; - default: - fprintf(stderr, "unknown hybrid_encoder_ctl() request: %d", request); - break; - } - - va_end(ap); -} - -void hybrid_encoder_destroy(HybridEncoder *st) -{ - celt_mode_destroy(st->celt_mode); - free(st); -} - diff --git a/src/hybrid_encoder.h b/src/hybrid_encoder.h deleted file mode 100644 index adb5f1df..00000000 --- a/src/hybrid_encoder.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 2010 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef HYBRID_ENCODER_H -#define HYBRID_ENCODER_H - -#include "celt.h" -#include "hybrid.h" -#include "SKP_Silk_SDK_API.h" - -/* FIXME: This is only valid for 48 kHz */ -#define ENCODER_DELAY_COMPENSATION 130 - -struct HybridEncoder { - CELTMode *celt_mode; - CELTEncoder *celt_enc; - void *silk_enc; - - int mode; - int bandwidth; - int vbr_rate; - /* Sampling rate (at the API level) */ - int Fs; - - short delay_buffer[ENCODER_DELAY_COMPENSATION]; -}; - - -#endif /* HYBRID_ENCODER_H */ - diff --git a/src/test_harmony.c b/src/test_harmony.c new file mode 100644 index 00000000..6c873ce7 --- /dev/null +++ b/src/test_harmony.c @@ -0,0 +1,160 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include "harmony.h" + + +#define MAX_PACKET 1024 + +int main(int argc, char *argv[]) +{ + int err; + char *inFile, *outFile; + FILE *fin, *fout; + HarmonyEncoder *enc; + HarmonyDecoder *dec; + int len; + int frame_size, channels; + int bytes_per_packet; + unsigned char data[MAX_PACKET]; + int rate; + int loss = 0; + int count = 0; + int skip; + int stop=0; + int vbr=0; + int tot_read=0, tot_written=0; + short *in, *out; + int mode=MODE_HYBRID; + double bits=0; + if (argc != 9 && argc != 8 && argc != 7) + { + fprintf (stderr, "Usage: test_harmony " + " [] [] " + " \n"); + return 1; + } + + rate = atoi(argv[1]); + channels = atoi(argv[2]); + frame_size = atoi(argv[3]); + + bytes_per_packet = atoi(argv[4]); + + if (argc >= 8) + vbr = atoi(argv[5]); + if (argc >= 9) + loss = atoi(argv[6]); + + if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET) + { + fprintf (stderr, "bytes per packet must be between 0 and %d\n", + MAX_PACKET); + return 1; + } + + inFile = argv[argc-2]; + fin = fopen(inFile, "rb"); + if (!fin) + { + fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); + return 1; + } + outFile = argv[argc-1]; + fout = fopen(outFile, "wb+"); + if (!fout) + { + fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); + return 1; + } + + enc = harmony_encoder_create(rate); + dec = harmony_decoder_create(rate); + + mode = MODE_HYBRID; + harmony_encoder_ctl(enc, HARMONY_SET_BANDWIDTH(BANDWIDTH_FULLBAND)); + harmony_encoder_ctl(enc, HARMONY_SET_MODE(mode)); + + if (vbr) + harmony_encoder_ctl(enc, HARMONY_SET_VBR_RATE(vbr)); + + skip = 5*rate/1000 + 10; + + in = (short*)malloc(frame_size*channels*sizeof(short)); + out = (short*)malloc(frame_size*channels*sizeof(short)); + while (!stop) + { + int write_samples; + err = fread(in, sizeof(short), frame_size*channels, fin); + tot_read += err; + if (err < frame_size*channels) + { + int i; + for (i=err;i tot_read && skip==0) + { + write_samples -= (tot_written-tot_read)/channels; + stop = 1; + } + fwrite(out+skip, sizeof(short), (write_samples-skip)*channels, fout); + skip = 0; + } + fprintf (stderr, "average bit-rate: %f kb/s\n", bits*rate/(frame_size*(double)count)); + harmony_encoder_destroy(enc); + harmony_decoder_destroy(dec); + fclose(fin); + fclose(fout); + free(in); + free(out); + return 0; +} diff --git a/src/test_hybrid.c b/src/test_hybrid.c deleted file mode 100644 index 9a547a88..00000000 --- a/src/test_hybrid.c +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include "hybrid.h" - - -#define MAX_PACKET 1024 - -int main(int argc, char *argv[]) -{ - int err; - char *inFile, *outFile; - FILE *fin, *fout; - HybridEncoder *enc; - HybridDecoder *dec; - int len; - int frame_size, channels; - int bytes_per_packet; - unsigned char data[MAX_PACKET]; - int rate; - int loss = 0; - int count = 0; - int skip; - int stop=0; - int vbr=0; - int tot_read=0, tot_written=0; - short *in, *out; - int mode=MODE_HYBRID; - double bits=0; - if (argc != 9 && argc != 8 && argc != 7) - { - fprintf (stderr, "Usage: test_hybrid " - " [] [] " - " \n"); - return 1; - } - - rate = atoi(argv[1]); - channels = atoi(argv[2]); - frame_size = atoi(argv[3]); - - bytes_per_packet = atoi(argv[4]); - - if (argc >= 8) - vbr = atoi(argv[5]); - if (argc >= 9) - loss = atoi(argv[6]); - - if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET) - { - fprintf (stderr, "bytes per packet must be between 0 and %d\n", - MAX_PACKET); - return 1; - } - - inFile = argv[argc-2]; - fin = fopen(inFile, "rb"); - if (!fin) - { - fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); - return 1; - } - outFile = argv[argc-1]; - fout = fopen(outFile, "wb+"); - if (!fout) - { - fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); - return 1; - } - - enc = hybrid_encoder_create(rate); - dec = hybrid_decoder_create(rate); - - mode = MODE_HYBRID; - hybrid_encoder_ctl(enc, HYBRID_SET_BANDWIDTH(BANDWIDTH_FULLBAND)); - hybrid_encoder_ctl(enc, HYBRID_SET_MODE(mode)); - - if (vbr) - hybrid_encoder_ctl(enc, HYBRID_SET_VBR_RATE(vbr)); - - skip = 5*rate/1000 + 10; - - in = (short*)malloc(frame_size*channels*sizeof(short)); - out = (short*)malloc(frame_size*channels*sizeof(short)); - while (!stop) - { - int write_samples; - err = fread(in, sizeof(short), frame_size*channels, fin); - tot_read += err; - if (err < frame_size*channels) - { - int i; - for (i=err;i tot_read && skip==0) - { - write_samples -= (tot_written-tot_read)/channels; - stop = 1; - } - fwrite(out+skip, sizeof(short), (write_samples-skip)*channels, fout); - skip = 0; - } - fprintf (stderr, "average bit-rate: %f kb/s\n", bits*rate/(frame_size*(double)count)); - hybrid_encoder_destroy(enc); - hybrid_decoder_destroy(dec); - fclose(fin); - fclose(fout); - free(in); - free(out); - return 0; -} -- cgit v1.2.3