ref: 05dd36a1b36670b1eb9d8f510ad1aa82944ac091
parent: 4e777532ee8acccf62cdf62d8efc4c3f4c6a3104
author: Jean-Marc Valin <[email protected]>
date: Mon Oct 18 08:50:49 EDT 2010
API renamed to Opus
--- a/README
+++ b/README
@@ -23,10 +23,10 @@
% make
-Once you have compiled the codec, there will be a test_harmony executable in
+Once you have compiled the codec, there will be a test_opus executable in
the src/ directory. This can be in the following way:
-% ./test_harmony 48000 1 960 80 input.sw output.sw
+% ./test_opus 48000 1 960 80 input.sw output.sw
The arguments are:
1) The sampling rate (only 48000 supported for now)
--- a/configure.ac
+++ b/configure.ac
@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.59])
-AC_INIT(src/harmony.h)
-AM_INIT_AUTOMAKE(harmony,20100921)
+AC_INIT(src/opus.h)
+AM_INIT_AUTOMAKE(opus,20100921)
# Checks for programs.
AC_PROG_CC
--- 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 = harmony_decoder.c harmony_encoder.c
+libietfcodec_la_SOURCES = opus_decoder.c opus_encoder.c
-noinst_HEADERS = harmony_decoder.h harmony_encoder.h
+noinst_HEADERS = opus_decoder.h opus_encoder.h
-pkginclude_HEADERS = harmony.h
+pkginclude_HEADERS = opus.h
-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
+noinst_PROGRAMS = test_opus
+test_opus_SOURCES = test_opus.c $(top_srcdir)/silk/test/SKP_debug.c
+test_opus_LDADD = libietfcodec.la $(top_builddir)/celt/libcelt/libcelt0.la $(top_builddir)/silk/libSKP_SILK_SDK.la
--- a/src/framepack.c
+++ b/src/framepack.c
@@ -100,7 +100,7 @@
}
#define MAX_FRAMES 256
-int harmony_merge_packets(unsigned char **packets, int *plen, int nb_packets,
+int opus_merge_packets(unsigned char **packets, int *plen, int nb_packets,
unsigned *output, int maxlen)
{
int i;
--- a/src/harmony.h
+++ /dev/null
@@ -1,102 +1,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 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 */
--- a/src/harmony_decoder.c
+++ /dev/null
@@ -1,212 +1,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 <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#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<<audiosize)/400;
- } else if ((data[0]&0x60) == 0x60)
- {
- st->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<<audiosize)/100;
- }
- /*printf ("%d %d %d\n", st->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;i<frame_size;i++)
- pcm[i] = 0;
- }
-
- if (st->mode == 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;i<frame_size;i++)
- pcm[i] += pcm_celt[i];
- }
- return celt_ret;
-
-}
-
-void harmony_decoder_ctl(HarmonyDecoder *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;
- 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);
-}
--- a/src/harmony_decoder.h
+++ /dev/null
@@ -1,51 +1,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 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 */
-
--- a/src/harmony_encoder.c
+++ /dev/null
@@ -1,270 +1,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 <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#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;i<ENCODER_DELAY_COMPENSATION;i++)
- pcm_buf[i] = st->delay_buffer[i];
- for (;i<frame_size;i++)
- pcm_buf[i] = pcm[i-ENCODER_DELAY_COMPENSATION];
-
- celt_encoder_ctl(st->celt_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;i<ENCODER_DELAY_COMPENSATION;i++)
- st->delay_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);
-}
-
--- a/src/harmony_encoder.h
+++ /dev/null
@@ -1,58 +1,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 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 */
-
--- /dev/null
+++ b/src/opus.h
@@ -1,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 OPUS_H
+#define OPUS_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 OPUS_SET_MODE_REQUEST 0
+#define OPUS_SET_MODE(x) OPUS_SET_MODE_REQUEST, __check_int(x)
+#define OPUS_GET_MODE_REQUEST 1
+#define OPUS_GET_MODE(x) OPUS_GET_MODE_REQUEST, __check_int_ptr(x)
+
+#define OPUS_SET_BANDWIDTH_REQUEST 2
+#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __check_int(x)
+#define OPUS_GET_BANDWIDTH_REQUEST 3
+#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __check_int_ptr(x)
+
+#define OPUS_SET_VBR_RATE_REQUEST 4
+#define OPUS_SET_VBR_RATE(x) OPUS_SET_VBR_RATE_REQUEST, __check_int(x)
+#define OPUS_GET_VBR_RATE_REQUEST 5
+#define OPUS_GET_VBR_RATE(x) OPUS_GET_VBR_RATE_REQUEST, __check_int_ptr(x)
+
+typedef struct OpusEncoder OpusEncoder;
+typedef struct OpusDecoder OpusDecoder;
+
+OpusEncoder *opus_encoder_create(int Fs);
+
+int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
+ unsigned char *data, int bytes_per_packet);
+
+void opus_encoder_destroy(OpusEncoder *st);
+
+void opus_encoder_ctl(OpusEncoder *st, int request, ...);
+
+OpusDecoder *opus_decoder_create(int Fs);
+
+int opus_decode(OpusDecoder *st, const unsigned char *data, int len,
+ short *pcm, int frame_size);
+
+void opus_decoder_ctl(OpusDecoder *st, int request, ...);
+
+void opus_decoder_destroy(OpusDecoder *st);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_H */
--- /dev/null
+++ b/src/opus_decoder.c
@@ -1,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 <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "opus_decoder.h"
+#include "entdec.h"
+#include "modes.h"
+#include "SKP_Silk_SDK_API.h"
+
+
+OpusDecoder *opus_decoder_create(int Fs)
+{
+ char *raw_state;
+ int ret, silkDecSizeBytes, celtDecSizeBytes;
+ CELTMode *celtMode;
+ OpusDecoder *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(OpusDecoder)+silkDecSizeBytes+celtDecSizeBytes, 1);
+ st = (OpusDecoder*)raw_state;
+ st->silk_dec = (void*)(raw_state+sizeof(OpusDecoder));
+ st->celt_dec = (CELTDecoder*)(raw_state+sizeof(OpusDecoder)+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 opus_decode(OpusDecoder *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<<audiosize)/400;
+ } else if ((data[0]&0x60) == 0x60)
+ {
+ st->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<<audiosize)/100;
+ }
+ /*printf ("%d %d %d\n", st->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;i<frame_size;i++)
+ pcm[i] = 0;
+ }
+
+ if (st->mode == 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;i<frame_size;i++)
+ pcm[i] += pcm_celt[i];
+ }
+ return celt_ret;
+
+}
+
+void opus_decoder_ctl(OpusDecoder *st, int request, ...)
+{
+ va_list ap;
+
+ va_start(ap, request);
+
+ switch (request)
+ {
+ case OPUS_SET_MODE_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ st->mode = value;
+ }
+ break;
+ case OPUS_GET_MODE_REQUEST:
+ {
+ int *value = va_arg(ap, int*);
+ *value = st->mode;
+ }
+ break;
+ case OPUS_SET_BANDWIDTH_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ st->bandwidth = value;
+ }
+ break;
+ case OPUS_GET_BANDWIDTH_REQUEST:
+ {
+ int *value = va_arg(ap, int*);
+ *value = st->bandwidth;
+ }
+ break;
+ default:
+ fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);
+ break;
+ }
+
+ va_end(ap);
+}
+
+void opus_decoder_destroy(OpusDecoder *st)
+{
+ celt_mode_destroy(st->celt_mode);
+
+ free(st);
+}
--- /dev/null
+++ b/src/opus_decoder.h
@@ -1,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 OPUS_DECODER_H
+#define OPUS_DECODER_H
+
+#include "celt.h"
+#include "opus.h"
+
+struct OpusDecoder {
+ CELTMode *celt_mode;
+ CELTDecoder *celt_dec;
+ void *silk_dec;
+
+ int mode;
+ int bandwidth;
+ /* Sampling rate (at the API level) */
+ int Fs;
+};
+
+
+#endif /* OPUS_DECODER_H */
+
--- /dev/null
+++ b/src/opus_encoder.c
@@ -1,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 <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "opus_encoder.h"
+#include "entenc.h"
+#include "modes.h"
+#include "SKP_Silk_SDK_API.h"
+
+OpusEncoder *opus_encoder_create(int Fs)
+{
+ char *raw_state;
+ CELTMode *celtMode;
+ OpusEncoder *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(OpusEncoder)+silkEncSizeBytes+celtEncSizeBytes, 1);
+ st = (OpusEncoder*)raw_state;
+ st->silk_enc = (void*)(raw_state+sizeof(OpusEncoder));
+ st->celt_enc = (CELTEncoder*)(raw_state+sizeof(OpusEncoder)+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 opus_encode(OpusEncoder *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;i<ENCODER_DELAY_COMPENSATION;i++)
+ pcm_buf[i] = st->delay_buffer[i];
+ for (;i<frame_size;i++)
+ pcm_buf[i] = pcm[i-ENCODER_DELAY_COMPENSATION];
+
+ celt_encoder_ctl(st->celt_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;i<ENCODER_DELAY_COMPENSATION;i++)
+ st->delay_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 /* Opus */
+ {
+ 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 opus_encoder_ctl(OpusEncoder *st, int request, ...)
+{
+ va_list ap;
+
+ va_start(ap, request);
+
+ switch (request)
+ {
+ case OPUS_SET_MODE_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ st->mode = value;
+ }
+ break;
+ case OPUS_GET_MODE_REQUEST:
+ {
+ int *value = va_arg(ap, int*);
+ *value = st->mode;
+ }
+ break;
+ case OPUS_SET_BANDWIDTH_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ st->bandwidth = value;
+ }
+ break;
+ case OPUS_GET_BANDWIDTH_REQUEST:
+ {
+ int *value = va_arg(ap, int*);
+ *value = st->bandwidth;
+ }
+ break;
+ case OPUS_SET_VBR_RATE_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ st->vbr_rate = value;
+ }
+ break;
+ case OPUS_GET_VBR_RATE_REQUEST:
+ {
+ int *value = va_arg(ap, int*);
+ *value = st->vbr_rate;
+ }
+ break;
+ default:
+ fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
+ break;
+ }
+
+ va_end(ap);
+}
+
+void opus_encoder_destroy(OpusEncoder *st)
+{
+ celt_mode_destroy(st->celt_mode);
+ free(st);
+}
+
--- /dev/null
+++ b/src/opus_encoder.h
@@ -1,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 OPUS_ENCODER_H
+#define OPUS_ENCODER_H
+
+#include "celt.h"
+#include "opus.h"
+#include "SKP_Silk_SDK_API.h"
+
+/* FIXME: This is only valid for 48 kHz */
+#define ENCODER_DELAY_COMPENSATION 130
+
+struct OpusEncoder {
+ 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 /* OPUS_ENCODER_H */
+
--- a/src/test_harmony.c
+++ /dev/null
@@ -1,160 +1,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 <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#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 <rate (kHz)> <channels> <frame size> "
- " <bytes per packet> [<VBR rate (kb/s)>] [<packet loss rate>] "
- "<input> <output>\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<frame_size*channels;i++)
- in[i] = 0;
- }
- len = harmony_encode(enc, in, frame_size, data, bytes_per_packet);
- if (len <= 0)
- {
- fprintf (stderr, "harmony_encode() returned %d\n", len);
- return 1;
- }
- bits += len*8;
- harmony_decode(dec, rand()%100<loss ? NULL : data, len, out, frame_size);
- count++;
- tot_written += (frame_size-skip)*channels;
- write_samples = frame_size;
- if (tot_written > 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;
-}
--- /dev/null
+++ b/src/test_opus.c
@@ -1,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 <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include "opus.h"
+
+
+#define MAX_PACKET 1024
+
+int main(int argc, char *argv[])
+{
+ int err;
+ char *inFile, *outFile;
+ FILE *fin, *fout;
+ OpusEncoder *enc;
+ OpusDecoder *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_opus <rate (kHz)> <channels> <frame size> "
+ " <bytes per packet> [<VBR rate (kb/s)>] [<packet loss rate>] "
+ "<input> <output>\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 = opus_encoder_create(rate);
+ dec = opus_decoder_create(rate);
+
+ mode = MODE_HYBRID;
+ opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(BANDWIDTH_FULLBAND));
+ opus_encoder_ctl(enc, OPUS_SET_MODE(mode));
+
+ if (vbr)
+ opus_encoder_ctl(enc, OPUS_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<frame_size*channels;i++)
+ in[i] = 0;
+ }
+ len = opus_encode(enc, in, frame_size, data, bytes_per_packet);
+ if (len <= 0)
+ {
+ fprintf (stderr, "opus_encode() returned %d\n", len);
+ return 1;
+ }
+ bits += len*8;
+ opus_decode(dec, rand()%100<loss ? NULL : data, len, out, frame_size);
+ count++;
+ tot_written += (frame_size-skip)*channels;
+ write_samples = frame_size;
+ if (tot_written > 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));
+ opus_encoder_destroy(enc);
+ opus_decoder_destroy(dec);
+ fclose(fin);
+ fclose(fout);
+ free(in);
+ free(out);
+ return 0;
+}