summaryrefslogtreecommitdiffstats
path: root/lib/rbcodec/codecs
diff options
context:
space:
mode:
authorFrederik M J Vestre <freqmod@gmail.com>2012-07-26 14:38:32 +0200
committerBertrik Sikken <bertrik@sikken.nl>2012-09-20 20:47:44 +0200
commit1b8e3801b2444f6e466e1b7c09cfc51605e80fb3 (patch)
treebd1d6fe08452d388d0d160ec02e03963f3f9525d /lib/rbcodec/codecs
parent72ebcbf73b4db911d517a66c820fdceccb8ec798 (diff)
downloadrockbox-1b8e3801b2444f6e466e1b7c09cfc51605e80fb3.tar.gz
rockbox-1b8e3801b2444f6e466e1b7c09cfc51605e80fb3.tar.bz2
rockbox-1b8e3801b2444f6e466e1b7c09cfc51605e80fb3.zip
Initial opus codec support
Synchronised with opus repo on github (https://github.com/freqmod/rockbox-opus) Status: * Seeking ported from speex, but fails on some cases (e.g. seek to granule 0) * ReplayGain parsing needs to be reworked, we do vorbis-style replaygain now. http://wiki.xiph.org/OggOpus#Comment_Header explicitly forbids these in favour of R128_TRACK_GAIN tag. * No optimisation yet, source files still nearly identical to opus upstream * Multi-stream opus files may not be parsed correctly Change-Id: Ia66f1027dc1d288083e3c57b2816700078376f9a Reviewed-on: http://gerrit.rockbox.org/300 Reviewed-by: Bertrik Sikken <bertrik@sikken.nl> Tested-by: Bertrik Sikken <bertrik@sikken.nl>
Diffstat (limited to 'lib/rbcodec/codecs')
-rw-r--r--lib/rbcodec/codecs/SOURCES1
-rw-r--r--lib/rbcodec/codecs/codecs.make3
-rw-r--r--lib/rbcodec/codecs/lib/codeclib.c2
-rw-r--r--lib/rbcodec/codecs/libopus/README.rockbox26
-rw-r--r--lib/rbcodec/codecs/libopus/SOURCES70
-rw-r--r--lib/rbcodec/codecs/libopus/celt/_kiss_fft_guts.h175
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arch.h209
-rw-r--r--lib/rbcodec/codecs/libopus/celt/bands.c1302
-rw-r--r--lib/rbcodec/codecs/libopus/celt/bands.h95
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt.c2870
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt.h117
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt_lpc.c188
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt_lpc.h53
-rw-r--r--lib/rbcodec/codecs/libopus/celt/cwrs.c645
-rw-r--r--lib/rbcodec/codecs/libopus/celt/cwrs.h48
-rw-r--r--lib/rbcodec/codecs/libopus/celt/ecintrin.h87
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entcode.c88
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entcode.h116
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entdec.c245
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entdec.h100
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entenc.c294
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entenc.h110
-rw-r--r--lib/rbcodec/codecs/libopus/celt/fixed_generic.h129
-rw-r--r--lib/rbcodec/codecs/libopus/celt/float_cast.h140
-rw-r--r--lib/rbcodec/codecs/libopus/celt/kiss_fft.c722
-rw-r--r--lib/rbcodec/codecs/libopus/celt/kiss_fft.h139
-rw-r--r--lib/rbcodec/codecs/libopus/celt/laplace.c134
-rw-r--r--lib/rbcodec/codecs/libopus/celt/laplace.h48
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mathops.c206
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mathops.h237
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mdct.c332
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mdct.h70
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mfrngcod.h48
-rw-r--r--lib/rbcodec/codecs/libopus/celt/modes.c430
-rw-r--r--lib/rbcodec/codecs/libopus/celt/modes.h83
-rw-r--r--lib/rbcodec/codecs/libopus/celt/os_support.h89
-rw-r--r--lib/rbcodec/codecs/libopus/celt/pitch.c410
-rw-r--r--lib/rbcodec/codecs/libopus/celt/pitch.h48
-rw-r--r--lib/rbcodec/codecs/libopus/celt/quant_bands.c567
-rw-r--r--lib/rbcodec/codecs/libopus/celt/quant_bands.h60
-rw-r--r--lib/rbcodec/codecs/libopus/celt/rate.c638
-rw-r--r--lib/rbcodec/codecs/libopus/celt/rate.h101
-rw-r--r--lib/rbcodec/codecs/libopus/celt/stack_alloc.h149
-rw-r--r--lib/rbcodec/codecs/libopus/celt/static_modes_fixed.h595
-rw-r--r--lib/rbcodec/codecs/libopus/celt/vq.c415
-rw-r--r--lib/rbcodec/codecs/libopus/celt/vq.h73
-rw-r--r--lib/rbcodec/codecs/libopus/libopus.make24
-rw-r--r--lib/rbcodec/codecs/libopus/ogg/framing.c1025
-rw-r--r--lib/rbcodec/codecs/libopus/ogg/ogg.h210
-rw-r--r--lib/rbcodec/codecs/libopus/ogg/os_types.h56
-rw-r--r--lib/rbcodec/codecs/libopus/opus.h882
-rw-r--r--lib/rbcodec/codecs/libopus/opus_config.h42
-rw-r--r--lib/rbcodec/codecs/libopus/opus_custom.h329
-rw-r--r--lib/rbcodec/codecs/libopus/opus_decoder.c999
-rw-r--r--lib/rbcodec/codecs/libopus/opus_defines.h644
-rw-r--r--lib/rbcodec/codecs/libopus/opus_header.c286
-rw-r--r--lib/rbcodec/codecs/libopus/opus_header.h51
-rw-r--r--lib/rbcodec/codecs/libopus/opus_private.h85
-rw-r--r--lib/rbcodec/codecs/libopus/opus_types.h159
-rw-r--r--lib/rbcodec/codecs/libopus/silk/API.h132
-rw-r--r--lib/rbcodec/codecs/libopus/silk/CNG.c167
-rw-r--r--lib/rbcodec/codecs/libopus/silk/Inlines.h188
-rw-r--r--lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c85
-rw-r--r--lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c154
-rw-r--r--lib/rbcodec/codecs/libopus/silk/MacroCount.h718
-rw-r--r--lib/rbcodec/codecs/libopus/silk/MacroDebug.h952
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF2A.c178
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c80
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_decode.c101
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c142
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_unpack.c55
-rw-r--r--lib/rbcodec/codecs/libopus/silk/PLC.c423
-rw-r--r--lib/rbcodec/codecs/libopus/silk/PLC.h61
-rw-r--r--lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h589
-rw-r--r--lib/rbcodec/codecs/libopus/silk/bwexpander.c51
-rw-r--r--lib/rbcodec/codecs/libopus/silk/bwexpander_32.c50
-rw-r--r--lib/rbcodec/codecs/libopus/silk/code_signs.c115
-rw-r--r--lib/rbcodec/codecs/libopus/silk/control.h139
-rw-r--r--lib/rbcodec/codecs/libopus/silk/dec_API.c392
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_core.c238
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_frame.c128
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_indices.c151
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_parameters.c115
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_pitch.c77
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_pulses.c115
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c108
-rw-r--r--lib/rbcodec/codecs/libopus/silk/define.h235
-rw-r--r--lib/rbcodec/codecs/libopus/silk/errors.h98
-rw-r--r--lib/rbcodec/codecs/libopus/silk/gain_quant.c141
-rw-r--r--lib/rbcodec/codecs/libopus/silk/init_decoder.c56
-rw-r--r--lib/rbcodec/codecs/libopus/silk/lin2log.c46
-rw-r--r--lib/rbcodec/codecs/libopus/silk/log2lin.c56
-rw-r--r--lib/rbcodec/codecs/libopus/silk/macros.h135
-rw-r--r--lib/rbcodec/codecs/libopus/silk/main.h434
-rw-r--r--lib/rbcodec/codecs/libopus/silk/pitch_est_defines.h88
-rw-r--r--lib/rbcodec/codecs/libopus/silk/pitch_est_tables.c99
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler.c215
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_private.h88
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_private_AR2.c55
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_private_IIR_FIR.c103
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c189
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_private_up2_HQ.c113
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_rom.c96
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_rom.h68
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_structs.h57
-rw-r--r--lib/rbcodec/codecs/libopus/silk/shell_coder.c151
-rw-r--r--lib/rbcodec/codecs/libopus/silk/sort.c154
-rw-r--r--lib/rbcodec/codecs/libopus/silk/stereo_MS_to_LR.c85
-rw-r--r--lib/rbcodec/codecs/libopus/silk/stereo_decode_pred.c73
-rw-r--r--lib/rbcodec/codecs/libopus/silk/structs.h324
-rw-r--r--lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c85
-rw-r--r--lib/rbcodec/codecs/libopus/silk/table_LSF_cos.c70
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables.h120
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_LTP.c272
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c159
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c198
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_gain.c63
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_other.c138
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_pitch_lag.c69
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_pulses_per_block.c264
-rw-r--r--lib/rbcodec/codecs/libopus/silk/typedef.h77
-rw-r--r--lib/rbcodec/codecs/opus.c461
122 files changed, 28337 insertions, 1 deletions
diff --git a/lib/rbcodec/codecs/SOURCES b/lib/rbcodec/codecs/SOURCES
index db6e82c75f..039772cf9a 100644
--- a/lib/rbcodec/codecs/SOURCES
+++ b/lib/rbcodec/codecs/SOURCES
@@ -1,5 +1,6 @@
/* decoders */
+opus.c
vorbis.c
mpa.c
flac.c
diff --git a/lib/rbcodec/codecs/codecs.make b/lib/rbcodec/codecs/codecs.make
index 919aef2024..f56c032c60 100644
--- a/lib/rbcodec/codecs/codecs.make
+++ b/lib/rbcodec/codecs/codecs.make
@@ -51,6 +51,7 @@ include $(RBCODECLIB_DIR)/codecs/libgme/libsgc.make
include $(RBCODECLIB_DIR)/codecs/libgme/libvgm.make
include $(RBCODECLIB_DIR)/codecs/libgme/libkss.make
include $(RBCODECLIB_DIR)/codecs/libgme/libemu2413.make
+include $(RBCODECLIB_DIR)/codecs/libopus/libopus.make
# compile flags for codecs
CODECFLAGS = $(CFLAGS) $(RBCODEC_CFLAGS) -fstrict-aliasing \
@@ -74,6 +75,7 @@ $(KSSLIB) : CODECFLAGS += -O2
$(M4ALIB) : CODECFLAGS += -O3
$(MUSEPACKLIB) : CODECFLAGS += -O1
$(NSFLIB) : CODECFLAGS += -O2
+$(OPUSLIB) : CODECFLAGS += -O2
$(PCMSLIB) : CODECFLAGS += -O1
$(RMLIB) : CODECFLAGS += -O3
$(SGCLIB) : CODECFLAGS += -O2
@@ -168,6 +170,7 @@ $(CODECDIR)/nsf.codec : $(CODECDIR)/libnsf.a $(CODECDIR)/libemu2413.a
$(CODECDIR)/sgc.codec : $(CODECDIR)/libsgc.a $(CODECDIR)/libemu2413.a
$(CODECDIR)/vgm.codec : $(CODECDIR)/libvgm.a $(CODECDIR)/libemu2413.a
$(CODECDIR)/kss.codec : $(CODECDIR)/libkss.a $(CODECDIR)/libemu2413.a
+$(CODECDIR)/opus.codec : $(CODECDIR)/libopus.a
$(CODECS): $(CODEC_LIBS) # this must be last in codec dependency list
diff --git a/lib/rbcodec/codecs/lib/codeclib.c b/lib/rbcodec/codecs/lib/codeclib.c
index 09c96f921c..a12038eeb8 100644
--- a/lib/rbcodec/codecs/lib/codeclib.c
+++ b/lib/rbcodec/codecs/lib/codeclib.c
@@ -91,7 +91,7 @@ void* codec_realloc(void* ptr, size_t size)
{
void* x;
x = codec_malloc(size);
- memcpy(x, ptr, size);
+ ci->memcpy(x, ptr, size);
codec_free(ptr);
return(x);
}
diff --git a/lib/rbcodec/codecs/libopus/README.rockbox b/lib/rbcodec/codecs/libopus/README.rockbox
new file mode 100644
index 0000000000..8a5ef41fba
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/README.rockbox
@@ -0,0 +1,26 @@
+Libraries: Opus (snapshot) / Opus-tools (snapshot) / libogg 1.3
+Imported: September 15th, 2012
+
+Steps taken to adapt original opus/opus-tool/ogg source files to rockbox
+(useful when for example syncing a new snapshot)
+
+Opus:
+* copied .c/.h files from opus/src lib/rbcodec/codecs/libopus
+* copied .h files from opus/include to lib/rbcodec/codecs/libopus
+* copied .c/.h files from opus/celt to lib/rbcodec/codecs/libopus/celt
+* copied .c/.h files from opus/silk to lib/rbcodec/codecs/libopus/silk
+* renamed opus config.h file to opus_config.h and replaced #include "config.h",
+ for example
+find . -name "*.h" -print | xargs sed -i 's/include "config.h"/include "opus_config.h"/g'
+find . -name "*.c" -print | xargs sed -i 's/include "config.h"/include "opus_config.h"/g'
+
+Opus-tools:
+* copied src/opus_header.h and src/opus_header.c to lib/rbcodec/codecs/libopus
+* changed #include <ogg/ogg.h> to #include "ogg/ogg.h" in opus_header.c
+
+Ogg:
+* copied libogg/src/framing.c to lib/rbcodec/codecs/libopus/ogg
+* copied libogg/include/ogg.h to lib/rbcodec/codecs/libopus/ogg
+* changed #include "ogg/ogg.h" to #include "ogg.h" in framing.c
+* added os_config.h to lib/rbcodec/codecs/libopus/ogg
+
diff --git a/lib/rbcodec/codecs/libopus/SOURCES b/lib/rbcodec/codecs/libopus/SOURCES
new file mode 100644
index 0000000000..df3f014f38
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/SOURCES
@@ -0,0 +1,70 @@
+/* CELT sources */
+celt/bands.c
+celt/celt.c
+celt/celt_lpc.c
+celt/cwrs.c
+celt/entcode.c
+celt/entdec.c
+celt/entenc.c
+celt/kiss_fft.c
+celt/laplace.c
+celt/mathops.c
+celt/mdct.c
+celt/modes.c
+celt/pitch.c
+celt/quant_bands.c
+celt/rate.c
+celt/vq.c
+
+/* SILK sources */
+silk/bwexpander_32.c
+silk/bwexpander.c
+silk/CNG.c
+silk/code_signs.c
+silk/dec_API.c
+silk/decode_core.c
+silk/decode_frame.c
+silk/decode_indices.c
+silk/decode_parameters.c
+silk/decode_pitch.c
+silk/decode_pulses.c
+silk/decoder_set_fs.c
+silk/gain_quant.c
+silk/init_decoder.c
+silk/lin2log.c
+silk/log2lin.c
+silk/LPC_analysis_filter.c
+silk/LPC_inv_pred_gain.c
+silk/NLSF2A.c
+silk/NLSF_decode.c
+silk/NLSF_stabilize.c
+silk/NLSF_unpack.c
+silk/NLSF_VQ_weights_laroia.c
+silk/pitch_est_tables.c
+silk/PLC.c
+silk/resampler.c
+silk/resampler_private_AR2.c
+silk/resampler_private_down_FIR.c
+silk/resampler_private_IIR_FIR.c
+silk/resampler_private_up2_HQ.c
+silk/resampler_rom.c
+silk/shell_coder.c
+silk/sort.c
+silk/stereo_decode_pred.c
+silk/stereo_MS_to_LR.c
+silk/sum_sqr_shift.c
+silk/table_LSF_cos.c
+silk/tables_gain.c
+silk/tables_LTP.c
+silk/tables_NLSF_CB_NB_MB.c
+silk/tables_NLSF_CB_WB.c
+silk/tables_other.c
+silk/tables_pitch_lag.c
+silk/tables_pulses_per_block.c
+
+/* OPUS sources */
+opus_decoder.c
+opus_header.c
+
+/* OGG sources */
+ogg/framing.c
diff --git a/lib/rbcodec/codecs/libopus/celt/_kiss_fft_guts.h b/lib/rbcodec/codecs/libopus/celt/_kiss_fft_guts.h
new file mode 100644
index 0000000000..33e62c6b3d
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/_kiss_fft_guts.h
@@ -0,0 +1,175 @@
+/*Copyright (c) 2003-2004, Mark Borgerding
+
+ All rights reserved.
+
+ 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.
+
+ 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 COPYRIGHT OWNER 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 KISS_FFT_GUTS_H
+#define KISS_FFT_GUTS_H
+
+#define MIN(a,b) ((a)<(b) ? (a):(b))
+#define MAX(a,b) ((a)>(b) ? (a):(b))
+
+/* kiss_fft.h
+ defines kiss_fft_scalar as either short or a float type
+ and defines
+ typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
+#include "kiss_fft.h"
+
+/*
+ Explanation of macros dealing with complex math:
+
+ C_MUL(m,a,b) : m = a*b
+ C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
+ C_SUB( res, a,b) : res = a - b
+ C_SUBFROM( res , a) : res -= a
+ C_ADDTO( res , a) : res += a
+ * */
+#ifdef FIXED_POINT
+#include "arch.h"
+
+
+#define SAMP_MAX 2147483647
+#define TWID_MAX 32767
+#define TRIG_UPSCALE 1
+
+#define SAMP_MIN -SAMP_MAX
+
+
+# define S_MUL(a,b) MULT16_32_Q15(b, a)
+
+# define C_MUL(m,a,b) \
+ do{ (m).r = SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
+ (m).i = ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)
+
+# define C_MULC(m,a,b) \
+ do{ (m).r = ADD32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
+ (m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)
+
+# define C_MUL4(m,a,b) \
+ do{ (m).r = SHR32(SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)),2); \
+ (m).i = SHR32(ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)),2); }while(0)
+
+# define C_MULBYSCALAR( c, s ) \
+ do{ (c).r = S_MUL( (c).r , s ) ;\
+ (c).i = S_MUL( (c).i , s ) ; }while(0)
+
+# define DIVSCALAR(x,k) \
+ (x) = S_MUL( x, (TWID_MAX-((k)>>1))/(k)+1 )
+
+# define C_FIXDIV(c,div) \
+ do { DIVSCALAR( (c).r , div); \
+ DIVSCALAR( (c).i , div); }while (0)
+
+#define C_ADD( res, a,b)\
+ do {(res).r=ADD32((a).r,(b).r); (res).i=ADD32((a).i,(b).i); \
+ }while(0)
+#define C_SUB( res, a,b)\
+ do {(res).r=SUB32((a).r,(b).r); (res).i=SUB32((a).i,(b).i); \
+ }while(0)
+#define C_ADDTO( res , a)\
+ do {(res).r = ADD32((res).r, (a).r); (res).i = ADD32((res).i,(a).i);\
+ }while(0)
+
+#define C_SUBFROM( res , a)\
+ do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \
+ }while(0)
+
+#else /* not FIXED_POINT*/
+
+# define S_MUL(a,b) ( (a)*(b) )
+#define C_MUL(m,a,b) \
+ do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
+ (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
+#define C_MULC(m,a,b) \
+ do{ (m).r = (a).r*(b).r + (a).i*(b).i;\
+ (m).i = (a).i*(b).r - (a).r*(b).i; }while(0)
+
+#define C_MUL4(m,a,b) C_MUL(m,a,b)
+
+# define C_FIXDIV(c,div) /* NOOP */
+# define C_MULBYSCALAR( c, s ) \
+ do{ (c).r *= (s);\
+ (c).i *= (s); }while(0)
+#endif
+
+#ifndef CHECK_OVERFLOW_OP
+# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
+#endif
+
+#ifndef C_ADD
+#define C_ADD( res, a,b)\
+ do { \
+ CHECK_OVERFLOW_OP((a).r,+,(b).r)\
+ CHECK_OVERFLOW_OP((a).i,+,(b).i)\
+ (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
+ }while(0)
+#define C_SUB( res, a,b)\
+ do { \
+ CHECK_OVERFLOW_OP((a).r,-,(b).r)\
+ CHECK_OVERFLOW_OP((a).i,-,(b).i)\
+ (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
+ }while(0)
+#define C_ADDTO( res , a)\
+ do { \
+ CHECK_OVERFLOW_OP((res).r,+,(a).r)\
+ CHECK_OVERFLOW_OP((res).i,+,(a).i)\
+ (res).r += (a).r; (res).i += (a).i;\
+ }while(0)
+
+#define C_SUBFROM( res , a)\
+ do {\
+ CHECK_OVERFLOW_OP((res).r,-,(a).r)\
+ CHECK_OVERFLOW_OP((res).i,-,(a).i)\
+ (res).r -= (a).r; (res).i -= (a).i; \
+ }while(0)
+#endif /* C_ADD defined */
+
+#ifdef FIXED_POINT
+/*# define KISS_FFT_COS(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase))))
+# define KISS_FFT_SIN(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))*/
+# define KISS_FFT_COS(phase) floor(.5+TWID_MAX*cos (phase))
+# define KISS_FFT_SIN(phase) floor(.5+TWID_MAX*sin (phase))
+# define HALF_OF(x) ((x)>>1)
+#elif defined(USE_SIMD)
+# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
+# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
+# define HALF_OF(x) ((x)*_mm_set1_ps(.5f))
+#else
+# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
+# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
+# define HALF_OF(x) ((x)*.5f)
+#endif
+
+#define kf_cexp(x,phase) \
+ do{ \
+ (x)->r = KISS_FFT_COS(phase);\
+ (x)->i = KISS_FFT_SIN(phase);\
+ }while(0)
+
+#define kf_cexp2(x,phase) \
+ do{ \
+ (x)->r = TRIG_UPSCALE*celt_cos_norm((phase));\
+ (x)->i = TRIG_UPSCALE*celt_cos_norm((phase)-32768);\
+}while(0)
+
+#endif /* KISS_FFT_GUTS_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/arch.h b/lib/rbcodec/codecs/libopus/celt/arch.h
new file mode 100644
index 0000000000..03cda40f69
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arch.h
@@ -0,0 +1,209 @@
+/* Copyright (c) 2003-2008 Jean-Marc Valin
+ Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/**
+ @file arch.h
+ @brief Various architecture definitions for CELT
+*/
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 ARCH_H
+#define ARCH_H
+
+#include "opus_types.h"
+
+# if !defined(__GNUC_PREREQ)
+# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
+# define __GNUC_PREREQ(_maj,_min) \
+ ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
+# else
+# define __GNUC_PREREQ(_maj,_min) 0
+# endif
+# endif
+
+#define CELT_SIG_SCALE 32768.f
+
+#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__);
+#ifdef ENABLE_ASSERTIONS
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef __GNUC__
+__attribute__((noreturn))
+#endif
+static inline void _celt_fatal(const char *str, const char *file, int line)
+{
+ fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
+ abort();
+}
+#define celt_assert(cond) {if (!(cond)) {celt_fatal("assertion failed: " #cond);}}
+#define celt_assert2(cond, message) {if (!(cond)) {celt_fatal("assertion failed: " #cond "\n" message);}}
+#else
+#define celt_assert(cond)
+#define celt_assert2(cond, message)
+#endif
+
+#define IMUL32(a,b) ((a)*(b))
+
+#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
+#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */
+#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 16-bit value. */
+#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
+#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */
+#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 32-bit value. */
+#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
+#define IMIN(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum int value. */
+#define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */
+#define UADD32(a,b) ((a)+(b))
+#define USUB32(a,b) ((a)-(b))
+
+#define PRINT_MIPS(file)
+
+#ifdef FIXED_POINT
+
+typedef opus_int16 opus_val16;
+typedef opus_int32 opus_val32;
+
+typedef opus_val32 celt_sig;
+typedef opus_val16 celt_norm;
+typedef opus_val32 celt_ener;
+
+#define Q15ONE 32767
+
+#define SIG_SHIFT 12
+
+#define NORM_SCALING 16384
+
+#define DB_SHIFT 10
+
+#define EPSILON 1
+#define VERY_LARGE16 ((opus_val16)32767)
+#define Q15_ONE ((opus_val16)32767)
+
+#define SCALEIN(a) (a)
+#define SCALEOUT(a) (a)
+
+#ifdef FIXED_DEBUG
+#include "fixed_debug.h"
+#else
+
+#include "fixed_generic.h"
+
+#ifdef ARM5E_ASM
+#include "fixed_arm5e.h"
+#elif defined (ARM4_ASM)
+#include "fixed_arm4.h"
+#elif defined (BFIN_ASM)
+#include "fixed_bfin.h"
+#elif defined (TI_C5X_ASM)
+#include "fixed_c5x.h"
+#elif defined (TI_C6X_ASM)
+#include "fixed_c6x.h"
+#endif
+
+#endif
+
+#else /* FIXED_POINT */
+
+typedef float opus_val16;
+typedef float opus_val32;
+
+typedef float celt_sig;
+typedef float celt_norm;
+typedef float celt_ener;
+
+#define Q15ONE 1.0f
+
+#define NORM_SCALING 1.f
+
+#define EPSILON 1e-15f
+#define VERY_LARGE16 1e15f
+#define Q15_ONE ((opus_val16)1.f)
+
+#define QCONST16(x,bits) (x)
+#define QCONST32(x,bits) (x)
+
+#define NEG16(x) (-(x))
+#define NEG32(x) (-(x))
+#define EXTRACT16(x) (x)
+#define EXTEND32(x) (x)
+#define SHR16(a,shift) (a)
+#define SHL16(a,shift) (a)
+#define SHR32(a,shift) (a)
+#define SHL32(a,shift) (a)
+#define PSHR32(a,shift) (a)
+#define VSHR32(a,shift) (a)
+
+#define PSHR(a,shift) (a)
+#define SHR(a,shift) (a)
+#define SHL(a,shift) (a)
+#define SATURATE(x,a) (x)
+
+#define ROUND16(a,shift) (a)
+#define HALF16(x) (.5f*(x))
+#define HALF32(x) (.5f*(x))
+
+#define ADD16(a,b) ((a)+(b))
+#define SUB16(a,b) ((a)-(b))
+#define ADD32(a,b) ((a)+(b))
+#define SUB32(a,b) ((a)-(b))
+#define MULT16_16_16(a,b) ((a)*(b))
+#define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b))
+#define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b))
+
+#define MULT16_32_Q15(a,b) ((a)*(b))
+#define MULT16_32_Q16(a,b) ((a)*(b))
+
+#define MULT32_32_Q31(a,b) ((a)*(b))
+
+#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
+
+#define MULT16_16_Q11_32(a,b) ((a)*(b))
+#define MULT16_16_Q13(a,b) ((a)*(b))
+#define MULT16_16_Q14(a,b) ((a)*(b))
+#define MULT16_16_Q15(a,b) ((a)*(b))
+#define MULT16_16_P15(a,b) ((a)*(b))
+#define MULT16_16_P13(a,b) ((a)*(b))
+#define MULT16_16_P14(a,b) ((a)*(b))
+#define MULT16_32_P16(a,b) ((a)*(b))
+
+#define DIV32_16(a,b) (((opus_val32)(a))/(opus_val16)(b))
+#define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b))
+
+#define SCALEIN(a) ((a)*CELT_SIG_SCALE)
+#define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE))
+
+#endif /* !FIXED_POINT */
+
+#ifndef GLOBAL_STACK_SIZE
+#ifdef FIXED_POINT
+#define GLOBAL_STACK_SIZE 100000
+#else
+#define GLOBAL_STACK_SIZE 100000
+#endif
+#endif
+
+#endif /* ARCH_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/bands.c b/lib/rbcodec/codecs/libopus/celt/bands.c
new file mode 100644
index 0000000000..6e612980b6
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/bands.c
@@ -0,0 +1,1302 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2008-2009 Gregory Maxwell
+ Written by Jean-Marc Valin and Gregory Maxwell */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include <math.h>
+#include "bands.h"
+#include "modes.h"
+#include "vq.h"
+#include "cwrs.h"
+#include "stack_alloc.h"
+#include "os_support.h"
+#include "mathops.h"
+#include "rate.h"
+
+opus_uint32 celt_lcg_rand(opus_uint32 seed)
+{
+ return 1664525 * seed + 1013904223;
+}
+
+/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness
+ with this approximation is important because it has an impact on the bit allocation */
+static opus_int16 bitexact_cos(opus_int16 x)
+{
+ opus_int32 tmp;
+ opus_int16 x2;
+ tmp = (4096+((opus_int32)(x)*(x)))>>13;
+ celt_assert(tmp<=32767);
+ x2 = tmp;
+ x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2)))));
+ celt_assert(x2<=32766);
+ return 1+x2;
+}
+
+static int bitexact_log2tan(int isin,int icos)
+{
+ int lc;
+ int ls;
+ lc=EC_ILOG(icos);
+ ls=EC_ILOG(isin);
+ icos<<=15-lc;
+ isin<<=15-ls;
+ return (ls-lc)*(1<<11)
+ +FRAC_MUL16(isin, FRAC_MUL16(isin, -2597) + 7932)
+ -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932);
+}
+
+#ifdef FIXED_POINT
+/* Compute the amplitude (sqrt energy) in each of the bands */
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M)
+{
+ int i, c, N;
+ const opus_int16 *eBands = m->eBands;
+ N = M*m->shortMdctSize;
+ c=0; do {
+ for (i=0;i<end;i++)
+ {
+ int j;
+ opus_val32 maxval=0;
+ opus_val32 sum = 0;
+
+ j=M*eBands[i]; do {
+ maxval = MAX32(maxval, X[j+c*N]);
+ maxval = MAX32(maxval, -X[j+c*N]);
+ } while (++j<M*eBands[i+1]);
+
+ if (maxval > 0)
+ {
+ int shift = celt_ilog2(maxval)-10;
+ j=M*eBands[i]; do {
+ sum = MAC16_16(sum, EXTRACT16(VSHR32(X[j+c*N],shift)),
+ EXTRACT16(VSHR32(X[j+c*N],shift)));
+ } while (++j<M*eBands[i+1]);
+ /* We're adding one here to ensure the normalized band isn't larger than unity norm */
+ bandE[i+c*m->nbEBands] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift);
+ } else {
+ bandE[i+c*m->nbEBands] = EPSILON;
+ }
+ /*printf ("%f ", bandE[i+c*m->nbEBands]);*/
+ }
+ } while (++c<C);
+ /*printf ("\n");*/
+}
+
+/* Normalise each band such that the energy is one. */
+void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M)
+{
+ int i, c, N;
+ const opus_int16 *eBands = m->eBands;
+ N = M*m->shortMdctSize;
+ c=0; do {
+ i=0; do {
+ opus_val16 g;
+ int j,shift;
+ opus_val16 E;
+ shift = celt_zlog2(bandE[i+c*m->nbEBands])-13;
+ E = VSHR32(bandE[i+c*m->nbEBands], shift);
+ g = EXTRACT16(celt_rcp(SHL32(E,3)));
+ j=M*eBands[i]; do {
+ X[j+c*N] = MULT16_16_Q15(VSHR32(freq[j+c*N],shift-1),g);
+ } while (++j<M*eBands[i+1]);
+ } while (++i<end);
+ } while (++c<C);
+}
+
+#else /* FIXED_POINT */
+/* Compute the amplitude (sqrt energy) in each of the bands */
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M)
+{
+ int i, c, N;
+ const opus_int16 *eBands = m->eBands;
+ N = M*m->shortMdctSize;
+ c=0; do {
+ for (i=0;i<end;i++)
+ {
+ int j;
+ opus_val32 sum = 1e-27f;
+ for (j=M*eBands[i];j<M*eBands[i+1];j++)
+ sum += X[j+c*N]*X[j+c*N];
+ bandE[i+c*m->nbEBands] = celt_sqrt(sum);
+ /*printf ("%f ", bandE[i+c*m->nbEBands]);*/
+ }
+ } while (++c<C);
+ /*printf ("\n");*/
+}
+
+/* Normalise each band such that the energy is one. */
+void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M)
+{
+ int i, c, N;
+ const opus_int16 *eBands = m->eBands;
+ N = M*m->shortMdctSize;
+ c=0; do {
+ for (i=0;i<end;i++)
+ {
+ int j;
+ opus_val16 g = 1.f/(1e-27f+bandE[i+c*m->nbEBands]);
+ for (j=M*eBands[i];j<M*eBands[i+1];j++)
+ X[j+c*N] = freq[j+c*N]*g;
+ }
+ } while (++c<C);
+}
+
+#endif /* FIXED_POINT */
+
+/* De-normalise the energy to produce the synthesis from the unit-energy bands */
+void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, celt_sig * OPUS_RESTRICT freq, const celt_ener *bandE, int end, int C, int M)
+{
+ int i, c, N;
+ const opus_int16 *eBands = m->eBands;
+ N = M*m->shortMdctSize;
+ celt_assert2(C<=2, "denormalise_bands() not implemented for >2 channels");
+ c=0; do {
+ celt_sig * OPUS_RESTRICT f;
+ const celt_norm * OPUS_RESTRICT x;
+ f = freq+c*N;
+ x = X+c*N;
+ for (i=0;i<end;i++)
+ {
+ int j, band_end;
+ opus_val32 g = SHR32(bandE[i+c*m->nbEBands],1);
+ j=M*eBands[i];
+ band_end = M*eBands[i+1];
+ do {
+ *f++ = SHL32(MULT16_32_Q15(*x, g),2);
+ x++;
+ } while (++j<band_end);
+ }
+ for (i=M*eBands[end];i<N;i++)
+ *f++ = 0;
+ } while (++c<C);
+}
+
+/* This prevents energy collapse for transients with multiple short MDCTs */
+void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size,
+ int start, int end, opus_val16 *logE, opus_val16 *prev1logE,
+ opus_val16 *prev2logE, int *pulses, opus_uint32 seed)
+{
+ int c, i, j, k;
+ for (i=start;i<end;i++)
+ {
+ int N0;
+ opus_val16 thresh, sqrt_1;
+ int depth;
+#ifdef FIXED_POINT
+ int shift;
+ opus_val32 thresh32;
+#endif
+
+ N0 = m->eBands[i+1]-m->eBands[i];
+ /* depth in 1/8 bits */
+ depth = (1+pulses[i])/((m->eBands[i+1]-m->eBands[i])<<LM);
+
+#ifdef FIXED_POINT
+ thresh32 = SHR32(celt_exp2(-SHL16(depth, 10-BITRES)),1);
+ thresh = MULT16_32_Q15(QCONST16(0.5f, 15), MIN32(32767,thresh32));
+ {
+ opus_val32 t;
+ t = N0<<LM;
+ shift = celt_ilog2(t)>>1;
+ t = SHL32(t, (7-shift)<<1);
+ sqrt_1 = celt_rsqrt_norm(t);
+ }
+#else
+ thresh = .5f*celt_exp2(-.125f*depth);
+ sqrt_1 = celt_rsqrt(N0<<LM);
+#endif
+
+ c=0; do
+ {
+ celt_norm *X;
+ opus_val16 prev1;
+ opus_val16 prev2;
+ opus_val32 Ediff;
+ opus_val16 r;
+ int renormalize=0;
+ prev1 = prev1logE[c*m->nbEBands+i];
+ prev2 = prev2logE[c*m->nbEBands+i];
+ if (C==1)
+ {
+ prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]);
+ prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]);
+ }
+ Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2));
+ Ediff = MAX32(0, Ediff);
+
+#ifdef FIXED_POINT
+ if (Ediff < 16384)
+ {
+ opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1);
+ r = 2*MIN16(16383,r32);
+ } else {
+ r = 0;
+ }
+ if (LM==3)
+ r = MULT16_16_Q14(23170, MIN32(23169, r));
+ r = SHR16(MIN16(thresh, r),1);
+ r = SHR32(MULT16_16_Q15(sqrt_1, r),shift);
+#else
+ /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because
+ short blocks don't have the same energy as long */
+ r = 2.f*celt_exp2(-Ediff);
+ if (LM==3)
+ r *= 1.41421356f;
+ r = MIN16(thresh, r);
+ r = r*sqrt_1;
+#endif
+ X = X_+c*size+(m->eBands[i]<<LM);
+ for (k=0;k<1<<LM;k++)
+ {
+ /* Detect collapse */
+ if (!(collapse_masks[i*C+c]&1<<k))
+ {
+ /* Fill with noise */
+ for (j=0;j<N0;j++)
+ {
+ seed = celt_lcg_rand(seed);
+ X[(j<<LM)+k] = (seed&0x8000 ? r : -r);
+ }
+ renormalize = 1;
+ }
+ }
+ /* We just added some energy, so we need to renormalise */
+ if (renormalize)
+ renormalise_vector(X, N0<<LM, Q15ONE);
+ } while (++c<C);
+ }
+}
+
+static void intensity_stereo(const CELTMode *m, celt_norm *X, celt_norm *Y, const celt_ener *bandE, int bandID, int N)
+{
+ int i = bandID;
+ int j;
+ opus_val16 a1, a2;
+ opus_val16 left, right;
+ opus_val16 norm;
+#ifdef FIXED_POINT
+ int shift = celt_zlog2(MAX32(bandE[i], bandE[i+m->nbEBands]))-13;
+#endif
+ left = VSHR32(bandE[i],shift);
+ right = VSHR32(bandE[i+m->nbEBands],shift);
+ norm = EPSILON + celt_sqrt(EPSILON+MULT16_16(left,left)+MULT16_16(right,right));
+ a1 = DIV32_16(SHL32(EXTEND32(left),14),norm);
+ a2 = DIV32_16(SHL32(EXTEND32(right),14),norm);
+ for (j=0;j<N;j++)
+ {
+ celt_norm r, l;
+ l = X[j];
+ r = Y[j];
+ X[j] = MULT16_16_Q14(a1,l) + MULT16_16_Q14(a2,r);
+ /* Side is not encoded, no need to calculate */
+ }
+}
+
+static void stereo_split(celt_norm *X, celt_norm *Y, int N)
+{
+ int j;
+ for (j=0;j<N;j++)
+ {
+ celt_norm r, l;
+ l = MULT16_16_Q15(QCONST16(.70710678f,15), X[j]);
+ r = MULT16_16_Q15(QCONST16(.70710678f,15), Y[j]);
+ X[j] = l+r;
+ Y[j] = r-l;
+ }
+}
+
+static void stereo_merge(celt_norm *X, celt_norm *Y, opus_val16 mid, int N)
+{
+ int j;
+ opus_val32 xp=0, side=0;
+ opus_val32 El, Er;
+ opus_val16 mid2;
+#ifdef FIXED_POINT
+ int kl, kr;
+#endif
+ opus_val32 t, lgain, rgain;
+
+ /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */
+ for (j=0;j<N;j++)
+ {
+ xp = MAC16_16(xp, X[j], Y[j]);
+ side = MAC16_16(side, Y[j], Y[j]);
+ }
+ /* Compensating for the mid normalization */
+ xp = MULT16_32_Q15(mid, xp);
+ /* mid and side are in Q15, not Q14 like X and Y */
+ mid2 = SHR32(mid, 1);
+ El = MULT16_16(mid2, mid2) + side - 2*xp;
+ Er = MULT16_16(mid2, mid2) + side + 2*xp;
+ if (Er < QCONST32(6e-4f, 28) || El < QCONST32(6e-4f, 28))
+ {
+ for (j=0;j<N;j++)
+ Y[j] = X[j];
+ return;
+ }
+
+#ifdef FIXED_POINT
+ kl = celt_ilog2(El)>>1;
+ kr = celt_ilog2(Er)>>1;
+#endif
+ t = VSHR32(El, (kl-7)<<1);
+ lgain = celt_rsqrt_norm(t);
+ t = VSHR32(Er, (kr-7)<<1);
+ rgain = celt_rsqrt_norm(t);
+
+#ifdef FIXED_POINT
+ if (kl < 7)
+ kl = 7;
+ if (kr < 7)
+ kr = 7;
+#endif
+
+ for (j=0;j<N;j++)
+ {
+ celt_norm r, l;
+ /* Apply mid scaling (side is already scaled) */
+ l = MULT16_16_Q15(mid, X[j]);
+ r = Y[j];
+ X[j] = EXTRACT16(PSHR32(MULT16_16(lgain, SUB16(l,r)), kl+1));
+ Y[j] = EXTRACT16(PSHR32(MULT16_16(rgain, ADD16(l,r)), kr+1));
+ }
+}
+
+/* Decide whether we should spread the pulses in the current frame */
+int spreading_decision(const CELTMode *m, celt_norm *X, int *average,
+ int last_decision, int *hf_average, int *tapset_decision, int update_hf,
+ int end, int C, int M)
+{
+ int i, c, N0;
+ int sum = 0, nbBands=0;
+ const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
+ int decision;
+ int hf_sum=0;
+
+ celt_assert(end>0);
+
+ N0 = M*m->shortMdctSize;
+
+ if (M*(eBands[end]-eBands[end-1]) <= 8)
+ return SPREAD_NONE;
+ c=0; do {
+ for (i=0;i<end;i++)
+ {
+ int j, N, tmp=0;
+ int tcount[3] = {0,0,0};
+ celt_norm * OPUS_RESTRICT x = X+M*eBands[i]+c*N0;
+ N = M*(eBands[i+1]-eBands[i]);
+ if (N<=8)
+ continue;
+ /* Compute rough CDF of |x[j]| */
+ for (j=0;j<N;j++)
+ {
+ opus_val32 x2N; /* Q13 */
+
+ x2N = MULT16_16(MULT16_16_Q15(x[j], x[j]), N);
+ if (x2N < QCONST16(0.25f,13))
+ tcount[0]++;
+ if (x2N < QCONST16(0.0625f,13))
+ tcount[1]++;
+ if (x2N < QCONST16(0.015625f,13))
+ tcount[2]++;
+ }
+
+ /* Only include four last bands (8 kHz and up) */
+ if (i>m->nbEBands-4)
+ hf_sum += 32*(tcount[1]+tcount[0])/N;
+ tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N);
+ sum += tmp*256;
+ nbBands++;
+ }
+ } while (++c<C);
+
+ if (update_hf)
+ {
+ if (hf_sum)
+ hf_sum /= C*(4-m->nbEBands+end);
+ *hf_average = (*hf_average+hf_sum)>>1;
+ hf_sum = *hf_average;
+ if (*tapset_decision==2)
+ hf_sum += 4;
+ else if (*tapset_decision==0)
+ hf_sum -= 4;
+ if (hf_sum > 22)
+ *tapset_decision=2;
+ else if (hf_sum > 18)
+ *tapset_decision=1;
+ else
+ *tapset_decision=0;
+ }
+ /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/
+ celt_assert(nbBands>0); /*M*(eBands[end]-eBands[end-1]) <= 8 assures this*/
+ sum /= nbBands;
+ /* Recursive averaging */
+ sum = (sum+*average)>>1;
+ *average = sum;
+ /* Hysteresis */
+ sum = (3*sum + (((3-last_decision)<<7) + 64) + 2)>>2;
+ if (sum < 80)
+ {
+ decision = SPREAD_AGGRESSIVE;
+ } else if (sum < 256)
+ {
+ decision = SPREAD_NORMAL;
+ } else if (sum < 384)
+ {
+ decision = SPREAD_LIGHT;
+ } else {
+ decision = SPREAD_NONE;
+ }
+#ifdef FUZZING
+ decision = rand()&0x3;
+ *tapset_decision=rand()%3;
+#endif
+ return decision;
+}
+
+#ifdef MEASURE_NORM_MSE
+
+float MSE[30] = {0};
+int nbMSEBands = 0;
+int MSECount[30] = {0};
+
+void dump_norm_mse(void)
+{
+ int i;
+ for (i=0;i<nbMSEBands;i++)
+ {
+ printf ("%g ", MSE[i]/MSECount[i]);
+ }
+ printf ("\n");
+}
+
+void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C)
+{
+ static int init = 0;
+ int i;
+ if (!init)
+ {
+ atexit(dump_norm_mse);
+ init = 1;
+ }
+ for (i=0;i<m->nbEBands;i++)
+ {
+ int j;
+ int c;
+ float g;
+ if (bandE0[i]<10 || (C==2 && bandE0[i+m->nbEBands]<1))
+ continue;
+ c=0; do {
+ g = bandE[i+c*m->nbEBands]/(1e-15+bandE0[i+c*m->nbEBands]);
+ for (j=M*m->eBands[i];j<M*m->eBands[i+1];j++)
+ MSE[i] += (g*X[j+c*N]-X0[j+c*N])*(g*X[j+c*N]-X0[j+c*N]);
+ } while (++c<C);
+ MSECount[i]+=C;
+ }
+ nbMSEBands = m->nbEBands;
+}
+
+#endif
+
+/* Indexing table for converting from natural Hadamard to ordery Hadamard
+ This is essentially a bit-reversed Gray, on top of which we've added
+ an inversion of the order because we want the DC at the end rather than
+ the beginning. The lines are for N=2, 4, 8, 16 */
+static const int ordery_table[] = {
+ 1, 0,
+ 3, 0, 2, 1,
+ 7, 0, 4, 3, 6, 1, 5, 2,
+ 15, 0, 8, 7, 12, 3, 11, 4, 14, 1, 9, 6, 13, 2, 10, 5,
+};
+
+static void deinterleave_hadamard(celt_norm *X, int N0, int stride, int hadamard)
+{
+ int i,j;
+ VARDECL(celt_norm, tmp);
+ int N;
+ SAVE_STACK;
+ N = N0*stride;
+ ALLOC(tmp, N, celt_norm);
+ celt_assert(stride>0);
+ if (hadamard)
+ {
+ const int *ordery = ordery_table+stride-2;
+ for (i=0;i<stride;i++)
+ {
+ for (j=0;j<N0;j++)
+ tmp[ordery[i]*N0+j] = X[j*stride+i];
+ }
+ } else {
+ for (i=0;i<stride;i++)
+ for (j=0;j<N0;j++)
+ tmp[i*N0+j] = X[j*stride+i];
+ }
+ for (j=0;j<N;j++)
+ X[j] = tmp[j];
+ RESTORE_STACK;
+}
+
+static void interleave_hadamard(celt_norm *X, int N0, int stride, int hadamard)
+{
+ int i,j;
+ VARDECL(celt_norm, tmp);
+ int N;
+ SAVE_STACK;
+ N = N0*stride;
+ ALLOC(tmp, N, celt_norm);
+ if (hadamard)
+ {
+ const int *ordery = ordery_table+stride-2;
+ for (i=0;i<stride;i++)
+ for (j=0;j<N0;j++)
+ tmp[j*stride+i] = X[ordery[i]*N0+j];
+ } else {
+ for (i=0;i<stride;i++)
+ for (j=0;j<N0;j++)
+ tmp[j*stride+i] = X[i*N0+j];
+ }
+ for (j=0;j<N;j++)
+ X[j] = tmp[j];
+ RESTORE_STACK;
+}
+
+void haar1(celt_norm *X, int N0, int stride)
+{
+ int i, j;
+ N0 >>= 1;
+ for (i=0;i<stride;i++)
+ for (j=0;j<N0;j++)
+ {
+ celt_norm tmp1, tmp2;
+ tmp1 = MULT16_16_Q15(QCONST16(.70710678f,15), X[stride*2*j+i]);
+ tmp2 = MULT16_16_Q15(QCONST16(.70710678f,15), X[stride*(2*j+1)+i]);
+ X[stride*2*j+i] = tmp1 + tmp2;
+ X[stride*(2*j+1)+i] = tmp1 - tmp2;
+ }
+}
+
+static int compute_qn(int N, int b, int offset, int pulse_cap, int stereo)
+{
+ static const opus_int16 exp2_table8[8] =
+ {16384, 17866, 19483, 21247, 23170, 25267, 27554, 30048};
+ int qn, qb;
+ int N2 = 2*N-1;
+ if (stereo && N==2)
+ N2--;
+ /* The upper limit ensures that in a stereo split with itheta==16384, we'll
+ always have enough bits left over to code at least one pulse in the
+ side; otherwise it would collapse, since it doesn't get folded. */
+ qb = IMIN(b-pulse_cap-(4<<BITRES), (b+N2*offset)/N2);
+
+ qb = IMIN(8<<BITRES, qb);
+
+ if (qb<(1<<BITRES>>1)) {
+ qn = 1;
+ } else {
+ qn = exp2_table8[qb&0x7]>>(14-(qb>>BITRES));
+ qn = (qn+1)>>1<<1;
+ }
+ celt_assert(qn <= 256);
+ return qn;
+}
+
+/* This function is responsible for encoding and decoding a band for both
+ the mono and stereo case. Even in the mono case, it can split the band
+ in two and transmit the energy difference with the two half-bands. It
+ can be called recursively so bands can end up being split in 8 parts. */
+static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_norm *Y,
+ int N, int b, int spread, int B, int intensity, int tf_change, celt_norm *lowband, ec_ctx *ec,
+ opus_int32 *remaining_bits, int LM, celt_norm *lowband_out, const celt_ener *bandE, int level,
+ opus_uint32 *seed, opus_val16 gain, celt_norm *lowband_scratch, int fill)
+{
+ const unsigned char *cache;
+ int q;
+ int curr_bits;
+ int stereo, split;
+ int imid=0, iside=0;
+ int N0=N;
+ int N_B=N;
+ int N_B0;
+ int B0=B;
+ int time_divide=0;
+ int recombine=0;
+ int inv = 0;
+ opus_val16 mid=0, side=0;
+ int longBlocks;
+ unsigned cm=0;
+#ifdef RESYNTH
+ int resynth = 1;
+#else
+ int resynth = !encode;
+#endif
+
+ longBlocks = B0==1;
+
+ N_B /= B;
+ N_B0 = N_B;
+
+ split = stereo = Y != NULL;
+
+ /* Special case for one sample */
+ if (N==1)
+ {
+ int c;
+ celt_norm *x = X;
+ c=0; do {
+ int sign=0;
+ if (*remaining_bits>=1<<BITRES)
+ {
+ if (encode)
+ {
+ sign = x[0]<0;
+ ec_enc_bits(ec, sign, 1);
+ } else {
+ sign = ec_dec_bits(ec, 1);
+ }
+ *remaining_bits -= 1<<BITRES;
+ b-=1<<BITRES;
+ }
+ if (resynth)
+ x[0] = sign ? -NORM_SCALING : NORM_SCALING;
+ x = Y;
+ } while (++c<1+stereo);
+ if (lowband_out)
+ lowband_out[0] = SHR16(X[0],4);
+ return 1;
+ }
+
+ if (!stereo && level == 0)
+ {
+ int k;
+ if (tf_change>0)
+ recombine = tf_change;
+ /* Band recombining to increase frequency resolution */
+
+ if (lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1))
+ {
+ int j;
+ for (j=0;j<N;j++)
+ lowband_scratch[j] = lowband[j];
+ lowband = lowband_scratch;
+ }
+
+ for (k=0;k<recombine;k++)
+ {
+ static const unsigned char bit_interleave_table[16]={
+ 0,1,1,1,2,3,3,3,2,3,3,3,2,3,3,3
+ };
+ if (encode)
+ haar1(X, N>>k, 1<<k);
+ if (lowband)
+ haar1(lowband, N>>k, 1<<k);
+ fill = bit_interleave_table[fill&0xF]|bit_interleave_table[fill>>4]<<2;
+ }
+ B>>=recombine;
+ N_B<<=recombine;
+
+ /* Increasing the time resolution */
+ while ((N_B&1) == 0 && tf_change<0)
+ {
+ if (encode)
+ haar1(X, N_B, B);
+ if (lowband)
+ haar1(lowband, N_B, B);
+ fill |= fill<<B;
+ B <<= 1;
+ N_B >>= 1;
+ time_divide++;
+ tf_change++;
+ }
+ B0=B;
+ N_B0 = N_B;
+
+ /* Reorganize the samples in time order instead of frequency order */
+ if (B0>1)
+ {
+ if (encode)
+ deinterleave_hadamard(X, N_B>>recombine, B0<<recombine, longBlocks);
+ if (lowband)
+ deinterleave_hadamard(lowband, N_B>>recombine, B0<<recombine, longBlocks);
+ }
+ }
+
+ /* If we need 1.5 more bit than we can produce, split the band in two. */
+ cache = m->cache.bits + m->cache.index[(LM+1)*m->nbEBands+i];
+ if (!stereo && LM != -1 && b > cache[cache[0]]+12 && N>2)
+ {
+ N >>= 1;
+ Y = X+N;
+ split = 1;
+ LM -= 1;
+ if (B==1)
+ fill = (fill&1)|(fill<<1);
+ B = (B+1)>>1;
+ }
+
+ if (split)
+ {
+ int qn;
+ int itheta=0;
+ int mbits, sbits, delta;
+ int qalloc;
+ int pulse_cap;
+ int offset;
+ int orig_fill;
+ opus_int32 tell;
+
+ /* Decide on the resolution to give to the split parameter theta */
+ pulse_cap = m->logN[i]+LM*(1<<BITRES);
+ offset = (pulse_cap>>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET);
+ qn = compute_qn(N, b, offset, pulse_cap, stereo);
+ if (stereo && i>=intensity)
+ qn = 1;
+ if (encode)
+ {
+ /* theta is the atan() of the ratio between the (normalized)
+ side and mid. With just that parameter, we can re-scale both
+ mid and side because we know that 1) they have unit norm and
+ 2) they are orthogonal. */
+ itheta = stereo_itheta(X, Y, stereo, N);
+ }
+ tell = ec_tell_frac(ec);
+ if (qn!=1)
+ {
+ if (encode)
+ itheta = (itheta*qn+8192)>>14;
+
+ /* Entropy coding of the angle. We use a uniform pdf for the
+ time split, a step for stereo, and a triangular one for the rest. */
+ if (stereo && N>2)
+ {
+ int p0 = 3;
+ int x = itheta;
+ int x0 = qn/2;
+ int ft = p0*(x0+1) + x0;
+ /* Use a probability of p0 up to itheta=8192 and then use 1 after */
+ if (encode)
+ {
+ ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);
+ } else {
+ int fs;
+ fs=ec_decode(ec,ft);
+ if (fs<(x0+1)*p0)
+ x=fs/p0;
+ else
+ x=x0+1+(fs-(x0+1)*p0);
+ ec_dec_update(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);
+ itheta = x;
+ }
+ } else if (B0>1 || stereo) {
+ /* Uniform pdf */
+ if (encode)
+ ec_enc_uint(ec, itheta, qn+1);
+ else
+ itheta = ec_dec_uint(ec, qn+1);
+ } else {
+ int fs=1, ft;
+ ft = ((qn>>1)+1)*((qn>>1)+1);
+ if (encode)
+ {
+ int fl;
+
+ fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta;
+ fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 :
+ ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
+
+ ec_encode(ec, fl, fl+fs, ft);
+ } else {
+ /* Triangular pdf */
+ int fl=0;
+ int fm;
+ fm = ec_decode(ec, ft);
+
+ if (fm < ((qn>>1)*((qn>>1) + 1)>>1))
+ {
+ itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1;
+ fs = itheta + 1;
+ fl = itheta*(itheta + 1)>>1;
+ }
+ else
+ {
+ itheta = (2*(qn + 1)
+ - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1;
+ fs = qn + 1 - itheta;
+ fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
+ }
+
+ ec_dec_update(ec, fl, fl+fs, ft);
+ }
+ }
+ itheta = (opus_int32)itheta*16384/qn;
+ if (encode && stereo)
+ {
+ if (itheta==0)
+ intensity_stereo(m, X, Y, bandE, i, N);
+ else
+ stereo_split(X, Y, N);
+ }
+ /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate.
+ Let's do that at higher complexity */
+ } else if (stereo) {
+ if (encode)
+ {
+ inv = itheta > 8192;
+ if (inv)
+ {
+ int j;
+ for (j=0;j<N;j++)
+ Y[j] = -Y[j];
+ }
+ intensity_stereo(m, X, Y, bandE, i, N);
+ }
+ if (b>2<<BITRES && *remaining_bits > 2<<BITRES)
+ {
+ if (encode)
+ ec_enc_bit_logp(ec, inv, 2);
+ else
+ inv = ec_dec_bit_logp(ec, 2);
+ } else
+ inv = 0;
+ itheta = 0;
+ }
+ qalloc = ec_tell_frac(ec) - tell;
+ b -= qalloc;
+
+ orig_fill = fill;
+ if (itheta == 0)
+ {
+ imid = 32767;
+ iside = 0;
+ fill &= (1<<B)-1;
+ delta = -16384;
+ } else if (itheta == 16384)
+ {
+ imid = 0;
+ iside = 32767;
+ fill &= ((1<<B)-1)<<B;
+ delta = 16384;
+ } else {
+ imid = bitexact_cos(itheta);
+ iside = bitexact_cos(16384-itheta);
+ /* This is the mid vs side allocation that minimizes squared error
+ in that band. */
+ delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid));
+ }
+
+#ifdef FIXED_POINT
+ mid = imid;
+ side = iside;
+#else
+ mid = (1.f/32768)*imid;
+ side = (1.f/32768)*iside;
+#endif
+
+ /* This is a special case for N=2 that only works for stereo and takes
+ advantage of the fact that mid and side are orthogonal to encode
+ the side with just one bit. */
+ if (N==2 && stereo)
+ {
+ int c;
+ int sign=0;
+ celt_norm *x2, *y2;
+ mbits = b;
+ sbits = 0;
+ /* Only need one bit for the side */
+ if (itheta != 0 && itheta != 16384)
+ sbits = 1<<BITRES;
+ mbits -= sbits;
+ c = itheta > 8192;
+ *remaining_bits -= qalloc+sbits;
+
+ x2 = c ? Y : X;
+ y2 = c ? X : Y;
+ if (sbits)
+ {
+ if (encode)
+ {
+ /* Here we only need to encode a sign for the side */
+ sign = x2[0]*y2[1] - x2[1]*y2[0] < 0;
+ ec_enc_bits(ec, sign, 1);
+ } else {
+ sign = ec_dec_bits(ec, 1);
+ }
+ }
+ sign = 1-2*sign;
+ /* We use orig_fill here because we want to fold the side, but if
+ itheta==16384, we'll have cleared the low bits of fill. */
+ cm = quant_band(encode, m, i, x2, NULL, N, mbits, spread, B, intensity, tf_change, lowband, ec, remaining_bits, LM, lowband_out, NULL, level, seed, gain, lowband_scratch, orig_fill);
+ /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
+ and there's no need to worry about mixing with the other channel. */
+ y2[0] = -sign*x2[1];
+ y2[1] = sign*x2[0];
+ if (resynth)
+ {
+ celt_norm tmp;
+ X[0] = MULT16_16_Q15(mid, X[0]);
+ X[1] = MULT16_16_Q15(mid, X[1]);
+ Y[0] = MULT16_16_Q15(side, Y[0]);
+ Y[1] = MULT16_16_Q15(side, Y[1]);
+ tmp = X[0];
+ X[0] = SUB16(tmp,Y[0]);
+ Y[0] = ADD16(tmp,Y[0]);
+ tmp = X[1];
+ X[1] = SUB16(tmp,Y[1]);
+ Y[1] = ADD16(tmp,Y[1]);
+ }
+ } else {
+ /* "Normal" split code */
+ celt_norm *next_lowband2=NULL;
+ celt_norm *next_lowband_out1=NULL;
+ int next_level=0;
+ opus_int32 rebalance;
+
+ /* Give more bits to low-energy MDCTs than they would otherwise deserve */
+ if (B0>1 && !stereo && (itheta&0x3fff))
+ {
+ if (itheta > 8192)
+ /* Rough approximation for pre-echo masking */
+ delta -= delta>>(4-LM);
+ else
+ /* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */
+ delta = IMIN(0, delta + (N<<BITRES>>(5-LM)));
+ }
+ mbits = IMAX(0, IMIN(b, (b-delta)/2));
+ sbits = b-mbits;
+ *remaining_bits -= qalloc;
+
+ if (lowband && !stereo)
+ next_lowband2 = lowband+N; /* >32-bit split case */
+
+ /* Only stereo needs to pass on lowband_out. Otherwise, it's
+ handled at the end */
+ if (stereo)
+ next_lowband_out1 = lowband_out;
+ else
+ next_level = level+1;
+
+ rebalance = *remaining_bits;
+ if (mbits >= sbits)
+ {
+ /* In stereo mode, we do not apply a scaling to the mid because we need the normalized
+ mid for folding later */
+ cm = quant_band(encode, m, i, X, NULL, N, mbits, spread, B, intensity, tf_change,
+ lowband, ec, remaining_bits, LM, next_lowband_out1,
+ NULL, next_level, seed, stereo ? Q15ONE : MULT16_16_P15(gain,mid), lowband_scratch, fill);
+ rebalance = mbits - (rebalance-*remaining_bits);
+ if (rebalance > 3<<BITRES && itheta!=0)
+ sbits += rebalance - (3<<BITRES);
+
+ /* For a stereo split, the high bits of fill are always zero, so no
+ folding will be done to the side. */
+ cm |= quant_band(encode, m, i, Y, NULL, N, sbits, spread, B, intensity, tf_change,
+ next_lowband2, ec, remaining_bits, LM, NULL,
+ NULL, next_level, seed, MULT16_16_P15(gain,side), NULL, fill>>B)<<((B0>>1)&(stereo-1));
+ } else {
+ /* For a stereo split, the high bits of fill are always zero, so no
+ folding will be done to the side. */
+ cm = quant_band(encode, m, i, Y, NULL, N, sbits, spread, B, intensity, tf_change,
+ next_lowband2, ec, remaining_bits, LM, NULL,
+ NULL, next_level, seed, MULT16_16_P15(gain,side), NULL, fill>>B)<<((B0>>1)&(stereo-1));
+ rebalance = sbits - (rebalance-*remaining_bits);
+ if (rebalance > 3<<BITRES && itheta!=16384)
+ mbits += rebalance - (3<<BITRES);
+ /* In stereo mode, we do not apply a scaling to the mid because we need the normalized
+ mid for folding later */
+ cm |= quant_band(encode, m, i, X, NULL, N, mbits, spread, B, intensity, tf_change,
+ lowband, ec, remaining_bits, LM, next_lowband_out1,
+ NULL, next_level, seed, stereo ? Q15ONE : MULT16_16_P15(gain,mid), lowband_scratch, fill);
+ }
+ }
+
+ } else {
+ /* This is the basic no-split case */
+ q = bits2pulses(m, i, LM, b);
+ curr_bits = pulses2bits(m, i, LM, q);
+ *remaining_bits -= curr_bits;
+
+ /* Ensures we can never bust the budget */
+ while (*remaining_bits < 0 && q > 0)
+ {
+ *remaining_bits += curr_bits;
+ q--;
+ curr_bits = pulses2bits(m, i, LM, q);
+ *remaining_bits -= curr_bits;
+ }
+
+ if (q!=0)
+ {
+ int K = get_pulses(q);
+
+ /* Finally do the actual quantization */
+ if (encode)
+ {
+ cm = alg_quant(X, N, K, spread, B, ec
+#ifdef RESYNTH
+ , gain
+#endif
+ );
+ } else {
+ cm = alg_unquant(X, N, K, spread, B, ec, gain);
+ }
+ } else {
+ /* If there's no pulse, fill the band anyway */
+ int j;
+ if (resynth)
+ {
+ unsigned cm_mask;
+ /*B can be as large as 16, so this shift might overflow an int on a
+ 16-bit platform; use a long to get defined behavior.*/
+ cm_mask = (unsigned)(1UL<<B)-1;
+ fill &= cm_mask;
+ if (!fill)
+ {
+ for (j=0;j<N;j++)
+ X[j] = 0;
+ } else {
+ if (lowband == NULL)
+ {
+ /* Noise */
+ for (j=0;j<N;j++)
+ {
+ *seed = celt_lcg_rand(*seed);
+ X[j] = (celt_norm)((opus_int32)*seed>>20);
+ }
+ cm = cm_mask;
+ } else {
+ /* Folded spectrum */
+ for (j=0;j<N;j++)
+ {
+ opus_val16 tmp;
+ *seed = celt_lcg_rand(*seed);
+ /* About 48 dB below the "normal" folding level */
+ tmp = QCONST16(1.0f/256, 10);
+ tmp = (*seed)&0x8000 ? tmp : -tmp;
+ X[j] = lowband[j]+tmp;
+ }
+ cm = fill;
+ }
+ renormalise_vector(X, N, gain);
+ }
+ }
+ }
+ }
+
+ /* This code is used by the decoder and by the resynthesis-enabled encoder */
+ if (resynth)
+ {
+ if (stereo)
+ {
+ if (N!=2)
+ stereo_merge(X, Y, mid, N);
+ if (inv)
+ {
+ int j;
+ for (j=0;j<N;j++)
+ Y[j] = -Y[j];
+ }
+ } else if (level == 0)
+ {
+ int k;
+
+ /* Undo the sample reorganization going from time order to frequency order */
+ if (B0>1)
+ interleave_hadamard(X, N_B>>recombine, B0<<recombine, longBlocks);
+
+ /* Undo time-freq changes that we did earlier */
+ N_B = N_B0;
+ B = B0;
+ for (k=0;k<time_divide;k++)
+ {
+ B >>= 1;
+ N_B <<= 1;
+ cm |= cm>>B;
+ haar1(X, N_B, B);
+ }
+
+ for (k=0;k<recombine;k++)
+ {
+ static const unsigned char bit_deinterleave_table[16]={
+ 0x00,0x03,0x0C,0x0F,0x30,0x33,0x3C,0x3F,
+ 0xC0,0xC3,0xCC,0xCF,0xF0,0xF3,0xFC,0xFF
+ };
+ cm = bit_deinterleave_table[cm];
+ haar1(X, N0>>k, 1<<k);
+ }
+ B<<=recombine;
+
+ /* Scale output for later folding */
+ if (lowband_out)
+ {
+ int j;
+ opus_val16 n;
+ n = celt_sqrt(SHL32(EXTEND32(N0),22));
+ for (j=0;j<N0;j++)
+ lowband_out[j] = MULT16_16_Q15(n,X[j]);
+ }
+ cm &= (1<<B)-1;
+ }
+ }
+ return cm;
+}
+
+void quant_all_bands(int encode, const CELTMode *m, int start, int end,
+ celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
+ int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res,
+ opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int LM, int codedBands, opus_uint32 *seed)
+{
+ int i;
+ opus_int32 remaining_bits;
+ const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
+ celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2;
+ VARDECL(celt_norm, _norm);
+ VARDECL(celt_norm, lowband_scratch);
+ int B;
+ int M;
+ int lowband_offset;
+ int update_lowband = 1;
+ int C = Y_ != NULL ? 2 : 1;
+#ifdef RESYNTH
+ int resynth = 1;
+#else
+ int resynth = !encode;
+#endif
+ SAVE_STACK;
+
+ M = 1<<LM;
+ B = shortBlocks ? M : 1;
+ ALLOC(_norm, C*M*eBands[m->nbEBands], celt_norm);
+ ALLOC(lowband_scratch, M*(eBands[m->nbEBands]-eBands[m->nbEBands-1]), celt_norm);
+ norm = _norm;
+ norm2 = norm + M*eBands[m->nbEBands];
+
+ lowband_offset = 0;
+ for (i=start;i<end;i++)
+ {
+ opus_int32 tell;
+ int b;
+ int N;
+ opus_int32 curr_balance;
+ int effective_lowband=-1;
+ celt_norm * OPUS_RESTRICT X, * OPUS_RESTRICT Y;
+ int tf_change=0;
+ unsigned x_cm;
+ unsigned y_cm;
+
+ X = X_+M*eBands[i];
+ if (Y_!=NULL)
+ Y = Y_+M*eBands[i];
+ else
+ Y = NULL;
+ N = M*eBands[i+1]-M*eBands[i];
+ tell = ec_tell_frac(ec);
+
+ /* Compute how many bits we want to allocate to this band */
+ if (i != start)
+ balance -= tell;
+ remaining_bits = total_bits-tell-1;
+ if (i <= codedBands-1)
+ {
+ curr_balance = balance / IMIN(3, codedBands-i);
+ b = IMAX(0, IMIN(16383, IMIN(remaining_bits+1,pulses[i]+curr_balance)));
+ } else {
+ b = 0;
+ }
+
+ if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0))
+ lowband_offset = i;
+
+ tf_change = tf_res[i];
+ if (i>=m->effEBands)
+ {
+ X=norm;
+ if (Y_!=NULL)
+ Y = norm;
+ }
+
+ /* Get a conservative estimate of the collapse_mask's for the bands we're
+ going to be folding from. */
+ if (lowband_offset != 0 && (spread!=SPREAD_AGGRESSIVE || B>1 || tf_change<0))
+ {
+ int fold_start;
+ int fold_end;
+ int fold_i;
+ /* This ensures we never repeat spectral content within one band */
+ effective_lowband = IMAX(M*eBands[start], M*eBands[lowband_offset]-N);
+ fold_start = lowband_offset;
+ while(M*eBands[--fold_start] > effective_lowband);
+ fold_end = lowband_offset-1;
+ while(M*eBands[++fold_end] < effective_lowband+N);
+ x_cm = y_cm = 0;
+ fold_i = fold_start; do {
+ x_cm |= collapse_masks[fold_i*C+0];
+ y_cm |= collapse_masks[fold_i*C+C-1];
+ } while (++fold_i<fold_end);
+ }
+ /* Otherwise, we'll be using the LCG to fold, so all blocks will (almost
+ always) be non-zero.*/
+ else
+ x_cm = y_cm = (1<<B)-1;
+
+ if (dual_stereo && i==intensity)
+ {
+ int j;
+
+ /* Switch off dual stereo to do intensity */
+ dual_stereo = 0;
+ if (resynth)
+ for (j=M*eBands[start];j<M*eBands[i];j++)
+ norm[j] = HALF32(norm[j]+norm2[j]);
+ }
+ if (dual_stereo)
+ {
+ x_cm = quant_band(encode, m, i, X, NULL, N, b/2, spread, B, intensity, tf_change,
+ effective_lowband != -1 ? norm+effective_lowband : NULL, ec, &remaining_bits, LM,
+ norm+M*eBands[i], bandE, 0, seed, Q15ONE, lowband_scratch, x_cm);
+ y_cm = quant_band(encode, m, i, Y, NULL, N, b/2, spread, B, intensity, tf_change,
+ effective_lowband != -1 ? norm2+effective_lowband : NULL, ec, &remaining_bits, LM,
+ norm2+M*eBands[i], bandE, 0, seed, Q15ONE, lowband_scratch, y_cm);
+ } else {
+ x_cm = quant_band(encode, m, i, X, Y, N, b, spread, B, intensity, tf_change,
+ effective_lowband != -1 ? norm+effective_lowband : NULL, ec, &remaining_bits, LM,
+ norm+M*eBands[i], bandE, 0, seed, Q15ONE, lowband_scratch, x_cm|y_cm);
+ y_cm = x_cm;
+ }
+ collapse_masks[i*C+0] = (unsigned char)x_cm;
+ collapse_masks[i*C+C-1] = (unsigned char)y_cm;
+ balance += pulses[i] + tell;
+
+ /* Update the folding position only as long as we have 1 bit/sample depth */
+ update_lowband = b>(N<<BITRES);
+ }
+ RESTORE_STACK;
+}
+
diff --git a/lib/rbcodec/codecs/libopus/celt/bands.h b/lib/rbcodec/codecs/libopus/celt/bands.h
new file mode 100644
index 0000000000..9ff8ffd7ba
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/bands.h
@@ -0,0 +1,95 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2008-2009 Gregory Maxwell
+ Written by Jean-Marc Valin and Gregory Maxwell */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 BANDS_H
+#define BANDS_H
+
+#include "arch.h"
+#include "modes.h"
+#include "entenc.h"
+#include "entdec.h"
+#include "rate.h"
+
+/** Compute the amplitude (sqrt energy) in each of the bands
+ * @param m Mode data
+ * @param X Spectrum
+ * @param bands Square root of the energy for each band (returned)
+ */
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M);
+
+/*void compute_noise_energies(const CELTMode *m, const celt_sig *X, const opus_val16 *tonality, celt_ener *bandE);*/
+
+/** Normalise each band of X such that the energy in each band is
+ equal to 1
+ * @param m Mode data
+ * @param X Spectrum (returned normalised)
+ * @param bands Square root of the energy for each band
+ */
+void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M);
+
+/** Denormalise each band of X to restore full amplitude
+ * @param m Mode data
+ * @param X Spectrum (returned de-normalised)
+ * @param bands Square root of the energy for each band
+ */
+void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, celt_sig * OPUS_RESTRICT freq, const celt_ener *bandE, int end, int C, int M);
+
+#define SPREAD_NONE (0)
+#define SPREAD_LIGHT (1)
+#define SPREAD_NORMAL (2)
+#define SPREAD_AGGRESSIVE (3)
+
+int spreading_decision(const CELTMode *m, celt_norm *X, int *average,
+ int last_decision, int *hf_average, int *tapset_decision, int update_hf,
+ int end, int C, int M);
+
+#ifdef MEASURE_NORM_MSE
+void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C);
+#endif
+
+void haar1(celt_norm *X, int N0, int stride);
+
+/** Quantisation/encoding of the residual spectrum
+ * @param m Mode data
+ * @param X Residual (normalised)
+ * @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
+ * @param enc Entropy encoder
+ */
+void quant_all_bands(int encode, const CELTMode *m, int start, int end,
+ celt_norm * X, celt_norm * Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
+ int time_domain, int fold, int dual_stereo, int intensity, int *tf_res,
+ opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed);
+
+void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size,
+ int start, int end, opus_val16 *logE, opus_val16 *prev1logE,
+ opus_val16 *prev2logE, int *pulses, opus_uint32 seed);
+
+opus_uint32 celt_lcg_rand(opus_uint32 seed);
+
+#endif /* BANDS_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/celt.c b/lib/rbcodec/codecs/libopus/celt/celt.c
new file mode 100644
index 0000000000..8d42cc95b3
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/celt.c
@@ -0,0 +1,2870 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2010 Xiph.Org Foundation
+ Copyright (c) 2008 Gregory Maxwell
+ Written by Jean-Marc Valin and Gregory Maxwell */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#define CELT_C
+
+#include "os_support.h"
+#include "mdct.h"
+#include <math.h>
+#include "celt.h"
+#include "pitch.h"
+#include "bands.h"
+#include "modes.h"
+#include "entcode.h"
+#include "quant_bands.h"
+#include "rate.h"
+#include "stack_alloc.h"
+#include "mathops.h"
+#include "float_cast.h"
+#include <stdarg.h>
+#include "celt_lpc.h"
+#include "vq.h"
+
+#ifndef OPUS_VERSION
+#define OPUS_VERSION "unknown"
+#endif
+
+#ifdef CUSTOM_MODES
+#define OPUS_CUSTOM_NOSTATIC
+#else
+#define OPUS_CUSTOM_NOSTATIC static inline
+#endif
+
+static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0};
+/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
+static const unsigned char spread_icdf[4] = {25, 23, 2, 0};
+
+static const unsigned char tapset_icdf[3]={2,1,0};
+
+#ifdef CUSTOM_MODES
+static const unsigned char toOpusTable[20] = {
+ 0xE0, 0xE8, 0xF0, 0xF8,
+ 0xC0, 0xC8, 0xD0, 0xD8,
+ 0xA0, 0xA8, 0xB0, 0xB8,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x88, 0x90, 0x98,
+};
+
+static const unsigned char fromOpusTable[16] = {
+ 0x80, 0x88, 0x90, 0x98,
+ 0x40, 0x48, 0x50, 0x58,
+ 0x20, 0x28, 0x30, 0x38,
+ 0x00, 0x08, 0x10, 0x18
+};
+
+static inline int toOpus(unsigned char c)
+{
+ int ret=0;
+ if (c<0xA0)
+ ret = toOpusTable[c>>3];
+ if (ret == 0)
+ return -1;
+ else
+ return ret|(c&0x7);
+}
+
+static inline int fromOpus(unsigned char c)
+{
+ if (c<0x80)
+ return -1;
+ else
+ return fromOpusTable[(c>>3)-16] | (c&0x7);
+}
+#endif /* CUSTOM_MODES */
+
+#define COMBFILTER_MAXPERIOD 1024
+#define COMBFILTER_MINPERIOD 15
+
+static int resampling_factor(opus_int32 rate)
+{
+ int ret;
+ switch (rate)
+ {
+ case 48000:
+ ret = 1;
+ break;
+ case 24000:
+ ret = 2;
+ break;
+ case 16000:
+ ret = 3;
+ break;
+ case 12000:
+ ret = 4;
+ break;
+ case 8000:
+ ret = 6;
+ break;
+ default:
+#ifndef CUSTOM_MODES
+ celt_assert(0);
+#endif
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+/** Encoder state
+ @brief Encoder state
+ */
+struct OpusCustomEncoder {
+ const OpusCustomMode *mode; /**< Mode used by the encoder */
+ int overlap;
+ int channels;
+ int stream_channels;
+
+ int force_intra;
+ int clip;
+ int disable_pf;
+ int complexity;
+ int upsample;
+ int start, end;
+
+ opus_int32 bitrate;
+ int vbr;
+ int signalling;
+ int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
+ int loss_rate;
+ int lsb_depth;
+
+ /* Everything beyond this point gets cleared on a reset */
+#define ENCODER_RESET_START rng
+
+ opus_uint32 rng;
+ int spread_decision;
+ opus_val32 delayedIntra;
+ int tonal_average;
+ int lastCodedBands;
+ int hf_average;
+ int tapset_decision;
+
+ int prefilter_period;
+ opus_val16 prefilter_gain;
+ int prefilter_tapset;
+#ifdef RESYNTH
+ int prefilter_period_old;
+ opus_val16 prefilter_gain_old;
+ int prefilter_tapset_old;
+#endif
+ int consec_transient;
+
+ opus_val32 preemph_memE[2];
+ opus_val32 preemph_memD[2];
+
+ /* VBR-related parameters */
+ opus_int32 vbr_reservoir;
+ opus_int32 vbr_drift;
+ opus_int32 vbr_offset;
+ opus_int32 vbr_count;
+
+#ifdef RESYNTH
+ celt_sig syn_mem[2][2*MAX_PERIOD];
+#endif
+
+ celt_sig in_mem[1]; /* Size = channels*mode->overlap */
+ /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_PERIOD */
+ /* celt_sig overlap_mem[], Size = channels*mode->overlap */
+ /* opus_val16 oldEBands[], Size = 2*channels*mode->nbEBands */
+};
+
+int celt_encoder_get_size(int channels)
+{
+ CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
+ return opus_custom_encoder_get_size(mode, channels);
+}
+
+OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels)
+{
+ int size = sizeof(struct CELTEncoder)
+ + (2*channels*mode->overlap-1)*sizeof(celt_sig)
+ + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig)
+ + 3*channels*mode->nbEBands*sizeof(opus_val16);
+ return size;
+}
+
+#ifdef CUSTOM_MODES
+CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error)
+{
+ int ret;
+ CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels));
+ /* init will handle the NULL case */
+ ret = opus_custom_encoder_init(st, mode, channels);
+ if (ret != OPUS_OK)
+ {
+ opus_custom_encoder_destroy(st);
+ st = NULL;
+ }
+ if (error)
+ *error = ret;
+ return st;
+}
+#endif /* CUSTOM_MODES */
+
+int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels)
+{
+ int ret;
+ ret = opus_custom_encoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels);
+ if (ret != OPUS_OK)
+ return ret;
+ st->upsample = resampling_factor(sampling_rate);
+ return OPUS_OK;
+}
+
+OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels)
+{
+ if (channels < 0 || channels > 2)
+ return OPUS_BAD_ARG;
+
+ if (st==NULL || mode==NULL)
+ return OPUS_ALLOC_FAIL;
+
+ OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels));
+
+ st->mode = mode;
+ st->overlap = mode->overlap;
+ st->stream_channels = st->channels = channels;
+
+ st->upsample = 1;
+ st->start = 0;
+ st->end = st->mode->effEBands;
+ st->signalling = 1;
+
+ st->constrained_vbr = 1;
+ st->clip = 1;
+
+ st->bitrate = OPUS_BITRATE_MAX;
+ st->vbr = 0;
+ st->force_intra = 0;
+ st->complexity = 5;
+ st->lsb_depth=24;
+
+ opus_custom_encoder_ctl(st, OPUS_RESET_STATE);
+
+ return OPUS_OK;
+}
+
+#ifdef CUSTOM_MODES
+void opus_custom_encoder_destroy(CELTEncoder *st)
+{
+ opus_free(st);
+}
+#endif /* CUSTOM_MODES */
+
+static inline opus_val16 SIG2WORD16(celt_sig x)
+{
+#ifdef FIXED_POINT
+ x = PSHR32(x, SIG_SHIFT);
+ x = MAX32(x, -32768);
+ x = MIN32(x, 32767);
+ return EXTRACT16(x);
+#else
+ return (opus_val16)x;
+#endif
+}
+
+static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C,
+ int overlap)
+{
+ int i;
+ VARDECL(opus_val16, tmp);
+ opus_val32 mem0=0,mem1=0;
+ int is_transient = 0;
+ int block;
+ int N;
+ VARDECL(opus_val16, bins);
+ SAVE_STACK;
+ ALLOC(tmp, len, opus_val16);
+
+ block = overlap/2;
+ N=len/block;
+ ALLOC(bins, N, opus_val16);
+ if (C==1)
+ {
+ for (i=0;i<len;i++)
+ tmp[i] = SHR32(in[i],SIG_SHIFT);
+ } else {
+ for (i=0;i<len;i++)
+ tmp[i] = SHR32(ADD32(in[i],in[i+len]), SIG_SHIFT+1);
+ }
+
+ /* High-pass filter: (1 - 2*z^-1 + z^-2) / (1 - z^-1 + .5*z^-2) */
+ for (i=0;i<len;i++)
+ {
+ opus_val32 x,y;
+ x = tmp[i];
+ y = ADD32(mem0, x);
+#ifdef FIXED_POINT
+ mem0 = mem1 + y - SHL32(x,1);
+ mem1 = x - SHR32(y,1);
+#else
+ mem0 = mem1 + y - 2*x;
+ mem1 = x - .5f*y;
+#endif
+ tmp[i] = EXTRACT16(SHR32(y,2));
+ }
+ /* First few samples are bad because we don't propagate the memory */
+ for (i=0;i<12;i++)
+ tmp[i] = 0;
+
+ for (i=0;i<N;i++)
+ {
+ int j;
+ opus_val16 max_abs=0;
+ for (j=0;j<block;j++)
+ max_abs = MAX16(max_abs, ABS16(tmp[i*block+j]));
+ bins[i] = max_abs;
+ }
+ for (i=0;i<N;i++)
+ {
+ int j;
+ int conseq=0;
+ opus_val16 t1, t2, t3;
+
+ t1 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
+ t2 = MULT16_16_Q15(QCONST16(.4f, 15), bins[i]);
+ t3 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
+ for (j=0;j<i;j++)
+ {
+ if (bins[j] < t1)
+ conseq++;
+ if (bins[j] < t2)
+ conseq++;
+ else
+ conseq = 0;
+ }
+ if (conseq>=3)
+ is_transient=1;
+ conseq = 0;
+ for (j=i+1;j<N;j++)
+ {
+ if (bins[j] < t3)
+ conseq++;
+ else
+ conseq = 0;
+ }
+ if (conseq>=7)
+ is_transient=1;
+ }
+ RESTORE_STACK;
+#ifdef FUZZING
+ is_transient = rand()&0x1;
+#endif
+ return is_transient;
+}
+
+/** Apply window and compute the MDCT for all sub-frames and
+ all channels in a frame */
+static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS_RESTRICT in, celt_sig * OPUS_RESTRICT out, int C, int LM)
+{
+ if (C==1 && !shortBlocks)
+ {
+ const int overlap = OVERLAP(mode);
+ clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM, 1);
+ } else {
+ const int overlap = OVERLAP(mode);
+ int N = mode->shortMdctSize<<LM;
+ int B = 1;
+ int b, c;
+ if (shortBlocks)
+ {
+ N = mode->shortMdctSize;
+ B = shortBlocks;
+ }
+ c=0; do {
+ for (b=0;b<B;b++)
+ {
+ /* Interleaving the sub-frames while doing the MDCTs */
+ clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N, &out[b+c*N*B], mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B);
+ }
+ } while (++c<C);
+ }
+}
+
+/** Compute the IMDCT and apply window for all sub-frames and
+ all channels in a frame */
+static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X,
+ celt_sig * OPUS_RESTRICT out_mem[],
+ celt_sig * OPUS_RESTRICT overlap_mem[], int C, int LM)
+{
+ int c;
+ const int N = mode->shortMdctSize<<LM;
+ const int overlap = OVERLAP(mode);
+ VARDECL(opus_val32, x);
+ SAVE_STACK;
+
+ ALLOC(x, N+overlap, opus_val32);
+ c=0; do {
+ int j;
+ int b;
+ int N2 = N;
+ int B = 1;
+
+ if (shortBlocks)
+ {
+ N2 = mode->shortMdctSize;
+ B = shortBlocks;
+ }
+ /* Prevents problems from the imdct doing the overlap-add */
+ OPUS_CLEAR(x, overlap);
+
+ for (b=0;b<B;b++)
+ {
+ /* IMDCT on the interleaved the sub-frames */
+ clt_mdct_backward(&mode->mdct, &X[b+c*N2*B], x+N2*b, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B);
+ }
+
+ for (j=0;j<overlap;j++)
+ out_mem[c][j] = x[j] + overlap_mem[c][j];
+ for (;j<N;j++)
+ out_mem[c][j] = x[j];
+ for (j=0;j<overlap;j++)
+ overlap_mem[c][j] = x[N+j];
+ } while (++c<C);
+ RESTORE_STACK;
+}
+
+static void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem)
+{
+ int c;
+ int count=0;
+ c=0; do {
+ int j;
+ celt_sig * OPUS_RESTRICT x;
+ opus_val16 * OPUS_RESTRICT y;
+ celt_sig m = mem[c];
+ x =in[c];
+ y = pcm+c;
+ for (j=0;j<N;j++)
+ {
+ celt_sig tmp = *x + m;
+ m = MULT16_32_Q15(coef[0], tmp)
+ - MULT16_32_Q15(coef[1], *x);
+ tmp = SHL32(MULT16_32_Q15(coef[3], tmp), 2);
+ x++;
+ /* Technically the store could be moved outside of the if because
+ the stores we don't want will just be overwritten */
+ if (count==0)
+ *y = SCALEOUT(SIG2WORD16(tmp));
+ if (++count==downsample)
+ {
+ y+=C;
+ count=0;
+ }
+ }
+ mem[c] = m;
+ } while (++c<C);
+}
+
+static void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
+ opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
+ const opus_val16 *window, int overlap)
+{
+ int i;
+ /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
+ opus_val16 g00, g01, g02, g10, g11, g12;
+ static const opus_val16 gains[3][3] = {
+ {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
+ {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
+ {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
+ g00 = MULT16_16_Q15(g0, gains[tapset0][0]);
+ g01 = MULT16_16_Q15(g0, gains[tapset0][1]);
+ g02 = MULT16_16_Q15(g0, gains[tapset0][2]);
+ g10 = MULT16_16_Q15(g1, gains[tapset1][0]);
+ g11 = MULT16_16_Q15(g1, gains[tapset1][1]);
+ g12 = MULT16_16_Q15(g1, gains[tapset1][2]);
+ for (i=0;i<overlap;i++)
+ {
+ opus_val16 f;
+ f = MULT16_16_Q15(window[i],window[i]);
+ y[i] = x[i]
+ + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
+ + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),x[i-T0-1])
+ + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),x[i-T0+1])
+ + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),x[i-T0-2])
+ + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),x[i-T0+2])
+ + MULT16_32_Q15(MULT16_16_Q15(f,g10),x[i-T1])
+ + MULT16_32_Q15(MULT16_16_Q15(f,g11),x[i-T1-1])
+ + MULT16_32_Q15(MULT16_16_Q15(f,g11),x[i-T1+1])
+ + MULT16_32_Q15(MULT16_16_Q15(f,g12),x[i-T1-2])
+ + MULT16_32_Q15(MULT16_16_Q15(f,g12),x[i-T1+2]);
+
+ }
+ for (i=overlap;i<N;i++)
+ y[i] = x[i]
+ + MULT16_32_Q15(g10,x[i-T1])
+ + MULT16_32_Q15(g11,x[i-T1-1])
+ + MULT16_32_Q15(g11,x[i-T1+1])
+ + MULT16_32_Q15(g12,x[i-T1-2])
+ + MULT16_32_Q15(g12,x[i-T1+2]);
+}
+
+static const signed char tf_select_table[4][8] = {
+ {0, -1, 0, -1, 0,-1, 0,-1},
+ {0, -1, 0, -2, 1, 0, 1,-1},
+ {0, -2, 0, -3, 2, 0, 1,-1},
+ {0, -2, 0, -3, 3, 0, 1,-1},
+};
+
+static opus_val32 l1_metric(const celt_norm *tmp, int N, int LM, int width)
+{
+ int i, j;
+ static const opus_val16 sqrtM_1[4] = {Q15ONE, QCONST16(.70710678f,15), QCONST16(0.5f,15), QCONST16(0.35355339f,15)};
+ opus_val32 L1;
+ opus_val16 bias;
+ L1=0;
+ for (i=0;i<1<<LM;i++)
+ {
+ opus_val32 L2 = 0;
+ for (j=0;j<N>>LM;j++)
+ L2 = MAC16_16(L2, tmp[(j<<LM)+i], tmp[(j<<LM)+i]);
+ L1 += celt_sqrt(L2);
+ }
+ L1 = MULT16_32_Q15(sqrtM_1[LM], L1);
+ if (width==1)
+ bias = QCONST16(.12f,15)*LM;
+ else if (width==2)
+ bias = QCONST16(.05f,15)*LM;
+ else
+ bias = QCONST16(.02f,15)*LM;
+ L1 = MAC16_32_Q15(L1, bias, L1);
+ return L1;
+}
+
+static int tf_analysis(const CELTMode *m, int len, int C, int isTransient,
+ int *tf_res, int nbCompressedBytes, celt_norm *X, int N0, int LM,
+ int *tf_sum)
+{
+ int i;
+ VARDECL(int, metric);
+ int cost0;
+ int cost1;
+ VARDECL(int, path0);
+ VARDECL(int, path1);
+ VARDECL(celt_norm, tmp);
+ int lambda;
+ int tf_select=0;
+ SAVE_STACK;
+
+ if (nbCompressedBytes<15*C)
+ {
+ *tf_sum = 0;
+ for (i=0;i<len;i++)
+ tf_res[i] = isTransient;
+ return 0;
+ }
+ if (nbCompressedBytes<40)
+ lambda = 12;
+ else if (nbCompressedBytes<60)
+ lambda = 6;
+ else if (nbCompressedBytes<100)
+ lambda = 4;
+ else
+ lambda = 3;
+
+ ALLOC(metric, len, int);
+ ALLOC(tmp, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
+ ALLOC(path0, len, int);
+ ALLOC(path1, len, int);
+
+ *tf_sum = 0;
+ for (i=0;i<len;i++)
+ {
+ int j, k, N;
+ opus_val32 L1, best_L1;
+ int best_level=0;
+ N = (m->eBands[i+1]-m->eBands[i])<<LM;
+ for (j=0;j<N;j++)
+ tmp[j] = X[j+(m->eBands[i]<<LM)];
+ /* Just add the right channel if we're in stereo */
+ if (C==2)
+ for (j=0;j<N;j++)
+ tmp[j] = ADD16(SHR16(tmp[j], 1),SHR16(X[N0+j+(m->eBands[i]<<LM)], 1));
+ L1 = l1_metric(tmp, N, isTransient ? LM : 0, N>>LM);
+ best_L1 = L1;
+ /*printf ("%f ", L1);*/
+ for (k=0;k<LM;k++)
+ {
+ int B;
+
+ if (isTransient)
+ B = (LM-k-1);
+ else
+ B = k+1;
+
+ if (isTransient)
+ haar1(tmp, N>>(LM-k), 1<<(LM-k));
+ else
+ haar1(tmp, N>>k, 1<<k);
+
+ L1 = l1_metric(tmp, N, B, N>>LM);
+
+ if (L1 < best_L1)
+ {
+ best_L1 = L1;
+ best_level = k+1;
+ }
+ }
+ /*printf ("%d ", isTransient ? LM-best_level : best_level);*/
+ if (isTransient)
+ metric[i] = best_level;
+ else
+ metric[i] = -best_level;
+ *tf_sum += metric[i];
+ }
+ /*printf("\n");*/
+ /* NOTE: Future optimized implementations could detect extreme transients and set
+ tf_select = 1 but so far we have not found a reliable way of making this useful */
+ tf_select = 0;
+
+ cost0 = 0;
+ cost1 = isTransient ? 0 : lambda;
+ /* Viterbi forward pass */
+ for (i=1;i<len;i++)
+ {
+ int curr0, curr1;
+ int from0, from1;
+
+ from0 = cost0;
+ from1 = cost1 + lambda;
+ if (from0 < from1)
+ {
+ curr0 = from0;
+ path0[i]= 0;
+ } else {
+ curr0 = from1;
+ path0[i]= 1;
+ }
+
+ from0 = cost0 + lambda;
+ from1 = cost1;
+ if (from0 < from1)
+ {
+ curr1 = from0;
+ path1[i]= 0;
+ } else {
+ curr1 = from1;
+ path1[i]= 1;
+ }
+ cost0 = curr0 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+0]);
+ cost1 = curr1 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+1]);
+ }
+ tf_res[len-1] = cost0 < cost1 ? 0 : 1;
+ /* Viterbi backward pass to check the decisions */
+ for (i=len-2;i>=0;i--)
+ {
+ if (tf_res[i+1] == 1)
+ tf_res[i] = path1[i+1];
+ else
+ tf_res[i] = path0[i+1];
+ }
+ RESTORE_STACK;
+#ifdef FUZZING
+ tf_select = rand()&0x1;
+ tf_res[0] = rand()&0x1;
+ for (i=1;i<len;i++)
+ tf_res[i] = tf_res[i-1] ^ ((rand()&0xF) == 0);
+#endif
+ return tf_select;
+}
+
+static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM, int tf_select, ec_enc *enc)
+{
+ int curr, i;
+ int tf_select_rsv;
+ int tf_changed;
+ int logp;
+ opus_uint32 budget;
+ opus_uint32 tell;
+ budget = enc->storage*8;
+ tell = ec_tell(enc);
+ logp = isTransient ? 2 : 4;
+ /* Reserve space to code the tf_select decision. */
+ tf_select_rsv = LM>0 && tell+logp+1 <= budget;
+ budget -= tf_select_rsv;
+ curr = tf_changed = 0;
+ for (i=start;i<end;i++)
+ {
+ if (tell+logp<=budget)
+ {
+ ec_enc_bit_logp(enc, tf_res[i] ^ curr, logp);
+ tell = ec_tell(enc);
+ curr = tf_res[i];
+ tf_changed |= curr;
+ }
+ else
+ tf_res[i] = curr;
+ logp = isTransient ? 4 : 5;
+ }
+ /* Only code tf_select if it would actually make a difference. */
+ if (tf_select_rsv &&
+ tf_select_table[LM][4*isTransient+0+tf_changed]!=
+ tf_select_table[LM][4*isTransient+2+tf_changed])
+ ec_enc_bit_logp(enc, tf_select, 1);
+ else
+ tf_select = 0;
+ for (i=start;i<end;i++)
+ tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
+ /*printf("%d %d ", isTransient, tf_select); for(i=0;i<end;i++)printf("%d ", tf_res[i]);printf("\n");*/
+}
+
+static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM, ec_dec *dec)
+{
+ int i, curr, tf_select;
+ int tf_select_rsv;
+ int tf_changed;
+ int logp;
+ opus_uint32 budget;
+ opus_uint32 tell;
+
+ budget = dec->storage*8;
+ tell = ec_tell(dec);
+ logp = isTransient ? 2 : 4;
+ tf_select_rsv = LM>0 && tell+logp+1<=budget;
+ budget -= tf_select_rsv;
+ tf_changed = curr = 0;
+ for (i=start;i<end;i++)
+ {
+ if (tell+logp<=budget)
+ {
+ curr ^= ec_dec_bit_logp(dec, logp);
+ tell = ec_tell(dec);
+ tf_changed |= curr;
+ }
+ tf_res[i] = curr;
+ logp = isTransient ? 4 : 5;
+ }
+ tf_select = 0;
+ if (tf_select_rsv &&
+ tf_select_table[LM][4*isTransient+0+tf_changed] !=
+ tf_select_table[LM][4*isTransient+2+tf_changed])
+ {
+ tf_select = ec_dec_bit_logp(dec, 1);
+ }
+ for (i=start;i<end;i++)
+ {
+ tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
+ }
+}
+
+static void init_caps(const CELTMode *m,int *cap,int LM,int C)
+{
+ int i;
+ for (i=0;i<m->nbEBands;i++)
+ {
+ int N;
+ N=(m->eBands[i+1]-m->eBands[i])<<LM;
+ cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
+ }
+}
+
+static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
+ const opus_val16 *bandLogE, int end, int LM, int C, int N0)
+{
+ int i;
+ opus_val32 diff=0;
+ int c;
+ int trim_index = 5;
+ if (C==2)
+ {
+ opus_val16 sum = 0; /* Q10 */
+ /* Compute inter-channel correlation for low frequencies */
+ for (i=0;i<8;i++)
+ {
+ int j;
+ opus_val32 partial = 0;
+ for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
+ partial = MAC16_16(partial, X[j], X[N0+j]);
+ sum = ADD16(sum, EXTRACT16(SHR32(partial, 18)));
+ }
+ sum = MULT16_16_Q15(QCONST16(1.f/8, 15), sum);
+ /*printf ("%f\n", sum);*/
+ if (sum > QCONST16(.995f,10))
+ trim_index-=4;
+ else if (sum > QCONST16(.92f,10))
+ trim_index-=3;
+ else if (sum > QCONST16(.85f,10))
+ trim_index-=2;
+ else if (sum > QCONST16(.8f,10))
+ trim_index-=1;
+ }
+
+ /* Estimate spectral tilt */
+ c=0; do {
+ for (i=0;i<end-1;i++)
+ {
+ diff += bandLogE[i+c*m->nbEBands]*(opus_int32)(2+2*i-m->nbEBands);
+ }
+ } while (++c<C);
+ /* We divide by two here to avoid making the tilt larger for stereo as a
+ result of a bug in the loop above */
+ diff /= 2*C*(end-1);
+ /*printf("%f\n", diff);*/
+ if (diff > QCONST16(2.f, DB_SHIFT))
+ trim_index--;
+ if (diff > QCONST16(8.f, DB_SHIFT))
+ trim_index--;
+ if (diff < -QCONST16(4.f, DB_SHIFT))
+ trim_index++;
+ if (diff < -QCONST16(10.f, DB_SHIFT))
+ trim_index++;
+
+ if (trim_index<0)
+ trim_index = 0;
+ if (trim_index>10)
+ trim_index = 10;
+#ifdef FUZZING
+ trim_index = rand()%11;
+#endif
+ return trim_index;
+}
+
+static int stereo_analysis(const CELTMode *m, const celt_norm *X,
+ int LM, int N0)
+{
+ int i;
+ int thetas;
+ opus_val32 sumLR = EPSILON, sumMS = EPSILON;
+
+ /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */
+ for (i=0;i<13;i++)
+ {
+ int j;
+ for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
+ {
+ opus_val32 L, R, M, S;
+ /* We cast to 32-bit first because of the -32768 case */
+ L = EXTEND32(X[j]);
+ R = EXTEND32(X[N0+j]);
+ M = ADD32(L, R);
+ S = SUB32(L, R);
+ sumLR = ADD32(sumLR, ADD32(ABS32(L), ABS32(R)));
+ sumMS = ADD32(sumMS, ADD32(ABS32(M), ABS32(S)));
+ }
+ }
+ sumMS = MULT16_32_Q15(QCONST16(0.707107f, 15), sumMS);
+ thetas = 13;
+ /* We don't need thetas for lower bands with LM<=1 */
+ if (LM<=1)
+ thetas -= 8;
+ return MULT16_32_Q15((m->eBands[13]<<(LM+1))+thetas, sumMS)
+ > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR);
+}
+
+int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
+{
+ int i, c, N;
+ opus_int32 bits;
+ ec_enc _enc;
+ VARDECL(celt_sig, in);
+ VARDECL(celt_sig, freq);
+ VARDECL(celt_norm, X);
+ VARDECL(celt_ener, bandE);
+ VARDECL(opus_val16, bandLogE);
+ VARDECL(int, fine_quant);
+ VARDECL(opus_val16, error);
+ VARDECL(int, pulses);
+ VARDECL(int, cap);
+ VARDECL(int, offsets);
+ VARDECL(int, fine_priority);
+ VARDECL(int, tf_res);
+ VARDECL(unsigned char, collapse_masks);
+ celt_sig *prefilter_mem;
+ opus_val16 *oldBandE, *oldLogE, *oldLogE2;
+ int shortBlocks=0;
+ int isTransient=0;
+ const int CC = st->channels;
+ const int C = st->stream_channels;
+ int LM, M;
+ int tf_select;
+ int nbFilledBytes, nbAvailableBytes;
+ int effEnd;
+ int codedBands;
+ int tf_sum;
+ int alloc_trim;
+ int pitch_index=COMBFILTER_MINPERIOD;
+ opus_val16 gain1 = 0;
+ int intensity=0;
+ int dual_stereo=0;
+ int effectiveBytes;
+ opus_val16 pf_threshold;
+ int dynalloc_logp;
+ opus_int32 vbr_rate;
+ opus_int32 total_bits;
+ opus_int32 total_boost;
+ opus_int32 balance;
+ opus_int32 tell;
+ int prefilter_tapset=0;
+ int pf_on;
+ int anti_collapse_rsv;
+ int anti_collapse_on=0;
+ int silence=0;
+ ALLOC_STACK;
+
+ if (nbCompressedBytes<2 || pcm==NULL)
+ return OPUS_BAD_ARG;
+
+ frame_size *= st->upsample;
+ for (LM=0;LM<=st->mode->maxLM;LM++)
+ if (st->mode->shortMdctSize<<LM==frame_size)
+ break;
+ if (LM>st->mode->maxLM)
+ return OPUS_BAD_ARG;
+ M=1<<LM;
+ N = M*st->mode->shortMdctSize;
+
+ prefilter_mem = st->in_mem+CC*(st->overlap);
+ oldBandE = (opus_val16*)(st->in_mem+CC*(2*st->overlap+COMBFILTER_MAXPERIOD));
+ oldLogE = oldBandE + CC*st->mode->nbEBands;
+ oldLogE2 = oldLogE + CC*st->mode->nbEBands;
+
+ if (enc==NULL)
+ {
+ tell=1;
+ nbFilledBytes=0;
+ } else {
+ tell=ec_tell(enc);
+ nbFilledBytes=(tell+4)>>3;
+ }
+
+#ifdef CUSTOM_MODES
+ if (st->signalling && enc==NULL)
+ {
+ int tmp = (st->mode->effEBands-st->end)>>1;
+ st->end = IMAX(1, st->mode->effEBands-tmp);
+ compressed[0] = tmp<<5;
+ compressed[0] |= LM<<3;
+ compressed[0] |= (C==2)<<2;
+ /* Convert "standard mode" to Opus header */
+ if (st->mode->Fs==48000 && st->mode->shortMdctSize==120)
+ {
+ int c0 = toOpus(compressed[0]);
+ if (c0<0)
+ return OPUS_BAD_ARG;
+ compressed[0] = c0;
+ }
+ compressed++;
+ nbCompressedBytes--;
+ }
+#else
+ celt_assert(st->signalling==0);
+#endif
+
+ /* Can't produce more than 1275 output bytes */
+ nbCompressedBytes = IMIN(nbCompressedBytes,1275);
+ nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
+
+ if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX)
+ {
+ opus_int32 den=st->mode->Fs>>BITRES;
+ vbr_rate=(st->bitrate*frame_size+(den>>1))/den;
+#ifdef CUSTOM_MODES
+ if (st->signalling)
+ vbr_rate -= 8<<BITRES;
+#endif
+ effectiveBytes = vbr_rate>>(3+BITRES);
+ } else {
+ opus_int32 tmp;
+ vbr_rate = 0;
+ tmp = st->bitrate*frame_size;
+ if (tell>1)
+ tmp += tell;
+ if (st->bitrate!=OPUS_BITRATE_MAX)
+ nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,
+ (tmp+4*st->mode->Fs)/(8*st->mode->Fs)-!!st->signalling));
+ effectiveBytes = nbCompressedBytes;
+ }
+
+ if (enc==NULL)
+ {
+ ec_enc_init(&_enc, compressed, nbCompressedBytes);
+ enc = &_enc;
+ }
+
+ if (vbr_rate>0)
+ {
+ /* Computes the max bit-rate allowed in VBR mode to avoid violating the
+ target rate and buffering.
+ We must do this up front so that bust-prevention logic triggers
+ correctly if we don't have enough bits. */
+ if (st->constrained_vbr)
+ {
+ opus_int32 vbr_bound;
+ opus_int32 max_allowed;
+ /* We could use any multiple of vbr_rate as bound (depending on the
+ delay).
+ This is clamped to ensure we use at least two bytes if the encoder
+ was entirely empty, but to allow 0 in hybrid mode. */
+ vbr_bound = vbr_rate;
+ max_allowed = IMIN(IMAX(tell==1?2:0,
+ (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)),
+ nbAvailableBytes);
+ if(max_allowed < nbAvailableBytes)
+ {
+ nbCompressedBytes = nbFilledBytes+max_allowed;
+ nbAvailableBytes = max_allowed;
+ ec_enc_shrink(enc, nbCompressedBytes);
+ }
+ }
+ }
+ total_bits = nbCompressedBytes*8;
+
+ effEnd = st->end;
+ if (effEnd > st->mode->effEBands)
+ effEnd = st->mode->effEBands;
+
+ ALLOC(in, CC*(N+st->overlap), celt_sig);
+
+ /* Find pitch period and gain */
+ {
+ VARDECL(celt_sig, _pre);
+ celt_sig *pre[2];
+ SAVE_STACK;
+ ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig);
+
+ pre[0] = _pre;
+ pre[1] = _pre + (N+COMBFILTER_MAXPERIOD);
+
+ silence = 1;
+ c=0; do {
+ int count = 0;
+ const opus_val16 * OPUS_RESTRICT pcmp = pcm+c;
+ celt_sig * OPUS_RESTRICT inp = in+c*(N+st->overlap)+st->overlap;
+
+ for (i=0;i<N;i++)
+ {
+ celt_sig x, tmp;
+
+ x = SCALEIN(*pcmp);
+#ifndef FIXED_POINT
+ if (!(x==x))
+ x = 0;
+ if (st->clip)
+ x = MAX32(-65536.f, MIN32(65536.f,x));
+#endif
+ if (++count==st->upsample)
+ {
+ count=0;
+ pcmp+=CC;
+ } else {
+ x = 0;
+ }
+ /* Apply pre-emphasis */
+ tmp = MULT16_16(st->mode->preemph[2], x);
+ *inp = tmp + st->preemph_memE[c];
+ st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp)
+ - MULT16_32_Q15(st->mode->preemph[0], tmp);
+ silence = silence && *inp == 0;
+ inp++;
+ }
+ OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD);
+ OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N);
+ } while (++c<CC);
+
+#ifdef FUZZING
+ if ((rand()&0x3F)==0)
+ silence = 1;
+#endif
+ if (tell==1)
+ ec_enc_bit_logp(enc, silence, 15);
+ else
+ silence=0;
+ if (silence)
+ {
+ /*In VBR mode there is no need to send more than the minimum. */
+ if (vbr_rate>0)
+ {
+ effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2);
+ total_bits=nbCompressedBytes*8;
+ nbAvailableBytes=2;
+ ec_enc_shrink(enc, nbCompressedBytes);
+ }
+ /* Pretend we've filled all the remaining bits with zeros
+ (that's what the initialiser did anyway) */
+ tell = nbCompressedBytes*8;
+ enc->nbits_total+=tell-ec_tell(enc);
+ }
+ if (nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf && st->complexity >= 5)
+ {
+ VARDECL(opus_val16, pitch_buf);
+ ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, opus_val16);
+
+ pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC);
+ pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,
+ COMBFILTER_MAXPERIOD-COMBFILTER_MINPERIOD, &pitch_index);
+ pitch_index = COMBFILTER_MAXPERIOD-pitch_index;
+
+ gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD,
+ N, &pitch_index, st->prefilter_period, st->prefilter_gain);
+ if (pitch_index > COMBFILTER_MAXPERIOD-2)
+ pitch_index = COMBFILTER_MAXPERIOD-2;
+ gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1);
+ if (st->loss_rate>2)
+ gain1 = HALF32(gain1);
+ if (st->loss_rate>4)
+ gain1 = HALF32(gain1);
+ if (st->loss_rate>8)
+ gain1 = 0;
+ prefilter_tapset = st->tapset_decision;
+ } else {
+ gain1 = 0;
+ }
+
+ /* Gain threshold for enabling the prefilter/postfilter */
+ pf_threshold = QCONST16(.2f,15);
+
+ /* Adjusting the threshold based on rate and continuity */
+ if (abs(pitch_index-st->prefilter_period)*10>pitch_index)
+ pf_threshold += QCONST16(.2f,15);
+ if (nbAvailableBytes<25)
+ pf_threshold += QCONST16(.1f,15);
+ if (nbAvailableBytes<35)
+ pf_threshold += QCONST16(.1f,15);
+ if (st->prefilter_gain > QCONST16(.4f,15))
+ pf_threshold -= QCONST16(.1f,15);
+ if (st->prefilter_gain > QCONST16(.55f,15))
+ pf_threshold -= QCONST16(.1f,15);
+
+ /* Hard threshold at 0.2 */
+ pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15));
+ if (gain1<pf_threshold)
+ {
+ if(st->start==0 && tell+16<=total_bits)
+ ec_enc_bit_logp(enc, 0, 1);
+ gain1 = 0;
+ pf_on = 0;
+ } else {
+ /*This block is not gated by a total bits check only because
+ of the nbAvailableBytes check above.*/
+ int qg;
+ int octave;
+
+ if (ABS16(gain1-st->prefilter_gain)<QCONST16(.1f,15))
+ gain1=st->prefilter_gain;
+
+#ifdef FIXED_POINT
+ qg = ((gain1+1536)>>10)/3-1;
+#else
+ qg = (int)floor(.5f+gain1*32/3)-1;
+#endif
+ qg = IMAX(0, IMIN(7, qg));
+ ec_enc_bit_logp(enc, 1, 1);
+ pitch_index += 1;
+ octave = EC_ILOG(pitch_index)-5;
+ ec_enc_uint(enc, octave, 6);
+ ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
+ pitch_index -= 1;
+ ec_enc_bits(enc, qg, 3);
+ if (ec_tell(enc)+2<=total_bits)
+ ec_enc_icdf(enc, prefilter_tapset, tapset_icdf, 2);
+ else
+ prefilter_tapset = 0;
+ gain1 = QCONST16(0.09375f,15)*(qg+1);
+ pf_on = 1;
+ }
+ /*printf("%d %f\n", pitch_index, gain1);*/
+
+ c=0; do {
+ int offset = st->mode->shortMdctSize-st->mode->overlap;
+ st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
+ OPUS_COPY(in+c*(N+st->overlap), st->in_mem+c*(st->overlap), st->overlap);
+ if (offset)
+ comb_filter(in+c*(N+st->overlap)+st->overlap, pre[c]+COMBFILTER_MAXPERIOD,
+ st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain,
+ st->prefilter_tapset, st->prefilter_tapset, NULL, 0);
+
+ comb_filter(in+c*(N+st->overlap)+st->overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset,
+ st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1,
+ st->prefilter_tapset, prefilter_tapset, st->mode->window, st->mode->overlap);
+ OPUS_COPY(st->in_mem+c*(st->overlap), in+c*(N+st->overlap)+N, st->overlap);
+
+ if (N>COMBFILTER_MAXPERIOD)
+ {
+ OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD);
+ } else {
+ OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N);
+ OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
+ }
+ } while (++c<CC);
+
+ RESTORE_STACK;
+ }
+
+ isTransient = 0;
+ shortBlocks = 0;
+ if (LM>0 && ec_tell(enc)+3<=total_bits)
+ {
+ if (st->complexity > 1)
+ {
+ isTransient = transient_analysis(in, N+st->overlap, CC,
+ st->overlap);
+ if (isTransient)
+ shortBlocks = M;
+ }
+ ec_enc_bit_logp(enc, isTransient, 3);
+ }
+
+ ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */
+ ALLOC(bandE,st->mode->nbEBands*CC, celt_ener);
+ ALLOC(bandLogE,st->mode->nbEBands*CC, opus_val16);
+ /* Compute MDCTs */
+ compute_mdcts(st->mode, shortBlocks, in, freq, CC, LM);
+
+ if (CC==2&&C==1)
+ {
+ for (i=0;i<N;i++)
+ freq[i] = ADD32(HALF32(freq[i]), HALF32(freq[N+i]));
+ }
+ if (st->upsample != 1)
+ {
+ c=0; do
+ {
+ int bound = N/st->upsample;
+ for (i=0;i<bound;i++)
+ freq[c*N+i] *= st->upsample;
+ for (;i<N;i++)
+ freq[c*N+i] = 0;
+ } while (++c<C);
+ }
+ ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
+
+ compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
+
+ amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C);
+
+ /* Band normalisation */
+ normalise_bands(st->mode, freq, X, bandE, effEnd, C, M);
+
+ ALLOC(tf_res, st->mode->nbEBands, int);
+ tf_select = tf_analysis(st->mode, effEnd, C, isTransient, tf_res, effectiveBytes, X, N, LM, &tf_sum);
+ for (i=effEnd;i<st->end;i++)
+ tf_res[i] = tf_res[effEnd-1];
+
+ ALLOC(error, C*st->mode->nbEBands, opus_val16);
+ quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE,
+ oldBandE, total_bits, error, enc,
+ C, LM, nbAvailableBytes, st->force_intra,
+ &st->delayedIntra, st->complexity >= 4, st->loss_rate);
+
+ tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
+
+ st->spread_decision = SPREAD_NORMAL;
+ if (ec_tell(enc)+4<=total_bits)
+ {
+ if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
+ {
+ if (st->complexity == 0)
+ st->spread_decision = SPREAD_NONE;
+ } else {
+ st->spread_decision = spreading_decision(st->mode, X,
+ &st->tonal_average, st->spread_decision, &st->hf_average,
+ &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M);
+ }
+ ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
+ }
+
+ ALLOC(cap, st->mode->nbEBands, int);
+ ALLOC(offsets, st->mode->nbEBands, int);
+
+ init_caps(st->mode,cap,LM,C);
+ for (i=0;i<st->mode->nbEBands;i++)
+ offsets[i] = 0;
+ /* Dynamic allocation code */
+ /* Make sure that dynamic allocation can't make us bust the budget */
+ if (effectiveBytes > 50 && LM>=1)
+ {
+ int t1, t2;
+ if (LM <= 1)
+ {
+ t1 = 3;
+ t2 = 5;
+ } else {
+ t1 = 2;
+ t2 = 4;
+ }
+ for (i=st->start+1;i<st->end-1;i++)
+ {
+ opus_val32 d2;
+ d2 = 2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1];
+ if (C==2)
+ d2 = HALF32(d2 + 2*bandLogE[i+st->mode->nbEBands]-
+ bandLogE[i-1+st->mode->nbEBands]-bandLogE[i+1+st->mode->nbEBands]);
+#ifdef FUZZING
+ if((rand()&0xF)==0)
+ {
+ offsets[i] += 1;
+ if((rand()&0x3)==0)
+ offsets[i] += 1+(rand()&0x3);
+ }
+#else
+ if (d2 > SHL16(t1,DB_SHIFT))
+ offsets[i] += 1;
+ if (d2 > SHL16(t2,DB_SHIFT))
+ offsets[i] += 1;
+#endif
+ }
+ }
+ dynalloc_logp = 6;
+ total_bits<<=BITRES;
+ total_boost = 0;
+ tell = ec_tell_frac(enc);
+ for (i=st->start;i<st->end;i++)
+ {
+ int width, quanta;
+ int dynalloc_loop_logp;
+ int boost;
+ int j;
+ width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
+ /* quanta is 6 bits, but no more than 1 bit/sample
+ and no less than 1/8 bit/sample */
+ quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
+ dynalloc_loop_logp = dynalloc_logp;
+ boost = 0;
+ for (j = 0; tell+(dynalloc_loop_logp<<BITRES) < total_bits-total_boost
+ && boost < cap[i]; j++)
+ {
+ int flag;
+ flag = j<offsets[i];
+ ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);
+ tell = ec_tell_frac(enc);
+ if (!flag)
+ break;
+ boost += quanta;
+ total_boost += quanta;
+ dynalloc_loop_logp = 1;
+ }
+ /* Making dynalloc more likely */
+ if (j)
+ dynalloc_logp = IMAX(2, dynalloc_logp-1);
+ offsets[i] = boost;
+ }
+ alloc_trim = 5;
+ if (tell+(6<<BITRES) <= total_bits - total_boost)
+ {
+ alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE,
+ st->end, LM, C, N);
+ ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
+ tell = ec_tell_frac(enc);
+ }
+
+ /* Variable bitrate */
+ if (vbr_rate>0)
+ {
+ opus_val16 alpha;
+ opus_int32 delta;
+ /* The target rate in 8th bits per frame */
+ opus_int32 target;
+ opus_int32 min_allowed;
+ int lm_diff = st->mode->maxLM - LM;
+
+ /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms.
+ The CELT allocator will just not be able to use more than that anyway. */
+ nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM));
+ target = vbr_rate + (st->vbr_offset>>lm_diff) - ((40*C+20)<<BITRES);
+
+ /* Shortblocks get a large boost in bitrate, but since they
+ are uncommon long blocks are not greatly affected */
+ if (shortBlocks || tf_sum < -2*(st->end-st->start))
+ target = 7*target/4;
+ else if (tf_sum < -(st->end-st->start))
+ target = 3*target/2;
+ else if (M > 1)
+ target-=(target+14)/28;
+
+ /* The current offset is removed from the target and the space used
+ so far is added*/
+ target=target+tell;
+
+ /* In VBR mode the frame size must not be reduced so much that it would
+ result in the encoder running out of bits.
+ The margin of 2 bytes ensures that none of the bust-prevention logic
+ in the decoder will have triggered so far. */
+ min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2 - nbFilledBytes;
+
+ nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3);
+ nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes);
+ nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes;
+
+ /* By how much did we "miss" the target on that frame */
+ delta = target - vbr_rate;
+
+ target=nbAvailableBytes<<(BITRES+3);
+
+ /*If the frame is silent we don't adjust our drift, otherwise
+ the encoder will shoot to very high rates after hitting a
+ span of silence, but we do allow the bitres to refill.
+ This means that we'll undershoot our target in CVBR/VBR modes
+ on files with lots of silence. */
+ if(silence)
+ {
+ nbAvailableBytes = 2;
+ target = 2*8<<BITRES;
+ delta = 0;
+ }
+
+ if (st->vbr_count < 970)
+ {
+ st->vbr_count++;
+ alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16));
+ } else
+ alpha = QCONST16(.001f,15);
+ /* How many bits have we used in excess of what we're allowed */
+ if (st->constrained_vbr)
+ st->vbr_reservoir += target - vbr_rate;
+ /*printf ("%d\n", st->vbr_reservoir);*/
+
+ /* Compute the offset we need to apply in order to reach the target */
+ st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<<lm_diff))-st->vbr_offset-st->vbr_drift);
+ st->vbr_offset = -st->vbr_drift;
+ /*printf ("%d\n", st->vbr_drift);*/
+
+ if (st->constrained_vbr && st->vbr_reservoir < 0)
+ {
+ /* We're under the min value -- increase rate */
+ int adjust = (-st->vbr_reservoir)/(8<<BITRES);
+ /* Unless we're just coding silence */
+ nbAvailableBytes += silence?0:adjust;
+ st->vbr_reservoir = 0;
+ /*printf ("+%d\n", adjust);*/
+ }
+ nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
+ /* This moves the raw bits to take into account the new compressed size */
+ ec_enc_shrink(enc, nbCompressedBytes);
+ }
+ if (C==2)
+ {
+ int effectiveRate;
+
+ /* Always use MS for 2.5 ms frames until we can do a better analysis */
+ if (LM!=0)
+ dual_stereo = stereo_analysis(st->mode, X, LM, N);
+
+ /* Account for coarse energy */
+ effectiveRate = (8*effectiveBytes - 80)>>LM;
+
+ /* effectiveRate in kb/s */
+ effectiveRate = 2*effectiveRate/5;
+ if (effectiveRate<35)
+ intensity = 8;
+ else if (effectiveRate<50)
+ intensity = 12;
+ else if (effectiveRate<68)
+ intensity = 16;
+ else if (effectiveRate<84)
+ intensity = 18;
+ else if (effectiveRate<102)
+ intensity = 19;
+ else if (effectiveRate<130)
+ intensity = 20;
+ else
+ intensity = 100;
+ intensity = IMIN(st->end,IMAX(st->start, intensity));
+ }
+
+ /* Bit allocation */
+ ALLOC(fine_quant, st->mode->nbEBands, int);
+ ALLOC(pulses, st->mode->nbEBands, int);
+ ALLOC(fine_priority, st->mode->nbEBands, int);
+
+ /* bits = packet size - where we are - safety*/
+ bits = (((opus_int32)nbCompressedBytes*8)<<BITRES) - ec_tell_frac(enc) - 1;
+ anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
+ bits -= anti_collapse_rsv;
+ codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
+ alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
+ fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands);
+ st->lastCodedBands = codedBands;
+
+ quant_fine_energy(st->mode, st->start, st->end, oldBandE, error, fine_quant, enc, C);
+
+#ifdef MEASURE_NORM_MSE
+ float X0[3000];
+ float bandE0[60];
+ c=0; do
+ for (i=0;i<N;i++)
+ X0[i+c*N] = X[i+c*N];
+ while (++c<C);
+ for (i=0;i<C*st->mode->nbEBands;i++)
+ bandE0[i] = bandE[i];
+#endif
+
+ /* Residual quantisation */
+ ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char);
+ quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks,
+ bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, intensity, tf_res,
+ nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv, balance, enc, LM, codedBands, &st->rng);
+
+ if (anti_collapse_rsv > 0)
+ {
+ anti_collapse_on = st->consec_transient<2;
+#ifdef FUZZING
+ anti_collapse_on = rand()&0x1;
+#endif
+ ec_enc_bits(enc, anti_collapse_on, 1);
+ }
+ quant_energy_finalise(st->mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C);
+
+ if (silence)
+ {
+ for (i=0;i<C*st->mode->nbEBands;i++)
+ oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
+ }
+
+#ifdef RESYNTH
+ /* Re-synthesis of the coded audio if required */
+ {
+ celt_sig *out_mem[2];
+ celt_sig *overlap_mem[2];
+
+ log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
+ if (silence)
+ {
+ for (i=0;i<C*st->mode->nbEBands;i++)
+ bandE[i] = 0;
+ }
+
+#ifdef MEASURE_NORM_MSE
+ measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C);
+#endif
+ if (anti_collapse_on)
+ {
+ anti_collapse(st->mode, X, collapse_masks, LM, C, N,
+ st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
+ }
+
+ /* Synthesis */
+ denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
+
+ OPUS_MOVE(st->syn_mem[0], st->syn_mem[0]+N, MAX_PERIOD);
+ if (CC==2)
+ OPUS_MOVE(st->syn_mem[1], st->syn_mem[1]+N, MAX_PERIOD);
+
+ c=0; do
+ for (i=0;i<M*st->mode->eBands[st->start];i++)
+ freq[c*N+i] = 0;
+ while (++c<C);
+ c=0; do
+ for (i=M*st->mode->eBands[st->end];i<N;i++)
+ freq[c*N+i] = 0;
+ while (++c<C);
+
+ if (CC==2&&C==1)
+ {
+ for (i=0;i<N;i++)
+ freq[N+i] = freq[i];
+ }
+
+ out_mem[0] = st->syn_mem[0]+MAX_PERIOD;
+ if (CC==2)
+ out_mem[1] = st->syn_mem[1]+MAX_PERIOD;
+
+ overlap_mem[0] = prefilter_mem+CC*COMBFILTER_MAXPERIOD;
+ if (CC==2)
+ overlap_mem[1] = overlap_mem[0] + st->overlap;
+
+ compute_inv_mdcts(st->mode, shortBlocks, freq, out_mem, overlap_mem, CC, LM);
+
+ c=0; do {
+ st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
+ st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD);
+ comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, st->mode->shortMdctSize,
+ st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset,
+ st->mode->window, st->overlap);
+ if (LM!=0)
+ comb_filter(out_mem[c]+st->mode->shortMdctSize, out_mem[c]+st->mode->shortMdctSize, st->prefilter_period, pitch_index, N-st->mode->shortMdctSize,
+ st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset,
+ st->mode->window, st->mode->overlap);
+ } while (++c<CC);
+
+ deemphasis(out_mem, (opus_val16*)pcm, N, CC, st->upsample, st->mode->preemph, st->preemph_memD);
+ st->prefilter_period_old = st->prefilter_period;
+ st->prefilter_gain_old = st->prefilter_gain;
+ st->prefilter_tapset_old = st->prefilter_tapset;
+ }
+#endif
+
+ st->prefilter_period = pitch_index;
+ st->prefilter_gain = gain1;
+ st->prefilter_tapset = prefilter_tapset;
+#ifdef RESYNTH
+ if (LM!=0)
+ {
+ st->prefilter_period_old = st->prefilter_period;
+ st->prefilter_gain_old = st->prefilter_gain;
+ st->prefilter_tapset_old = st->prefilter_tapset;
+ }
+#endif
+
+ if (CC==2&&C==1) {
+ for (i=0;i<st->mode->nbEBands;i++)
+ oldBandE[st->mode->nbEBands+i]=oldBandE[i];
+ }
+
+ if (!isTransient)
+ {
+ for (i=0;i<CC*st->mode->nbEBands;i++)
+ oldLogE2[i] = oldLogE[i];
+ for (i=0;i<CC*st->mode->nbEBands;i++)
+ oldLogE[i] = oldBandE[i];
+ } else {
+ for (i=0;i<CC*st->mode->nbEBands;i++)
+ oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
+ }
+ /* In case start or end were to change */
+ c=0; do
+ {
+ for (i=0;i<st->start;i++)
+ {
+ oldBandE[c*st->mode->nbEBands+i]=0;
+ oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
+ }
+ for (i=st->end;i<st->mode->nbEBands;i++)
+ {
+ oldBandE[c*st->mode->nbEBands+i]=0;
+ oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
+ }
+ } while (++c<CC);
+
+ if (isTransient)
+ st->consec_transient++;
+ else
+ st->consec_transient=0;
+ st->rng = enc->rng;
+
+ /* If there's any room left (can only happen for very high rates),
+ it's already filled with zeros */
+ ec_enc_done(enc);
+
+#ifdef CUSTOM_MODES
+ if (st->signalling)
+ nbCompressedBytes++;
+#endif
+
+ RESTORE_STACK;
+ if (ec_get_error(enc))
+ return OPUS_INTERNAL_ERROR;
+ else
+ return nbCompressedBytes;
+}
+
+
+#ifdef CUSTOM_MODES
+
+#ifdef FIXED_POINT
+int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
+{
+ return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
+}
+
+#ifndef DISABLE_FLOAT_API
+int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
+{
+ int j, ret, C, N;
+ VARDECL(opus_int16, in);
+ ALLOC_STACK;
+
+ if (pcm==NULL)
+ return OPUS_BAD_ARG;
+
+ C = st->channels;
+ N = frame_size;
+ ALLOC(in, C*N, opus_int16);
+
+ for (j=0;j<C*N;j++)
+ in[j] = FLOAT2INT16(pcm[j]);
+
+ ret=celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);
+#ifdef RESYNTH
+ for (j=0;j<C*N;j++)
+ ((float*)pcm)[j]=in[j]*(1.f/32768.f);
+#endif
+ RESTORE_STACK;
+ return ret;
+}
+#endif /* DISABLE_FLOAT_API */
+#else
+
+int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
+{
+ int j, ret, C, N;
+ VARDECL(celt_sig, in);
+ ALLOC_STACK;
+
+ if (pcm==NULL)
+ return OPUS_BAD_ARG;
+
+ C=st->channels;
+ N=frame_size;
+ ALLOC(in, C*N, celt_sig);
+ for (j=0;j<C*N;j++) {
+ in[j] = SCALEOUT(pcm[j]);
+ }
+
+ ret = celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);
+#ifdef RESYNTH
+ for (j=0;j<C*N;j++)
+ ((opus_int16*)pcm)[j] = FLOAT2INT16(in[j]);
+#endif
+ RESTORE_STACK;
+ return ret;
+}
+
+int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
+{
+ return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
+}
+
+#endif
+
+#endif /* CUSTOM_MODES */
+
+int opus_custom_encoder_ctl(CELTEncoder * OPUS_RESTRICT st, int request, ...)
+{
+ va_list ap;
+
+ va_start(ap, request);
+ switch (request)
+ {
+ case OPUS_SET_COMPLEXITY_REQUEST:
+ {
+ int value = va_arg(ap, opus_int32);
+ if (value<0 || value>10)
+ goto bad_arg;
+ st->complexity = value;
+ }
+ break;
+ case CELT_SET_START_BAND_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value<0 || value>=st->mode->nbEBands)
+ goto bad_arg;
+ st->start = value;
+ }
+ break;
+ case CELT_SET_END_BAND_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value<1 || value>st->mode->nbEBands)
+ goto bad_arg;
+ st->end = value;
+ }
+ break;
+ case CELT_SET_PREDICTION_REQUEST:
+ {
+ int value = va_arg(ap, opus_int32);
+ if (value<0 || value>2)
+ goto bad_arg;
+ st->disable_pf = value<=1;
+ st->force_intra = value==0;
+ }
+ break;
+ case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
+ {
+ int value = va_arg(ap, opus_int32);
+ if (value<0 || value>100)
+ goto bad_arg;
+ st->loss_rate = value;
+ }
+ break;
+ case OPUS_SET_VBR_CONSTRAINT_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ st->constrained_vbr = value;
+ }
+ break;
+ case OPUS_SET_VBR_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ st->vbr = value;
+ }
+ break;
+ case OPUS_SET_BITRATE_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value<=500 && value!=OPUS_BITRATE_MAX)
+ goto bad_arg;
+ value = IMIN(value, 260000*st->channels);
+ st->bitrate = value;
+ }
+ break;
+ case CELT_SET_CHANNELS_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value<1 || value>2)
+ goto bad_arg;
+ st->stream_channels = value;
+ }
+ break;
+ case OPUS_SET_LSB_DEPTH_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value<8 || value>24)
+ goto bad_arg;
+ st->lsb_depth=value;
+ }
+ break;
+ case OPUS_GET_LSB_DEPTH_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ *value=st->lsb_depth;
+ }
+ break;
+ case OPUS_RESET_STATE:
+ {
+ int i;
+ opus_val16 *oldBandE, *oldLogE, *oldLogE2;
+ oldBandE = (opus_val16*)(st->in_mem+st->channels*(2*st->overlap+COMBFILTER_MAXPERIOD));
+ oldLogE = oldBandE + st->channels*st->mode->nbEBands;
+ oldLogE2 = oldLogE + st->channels*st->mode->nbEBands;
+ OPUS_CLEAR((char*)&st->ENCODER_RESET_START,
+ opus_custom_encoder_get_size(st->mode, st->channels)-
+ ((char*)&st->ENCODER_RESET_START - (char*)st));
+ for (i=0;i<st->channels*st->mode->nbEBands;i++)
+ oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
+ st->vbr_offset = 0;
+ st->delayedIntra = 1;
+ st->spread_decision = SPREAD_NORMAL;
+ st->tonal_average = 256;
+ st->hf_average = 0;
+ st->tapset_decision = 0;
+ }
+ break;
+#ifdef CUSTOM_MODES
+ case CELT_SET_INPUT_CLIPPING_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ st->clip = value;
+ }
+ break;
+#endif
+ case CELT_SET_SIGNALLING_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ st->signalling = value;
+ }
+ break;
+ case CELT_GET_MODE_REQUEST:
+ {
+ const CELTMode ** value = va_arg(ap, const CELTMode**);
+ if (value==0)
+ goto bad_arg;
+ *value=st->mode;
+ }
+ break;
+ case OPUS_GET_FINAL_RANGE_REQUEST:
+ {
+ opus_uint32 * value = va_arg(ap, opus_uint32 *);
+ if (value==0)
+ goto bad_arg;
+ *value=st->rng;
+ }
+ break;
+ default:
+ goto bad_request;
+ }
+ va_end(ap);
+ return OPUS_OK;
+bad_arg:
+ va_end(ap);
+ return OPUS_BAD_ARG;
+bad_request:
+ va_end(ap);
+ return OPUS_UNIMPLEMENTED;
+}
+
+/**********************************************************************/
+/* */
+/* DECODER */
+/* */
+/**********************************************************************/
+#define DECODE_BUFFER_SIZE 2048
+
+/** Decoder state
+ @brief Decoder state
+ */
+struct OpusCustomDecoder {
+ const OpusCustomMode *mode;
+ int overlap;
+ int channels;
+ int stream_channels;
+
+ int downsample;
+ int start, end;
+ int signalling;
+
+ /* Everything beyond this point gets cleared on a reset */
+#define DECODER_RESET_START rng
+
+ opus_uint32 rng;
+ int error;
+ int last_pitch_index;
+ int loss_count;
+ int postfilter_period;
+ int postfilter_period_old;
+ opus_val16 postfilter_gain;
+ opus_val16 postfilter_gain_old;
+ int postfilter_tapset;
+ int postfilter_tapset_old;
+
+ celt_sig preemph_memD[2];
+
+ celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
+ /* opus_val16 lpc[], Size = channels*LPC_ORDER */
+ /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */
+ /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */
+ /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */
+ /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
+};
+
+int celt_decoder_get_size(int channels)
+{
+ const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
+ return opus_custom_decoder_get_size(mode, channels);
+}
+
+OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels)
+{
+ int size = sizeof(struct CELTDecoder)
+ + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
+ + channels*LPC_ORDER*sizeof(opus_val16)
+ + 4*2*mode->nbEBands*sizeof(opus_val16);
+ return size;
+}
+
+#ifdef CUSTOM_MODES
+CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error)
+{
+ int ret;
+ CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels));
+ ret = opus_custom_decoder_init(st, mode, channels);
+ if (ret != OPUS_OK)
+ {
+ opus_custom_decoder_destroy(st);
+ st = NULL;
+ }
+ if (error)
+ *error = ret;
+ return st;
+}
+#endif /* CUSTOM_MODES */
+
+int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels)
+{
+ int ret;
+ ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels);
+ if (ret != OPUS_OK)
+ return ret;
+ st->downsample = resampling_factor(sampling_rate);
+ if (st->downsample==0)
+ return OPUS_BAD_ARG;
+ else
+ return OPUS_OK;
+}
+
+OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels)
+{
+ if (channels < 0 || channels > 2)
+ return OPUS_BAD_ARG;
+
+ if (st==NULL)
+ return OPUS_ALLOC_FAIL;
+
+ OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels));
+
+ st->mode = mode;
+ st->overlap = mode->overlap;
+ st->stream_channels = st->channels = channels;
+
+ st->downsample = 1;
+ st->start = 0;
+ st->end = st->mode->effEBands;
+ st->signalling = 1;
+
+ st->loss_count = 0;
+
+ opus_custom_decoder_ctl(st, OPUS_RESET_STATE);
+
+ return OPUS_OK;
+}
+
+#ifdef CUSTOM_MODES
+void opus_custom_decoder_destroy(CELTDecoder *st)
+{
+ opus_free(st);
+}
+#endif /* CUSTOM_MODES */
+
+static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_RESTRICT pcm, int N, int LM)
+{
+ int c;
+ int pitch_index;
+ int overlap = st->mode->overlap;
+ opus_val16 fade = Q15ONE;
+ int i, len;
+ const int C = st->channels;
+ int offset;
+ celt_sig *out_mem[2];
+ celt_sig *decode_mem[2];
+ celt_sig *overlap_mem[2];
+ opus_val16 *lpc;
+ opus_val32 *out_syn[2];
+ opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
+ SAVE_STACK;
+
+ c=0; do {
+ decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
+ out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
+ overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
+ } while (++c<C);
+ lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
+ oldBandE = lpc+C*LPC_ORDER;
+ oldLogE = oldBandE + 2*st->mode->nbEBands;
+ oldLogE2 = oldLogE + 2*st->mode->nbEBands;
+ backgroundLogE = oldLogE2 + 2*st->mode->nbEBands;
+
+ out_syn[0] = out_mem[0]+MAX_PERIOD-N;
+ if (C==2)
+ out_syn[1] = out_mem[1]+MAX_PERIOD-N;
+
+ len = N+st->mode->overlap;
+
+ if (st->loss_count >= 5 || st->start!=0)
+ {
+ /* Noise-based PLC/CNG */
+ VARDECL(celt_sig, freq);
+ VARDECL(celt_norm, X);
+ VARDECL(celt_ener, bandE);
+ opus_uint32 seed;
+ int effEnd;
+
+ effEnd = st->end;
+ if (effEnd > st->mode->effEBands)
+ effEnd = st->mode->effEBands;
+
+ ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
+ ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
+ ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
+
+ if (st->loss_count >= 5)
+ log2Amp(st->mode, st->start, st->end, bandE, backgroundLogE, C);
+ else {
+ /* Energy decay */
+ opus_val16 decay = st->loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT);
+ c=0; do
+ {
+ for (i=st->start;i<st->end;i++)
+ oldBandE[c*st->mode->nbEBands+i] -= decay;
+ } while (++c<C);
+ log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
+ }
+ seed = st->rng;
+ for (c=0;c<C;c++)
+ {
+ for (i=0;i<(st->mode->eBands[st->start]<<LM);i++)
+ X[c*N+i] = 0;
+ for (i=st->start;i<st->mode->effEBands;i++)
+ {
+ int j;
+ int boffs;
+ int blen;
+ boffs = N*c+(st->mode->eBands[i]<<LM);
+ blen = (st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
+ for (j=0;j<blen;j++)
+ {
+ seed = celt_lcg_rand(seed);
+ X[boffs+j] = (celt_norm)((opus_int32)seed>>20);
+ }
+ renormalise_vector(X+boffs, blen, Q15ONE);
+ }
+ for (i=(st->mode->eBands[st->end]<<LM);i<N;i++)
+ X[c*N+i] = 0;
+ }
+ st->rng = seed;
+
+ denormalise_bands(st->mode, X, freq, bandE, st->mode->effEBands, C, 1<<LM);
+
+ c=0; do
+ for (i=0;i<st->mode->eBands[st->start]<<LM;i++)
+ freq[c*N+i] = 0;
+ while (++c<C);
+ c=0; do {
+ int bound = st->mode->eBands[effEnd]<<LM;
+ if (st->downsample!=1)
+ bound = IMIN(bound, N/st->downsample);
+ for (i=bound;i<N;i++)
+ freq[c*N+i] = 0;
+ } while (++c<C);
+ compute_inv_mdcts(st->mode, 0, freq, out_syn, overlap_mem, C, LM);
+ } else {
+ /* Pitch-based PLC */
+ if (st->loss_count == 0)
+ {
+ opus_val16 pitch_buf[DECODE_BUFFER_SIZE>>1];
+ /* Corresponds to a min pitch of 67 Hz. It's possible to save CPU in this
+ search by using only part of the decode buffer */
+ int poffset = 720;
+ pitch_downsample(decode_mem, pitch_buf, DECODE_BUFFER_SIZE, C);
+ /* Max pitch is 100 samples (480 Hz) */
+ pitch_search(pitch_buf+((poffset)>>1), pitch_buf, DECODE_BUFFER_SIZE-poffset,
+ poffset-100, &pitch_index);
+ pitch_index = poffset-pitch_index;
+ st->last_pitch_index = pitch_index;
+ } else {
+ pitch_index = st->last_pitch_index;
+ fade = QCONST16(.8f,15);
+ }
+
+ c=0; do {
+ VARDECL(opus_val32, e);
+ opus_val16 exc[MAX_PERIOD];
+ opus_val32 ac[LPC_ORDER+1];
+ opus_val16 decay = 1;
+ opus_val32 S1=0;
+ opus_val16 mem[LPC_ORDER]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ ALLOC(e, MAX_PERIOD+2*st->mode->overlap, opus_val32);
+
+ offset = MAX_PERIOD-pitch_index;
+ for (i=0;i<MAX_PERIOD;i++)
+ exc[i] = ROUND16(out_mem[c][i], SIG_SHIFT);
+
+ if (st->loss_count == 0)
+ {
+ _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
+ LPC_ORDER, MAX_PERIOD);
+
+ /* Noise floor -40 dB */
+#ifdef FIXED_POINT
+ ac[0] += SHR32(ac[0],13);
+#else
+ ac[0] *= 1.0001f;
+#endif
+ /* Lag windowing */
+ for (i=1;i<=LPC_ORDER;i++)
+ {
+ /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
+#ifdef FIXED_POINT
+ ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
+#else
+ ac[i] -= ac[i]*(.008f*i)*(.008f*i);
+#endif
+ }
+
+ _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
+ }
+ for (i=0;i<LPC_ORDER;i++)
+ mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
+ celt_fir(exc, lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
+ /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
+ /* Check if the waveform is decaying (and if so how fast) */
+ {
+ opus_val32 E1=1, E2=1;
+ int period;
+ if (pitch_index <= MAX_PERIOD/2)
+ period = pitch_index;
+ else
+ period = MAX_PERIOD/2;
+ for (i=0;i<period;i++)
+ {
+ E1 += SHR32(MULT16_16(exc[MAX_PERIOD-period+i],exc[MAX_PERIOD-period+i]),8);
+ E2 += SHR32(MULT16_16(exc[MAX_PERIOD-2*period+i],exc[MAX_PERIOD-2*period+i]),8);
+ }
+ if (E1 > E2)
+ E1 = E2;
+ decay = celt_sqrt(frac_div32(SHR32(E1,1),E2));
+ }
+
+ /* Copy excitation, taking decay into account */
+ for (i=0;i<len+st->mode->overlap;i++)
+ {
+ opus_val16 tmp;
+ if (offset+i >= MAX_PERIOD)
+ {
+ offset -= pitch_index;
+ decay = MULT16_16_Q15(decay, decay);
+ }
+ e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
+ tmp = ROUND16(out_mem[c][offset+i],SIG_SHIFT);
+ S1 += SHR32(MULT16_16(tmp,tmp),8);
+ }
+ for (i=0;i<LPC_ORDER;i++)
+ mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
+ for (i=0;i<len+st->mode->overlap;i++)
+ e[i] = MULT16_32_Q15(fade, e[i]);
+ celt_iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
+
+ {
+ opus_val32 S2=0;
+ for (i=0;i<len+overlap;i++)
+ {
+ opus_val16 tmp = ROUND16(e[i],SIG_SHIFT);
+ S2 += SHR32(MULT16_16(tmp,tmp),8);
+ }
+ /* This checks for an "explosion" in the synthesis */
+#ifdef FIXED_POINT
+ if (!(S1 > SHR32(S2,2)))
+#else
+ /* Float test is written this way to catch NaNs at the same time */
+ if (!(S1 > 0.2f*S2))
+#endif
+ {
+ for (i=0;i<len+overlap;i++)
+ e[i] = 0;
+ } else if (S1 < S2)
+ {
+ opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
+ for (i=0;i<len+overlap;i++)
+ e[i] = MULT16_32_Q15(ratio, e[i]);
+ }
+ }
+
+ /* Apply post-filter to the MDCT overlap of the previous frame */
+ comb_filter(out_mem[c]+MAX_PERIOD, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
+ st->postfilter_gain, st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
+ NULL, 0);
+
+ for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
+ out_mem[c][i] = out_mem[c][N+i];
+
+ /* Apply TDAC to the concealed audio so that it blends with the
+ previous and next frames */
+ for (i=0;i<overlap/2;i++)
+ {
+ opus_val32 tmp;
+ tmp = MULT16_32_Q15(st->mode->window[i], e[N+overlap-1-i]) +
+ MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i ]);
+ out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp);
+ out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp);
+ }
+ for (i=0;i<N;i++)
+ out_mem[c][MAX_PERIOD-N+i] = e[i];
+
+ /* Apply pre-filter to the MDCT overlap for the next frame (post-filter will be applied then) */
+ comb_filter(e, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
+ -st->postfilter_gain, -st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
+ NULL, 0);
+ for (i=0;i<overlap;i++)
+ out_mem[c][MAX_PERIOD+i] = e[i];
+ } while (++c<C);
+ }
+
+ deemphasis(out_syn, pcm, N, C, st->downsample, st->mode->preemph, st->preemph_memD);
+
+ st->loss_count++;
+
+ RESTORE_STACK;
+}
+
+int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec)
+{
+ int c, i, N;
+ int spread_decision;
+ opus_int32 bits;
+ ec_dec _dec;
+ VARDECL(celt_sig, freq);
+ VARDECL(celt_norm, X);
+ VARDECL(celt_ener, bandE);
+ VARDECL(int, fine_quant);
+ VARDECL(int, pulses);
+ VARDECL(int, cap);
+ VARDECL(int, offsets);
+ VARDECL(int, fine_priority);
+ VARDECL(int, tf_res);
+ VARDECL(unsigned char, collapse_masks);
+ celt_sig *out_mem[2];
+ celt_sig *decode_mem[2];
+ celt_sig *overlap_mem[2];
+ celt_sig *out_syn[2];
+ opus_val16 *lpc;
+ opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
+
+ int shortBlocks;
+ int isTransient;
+ int intra_ener;
+ const int CC = st->channels;
+ int LM, M;
+ int effEnd;
+ int codedBands;
+ int alloc_trim;
+ int postfilter_pitch;
+ opus_val16 postfilter_gain;
+ int intensity=0;
+ int dual_stereo=0;
+ opus_int32 total_bits;
+ opus_int32 balance;
+ opus_int32 tell;
+ int dynalloc_logp;
+ int postfilter_tapset;
+ int anti_collapse_rsv;
+ int anti_collapse_on=0;
+ int silence;
+ int C = st->stream_channels;
+ ALLOC_STACK;
+
+ frame_size *= st->downsample;
+
+ c=0; do {
+ decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
+ out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
+ overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
+ } while (++c<CC);
+ lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*CC);
+ oldBandE = lpc+CC*LPC_ORDER;
+ oldLogE = oldBandE + 2*st->mode->nbEBands;
+ oldLogE2 = oldLogE + 2*st->mode->nbEBands;
+ backgroundLogE = oldLogE2 + 2*st->mode->nbEBands;
+
+#ifdef CUSTOM_MODES
+ if (st->signalling && data!=NULL)
+ {
+ int data0=data[0];
+ /* Convert "standard mode" to Opus header */
+ if (st->mode->Fs==48000 && st->mode->shortMdctSize==120)
+ {
+ data0 = fromOpus(data0);
+ if (data0<0)
+ return OPUS_INVALID_PACKET;
+ }
+ st->end = IMAX(1, st->mode->effEBands-2*(data0>>5));
+ LM = (data0>>3)&0x3;
+ C = 1 + ((data0>>2)&0x1);
+ data++;
+ len--;
+ if (LM>st->mode->maxLM)
+ return OPUS_INVALID_PACKET;
+ if (frame_size < st->mode->shortMdctSize<<LM)
+ return OPUS_BUFFER_TOO_SMALL;
+ else
+ frame_size = st->mode->shortMdctSize<<LM;
+ } else {
+#else
+ {
+#endif
+ for (LM=0;LM<=st->mode->maxLM;LM++)
+ if (st->mode->shortMdctSize<<LM==frame_size)
+ break;
+ if (LM>st->mode->maxLM)
+ return OPUS_BAD_ARG;
+ }
+ M=1<<LM;
+
+ if (len<0 || len>1275 || pcm==NULL)
+ return OPUS_BAD_ARG;
+
+ N = M*st->mode->shortMdctSize;
+
+ effEnd = st->end;
+ if (effEnd > st->mode->effEBands)
+ effEnd = st->mode->effEBands;
+
+ ALLOC(freq, IMAX(CC,C)*N, celt_sig); /**< Interleaved signal MDCTs */
+ ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
+ ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
+ c=0; do
+ for (i=0;i<M*st->mode->eBands[st->start];i++)
+ X[c*N+i] = 0;
+ while (++c<C);
+ c=0; do
+ for (i=M*st->mode->eBands[effEnd];i<N;i++)
+ X[c*N+i] = 0;
+ while (++c<C);
+
+ if (data == NULL || len<=1)
+ {
+ celt_decode_lost(st, pcm, N, LM);
+ RESTORE_STACK;
+ return frame_size/st->downsample;
+ }
+
+ if (dec == NULL)
+ {
+ ec_dec_init(&_dec,(unsigned char*)data,len);
+ dec = &_dec;
+ }
+
+ if (C==1)
+ {
+ for (i=0;i<st->mode->nbEBands;i++)
+ oldBandE[i]=MAX16(oldBandE[i],oldBandE[st->mode->nbEBands+i]);
+ }
+
+ total_bits = len*8;
+ tell = ec_tell(dec);
+
+ if (tell >= total_bits)
+ silence = 1;
+ else if (tell==1)
+ silence = ec_dec_bit_logp(dec, 15);
+ else
+ silence = 0;
+ if (silence)
+ {
+ /* Pretend we've read all the remaining bits */
+ tell = len*8;
+ dec->nbits_total+=tell-ec_tell(dec);
+ }
+
+ postfilter_gain = 0;
+ postfilter_pitch = 0;
+ postfilter_tapset = 0;
+ if (st->start==0 && tell+16 <= total_bits)
+ {
+ if(ec_dec_bit_logp(dec, 1))
+ {
+ int qg, octave;
+ octave = ec_dec_uint(dec, 6);
+ postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
+ qg = ec_dec_bits(dec, 3);
+ if (ec_tell(dec)+2<=total_bits)
+ postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
+ postfilter_gain = QCONST16(.09375f,15)*(qg+1);
+ }
+ tell = ec_tell(dec);
+ }
+
+ if (LM > 0 && tell+3 <= total_bits)
+ {
+ isTransient = ec_dec_bit_logp(dec, 3);
+ tell = ec_tell(dec);
+ }
+ else
+ isTransient = 0;
+
+ if (isTransient)
+ shortBlocks = M;
+ else
+ shortBlocks = 0;
+
+ /* Decode the global flags (first symbols in the stream) */
+ intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;
+ /* Get band energies */
+ unquant_coarse_energy(st->mode, st->start, st->end, oldBandE,
+ intra_ener, dec, C, LM);
+
+ ALLOC(tf_res, st->mode->nbEBands, int);
+ tf_decode(st->start, st->end, isTransient, tf_res, LM, dec);
+
+ tell = ec_tell(dec);
+ spread_decision = SPREAD_NORMAL;
+ if (tell+4 <= total_bits)
+ spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
+
+ ALLOC(pulses, st->mode->nbEBands, int);
+ ALLOC(cap, st->mode->nbEBands, int);
+ ALLOC(offsets, st->mode->nbEBands, int);
+ ALLOC(fine_priority, st->mode->nbEBands, int);
+
+ init_caps(st->mode,cap,LM,C);
+
+ dynalloc_logp = 6;
+ total_bits<<=BITRES;
+ tell = ec_tell_frac(dec);
+ for (i=st->start;i<st->end;i++)
+ {
+ int width, quanta;
+ int dynalloc_loop_logp;
+ int boost;
+ width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
+ /* quanta is 6 bits, but no more than 1 bit/sample
+ and no less than 1/8 bit/sample */
+ quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
+ dynalloc_loop_logp = dynalloc_logp;
+ boost = 0;
+ while (tell+(dynalloc_loop_logp<<BITRES) < total_bits && boost < cap[i])
+ {
+ int flag;
+ flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
+ tell = ec_tell_frac(dec);
+ if (!flag)
+ break;
+ boost += quanta;
+ total_bits -= quanta;
+ dynalloc_loop_logp = 1;
+ }
+ offsets[i] = boost;
+ /* Making dynalloc more likely */
+ if (boost>0)
+ dynalloc_logp = IMAX(2, dynalloc_logp-1);
+ }
+
+ ALLOC(fine_quant, st->mode->nbEBands, int);
+ alloc_trim = tell+(6<<BITRES) <= total_bits ?
+ ec_dec_icdf(dec, trim_icdf, 7) : 5;
+
+ bits = (((opus_int32)len*8)<<BITRES) - ec_tell_frac(dec) - 1;
+ anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
+ bits -= anti_collapse_rsv;
+ codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
+ alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
+ fine_quant, fine_priority, C, LM, dec, 0, 0);
+
+ unquant_fine_energy(st->mode, st->start, st->end, oldBandE, fine_quant, dec, C);
+
+ /* Decode fixed codebook */
+ ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char);
+ quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks,
+ NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
+ len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng);
+
+ if (anti_collapse_rsv > 0)
+ {
+ anti_collapse_on = ec_dec_bits(dec, 1);
+ }
+
+ unquant_energy_finalise(st->mode, st->start, st->end, oldBandE,
+ fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
+
+ if (anti_collapse_on)
+ anti_collapse(st->mode, X, collapse_masks, LM, C, N,
+ st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
+
+ log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
+
+ if (silence)
+ {
+ for (i=0;i<C*st->mode->nbEBands;i++)
+ {
+ bandE[i] = 0;
+ oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
+ }
+ }
+ /* Synthesis */
+ denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
+
+ OPUS_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N);
+ if (CC==2)
+ OPUS_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N);
+
+ c=0; do
+ for (i=0;i<M*st->mode->eBands[st->start];i++)
+ freq[c*N+i] = 0;
+ while (++c<C);
+ c=0; do {
+ int bound = M*st->mode->eBands[effEnd];
+ if (st->downsample!=1)
+ bound = IMIN(bound, N/st->downsample);
+ for (i=bound;i<N;i++)
+ freq[c*N+i] = 0;
+ } while (++c<C);
+
+ out_syn[0] = out_mem[0]+MAX_PERIOD-N;
+ if (CC==2)
+ out_syn[1] = out_mem[1]+MAX_PERIOD-N;
+
+ if (CC==2&&C==1)
+ {
+ for (i=0;i<N;i++)
+ freq[N+i] = freq[i];
+ }
+ if (CC==1&&C==2)
+ {
+ for (i=0;i<N;i++)
+ freq[i] = HALF32(ADD32(freq[i],freq[N+i]));
+ }
+
+ /* Compute inverse MDCTs */
+ compute_inv_mdcts(st->mode, shortBlocks, freq, out_syn, overlap_mem, CC, LM);
+
+ c=0; do {
+ st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
+ st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
+ comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, st->mode->shortMdctSize,
+ st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
+ st->mode->window, st->overlap);
+ if (LM!=0)
+ comb_filter(out_syn[c]+st->mode->shortMdctSize, out_syn[c]+st->mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-st->mode->shortMdctSize,
+ st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,
+ st->mode->window, st->mode->overlap);
+
+ } while (++c<CC);
+ st->postfilter_period_old = st->postfilter_period;
+ st->postfilter_gain_old = st->postfilter_gain;
+ st->postfilter_tapset_old = st->postfilter_tapset;
+ st->postfilter_period = postfilter_pitch;
+ st->postfilter_gain = postfilter_gain;
+ st->postfilter_tapset = postfilter_tapset;
+ if (LM!=0)
+ {
+ st->postfilter_period_old = st->postfilter_period;
+ st->postfilter_gain_old = st->postfilter_gain;
+ st->postfilter_tapset_old = st->postfilter_tapset;
+ }
+
+ if (C==1) {
+ for (i=0;i<st->mode->nbEBands;i++)
+ oldBandE[st->mode->nbEBands+i]=oldBandE[i];
+ }
+
+ /* In case start or end were to change */
+ if (!isTransient)
+ {
+ for (i=0;i<2*st->mode->nbEBands;i++)
+ oldLogE2[i] = oldLogE[i];
+ for (i=0;i<2*st->mode->nbEBands;i++)
+ oldLogE[i] = oldBandE[i];
+ for (i=0;i<2*st->mode->nbEBands;i++)
+ backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]);
+ } else {
+ for (i=0;i<2*st->mode->nbEBands;i++)
+ oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
+ }
+ c=0; do
+ {
+ for (i=0;i<st->start;i++)
+ {
+ oldBandE[c*st->mode->nbEBands+i]=0;
+ oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
+ }
+ for (i=st->end;i<st->mode->nbEBands;i++)
+ {
+ oldBandE[c*st->mode->nbEBands+i]=0;
+ oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
+ }
+ } while (++c<2);
+ st->rng = dec->rng;
+
+ deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD);
+ st->loss_count = 0;
+ RESTORE_STACK;
+ if (ec_tell(dec) > 8*len)
+ return OPUS_INTERNAL_ERROR;
+ if(ec_get_error(dec))
+ st->error = 1;
+ return frame_size/st->downsample;
+}
+
+
+#ifdef CUSTOM_MODES
+
+#ifdef FIXED_POINT
+int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
+{
+ return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
+}
+
+#ifndef DISABLE_FLOAT_API
+int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
+{
+ int j, ret, C, N;
+ VARDECL(opus_int16, out);
+ ALLOC_STACK;
+
+ if (pcm==NULL)
+ return OPUS_BAD_ARG;
+
+ C = st->channels;
+ N = frame_size;
+
+ ALLOC(out, C*N, opus_int16);
+ ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL);
+ if (ret>0)
+ for (j=0;j<C*ret;j++)
+ pcm[j]=out[j]*(1.f/32768.f);
+
+ RESTORE_STACK;
+ return ret;
+}
+#endif /* DISABLE_FLOAT_API */
+
+#else
+
+int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
+{
+ return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
+}
+
+int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
+{
+ int j, ret, C, N;
+ VARDECL(celt_sig, out);
+ ALLOC_STACK;
+
+ if (pcm==NULL)
+ return OPUS_BAD_ARG;
+
+ C = st->channels;
+ N = frame_size;
+ ALLOC(out, C*N, celt_sig);
+
+ ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL);
+
+ if (ret>0)
+ for (j=0;j<C*ret;j++)
+ pcm[j] = FLOAT2INT16 (out[j]);
+
+ RESTORE_STACK;
+ return ret;
+}
+
+#endif
+#endif /* CUSTOM_MODES */
+
+int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
+{
+ va_list ap;
+
+ va_start(ap, request);
+ switch (request)
+ {
+ case CELT_SET_START_BAND_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value<0 || value>=st->mode->nbEBands)
+ goto bad_arg;
+ st->start = value;
+ }
+ break;
+ case CELT_SET_END_BAND_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value<1 || value>st->mode->nbEBands)
+ goto bad_arg;
+ st->end = value;
+ }
+ break;
+ case CELT_SET_CHANNELS_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value<1 || value>2)
+ goto bad_arg;
+ st->stream_channels = value;
+ }
+ break;
+ case CELT_GET_AND_CLEAR_ERROR_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (value==NULL)
+ goto bad_arg;
+ *value=st->error;
+ st->error = 0;
+ }
+ break;
+ case OPUS_GET_LOOKAHEAD_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (value==NULL)
+ goto bad_arg;
+ *value = st->overlap/st->downsample;
+ }
+ break;
+ case OPUS_RESET_STATE:
+ {
+ int i;
+ opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2;
+ lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels);
+ oldBandE = lpc+st->channels*LPC_ORDER;
+ oldLogE = oldBandE + 2*st->mode->nbEBands;
+ oldLogE2 = oldLogE + 2*st->mode->nbEBands;
+ OPUS_CLEAR((char*)&st->DECODER_RESET_START,
+ opus_custom_decoder_get_size(st->mode, st->channels)-
+ ((char*)&st->DECODER_RESET_START - (char*)st));
+ for (i=0;i<2*st->mode->nbEBands;i++)
+ oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
+ }
+ break;
+ case OPUS_GET_PITCH_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (value==NULL)
+ goto bad_arg;
+ *value = st->postfilter_period;
+ }
+ break;
+#ifdef OPUS_BUILD
+ case CELT_GET_MODE_REQUEST:
+ {
+ const CELTMode ** value = va_arg(ap, const CELTMode**);
+ if (value==0)
+ goto bad_arg;
+ *value=st->mode;
+ }
+ break;
+ case CELT_SET_SIGNALLING_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ st->signalling = value;
+ }
+ break;
+ case OPUS_GET_FINAL_RANGE_REQUEST:
+ {
+ opus_uint32 * value = va_arg(ap, opus_uint32 *);
+ if (value==0)
+ goto bad_arg;
+ *value=st->rng;
+ }
+ break;
+#endif
+ default:
+ goto bad_request;
+ }
+ va_end(ap);
+ return OPUS_OK;
+bad_arg:
+ va_end(ap);
+ return OPUS_BAD_ARG;
+bad_request:
+ va_end(ap);
+ return OPUS_UNIMPLEMENTED;
+}
+
+
+
+const char *opus_strerror(int error)
+{
+ static const char * const error_strings[8] = {
+ "success",
+ "invalid argument",
+ "buffer too small",
+ "internal error",
+ "corrupted stream",
+ "request not implemented",
+ "invalid state",
+ "memory allocation failed"
+ };
+ if (error > 0 || error < -7)
+ return "unknown error";
+ else
+ return error_strings[-error];
+}
+
+const char *opus_get_version_string(void)
+{
+ return "libopus " OPUS_VERSION
+#ifdef FIXED_POINT
+ "-fixed"
+#endif
+#ifdef FUZZING
+ "-fuzzing"
+#endif
+ ;
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/celt.h b/lib/rbcodec/codecs/libopus/celt/celt.h
new file mode 100644
index 0000000000..218cd883df
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/celt.h
@@ -0,0 +1,117 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2008 Gregory Maxwell
+ Written by Jean-Marc Valin and Gregory Maxwell */
+/**
+ @file celt.h
+ @brief Contains all the functions for encoding and decoding audio
+ */
+
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 CELT_H
+#define CELT_H
+
+#include "opus_types.h"
+#include "opus_defines.h"
+#include "opus_custom.h"
+#include "entenc.h"
+#include "entdec.h"
+#include "arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CELTEncoder OpusCustomEncoder
+#define CELTDecoder OpusCustomDecoder
+#define CELTMode OpusCustomMode
+
+#define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
+
+/* Encoder/decoder Requests */
+
+#define CELT_SET_PREDICTION_REQUEST 10002
+/** Controls the use of interframe prediction.
+ 0=Independent frames
+ 1=Short term interframe prediction allowed
+ 2=Long term prediction allowed
+ */
+#define CELT_SET_PREDICTION(x) CELT_SET_PREDICTION_REQUEST, __opus_check_int(x)
+
+#define CELT_SET_INPUT_CLIPPING_REQUEST 10004
+#define CELT_SET_INPUT_CLIPPING(x) CELT_SET_INPUT_CLIPPING_REQUEST, __opus_check_int(x)
+
+#define CELT_GET_AND_CLEAR_ERROR_REQUEST 10007
+#define CELT_GET_AND_CLEAR_ERROR(x) CELT_GET_AND_CLEAR_ERROR_REQUEST, __opus_check_int_ptr(x)
+
+#define CELT_SET_CHANNELS_REQUEST 10008
+#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, __opus_check_int(x)
+
+
+/* Internal */
+#define CELT_SET_START_BAND_REQUEST 10010
+#define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, __opus_check_int(x)
+
+#define CELT_SET_END_BAND_REQUEST 10012
+#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, __opus_check_int(x)
+
+#define CELT_GET_MODE_REQUEST 10015
+/** Get the CELTMode used by an encoder or decoder */
+#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, _celt_check_mode_ptr_ptr(x)
+
+#define CELT_SET_SIGNALLING_REQUEST 10016
+#define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x)
+
+
+
+/* Encoder stuff */
+
+int celt_encoder_get_size(int channels);
+
+int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc);
+
+int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels);
+
+
+
+/* Decoder stuff */
+
+int celt_decoder_get_size(int channels);
+
+
+int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels);
+
+int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec);
+
+#define celt_encoder_ctl opus_custom_encoder_ctl
+#define celt_decoder_ctl opus_custom_decoder_ctl
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CELT_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/celt_lpc.c b/lib/rbcodec/codecs/libopus/celt/celt_lpc.c
new file mode 100644
index 0000000000..66aed1de09
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/celt_lpc.c
@@ -0,0 +1,188 @@
+/* Copyright (c) 2009-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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include "celt_lpc.h"
+#include "stack_alloc.h"
+#include "mathops.h"
+
+void _celt_lpc(
+ opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */
+const opus_val32 *ac, /* in: [0...p] autocorrelation values */
+int p
+)
+{
+ int i, j;
+ opus_val32 r;
+ opus_val32 error = ac[0];
+#ifdef FIXED_POINT
+ opus_val32 lpc[LPC_ORDER];
+#else
+ float *lpc = _lpc;
+#endif
+
+ for (i = 0; i < p; i++)
+ lpc[i] = 0;
+ if (ac[0] != 0)
+ {
+ for (i = 0; i < p; i++) {
+ /* Sum up this iteration's reflection coefficient */
+ opus_val32 rr = 0;
+ for (j = 0; j < i; j++)
+ rr += MULT32_32_Q31(lpc[j],ac[i - j]);
+ rr += SHR32(ac[i + 1],3);
+ r = -frac_div32(SHL32(rr,3), error);
+ /* Update LPC coefficients and total error */
+ lpc[i] = SHR32(r,3);
+ for (j = 0; j < (i+1)>>1; j++)
+ {
+ opus_val32 tmp1, tmp2;
+ tmp1 = lpc[j];
+ tmp2 = lpc[i-1-j];
+ lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2);
+ lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
+ }
+
+ error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
+ /* Bail out once we get 30 dB gain */
+#ifdef FIXED_POINT
+ if (error<SHR32(ac[0],10))
+ break;
+#else
+ if (error<.001f*ac[0])
+ break;
+#endif
+ }
+ }
+#ifdef FIXED_POINT
+ for (i=0;i<p;i++)
+ _lpc[i] = ROUND16(lpc[i],16);
+#endif
+}
+
+void celt_fir(const opus_val16 *x,
+ const opus_val16 *num,
+ opus_val16 *y,
+ int N,
+ int ord,
+ opus_val16 *mem)
+{
+ int i,j;
+
+ for (i=0;i<N;i++)
+ {
+ opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
+ for (j=0;j<ord;j++)
+ {
+ sum += MULT16_16(num[j],mem[j]);
+ }
+ for (j=ord-1;j>=1;j--)
+ {
+ mem[j]=mem[j-1];
+ }
+ mem[0] = x[i];
+ y[i] = ROUND16(sum, SIG_SHIFT);
+ }
+}
+
+void celt_iir(const opus_val32 *x,
+ const opus_val16 *den,
+ opus_val32 *y,
+ int N,
+ int ord,
+ opus_val16 *mem)
+{
+ int i,j;
+ for (i=0;i<N;i++)
+ {
+ opus_val32 sum = x[i];
+ for (j=0;j<ord;j++)
+ {
+ sum -= MULT16_16(den[j],mem[j]);
+ }
+ for (j=ord-1;j>=1;j--)
+ {
+ mem[j]=mem[j-1];
+ }
+ mem[0] = ROUND16(sum,SIG_SHIFT);
+ y[i] = sum;
+ }
+}
+
+void _celt_autocorr(
+ const opus_val16 *x, /* in: [0...n-1] samples x */
+ opus_val32 *ac, /* out: [0...lag-1] ac values */
+ const opus_val16 *window,
+ int overlap,
+ int lag,
+ int n
+ )
+{
+ opus_val32 d;
+ int i;
+ VARDECL(opus_val16, xx);
+ SAVE_STACK;
+ ALLOC(xx, n, opus_val16);
+ celt_assert(n>0);
+ celt_assert(overlap>=0);
+ for (i=0;i<n;i++)
+ xx[i] = x[i];
+ for (i=0;i<overlap;i++)
+ {
+ xx[i] = MULT16_16_Q15(x[i],window[i]);
+ xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
+ }
+#ifdef FIXED_POINT
+ {
+ opus_val32 ac0=0;
+ int shift;
+ for(i=0;i<n;i++)
+ ac0 += SHR32(MULT16_16(xx[i],xx[i]),9);
+ ac0 += 1+n;
+
+ shift = celt_ilog2(ac0)-30+10;
+ shift = (shift+1)/2;
+ for(i=0;i<n;i++)
+ xx[i] = VSHR32(xx[i], shift);
+ }
+#endif
+ while (lag>=0)
+ {
+ for (i = lag, d = 0; i < n; i++)
+ d += xx[i] * xx[i-lag];
+ ac[lag] = d;
+ /*printf ("%f ", ac[lag]);*/
+ lag--;
+ }
+ /*printf ("\n");*/
+ ac[0] += 10;
+
+ RESTORE_STACK;
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/celt_lpc.h b/lib/rbcodec/codecs/libopus/celt/celt_lpc.h
new file mode 100644
index 0000000000..2baa77edf8
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/celt_lpc.h
@@ -0,0 +1,53 @@
+/* Copyright (c) 2009-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.
+
+ 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 COPYRIGHT OWNER
+ 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 PLC_H
+#define PLC_H
+
+#include "arch.h"
+
+#define LPC_ORDER 24
+
+void _celt_lpc(opus_val16 *_lpc, const opus_val32 *ac, int p);
+
+void celt_fir(const opus_val16 *x,
+ const opus_val16 *num,
+ opus_val16 *y,
+ int N,
+ int ord,
+ opus_val16 *mem);
+
+void celt_iir(const opus_val32 *x,
+ const opus_val16 *den,
+ opus_val32 *y,
+ int N,
+ int ord,
+ opus_val16 *mem);
+
+void _celt_autocorr(const opus_val16 *x, opus_val32 *ac, const opus_val16 *window, int overlap, int lag, int n);
+
+#endif /* PLC_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/cwrs.c b/lib/rbcodec/codecs/libopus/celt/cwrs.c
new file mode 100644
index 0000000000..3d5dd790d9
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/cwrs.c
@@ -0,0 +1,645 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2007-2009 Timothy B. Terriberry
+ Written by Timothy B. Terriberry and 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include "os_support.h"
+#include "cwrs.h"
+#include "mathops.h"
+#include "arch.h"
+
+#ifdef CUSTOM_MODES
+
+/*Guaranteed to return a conservatively large estimate of the binary logarithm
+ with frac bits of fractional precision.
+ Tested for all possible 32-bit inputs with frac=4, where the maximum
+ overestimation is 0.06254243 bits.*/
+int log2_frac(opus_uint32 val, int frac)
+{
+ int l;
+ l=EC_ILOG(val);
+ if(val&(val-1)){
+ /*This is (val>>l-16), but guaranteed to round up, even if adding a bias
+ before the shift would cause overflow (e.g., for 0xFFFFxxxx).
+ Doesn't work for val=0, but that case fails the test above.*/
+ if(l>16)val=((val-1)>>(l-16))+1;
+ else val<<=16-l;
+ l=(l-1)<<frac;
+ /*Note that we always need one iteration, since the rounding up above means
+ that we might need to adjust the integer part of the logarithm.*/
+ do{
+ int b;
+ b=(int)(val>>16);
+ l+=b<<frac;
+ val=(val+b)>>b;
+ val=(val*val+0x7FFF)>>15;
+ }
+ while(frac-->0);
+ /*If val is not exactly 0x8000, then we have to round up the remainder.*/
+ return l+(val>0x8000);
+ }
+ /*Exact powers of two require no rounding.*/
+ else return (l-1)<<frac;
+}
+#endif
+
+#ifndef SMALL_FOOTPRINT
+
+#define MASK32 (0xFFFFFFFF)
+
+/*INV_TABLE[i] holds the multiplicative inverse of (2*i+1) mod 2**32.*/
+static const opus_uint32 INV_TABLE[53]={
+ 0x00000001,0xAAAAAAAB,0xCCCCCCCD,0xB6DB6DB7,
+ 0x38E38E39,0xBA2E8BA3,0xC4EC4EC5,0xEEEEEEEF,
+ 0xF0F0F0F1,0x286BCA1B,0x3CF3CF3D,0xE9BD37A7,
+ 0xC28F5C29,0x684BDA13,0x4F72C235,0xBDEF7BDF,
+ 0x3E0F83E1,0x8AF8AF8B,0x914C1BAD,0x96F96F97,
+ 0xC18F9C19,0x2FA0BE83,0xA4FA4FA5,0x677D46CF,
+ 0x1A1F58D1,0xFAFAFAFB,0x8C13521D,0x586FB587,
+ 0xB823EE09,0xA08AD8F3,0xC10C9715,0xBEFBEFBF,
+ 0xC0FC0FC1,0x07A44C6B,0xA33F128D,0xE327A977,
+ 0xC7E3F1F9,0x962FC963,0x3F2B3885,0x613716AF,
+ 0x781948B1,0x2B2E43DB,0xFCFCFCFD,0x6FD0EB67,
+ 0xFA3F47E9,0xD2FD2FD3,0x3F4FD3F5,0xD4E25B9F,
+ 0x5F02A3A1,0xBF5A814B,0x7C32B16D,0xD3431B57,
+ 0xD8FD8FD9,
+};
+
+/*Computes (_a*_b-_c)/(2*_d+1) when the quotient is known to be exact.
+ _a, _b, _c, and _d may be arbitrary so long as the arbitrary precision result
+ fits in 32 bits, but currently the table for multiplicative inverses is only
+ valid for _d<=52.*/
+static inline opus_uint32 imusdiv32odd(opus_uint32 _a,opus_uint32 _b,
+ opus_uint32 _c,int _d){
+ celt_assert(_d<=52);
+ return (_a*_b-_c)*INV_TABLE[_d]&MASK32;
+}
+
+/*Computes (_a*_b-_c)/_d when the quotient is known to be exact.
+ _d does not actually have to be even, but imusdiv32odd will be faster when
+ it's odd, so you should use that instead.
+ _a and _d are assumed to be small (e.g., _a*_d fits in 32 bits; currently the
+ table for multiplicative inverses is only valid for _d<=54).
+ _b and _c may be arbitrary so long as the arbitrary precision reuslt fits in
+ 32 bits.*/
+static inline opus_uint32 imusdiv32even(opus_uint32 _a,opus_uint32 _b,
+ opus_uint32 _c,int _d){
+ opus_uint32 inv;
+ int mask;
+ int shift;
+ int one;
+ celt_assert(_d>0);
+ celt_assert(_d<=54);
+ shift=EC_ILOG(_d^(_d-1));
+ inv=INV_TABLE[(_d-1)>>shift];
+ shift--;
+ one=1<<shift;
+ mask=one-1;
+ return (_a*(_b>>shift)-(_c>>shift)+
+ ((_a*(_b&mask)+one-(_c&mask))>>shift)-1)*inv&MASK32;
+}
+
+#endif /* SMALL_FOOTPRINT */
+
+/*Although derived separately, the pulse vector coding scheme is equivalent to
+ a Pyramid Vector Quantizer \cite{Fis86}.
+ Some additional notes about an early version appear at
+ http://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering
+ and the definitions of some terms have evolved since that was written.
+
+ The conversion from a pulse vector to an integer index (encoding) and back
+ (decoding) is governed by two related functions, V(N,K) and U(N,K).
+
+ V(N,K) = the number of combinations, with replacement, of N items, taken K
+ at a time, when a sign bit is added to each item taken at least once (i.e.,
+ the number of N-dimensional unit pulse vectors with K pulses).
+ One way to compute this is via
+ V(N,K) = K>0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1,
+ where choose() is the binomial function.
+ A table of values for N<10 and K<10 looks like:
+ V[10][10] = {
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 2, 2, 2, 2, 2, 2, 2, 2, 2},
+ {1, 4, 8, 12, 16, 20, 24, 28, 32, 36},
+ {1, 6, 18, 38, 66, 102, 146, 198, 258, 326},
+ {1, 8, 32, 88, 192, 360, 608, 952, 1408, 1992},
+ {1, 10, 50, 170, 450, 1002, 1970, 3530, 5890, 9290},
+ {1, 12, 72, 292, 912, 2364, 5336, 10836, 20256, 35436},
+ {1, 14, 98, 462, 1666, 4942, 12642, 28814, 59906, 115598},
+ {1, 16, 128, 688, 2816, 9424, 27008, 68464, 157184, 332688},
+ {1, 18, 162, 978, 4482, 16722, 53154, 148626, 374274, 864146}
+ };
+
+ U(N,K) = the number of such combinations wherein N-1 objects are taken at
+ most K-1 at a time.
+ This is given by
+ U(N,K) = sum(k=0...K-1,V(N-1,k))
+ = K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0.
+ The latter expression also makes clear that U(N,K) is half the number of such
+ combinations wherein the first object is taken at least once.
+ Although it may not be clear from either of these definitions, U(N,K) is the
+ natural function to work with when enumerating the pulse vector codebooks,
+ not V(N,K).
+ U(N,K) is not well-defined for N=0, but with the extension
+ U(0,K) = K>0 ? 0 : 1,
+ the function becomes symmetric: U(N,K) = U(K,N), with a similar table:
+ U[10][10] = {
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {0, 1, 3, 5, 7, 9, 11, 13, 15, 17},
+ {0, 1, 5, 13, 25, 41, 61, 85, 113, 145},
+ {0, 1, 7, 25, 63, 129, 231, 377, 575, 833},
+ {0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649},
+ {0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073},
+ {0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081},
+ {0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545},
+ {0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729}
+ };
+
+ With this extension, V(N,K) may be written in terms of U(N,K):
+ V(N,K) = U(N,K) + U(N,K+1)
+ for all N>=0, K>=0.
+ Thus U(N,K+1) represents the number of combinations where the first element
+ is positive or zero, and U(N,K) represents the number of combinations where
+ it is negative.
+ With a large enough table of U(N,K) values, we could write O(N) encoding
+ and O(min(N*log(K),N+K)) decoding routines, but such a table would be
+ prohibitively large for small embedded devices (K may be as large as 32767
+ for small N, and N may be as large as 200).
+
+ Both functions obey the same recurrence relation:
+ V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1),
+ U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1),
+ for all N>0, K>0, with different initial conditions at N=0 or K=0.
+ This allows us to construct a row of one of the tables above given the
+ previous row or the next row.
+ Thus we can derive O(NK) encoding and decoding routines with O(K) memory
+ using only addition and subtraction.
+
+ When encoding, we build up from the U(2,K) row and work our way forwards.
+ When decoding, we need to start at the U(N,K) row and work our way backwards,
+ which requires a means of computing U(N,K).
+ U(N,K) may be computed from two previous values with the same N:
+ U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2)
+ for all N>1, and since U(N,K) is symmetric, a similar relation holds for two
+ previous values with the same K:
+ U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K)
+ for all K>1.
+ This allows us to construct an arbitrary row of the U(N,K) table by starting
+ with the first two values, which are constants.
+ This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K)
+ multiplications.
+ Similar relations can be derived for V(N,K), but are not used here.
+
+ For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree
+ polynomial for fixed N.
+ The first few are
+ U(1,K) = 1,
+ U(2,K) = 2*K-1,
+ U(3,K) = (2*K-2)*K+1,
+ U(4,K) = (((4*K-6)*K+8)*K-3)/3,
+ U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3,
+ and
+ V(1,K) = 2,
+ V(2,K) = 4*K,
+ V(3,K) = 4*K*K+2,
+ V(4,K) = 8*(K*K+2)*K/3,
+ V(5,K) = ((4*K*K+20)*K*K+6)/3,
+ for all K>0.
+ This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for
+ small N (and indeed decoding is also O(N) for N<3).
+
+ @ARTICLE{Fis86,
+ author="Thomas R. Fischer",
+ title="A Pyramid Vector Quantizer",
+ journal="IEEE Transactions on Information Theory",
+ volume="IT-32",
+ number=4,
+ pages="568--583",
+ month=Jul,
+ year=1986
+ }*/
+
+#ifndef SMALL_FOOTPRINT
+/*Compute U(2,_k).
+ Note that this may be called with _k=32768 (maxK[2]+1).*/
+static inline unsigned ucwrs2(unsigned _k){
+ celt_assert(_k>0);
+ return _k+(_k-1);
+}
+
+/*Compute V(2,_k).*/
+static inline opus_uint32 ncwrs2(int _k){
+ celt_assert(_k>0);
+ return 4*(opus_uint32)_k;
+}
+
+/*Compute U(3,_k).
+ Note that this may be called with _k=32768 (maxK[3]+1).*/
+static inline opus_uint32 ucwrs3(unsigned _k){
+ celt_assert(_k>0);
+ return (2*(opus_uint32)_k-2)*_k+1;
+}
+
+/*Compute V(3,_k).*/
+static inline opus_uint32 ncwrs3(int _k){
+ celt_assert(_k>0);
+ return 2*(2*(unsigned)_k*(opus_uint32)_k+1);
+}
+
+/*Compute U(4,_k).*/
+static inline opus_uint32 ucwrs4(int _k){
+ celt_assert(_k>0);
+ return imusdiv32odd(2*_k,(2*_k-3)*(opus_uint32)_k+4,3,1);
+}
+
+/*Compute V(4,_k).*/
+static inline opus_uint32 ncwrs4(int _k){
+ celt_assert(_k>0);
+ return ((_k*(opus_uint32)_k+2)*_k)/3<<3;
+}
+
+#endif /* SMALL_FOOTPRINT */
+
+/*Computes the next row/column of any recurrence that obeys the relation
+ u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1].
+ _ui0 is the base case for the new row/column.*/
+static inline void unext(opus_uint32 *_ui,unsigned _len,opus_uint32 _ui0){
+ opus_uint32 ui1;
+ unsigned j;
+ /*This do-while will overrun the array if we don't have storage for at least
+ 2 values.*/
+ j=1; do {
+ ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0);
+ _ui[j-1]=_ui0;
+ _ui0=ui1;
+ } while (++j<_len);
+ _ui[j-1]=_ui0;
+}
+
+/*Computes the previous row/column of any recurrence that obeys the relation
+ u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1].
+ _ui0 is the base case for the new row/column.*/
+static inline void uprev(opus_uint32 *_ui,unsigned _n,opus_uint32 _ui0){
+ opus_uint32 ui1;
+ unsigned j;
+ /*This do-while will overrun the array if we don't have storage for at least
+ 2 values.*/
+ j=1; do {
+ ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0);
+ _ui[j-1]=_ui0;
+ _ui0=ui1;
+ } while (++j<_n);
+ _ui[j-1]=_ui0;
+}
+
+/*Compute V(_n,_k), as well as U(_n,0..._k+1).
+ _u: On exit, _u[i] contains U(_n,i) for i in [0..._k+1].*/
+static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){
+ opus_uint32 um2;
+ unsigned len;
+ unsigned k;
+ len=_k+2;
+ /*We require storage at least 3 values (e.g., _k>0).*/
+ celt_assert(len>=3);
+ _u[0]=0;
+ _u[1]=um2=1;
+#ifndef SMALL_FOOTPRINT
+ /*_k>52 doesn't work in the false branch due to the limits of INV_TABLE,
+ but _k isn't tested here because k<=52 for n=7*/
+ if(_n<=6)
+#endif
+ {
+ /*If _n==0, _u[0] should be 1 and the rest should be 0.*/
+ /*If _n==1, _u[i] should be 1 for i>1.*/
+ celt_assert(_n>=2);
+ /*If _k==0, the following do-while loop will overflow the buffer.*/
+ celt_assert(_k>0);
+ k=2;
+ do _u[k]=(k<<1)-1;
+ while(++k<len);
+ for(k=2;k<_n;k++)unext(_u+1,_k+1,1);
+ }
+#ifndef SMALL_FOOTPRINT
+ else{
+ opus_uint32 um1;
+ opus_uint32 n2m1;
+ _u[2]=n2m1=um1=(_n<<1)-1;
+ for(k=3;k<len;k++){
+ /*U(N,K) = ((2*N-1)*U(N,K-1)-U(N,K-2))/(K-1) + U(N,K-2)*/
+ _u[k]=um2=imusdiv32even(n2m1,um1,um2,k-1)+um2;
+ if(++k>=len)break;
+ _u[k]=um1=imusdiv32odd(n2m1,um2,um1,(k-1)>>1)+um1;
+ }
+ }
+#endif /* SMALL_FOOTPRINT */
+ return _u[_k]+_u[_k+1];
+}
+
+#ifndef SMALL_FOOTPRINT
+
+/*Returns the _i'th combination of _k elements (at most 32767) chosen from a
+ set of size 1 with associated sign bits.
+ _y: Returns the vector of pulses.*/
+static inline void cwrsi1(int _k,opus_uint32 _i,int *_y){
+ int s;
+ s=-(int)_i;
+ _y[0]=(_k+s)^s;
+}
+
+/*Returns the _i'th combination of _k elements (at most 32767) chosen from a
+ set of size 2 with associated sign bits.
+ _y: Returns the vector of pulses.*/
+static inline void cwrsi2(int _k,opus_uint32 _i,int *_y){
+ opus_uint32 p;
+ int s;
+ int yj;
+ p=ucwrs2(_k+1U);
+ s=-(_i>=p);
+ _i-=p&s;
+ yj=_k;
+ _k=(_i+1)>>1;
+ p=_k?ucwrs2(_k):0;
+ _i-=p;
+ yj-=_k;
+ _y[0]=(yj+s)^s;
+ cwrsi1(_k,_i,_y+1);
+}
+
+/*Returns the _i'th combination of _k elements (at most 32767) chosen from a
+ set of size 3 with associated sign bits.
+ _y: Returns the vector of pulses.*/
+static void cwrsi3(int _k,opus_uint32 _i,int *_y){
+ opus_uint32 p;
+ int s;
+ int yj;
+ p=ucwrs3(_k+1U);
+ s=-(_i>=p);
+ _i-=p&s;
+ yj=_k;
+ /*Finds the maximum _k such that ucwrs3(_k)<=_i (tested for all
+ _i<2147418113=U(3,32768)).*/
+ _k=_i>0?(isqrt32(2*_i-1)+1)>>1:0;
+ p=_k?ucwrs3(_k):0;
+ _i-=p;
+ yj-=_k;
+ _y[0]=(yj+s)^s;
+ cwrsi2(_k,_i,_y+1);
+}
+
+/*Returns the _i'th combination of _k elements (at most 1172) chosen from a set
+ of size 4 with associated sign bits.
+ _y: Returns the vector of pulses.*/
+static void cwrsi4(int _k,opus_uint32 _i,int *_y){
+ opus_uint32 p;
+ int s;
+ int yj;
+ int kl;
+ int kr;
+ p=ucwrs4(_k+1);
+ s=-(_i>=p);
+ _i-=p&s;
+ yj=_k;
+ /*We could solve a cubic for k here, but the form of the direct solution does
+ not lend itself well to exact integer arithmetic.
+ Instead we do a binary search on U(4,K).*/
+ kl=0;
+ kr=_k;
+ for(;;){
+ _k=(kl+kr)>>1;
+ p=_k?ucwrs4(_k):0;
+ if(p<_i){
+ if(_k>=kr)break;
+ kl=_k+1;
+ }
+ else if(p>_i)kr=_k-1;
+ else break;
+ }
+ _i-=p;
+ yj-=_k;
+ _y[0]=(yj+s)^s;
+ cwrsi3(_k,_i,_y+1);
+}
+
+#endif /* SMALL_FOOTPRINT */
+
+/*Returns the _i'th combination of _k elements chosen from a set of size _n
+ with associated sign bits.
+ _y: Returns the vector of pulses.
+ _u: Must contain entries [0..._k+1] of row _n of U() on input.
+ Its contents will be destructively modified.*/
+static void cwrsi(int _n,int _k,opus_uint32 _i,int *_y,opus_uint32 *_u){
+ int j;
+ celt_assert(_n>0);
+ j=0;
+ do{
+ opus_uint32 p;
+ int s;
+ int yj;
+ p=_u[_k+1];
+ s=-(_i>=p);
+ _i-=p&s;
+ yj=_k;
+ p=_u[_k];
+ while(p>_i)p=_u[--_k];
+ _i-=p;
+ yj-=_k;
+ _y[j]=(yj+s)^s;
+ uprev(_u,_k+2,0);
+ }
+ while(++j<_n);
+}
+
+/*Returns the index of the given combination of K elements chosen from a set
+ of size 1 with associated sign bits.
+ _y: The vector of pulses, whose sum of absolute values is K.
+ _k: Returns K.*/
+static inline opus_uint32 icwrs1(const int *_y,int *_k){
+ *_k=abs(_y[0]);
+ return _y[0]<0;
+}
+
+#ifndef SMALL_FOOTPRINT
+
+/*Returns the index of the given combination of K elements chosen from a set
+ of size 2 with associated sign bits.
+ _y: The vector of pulses, whose sum of absolute values is K.
+ _k: Returns K.*/
+static inline opus_uint32 icwrs2(const int *_y,int *_k){
+ opus_uint32 i;
+ int k;
+ i=icwrs1(_y+1,&k);
+ i+=k?ucwrs2(k):0;
+ k+=abs(_y[0]);
+ if(_y[0]<0)i+=ucwrs2(k+1U);
+ *_k=k;
+ return i;
+}
+
+/*Returns the index of the given combination of K elements chosen from a set
+ of size 3 with associated sign bits.
+ _y: The vector of pulses, whose sum of absolute values is K.
+ _k: Returns K.*/
+static inline opus_uint32 icwrs3(const int *_y,int *_k){
+ opus_uint32 i;
+ int k;
+ i=icwrs2(_y+1,&k);
+ i+=k?ucwrs3(k):0;
+ k+=abs(_y[0]);
+ if(_y[0]<0)i+=ucwrs3(k+1U);
+ *_k=k;
+ return i;
+}
+
+/*Returns the index of the given combination of K elements chosen from a set
+ of size 4 with associated sign bits.
+ _y: The vector of pulses, whose sum of absolute values is K.
+ _k: Returns K.*/
+static inline opus_uint32 icwrs4(const int *_y,int *_k){
+ opus_uint32 i;
+ int k;
+ i=icwrs3(_y+1,&k);
+ i+=k?ucwrs4(k):0;
+ k+=abs(_y[0]);
+ if(_y[0]<0)i+=ucwrs4(k+1);
+ *_k=k;
+ return i;
+}
+
+#endif /* SMALL_FOOTPRINT */
+
+/*Returns the index of the given combination of K elements chosen from a set
+ of size _n with associated sign bits.
+ _y: The vector of pulses, whose sum of absolute values must be _k.
+ _nc: Returns V(_n,_k).*/
+static inline opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y,
+ opus_uint32 *_u){
+ opus_uint32 i;
+ int j;
+ int k;
+ /*We can't unroll the first two iterations of the loop unless _n>=2.*/
+ celt_assert(_n>=2);
+ _u[0]=0;
+ for(k=1;k<=_k+1;k++)_u[k]=(k<<1)-1;
+ i=icwrs1(_y+_n-1,&k);
+ j=_n-2;
+ i+=_u[k];
+ k+=abs(_y[j]);
+ if(_y[j]<0)i+=_u[k+1];
+ while(j-->0){
+ unext(_u,_k+2,0);
+ i+=_u[k];
+ k+=abs(_y[j]);
+ if(_y[j]<0)i+=_u[k+1];
+ }
+ *_nc=_u[k]+_u[k+1];
+ return i;
+}
+
+#ifdef CUSTOM_MODES
+void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){
+ int k;
+ /*_maxk==0 => there's nothing to do.*/
+ celt_assert(_maxk>0);
+ _bits[0]=0;
+ if (_n==1)
+ {
+ for (k=1;k<=_maxk;k++)
+ _bits[k] = 1<<_frac;
+ }
+ else {
+ VARDECL(opus_uint32,u);
+ SAVE_STACK;
+ ALLOC(u,_maxk+2U,opus_uint32);
+ ncwrs_urow(_n,_maxk,u);
+ for(k=1;k<=_maxk;k++)
+ _bits[k]=log2_frac(u[k]+u[k+1],_frac);
+ RESTORE_STACK;
+ }
+}
+#endif /* CUSTOM_MODES */
+
+void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){
+ opus_uint32 i;
+ celt_assert(_k>0);
+#ifndef SMALL_FOOTPRINT
+ switch(_n){
+ case 2:{
+ i=icwrs2(_y,&_k);
+ ec_enc_uint(_enc,i,ncwrs2(_k));
+ }break;
+ case 3:{
+ i=icwrs3(_y,&_k);
+ ec_enc_uint(_enc,i,ncwrs3(_k));
+ }break;
+ case 4:{
+ i=icwrs4(_y,&_k);
+ ec_enc_uint(_enc,i,ncwrs4(_k));
+ }break;
+ default:
+ {
+#endif
+ VARDECL(opus_uint32,u);
+ opus_uint32 nc;
+ SAVE_STACK;
+ ALLOC(u,_k+2U,opus_uint32);
+ i=icwrs(_n,_k,&nc,_y,u);
+ ec_enc_uint(_enc,i,nc);
+ RESTORE_STACK;
+#ifndef SMALL_FOOTPRINT
+ }
+ break;
+ }
+#endif
+}
+
+void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec)
+{
+ celt_assert(_k>0);
+#ifndef SMALL_FOOTPRINT
+ switch(_n){
+ case 2:cwrsi2(_k,ec_dec_uint(_dec,ncwrs2(_k)),_y);break;
+ case 3:cwrsi3(_k,ec_dec_uint(_dec,ncwrs3(_k)),_y);break;
+ case 4:cwrsi4(_k,ec_dec_uint(_dec,ncwrs4(_k)),_y);break;
+ default:
+ {
+#endif
+ VARDECL(opus_uint32,u);
+ SAVE_STACK;
+ ALLOC(u,_k+2U,opus_uint32);
+ cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u);
+ RESTORE_STACK;
+#ifndef SMALL_FOOTPRINT
+ }
+ break;
+ }
+#endif
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/cwrs.h b/lib/rbcodec/codecs/libopus/celt/cwrs.h
new file mode 100644
index 0000000000..7dfbd076d1
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/cwrs.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2007-2009 Timothy B. Terriberry
+ Written by Timothy B. Terriberry and 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.
+
+ 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 COPYRIGHT OWNER
+ 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 CWRS_H
+#define CWRS_H
+
+#include "arch.h"
+#include "stack_alloc.h"
+#include "entenc.h"
+#include "entdec.h"
+
+#ifdef CUSTOM_MODES
+int log2_frac(opus_uint32 val, int frac);
+#endif
+
+void get_required_bits(opus_int16 *bits, int N, int K, int frac);
+
+void encode_pulses(const int *_y, int N, int K, ec_enc *enc);
+
+void decode_pulses(int *_y, int N, int K, ec_dec *dec);
+
+#endif /* CWRS_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/ecintrin.h b/lib/rbcodec/codecs/libopus/celt/ecintrin.h
new file mode 100644
index 0000000000..3dffa5f95c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/ecintrin.h
@@ -0,0 +1,87 @@
+/* Copyright (c) 2003-2008 Timothy B. Terriberry
+ Copyright (c) 2008 Xiph.Org Foundation */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+/*Some common macros for potential platform-specific optimization.*/
+#include "opus_types.h"
+#include <math.h>
+#include <limits.h>
+#include "arch.h"
+#if !defined(_ecintrin_H)
+# define _ecintrin_H (1)
+
+/*Some specific platforms may have optimized intrinsic or inline assembly
+ versions of these functions which can substantially improve performance.
+ We define macros for them to allow easy incorporation of these non-ANSI
+ features.*/
+
+/*Modern gcc (4.x) can compile the naive versions of min and max with cmov if
+ given an appropriate architecture, but the branchless bit-twiddling versions
+ are just as fast, and do not require any special target architecture.
+ Earlier gcc versions (3.x) compiled both code to the same assembly
+ instructions, because of the way they represented ((_b)>(_a)) internally.*/
+# define EC_MINI(_a,_b) ((_a)+(((_b)-(_a))&-((_b)<(_a))))
+
+/*Count leading zeros.
+ This macro should only be used for implementing ec_ilog(), if it is defined.
+ All other code should use EC_ILOG() instead.*/
+#if defined(_MSC_VER)
+# include <intrin.h>
+/*In _DEBUG mode this is not an intrinsic by default.*/
+# pragma intrinsic(_BitScanReverse)
+
+static __inline int ec_bsr(unsigned long _x){
+ unsigned long ret;
+ _BitScanReverse(&ret,_x);
+ return (int)ret;
+}
+# define EC_CLZ0 (1)
+# define EC_CLZ(_x) (-ec_bsr(_x))
+#elif defined(ENABLE_TI_DSPLIB)
+# include "dsplib.h"
+# define EC_CLZ0 (31)
+# define EC_CLZ(_x) (_lnorm(_x))
+#elif __GNUC_PREREQ(3,4)
+# if INT_MAX>=2147483647
+# define EC_CLZ0 ((int)sizeof(unsigned)*CHAR_BIT)
+# define EC_CLZ(_x) (__builtin_clz(_x))
+# elif LONG_MAX>=2147483647L
+# define EC_CLZ0 ((int)sizeof(unsigned long)*CHAR_BIT)
+# define EC_CLZ(_x) (__builtin_clzl(_x))
+# endif
+#endif
+
+#if defined(EC_CLZ)
+/*Note that __builtin_clz is not defined when _x==0, according to the gcc
+ documentation (and that of the BSR instruction that implements it on x86).
+ The majority of the time we can never pass it zero.
+ When we need to, it can be special cased.*/
+# define EC_ILOG(_x) (EC_CLZ0-EC_CLZ(_x))
+#else
+int ec_ilog(opus_uint32 _v);
+# define EC_ILOG(_x) (ec_ilog(_x))
+#endif
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/entcode.c b/lib/rbcodec/codecs/libopus/celt/entcode.c
new file mode 100644
index 0000000000..80e64fefaa
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/entcode.c
@@ -0,0 +1,88 @@
+/* Copyright (c) 2001-2011 Timothy B. Terriberry
+*/
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include "entcode.h"
+#include "arch.h"
+
+#if !defined(EC_CLZ)
+int ec_ilog(opus_uint32 _v){
+ /*On a Pentium M, this branchless version tested as the fastest on
+ 1,000,000,000 random 32-bit integers, edging out a similar version with
+ branches, and a 256-entry LUT version.*/
+ int ret;
+ int m;
+ ret=!!_v;
+ m=!!(_v&0xFFFF0000)<<4;
+ _v>>=m;
+ ret|=m;
+ m=!!(_v&0xFF00)<<3;
+ _v>>=m;
+ ret|=m;
+ m=!!(_v&0xF0)<<2;
+ _v>>=m;
+ ret|=m;
+ m=!!(_v&0xC)<<1;
+ _v>>=m;
+ ret|=m;
+ ret+=!!(_v&0x2);
+ return ret;
+}
+#endif
+
+opus_uint32 ec_tell_frac(ec_ctx *_this){
+ opus_uint32 nbits;
+ opus_uint32 r;
+ int l;
+ int i;
+ /*To handle the non-integral number of bits still left in the encoder/decoder
+ state, we compute the worst-case number of bits of val that must be
+ encoded to ensure that the value is inside the range for any possible
+ subsequent bits.
+ The computation here is independent of val itself (the decoder does not
+ even track that value), even though the real number of bits used after
+ ec_enc_done() may be 1 smaller if rng is a power of two and the
+ corresponding trailing bits of val are all zeros.
+ If we did try to track that special case, then coding a value with a
+ probability of 1/(1<<n) might sometimes appear to use more than n bits.
+ This may help explain the surprising result that a newly initialized
+ encoder or decoder claims to have used 1 bit.*/
+ nbits=_this->nbits_total<<BITRES;
+ l=EC_ILOG(_this->rng);
+ r=_this->rng>>(l-16);
+ for(i=BITRES;i-->0;){
+ int b;
+ r=r*r>>15;
+ b=(int)(r>>16);
+ l=l<<1|b;
+ r>>=b;
+ }
+ return nbits-l;
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/entcode.h b/lib/rbcodec/codecs/libopus/celt/entcode.h
new file mode 100644
index 0000000000..aebecc0647
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/entcode.h
@@ -0,0 +1,116 @@
+/* Copyright (c) 2001-2011 Timothy B. Terriberry
+ Copyright (c) 2008-2009 Xiph.Org Foundation */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+#include "opus_types.h"
+
+#if !defined(_entcode_H)
+# define _entcode_H (1)
+# include <limits.h>
+# include <stddef.h>
+# include "ecintrin.h"
+
+/*OPT: ec_window must be at least 32 bits, but if you have fast arithmetic on a
+ larger type, you can speed up the decoder by using it here.*/
+typedef opus_uint32 ec_window;
+typedef struct ec_ctx ec_ctx;
+typedef struct ec_ctx ec_enc;
+typedef struct ec_ctx ec_dec;
+
+# define EC_WINDOW_SIZE ((int)sizeof(ec_window)*CHAR_BIT)
+
+/*The number of bits to use for the range-coded part of unsigned integers.*/
+# define EC_UINT_BITS (8)
+
+/*The resolution of fractional-precision bit usage measurements, i.e.,
+ 3 => 1/8th bits.*/
+# define BITRES 3
+
+/*The entropy encoder/decoder context.
+ We use the same structure for both, so that common functions like ec_tell()
+ can be used on either one.*/
+struct ec_ctx{
+ /*Buffered input/output.*/
+ unsigned char *buf;
+ /*The size of the buffer.*/
+ opus_uint32 storage;
+ /*The offset at which the last byte containing raw bits was read/written.*/
+ opus_uint32 end_offs;
+ /*Bits that will be read from/written at the end.*/
+ ec_window end_window;
+ /*Number of valid bits in end_window.*/
+ int nend_bits;
+ /*The total number of whole bits read/written.
+ This does not include partial bits currently in the range coder.*/
+ int nbits_total;
+ /*The offset at which the next range coder byte will be read/written.*/
+ opus_uint32 offs;
+ /*The number of values in the current range.*/
+ opus_uint32 rng;
+ /*In the decoder: the difference between the top of the current range and
+ the input value, minus one.
+ In the encoder: the low end of the current range.*/
+ opus_uint32 val;
+ /*In the decoder: the saved normalization factor from ec_decode().
+ In the encoder: the number of oustanding carry propagating symbols.*/
+ opus_uint32 ext;
+ /*A buffered input/output symbol, awaiting carry propagation.*/
+ int rem;
+ /*Nonzero if an error occurred.*/
+ int error;
+};
+
+static inline opus_uint32 ec_range_bytes(ec_ctx *_this){
+ return _this->offs;
+}
+
+static inline unsigned char *ec_get_buffer(ec_ctx *_this){
+ return _this->buf;
+}
+
+static inline int ec_get_error(ec_ctx *_this){
+ return _this->error;
+}
+
+/*Returns the number of bits "used" by the encoded or decoded symbols so far.
+ This same number can be computed in either the encoder or the decoder, and is
+ suitable for making coding decisions.
+ Return: The number of bits.
+ This will always be slightly larger than the exact value (e.g., all
+ rounding error is in the positive direction).*/
+static inline int ec_tell(ec_ctx *_this){
+ return _this->nbits_total-EC_ILOG(_this->rng);
+}
+
+/*Returns the number of bits "used" by the encoded or decoded symbols so far.
+ This same number can be computed in either the encoder or the decoder, and is
+ suitable for making coding decisions.
+ Return: The number of bits scaled by 2**BITRES.
+ This will always be slightly larger than the exact value (e.g., all
+ rounding error is in the positive direction).*/
+opus_uint32 ec_tell_frac(ec_ctx *_this);
+
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/entdec.c b/lib/rbcodec/codecs/libopus/celt/entdec.c
new file mode 100644
index 0000000000..ff8442d534
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/entdec.c
@@ -0,0 +1,245 @@
+/* Copyright (c) 2001-2011 Timothy B. Terriberry
+ Copyright (c) 2008-2009 Xiph.Org Foundation */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include <stddef.h>
+#include "os_support.h"
+#include "arch.h"
+#include "entdec.h"
+#include "mfrngcod.h"
+
+/*A range decoder.
+ This is an entropy decoder based upon \cite{Mar79}, which is itself a
+ rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}.
+ It is very similar to arithmetic encoding, except that encoding is done with
+ digits in any base, instead of with bits, and so it is faster when using
+ larger bases (i.e.: a byte).
+ The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$
+ is the base, longer than the theoretical optimum, but to my knowledge there
+ is no published justification for this claim.
+ This only seems true when using near-infinite precision arithmetic so that
+ the process is carried out with no rounding errors.
+
+ An excellent description of implementation details is available at
+ http://www.arturocampos.com/ac_range.html
+ A recent work \cite{MNW98} which proposes several changes to arithmetic
+ encoding for efficiency actually re-discovers many of the principles
+ behind range encoding, and presents a good theoretical analysis of them.
+
+ End of stream is handled by writing out the smallest number of bits that
+ ensures that the stream will be correctly decoded regardless of the value of
+ any subsequent bits.
+ ec_tell() can be used to determine how many bits were needed to decode
+ all the symbols thus far; other data can be packed in the remaining bits of
+ the input buffer.
+ @PHDTHESIS{Pas76,
+ author="Richard Clark Pasco",
+ title="Source coding algorithms for fast data compression",
+ school="Dept. of Electrical Engineering, Stanford University",
+ address="Stanford, CA",
+ month=May,
+ year=1976
+ }
+ @INPROCEEDINGS{Mar79,
+ author="Martin, G.N.N.",
+ title="Range encoding: an algorithm for removing redundancy from a digitised
+ message",
+ booktitle="Video & Data Recording Conference",
+ year=1979,
+ address="Southampton",
+ month=Jul
+ }
+ @ARTICLE{MNW98,
+ author="Alistair Moffat and Radford Neal and Ian H. Witten",
+ title="Arithmetic Coding Revisited",
+ journal="{ACM} Transactions on Information Systems",
+ year=1998,
+ volume=16,
+ number=3,
+ pages="256--294",
+ month=Jul,
+ URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
+ }*/
+
+static int ec_read_byte(ec_dec *_this){
+ return _this->offs<_this->storage?_this->buf[_this->offs++]:0;
+}
+
+static int ec_read_byte_from_end(ec_dec *_this){
+ return _this->end_offs<_this->storage?
+ _this->buf[_this->storage-++(_this->end_offs)]:0;
+}
+
+/*Normalizes the contents of val and rng so that rng lies entirely in the
+ high-order symbol.*/
+static void ec_dec_normalize(ec_dec *_this){
+ /*If the range is too small, rescale it and input some bits.*/
+ while(_this->rng<=EC_CODE_BOT){
+ int sym;
+ _this->nbits_total+=EC_SYM_BITS;
+ _this->rng<<=EC_SYM_BITS;
+ /*Use up the remaining bits from our last symbol.*/
+ sym=_this->rem;
+ /*Read the next value from the input.*/
+ _this->rem=ec_read_byte(_this);
+ /*Take the rest of the bits we need from this new symbol.*/
+ sym=(sym<<EC_SYM_BITS|_this->rem)>>(EC_SYM_BITS-EC_CODE_EXTRA);
+ /*And subtract them from val, capped to be less than EC_CODE_TOP.*/
+ _this->val=((_this->val<<EC_SYM_BITS)+(EC_SYM_MAX&~sym))&(EC_CODE_TOP-1);
+ }
+}
+
+void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage){
+ _this->buf=_buf;
+ _this->storage=_storage;
+ _this->end_offs=0;
+ _this->end_window=0;
+ _this->nend_bits=0;
+ /*This is the offset from which ec_tell() will subtract partial bits.
+ The final value after the ec_dec_normalize() call will be the same as in
+ the encoder, but we have to compensate for the bits that are added there.*/
+ _this->nbits_total=EC_CODE_BITS+1
+ -((EC_CODE_BITS-EC_CODE_EXTRA)/EC_SYM_BITS)*EC_SYM_BITS;
+ _this->offs=0;
+ _this->rng=1U<<EC_CODE_EXTRA;
+ _this->rem=ec_read_byte(_this);
+ _this->val=_this->rng-1-(_this->rem>>(EC_SYM_BITS-EC_CODE_EXTRA));
+ _this->error=0;
+ /*Normalize the interval.*/
+ ec_dec_normalize(_this);
+}
+
+unsigned ec_decode(ec_dec *_this,unsigned _ft){
+ unsigned s;
+ _this->ext=_this->rng/_ft;
+ s=(unsigned)(_this->val/_this->ext);
+ return _ft-EC_MINI(s+1,_ft);
+}
+
+unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){
+ unsigned s;
+ _this->ext=_this->rng>>_bits;
+ s=(unsigned)(_this->val/_this->ext);
+ return (1U<<_bits)-EC_MINI(s+1U,1U<<_bits);
+}
+
+void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
+ opus_uint32 s;
+ s=IMUL32(_this->ext,_ft-_fh);
+ _this->val-=s;
+ _this->rng=_fl>0?IMUL32(_this->ext,_fh-_fl):_this->rng-s;
+ ec_dec_normalize(_this);
+}
+
+/*The probability of having a "one" is 1/(1<<_logp).*/
+int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){
+ opus_uint32 r;
+ opus_uint32 d;
+ opus_uint32 s;
+ int ret;
+ r=_this->rng;
+ d=_this->val;
+ s=r>>_logp;
+ ret=d<s;
+ if(!ret)_this->val=d-s;
+ _this->rng=ret?s:r-s;
+ ec_dec_normalize(_this);
+ return ret;
+}
+
+int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){
+ opus_uint32 r;
+ opus_uint32 d;
+ opus_uint32 s;
+ opus_uint32 t;
+ int ret;
+ s=_this->rng;
+ d=_this->val;
+ r=s>>_ftb;
+ ret=-1;
+ do{
+ t=s;
+ s=IMUL32(r,_icdf[++ret]);
+ }
+ while(d<s);
+ _this->val=d-s;
+ _this->rng=t-s;
+ ec_dec_normalize(_this);
+ return ret;
+}
+
+opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft){
+ unsigned ft;
+ unsigned s;
+ int ftb;
+ /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
+ celt_assert(_ft>1);
+ _ft--;
+ ftb=EC_ILOG(_ft);
+ if(ftb>EC_UINT_BITS){
+ opus_uint32 t;
+ ftb-=EC_UINT_BITS;
+ ft=(unsigned)(_ft>>ftb)+1;
+ s=ec_decode(_this,ft);
+ ec_dec_update(_this,s,s+1,ft);
+ t=(opus_uint32)s<<ftb|ec_dec_bits(_this,ftb);
+ if(t<=_ft)return t;
+ _this->error=1;
+ return _ft;
+ }
+ else{
+ _ft++;
+ s=ec_decode(_this,(unsigned)_ft);
+ ec_dec_update(_this,s,s+1,(unsigned)_ft);
+ return s;
+ }
+}
+
+opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _bits){
+ ec_window window;
+ int available;
+ opus_uint32 ret;
+ window=_this->end_window;
+ available=_this->nend_bits;
+ if((unsigned)available<_bits){
+ do{
+ window|=(ec_window)ec_read_byte_from_end(_this)<<available;
+ available+=EC_SYM_BITS;
+ }
+ while(available<=EC_WINDOW_SIZE-EC_SYM_BITS);
+ }
+ ret=(opus_uint32)window&(((opus_uint32)1<<_bits)-1U);
+ window>>=_bits;
+ available-=_bits;
+ _this->end_window=window;
+ _this->nend_bits=available;
+ _this->nbits_total+=_bits;
+ return ret;
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/entdec.h b/lib/rbcodec/codecs/libopus/celt/entdec.h
new file mode 100644
index 0000000000..d8ab318730
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/entdec.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2001-2011 Timothy B. Terriberry
+ Copyright (c) 2008-2009 Xiph.Org Foundation */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+#if !defined(_entdec_H)
+# define _entdec_H (1)
+# include <limits.h>
+# include "entcode.h"
+
+/*Initializes the decoder.
+ _buf: The input buffer to use.
+ Return: 0 on success, or a negative value on error.*/
+void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage);
+
+/*Calculates the cumulative frequency for the next symbol.
+ This can then be fed into the probability model to determine what that
+ symbol is, and the additional frequency information required to advance to
+ the next symbol.
+ This function cannot be called more than once without a corresponding call to
+ ec_dec_update(), or decoding will not proceed correctly.
+ _ft: The total frequency of the symbols in the alphabet the next symbol was
+ encoded with.
+ Return: A cumulative frequency representing the encoded symbol.
+ If the cumulative frequency of all the symbols before the one that
+ was encoded was fl, and the cumulative frequency of all the symbols
+ up to and including the one encoded is fh, then the returned value
+ will fall in the range [fl,fh).*/
+unsigned ec_decode(ec_dec *_this,unsigned _ft);
+
+/*Equivalent to ec_decode() with _ft==1<<_bits.*/
+unsigned ec_decode_bin(ec_dec *_this,unsigned _bits);
+
+/*Advance the decoder past the next symbol using the frequency information the
+ symbol was encoded with.
+ Exactly one call to ec_decode() must have been made so that all necessary
+ intermediate calculations are performed.
+ _fl: The cumulative frequency of all symbols that come before the symbol
+ decoded.
+ _fh: The cumulative frequency of all symbols up to and including the symbol
+ decoded.
+ Together with _fl, this defines the range [_fl,_fh) in which the value
+ returned above must fall.
+ _ft: The total frequency of the symbols in the alphabet the symbol decoded
+ was encoded in.
+ This must be the same as passed to the preceding call to ec_decode().*/
+void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft);
+
+/* Decode a bit that has a 1/(1<<_logp) probability of being a one */
+int ec_dec_bit_logp(ec_dec *_this,unsigned _logp);
+
+/*Decodes a symbol given an "inverse" CDF table.
+ No call to ec_dec_update() is necessary after this call.
+ _icdf: The "inverse" CDF, such that symbol s falls in the range
+ [s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb.
+ The values must be monotonically non-increasing, and the last value
+ must be 0.
+ _ftb: The number of bits of precision in the cumulative distribution.
+ Return: The decoded symbol s.*/
+int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb);
+
+/*Extracts a raw unsigned integer with a non-power-of-2 range from the stream.
+ The bits must have been encoded with ec_enc_uint().
+ No call to ec_dec_update() is necessary after this call.
+ _ft: The number of integers that can be decoded (one more than the max).
+ This must be at least one, and no more than 2**32-1.
+ Return: The decoded bits.*/
+opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft);
+
+/*Extracts a sequence of raw bits from the stream.
+ The bits must have been encoded with ec_enc_bits().
+ No call to ec_dec_update() is necessary after this call.
+ _ftb: The number of bits to extract.
+ This must be between 0 and 25, inclusive.
+ Return: The decoded bits.*/
+opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb);
+
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/entenc.c b/lib/rbcodec/codecs/libopus/celt/entenc.c
new file mode 100644
index 0000000000..0ec6e91fd7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/entenc.c
@@ -0,0 +1,294 @@
+/* Copyright (c) 2001-2011 Timothy B. Terriberry
+ Copyright (c) 2008-2009 Xiph.Org Foundation */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+#if defined(HAVE_CONFIG_H)
+# include "opus_config.h"
+#endif
+#include "os_support.h"
+#include "arch.h"
+#include "entenc.h"
+#include "mfrngcod.h"
+
+/*A range encoder.
+ See entdec.c and the references for implementation details \cite{Mar79,MNW98}.
+
+ @INPROCEEDINGS{Mar79,
+ author="Martin, G.N.N.",
+ title="Range encoding: an algorithm for removing redundancy from a digitised
+ message",
+ booktitle="Video \& Data Recording Conference",
+ year=1979,
+ address="Southampton",
+ month=Jul
+ }
+ @ARTICLE{MNW98,
+ author="Alistair Moffat and Radford Neal and Ian H. Witten",
+ title="Arithmetic Coding Revisited",
+ journal="{ACM} Transactions on Information Systems",
+ year=1998,
+ volume=16,
+ number=3,
+ pages="256--294",
+ month=Jul,
+ URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
+ }*/
+
+static int ec_write_byte(ec_enc *_this,unsigned _value){
+ if(_this->offs+_this->end_offs>=_this->storage)return -1;
+ _this->buf[_this->offs++]=(unsigned char)_value;
+ return 0;
+}
+
+static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){
+ if(_this->offs+_this->end_offs>=_this->storage)return -1;
+ _this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value;
+ return 0;
+}
+
+/*Outputs a symbol, with a carry bit.
+ If there is a potential to propagate a carry over several symbols, they are
+ buffered until it can be determined whether or not an actual carry will
+ occur.
+ If the counter for the buffered symbols overflows, then the stream becomes
+ undecodable.
+ This gives a theoretical limit of a few billion symbols in a single packet on
+ 32-bit systems.
+ The alternative is to truncate the range in order to force a carry, but
+ requires similar carry tracking in the decoder, needlessly slowing it down.*/
+static void ec_enc_carry_out(ec_enc *_this,int _c){
+ if(_c!=EC_SYM_MAX){
+ /*No further carry propagation possible, flush buffer.*/
+ int carry;
+ carry=_c>>EC_SYM_BITS;
+ /*Don't output a byte on the first write.
+ This compare should be taken care of by branch-prediction thereafter.*/
+ if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry);
+ if(_this->ext>0){
+ unsigned sym;
+ sym=(EC_SYM_MAX+carry)&EC_SYM_MAX;
+ do _this->error|=ec_write_byte(_this,sym);
+ while(--(_this->ext)>0);
+ }
+ _this->rem=_c&EC_SYM_MAX;
+ }
+ else _this->ext++;
+}
+
+static void ec_enc_normalize(ec_enc *_this){
+ /*If the range is too small, output some bits and rescale it.*/
+ while(_this->rng<=EC_CODE_BOT){
+ ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT));
+ /*Move the next-to-high-order symbol into the high-order position.*/
+ _this->val=(_this->val<<EC_SYM_BITS)&(EC_CODE_TOP-1);
+ _this->rng<<=EC_SYM_BITS;
+ _this->nbits_total+=EC_SYM_BITS;
+ }
+}
+
+void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){
+ _this->buf=_buf;
+ _this->end_offs=0;
+ _this->end_window=0;
+ _this->nend_bits=0;
+ /*This is the offset from which ec_tell() will subtract partial bits.*/
+ _this->nbits_total=EC_CODE_BITS+1;
+ _this->offs=0;
+ _this->rng=EC_CODE_TOP;
+ _this->rem=-1;
+ _this->val=0;
+ _this->ext=0;
+ _this->storage=_size;
+ _this->error=0;
+}
+
+void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
+ opus_uint32 r;
+ r=_this->rng/_ft;
+ if(_fl>0){
+ _this->val+=_this->rng-IMUL32(r,(_ft-_fl));
+ _this->rng=IMUL32(r,(_fh-_fl));
+ }
+ else _this->rng-=IMUL32(r,(_ft-_fh));
+ ec_enc_normalize(_this);
+}
+
+void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){
+ opus_uint32 r;
+ r=_this->rng>>_bits;
+ if(_fl>0){
+ _this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl));
+ _this->rng=IMUL32(r,(_fh-_fl));
+ }
+ else _this->rng-=IMUL32(r,((1U<<_bits)-_fh));
+ ec_enc_normalize(_this);
+}
+
+/*The probability of having a "one" is 1/(1<<_logp).*/
+void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
+ opus_uint32 r;
+ opus_uint32 s;
+ opus_uint32 l;
+ r=_this->rng;
+ l=_this->val;
+ s=r>>_logp;
+ r-=s;
+ if(_val)_this->val=l+r;
+ _this->rng=_val?s:r;
+ ec_enc_normalize(_this);
+}
+
+void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){
+ opus_uint32 r;
+ r=_this->rng>>_ftb;
+ if(_s>0){
+ _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]);
+ _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
+ }
+ else _this->rng-=IMUL32(r,_icdf[_s]);
+ ec_enc_normalize(_this);
+}
+
+void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){
+ unsigned ft;
+ unsigned fl;
+ int ftb;
+ /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
+ celt_assert(_ft>1);
+ _ft--;
+ ftb=EC_ILOG(_ft);
+ if(ftb>EC_UINT_BITS){
+ ftb-=EC_UINT_BITS;
+ ft=(_ft>>ftb)+1;
+ fl=(unsigned)(_fl>>ftb);
+ ec_encode(_this,fl,fl+1,ft);
+ ec_enc_bits(_this,_fl&(((opus_uint32)1<<ftb)-1U),ftb);
+ }
+ else ec_encode(_this,_fl,_fl+1,_ft+1);
+}
+
+void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _bits){
+ ec_window window;
+ int used;
+ window=_this->end_window;
+ used=_this->nend_bits;
+ celt_assert(_bits>0);
+ if(used+_bits>EC_WINDOW_SIZE){
+ do{
+ _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
+ window>>=EC_SYM_BITS;
+ used-=EC_SYM_BITS;
+ }
+ while(used>=EC_SYM_BITS);
+ }
+ window|=(ec_window)_fl<<used;
+ used+=_bits;
+ _this->end_window=window;
+ _this->nend_bits=used;
+ _this->nbits_total+=_bits;
+}
+
+void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){
+ int shift;
+ unsigned mask;
+ celt_assert(_nbits<=EC_SYM_BITS);
+ shift=EC_SYM_BITS-_nbits;
+ mask=((1<<_nbits)-1)<<shift;
+ if(_this->offs>0){
+ /*The first byte has been finalized.*/
+ _this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<<shift);
+ }
+ else if(_this->rem>=0){
+ /*The first byte is still awaiting carry propagation.*/
+ _this->rem=(_this->rem&~mask)|_val<<shift;
+ }
+ else if(_this->rng<=(EC_CODE_TOP>>_nbits)){
+ /*The renormalization loop has never been run.*/
+ _this->val=(_this->val&~((opus_uint32)mask<<EC_CODE_SHIFT))|
+ (opus_uint32)_val<<(EC_CODE_SHIFT+shift);
+ }
+ /*The encoder hasn't even encoded _nbits of data yet.*/
+ else _this->error=-1;
+}
+
+void ec_enc_shrink(ec_enc *_this,opus_uint32 _size){
+ celt_assert(_this->offs+_this->end_offs<=_size);
+ OPUS_MOVE(_this->buf+_size-_this->end_offs,
+ _this->buf+_this->storage-_this->end_offs,_this->end_offs);
+ _this->storage=_size;
+}
+
+void ec_enc_done(ec_enc *_this){
+ ec_window window;
+ int used;
+ opus_uint32 msk;
+ opus_uint32 end;
+ int l;
+ /*We output the minimum number of bits that ensures that the symbols encoded
+ thus far will be decoded correctly regardless of the bits that follow.*/
+ l=EC_CODE_BITS-EC_ILOG(_this->rng);
+ msk=(EC_CODE_TOP-1)>>l;
+ end=(_this->val+msk)&~msk;
+ if((end|msk)>=_this->val+_this->rng){
+ l++;
+ msk>>=1;
+ end=(_this->val+msk)&~msk;
+ }
+ while(l>0){
+ ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT));
+ end=(end<<EC_SYM_BITS)&(EC_CODE_TOP-1);
+ l-=EC_SYM_BITS;
+ }
+ /*If we have a buffered byte flush it into the output buffer.*/
+ if(_this->rem>=0||_this->ext>0)ec_enc_carry_out(_this,0);
+ /*If we have buffered extra bits, flush them as well.*/
+ window=_this->end_window;
+ used=_this->nend_bits;
+ while(used>=EC_SYM_BITS){
+ _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
+ window>>=EC_SYM_BITS;
+ used-=EC_SYM_BITS;
+ }
+ /*Clear any excess space and add any remaining extra bits to the last byte.*/
+ if(!_this->error){
+ OPUS_CLEAR(_this->buf+_this->offs,
+ _this->storage-_this->offs-_this->end_offs);
+ if(used>0){
+ /*If there's no range coder data at all, give up.*/
+ if(_this->end_offs>=_this->storage)_this->error=-1;
+ else{
+ l=-l;
+ /*If we've busted, don't add too many extra bits to the last byte; it
+ would corrupt the range coder data, and that's more important.*/
+ if(_this->offs+_this->end_offs>=_this->storage&&l<used){
+ window&=(1<<l)-1;
+ _this->error=-1;
+ }
+ _this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window;
+ }
+ }
+ }
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/entenc.h b/lib/rbcodec/codecs/libopus/celt/entenc.h
new file mode 100644
index 0000000000..796bc4d572
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/entenc.h
@@ -0,0 +1,110 @@
+/* Copyright (c) 2001-2011 Timothy B. Terriberry
+ Copyright (c) 2008-2009 Xiph.Org Foundation */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+#if !defined(_entenc_H)
+# define _entenc_H (1)
+# include <stddef.h>
+# include "entcode.h"
+
+/*Initializes the encoder.
+ _buf: The buffer to store output bytes in.
+ _size: The size of the buffer, in chars.*/
+void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size);
+/*Encodes a symbol given its frequency information.
+ The frequency information must be discernable by the decoder, assuming it
+ has read only the previous symbols from the stream.
+ It is allowable to change the frequency information, or even the entire
+ source alphabet, so long as the decoder can tell from the context of the
+ previously encoded information that it is supposed to do so as well.
+ _fl: The cumulative frequency of all symbols that come before the one to be
+ encoded.
+ _fh: The cumulative frequency of all symbols up to and including the one to
+ be encoded.
+ Together with _fl, this defines the range [_fl,_fh) in which the
+ decoded value will fall.
+ _ft: The sum of the frequencies of all the symbols*/
+void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft);
+
+/*Equivalent to ec_encode() with _ft==1<<_bits.*/
+void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits);
+
+/* Encode a bit that has a 1/(1<<_logp) probability of being a one */
+void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp);
+
+/*Encodes a symbol given an "inverse" CDF table.
+ _s: The index of the symbol to encode.
+ _icdf: The "inverse" CDF, such that symbol _s falls in the range
+ [_s>0?ft-_icdf[_s-1]:0,ft-_icdf[_s]), where ft=1<<_ftb.
+ The values must be monotonically non-increasing, and the last value
+ must be 0.
+ _ftb: The number of bits of precision in the cumulative distribution.*/
+void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb);
+
+/*Encodes a raw unsigned integer in the stream.
+ _fl: The integer to encode.
+ _ft: The number of integers that can be encoded (one more than the max).
+ This must be at least one, and no more than 2**32-1.*/
+void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft);
+
+/*Encodes a sequence of raw bits in the stream.
+ _fl: The bits to encode.
+ _ftb: The number of bits to encode.
+ This must be between 1 and 25, inclusive.*/
+void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _ftb);
+
+/*Overwrites a few bits at the very start of an existing stream, after they
+ have already been encoded.
+ This makes it possible to have a few flags up front, where it is easy for
+ decoders to access them without parsing the whole stream, even if their
+ values are not determined until late in the encoding process, without having
+ to buffer all the intermediate symbols in the encoder.
+ In order for this to work, at least _nbits bits must have already been
+ encoded using probabilities that are an exact power of two.
+ The encoder can verify the number of encoded bits is sufficient, but cannot
+ check this latter condition.
+ _val: The bits to encode (in the least _nbits significant bits).
+ They will be decoded in order from most-significant to least.
+ _nbits: The number of bits to overwrite.
+ This must be no more than 8.*/
+void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits);
+
+/*Compacts the data to fit in the target size.
+ This moves up the raw bits at the end of the current buffer so they are at
+ the end of the new buffer size.
+ The caller must ensure that the amount of data that's already been written
+ will fit in the new size.
+ _size: The number of bytes in the new buffer.
+ This must be large enough to contain the bits already written, and
+ must be no larger than the existing size.*/
+void ec_enc_shrink(ec_enc *_this,opus_uint32 _size);
+
+/*Indicates that there are no more symbols to encode.
+ All reamining output bytes are flushed to the output buffer.
+ ec_enc_init() must be called before the encoder can be used again.*/
+void ec_enc_done(ec_enc *_this);
+
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/fixed_generic.h b/lib/rbcodec/codecs/libopus/celt/fixed_generic.h
new file mode 100644
index 0000000000..71e28d62a8
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/fixed_generic.h
@@ -0,0 +1,129 @@
+/* Copyright (C) 2007-2009 Xiph.Org Foundation
+ Copyright (C) 2003-2008 Jean-Marc Valin
+ Copyright (C) 2007-2008 CSIRO */
+/**
+ @file fixed_generic.h
+ @brief Generic fixed-point operations
+*/
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 FIXED_GENERIC_H
+#define FIXED_GENERIC_H
+
+/** Multiply a 16-bit signed value by a 16-bit unsigned value. The result is a 32-bit signed value */
+#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
+
+/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
+#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
+
+/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */
+#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16((a),((b)&0x0000ffff)),16))
+
+/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
+#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))
+
+/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */
+#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15))
+
+/** Compile-time conversion of float constant to 16-bit value */
+#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
+
+/** Compile-time conversion of float constant to 32-bit value */
+#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
+
+/** Negate a 16-bit value */
+#define NEG16(x) (-(x))
+/** Negate a 32-bit value */
+#define NEG32(x) (-(x))
+
+/** Change a 32-bit value into a 16-bit value. The value is assumed to fit in 16-bit, otherwise the result is undefined */
+#define EXTRACT16(x) ((opus_val16)(x))
+/** Change a 16-bit value into a 32-bit value */
+#define EXTEND32(x) ((opus_val32)(x))
+
+/** Arithmetic shift-right of a 16-bit value */
+#define SHR16(a,shift) ((a) >> (shift))
+/** Arithmetic shift-left of a 16-bit value */
+#define SHL16(a,shift) ((opus_int16)((opus_uint16)(a)<<(shift)))
+/** Arithmetic shift-right of a 32-bit value */
+#define SHR32(a,shift) ((a) >> (shift))
+/** Arithmetic shift-left of a 32-bit value */
+#define SHL32(a,shift) ((opus_int32)((opus_uint32)(a)<<(shift)))
+
+/** 32-bit arithmetic shift right with rounding-to-nearest instead of rounding down */
+#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))
+/** 32-bit arithmetic shift right where the argument can be negative */
+#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
+
+/** "RAW" macros, should not be used outside of this header file */
+#define SHR(a,shift) ((a) >> (shift))
+#define SHL(a,shift) SHL32(a,shift)
+#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
+#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+
+/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */
+#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))
+/** Divide by two */
+#define HALF16(x) (SHR16(x,1))
+#define HALF32(x) (SHR32(x,1))
+
+/** Add two 16-bit values */
+#define ADD16(a,b) ((opus_val16)((opus_val16)(a)+(opus_val16)(b)))
+/** Subtract two 16-bit values */
+#define SUB16(a,b) ((opus_val16)(a)-(opus_val16)(b))
+/** Add two 32-bit values */
+#define ADD32(a,b) ((opus_val32)(a)+(opus_val32)(b))
+/** Subtract two 32-bit values */
+#define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b))
+
+/** 16x16 multiplication where the result fits in 16 bits */
+#define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b))))
+
+/* (opus_val32)(opus_val16) gives TI compiler a hint that it's 16x16->32 multiply */
+/** 16x16 multiplication where the result fits in 32 bits */
+#define MULT16_16(a,b) (((opus_val32)(opus_val16)(a))*((opus_val32)(opus_val16)(b)))
+
+/** 16x16 multiply-add where the result fits in 32 bits */
+#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
+/** 16x32 multiply-add, followed by a 15-bit shift right. Results fits in 32 bits */
+#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
+
+#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
+#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
+#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
+#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
+
+#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
+#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
+#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
+
+/** Divide a 32-bit value by a 16-bit value. Result fits in 16 bits */
+#define DIV32_16(a,b) ((opus_val16)(((opus_val32)(a))/((opus_val16)(b))))
+
+/** Divide a 32-bit value by a 32-bit value. Result fits in 32 bits */
+#define DIV32(a,b) (((opus_val32)(a))/((opus_val32)(b)))
+
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/float_cast.h b/lib/rbcodec/codecs/libopus/celt/float_cast.h
new file mode 100644
index 0000000000..5ded291599
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/float_cast.h
@@ -0,0 +1,140 @@
+/* Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com> */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+/* Version 1.1 */
+
+#ifndef FLOAT_CAST_H
+#define FLOAT_CAST_H
+
+
+#include "arch.h"
+
+/*============================================================================
+** On Intel Pentium processors (especially PIII and probably P4), converting
+** from float to int is very slow. To meet the C specs, the code produced by
+** most C compilers targeting Pentium needs to change the FPU rounding mode
+** before the float to int conversion is performed.
+**
+** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
+** is this flushing of the pipeline which is so slow.
+**
+** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
+** llrint and llrintf which fix this problem as a side effect.
+**
+** On Unix-like systems, the configure process should have detected the
+** presence of these functions. If they weren't found we have to replace them
+** here with a standard C cast.
+*/
+
+/*
+** The C99 prototypes for lrint and lrintf are as follows:
+**
+** long int lrintf (float x) ;
+** long int lrint (double x) ;
+*/
+
+/* The presence of the required functions are detected during the configure
+** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
+** the config.h file.
+*/
+
+#if (HAVE_LRINTF)
+
+/* These defines enable functionality introduced with the 1999 ISO C
+** standard. They must be defined before the inclusion of math.h to
+** engage them. If optimisation is enabled, these functions will be
+** inlined. With optimisation switched off, you have to link in the
+** maths library using -lm.
+*/
+
+#define _ISOC9X_SOURCE 1
+#define _ISOC99_SOURCE 1
+
+#define __USE_ISOC9X 1
+#define __USE_ISOC99 1
+
+#include <math.h>
+#define float2int(x) lrintf(x)
+
+#elif (defined(HAVE_LRINT))
+
+#define _ISOC9X_SOURCE 1
+#define _ISOC99_SOURCE 1
+
+#define __USE_ISOC9X 1
+#define __USE_ISOC99 1
+
+#include <math.h>
+#define float2int(x) lrint(x)
+
+#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN64) || defined (_WIN64))
+ #include <xmmintrin.h>
+
+ __inline long int float2int(float value)
+ {
+ return _mm_cvtss_si32(_mm_load_ss(&value));
+ }
+#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN32) || defined (_WIN32))
+ #include <math.h>
+
+ /* Win32 doesn't seem to have these functions.
+ ** Therefore implement inline versions of these functions here.
+ */
+
+ __inline long int
+ float2int (float flt)
+ { int intgr;
+
+ _asm
+ { fld flt
+ fistp intgr
+ } ;
+
+ return intgr ;
+ }
+
+#else
+
+#if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L)
+ /* supported by gcc in C99 mode, but not by all other compilers */
+ #warning "Don't have the functions lrint() and lrintf ()."
+ #warning "Replacing these functions with a standard C cast."
+#endif /* __STDC_VERSION__ >= 199901L */
+ #include <math.h>
+ #define float2int(flt) ((int)(floor(.5+flt)))
+#endif
+
+#ifndef DISABLE_FLOAT_API
+static inline opus_int16 FLOAT2INT16(float x)
+{
+ x = x*CELT_SIG_SCALE;
+ x = MAX32(x, -32768);
+ x = MIN32(x, 32767);
+ return (opus_int16)float2int(x);
+}
+#endif /* DISABLE_FLOAT_API */
+
+#endif /* FLOAT_CAST_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/kiss_fft.c b/lib/rbcodec/codecs/libopus/celt/kiss_fft.c
new file mode 100644
index 0000000000..3ba075ab0c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/kiss_fft.c
@@ -0,0 +1,722 @@
+/*Copyright (c) 2003-2004, Mark Borgerding
+ Lots of modifications by Jean-Marc Valin
+ Copyright (c) 2005-2007, Xiph.Org Foundation
+ Copyright (c) 2008, Xiph.Org Foundation, CSIRO
+
+ All rights reserved.
+
+ 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.
+
+ 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 COPYRIGHT OWNER 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.*/
+
+/* This code is originally from Mark Borgerding's KISS-FFT but has been
+ heavily modified to better suit Opus */
+
+#ifndef SKIP_CONFIG_H
+# ifdef HAVE_CONFIG_H
+# include "opus_config.h"
+# endif
+#endif
+
+#include "_kiss_fft_guts.h"
+#include "arch.h"
+#include "os_support.h"
+#include "mathops.h"
+#include "stack_alloc.h"
+#include "os_support.h"
+
+/* The guts header contains all the multiplication and addition macros that are defined for
+ complex numbers. It also delares the kf_ internal functions.
+*/
+
+static void kf_bfly2(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_state *st,
+ int m,
+ int N,
+ int mm
+ )
+{
+ kiss_fft_cpx * Fout2;
+ const kiss_twiddle_cpx * tw1;
+ int i,j;
+ kiss_fft_cpx * Fout_beg = Fout;
+ for (i=0;i<N;i++)
+ {
+ Fout = Fout_beg + i*mm;
+ Fout2 = Fout + m;
+ tw1 = st->twiddles;
+ for(j=0;j<m;j++)
+ {
+ kiss_fft_cpx t;
+ Fout->r = SHR32(Fout->r, 1);Fout->i = SHR32(Fout->i, 1);
+ Fout2->r = SHR32(Fout2->r, 1);Fout2->i = SHR32(Fout2->i, 1);
+ C_MUL (t, *Fout2 , *tw1);
+ tw1 += fstride;
+ C_SUB( *Fout2 , *Fout , t );
+ C_ADDTO( *Fout , t );
+ ++Fout2;
+ ++Fout;
+ }
+ }
+}
+
+static void ki_bfly2(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_state *st,
+ int m,
+ int N,
+ int mm
+ )
+{
+ kiss_fft_cpx * Fout2;
+ const kiss_twiddle_cpx * tw1;
+ kiss_fft_cpx t;
+ int i,j;
+ kiss_fft_cpx * Fout_beg = Fout;
+ for (i=0;i<N;i++)
+ {
+ Fout = Fout_beg + i*mm;
+ Fout2 = Fout + m;
+ tw1 = st->twiddles;
+ for(j=0;j<m;j++)
+ {
+ C_MULC (t, *Fout2 , *tw1);
+ tw1 += fstride;
+ C_SUB( *Fout2 , *Fout , t );
+ C_ADDTO( *Fout , t );
+ ++Fout2;
+ ++Fout;
+ }
+ }
+}
+
+static void kf_bfly4(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_state *st,
+ int m,
+ int N,
+ int mm
+ )
+{
+ const kiss_twiddle_cpx *tw1,*tw2,*tw3;
+ kiss_fft_cpx scratch[6];
+ const size_t m2=2*m;
+ const size_t m3=3*m;
+ int i, j;
+
+ kiss_fft_cpx * Fout_beg = Fout;
+ for (i=0;i<N;i++)
+ {
+ Fout = Fout_beg + i*mm;
+ tw3 = tw2 = tw1 = st->twiddles;
+ for (j=0;j<m;j++)
+ {
+ C_MUL4(scratch[0],Fout[m] , *tw1 );
+ C_MUL4(scratch[1],Fout[m2] , *tw2 );
+ C_MUL4(scratch[2],Fout[m3] , *tw3 );
+
+ Fout->r = PSHR32(Fout->r, 2);
+ Fout->i = PSHR32(Fout->i, 2);
+ C_SUB( scratch[5] , *Fout, scratch[1] );
+ C_ADDTO(*Fout, scratch[1]);
+ C_ADD( scratch[3] , scratch[0] , scratch[2] );
+ C_SUB( scratch[4] , scratch[0] , scratch[2] );
+ Fout[m2].r = PSHR32(Fout[m2].r, 2);
+ Fout[m2].i = PSHR32(Fout[m2].i, 2);
+ C_SUB( Fout[m2], *Fout, scratch[3] );
+ tw1 += fstride;
+ tw2 += fstride*2;
+ tw3 += fstride*3;
+ C_ADDTO( *Fout , scratch[3] );
+
+ Fout[m].r = scratch[5].r + scratch[4].i;
+ Fout[m].i = scratch[5].i - scratch[4].r;
+ Fout[m3].r = scratch[5].r - scratch[4].i;
+ Fout[m3].i = scratch[5].i + scratch[4].r;
+ ++Fout;
+ }
+ }
+}
+
+static void ki_bfly4(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_state *st,
+ int m,
+ int N,
+ int mm
+ )
+{
+ const kiss_twiddle_cpx *tw1,*tw2,*tw3;
+ kiss_fft_cpx scratch[6];
+ const size_t m2=2*m;
+ const size_t m3=3*m;
+ int i, j;
+
+ kiss_fft_cpx * Fout_beg = Fout;
+ for (i=0;i<N;i++)
+ {
+ Fout = Fout_beg + i*mm;
+ tw3 = tw2 = tw1 = st->twiddles;
+ for (j=0;j<m;j++)
+ {
+ C_MULC(scratch[0],Fout[m] , *tw1 );
+ C_MULC(scratch[1],Fout[m2] , *tw2 );
+ C_MULC(scratch[2],Fout[m3] , *tw3 );
+
+ C_SUB( scratch[5] , *Fout, scratch[1] );
+ C_ADDTO(*Fout, scratch[1]);
+ C_ADD( scratch[3] , scratch[0] , scratch[2] );
+ C_SUB( scratch[4] , scratch[0] , scratch[2] );
+ C_SUB( Fout[m2], *Fout, scratch[3] );
+ tw1 += fstride;
+ tw2 += fstride*2;
+ tw3 += fstride*3;
+ C_ADDTO( *Fout , scratch[3] );
+
+ Fout[m].r = scratch[5].r - scratch[4].i;
+ Fout[m].i = scratch[5].i + scratch[4].r;
+ Fout[m3].r = scratch[5].r + scratch[4].i;
+ Fout[m3].i = scratch[5].i - scratch[4].r;
+ ++Fout;
+ }
+ }
+}
+
+#ifndef RADIX_TWO_ONLY
+
+static void kf_bfly3(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_state *st,
+ int m,
+ int N,
+ int mm
+ )
+{
+ int i;
+ size_t k;
+ const size_t m2 = 2*m;
+ const kiss_twiddle_cpx *tw1,*tw2;
+ kiss_fft_cpx scratch[5];
+ kiss_twiddle_cpx epi3;
+
+ kiss_fft_cpx * Fout_beg = Fout;
+ epi3 = st->twiddles[fstride*m];
+ for (i=0;i<N;i++)
+ {
+ Fout = Fout_beg + i*mm;
+ tw1=tw2=st->twiddles;
+ k=m;
+ do {
+ C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
+
+ C_MUL(scratch[1],Fout[m] , *tw1);
+ C_MUL(scratch[2],Fout[m2] , *tw2);
+
+ C_ADD(scratch[3],scratch[1],scratch[2]);
+ C_SUB(scratch[0],scratch[1],scratch[2]);
+ tw1 += fstride;
+ tw2 += fstride*2;
+
+ Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
+ Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
+
+ C_MULBYSCALAR( scratch[0] , epi3.i );
+
+ C_ADDTO(*Fout,scratch[3]);
+
+ Fout[m2].r = Fout[m].r + scratch[0].i;
+ Fout[m2].i = Fout[m].i - scratch[0].r;
+
+ Fout[m].r -= scratch[0].i;
+ Fout[m].i += scratch[0].r;
+
+ ++Fout;
+ } while(--k);
+ }
+}
+
+static void ki_bfly3(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_state *st,
+ int m,
+ int N,
+ int mm
+ )
+{
+ int i, k;
+ const size_t m2 = 2*m;
+ const kiss_twiddle_cpx *tw1,*tw2;
+ kiss_fft_cpx scratch[5];
+ kiss_twiddle_cpx epi3;
+
+ kiss_fft_cpx * Fout_beg = Fout;
+ epi3 = st->twiddles[fstride*m];
+ for (i=0;i<N;i++)
+ {
+ Fout = Fout_beg + i*mm;
+ tw1=tw2=st->twiddles;
+ k=m;
+ do{
+
+ C_MULC(scratch[1],Fout[m] , *tw1);
+ C_MULC(scratch[2],Fout[m2] , *tw2);
+
+ C_ADD(scratch[3],scratch[1],scratch[2]);
+ C_SUB(scratch[0],scratch[1],scratch[2]);
+ tw1 += fstride;
+ tw2 += fstride*2;
+
+ Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
+ Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
+
+ C_MULBYSCALAR( scratch[0] , -epi3.i );
+
+ C_ADDTO(*Fout,scratch[3]);
+
+ Fout[m2].r = Fout[m].r + scratch[0].i;
+ Fout[m2].i = Fout[m].i - scratch[0].r;
+
+ Fout[m].r -= scratch[0].i;
+ Fout[m].i += scratch[0].r;
+
+ ++Fout;
+ }while(--k);
+ }
+}
+
+static void kf_bfly5(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_state *st,
+ int m,
+ int N,
+ int mm
+ )
+{
+ kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
+ int i, u;
+ kiss_fft_cpx scratch[13];
+ const kiss_twiddle_cpx * twiddles = st->twiddles;
+ const kiss_twiddle_cpx *tw;
+ kiss_twiddle_cpx ya,yb;
+ kiss_fft_cpx * Fout_beg = Fout;
+
+ ya = twiddles[fstride*m];
+ yb = twiddles[fstride*2*m];
+ tw=st->twiddles;
+
+ for (i=0;i<N;i++)
+ {
+ Fout = Fout_beg + i*mm;
+ Fout0=Fout;
+ Fout1=Fout0+m;
+ Fout2=Fout0+2*m;
+ Fout3=Fout0+3*m;
+ Fout4=Fout0+4*m;
+
+ for ( u=0; u<m; ++u ) {
+ C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
+ scratch[0] = *Fout0;
+
+ C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
+ C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
+ C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
+ C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
+
+ C_ADD( scratch[7],scratch[1],scratch[4]);
+ C_SUB( scratch[10],scratch[1],scratch[4]);
+ C_ADD( scratch[8],scratch[2],scratch[3]);
+ C_SUB( scratch[9],scratch[2],scratch[3]);
+
+ Fout0->r += scratch[7].r + scratch[8].r;
+ Fout0->i += scratch[7].i + scratch[8].i;
+
+ scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
+ scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
+
+ scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
+ scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
+
+ C_SUB(*Fout1,scratch[5],scratch[6]);
+ C_ADD(*Fout4,scratch[5],scratch[6]);
+
+ scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
+ scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
+ scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
+ scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
+
+ C_ADD(*Fout2,scratch[11],scratch[12]);
+ C_SUB(*Fout3,scratch[11],scratch[12]);
+
+ ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
+ }
+ }
+}
+
+static void ki_bfly5(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_state *st,
+ int m,
+ int N,
+ int mm
+ )
+{
+ kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
+ int i, u;
+ kiss_fft_cpx scratch[13];
+ const kiss_twiddle_cpx * twiddles = st->twiddles;
+ const kiss_twiddle_cpx *tw;
+ kiss_twiddle_cpx ya,yb;
+ kiss_fft_cpx * Fout_beg = Fout;
+
+ ya = twiddles[fstride*m];
+ yb = twiddles[fstride*2*m];
+ tw=st->twiddles;
+
+ for (i=0;i<N;i++)
+ {
+ Fout = Fout_beg + i*mm;
+ Fout0=Fout;
+ Fout1=Fout0+m;
+ Fout2=Fout0+2*m;
+ Fout3=Fout0+3*m;
+ Fout4=Fout0+4*m;
+
+ for ( u=0; u<m; ++u ) {
+ scratch[0] = *Fout0;
+
+ C_MULC(scratch[1] ,*Fout1, tw[u*fstride]);
+ C_MULC(scratch[2] ,*Fout2, tw[2*u*fstride]);
+ C_MULC(scratch[3] ,*Fout3, tw[3*u*fstride]);
+ C_MULC(scratch[4] ,*Fout4, tw[4*u*fstride]);
+
+ C_ADD( scratch[7],scratch[1],scratch[4]);
+ C_SUB( scratch[10],scratch[1],scratch[4]);
+ C_ADD( scratch[8],scratch[2],scratch[3]);
+ C_SUB( scratch[9],scratch[2],scratch[3]);
+
+ Fout0->r += scratch[7].r + scratch[8].r;
+ Fout0->i += scratch[7].i + scratch[8].i;
+
+ scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
+ scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
+
+ scratch[6].r = -S_MUL(scratch[10].i,ya.i) - S_MUL(scratch[9].i,yb.i);
+ scratch[6].i = S_MUL(scratch[10].r,ya.i) + S_MUL(scratch[9].r,yb.i);
+
+ C_SUB(*Fout1,scratch[5],scratch[6]);
+ C_ADD(*Fout4,scratch[5],scratch[6]);
+
+ scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
+ scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
+ scratch[12].r = S_MUL(scratch[10].i,yb.i) - S_MUL(scratch[9].i,ya.i);
+ scratch[12].i = -S_MUL(scratch[10].r,yb.i) + S_MUL(scratch[9].r,ya.i);
+
+ C_ADD(*Fout2,scratch[11],scratch[12]);
+ C_SUB(*Fout3,scratch[11],scratch[12]);
+
+ ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
+ }
+ }
+}
+
+#endif
+
+
+#ifdef CUSTOM_MODES
+
+static
+void compute_bitrev_table(
+ int Fout,
+ opus_int16 *f,
+ const size_t fstride,
+ int in_stride,
+ opus_int16 * factors,
+ const kiss_fft_state *st
+ )
+{
+ const int p=*factors++; /* the radix */
+ const int m=*factors++; /* stage's fft length/p */
+
+ /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
+ if (m==1)
+ {
+ int j;
+ for (j=0;j<p;j++)
+ {
+ *f = Fout+j;
+ f += fstride*in_stride;
+ }
+ } else {
+ int j;
+ for (j=0;j<p;j++)
+ {
+ compute_bitrev_table( Fout , f, fstride*p, in_stride, factors,st);
+ f += fstride*in_stride;
+ Fout += m;
+ }
+ }
+}
+
+/* facbuf is populated by p1,m1,p2,m2, ...
+ where
+ p[i] * m[i] = m[i-1]
+ m0 = n */
+static
+int kf_factor(int n,opus_int16 * facbuf)
+{
+ int p=4;
+
+ /*factor out powers of 4, powers of 2, then any remaining primes */
+ do {
+ while (n % p) {
+ switch (p) {
+ case 4: p = 2; break;
+ case 2: p = 3; break;
+ default: p += 2; break;
+ }
+ if (p>32000 || (opus_int32)p*(opus_int32)p > n)
+ p = n; /* no more factors, skip to end */
+ }
+ n /= p;
+#ifdef RADIX_TWO_ONLY
+ if (p!=2 && p != 4)
+#else
+ if (p>5)
+#endif
+ {
+ return 0;
+ }
+ *facbuf++ = p;
+ *facbuf++ = n;
+ } while (n > 1);
+ return 1;
+}
+
+static void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft)
+{
+ int i;
+#ifdef FIXED_POINT
+ for (i=0;i<nfft;++i) {
+ opus_val32 phase = -i;
+ kf_cexp2(twiddles+i, DIV32(SHL32(phase,17),nfft));
+ }
+#else
+ for (i=0;i<nfft;++i) {
+ const double pi=3.14159265358979323846264338327;
+ double phase = ( -2*pi /nfft ) * i;
+ kf_cexp(twiddles+i, phase );
+ }
+#endif
+}
+
+/*
+ *
+ * Allocates all necessary storage space for the fft and ifft.
+ * The return value is a contiguous block of memory. As such,
+ * It can be freed with free().
+ * */
+kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base)
+{
+ kiss_fft_state *st=NULL;
+ size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/
+
+ if ( lenmem==NULL ) {
+ st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded );
+ }else{
+ if (mem != NULL && *lenmem >= memneeded)
+ st = (kiss_fft_state*)mem;
+ *lenmem = memneeded;
+ }
+ if (st) {
+ opus_int16 *bitrev;
+ kiss_twiddle_cpx *twiddles;
+
+ st->nfft=nfft;
+#ifndef FIXED_POINT
+ st->scale = 1.f/nfft;
+#endif
+ if (base != NULL)
+ {
+ st->twiddles = base->twiddles;
+ st->shift = 0;
+ while (nfft<<st->shift != base->nfft && st->shift < 32)
+ st->shift++;
+ if (st->shift>=32)
+ goto fail;
+ } else {
+ st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft);
+ compute_twiddles(twiddles, nfft);
+ st->shift = -1;
+ }
+ if (!kf_factor(nfft,st->factors))
+ {
+ goto fail;
+ }
+
+ /* bitrev */
+ st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft);
+ if (st->bitrev==NULL)
+ goto fail;
+ compute_bitrev_table(0, bitrev, 1,1, st->factors,st);
+ }
+ return st;
+fail:
+ opus_fft_free(st);
+ return NULL;
+}
+
+kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem )
+{
+ return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL);
+}
+
+void opus_fft_free(const kiss_fft_state *cfg)
+{
+ if (cfg)
+ {
+ opus_free((opus_int16*)cfg->bitrev);
+ if (cfg->shift < 0)
+ opus_free((kiss_twiddle_cpx*)cfg->twiddles);
+ opus_free((kiss_fft_state*)cfg);
+ }
+}
+
+#endif /* CUSTOM_MODES */
+
+void opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
+{
+ int m2, m;
+ int p;
+ int L;
+ int fstride[MAXFACTORS];
+ int i;
+ int shift;
+
+ /* st->shift can be -1 */
+ shift = st->shift>0 ? st->shift : 0;
+
+ celt_assert2 (fin != fout, "In-place FFT not supported");
+ /* Bit-reverse the input */
+ for (i=0;i<st->nfft;i++)
+ {
+ fout[st->bitrev[i]] = fin[i];
+#ifndef FIXED_POINT
+ fout[st->bitrev[i]].r *= st->scale;
+ fout[st->bitrev[i]].i *= st->scale;
+#endif
+ }
+
+ fstride[0] = 1;
+ L=0;
+ do {
+ p = st->factors[2*L];
+ m = st->factors[2*L+1];
+ fstride[L+1] = fstride[L]*p;
+ L++;
+ } while(m!=1);
+ m = st->factors[2*L-1];
+ for (i=L-1;i>=0;i--)
+ {
+ if (i!=0)
+ m2 = st->factors[2*i-1];
+ else
+ m2 = 1;
+ switch (st->factors[2*i])
+ {
+ case 2:
+ kf_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2);
+ break;
+ case 4:
+ kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2);
+ break;
+ #ifndef RADIX_TWO_ONLY
+ case 3:
+ kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2);
+ break;
+ case 5:
+ kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2);
+ break;
+ #endif
+ }
+ m = m2;
+ }
+}
+
+void opus_ifft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
+{
+ int m2, m;
+ int p;
+ int L;
+ int fstride[MAXFACTORS];
+ int i;
+ int shift;
+
+ /* st->shift can be -1 */
+ shift = st->shift>0 ? st->shift : 0;
+ celt_assert2 (fin != fout, "In-place FFT not supported");
+ /* Bit-reverse the input */
+ for (i=0;i<st->nfft;i++)
+ fout[st->bitrev[i]] = fin[i];
+
+ fstride[0] = 1;
+ L=0;
+ do {
+ p = st->factors[2*L];
+ m = st->factors[2*L+1];
+ fstride[L+1] = fstride[L]*p;
+ L++;
+ } while(m!=1);
+ m = st->factors[2*L-1];
+ for (i=L-1;i>=0;i--)
+ {
+ if (i!=0)
+ m2 = st->factors[2*i-1];
+ else
+ m2 = 1;
+ switch (st->factors[2*i])
+ {
+ case 2:
+ ki_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2);
+ break;
+ case 4:
+ ki_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2);
+ break;
+#ifndef RADIX_TWO_ONLY
+ case 3:
+ ki_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2);
+ break;
+ case 5:
+ ki_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2);
+ break;
+#endif
+ }
+ m = m2;
+ }
+}
+
diff --git a/lib/rbcodec/codecs/libopus/celt/kiss_fft.h b/lib/rbcodec/codecs/libopus/celt/kiss_fft.h
new file mode 100644
index 0000000000..66332e3bb9
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/kiss_fft.h
@@ -0,0 +1,139 @@
+/*Copyright (c) 2003-2004, Mark Borgerding
+ Lots of modifications by Jean-Marc Valin
+ Copyright (c) 2005-2007, Xiph.Org Foundation
+ Copyright (c) 2008, Xiph.Org Foundation, CSIRO
+
+ All rights reserved.
+
+ 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.
+
+ 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 COPYRIGHT OWNER 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 KISS_FFT_H
+#define KISS_FFT_H
+
+#include <stdlib.h>
+#include <math.h>
+#include "arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef USE_SIMD
+# include <xmmintrin.h>
+# define kiss_fft_scalar __m128
+#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes)
+#else
+#define KISS_FFT_MALLOC opus_alloc
+#endif
+
+#ifdef FIXED_POINT
+#include "arch.h"
+
+# define kiss_fft_scalar opus_int32
+# define kiss_twiddle_scalar opus_int16
+
+
+#else
+# ifndef kiss_fft_scalar
+/* default is float */
+# define kiss_fft_scalar float
+# define kiss_twiddle_scalar float
+# define KF_SUFFIX _celt_single
+# endif
+#endif
+
+typedef struct {
+ kiss_fft_scalar r;
+ kiss_fft_scalar i;
+}kiss_fft_cpx;
+
+typedef struct {
+ kiss_twiddle_scalar r;
+ kiss_twiddle_scalar i;
+}kiss_twiddle_cpx;
+
+#define MAXFACTORS 8
+/* e.g. an fft of length 128 has 4 factors
+ as far as kissfft is concerned
+ 4*4*4*2
+ */
+
+typedef struct kiss_fft_state{
+ int nfft;
+#ifndef FIXED_POINT
+ kiss_fft_scalar scale;
+#endif
+ int shift;
+ opus_int16 factors[2*MAXFACTORS];
+ const opus_int16 *bitrev;
+ const kiss_twiddle_cpx *twiddles;
+} kiss_fft_state;
+
+/*typedef struct kiss_fft_state* kiss_fft_cfg;*/
+
+/**
+ * opus_fft_alloc
+ *
+ * Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
+ *
+ * typical usage: kiss_fft_cfg mycfg=opus_fft_alloc(1024,0,NULL,NULL);
+ *
+ * The return value from fft_alloc is a cfg buffer used internally
+ * by the fft routine or NULL.
+ *
+ * If lenmem is NULL, then opus_fft_alloc will allocate a cfg buffer using malloc.
+ * The returned value should be free()d when done to avoid memory leaks.
+ *
+ * The state can be placed in a user supplied buffer 'mem':
+ * If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
+ * then the function places the cfg in mem and the size used in *lenmem
+ * and returns mem.
+ *
+ * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
+ * then the function returns NULL and places the minimum cfg
+ * buffer size in *lenmem.
+ * */
+
+kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base);
+
+kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem);
+
+/**
+ * opus_fft(cfg,in_out_buf)
+ *
+ * Perform an FFT on a complex input buffer.
+ * for a forward FFT,
+ * fin should be f[0] , f[1] , ... ,f[nfft-1]
+ * fout will be F[0] , F[1] , ... ,F[nfft-1]
+ * Note that each element is complex and can be accessed like
+ f[k].r and f[k].i
+ * */
+void opus_fft(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
+void opus_ifft(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
+
+void opus_fft_free(const kiss_fft_state *cfg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/laplace.c b/lib/rbcodec/codecs/libopus/celt/laplace.c
new file mode 100644
index 0000000000..6fa4009d57
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/laplace.c
@@ -0,0 +1,134 @@
+/* Copyright (c) 2007 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include "laplace.h"
+#include "mathops.h"
+
+/* The minimum probability of an energy delta (out of 32768). */
+#define LAPLACE_LOG_MINP (0)
+#define LAPLACE_MINP (1<<LAPLACE_LOG_MINP)
+/* The minimum number of guaranteed representable energy deltas (in one
+ direction). */
+#define LAPLACE_NMIN (16)
+
+/* When called, decay is positive and at most 11456. */
+static unsigned ec_laplace_get_freq1(unsigned fs0, int decay)
+{
+ unsigned ft;
+ ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0;
+ return ft*(opus_int32)(16384-decay)>>15;
+}
+
+void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay)
+{
+ unsigned fl;
+ int val = *value;
+ fl = 0;
+ if (val)
+ {
+ int s;
+ int i;
+ s = -(val<0);
+ val = (val+s)^s;
+ fl = fs;
+ fs = ec_laplace_get_freq1(fs, decay);
+ /* Search the decaying part of the PDF.*/
+ for (i=1; fs > 0 && i < val; i++)
+ {
+ fs *= 2;
+ fl += fs+2*LAPLACE_MINP;
+ fs = (fs*(opus_int32)decay)>>15;
+ }
+ /* Everything beyond that has probability LAPLACE_MINP. */
+ if (!fs)
+ {
+ int di;
+ int ndi_max;
+ ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP;
+ ndi_max = (ndi_max-s)>>1;
+ di = IMIN(val - i, ndi_max - 1);
+ fl += (2*di+1+s)*LAPLACE_MINP;
+ fs = IMIN(LAPLACE_MINP, 32768-fl);
+ *value = (i+di+s)^s;
+ }
+ else
+ {
+ fs += LAPLACE_MINP;
+ fl += fs&~s;
+ }
+ celt_assert(fl+fs<=32768);
+ celt_assert(fs>0);
+ }
+ ec_encode_bin(enc, fl, fl+fs, 15);
+}
+
+int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay)
+{
+ int val=0;
+ unsigned fl;
+ unsigned fm;
+ fm = ec_decode_bin(dec, 15);
+ fl = 0;
+ if (fm >= fs)
+ {
+ val++;
+ fl = fs;
+ fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP;
+ /* Search the decaying part of the PDF.*/
+ while(fs > LAPLACE_MINP && fm >= fl+2*fs)
+ {
+ fs *= 2;
+ fl += fs;
+ fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15;
+ fs += LAPLACE_MINP;
+ val++;
+ }
+ /* Everything beyond that has probability LAPLACE_MINP. */
+ if (fs <= LAPLACE_MINP)
+ {
+ int di;
+ di = (fm-fl)>>(LAPLACE_LOG_MINP+1);
+ val += di;
+ fl += 2*di*LAPLACE_MINP;
+ }
+ if (fm < fl+fs)
+ val = -val;
+ else
+ fl += fs;
+ }
+ celt_assert(fl<32768);
+ celt_assert(fs>0);
+ celt_assert(fl<=fm);
+ celt_assert(fm<IMIN(fl+fs,32768));
+ ec_dec_update(dec, fl, IMIN(fl+fs,32768), 32768);
+ return val;
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/laplace.h b/lib/rbcodec/codecs/libopus/celt/laplace.h
new file mode 100644
index 0000000000..46c14b5da5
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/laplace.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2007 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+#include "entenc.h"
+#include "entdec.h"
+
+/** Encode a value that is assumed to be the realisation of a
+ Laplace-distributed random process
+ @param enc Entropy encoder state
+ @param value Value to encode
+ @param fs Probability of 0, multiplied by 32768
+ @param decay Probability of the value +/- 1, multiplied by 16384
+*/
+void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay);
+
+/** Decode a value that is assumed to be the realisation of a
+ Laplace-distributed random process
+ @param dec Entropy decoder state
+ @param fs Probability of 0, multiplied by 32768
+ @param decay Probability of the value +/- 1, multiplied by 16384
+ @return Value decoded
+ */
+int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay);
diff --git a/lib/rbcodec/codecs/libopus/celt/mathops.c b/lib/rbcodec/codecs/libopus/celt/mathops.c
new file mode 100644
index 0000000000..1af6672592
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mathops.c
@@ -0,0 +1,206 @@
+/* Copyright (c) 2002-2008 Jean-Marc Valin
+ Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/**
+ @file mathops.h
+ @brief Various math functions
+*/
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include "mathops.h"
+
+/*Compute floor(sqrt(_val)) with exact arithmetic.
+ This has been tested on all possible 32-bit inputs.*/
+unsigned isqrt32(opus_uint32 _val){
+ unsigned b;
+ unsigned g;
+ int bshift;
+ /*Uses the second method from
+ http://www.azillionmonkeys.com/qed/sqroot.html
+ The main idea is to search for the largest binary digit b such that
+ (g+b)*(g+b) <= _val, and add it to the solution g.*/
+ g=0;
+ bshift=(EC_ILOG(_val)-1)>>1;
+ b=1U<<bshift;
+ do{
+ opus_uint32 t;
+ t=(((opus_uint32)g<<1)+b)<<bshift;
+ if(t<=_val){
+ g+=b;
+ _val-=t;
+ }
+ b>>=1;
+ bshift--;
+ }
+ while(bshift>=0);
+ return g;
+}
+
+#ifdef FIXED_POINT
+
+opus_val32 frac_div32(opus_val32 a, opus_val32 b)
+{
+ opus_val16 rcp;
+ opus_val32 result, rem;
+ int shift = celt_ilog2(b)-29;
+ a = VSHR32(a,shift);
+ b = VSHR32(b,shift);
+ /* 16-bit reciprocal */
+ rcp = ROUND16(celt_rcp(ROUND16(b,16)),3);
+ result = MULT16_32_Q15(rcp, a);
+ rem = PSHR32(a,2)-MULT32_32_Q31(result, b);
+ result = ADD32(result, SHL32(MULT16_32_Q15(rcp, rem),2));
+ if (result >= 536870912) /* 2^29 */
+ return 2147483647; /* 2^31 - 1 */
+ else if (result <= -536870912) /* -2^29 */
+ return -2147483647; /* -2^31 */
+ else
+ return SHL32(result, 2);
+}
+
+/** Reciprocal sqrt approximation in the range [0.25,1) (Q16 in, Q14 out) */
+opus_val16 celt_rsqrt_norm(opus_val32 x)
+{
+ opus_val16 n;
+ opus_val16 r;
+ opus_val16 r2;
+ opus_val16 y;
+ /* Range of n is [-16384,32767] ([-0.5,1) in Q15). */
+ n = x-32768;
+ /* Get a rough initial guess for the root.
+ The optimal minimax quadratic approximation (using relative error) is
+ r = 1.437799046117536+n*(-0.823394375837328+n*0.4096419668459485).
+ Coefficients here, and the final result r, are Q14.*/
+ r = ADD16(23557, MULT16_16_Q15(n, ADD16(-13490, MULT16_16_Q15(n, 6713))));
+ /* We want y = x*r*r-1 in Q15, but x is 32-bit Q16 and r is Q14.
+ We can compute the result from n and r using Q15 multiplies with some
+ adjustment, carefully done to avoid overflow.
+ Range of y is [-1564,1594]. */
+ r2 = MULT16_16_Q15(r, r);
+ y = SHL16(SUB16(ADD16(MULT16_16_Q15(r2, n), r2), 16384), 1);
+ /* Apply a 2nd-order Householder iteration: r += r*y*(y*0.375-0.5).
+ This yields the Q14 reciprocal square root of the Q16 x, with a maximum
+ relative error of 1.04956E-4, a (relative) RMSE of 2.80979E-5, and a
+ peak absolute error of 2.26591/16384. */
+ return ADD16(r, MULT16_16_Q15(r, MULT16_16_Q15(y,
+ SUB16(MULT16_16_Q15(y, 12288), 16384))));
+}
+
+/** Sqrt approximation (QX input, QX/2 output) */
+opus_val32 celt_sqrt(opus_val32 x)
+{
+ int k;
+ opus_val16 n;
+ opus_val32 rt;
+ static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664};
+ if (x==0)
+ return 0;
+ k = (celt_ilog2(x)>>1)-7;
+ x = VSHR32(x, 2*k);
+ n = x-32768;
+ rt = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2],
+ MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, (C[4])))))))));
+ rt = VSHR32(rt,7-k);
+ return rt;
+}
+
+#define L1 32767
+#define L2 -7651
+#define L3 8277
+#define L4 -626
+
+static inline opus_val16 _celt_cos_pi_2(opus_val16 x)
+{
+ opus_val16 x2;
+
+ x2 = MULT16_16_P15(x,x);
+ return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2
+ ))))))));
+}
+
+#undef L1
+#undef L2
+#undef L3
+#undef L4
+
+opus_val16 celt_cos_norm(opus_val32 x)
+{
+ x = x&0x0001ffff;
+ if (x>SHL32(EXTEND32(1), 16))
+ x = SUB32(SHL32(EXTEND32(1), 17),x);
+ if (x&0x00007fff)
+ {
+ if (x<SHL32(EXTEND32(1), 15))
+ {
+ return _celt_cos_pi_2(EXTRACT16(x));
+ } else {
+ return NEG32(_celt_cos_pi_2(EXTRACT16(65536-x)));
+ }
+ } else {
+ if (x&0x0000ffff)
+ return 0;
+ else if (x&0x0001ffff)
+ return -32767;
+ else
+ return 32767;
+ }
+}
+
+/** Reciprocal approximation (Q15 input, Q16 output) */
+opus_val32 celt_rcp(opus_val32 x)
+{
+ int i;
+ opus_val16 n;
+ opus_val16 r;
+ celt_assert2(x>0, "celt_rcp() only defined for positive values");
+ i = celt_ilog2(x);
+ /* n is Q15 with range [0,1). */
+ n = VSHR32(x,i-15)-32768;
+ /* Start with a linear approximation:
+ r = 1.8823529411764706-0.9411764705882353*n.
+ The coefficients and the result are Q14 in the range [15420,30840].*/
+ r = ADD16(30840, MULT16_16_Q15(-15420, n));
+ /* Perform two Newton iterations:
+ r -= r*((r*n)-1.Q15)
+ = r*((r*n)+(r-1.Q15)). */
+ r = SUB16(r, MULT16_16_Q15(r,
+ ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768))));
+ /* We subtract an extra 1 in the second iteration to avoid overflow; it also
+ neatly compensates for truncation error in the rest of the process. */
+ r = SUB16(r, ADD16(1, MULT16_16_Q15(r,
+ ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768)))));
+ /* r is now the Q15 solution to 2/(n+1), with a maximum relative error
+ of 7.05346E-5, a (relative) RMSE of 2.14418E-5, and a peak absolute
+ error of 1.24665/32768. */
+ return VSHR32(EXTEND32(r),i-16);
+}
+
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/mathops.h b/lib/rbcodec/codecs/libopus/celt/mathops.h
new file mode 100644
index 0000000000..4e97795606
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mathops.h
@@ -0,0 +1,237 @@
+/* Copyright (c) 2002-2008 Jean-Marc Valin
+ Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/**
+ @file mathops.h
+ @brief Various math functions
+*/
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 MATHOPS_H
+#define MATHOPS_H
+
+#include "arch.h"
+#include "entcode.h"
+#include "os_support.h"
+
+/* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */
+#define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15)
+
+unsigned isqrt32(opus_uint32 _val);
+
+#ifndef FIXED_POINT
+
+#define PI 3.141592653f
+#define celt_sqrt(x) ((float)sqrt(x))
+#define celt_rsqrt(x) (1.f/celt_sqrt(x))
+#define celt_rsqrt_norm(x) (celt_rsqrt(x))
+#define celt_cos_norm(x) ((float)cos((.5f*PI)*(x)))
+#define celt_rcp(x) (1.f/(x))
+#define celt_div(a,b) ((a)/(b))
+#define frac_div32(a,b) ((float)(a)/(b))
+
+#ifdef FLOAT_APPROX
+
+/* Note: This assumes radix-2 floating point with the exponent at bits 23..30 and an offset of 127
+ denorm, +/- inf and NaN are *not* handled */
+
+/** Base-2 log approximation (log2(x)). */
+static inline float celt_log2(float x)
+{
+ int integer;
+ float frac;
+ union {
+ float f;
+ opus_uint32 i;
+ } in;
+ in.f = x;
+ integer = (in.i>>23)-127;
+ in.i -= integer<<23;
+ frac = in.f - 1.5f;
+ frac = -0.41445418f + frac*(0.95909232f
+ + frac*(-0.33951290f + frac*0.16541097f));
+ return 1+integer+frac;
+}
+
+/** Base-2 exponential approximation (2^x). */
+static inline float celt_exp2(float x)
+{
+ int integer;
+ float frac;
+ union {
+ float f;
+ opus_uint32 i;
+ } res;
+ integer = floor(x);
+ if (integer < -50)
+ return 0;
+ frac = x-integer;
+ /* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */
+ res.f = 0.99992522f + frac * (0.69583354f
+ + frac * (0.22606716f + 0.078024523f*frac));
+ res.i = (res.i + (integer<<23)) & 0x7fffffff;
+ return res.f;
+}
+
+#else
+#define celt_log2(x) ((float)(1.442695040888963387*log(x)))
+#define celt_exp2(x) ((float)exp(0.6931471805599453094*(x)))
+#endif
+
+#endif
+
+#ifdef FIXED_POINT
+
+#include "os_support.h"
+
+#ifndef OVERRIDE_CELT_ILOG2
+/** Integer log in base2. Undefined for zero and negative numbers */
+static inline opus_int16 celt_ilog2(opus_int32 x)
+{
+ celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers");
+ return EC_ILOG(x)-1;
+}
+#endif
+
+#ifndef OVERRIDE_CELT_MAXABS16
+static inline opus_val16 celt_maxabs16(opus_val16 *x, int len)
+{
+ int i;
+ opus_val16 maxval = 0;
+ for (i=0;i<len;i++)
+ maxval = MAX16(maxval, ABS16(x[i]));
+ return maxval;
+}
+#endif
+
+#ifndef OVERRIDE_CELT_MAXABS32
+static inline opus_val32 celt_maxabs32(opus_val32 *x, int len)
+{
+ int i;
+ opus_val32 maxval = 0;
+ for (i=0;i<len;i++)
+ maxval = MAX32(maxval, ABS32(x[i]));
+ return maxval;
+}
+#endif
+
+/** Integer log in base2. Defined for zero, but not for negative numbers */
+static inline opus_int16 celt_zlog2(opus_val32 x)
+{
+ return x <= 0 ? 0 : celt_ilog2(x);
+}
+
+opus_val16 celt_rsqrt_norm(opus_val32 x);
+
+opus_val32 celt_sqrt(opus_val32 x);
+
+opus_val16 celt_cos_norm(opus_val32 x);
+
+static inline opus_val16 celt_log2(opus_val32 x)
+{
+ int i;
+ opus_val16 n, frac;
+ /* -0.41509302963303146, 0.9609890551383969, -0.31836011537636605,
+ 0.15530808010959576, -0.08556153059057618 */
+ static const opus_val16 C[5] = {-6801+(1<<(13-DB_SHIFT)), 15746, -5217, 2545, -1401};
+ if (x==0)
+ return -32767;
+ i = celt_ilog2(x);
+ n = VSHR32(x,i-15)-32768-16384;
+ frac = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, C[4]))))))));
+ return SHL16(i-13,DB_SHIFT)+SHR16(frac,14-DB_SHIFT);
+}
+
+/*
+ K0 = 1
+ K1 = log(2)
+ K2 = 3-4*log(2)
+ K3 = 3*log(2) - 2
+*/
+#define D0 16383
+#define D1 22804
+#define D2 14819
+#define D3 10204
+/** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */
+static inline opus_val32 celt_exp2(opus_val16 x)
+{
+ int integer;
+ opus_val16 frac;
+ integer = SHR16(x,10);
+ if (integer>14)
+ return 0x7f000000;
+ else if (integer < -15)
+ return 0;
+ frac = SHL16(x-SHL16(integer,10),4);
+ frac = ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac))))));
+ return VSHR32(EXTEND32(frac), -integer-2);
+}
+
+opus_val32 celt_rcp(opus_val32 x);
+
+#define celt_div(a,b) MULT32_32_Q31((opus_val32)(a),celt_rcp(b))
+
+opus_val32 frac_div32(opus_val32 a, opus_val32 b);
+
+#define M1 32767
+#define M2 -21
+#define M3 -11943
+#define M4 4936
+
+/* Atan approximation using a 4th order polynomial. Input is in Q15 format
+ and normalized by pi/4. Output is in Q15 format */
+static inline opus_val16 celt_atan01(opus_val16 x)
+{
+ return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
+}
+
+#undef M1
+#undef M2
+#undef M3
+#undef M4
+
+/* atan2() approximation valid for positive input values */
+static inline opus_val16 celt_atan2p(opus_val16 y, opus_val16 x)
+{
+ if (y < x)
+ {
+ opus_val32 arg;
+ arg = celt_div(SHL32(EXTEND32(y),15),x);
+ if (arg >= 32767)
+ arg = 32767;
+ return SHR16(celt_atan01(EXTRACT16(arg)),1);
+ } else {
+ opus_val32 arg;
+ arg = celt_div(SHL32(EXTEND32(x),15),y);
+ if (arg >= 32767)
+ arg = 32767;
+ return 25736-SHR16(celt_atan01(EXTRACT16(arg)),1);
+ }
+}
+
+#endif /* FIXED_POINT */
+#endif /* MATHOPS_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/mdct.c b/lib/rbcodec/codecs/libopus/celt/mdct.c
new file mode 100644
index 0000000000..abf4e79d8d
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mdct.c
@@ -0,0 +1,332 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2008 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+/* This is a simple MDCT implementation that uses a N/4 complex FFT
+ to do most of the work. It should be relatively straightforward to
+ plug in pretty much and FFT here.
+
+ This replaces the Vorbis FFT (and uses the exact same API), which
+ was a bit too messy and that was ending up duplicating code
+ (might as well use the same FFT everywhere).
+
+ The algorithm is similar to (and inspired from) Fabrice Bellard's
+ MDCT implementation in FFMPEG, but has differences in signs, ordering
+ and scaling in many places.
+*/
+
+#ifndef SKIP_CONFIG_H
+#ifdef HAVE_CONFIG_H
+#include "opus_config.h"
+#endif
+#endif
+
+#include "mdct.h"
+#include "kiss_fft.h"
+#include "_kiss_fft_guts.h"
+#include <math.h>
+#include "os_support.h"
+#include "mathops.h"
+#include "stack_alloc.h"
+
+#ifdef CUSTOM_MODES
+
+int clt_mdct_init(mdct_lookup *l,int N, int maxshift)
+{
+ int i;
+ int N4;
+ kiss_twiddle_scalar *trig;
+#if defined(FIXED_POINT)
+ int N2=N>>1;
+#endif
+ l->n = N;
+ N4 = N>>2;
+ l->maxshift = maxshift;
+ for (i=0;i<=maxshift;i++)
+ {
+ if (i==0)
+ l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0);
+ else
+ l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0]);
+#ifndef ENABLE_TI_DSPLIB55
+ if (l->kfft[i]==NULL)
+ return 0;
+#endif
+ }
+ l->trig = trig = (kiss_twiddle_scalar*)opus_alloc((N4+1)*sizeof(kiss_twiddle_scalar));
+ if (l->trig==NULL)
+ return 0;
+ /* We have enough points that sine isn't necessary */
+#if defined(FIXED_POINT)
+ for (i=0;i<=N4;i++)
+ trig[i] = TRIG_UPSCALE*celt_cos_norm(DIV32(ADD32(SHL32(EXTEND32(i),17),N2),N));
+#else
+ for (i=0;i<=N4;i++)
+ trig[i] = (kiss_twiddle_scalar)cos(2*PI*i/N);
+#endif
+ return 1;
+}
+
+void clt_mdct_clear(mdct_lookup *l)
+{
+ int i;
+ for (i=0;i<=l->maxshift;i++)
+ opus_fft_free(l->kfft[i]);
+ opus_free((kiss_twiddle_scalar*)l->trig);
+}
+
+#endif /* CUSTOM_MODES */
+
+/* Forward MDCT trashes the input array */
+void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
+ const opus_val16 *window, int overlap, int shift, int stride)
+{
+ int i;
+ int N, N2, N4;
+ kiss_twiddle_scalar sine;
+ VARDECL(kiss_fft_scalar, f);
+ SAVE_STACK;
+ N = l->n;
+ N >>= shift;
+ N2 = N>>1;
+ N4 = N>>2;
+ ALLOC(f, N2, kiss_fft_scalar);
+ /* sin(x) ~= x here */
+#ifdef FIXED_POINT
+ sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N;
+#else
+ sine = (kiss_twiddle_scalar)2*PI*(.125f)/N;
+#endif
+
+ /* Consider the input to be composed of four blocks: [a, b, c, d] */
+ /* Window, shuffle, fold */
+ {
+ /* Temp pointers to make it really clear to the compiler what we're doing */
+ const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
+ const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
+ kiss_fft_scalar * OPUS_RESTRICT yp = f;
+ const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
+ const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
+ for(i=0;i<(overlap>>2);i++)
+ {
+ /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
+ *yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);
+ *yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]);
+ xp1+=2;
+ xp2-=2;
+ wp1+=2;
+ wp2-=2;
+ }
+ wp1 = window;
+ wp2 = window+overlap-1;
+ for(;i<N4-(overlap>>2);i++)
+ {
+ /* Real part arranged as a-bR, Imag part arranged as -c-dR */
+ *yp++ = *xp2;
+ *yp++ = *xp1;
+ xp1+=2;
+ xp2-=2;
+ }
+ for(;i<N4;i++)
+ {
+ /* Real part arranged as a-bR, Imag part arranged as -c-dR */
+ *yp++ = -MULT16_32_Q15(*wp1, xp1[-N2]) + MULT16_32_Q15(*wp2, *xp2);
+ *yp++ = MULT16_32_Q15(*wp2, *xp1) + MULT16_32_Q15(*wp1, xp2[N2]);
+ xp1+=2;
+ xp2-=2;
+ wp1+=2;
+ wp2-=2;
+ }
+ }
+ /* Pre-rotation */
+ {
+ kiss_fft_scalar * OPUS_RESTRICT yp = f;
+ const kiss_twiddle_scalar *t = &l->trig[0];
+ for(i=0;i<N4;i++)
+ {
+ kiss_fft_scalar re, im, yr, yi;
+ re = yp[0];
+ im = yp[1];
+ yr = -S_MUL(re,t[i<<shift]) - S_MUL(im,t[(N4-i)<<shift]);
+ yi = -S_MUL(im,t[i<<shift]) + S_MUL(re,t[(N4-i)<<shift]);
+ /* works because the cos is nearly one */
+ *yp++ = yr + S_MUL(yi,sine);
+ *yp++ = yi - S_MUL(yr,sine);
+ }
+ }
+
+ /* N/4 complex FFT, down-scales by 4/N */
+ opus_fft(l->kfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)in);
+
+ /* Post-rotate */
+ {
+ /* Temp pointers to make it really clear to the compiler what we're doing */
+ const kiss_fft_scalar * OPUS_RESTRICT fp = in;
+ kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
+ kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
+ const kiss_twiddle_scalar *t = &l->trig[0];
+ /* Temp pointers to make it really clear to the compiler what we're doing */
+ for(i=0;i<N4;i++)
+ {
+ kiss_fft_scalar yr, yi;
+ yr = S_MUL(fp[1],t[(N4-i)<<shift]) + S_MUL(fp[0],t[i<<shift]);
+ yi = S_MUL(fp[0],t[(N4-i)<<shift]) - S_MUL(fp[1],t[i<<shift]);
+ /* works because the cos is nearly one */
+ *yp1 = yr - S_MUL(yi,sine);
+ *yp2 = yi + S_MUL(yr,sine);;
+ fp += 2;
+ yp1 += 2*stride;
+ yp2 -= 2*stride;
+ }
+ }
+ RESTORE_STACK;
+}
+
+void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
+ const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride)
+{
+ int i;
+ int N, N2, N4;
+ kiss_twiddle_scalar sine;
+ VARDECL(kiss_fft_scalar, f);
+ VARDECL(kiss_fft_scalar, f2);
+ SAVE_STACK;
+ N = l->n;
+ N >>= shift;
+ N2 = N>>1;
+ N4 = N>>2;
+ ALLOC(f, N2, kiss_fft_scalar);
+ ALLOC(f2, N2, kiss_fft_scalar);
+ /* sin(x) ~= x here */
+#ifdef FIXED_POINT
+ sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N;
+#else
+ sine = (kiss_twiddle_scalar)2*PI*(.125f)/N;
+#endif
+
+ /* Pre-rotate */
+ {
+ /* Temp pointers to make it really clear to the compiler what we're doing */
+ const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
+ const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
+ kiss_fft_scalar * OPUS_RESTRICT yp = f2;
+ const kiss_twiddle_scalar *t = &l->trig[0];
+ for(i=0;i<N4;i++)
+ {
+ kiss_fft_scalar yr, yi;
+ yr = -S_MUL(*xp2, t[i<<shift]) + S_MUL(*xp1,t[(N4-i)<<shift]);
+ yi = -S_MUL(*xp2, t[(N4-i)<<shift]) - S_MUL(*xp1,t[i<<shift]);
+ /* works because the cos is nearly one */
+ *yp++ = yr - S_MUL(yi,sine);
+ *yp++ = yi + S_MUL(yr,sine);
+ xp1+=2*stride;
+ xp2-=2*stride;
+ }
+ }
+
+ /* Inverse N/4 complex FFT. This one should *not* downscale even in fixed-point */
+ opus_ifft(l->kfft[shift], (kiss_fft_cpx *)f2, (kiss_fft_cpx *)f);
+
+ /* Post-rotate */
+ {
+ kiss_fft_scalar * OPUS_RESTRICT fp = f;
+ const kiss_twiddle_scalar *t = &l->trig[0];
+
+ for(i=0;i<N4;i++)
+ {
+ kiss_fft_scalar re, im, yr, yi;
+ re = fp[0];
+ im = fp[1];
+ /* We'd scale up by 2 here, but instead it's done when mixing the windows */
+ yr = S_MUL(re,t[i<<shift]) - S_MUL(im,t[(N4-i)<<shift]);
+ yi = S_MUL(im,t[i<<shift]) + S_MUL(re,t[(N4-i)<<shift]);
+ /* works because the cos is nearly one */
+ *fp++ = yr - S_MUL(yi,sine);
+ *fp++ = yi + S_MUL(yr,sine);
+ }
+ }
+ /* De-shuffle the components for the middle of the window only */
+ {
+ const kiss_fft_scalar * OPUS_RESTRICT fp1 = f;
+ const kiss_fft_scalar * OPUS_RESTRICT fp2 = f+N2-1;
+ kiss_fft_scalar * OPUS_RESTRICT yp = f2;
+ for(i = 0; i < N4; i++)
+ {
+ *yp++ =-*fp1;
+ *yp++ = *fp2;
+ fp1 += 2;
+ fp2 -= 2;
+ }
+ }
+ out -= (N2-overlap)>>1;
+ /* Mirror on both sides for TDAC */
+ {
+ kiss_fft_scalar * OPUS_RESTRICT fp1 = f2+N4-1;
+ kiss_fft_scalar * OPUS_RESTRICT xp1 = out+N2-1;
+ kiss_fft_scalar * OPUS_RESTRICT yp1 = out+N4-overlap/2;
+ const opus_val16 * OPUS_RESTRICT wp1 = window;
+ const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
+ for(i = 0; i< N4-overlap/2; i++)
+ {
+ *xp1 = *fp1;
+ xp1--;
+ fp1--;
+ }
+ for(; i < N4; i++)
+ {
+ kiss_fft_scalar x1;
+ x1 = *fp1--;
+ *yp1++ +=-MULT16_32_Q15(*wp1, x1);
+ *xp1-- += MULT16_32_Q15(*wp2, x1);
+ wp1++;
+ wp2--;
+ }
+ }
+ {
+ kiss_fft_scalar * OPUS_RESTRICT fp2 = f2+N4;
+ kiss_fft_scalar * OPUS_RESTRICT xp2 = out+N2;
+ kiss_fft_scalar * OPUS_RESTRICT yp2 = out+N-1-(N4-overlap/2);
+ const opus_val16 * OPUS_RESTRICT wp1 = window;
+ const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
+ for(i = 0; i< N4-overlap/2; i++)
+ {
+ *xp2 = *fp2;
+ xp2++;
+ fp2++;
+ }
+ for(; i < N4; i++)
+ {
+ kiss_fft_scalar x2;
+ x2 = *fp2++;
+ *yp2-- = MULT16_32_Q15(*wp1, x2);
+ *xp2++ = MULT16_32_Q15(*wp2, x2);
+ wp1++;
+ wp2--;
+ }
+ }
+ RESTORE_STACK;
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/mdct.h b/lib/rbcodec/codecs/libopus/celt/mdct.h
new file mode 100644
index 0000000000..d72182138a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mdct.h
@@ -0,0 +1,70 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2008 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+/* This is a simple MDCT implementation that uses a N/4 complex FFT
+ to do most of the work. It should be relatively straightforward to
+ plug in pretty much and FFT here.
+
+ This replaces the Vorbis FFT (and uses the exact same API), which
+ was a bit too messy and that was ending up duplicating code
+ (might as well use the same FFT everywhere).
+
+ The algorithm is similar to (and inspired from) Fabrice Bellard's
+ MDCT implementation in FFMPEG, but has differences in signs, ordering
+ and scaling in many places.
+*/
+
+#ifndef MDCT_H
+#define MDCT_H
+
+#include "opus_defines.h"
+#include "kiss_fft.h"
+#include "arch.h"
+
+typedef struct {
+ int n;
+ int maxshift;
+ const kiss_fft_state *kfft[4];
+ const kiss_twiddle_scalar * OPUS_RESTRICT trig;
+} mdct_lookup;
+
+int clt_mdct_init(mdct_lookup *l,int N, int maxshift);
+void clt_mdct_clear(mdct_lookup *l);
+
+/** Compute a forward MDCT and scale by 4/N, trashes the input array */
+void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in,
+ kiss_fft_scalar * OPUS_RESTRICT out,
+ const opus_val16 *window, int overlap, int shift, int stride);
+
+/** Compute a backward MDCT (no scaling) and performs weighted overlap-add
+ (scales implicitly by 1/2) */
+void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in,
+ kiss_fft_scalar * OPUS_RESTRICT out,
+ const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride);
+
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/mfrngcod.h b/lib/rbcodec/codecs/libopus/celt/mfrngcod.h
new file mode 100644
index 0000000000..809152a59a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mfrngcod.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2001-2008 Timothy B. Terriberry
+ Copyright (c) 2008-2009 Xiph.Org Foundation */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+#if !defined(_mfrngcode_H)
+# define _mfrngcode_H (1)
+# include "entcode.h"
+
+/*Constants used by the entropy encoder/decoder.*/
+
+/*The number of bits to output at a time.*/
+# define EC_SYM_BITS (8)
+/*The total number of bits in each of the state registers.*/
+# define EC_CODE_BITS (32)
+/*The maximum symbol value.*/
+# define EC_SYM_MAX ((1U<<EC_SYM_BITS)-1)
+/*Bits to shift by to move a symbol into the high-order position.*/
+# define EC_CODE_SHIFT (EC_CODE_BITS-EC_SYM_BITS-1)
+/*Carry bit of the high-order range symbol.*/
+# define EC_CODE_TOP (((opus_uint32)1U)<<(EC_CODE_BITS-1))
+/*Low-order bit of the high-order range symbol.*/
+# define EC_CODE_BOT (EC_CODE_TOP>>EC_SYM_BITS)
+/*The number of bits available for the last, partial symbol in the code field.*/
+# define EC_CODE_EXTRA ((EC_CODE_BITS-2)%EC_SYM_BITS+1)
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/modes.c b/lib/rbcodec/codecs/libopus/celt/modes.c
new file mode 100644
index 0000000000..d44cb3b9de
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/modes.c
@@ -0,0 +1,430 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2008 Gregory Maxwell
+ Written by Jean-Marc Valin and Gregory Maxwell */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include "celt.h"
+#include "modes.h"
+#include "rate.h"
+#include "os_support.h"
+#include "stack_alloc.h"
+#include "quant_bands.h"
+
+static const opus_int16 eband5ms[] = {
+/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
+};
+
+/* Alternate tuning (partially derived from Vorbis) */
+#define BITALLOC_SIZE 11
+/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
+static const unsigned char band_allocation[] = {
+/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0,
+110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0,
+118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0,
+126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0,
+134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1,
+144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1,
+152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1,
+162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1,
+172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20,
+200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104,
+};
+
+#ifndef CUSTOM_MODES_ONLY
+ #ifdef FIXED_POINT
+ #include "static_modes_fixed.h"
+ #else
+ #include "static_modes_float.h"
+ #endif
+#endif /* CUSTOM_MODES_ONLY */
+
+#ifndef M_PI
+#define M_PI 3.141592653
+#endif
+
+#ifdef CUSTOM_MODES
+
+/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
+ Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
+#define BARK_BANDS 25
+static const opus_int16 bark_freq[BARK_BANDS+1] = {
+ 0, 100, 200, 300, 400,
+ 510, 630, 770, 920, 1080,
+ 1270, 1480, 1720, 2000, 2320,
+ 2700, 3150, 3700, 4400, 5300,
+ 6400, 7700, 9500, 12000, 15500,
+ 20000};
+
+static opus_int16 *compute_ebands(opus_int32 Fs, int frame_size, int res, int *nbEBands)
+{
+ opus_int16 *eBands;
+ int i, j, lin, low, high, nBark, offset=0;
+
+ /* All modes that have 2.5 ms short blocks use the same definition */
+ if (Fs == 400*(opus_int32)frame_size)
+ {
+ *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
+ eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+1));
+ for (i=0;i<*nbEBands+1;i++)
+ eBands[i] = eband5ms[i];
+ return eBands;
+ }
+ /* Find the number of critical bands supported by our sampling rate */
+ for (nBark=1;nBark<BARK_BANDS;nBark++)
+ if (bark_freq[nBark+1]*2 >= Fs)
+ break;
+
+ /* Find where the linear part ends (i.e. where the spacing is more than min_width */
+ for (lin=0;lin<nBark;lin++)
+ if (bark_freq[lin+1]-bark_freq[lin] >= res)
+ break;
+
+ low = (bark_freq[lin]+res/2)/res;
+ high = nBark-lin;
+ *nbEBands = low+high;
+ eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+2));
+
+ if (eBands==NULL)
+ return NULL;
+
+ /* Linear spacing (min_width) */
+ for (i=0;i<low;i++)
+ eBands[i] = i;
+ if (low>0)
+ offset = eBands[low-1]*res - bark_freq[lin-1];
+ /* Spacing follows critical bands */
+ for (i=0;i<high;i++)
+ {
+ int target = bark_freq[lin+i];
+ /* Round to an even value */
+ eBands[i+low] = (target+offset/2+res)/(2*res)*2;
+ offset = eBands[i+low]*res - target;
+ }
+ /* Enforce the minimum spacing at the boundary */
+ for (i=0;i<*nbEBands;i++)
+ if (eBands[i] < i)
+ eBands[i] = i;
+ /* Round to an even value */
+ eBands[*nbEBands] = (bark_freq[nBark]+res)/(2*res)*2;
+ if (eBands[*nbEBands] > frame_size)
+ eBands[*nbEBands] = frame_size;
+ for (i=1;i<*nbEBands-1;i++)
+ {
+ if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
+ {
+ eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
+ }
+ }
+ /* Remove any empty bands. */
+ for (i=j=0;i<*nbEBands;i++)
+ if(eBands[i+1]>eBands[j])
+ eBands[++j]=eBands[i+1];
+ *nbEBands=j;
+
+ for (i=1;i<*nbEBands;i++)
+ {
+ /* Every band must be smaller than the last band. */
+ celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]);
+ /* Each band must be no larger than twice the size of the previous one. */
+ celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1]));
+ }
+
+ return eBands;
+}
+
+static void compute_allocation_table(CELTMode *mode)
+{
+ int i, j;
+ unsigned char *allocVectors;
+ int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
+
+ mode->nbAllocVectors = BITALLOC_SIZE;
+ allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
+ if (allocVectors==NULL)
+ return;
+
+ /* Check for standard mode */
+ if (mode->Fs == 400*(opus_int32)mode->shortMdctSize)
+ {
+ for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
+ allocVectors[i] = band_allocation[i];
+ mode->allocVectors = allocVectors;
+ return;
+ }
+ /* If not the standard mode, interpolate */
+ /* Compute per-codec-band allocation from per-critical-band matrix */
+ for (i=0;i<BITALLOC_SIZE;i++)
+ {
+ for (j=0;j<mode->nbEBands;j++)
+ {
+ int k;
+ for (k=0;k<maxBands;k++)
+ {
+ if (400*(opus_int32)eband5ms[k] > mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize)
+ break;
+ }
+ if (k>maxBands-1)
+ allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1];
+ else {
+ opus_int32 a0, a1;
+ a1 = mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize - 400*(opus_int32)eband5ms[k-1];
+ a0 = 400*(opus_int32)eband5ms[k] - mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize;
+ allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1]
+ + a1*band_allocation[i*maxBands+k])/(a0+a1);
+ }
+ }
+ }
+
+ /*printf ("\n");
+ for (i=0;i<BITALLOC_SIZE;i++)
+ {
+ for (j=0;j<mode->nbEBands;j++)
+ printf ("%d ", allocVectors[i*mode->nbEBands+j]);
+ printf ("\n");
+ }
+ exit(0);*/
+
+ mode->allocVectors = allocVectors;
+}
+
+#endif /* CUSTOM_MODES */
+
+CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
+{
+ int i;
+#ifdef CUSTOM_MODES
+ CELTMode *mode=NULL;
+ int res;
+ opus_val16 *window;
+ opus_int16 *logN;
+ int LM;
+ ALLOC_STACK;
+#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
+ if (global_stack==NULL)
+ goto failure;
+#endif
+#endif
+
+#ifndef CUSTOM_MODES_ONLY
+ for (i=0;i<TOTAL_MODES;i++)
+ {
+ int j;
+ for (j=0;j<4;j++)
+ {
+ if (Fs == static_mode_list[i]->Fs &&
+ (frame_size<<j) == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
+ {
+ if (error)
+ *error = OPUS_OK;
+ return (CELTMode*)static_mode_list[i];
+ }
+ }
+ }
+#endif /* CUSTOM_MODES_ONLY */
+
+#ifndef CUSTOM_MODES
+ if (error)
+ *error = OPUS_BAD_ARG;
+ return NULL;
+#else
+
+ /* The good thing here is that permutation of the arguments will automatically be invalid */
+
+ if (Fs < 8000 || Fs > 96000)
+ {
+ if (error)
+ *error = OPUS_BAD_ARG;
+ return NULL;
+ }
+ if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
+ {
+ if (error)
+ *error = OPUS_BAD_ARG;
+ return NULL;
+ }
+ /* Frames of less than 1ms are not supported. */
+ if ((opus_int32)frame_size*1000 < Fs)
+ {
+ if (error)
+ *error = OPUS_BAD_ARG;
+ return NULL;
+ }
+
+ if ((opus_int32)frame_size*75 >= Fs && (frame_size%16)==0)
+ {
+ LM = 3;
+ } else if ((opus_int32)frame_size*150 >= Fs && (frame_size%8)==0)
+ {
+ LM = 2;
+ } else if ((opus_int32)frame_size*300 >= Fs && (frame_size%4)==0)
+ {
+ LM = 1;
+ } else
+ {
+ LM = 0;
+ }
+
+ /* Shorts longer than 3.3ms are not supported. */
+ if ((opus_int32)(frame_size>>LM)*300 > Fs)
+ {
+ if (error)
+ *error = OPUS_BAD_ARG;
+ return NULL;
+ }
+
+ mode = opus_alloc(sizeof(CELTMode));
+ if (mode==NULL)
+ goto failure;
+ mode->Fs = Fs;
+
+ /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
+ is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
+ approximate that. */
+ if(Fs < 12000) /* 8 kHz */
+ {
+ mode->preemph[0] = QCONST16(0.3500061035f, 15);
+ mode->preemph[1] = -QCONST16(0.1799926758f, 15);
+ mode->preemph[2] = QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */
+ mode->preemph[3] = QCONST16(3.6765136719f, 13);
+ } else if(Fs < 24000) /* 16 kHz */
+ {
+ mode->preemph[0] = QCONST16(0.6000061035f, 15);
+ mode->preemph[1] = -QCONST16(0.1799926758f, 15);
+ mode->preemph[2] = QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */
+ mode->preemph[3] = QCONST16(2.2598876953f, 13);
+ } else if(Fs < 40000) /* 32 kHz */
+ {
+ mode->preemph[0] = QCONST16(0.7799987793f, 15);
+ mode->preemph[1] = -QCONST16(0.1000061035f, 15);
+ mode->preemph[2] = QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */
+ mode->preemph[3] = QCONST16(1.3333740234f, 13);
+ } else /* 48 kHz */
+ {
+ mode->preemph[0] = QCONST16(0.8500061035f, 15);
+ mode->preemph[1] = QCONST16(0.0f, 15);
+ mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
+ mode->preemph[3] = QCONST16(1.f, 13);
+ }
+
+ mode->maxLM = LM;
+ mode->nbShortMdcts = 1<<LM;
+ mode->shortMdctSize = frame_size/mode->nbShortMdcts;
+ res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
+
+ mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
+ if (mode->eBands==NULL)
+ goto failure;
+
+ mode->effEBands = mode->nbEBands;
+ while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
+ mode->effEBands--;
+
+ /* Overlap must be divisible by 4 */
+ mode->overlap = ((mode->shortMdctSize>>2)<<2);
+
+ compute_allocation_table(mode);
+ if (mode->allocVectors==NULL)
+ goto failure;
+
+ window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16));
+ if (window==NULL)
+ goto failure;
+
+#ifndef FIXED_POINT
+ for (i=0;i<mode->overlap;i++)
+ window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
+#else
+ for (i=0;i<mode->overlap;i++)
+ window[i] = MIN32(32767,floor(.5+32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap))));
+#endif
+ mode->window = window;
+
+ logN = (opus_int16*)opus_alloc(mode->nbEBands*sizeof(opus_int16));
+ if (logN==NULL)
+ goto failure;
+
+ for (i=0;i<mode->nbEBands;i++)
+ logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
+ mode->logN = logN;
+
+ compute_pulse_cache(mode, mode->maxLM);
+
+ if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts,
+ mode->maxLM) == 0)
+ goto failure;
+
+ if (error)
+ *error = OPUS_OK;
+
+ return mode;
+failure:
+ if (error)
+ *error = OPUS_ALLOC_FAIL;
+ if (mode!=NULL)
+ opus_custom_mode_destroy(mode);
+ return NULL;
+#endif /* !CUSTOM_MODES */
+}
+
+#ifdef CUSTOM_MODES
+void opus_custom_mode_destroy(CELTMode *mode)
+{
+ if (mode == NULL)
+ return;
+#ifndef CUSTOM_MODES_ONLY
+ {
+ int i;
+ for (i=0;i<TOTAL_MODES;i++)
+ {
+ if (mode == static_mode_list[i])
+ {
+ return;
+ }
+ }
+ }
+#endif /* CUSTOM_MODES_ONLY */
+ opus_free((opus_int16*)mode->eBands);
+ opus_free((opus_int16*)mode->allocVectors);
+
+ opus_free((opus_val16*)mode->window);
+ opus_free((opus_int16*)mode->logN);
+
+ opus_free((opus_int16*)mode->cache.index);
+ opus_free((unsigned char*)mode->cache.bits);
+ opus_free((unsigned char*)mode->cache.caps);
+ clt_mdct_clear(&mode->mdct);
+
+ opus_free((CELTMode *)mode);
+}
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/modes.h b/lib/rbcodec/codecs/libopus/celt/modes.h
new file mode 100644
index 0000000000..c8340f9875
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/modes.h
@@ -0,0 +1,83 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2008 Gregory Maxwell
+ Written by Jean-Marc Valin and Gregory Maxwell */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 MODES_H
+#define MODES_H
+
+#include "opus_types.h"
+#include "celt.h"
+#include "arch.h"
+#include "mdct.h"
+#include "entenc.h"
+#include "entdec.h"
+
+#define MAX_PERIOD 1024
+
+#ifndef OVERLAP
+#define OVERLAP(mode) ((mode)->overlap)
+#endif
+
+#ifndef FRAMESIZE
+#define FRAMESIZE(mode) ((mode)->mdctSize)
+#endif
+
+typedef struct {
+ int size;
+ const opus_int16 *index;
+ const unsigned char *bits;
+ const unsigned char *caps;
+} PulseCache;
+
+/** Mode definition (opaque)
+ @brief Mode definition
+ */
+struct OpusCustomMode {
+ opus_int32 Fs;
+ int overlap;
+
+ int nbEBands;
+ int effEBands;
+ opus_val16 preemph[4];
+ const opus_int16 *eBands; /**< Definition for each "pseudo-critical band" */
+
+ int maxLM;
+ int nbShortMdcts;
+ int shortMdctSize;
+
+ int nbAllocVectors; /**< Number of lines in the matrix below */
+ const unsigned char *allocVectors; /**< Number of bits in each band for several rates */
+ const opus_int16 *logN;
+
+ const opus_val16 *window;
+ mdct_lookup mdct;
+ PulseCache cache;
+};
+
+
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/os_support.h b/lib/rbcodec/codecs/libopus/celt/os_support.h
new file mode 100644
index 0000000000..2484f0b2f7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/os_support.h
@@ -0,0 +1,89 @@
+/* Copyright (C) 2007 Jean-Marc Valin
+
+ File: os_support.h
+ This is the (tiny) OS abstraction layer. Aside from math.h, this is the
+ only place where system headers are allowed.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. 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.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 OS_SUPPORT_H
+#define OS_SUPPORT_H
+
+#ifdef CUSTOM_SUPPORT
+# include "custom_support.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */
+#ifndef OVERRIDE_OPUS_ALLOC
+static inline void *opus_alloc (size_t size)
+{
+ return malloc(size);
+}
+#endif
+
+/** Same as celt_alloc(), except that the area is only needed inside a CELT call (might cause problem with wideband though) */
+#ifndef OVERRIDE_OPUS_ALLOC_SCRATCH
+static inline void *opus_alloc_scratch (size_t size)
+{
+ /* Scratch space doesn't need to be cleared */
+ return opus_alloc(size);
+}
+#endif
+
+/** Opus wrapper for free(). To do your own dynamic allocation, all you need to do is replace this function and opus_alloc */
+#ifndef OVERRIDE_OPUS_FREE
+static inline void opus_free (void *ptr)
+{
+ free(ptr);
+}
+#endif
+
+/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking */
+#ifndef OVERRIDE_OPUS_COPY
+#define OPUS_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
+#endif
+
+/** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term
+ provides compile-time type checking */
+#ifndef OVERRIDE_OPUS_MOVE
+#define OPUS_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
+#endif
+
+/** Set n elements of dst to zero, starting at address s */
+#ifndef OVERRIDE_OPUS_CLEAR
+#define OPUS_CLEAR(dst, n) (memset((dst), 0, (n)*sizeof(*(dst))))
+#endif
+
+/*#ifdef __GNUC__
+#pragma GCC poison printf sprintf
+#pragma GCC poison malloc free realloc calloc
+#endif*/
+
+#endif /* OS_SUPPORT_H */
+
diff --git a/lib/rbcodec/codecs/libopus/celt/pitch.c b/lib/rbcodec/codecs/libopus/celt/pitch.c
new file mode 100644
index 0000000000..3bad8e46a7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/pitch.c
@@ -0,0 +1,410 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/**
+ @file pitch.c
+ @brief Pitch analysis
+ */
+
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include "pitch.h"
+#include "os_support.h"
+#include "modes.h"
+#include "stack_alloc.h"
+#include "mathops.h"
+#include "celt_lpc.h"
+
+static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len,
+ int max_pitch, int *best_pitch
+#ifdef FIXED_POINT
+ , int yshift, opus_val32 maxcorr
+#endif
+ )
+{
+ int i, j;
+ opus_val32 Syy=1;
+ opus_val16 best_num[2];
+ opus_val32 best_den[2];
+#ifdef FIXED_POINT
+ int xshift;
+
+ xshift = celt_ilog2(maxcorr)-14;
+#endif
+
+ best_num[0] = -1;
+ best_num[1] = -1;
+ best_den[0] = 0;
+ best_den[1] = 0;
+ best_pitch[0] = 0;
+ best_pitch[1] = 1;
+ for (j=0;j<len;j++)
+ Syy = ADD32(Syy, SHR32(MULT16_16(y[j],y[j]), yshift));
+ for (i=0;i<max_pitch;i++)
+ {
+ if (xcorr[i]>0)
+ {
+ opus_val16 num;
+ opus_val32 xcorr16;
+ xcorr16 = EXTRACT16(VSHR32(xcorr[i], xshift));
+#ifndef FIXED_POINT
+ /* Considering the range of xcorr16, this should avoid both underflows
+ and overflows (inf) when squaring xcorr16 */
+ xcorr16 *= 1e-12;
+#endif
+ num = MULT16_16_Q15(xcorr16,xcorr16);
+ if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy))
+ {
+ if (MULT16_32_Q15(num,best_den[0]) > MULT16_32_Q15(best_num[0],Syy))
+ {
+ best_num[1] = best_num[0];
+ best_den[1] = best_den[0];
+ best_pitch[1] = best_pitch[0];
+ best_num[0] = num;
+ best_den[0] = Syy;
+ best_pitch[0] = i;
+ } else {
+ best_num[1] = num;
+ best_den[1] = Syy;
+ best_pitch[1] = i;
+ }
+ }
+ }
+ Syy += SHR32(MULT16_16(y[i+len],y[i+len]),yshift) - SHR32(MULT16_16(y[i],y[i]),yshift);
+ Syy = MAX32(1, Syy);
+ }
+}
+
+void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,
+ int len, int C)
+{
+ int i;
+ opus_val32 ac[5];
+ opus_val16 tmp=Q15ONE;
+ opus_val16 lpc[4], mem[4]={0,0,0,0};
+#ifdef FIXED_POINT
+ int shift;
+ opus_val32 maxabs = celt_maxabs32(x[0], len);
+ if (C==2)
+ {
+ opus_val32 maxabs_1 = celt_maxabs32(x[1], len);
+ maxabs = MAX32(maxabs, maxabs_1);
+ }
+ if (maxabs<1)
+ maxabs=1;
+ shift = celt_ilog2(maxabs)-10;
+ if (shift<0)
+ shift=0;
+ if (C==2)
+ shift++;
+#endif
+ for (i=1;i<len>>1;i++)
+ x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift);
+ x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift);
+ if (C==2)
+ {
+ for (i=1;i<len>>1;i++)
+ x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift);
+ x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift);
+ }
+
+ _celt_autocorr(x_lp, ac, NULL, 0,
+ 4, len>>1);
+
+ /* Noise floor -40 dB */
+#ifdef FIXED_POINT
+ ac[0] += SHR32(ac[0],13);
+#else
+ ac[0] *= 1.0001f;
+#endif
+ /* Lag windowing */
+ for (i=1;i<=4;i++)
+ {
+ /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
+#ifdef FIXED_POINT
+ ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
+#else
+ ac[i] -= ac[i]*(.008f*i)*(.008f*i);
+#endif
+ }
+
+ _celt_lpc(lpc, ac, 4);
+ for (i=0;i<4;i++)
+ {
+ tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp);
+ lpc[i] = MULT16_16_Q15(lpc[i], tmp);
+ }
+ celt_fir(x_lp, lpc, x_lp, len>>1, 4, mem);
+
+ mem[0]=0;
+ lpc[0]=QCONST16(.8f,12);
+ celt_fir(x_lp, lpc, x_lp, len>>1, 1, mem);
+
+}
+
+void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,
+ int len, int max_pitch, int *pitch)
+{
+ int i, j;
+ int lag;
+ int best_pitch[2]={0,0};
+ VARDECL(opus_val16, x_lp4);
+ VARDECL(opus_val16, y_lp4);
+ VARDECL(opus_val32, xcorr);
+#ifdef FIXED_POINT
+ opus_val32 maxcorr=1;
+ opus_val16 xmax, ymax;
+ int shift=0;
+#endif
+ int offset;
+
+ SAVE_STACK;
+
+ celt_assert(len>0);
+ celt_assert(max_pitch>0);
+ lag = len+max_pitch;
+
+ ALLOC(x_lp4, len>>2, opus_val16);
+ ALLOC(y_lp4, lag>>2, opus_val16);
+ ALLOC(xcorr, max_pitch>>1, opus_val32);
+
+ /* Downsample by 2 again */
+ for (j=0;j<len>>2;j++)
+ x_lp4[j] = x_lp[2*j];
+ for (j=0;j<lag>>2;j++)
+ y_lp4[j] = y[2*j];
+
+#ifdef FIXED_POINT
+ xmax = celt_maxabs16(x_lp4, len>>2);
+ ymax = celt_maxabs16(y_lp4, lag>>2);
+ shift = celt_ilog2(MAX16(1, MAX16(xmax, ymax)))-11;
+ if (shift>0)
+ {
+ for (j=0;j<len>>2;j++)
+ x_lp4[j] = SHR16(x_lp4[j], shift);
+ for (j=0;j<lag>>2;j++)
+ y_lp4[j] = SHR16(y_lp4[j], shift);
+ /* Use double the shift for a MAC */
+ shift *= 2;
+ } else {
+ shift = 0;
+ }
+#endif
+
+ /* Coarse search with 4x decimation */
+
+ for (i=0;i<max_pitch>>2;i++)
+ {
+ opus_val32 sum = 0;
+ for (j=0;j<len>>2;j++)
+ sum = MAC16_16(sum, x_lp4[j],y_lp4[i+j]);
+ xcorr[i] = MAX32(-1, sum);
+#ifdef FIXED_POINT
+ maxcorr = MAX32(maxcorr, sum);
+#endif
+ }
+ find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch
+#ifdef FIXED_POINT
+ , 0, maxcorr
+#endif
+ );
+
+ /* Finer search with 2x decimation */
+#ifdef FIXED_POINT
+ maxcorr=1;
+#endif
+ for (i=0;i<max_pitch>>1;i++)
+ {
+ opus_val32 sum=0;
+ xcorr[i] = 0;
+ if (abs(i-2*best_pitch[0])>2 && abs(i-2*best_pitch[1])>2)
+ continue;
+ for (j=0;j<len>>1;j++)
+ sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift);
+ xcorr[i] = MAX32(-1, sum);
+#ifdef FIXED_POINT
+ maxcorr = MAX32(maxcorr, sum);
+#endif
+ }
+ find_best_pitch(xcorr, y, len>>1, max_pitch>>1, best_pitch
+#ifdef FIXED_POINT
+ , shift+1, maxcorr
+#endif
+ );
+
+ /* Refine by pseudo-interpolation */
+ if (best_pitch[0]>0 && best_pitch[0]<(max_pitch>>1)-1)
+ {
+ opus_val32 a, b, c;
+ a = xcorr[best_pitch[0]-1];
+ b = xcorr[best_pitch[0]];
+ c = xcorr[best_pitch[0]+1];
+ if ((c-a) > MULT16_32_Q15(QCONST16(.7f,15),b-a))
+ offset = 1;
+ else if ((a-c) > MULT16_32_Q15(QCONST16(.7f,15),b-c))
+ offset = -1;
+ else
+ offset = 0;
+ } else {
+ offset = 0;
+ }
+ *pitch = 2*best_pitch[0]-offset;
+
+ RESTORE_STACK;
+}
+
+static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2};
+opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
+ int N, int *T0_, int prev_period, opus_val16 prev_gain)
+{
+ int k, i, T, T0;
+ opus_val16 g, g0;
+ opus_val16 pg;
+ opus_val32 xy,xx,yy;
+ opus_val32 xcorr[3];
+ opus_val32 best_xy, best_yy;
+ int offset;
+ int minperiod0;
+
+ minperiod0 = minperiod;
+ maxperiod /= 2;
+ minperiod /= 2;
+ *T0_ /= 2;
+ prev_period /= 2;
+ N /= 2;
+ x += maxperiod;
+ if (*T0_>=maxperiod)
+ *T0_=maxperiod-1;
+
+ T = T0 = *T0_;
+ xx=xy=yy=0;
+ for (i=0;i<N;i++)
+ {
+ xy = MAC16_16(xy, x[i], x[i-T0]);
+ xx = MAC16_16(xx, x[i], x[i]);
+ yy = MAC16_16(yy, x[i-T0],x[i-T0]);
+ }
+ best_xy = xy;
+ best_yy = yy;
+#ifdef FIXED_POINT
+ {
+ opus_val32 x2y2;
+ int sh, t;
+ x2y2 = 1+HALF32(MULT32_32_Q31(xx,yy));
+ sh = celt_ilog2(x2y2)>>1;
+ t = VSHR32(x2y2, 2*(sh-7));
+ g = g0 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
+ }
+#else
+ g = g0 = xy/celt_sqrt(1+xx*yy);
+#endif
+ /* Look for any pitch at T/k */
+ for (k=2;k<=15;k++)
+ {
+ int T1, T1b;
+ opus_val16 g1;
+ opus_val16 cont=0;
+ T1 = (2*T0+k)/(2*k);
+ if (T1 < minperiod)
+ break;
+ /* Look for another strong correlation at T1b */
+ if (k==2)
+ {
+ if (T1+T0>maxperiod)
+ T1b = T0;
+ else
+ T1b = T0+T1;
+ } else
+ {
+ T1b = (2*second_check[k]*T0+k)/(2*k);
+ }
+ xy=yy=0;
+ for (i=0;i<N;i++)
+ {
+ xy = MAC16_16(xy, x[i], x[i-T1]);
+ yy = MAC16_16(yy, x[i-T1], x[i-T1]);
+
+ xy = MAC16_16(xy, x[i], x[i-T1b]);
+ yy = MAC16_16(yy, x[i-T1b], x[i-T1b]);
+ }
+#ifdef FIXED_POINT
+ {
+ opus_val32 x2y2;
+ int sh, t;
+ x2y2 = 1+MULT32_32_Q31(xx,yy);
+ sh = celt_ilog2(x2y2)>>1;
+ t = VSHR32(x2y2, 2*(sh-7));
+ g1 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
+ }
+#else
+ g1 = xy/celt_sqrt(1+2.f*xx*1.f*yy);
+#endif
+ if (abs(T1-prev_period)<=1)
+ cont = prev_gain;
+ else if (abs(T1-prev_period)<=2 && 5*k*k < T0)
+ cont = HALF32(prev_gain);
+ else
+ cont = 0;
+ if (g1 > QCONST16(.3f,15) + MULT16_16_Q15(QCONST16(.4f,15),g0)-cont)
+ {
+ best_xy = xy;
+ best_yy = yy;
+ T = T1;
+ g = g1;
+ }
+ }
+ best_xy = MAX32(0, best_xy);
+ if (best_yy <= best_xy)
+ pg = Q15ONE;
+ else
+ pg = SHR32(frac_div32(best_xy,best_yy+1),16);
+
+ for (k=0;k<3;k++)
+ {
+ int T1 = T+k-1;
+ xy = 0;
+ for (i=0;i<N;i++)
+ xy = MAC16_16(xy, x[i], x[i-T1]);
+ xcorr[k] = xy;
+ }
+ if ((xcorr[2]-xcorr[0]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[0]))
+ offset = 1;
+ else if ((xcorr[0]-xcorr[2]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[2]))
+ offset = -1;
+ else
+ offset = 0;
+ if (pg > g)
+ pg = g;
+ *T0_ = 2*T+offset;
+
+ if (*T0_<minperiod0)
+ *T0_=minperiod0;
+ return pg;
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/pitch.h b/lib/rbcodec/codecs/libopus/celt/pitch.h
new file mode 100644
index 0000000000..2757071a6f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/pitch.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/**
+ @file pitch.h
+ @brief Pitch analysis
+ */
+
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 PITCH_H
+#define PITCH_H
+
+#include "modes.h"
+
+void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,
+ int len, int C);
+
+void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,
+ int len, int max_pitch, int *pitch);
+
+opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
+ int N, int *T0, int prev_period, opus_val16 prev_gain);
+
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/quant_bands.c b/lib/rbcodec/codecs/libopus/celt/quant_bands.c
new file mode 100644
index 0000000000..5ad5311f84
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/quant_bands.c
@@ -0,0 +1,567 @@
+/* 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include "quant_bands.h"
+#include "laplace.h"
+#include <math.h>
+#include "os_support.h"
+#include "arch.h"
+#include "mathops.h"
+#include "stack_alloc.h"
+#include "rate.h"
+
+#ifdef FIXED_POINT
+/* Mean energy in each band quantized in Q6 */
+static const signed char eMeans[25] = {
+ 103,100, 92, 85, 81,
+ 77, 72, 70, 78, 75,
+ 73, 71, 78, 74, 69,
+ 72, 70, 74, 76, 71,
+ 60, 60, 60, 60, 60
+};
+#else
+/* Mean energy in each band quantized in Q6 and converted back to float */
+static const opus_val16 eMeans[25] = {
+ 6.437500f, 6.250000f, 5.750000f, 5.312500f, 5.062500f,
+ 4.812500f, 4.500000f, 4.375000f, 4.875000f, 4.687500f,
+ 4.562500f, 4.437500f, 4.875000f, 4.625000f, 4.312500f,
+ 4.500000f, 4.375000f, 4.625000f, 4.750000f, 4.437500f,
+ 3.750000f, 3.750000f, 3.750000f, 3.750000f, 3.750000f
+};
+#endif
+/* prediction coefficients: 0.9, 0.8, 0.65, 0.5 */
+#ifdef FIXED_POINT
+static const opus_val16 pred_coef[4] = {29440, 26112, 21248, 16384};
+static const opus_val16 beta_coef[4] = {30147, 22282, 12124, 6554};
+static const opus_val16 beta_intra = 4915;
+#else
+static const opus_val16 pred_coef[4] = {29440/32768., 26112/32768., 21248/32768., 16384/32768.};
+static const opus_val16 beta_coef[4] = {30147/32768., 22282/32768., 12124/32768., 6554/32768.};
+static const opus_val16 beta_intra = 4915/32768.;
+#endif
+
+/*Parameters of the Laplace-like probability models used for the coarse energy.
+ There is one pair of parameters for each frame size, prediction type
+ (inter/intra), and band number.
+ The first number of each pair is the probability of 0, and the second is the
+ decay rate, both in Q8 precision.*/
+static const unsigned char e_prob_model[4][2][42] = {
+ /*120 sample frames.*/
+ {
+ /*Inter*/
+ {
+ 72, 127, 65, 129, 66, 128, 65, 128, 64, 128, 62, 128, 64, 128,
+ 64, 128, 92, 78, 92, 79, 92, 78, 90, 79, 116, 41, 115, 40,
+ 114, 40, 132, 26, 132, 26, 145, 17, 161, 12, 176, 10, 177, 11
+ },
+ /*Intra*/
+ {
+ 24, 179, 48, 138, 54, 135, 54, 132, 53, 134, 56, 133, 55, 132,
+ 55, 132, 61, 114, 70, 96, 74, 88, 75, 88, 87, 74, 89, 66,
+ 91, 67, 100, 59, 108, 50, 120, 40, 122, 37, 97, 43, 78, 50
+ }
+ },
+ /*240 sample frames.*/
+ {
+ /*Inter*/
+ {
+ 83, 78, 84, 81, 88, 75, 86, 74, 87, 71, 90, 73, 93, 74,
+ 93, 74, 109, 40, 114, 36, 117, 34, 117, 34, 143, 17, 145, 18,
+ 146, 19, 162, 12, 165, 10, 178, 7, 189, 6, 190, 8, 177, 9
+ },
+ /*Intra*/
+ {
+ 23, 178, 54, 115, 63, 102, 66, 98, 69, 99, 74, 89, 71, 91,
+ 73, 91, 78, 89, 86, 80, 92, 66, 93, 64, 102, 59, 103, 60,
+ 104, 60, 117, 52, 123, 44, 138, 35, 133, 31, 97, 38, 77, 45
+ }
+ },
+ /*480 sample frames.*/
+ {
+ /*Inter*/
+ {
+ 61, 90, 93, 60, 105, 42, 107, 41, 110, 45, 116, 38, 113, 38,
+ 112, 38, 124, 26, 132, 27, 136, 19, 140, 20, 155, 14, 159, 16,
+ 158, 18, 170, 13, 177, 10, 187, 8, 192, 6, 175, 9, 159, 10
+ },
+ /*Intra*/
+ {
+ 21, 178, 59, 110, 71, 86, 75, 85, 84, 83, 91, 66, 88, 73,
+ 87, 72, 92, 75, 98, 72, 105, 58, 107, 54, 115, 52, 114, 55,
+ 112, 56, 129, 51, 132, 40, 150, 33, 140, 29, 98, 35, 77, 42
+ }
+ },
+ /*960 sample frames.*/
+ {
+ /*Inter*/
+ {
+ 42, 121, 96, 66, 108, 43, 111, 40, 117, 44, 123, 32, 120, 36,
+ 119, 33, 127, 33, 134, 34, 139, 21, 147, 23, 152, 20, 158, 25,
+ 154, 26, 166, 21, 173, 16, 184, 13, 184, 10, 150, 13, 139, 15
+ },
+ /*Intra*/
+ {
+ 22, 178, 63, 114, 74, 82, 84, 83, 92, 82, 103, 62, 96, 72,
+ 96, 67, 101, 73, 107, 72, 113, 55, 118, 52, 125, 52, 118, 52,
+ 117, 55, 135, 49, 137, 39, 157, 32, 145, 29, 97, 33, 77, 40
+ }
+ }
+};
+
+static const unsigned char small_energy_icdf[3]={2,1,0};
+
+static opus_val32 loss_distortion(const opus_val16 *eBands, opus_val16 *oldEBands, int start, int end, int len, int C)
+{
+ int c, i;
+ opus_val32 dist = 0;
+ c=0; do {
+ for (i=start;i<end;i++)
+ {
+ opus_val16 d = SUB16(SHR16(eBands[i+c*len], 3), SHR16(oldEBands[i+c*len], 3));
+ dist = MAC16_16(dist, d,d);
+ }
+ } while (++c<C);
+ return MIN32(200,SHR32(dist,2*DB_SHIFT-6));
+}
+
+static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
+ const opus_val16 *eBands, opus_val16 *oldEBands,
+ opus_int32 budget, opus_int32 tell,
+ const unsigned char *prob_model, opus_val16 *error, ec_enc *enc,
+ int C, int LM, int intra, opus_val16 max_decay)
+{
+ int i, c;
+ int badness = 0;
+ opus_val32 prev[2] = {0,0};
+ opus_val16 coef;
+ opus_val16 beta;
+
+ if (tell+3 <= budget)
+ ec_enc_bit_logp(enc, intra, 3);
+ if (intra)
+ {
+ coef = 0;
+ beta = beta_intra;
+ } else {
+ beta = beta_coef[LM];
+ coef = pred_coef[LM];
+ }
+
+ /* Encode at a fixed coarse resolution */
+ for (i=start;i<end;i++)
+ {
+ c=0;
+ do {
+ int bits_left;
+ int qi, qi0;
+ opus_val32 q;
+ opus_val16 x;
+ opus_val32 f, tmp;
+ opus_val16 oldE;
+ opus_val16 decay_bound;
+ x = eBands[i+c*m->nbEBands];
+ oldE = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);
+#ifdef FIXED_POINT
+ f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c];
+ /* Rounding to nearest integer here is really important! */
+ qi = (f+QCONST32(.5f,DB_SHIFT+7))>>(DB_SHIFT+7);
+ decay_bound = EXTRACT16(MAX32(-QCONST16(28.f,DB_SHIFT),
+ SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay)));
+#else
+ f = x-coef*oldE-prev[c];
+ /* Rounding to nearest integer here is really important! */
+ qi = (int)floor(.5f+f);
+ decay_bound = MAX16(-QCONST16(28.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]) - max_decay;
+#endif
+ /* Prevent the energy from going down too quickly (e.g. for bands
+ that have just one bin) */
+ if (qi < 0 && x < decay_bound)
+ {
+ qi += (int)SHR16(SUB16(decay_bound,x), DB_SHIFT);
+ if (qi > 0)
+ qi = 0;
+ }
+ qi0 = qi;
+ /* If we don't have enough bits to encode all the energy, just assume
+ something safe. */
+ tell = ec_tell(enc);
+ bits_left = budget-tell-3*C*(end-i);
+ if (i!=start && bits_left < 30)
+ {
+ if (bits_left < 24)
+ qi = IMIN(1, qi);
+ if (bits_left < 16)
+ qi = IMAX(-1, qi);
+ }
+ if (budget-tell >= 15)
+ {
+ int pi;
+ pi = 2*IMIN(i,20);
+ ec_laplace_encode(enc, &qi,
+ prob_model[pi]<<7, prob_model[pi+1]<<6);
+ }
+ else if(budget-tell >= 2)
+ {
+ qi = IMAX(-1, IMIN(qi, 1));
+ ec_enc_icdf(enc, 2*qi^-(qi<0), small_energy_icdf, 2);
+ }
+ else if(budget-tell >= 1)
+ {
+ qi = IMIN(0, qi);
+ ec_enc_bit_logp(enc, -qi, 1);
+ }
+ else
+ qi = -1;
+ error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT);
+ badness += abs(qi0-qi);
+ q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);
+
+ tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(q,7);
+#ifdef FIXED_POINT
+ tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);
+#endif
+ oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);
+ prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
+ } while (++c < C);
+ }
+ return badness;
+}
+
+void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
+ const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,
+ opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes,
+ int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate)
+{
+ int intra;
+ opus_val16 max_decay;
+ VARDECL(opus_val16, oldEBands_intra);
+ VARDECL(opus_val16, error_intra);
+ ec_enc enc_start_state;
+ opus_uint32 tell;
+ int badness1=0;
+ opus_int32 intra_bias;
+ opus_val32 new_distortion;
+ SAVE_STACK;
+
+ intra = force_intra || (!two_pass && *delayedIntra>2*C*(end-start) && nbAvailableBytes > (end-start)*C);
+ intra_bias = (opus_int32)((budget**delayedIntra*loss_rate)/(C*512));
+ new_distortion = loss_distortion(eBands, oldEBands, start, effEnd, m->nbEBands, C);
+
+ tell = ec_tell(enc);
+ if (tell+3 > budget)
+ two_pass = intra = 0;
+
+ /* Encode the global flags using a simple probability model
+ (first symbols in the stream) */
+
+#ifdef FIXED_POINT
+ max_decay = MIN32(QCONST16(16.f,DB_SHIFT), SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3));
+#else
+ max_decay = MIN32(16.f, .125f*nbAvailableBytes);
+#endif
+
+ enc_start_state = *enc;
+
+ ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16);
+ ALLOC(error_intra, C*m->nbEBands, opus_val16);
+ OPUS_COPY(oldEBands_intra, oldEBands, C*m->nbEBands);
+
+ if (two_pass || intra)
+ {
+ badness1 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands_intra, budget,
+ tell, e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay);
+ }
+
+ if (!intra)
+ {
+ unsigned char *intra_buf;
+ ec_enc enc_intra_state;
+ opus_int32 tell_intra;
+ opus_uint32 nstart_bytes;
+ opus_uint32 nintra_bytes;
+ int badness2;
+ VARDECL(unsigned char, intra_bits);
+
+ tell_intra = ec_tell_frac(enc);
+
+ enc_intra_state = *enc;
+
+ nstart_bytes = ec_range_bytes(&enc_start_state);
+ nintra_bytes = ec_range_bytes(&enc_intra_state);
+ intra_buf = ec_get_buffer(&enc_intra_state) + nstart_bytes;
+ ALLOC(intra_bits, nintra_bytes-nstart_bytes, unsigned char);
+ /* Copy bits from intra bit-stream */
+ OPUS_COPY(intra_bits, intra_buf, nintra_bytes - nstart_bytes);
+
+ *enc = enc_start_state;
+
+ badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget,
+ tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay);
+
+ if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ((opus_int32)ec_tell_frac(enc))+intra_bias > tell_intra)))
+ {
+ *enc = enc_intra_state;
+ /* Copy intra bits to bit-stream */
+ OPUS_COPY(intra_buf, intra_bits, nintra_bytes - nstart_bytes);
+ OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands);
+ OPUS_COPY(error, error_intra, C*m->nbEBands);
+ intra = 1;
+ }
+ } else {
+ OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands);
+ OPUS_COPY(error, error_intra, C*m->nbEBands);
+ }
+
+ if (intra)
+ *delayedIntra = new_distortion;
+ else
+ *delayedIntra = ADD32(MULT16_32_Q15(MULT16_16_Q15(pred_coef[LM], pred_coef[LM]),*delayedIntra),
+ new_distortion);
+
+ RESTORE_STACK;
+}
+
+void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C)
+{
+ int i, c;
+
+ /* Encode finer resolution */
+ for (i=start;i<end;i++)
+ {
+ opus_int16 frac = 1<<fine_quant[i];
+ if (fine_quant[i] <= 0)
+ continue;
+ c=0;
+ do {
+ int q2;
+ opus_val16 offset;
+#ifdef FIXED_POINT
+ /* Has to be without rounding */
+ q2 = (error[i+c*m->nbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]);
+#else
+ q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac);
+#endif
+ if (q2 > frac-1)
+ q2 = frac-1;
+ if (q2<0)
+ q2 = 0;
+ ec_enc_bits(enc, q2, fine_quant[i]);
+#ifdef FIXED_POINT
+ offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
+#else
+ offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
+#endif
+ oldEBands[i+c*m->nbEBands] += offset;
+ error[i+c*m->nbEBands] -= offset;
+ /*printf ("%f ", error[i] - offset);*/
+ } while (++c < C);
+ }
+}
+
+void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C)
+{
+ int i, prio, c;
+
+ /* Use up the remaining bits */
+ for (prio=0;prio<2;prio++)
+ {
+ for (i=start;i<end && bits_left>=C ;i++)
+ {
+ if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio)
+ continue;
+ c=0;
+ do {
+ int q2;
+ opus_val16 offset;
+ q2 = error[i+c*m->nbEBands]<0 ? 0 : 1;
+ ec_enc_bits(enc, q2, 1);
+#ifdef FIXED_POINT
+ offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1);
+#else
+ offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
+#endif
+ oldEBands[i+c*m->nbEBands] += offset;
+ bits_left--;
+ } while (++c < C);
+ }
+ }
+}
+
+void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM)
+{
+ const unsigned char *prob_model = e_prob_model[LM][intra];
+ int i, c;
+ opus_val32 prev[2] = {0, 0};
+ opus_val16 coef;
+ opus_val16 beta;
+ opus_int32 budget;
+ opus_int32 tell;
+
+ if (intra)
+ {
+ coef = 0;
+ beta = beta_intra;
+ } else {
+ beta = beta_coef[LM];
+ coef = pred_coef[LM];
+ }
+
+ budget = dec->storage*8;
+
+ /* Decode at a fixed coarse resolution */
+ for (i=start;i<end;i++)
+ {
+ c=0;
+ do {
+ int qi;
+ opus_val32 q;
+ opus_val32 tmp;
+ /* It would be better to express this invariant as a
+ test on C at function entry, but that isn't enough
+ to make the static analyzer happy. */
+ celt_assert(c<2);
+ tell = ec_tell(dec);
+ if(budget-tell>=15)
+ {
+ int pi;
+ pi = 2*IMIN(i,20);
+ qi = ec_laplace_decode(dec,
+ prob_model[pi]<<7, prob_model[pi+1]<<6);
+ }
+ else if(budget-tell>=2)
+ {
+ qi = ec_dec_icdf(dec, small_energy_icdf, 2);
+ qi = (qi>>1)^-(qi&1);
+ }
+ else if(budget-tell>=1)
+ {
+ qi = -ec_dec_bit_logp(dec, 1);
+ }
+ else
+ qi = -1;
+ q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);
+
+ oldEBands[i+c*m->nbEBands] = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);
+ tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(q,7);
+#ifdef FIXED_POINT
+ tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);
+#endif
+ oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);
+ prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
+ } while (++c < C);
+ }
+}
+
+void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C)
+{
+ int i, c;
+ /* Decode finer resolution */
+ for (i=start;i<end;i++)
+ {
+ if (fine_quant[i] <= 0)
+ continue;
+ c=0;
+ do {
+ int q2;
+ opus_val16 offset;
+ q2 = ec_dec_bits(dec, fine_quant[i]);
+#ifdef FIXED_POINT
+ offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
+#else
+ offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
+#endif
+ oldEBands[i+c*m->nbEBands] += offset;
+ } while (++c < C);
+ }
+}
+
+void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C)
+{
+ int i, prio, c;
+
+ /* Use up the remaining bits */
+ for (prio=0;prio<2;prio++)
+ {
+ for (i=start;i<end && bits_left>=C ;i++)
+ {
+ if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio)
+ continue;
+ c=0;
+ do {
+ int q2;
+ opus_val16 offset;
+ q2 = ec_dec_bits(dec, 1);
+#ifdef FIXED_POINT
+ offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1);
+#else
+ offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
+#endif
+ oldEBands[i+c*m->nbEBands] += offset;
+ bits_left--;
+ } while (++c < C);
+ }
+ }
+}
+
+void log2Amp(const CELTMode *m, int start, int end,
+ celt_ener *eBands, const opus_val16 *oldEBands, int C)
+{
+ int c, i;
+ c=0;
+ do {
+ for (i=0;i<start;i++)
+ eBands[i+c*m->nbEBands] = 0;
+ for (;i<end;i++)
+ {
+ opus_val16 lg = ADD16(oldEBands[i+c*m->nbEBands],
+ SHL16((opus_val16)eMeans[i],6));
+ eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4);
+ }
+ for (;i<m->nbEBands;i++)
+ eBands[i+c*m->nbEBands] = 0;
+ } while (++c < C);
+}
+
+void amp2Log2(const CELTMode *m, int effEnd, int end,
+ celt_ener *bandE, opus_val16 *bandLogE, int C)
+{
+ int c, i;
+ c=0;
+ do {
+ for (i=0;i<effEnd;i++)
+ bandLogE[i+c*m->nbEBands] =
+ celt_log2(SHL32(bandE[i+c*m->nbEBands],2))
+ - SHL16((opus_val16)eMeans[i],6);
+ for (i=effEnd;i<end;i++)
+ bandLogE[c*m->nbEBands+i] = -QCONST16(14.f,DB_SHIFT);
+ } while (++c < C);
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/quant_bands.h b/lib/rbcodec/codecs/libopus/celt/quant_bands.h
new file mode 100644
index 0000000000..bec2855cf0
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/quant_bands.h
@@ -0,0 +1,60 @@
+/* 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.
+
+ 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 COPYRIGHT OWNER
+ 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 QUANT_BANDS
+#define QUANT_BANDS
+
+#include "arch.h"
+#include "modes.h"
+#include "entenc.h"
+#include "entdec.h"
+#include "mathops.h"
+
+void amp2Log2(const CELTMode *m, int effEnd, int end,
+ celt_ener *bandE, opus_val16 *bandLogE, int C);
+
+void log2Amp(const CELTMode *m, int start, int end,
+ celt_ener *eBands, const opus_val16 *oldEBands, int C);
+
+void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
+ const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,
+ opus_val16 *error, ec_enc *enc, int C, int LM,
+ int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra,
+ int two_pass, int loss_rate);
+
+void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C);
+
+void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C);
+
+void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM);
+
+void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C);
+
+void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C);
+
+#endif /* QUANT_BANDS */
diff --git a/lib/rbcodec/codecs/libopus/celt/rate.c b/lib/rbcodec/codecs/libopus/celt/rate.c
new file mode 100644
index 0000000000..3b056d8dc7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/rate.c
@@ -0,0 +1,638 @@
+/* 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include <math.h>
+#include "modes.h"
+#include "cwrs.h"
+#include "arch.h"
+#include "os_support.h"
+
+#include "entcode.h"
+#include "rate.h"
+
+static const unsigned char LOG2_FRAC_TABLE[24]={
+ 0,
+ 8,13,
+ 16,19,21,23,
+ 24,26,27,28,29,30,31,32,
+ 32,33,34,34,35,36,36,37,37
+};
+
+#ifdef CUSTOM_MODES
+
+/*Determines if V(N,K) fits in a 32-bit unsigned integer.
+ N and K are themselves limited to 15 bits.*/
+static int fits_in32(int _n, int _k)
+{
+ static const opus_int16 maxN[15] = {
+ 32767, 32767, 32767, 1476, 283, 109, 60, 40,
+ 29, 24, 20, 18, 16, 14, 13};
+ static const opus_int16 maxK[15] = {
+ 32767, 32767, 32767, 32767, 1172, 238, 95, 53,
+ 36, 27, 22, 18, 16, 15, 13};
+ if (_n>=14)
+ {
+ if (_k>=14)
+ return 0;
+ else
+ return _n <= maxN[_k];
+ } else {
+ return _k <= maxK[_n];
+ }
+}
+
+void compute_pulse_cache(CELTMode *m, int LM)
+{
+ int C;
+ int i;
+ int j;
+ int curr=0;
+ int nbEntries=0;
+ int entryN[100], entryK[100], entryI[100];
+ const opus_int16 *eBands = m->eBands;
+ PulseCache *cache = &m->cache;
+ opus_int16 *cindex;
+ unsigned char *bits;
+ unsigned char *cap;
+
+ cindex = (opus_int16 *)opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2));
+ cache->index = cindex;
+
+ /* Scan for all unique band sizes */
+ for (i=0;i<=LM+1;i++)
+ {
+ for (j=0;j<m->nbEBands;j++)
+ {
+ int k;
+ int N = (eBands[j+1]-eBands[j])<<i>>1;
+ cindex[i*m->nbEBands+j] = -1;
+ /* Find other bands that have the same size */
+ for (k=0;k<=i;k++)
+ {
+ int n;
+ for (n=0;n<m->nbEBands && (k!=i || n<j);n++)
+ {
+ if (N == (eBands[n+1]-eBands[n])<<k>>1)
+ {
+ cindex[i*m->nbEBands+j] = cindex[k*m->nbEBands+n];
+ break;
+ }
+ }
+ }
+ if (cache->index[i*m->nbEBands+j] == -1 && N!=0)
+ {
+ int K;
+ entryN[nbEntries] = N;
+ K = 0;
+ while (fits_in32(N,get_pulses(K+1)) && K<MAX_PSEUDO)
+ K++;
+ entryK[nbEntries] = K;
+ cindex[i*m->nbEBands+j] = curr;
+ entryI[nbEntries] = curr;
+
+ curr += K+1;
+ nbEntries++;
+ }
+ }
+ }
+ bits = (unsigned char *)opus_alloc(sizeof(unsigned char)*curr);
+ cache->bits = bits;
+ cache->size = curr;
+ /* Compute the cache for all unique sizes */
+ for (i=0;i<nbEntries;i++)
+ {
+ unsigned char *ptr = bits+entryI[i];
+ opus_int16 tmp[MAX_PULSES+1];
+ get_required_bits(tmp, entryN[i], get_pulses(entryK[i]), BITRES);
+ for (j=1;j<=entryK[i];j++)
+ ptr[j] = tmp[get_pulses(j)]-1;
+ ptr[0] = entryK[i];
+ }
+
+ /* Compute the maximum rate for each band at which we'll reliably use as
+ many bits as we ask for. */
+ cache->caps = cap = (unsigned char *)opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands);
+ for (i=0;i<=LM;i++)
+ {
+ for (C=1;C<=2;C++)
+ {
+ for (j=0;j<m->nbEBands;j++)
+ {
+ int N0;
+ int max_bits;
+ N0 = m->eBands[j+1]-m->eBands[j];
+ /* N=1 bands only have a sign bit and fine bits. */
+ if (N0<<i == 1)
+ max_bits = C*(1+MAX_FINE_BITS)<<BITRES;
+ else
+ {
+ const unsigned char *pcache;
+ opus_int32 num;
+ opus_int32 den;
+ int LM0;
+ int N;
+ int offset;
+ int ndof;
+ int qb;
+ int k;
+ LM0 = 0;
+ /* Even-sized bands bigger than N=2 can be split one more time.
+ As of commit 44203907 all bands >1 are even, including custom modes.*/
+ if (N0 > 2)
+ {
+ N0>>=1;
+ LM0--;
+ }
+ /* N0=1 bands can't be split down to N<2. */
+ else if (N0 <= 1)
+ {
+ LM0=IMIN(i,1);
+ N0<<=LM0;
+ }
+ /* Compute the cost for the lowest-level PVQ of a fully split
+ band. */
+ pcache = bits + cindex[(LM0+1)*m->nbEBands+j];
+ max_bits = pcache[pcache[0]]+1;
+ /* Add in the cost of coding regular splits. */
+ N = N0;
+ for(k=0;k<i-LM0;k++){
+ max_bits <<= 1;
+ /* Offset the number of qtheta bits by log2(N)/2
+ + QTHETA_OFFSET compared to their "fair share" of
+ total/N */
+ offset = ((m->logN[j]+((LM0+k)<<BITRES))>>1)-QTHETA_OFFSET;
+ /* The number of qtheta bits we'll allocate if the remainder
+ is to be max_bits.
+ The average measured cost for theta is 0.89701 times qb,
+ approximated here as 459/512. */
+ num=459*(opus_int32)((2*N-1)*offset+max_bits);
+ den=((opus_int32)(2*N-1)<<9)-459;
+ qb = IMIN((num+(den>>1))/den, 57);
+ celt_assert(qb >= 0);
+ max_bits += qb;
+ N <<= 1;
+ }
+ /* Add in the cost of a stereo split, if necessary. */
+ if (C==2)
+ {
+ max_bits <<= 1;
+ offset = ((m->logN[j]+(i<<BITRES))>>1)-(N==2?QTHETA_OFFSET_TWOPHASE:QTHETA_OFFSET);
+ ndof = 2*N-1-(N==2);
+ /* The average measured cost for theta with the step PDF is
+ 0.95164 times qb, approximated here as 487/512. */
+ num = (N==2?512:487)*(opus_int32)(max_bits+ndof*offset);
+ den = ((opus_int32)ndof<<9)-(N==2?512:487);
+ qb = IMIN((num+(den>>1))/den, (N==2?64:61));
+ celt_assert(qb >= 0);
+ max_bits += qb;
+ }
+ /* Add the fine bits we'll use. */
+ /* Compensate for the extra DoF in stereo */
+ ndof = C*N + ((C==2 && N>2) ? 1 : 0);
+ /* Offset the number of fine bits by log2(N)/2 + FINE_OFFSET
+ compared to their "fair share" of total/N */
+ offset = ((m->logN[j] + (i<<BITRES))>>1)-FINE_OFFSET;
+ /* N=2 is the only point that doesn't match the curve */
+ if (N==2)
+ offset += 1<<BITRES>>2;
+ /* The number of fine bits we'll allocate if the remainder is
+ to be max_bits. */
+ num = max_bits+ndof*offset;
+ den = (ndof-1)<<BITRES;
+ qb = IMIN((num+(den>>1))/den, MAX_FINE_BITS);
+ celt_assert(qb >= 0);
+ max_bits += C*qb<<BITRES;
+ }
+ max_bits = (4*max_bits/(C*((m->eBands[j+1]-m->eBands[j])<<i)))-64;
+ celt_assert(max_bits >= 0);
+ celt_assert(max_bits < 256);
+ *cap++ = (unsigned char)max_bits;
+ }
+ }
+ }
+}
+
+#endif /* CUSTOM_MODES */
+
+#define ALLOC_STEPS 6
+
+static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start,
+ const int *bits1, const int *bits2, const int *thresh, const int *cap, opus_int32 total, opus_int32 *_balance,
+ int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits,
+ int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev)
+{
+ opus_int32 psum;
+ int lo, hi;
+ int i, j;
+ int logM;
+ int stereo;
+ int codedBands=-1;
+ int alloc_floor;
+ opus_int32 left, percoeff;
+ int done;
+ opus_int32 balance;
+ SAVE_STACK;
+
+ alloc_floor = C<<BITRES;
+ stereo = C>1;
+
+ logM = LM<<BITRES;
+ lo = 0;
+ hi = 1<<ALLOC_STEPS;
+ for (i=0;i<ALLOC_STEPS;i++)
+ {
+ int mid = (lo+hi)>>1;
+ psum = 0;
+ done = 0;
+ for (j=end;j-->start;)
+ {
+ int tmp = bits1[j] + (mid*(opus_int32)bits2[j]>>ALLOC_STEPS);
+ if (tmp >= thresh[j] || done)
+ {
+ done = 1;
+ /* Don't allocate more than we can actually use */
+ psum += IMIN(tmp, cap[j]);
+ } else {
+ if (tmp >= alloc_floor)
+ psum += alloc_floor;
+ }
+ }
+ if (psum > total)
+ hi = mid;
+ else
+ lo = mid;
+ }
+ psum = 0;
+ /*printf ("interp bisection gave %d\n", lo);*/
+ done = 0;
+ for (j=end;j-->start;)
+ {
+ int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS);
+ if (tmp < thresh[j] && !done)
+ {
+ if (tmp >= alloc_floor)
+ tmp = alloc_floor;
+ else
+ tmp = 0;
+ } else
+ done = 1;
+ /* Don't allocate more than we can actually use */
+ tmp = IMIN(tmp, cap[j]);
+ bits[j] = tmp;
+ psum += tmp;
+ }
+
+ /* Decide which bands to skip, working backwards from the end. */
+ for (codedBands=end;;codedBands--)
+ {
+ int band_width;
+ int band_bits;
+ int rem;
+ j = codedBands-1;
+ /* Never skip the first band, nor a band that has been boosted by
+ dynalloc.
+ In the first case, we'd be coding a bit to signal we're going to waste
+ all the other bits.
+ In the second case, we'd be coding a bit to redistribute all the bits
+ we just signaled should be cocentrated in this band. */
+ if (j<=skip_start)
+ {
+ /* Give the bit we reserved to end skipping back. */
+ total += skip_rsv;
+ break;
+ }
+ /*Figure out how many left-over bits we would be adding to this band.
+ This can include bits we've stolen back from higher, skipped bands.*/
+ left = total-psum;
+ percoeff = left/(m->eBands[codedBands]-m->eBands[start]);
+ left -= (m->eBands[codedBands]-m->eBands[start])*percoeff;
+ rem = IMAX(left-(m->eBands[j]-m->eBands[start]),0);
+ band_width = m->eBands[codedBands]-m->eBands[j];
+ band_bits = (int)(bits[j] + percoeff*band_width + rem);
+ /*Only code a skip decision if we're above the threshold for this band.
+ Otherwise it is force-skipped.
+ This ensures that we have enough bits to code the skip flag.*/
+ if (band_bits >= IMAX(thresh[j], alloc_floor+(1<<BITRES)))
+ {
+ if (encode)
+ {
+ /*This if() block is the only part of the allocation function that
+ is not a mandatory part of the bitstream: any bands we choose to
+ skip here must be explicitly signaled.*/
+ /*Choose a threshold with some hysteresis to keep bands from
+ fluctuating in and out.*/
+#ifdef FUZZING
+ if ((rand()&0x1) == 0)
+#else
+ if (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
+#endif
+ {
+ ec_enc_bit_logp(ec, 1, 1);
+ break;
+ }
+ ec_enc_bit_logp(ec, 0, 1);
+ } else if (ec_dec_bit_logp(ec, 1)) {
+ break;
+ }
+ /*We used a bit to skip this band.*/
+ psum += 1<<BITRES;
+ band_bits -= 1<<BITRES;
+ }
+ /*Reclaim the bits originally allocated to this band.*/
+ psum -= bits[j]+intensity_rsv;
+ if (intensity_rsv > 0)
+ intensity_rsv = LOG2_FRAC_TABLE[j-start];
+ psum += intensity_rsv;
+ if (band_bits >= alloc_floor)
+ {
+ /*If we have enough for a fine energy bit per channel, use it.*/
+ psum += alloc_floor;
+ bits[j] = alloc_floor;
+ } else {
+ /*Otherwise this band gets nothing at all.*/
+ bits[j] = 0;
+ }
+ }
+
+ celt_assert(codedBands > start);
+ /* Code the intensity and dual stereo parameters. */
+ if (intensity_rsv > 0)
+ {
+ if (encode)
+ {
+ *intensity = IMIN(*intensity, codedBands);
+ ec_enc_uint(ec, *intensity-start, codedBands+1-start);
+ }
+ else
+ *intensity = start+ec_dec_uint(ec, codedBands+1-start);
+ }
+ else
+ *intensity = 0;
+ if (*intensity <= start)
+ {
+ total += dual_stereo_rsv;
+ dual_stereo_rsv = 0;
+ }
+ if (dual_stereo_rsv > 0)
+ {
+ if (encode)
+ ec_enc_bit_logp(ec, *dual_stereo, 1);
+ else
+ *dual_stereo = ec_dec_bit_logp(ec, 1);
+ }
+ else
+ *dual_stereo = 0;
+
+ /* Allocate the remaining bits */
+ left = total-psum;
+ percoeff = left/(m->eBands[codedBands]-m->eBands[start]);
+ left -= (m->eBands[codedBands]-m->eBands[start])*percoeff;
+ for (j=start;j<codedBands;j++)
+ bits[j] += ((int)percoeff*(m->eBands[j+1]-m->eBands[j]));
+ for (j=start;j<codedBands;j++)
+ {
+ int tmp = (int)IMIN(left, m->eBands[j+1]-m->eBands[j]);
+ bits[j] += tmp;
+ left -= tmp;
+ }
+ /*for (j=0;j<end;j++)printf("%d ", bits[j]);printf("\n");*/
+
+ balance = 0;
+ for (j=start;j<codedBands;j++)
+ {
+ int N0, N, den;
+ int offset;
+ int NClogN;
+ opus_int32 excess, bit;
+
+ celt_assert(bits[j] >= 0);
+ N0 = m->eBands[j+1]-m->eBands[j];
+ N=N0<<LM;
+ bit = (opus_int32)bits[j]+balance;
+
+ if (N>1)
+ {
+ excess = MAX32(bit-cap[j],0);
+ bits[j] = bit-excess;
+
+ /* Compensate for the extra DoF in stereo */
+ den=(C*N+ ((C==2 && N>2 && !*dual_stereo && j<*intensity) ? 1 : 0));
+
+ NClogN = den*(m->logN[j] + logM);
+
+ /* Offset for the number of fine bits by log2(N)/2 + FINE_OFFSET
+ compared to their "fair share" of total/N */
+ offset = (NClogN>>1)-den*FINE_OFFSET;
+
+ /* N=2 is the only point that doesn't match the curve */
+ if (N==2)
+ offset += den<<BITRES>>2;
+
+ /* Changing the offset for allocating the second and third
+ fine energy bit */
+ if (bits[j] + offset < den*2<<BITRES)
+ offset += NClogN>>2;
+ else if (bits[j] + offset < den*3<<BITRES)
+ offset += NClogN>>3;
+
+ /* Divide with rounding */
+ ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1))) / (den<<BITRES));
+
+ /* Make sure not to bust */
+ if (C*ebits[j] > (bits[j]>>BITRES))
+ ebits[j] = bits[j] >> stereo >> BITRES;
+
+ /* More than that is useless because that's about as far as PVQ can go */
+ ebits[j] = IMIN(ebits[j], MAX_FINE_BITS);
+
+ /* If we rounded down or capped this band, make it a candidate for the
+ final fine energy pass */
+ fine_priority[j] = ebits[j]*(den<<BITRES) >= bits[j]+offset;
+
+ /* Remove the allocated fine bits; the rest are assigned to PVQ */
+ bits[j] -= C*ebits[j]<<BITRES;
+
+ } else {
+ /* For N=1, all bits go to fine energy except for a single sign bit */
+ excess = MAX32(0,bit-(C<<BITRES));
+ bits[j] = bit-excess;
+ ebits[j] = 0;
+ fine_priority[j] = 1;
+ }
+
+ /* Fine energy can't take advantage of the re-balancing in
+ quant_all_bands().
+ Instead, do the re-balancing here.*/
+ if(excess > 0)
+ {
+ int extra_fine;
+ int extra_bits;
+ extra_fine = IMIN(excess>>(stereo+BITRES),MAX_FINE_BITS-ebits[j]);
+ ebits[j] += extra_fine;
+ extra_bits = extra_fine*C<<BITRES;
+ fine_priority[j] = extra_bits >= excess-balance;
+ excess -= extra_bits;
+ }
+ balance = excess;
+
+ celt_assert(bits[j] >= 0);
+ celt_assert(ebits[j] >= 0);
+ }
+ /* Save any remaining bits over the cap for the rebalancing in
+ quant_all_bands(). */
+ *_balance = balance;
+
+ /* The skipped bands use all their bits for fine energy. */
+ for (;j<end;j++)
+ {
+ ebits[j] = bits[j] >> stereo >> BITRES;
+ celt_assert(C*ebits[j]<<BITRES == bits[j]);
+ bits[j] = 0;
+ fine_priority[j] = ebits[j]<1;
+ }
+ RESTORE_STACK;
+ return codedBands;
+}
+
+int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
+ opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev)
+{
+ int lo, hi, len, j;
+ int codedBands;
+ int skip_start;
+ int skip_rsv;
+ int intensity_rsv;
+ int dual_stereo_rsv;
+ VARDECL(int, bits1);
+ VARDECL(int, bits2);
+ VARDECL(int, thresh);
+ VARDECL(int, trim_offset);
+ SAVE_STACK;
+
+ total = IMAX(total, 0);
+ len = m->nbEBands;
+ skip_start = start;
+ /* Reserve a bit to signal the end of manually skipped bands. */
+ skip_rsv = total >= 1<<BITRES ? 1<<BITRES : 0;
+ total -= skip_rsv;
+ /* Reserve bits for the intensity and dual stereo parameters. */
+ intensity_rsv = dual_stereo_rsv = 0;
+ if (C==2)
+ {
+ intensity_rsv = LOG2_FRAC_TABLE[end-start];
+ if (intensity_rsv>total)
+ intensity_rsv = 0;
+ else
+ {
+ total -= intensity_rsv;
+ dual_stereo_rsv = total>=1<<BITRES ? 1<<BITRES : 0;
+ total -= dual_stereo_rsv;
+ }
+ }
+ ALLOC(bits1, len, int);
+ ALLOC(bits2, len, int);
+ ALLOC(thresh, len, int);
+ ALLOC(trim_offset, len, int);
+
+ for (j=start;j<end;j++)
+ {
+ /* Below this threshold, we're sure not to allocate any PVQ bits */
+ thresh[j] = IMAX((C)<<BITRES, (3*(m->eBands[j+1]-m->eBands[j])<<LM<<BITRES)>>4);
+ /* Tilt of the allocation curve */
+ trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(end-j-1)
+ *(1<<(LM+BITRES))>>6;
+ /* Giving less resolution to single-coefficient bands because they get
+ more benefit from having one coarse value per coefficient*/
+ if ((m->eBands[j+1]-m->eBands[j])<<LM==1)
+ trim_offset[j] -= C<<BITRES;
+ }
+ lo = 1;
+ hi = m->nbAllocVectors - 1;
+ do
+ {
+ int done = 0;
+ int psum = 0;
+ int mid = (lo+hi) >> 1;
+ for (j=end;j-->start;)
+ {
+ int bitsj;
+ int N = m->eBands[j+1]-m->eBands[j];
+ bitsj = C*N*m->allocVectors[mid*len+j]<<LM>>2;
+ if (bitsj > 0)
+ bitsj = IMAX(0, bitsj + trim_offset[j]);
+ bitsj += offsets[j];
+ if (bitsj >= thresh[j] || done)
+ {
+ done = 1;
+ /* Don't allocate more than we can actually use */
+ psum += IMIN(bitsj, cap[j]);
+ } else {
+ if (bitsj >= C<<BITRES)
+ psum += C<<BITRES;
+ }
+ }
+ if (psum > total)
+ hi = mid - 1;
+ else
+ lo = mid + 1;
+ /*printf ("lo = %d, hi = %d\n", lo, hi);*/
+ }
+ while (lo <= hi);
+ hi = lo--;
+ /*printf ("interp between %d and %d\n", lo, hi);*/
+ for (j=start;j<end;j++)
+ {
+ int bits1j, bits2j;
+ int N = m->eBands[j+1]-m->eBands[j];
+ bits1j = C*N*m->allocVectors[lo*len+j]<<LM>>2;
+ bits2j = hi>=m->nbAllocVectors ?
+ cap[j] : C*N*m->allocVectors[hi*len+j]<<LM>>2;
+ if (bits1j > 0)
+ bits1j = IMAX(0, bits1j + trim_offset[j]);
+ if (bits2j > 0)
+ bits2j = IMAX(0, bits2j + trim_offset[j]);
+ if (lo > 0)
+ bits1j += offsets[j];
+ bits2j += offsets[j];
+ if (offsets[j]>0)
+ skip_start = j;
+ bits2j = IMAX(0,bits2j-bits1j);
+ bits1[j] = bits1j;
+ bits2[j] = bits2j;
+ }
+ codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, cap,
+ total, balance, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv,
+ pulses, ebits, fine_priority, C, LM, ec, encode, prev);
+ RESTORE_STACK;
+ return codedBands;
+}
+
diff --git a/lib/rbcodec/codecs/libopus/celt/rate.h b/lib/rbcodec/codecs/libopus/celt/rate.h
new file mode 100644
index 0000000000..e0d5022326
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/rate.h
@@ -0,0 +1,101 @@
+/* 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.
+
+ 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 COPYRIGHT OWNER
+ 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 RATE_H
+#define RATE_H
+
+#define MAX_PSEUDO 40
+#define LOG_MAX_PSEUDO 6
+
+#define MAX_PULSES 128
+
+#define MAX_FINE_BITS 8
+
+#define FINE_OFFSET 21
+#define QTHETA_OFFSET 4
+#define QTHETA_OFFSET_TWOPHASE 16
+
+#include "cwrs.h"
+#include "modes.h"
+
+void compute_pulse_cache(CELTMode *m, int LM);
+
+static inline int get_pulses(int i)
+{
+ return i<8 ? i : (8 + (i&7)) << ((i>>3)-1);
+}
+
+static inline int bits2pulses(const CELTMode *m, int band, int LM, int bits)
+{
+ int i;
+ int lo, hi;
+ const unsigned char *cache;
+
+ LM++;
+ cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band];
+
+ lo = 0;
+ hi = cache[0];
+ bits--;
+ for (i=0;i<LOG_MAX_PSEUDO;i++)
+ {
+ int mid = (lo+hi+1)>>1;
+ /* OPT: Make sure this is implemented with a conditional move */
+ if ((int)cache[mid] >= bits)
+ hi = mid;
+ else
+ lo = mid;
+ }
+ if (bits- (lo == 0 ? -1 : (int)cache[lo]) <= (int)cache[hi]-bits)
+ return lo;
+ else
+ return hi;
+}
+
+static inline int pulses2bits(const CELTMode *m, int band, int LM, int pulses)
+{
+ const unsigned char *cache;
+
+ LM++;
+ cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band];
+ return pulses == 0 ? 0 : cache[pulses]+1;
+}
+
+/** Compute the pulse allocation, i.e. how many pulses will go in each
+ * band.
+ @param m mode
+ @param offsets Requested increase or decrease in the number of bits for
+ each band
+ @param total Number of bands
+ @param pulses Number of pulses per band (returned)
+ @return Total number of bits allocated
+*/
+int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
+ opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev);
+
+#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/stack_alloc.h b/lib/rbcodec/codecs/libopus/celt/stack_alloc.h
new file mode 100644
index 0000000000..a6f06d2263
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/stack_alloc.h
@@ -0,0 +1,149 @@
+/* Copyright (C) 2002-2003 Jean-Marc Valin
+ Copyright (C) 2007-2009 Xiph.Org Foundation */
+/**
+ @file stack_alloc.h
+ @brief Temporary memory allocation on stack
+*/
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 STACK_ALLOC_H
+#define STACK_ALLOC_H
+
+#if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA) && !defined (NONTHREADSAFE_PSEUDOSTACK))
+#error "Opus requires one of VAR_ARRAYS, USE_ALLOCA, or NONTHREADSAFE_PSEUDOSTACK be defined to select the temporary allocation mode."
+#endif
+
+#ifdef USE_ALLOCA
+# ifdef WIN32
+# include <malloc.h>
+# else
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# include <stdlib.h>
+# endif
+# endif
+#endif
+
+/**
+ * @def ALIGN(stack, size)
+ *
+ * Aligns the stack to a 'size' boundary
+ *
+ * @param stack Stack
+ * @param size New size boundary
+ */
+
+/**
+ * @def PUSH(stack, size, type)
+ *
+ * Allocates 'size' elements of type 'type' on the stack
+ *
+ * @param stack Stack
+ * @param size Number of elements
+ * @param type Type of element
+ */
+
+/**
+ * @def VARDECL(var)
+ *
+ * Declare variable on stack
+ *
+ * @param var Variable to declare
+ */
+
+/**
+ * @def ALLOC(var, size, type)
+ *
+ * Allocate 'size' elements of 'type' on stack
+ *
+ * @param var Name of variable to allocate
+ * @param size Number of elements
+ * @param type Type of element
+ */
+
+#if defined(VAR_ARRAYS)
+
+#define VARDECL(type, var)
+#define ALLOC(var, size, type) type var[size]
+#define SAVE_STACK
+#define RESTORE_STACK
+#define ALLOC_STACK
+
+#elif defined(USE_ALLOCA)
+
+#define VARDECL(type, var) type *var
+
+# ifdef WIN32
+# define ALLOC(var, size, type) var = ((type*)_alloca(sizeof(type)*(size)))
+# else
+# define ALLOC(var, size, type) var = ((type*)alloca(sizeof(type)*(size)))
+# endif
+
+#define SAVE_STACK
+#define RESTORE_STACK
+#define ALLOC_STACK
+
+#else
+
+#ifdef CELT_C
+char *global_stack=0;
+#else
+extern char *global_stack;
+#endif /* CELT_C */
+
+#ifdef ENABLE_VALGRIND
+
+#include <valgrind/memcheck.h>
+
+#ifdef CELT_C
+char *global_stack_top=0;
+#else
+extern char *global_stack_top;
+#endif /* CELT_C */
+
+#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
+#define PUSH(stack, size, type) (VALGRIND_MAKE_MEM_NOACCESS(stack, global_stack_top-stack),ALIGN((stack),sizeof(type)/sizeof(char)),VALGRIND_MAKE_MEM_UNDEFINED(stack, ((size)*sizeof(type)/sizeof(char))),(stack)+=(2*(size)*sizeof(type)/sizeof(char)),(type*)((stack)-(2*(size)*sizeof(type)/sizeof(char))))
+#define RESTORE_STACK ((global_stack = _saved_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack))
+#define ALLOC_STACK char *_saved_stack; ((global_stack = (global_stack==0) ? ((global_stack_top=opus_alloc_scratch(GLOBAL_STACK_SIZE*2)+(GLOBAL_STACK_SIZE*2))-(GLOBAL_STACK_SIZE*2)) : global_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack)); _saved_stack = global_stack;
+
+#else
+
+#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
+#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)/sizeof(char)),(stack)+=(size)*(sizeof(type)/sizeof(char)),(type*)((stack)-(size)*(sizeof(type)/sizeof(char))))
+#define RESTORE_STACK (global_stack = _saved_stack)
+#define ALLOC_STACK char *_saved_stack; (global_stack = (global_stack==0) ? opus_alloc_scratch(GLOBAL_STACK_SIZE) : global_stack); _saved_stack = global_stack;
+
+#endif /* ENABLE_VALGRIND */
+
+#include "os_support.h"
+#define VARDECL(type, var) type *var
+#define ALLOC(var, size, type) var = PUSH(global_stack, size, type)
+#define SAVE_STACK char *_saved_stack = global_stack;
+
+#endif /* VAR_ARRAYS */
+
+#endif /* STACK_ALLOC_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/static_modes_fixed.h b/lib/rbcodec/codecs/libopus/celt/static_modes_fixed.h
new file mode 100644
index 0000000000..216df9e605
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/static_modes_fixed.h
@@ -0,0 +1,595 @@
+/* The contents of this file was automatically generated by dump_modes.c
+ with arguments: 48000 960
+ It contains static definitions for some pre-defined modes. */
+#include "modes.h"
+#include "rate.h"
+
+#ifndef DEF_WINDOW120
+#define DEF_WINDOW120
+static const opus_val16 window120[120] = {
+2, 20, 55, 108, 178,
+266, 372, 494, 635, 792,
+966, 1157, 1365, 1590, 1831,
+2089, 2362, 2651, 2956, 3276,
+3611, 3961, 4325, 4703, 5094,
+5499, 5916, 6346, 6788, 7241,
+7705, 8179, 8663, 9156, 9657,
+10167, 10684, 11207, 11736, 12271,
+12810, 13353, 13899, 14447, 14997,
+15547, 16098, 16648, 17197, 17744,
+18287, 18827, 19363, 19893, 20418,
+20936, 21447, 21950, 22445, 22931,
+23407, 23874, 24330, 24774, 25208,
+25629, 26039, 26435, 26819, 27190,
+27548, 27893, 28224, 28541, 28845,
+29135, 29411, 29674, 29924, 30160,
+30384, 30594, 30792, 30977, 31151,
+31313, 31463, 31602, 31731, 31849,
+31958, 32057, 32148, 32229, 32303,
+32370, 32429, 32481, 32528, 32568,
+32604, 32634, 32661, 32683, 32701,
+32717, 32729, 32740, 32748, 32754,
+32758, 32762, 32764, 32766, 32767,
+32767, 32767, 32767, 32767, 32767,
+};
+#endif
+
+#ifndef DEF_LOGN400
+#define DEF_LOGN400
+static const opus_int16 logN400[21] = {
+0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, };
+#endif
+
+#ifndef DEF_PULSE_CACHE50
+#define DEF_PULSE_CACHE50
+static const opus_int16 cache_index50[105] = {
+-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41,
+82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41,
+41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41,
+41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305,
+318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240,
+305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240,
+240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387,
+};
+static const unsigned char cache_bits50[392] = {
+40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28,
+31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50,
+51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65,
+66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61,
+64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92,
+94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123,
+124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94,
+97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139,
+142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35,
+28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149,
+153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225,
+229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157,
+166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63,
+86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250,
+25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180,
+185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89,
+110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41,
+74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138,
+163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214,
+228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49,
+90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47,
+87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57,
+106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187,
+224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127,
+182, 234, };
+static const unsigned char cache_caps50[168] = {
+224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185,
+178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240,
+240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160,
+160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172,
+138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207,
+204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185,
+185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39,
+207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201,
+188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193,
+193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204,
+204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175,
+140, 66, 40, };
+#endif
+
+#ifndef FFT_TWIDDLES48000_960
+#define FFT_TWIDDLES48000_960
+static const kiss_twiddle_cpx fft_twiddles48000_960[480] = {
+{32767, 0}, {32766, -429},
+{32757, -858}, {32743, -1287},
+{32724, -1715}, {32698, -2143},
+{32667, -2570}, {32631, -2998},
+{32588, -3425}, {32541, -3851},
+{32488, -4277}, {32429, -4701},
+{32364, -5125}, {32295, -5548},
+{32219, -5971}, {32138, -6393},
+{32051, -6813}, {31960, -7231},
+{31863, -7650}, {31760, -8067},
+{31652, -8481}, {31539, -8895},
+{31419, -9306}, {31294, -9716},
+{31165, -10126}, {31030, -10532},
+{30889, -10937}, {30743, -11340},
+{30592, -11741}, {30436, -12141},
+{30274, -12540}, {30107, -12935},
+{29936, -13328}, {29758, -13718},
+{29577, -14107}, {29390, -14493},
+{29197, -14875}, {29000, -15257},
+{28797, -15635}, {28590, -16010},
+{28379, -16384}, {28162, -16753},
+{27940, -17119}, {27714, -17484},
+{27482, -17845}, {27246, -18205},
+{27006, -18560}, {26760, -18911},
+{26510, -19260}, {26257, -19606},
+{25997, -19947}, {25734, -20286},
+{25466, -20621}, {25194, -20952},
+{24918, -21281}, {24637, -21605},
+{24353, -21926}, {24063, -22242},
+{23770, -22555}, {23473, -22865},
+{23171, -23171}, {22866, -23472},
+{22557, -23769}, {22244, -24063},
+{21927, -24352}, {21606, -24636},
+{21282, -24917}, {20954, -25194},
+{20622, -25465}, {20288, -25733},
+{19949, -25997}, {19607, -26255},
+{19261, -26509}, {18914, -26760},
+{18561, -27004}, {18205, -27246},
+{17846, -27481}, {17485, -27713},
+{17122, -27940}, {16755, -28162},
+{16385, -28378}, {16012, -28590},
+{15636, -28797}, {15258, -28999},
+{14878, -29197}, {14494, -29389},
+{14108, -29576}, {13720, -29757},
+{13329, -29934}, {12937, -30107},
+{12540, -30274}, {12142, -30435},
+{11744, -30592}, {11342, -30743},
+{10939, -30889}, {10534, -31030},
+{10127, -31164}, {9718, -31294},
+{9307, -31418}, {8895, -31537},
+{8482, -31652}, {8067, -31759},
+{7650, -31862}, {7233, -31960},
+{6815, -32051}, {6393, -32138},
+{5973, -32219}, {5549, -32294},
+{5127, -32364}, {4703, -32429},
+{4278, -32487}, {3852, -32541},
+{3426, -32588}, {2999, -32630},
+{2572, -32667}, {2144, -32698},
+{1716, -32724}, {1287, -32742},
+{860, -32757}, {430, -32766},
+{0, -32767}, {-429, -32766},
+{-858, -32757}, {-1287, -32743},
+{-1715, -32724}, {-2143, -32698},
+{-2570, -32667}, {-2998, -32631},
+{-3425, -32588}, {-3851, -32541},
+{-4277, -32488}, {-4701, -32429},
+{-5125, -32364}, {-5548, -32295},
+{-5971, -32219}, {-6393, -32138},
+{-6813, -32051}, {-7231, -31960},
+{-7650, -31863}, {-8067, -31760},
+{-8481, -31652}, {-8895, -31539},
+{-9306, -31419}, {-9716, -31294},
+{-10126, -31165}, {-10532, -31030},
+{-10937, -30889}, {-11340, -30743},
+{-11741, -30592}, {-12141, -30436},
+{-12540, -30274}, {-12935, -30107},
+{-13328, -29936}, {-13718, -29758},
+{-14107, -29577}, {-14493, -29390},
+{-14875, -29197}, {-15257, -29000},
+{-15635, -28797}, {-16010, -28590},
+{-16384, -28379}, {-16753, -28162},
+{-17119, -27940}, {-17484, -27714},
+{-17845, -27482}, {-18205, -27246},
+{-18560, -27006}, {-18911, -26760},
+{-19260, -26510}, {-19606, -26257},
+{-19947, -25997}, {-20286, -25734},
+{-20621, -25466}, {-20952, -25194},
+{-21281, -24918}, {-21605, -24637},
+{-21926, -24353}, {-22242, -24063},
+{-22555, -23770}, {-22865, -23473},
+{-23171, -23171}, {-23472, -22866},
+{-23769, -22557}, {-24063, -22244},
+{-24352, -21927}, {-24636, -21606},
+{-24917, -21282}, {-25194, -20954},
+{-25465, -20622}, {-25733, -20288},
+{-25997, -19949}, {-26255, -19607},
+{-26509, -19261}, {-26760, -18914},
+{-27004, -18561}, {-27246, -18205},
+{-27481, -17846}, {-27713, -17485},
+{-27940, -17122}, {-28162, -16755},
+{-28378, -16385}, {-28590, -16012},
+{-28797, -15636}, {-28999, -15258},
+{-29197, -14878}, {-29389, -14494},
+{-29576, -14108}, {-29757, -13720},
+{-29934, -13329}, {-30107, -12937},
+{-30274, -12540}, {-30435, -12142},
+{-30592, -11744}, {-30743, -11342},
+{-30889, -10939}, {-31030, -10534},
+{-31164, -10127}, {-31294, -9718},
+{-31418, -9307}, {-31537, -8895},
+{-31652, -8482}, {-31759, -8067},
+{-31862, -7650}, {-31960, -7233},
+{-32051, -6815}, {-32138, -6393},
+{-32219, -5973}, {-32294, -5549},
+{-32364, -5127}, {-32429, -4703},
+{-32487, -4278}, {-32541, -3852},
+{-32588, -3426}, {-32630, -2999},
+{-32667, -2572}, {-32698, -2144},
+{-32724, -1716}, {-32742, -1287},
+{-32757, -860}, {-32766, -430},
+{-32767, 0}, {-32766, 429},
+{-32757, 858}, {-32743, 1287},
+{-32724, 1715}, {-32698, 2143},
+{-32667, 2570}, {-32631, 2998},
+{-32588, 3425}, {-32541, 3851},
+{-32488, 4277}, {-32429, 4701},
+{-32364, 5125}, {-32295, 5548},
+{-32219, 5971}, {-32138, 6393},
+{-32051, 6813}, {-31960, 7231},
+{-31863, 7650}, {-31760, 8067},
+{-31652, 8481}, {-31539, 8895},
+{-31419, 9306}, {-31294, 9716},
+{-31165, 10126}, {-31030, 10532},
+{-30889, 10937}, {-30743, 11340},
+{-30592, 11741}, {-30436, 12141},
+{-30274, 12540}, {-30107, 12935},
+{-29936, 13328}, {-29758, 13718},
+{-29577, 14107}, {-29390, 14493},
+{-29197, 14875}, {-29000, 15257},
+{-28797, 15635}, {-28590, 16010},
+{-28379, 16384}, {-28162, 16753},
+{-27940, 17119}, {-27714, 17484},
+{-27482, 17845}, {-27246, 18205},
+{-27006, 18560}, {-26760, 18911},
+{-26510, 19260}, {-26257, 19606},
+{-25997, 19947}, {-25734, 20286},
+{-25466, 20621}, {-25194, 20952},
+{-24918, 21281}, {-24637, 21605},
+{-24353, 21926}, {-24063, 22242},
+{-23770, 22555}, {-23473, 22865},
+{-23171, 23171}, {-22866, 23472},
+{-22557, 23769}, {-22244, 24063},
+{-21927, 24352}, {-21606, 24636},
+{-21282, 24917}, {-20954, 25194},
+{-20622, 25465}, {-20288, 25733},
+{-19949, 25997}, {-19607, 26255},
+{-19261, 26509}, {-18914, 26760},
+{-18561, 27004}, {-18205, 27246},
+{-17846, 27481}, {-17485, 27713},
+{-17122, 27940}, {-16755, 28162},
+{-16385, 28378}, {-16012, 28590},
+{-15636, 28797}, {-15258, 28999},
+{-14878, 29197}, {-14494, 29389},
+{-14108, 29576}, {-13720, 29757},
+{-13329, 29934}, {-12937, 30107},
+{-12540, 30274}, {-12142, 30435},
+{-11744, 30592}, {-11342, 30743},
+{-10939, 30889}, {-10534, 31030},
+{-10127, 31164}, {-9718, 31294},
+{-9307, 31418}, {-8895, 31537},
+{-8482, 31652}, {-8067, 31759},
+{-7650, 31862}, {-7233, 31960},
+{-6815, 32051}, {-6393, 32138},
+{-5973, 32219}, {-5549, 32294},
+{-5127, 32364}, {-4703, 32429},
+{-4278, 32487}, {-3852, 32541},
+{-3426, 32588}, {-2999, 32630},
+{-2572, 32667}, {-2144, 32698},
+{-1716, 32724}, {-1287, 32742},
+{-860, 32757}, {-430, 32766},
+{0, 32767}, {429, 32766},
+{858, 32757}, {1287, 32743},
+{1715, 32724}, {2143, 32698},
+{2570, 32667}, {2998, 32631},
+{3425, 32588}, {3851, 32541},
+{4277, 32488}, {4701, 32429},
+{5125, 32364}, {5548, 32295},
+{5971, 32219}, {6393, 32138},
+{6813, 32051}, {7231, 31960},
+{7650, 31863}, {8067, 31760},
+{8481, 31652}, {8895, 31539},
+{9306, 31419}, {9716, 31294},
+{10126, 31165}, {10532, 31030},
+{10937, 30889}, {11340, 30743},
+{11741, 30592}, {12141, 30436},
+{12540, 30274}, {12935, 30107},
+{13328, 29936}, {13718, 29758},
+{14107, 29577}, {14493, 29390},
+{14875, 29197}, {15257, 29000},
+{15635, 28797}, {16010, 28590},
+{16384, 28379}, {16753, 28162},
+{17119, 27940}, {17484, 27714},
+{17845, 27482}, {18205, 27246},
+{18560, 27006}, {18911, 26760},
+{19260, 26510}, {19606, 26257},
+{19947, 25997}, {20286, 25734},
+{20621, 25466}, {20952, 25194},
+{21281, 24918}, {21605, 24637},
+{21926, 24353}, {22242, 24063},
+{22555, 23770}, {22865, 23473},
+{23171, 23171}, {23472, 22866},
+{23769, 22557}, {24063, 22244},
+{24352, 21927}, {24636, 21606},
+{24917, 21282}, {25194, 20954},
+{25465, 20622}, {25733, 20288},
+{25997, 19949}, {26255, 19607},
+{26509, 19261}, {26760, 18914},
+{27004, 18561}, {27246, 18205},
+{27481, 17846}, {27713, 17485},
+{27940, 17122}, {28162, 16755},
+{28378, 16385}, {28590, 16012},
+{28797, 15636}, {28999, 15258},
+{29197, 14878}, {29389, 14494},
+{29576, 14108}, {29757, 13720},
+{29934, 13329}, {30107, 12937},
+{30274, 12540}, {30435, 12142},
+{30592, 11744}, {30743, 11342},
+{30889, 10939}, {31030, 10534},
+{31164, 10127}, {31294, 9718},
+{31418, 9307}, {31537, 8895},
+{31652, 8482}, {31759, 8067},
+{31862, 7650}, {31960, 7233},
+{32051, 6815}, {32138, 6393},
+{32219, 5973}, {32294, 5549},
+{32364, 5127}, {32429, 4703},
+{32487, 4278}, {32541, 3852},
+{32588, 3426}, {32630, 2999},
+{32667, 2572}, {32698, 2144},
+{32724, 1716}, {32742, 1287},
+{32757, 860}, {32766, 430},
+};
+#ifndef FFT_BITREV480
+#define FFT_BITREV480
+static const opus_int16 fft_bitrev480[480] = {
+0, 120, 240, 360, 30, 150, 270, 390, 60, 180, 300, 420, 90, 210, 330,
+450, 15, 135, 255, 375, 45, 165, 285, 405, 75, 195, 315, 435, 105, 225,
+345, 465, 5, 125, 245, 365, 35, 155, 275, 395, 65, 185, 305, 425, 95,
+215, 335, 455, 20, 140, 260, 380, 50, 170, 290, 410, 80, 200, 320, 440,
+110, 230, 350, 470, 10, 130, 250, 370, 40, 160, 280, 400, 70, 190, 310,
+430, 100, 220, 340, 460, 25, 145, 265, 385, 55, 175, 295, 415, 85, 205,
+325, 445, 115, 235, 355, 475, 1, 121, 241, 361, 31, 151, 271, 391, 61,
+181, 301, 421, 91, 211, 331, 451, 16, 136, 256, 376, 46, 166, 286, 406,
+76, 196, 316, 436, 106, 226, 346, 466, 6, 126, 246, 366, 36, 156, 276,
+396, 66, 186, 306, 426, 96, 216, 336, 456, 21, 141, 261, 381, 51, 171,
+291, 411, 81, 201, 321, 441, 111, 231, 351, 471, 11, 131, 251, 371, 41,
+161, 281, 401, 71, 191, 311, 431, 101, 221, 341, 461, 26, 146, 266, 386,
+56, 176, 296, 416, 86, 206, 326, 446, 116, 236, 356, 476, 2, 122, 242,
+362, 32, 152, 272, 392, 62, 182, 302, 422, 92, 212, 332, 452, 17, 137,
+257, 377, 47, 167, 287, 407, 77, 197, 317, 437, 107, 227, 347, 467, 7,
+127, 247, 367, 37, 157, 277, 397, 67, 187, 307, 427, 97, 217, 337, 457,
+22, 142, 262, 382, 52, 172, 292, 412, 82, 202, 322, 442, 112, 232, 352,
+472, 12, 132, 252, 372, 42, 162, 282, 402, 72, 192, 312, 432, 102, 222,
+342, 462, 27, 147, 267, 387, 57, 177, 297, 417, 87, 207, 327, 447, 117,
+237, 357, 477, 3, 123, 243, 363, 33, 153, 273, 393, 63, 183, 303, 423,
+93, 213, 333, 453, 18, 138, 258, 378, 48, 168, 288, 408, 78, 198, 318,
+438, 108, 228, 348, 468, 8, 128, 248, 368, 38, 158, 278, 398, 68, 188,
+308, 428, 98, 218, 338, 458, 23, 143, 263, 383, 53, 173, 293, 413, 83,
+203, 323, 443, 113, 233, 353, 473, 13, 133, 253, 373, 43, 163, 283, 403,
+73, 193, 313, 433, 103, 223, 343, 463, 28, 148, 268, 388, 58, 178, 298,
+418, 88, 208, 328, 448, 118, 238, 358, 478, 4, 124, 244, 364, 34, 154,
+274, 394, 64, 184, 304, 424, 94, 214, 334, 454, 19, 139, 259, 379, 49,
+169, 289, 409, 79, 199, 319, 439, 109, 229, 349, 469, 9, 129, 249, 369,
+39, 159, 279, 399, 69, 189, 309, 429, 99, 219, 339, 459, 24, 144, 264,
+384, 54, 174, 294, 414, 84, 204, 324, 444, 114, 234, 354, 474, 14, 134,
+254, 374, 44, 164, 284, 404, 74, 194, 314, 434, 104, 224, 344, 464, 29,
+149, 269, 389, 59, 179, 299, 419, 89, 209, 329, 449, 119, 239, 359, 479,
+};
+#endif
+
+#ifndef FFT_BITREV240
+#define FFT_BITREV240
+static const opus_int16 fft_bitrev240[240] = {
+0, 60, 120, 180, 15, 75, 135, 195, 30, 90, 150, 210, 45, 105, 165,
+225, 5, 65, 125, 185, 20, 80, 140, 200, 35, 95, 155, 215, 50, 110,
+170, 230, 10, 70, 130, 190, 25, 85, 145, 205, 40, 100, 160, 220, 55,
+115, 175, 235, 1, 61, 121, 181, 16, 76, 136, 196, 31, 91, 151, 211,
+46, 106, 166, 226, 6, 66, 126, 186, 21, 81, 141, 201, 36, 96, 156,
+216, 51, 111, 171, 231, 11, 71, 131, 191, 26, 86, 146, 206, 41, 101,
+161, 221, 56, 116, 176, 236, 2, 62, 122, 182, 17, 77, 137, 197, 32,
+92, 152, 212, 47, 107, 167, 227, 7, 67, 127, 187, 22, 82, 142, 202,
+37, 97, 157, 217, 52, 112, 172, 232, 12, 72, 132, 192, 27, 87, 147,
+207, 42, 102, 162, 222, 57, 117, 177, 237, 3, 63, 123, 183, 18, 78,
+138, 198, 33, 93, 153, 213, 48, 108, 168, 228, 8, 68, 128, 188, 23,
+83, 143, 203, 38, 98, 158, 218, 53, 113, 173, 233, 13, 73, 133, 193,
+28, 88, 148, 208, 43, 103, 163, 223, 58, 118, 178, 238, 4, 64, 124,
+184, 19, 79, 139, 199, 34, 94, 154, 214, 49, 109, 169, 229, 9, 69,
+129, 189, 24, 84, 144, 204, 39, 99, 159, 219, 54, 114, 174, 234, 14,
+74, 134, 194, 29, 89, 149, 209, 44, 104, 164, 224, 59, 119, 179, 239,
+};
+#endif
+
+#ifndef FFT_BITREV120
+#define FFT_BITREV120
+static const opus_int16 fft_bitrev120[120] = {
+0, 30, 60, 90, 15, 45, 75, 105, 5, 35, 65, 95, 20, 50, 80,
+110, 10, 40, 70, 100, 25, 55, 85, 115, 1, 31, 61, 91, 16, 46,
+76, 106, 6, 36, 66, 96, 21, 51, 81, 111, 11, 41, 71, 101, 26,
+56, 86, 116, 2, 32, 62, 92, 17, 47, 77, 107, 7, 37, 67, 97,
+22, 52, 82, 112, 12, 42, 72, 102, 27, 57, 87, 117, 3, 33, 63,
+93, 18, 48, 78, 108, 8, 38, 68, 98, 23, 53, 83, 113, 13, 43,
+73, 103, 28, 58, 88, 118, 4, 34, 64, 94, 19, 49, 79, 109, 9,
+39, 69, 99, 24, 54, 84, 114, 14, 44, 74, 104, 29, 59, 89, 119,
+};
+#endif
+
+#ifndef FFT_BITREV60
+#define FFT_BITREV60
+static const opus_int16 fft_bitrev60[60] = {
+0, 15, 30, 45, 5, 20, 35, 50, 10, 25, 40, 55, 1, 16, 31,
+46, 6, 21, 36, 51, 11, 26, 41, 56, 2, 17, 32, 47, 7, 22,
+37, 52, 12, 27, 42, 57, 3, 18, 33, 48, 8, 23, 38, 53, 13,
+28, 43, 58, 4, 19, 34, 49, 9, 24, 39, 54, 14, 29, 44, 59,
+};
+#endif
+
+#ifndef FFT_STATE48000_960_0
+#define FFT_STATE48000_960_0
+static const kiss_fft_state fft_state48000_960_0 = {
+480, /* nfft */
+-1, /* shift */
+{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */
+fft_bitrev480, /* bitrev */
+fft_twiddles48000_960, /* bitrev */
+};
+#endif
+
+#ifndef FFT_STATE48000_960_1
+#define FFT_STATE48000_960_1
+static const kiss_fft_state fft_state48000_960_1 = {
+240, /* nfft */
+1, /* shift */
+{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
+fft_bitrev240, /* bitrev */
+fft_twiddles48000_960, /* bitrev */
+};
+#endif
+
+#ifndef FFT_STATE48000_960_2
+#define FFT_STATE48000_960_2
+static const kiss_fft_state fft_state48000_960_2 = {
+120, /* nfft */
+2, /* shift */
+{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
+fft_bitrev120, /* bitrev */
+fft_twiddles48000_960, /* bitrev */
+};
+#endif
+
+#ifndef FFT_STATE48000_960_3
+#define FFT_STATE48000_960_3
+static const kiss_fft_state fft_state48000_960_3 = {
+60, /* nfft */
+3, /* shift */
+{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
+fft_bitrev60, /* bitrev */
+fft_twiddles48000_960, /* bitrev */
+};
+#endif
+
+#endif
+
+#ifndef MDCT_TWIDDLES960
+#define MDCT_TWIDDLES960
+static const opus_val16 mdct_twiddles960[481] = {
+32767, 32767, 32767, 32767, 32766,
+32763, 32762, 32759, 32757, 32753,
+32751, 32747, 32743, 32738, 32733,
+32729, 32724, 32717, 32711, 32705,
+32698, 32690, 32683, 32676, 32667,
+32658, 32650, 32640, 32631, 32620,
+32610, 32599, 32588, 32577, 32566,
+32554, 32541, 32528, 32515, 32502,
+32487, 32474, 32459, 32444, 32429,
+32413, 32397, 32381, 32364, 32348,
+32331, 32313, 32294, 32277, 32257,
+32239, 32219, 32200, 32180, 32159,
+32138, 32118, 32096, 32074, 32051,
+32029, 32006, 31984, 31960, 31936,
+31912, 31888, 31863, 31837, 31812,
+31786, 31760, 31734, 31707, 31679,
+31652, 31624, 31596, 31567, 31539,
+31508, 31479, 31450, 31419, 31388,
+31357, 31326, 31294, 31262, 31230,
+31198, 31164, 31131, 31097, 31063,
+31030, 30994, 30959, 30924, 30889,
+30853, 30816, 30779, 30743, 30705,
+30668, 30629, 30592, 30553, 30515,
+30475, 30435, 30396, 30356, 30315,
+30274, 30233, 30191, 30149, 30107,
+30065, 30022, 29979, 29936, 29891,
+29847, 29803, 29758, 29713, 29668,
+29622, 29577, 29529, 29483, 29436,
+29390, 29341, 29293, 29246, 29197,
+29148, 29098, 29050, 29000, 28949,
+28899, 28848, 28797, 28746, 28694,
+28642, 28590, 28537, 28485, 28432,
+28378, 28324, 28271, 28217, 28162,
+28106, 28051, 27995, 27940, 27884,
+27827, 27770, 27713, 27657, 27598,
+27540, 27481, 27423, 27365, 27305,
+27246, 27187, 27126, 27066, 27006,
+26945, 26883, 26822, 26760, 26698,
+26636, 26574, 26510, 26448, 26383,
+26320, 26257, 26191, 26127, 26062,
+25997, 25931, 25866, 25800, 25734,
+25667, 25601, 25533, 25466, 25398,
+25330, 25262, 25194, 25125, 25056,
+24987, 24917, 24848, 24778, 24707,
+24636, 24566, 24495, 24424, 24352,
+24280, 24208, 24135, 24063, 23990,
+23917, 23842, 23769, 23695, 23622,
+23546, 23472, 23398, 23322, 23246,
+23171, 23095, 23018, 22942, 22866,
+22788, 22711, 22634, 22557, 22478,
+22400, 22322, 22244, 22165, 22085,
+22006, 21927, 21846, 21766, 21687,
+21606, 21524, 21443, 21363, 21282,
+21199, 21118, 21035, 20954, 20870,
+20788, 20705, 20621, 20538, 20455,
+20371, 20286, 20202, 20118, 20034,
+19947, 19863, 19777, 19692, 19606,
+19520, 19434, 19347, 19260, 19174,
+19088, 18999, 18911, 18825, 18737,
+18648, 18560, 18472, 18384, 18294,
+18205, 18116, 18025, 17936, 17846,
+17757, 17666, 17576, 17485, 17395,
+17303, 17212, 17122, 17030, 16937,
+16846, 16755, 16662, 16569, 16477,
+16385, 16291, 16198, 16105, 16012,
+15917, 15824, 15730, 15636, 15541,
+15447, 15352, 15257, 15162, 15067,
+14973, 14875, 14781, 14685, 14589,
+14493, 14396, 14300, 14204, 14107,
+14010, 13914, 13815, 13718, 13621,
+13524, 13425, 13328, 13230, 13133,
+13033, 12935, 12836, 12738, 12638,
+12540, 12441, 12341, 12241, 12142,
+12044, 11943, 11843, 11744, 11643,
+11542, 11442, 11342, 11241, 11139,
+11039, 10939, 10836, 10736, 10635,
+10534, 10431, 10330, 10228, 10127,
+10024, 9921, 9820, 9718, 9614,
+9512, 9410, 9306, 9204, 9101,
+8998, 8895, 8791, 8689, 8585,
+8481, 8377, 8274, 8171, 8067,
+7962, 7858, 7753, 7650, 7545,
+7441, 7336, 7231, 7129, 7023,
+6917, 6813, 6709, 6604, 6498,
+6393, 6288, 6182, 6077, 5973,
+5867, 5760, 5656, 5549, 5445,
+5339, 5232, 5127, 5022, 4914,
+4809, 4703, 4596, 4490, 4384,
+4278, 4171, 4065, 3958, 3852,
+3745, 3640, 3532, 3426, 3318,
+3212, 3106, 2998, 2891, 2786,
+2679, 2570, 2465, 2358, 2251,
+2143, 2037, 1929, 1823, 1715,
+1609, 1501, 1393, 1287, 1180,
+1073, 964, 858, 751, 644,
+535, 429, 322, 214, 107,
+0, };
+#endif
+
+static const CELTMode mode48000_960_120 = {
+48000, /* Fs */
+120, /* overlap */
+21, /* nbEBands */
+21, /* effEBands */
+{27853, 0, 4096, 8192, }, /* preemph */
+eband5ms, /* eBands */
+3, /* maxLM */
+8, /* nbShortMdcts */
+120, /* shortMdctSize */
+11, /* nbAllocVectors */
+band_allocation, /* allocVectors */
+logN400, /* logN */
+window120, /* window */
+{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */
+{392, cache_index50, cache_bits50, cache_caps50}, /* cache */
+};
+
+/* List of all the available modes */
+#define TOTAL_MODES 1
+static const CELTMode * const static_mode_list[TOTAL_MODES] = {
+&mode48000_960_120,
+};
diff --git a/lib/rbcodec/codecs/libopus/celt/vq.c b/lib/rbcodec/codecs/libopus/celt/vq.c
new file mode 100644
index 0000000000..6a00edf9cd
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/vq.c
@@ -0,0 +1,415 @@
+/* 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#include "mathops.h"
+#include "cwrs.h"
+#include "vq.h"
+#include "arch.h"
+#include "os_support.h"
+#include "bands.h"
+#include "rate.h"
+
+static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)
+{
+ int i;
+ celt_norm *Xptr;
+ Xptr = X;
+ for (i=0;i<len-stride;i++)
+ {
+ celt_norm x1, x2;
+ x1 = Xptr[0];
+ x2 = Xptr[stride];
+ Xptr[stride] = EXTRACT16(SHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15));
+ *Xptr++ = EXTRACT16(SHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15));
+ }
+ Xptr = &X[len-2*stride-1];
+ for (i=len-2*stride-1;i>=0;i--)
+ {
+ celt_norm x1, x2;
+ x1 = Xptr[0];
+ x2 = Xptr[stride];
+ Xptr[stride] = EXTRACT16(SHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15));
+ *Xptr-- = EXTRACT16(SHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15));
+ }
+}
+
+static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread)
+{
+ static const int SPREAD_FACTOR[3]={15,10,5};
+ int i;
+ opus_val16 c, s;
+ opus_val16 gain, theta;
+ int stride2=0;
+ int factor;
+
+ if (2*K>=len || spread==SPREAD_NONE)
+ return;
+ factor = SPREAD_FACTOR[spread-1];
+
+ gain = celt_div((opus_val32)MULT16_16(Q15_ONE,len),(opus_val32)(len+factor*K));
+ theta = HALF16(MULT16_16_Q15(gain,gain));
+
+ c = celt_cos_norm(EXTEND32(theta));
+ s = celt_cos_norm(EXTEND32(SUB16(Q15ONE,theta))); /* sin(theta) */
+
+ if (len>=8*stride)
+ {
+ stride2 = 1;
+ /* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding.
+ It's basically incrementing long as (stride2+0.5)^2 < len/stride. */
+ while ((stride2*stride2+stride2)*stride + (stride>>2) < len)
+ stride2++;
+ }
+ /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for
+ extract_collapse_mask().*/
+ len /= stride;
+ for (i=0;i<stride;i++)
+ {
+ if (dir < 0)
+ {
+ if (stride2)
+ exp_rotation1(X+i*len, len, stride2, s, c);
+ exp_rotation1(X+i*len, len, 1, c, s);
+ } else {
+ exp_rotation1(X+i*len, len, 1, c, -s);
+ if (stride2)
+ exp_rotation1(X+i*len, len, stride2, s, -c);
+ }
+ }
+}
+
+/** Takes the pitch vector and the decoded residual vector, computes the gain
+ that will give ||p+g*y||=1 and mixes the residual with the pitch. */
+static void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT X,
+ int N, opus_val32 Ryy, opus_val16 gain)
+{
+ int i;
+#ifdef FIXED_POINT
+ int k;
+#endif
+ opus_val32 t;
+ opus_val16 g;
+
+#ifdef FIXED_POINT
+ k = celt_ilog2(Ryy)>>1;
+#endif
+ t = VSHR32(Ryy, 2*(k-7));
+ g = MULT16_16_P15(celt_rsqrt_norm(t),gain);
+
+ i=0;
+ do
+ X[i] = EXTRACT16(PSHR32(MULT16_16(g, iy[i]), k+1));
+ while (++i < N);
+}
+
+static unsigned extract_collapse_mask(int *iy, int N, int B)
+{
+ unsigned collapse_mask;
+ int N0;
+ int i;
+ if (B<=1)
+ return 1;
+ /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for
+ exp_rotation().*/
+ N0 = N/B;
+ collapse_mask = 0;
+ i=0; do {
+ int j;
+ j=0; do {
+ collapse_mask |= (iy[i*N0+j]!=0)<<i;
+ } while (++j<N0);
+ } while (++i<B);
+ return collapse_mask;
+}
+
+unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
+#ifdef RESYNTH
+ , opus_val16 gain
+#endif
+ )
+{
+ VARDECL(celt_norm, y);
+ VARDECL(int, iy);
+ VARDECL(opus_val16, signx);
+ int i, j;
+ opus_val16 s;
+ int pulsesLeft;
+ opus_val32 sum;
+ opus_val32 xy;
+ opus_val16 yy;
+ unsigned collapse_mask;
+ SAVE_STACK;
+
+ celt_assert2(K>0, "alg_quant() needs at least one pulse");
+ celt_assert2(N>1, "alg_quant() needs at least two dimensions");
+
+ ALLOC(y, N, celt_norm);
+ ALLOC(iy, N, int);
+ ALLOC(signx, N, opus_val16);
+
+ exp_rotation(X, N, 1, B, K, spread);
+
+ /* Get rid of the sign */
+ sum = 0;
+ j=0; do {
+ if (X[j]>0)
+ signx[j]=1;
+ else {
+ signx[j]=-1;
+ X[j]=-X[j];
+ }
+ iy[j] = 0;
+ y[j] = 0;
+ } while (++j<N);
+
+ xy = yy = 0;
+
+ pulsesLeft = K;
+
+ /* Do a pre-search by projecting on the pyramid */
+ if (K > (N>>1))
+ {
+ opus_val16 rcp;
+ j=0; do {
+ sum += X[j];
+ } while (++j<N);
+
+ /* If X is too small, just replace it with a pulse at 0 */
+#ifdef FIXED_POINT
+ if (sum <= K)
+#else
+ /* Prevents infinities and NaNs from causing too many pulses
+ to be allocated. 64 is an approximation of infinity here. */
+ if (!(sum > EPSILON && sum < 64))
+#endif
+ {
+ X[0] = QCONST16(1.f,14);
+ j=1; do
+ X[j]=0;
+ while (++j<N);
+ sum = QCONST16(1.f,14);
+ }
+ rcp = EXTRACT16(MULT16_32_Q16(K-1, celt_rcp(sum)));
+ j=0; do {
+#ifdef FIXED_POINT
+ /* It's really important to round *towards zero* here */
+ iy[j] = MULT16_16_Q15(X[j],rcp);
+#else
+ iy[j] = (int)floor(rcp*X[j]);
+#endif
+ y[j] = (celt_norm)iy[j];
+ yy = MAC16_16(yy, y[j],y[j]);
+ xy = MAC16_16(xy, X[j],y[j]);
+ y[j] *= 2;
+ pulsesLeft -= iy[j];
+ } while (++j<N);
+ }
+ celt_assert2(pulsesLeft>=1, "Allocated too many pulses in the quick pass");
+
+ /* This should never happen, but just in case it does (e.g. on silence)
+ we fill the first bin with pulses. */
+#ifdef FIXED_POINT_DEBUG
+ celt_assert2(pulsesLeft<=N+3, "Not enough pulses in the quick pass");
+#endif
+ if (pulsesLeft > N+3)
+ {
+ opus_val16 tmp = (opus_val16)pulsesLeft;
+ yy = MAC16_16(yy, tmp, tmp);
+ yy = MAC16_16(yy, tmp, y[0]);
+ iy[0] += pulsesLeft;
+ pulsesLeft=0;
+ }
+
+ s = 1;
+ for (i=0;i<pulsesLeft;i++)
+ {
+ int best_id;
+ opus_val32 best_num = -VERY_LARGE16;
+ opus_val16 best_den = 0;
+#ifdef FIXED_POINT
+ int rshift;
+#endif
+#ifdef FIXED_POINT
+ rshift = 1+celt_ilog2(K-pulsesLeft+i+1);
+#endif
+ best_id = 0;
+ /* The squared magnitude term gets added anyway, so we might as well
+ add it outside the loop */
+ yy = ADD32(yy, 1);
+ j=0;
+ do {
+ opus_val16 Rxy, Ryy;
+ /* Temporary sums of the new pulse(s) */
+ Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[j])),rshift));
+ /* We're multiplying y[j] by two so we don't have to do it here */
+ Ryy = ADD16(yy, y[j]);
+
+ /* Approximate score: we maximise Rxy/sqrt(Ryy) (we're guaranteed that
+ Rxy is positive because the sign is pre-computed) */
+ Rxy = MULT16_16_Q15(Rxy,Rxy);
+ /* The idea is to check for num/den >= best_num/best_den, but that way
+ we can do it without any division */
+ /* OPT: Make sure to use conditional moves here */
+ if (MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num))
+ {
+ best_den = Ryy;
+ best_num = Rxy;
+ best_id = j;
+ }
+ } while (++j<N);
+
+ /* Updating the sums of the new pulse(s) */
+ xy = ADD32(xy, EXTEND32(X[best_id]));
+ /* We're multiplying y[j] by two so we don't have to do it here */
+ yy = ADD16(yy, y[best_id]);
+
+ /* Only now that we've made the final choice, update y/iy */
+ /* Multiplying y[j] by 2 so we don't have to do it everywhere else */
+ y[best_id] += 2*s;
+ iy[best_id]++;
+ }
+
+ /* Put the original sign back */
+ j=0;
+ do {
+ X[j] = MULT16_16(signx[j],X[j]);
+ if (signx[j] < 0)
+ iy[j] = -iy[j];
+ } while (++j<N);
+ encode_pulses(iy, N, K, enc);
+
+#ifdef RESYNTH
+ normalise_residual(iy, X, N, yy, gain);
+ exp_rotation(X, N, -1, B, K, spread);
+#endif
+
+ collapse_mask = extract_collapse_mask(iy, N, B);
+ RESTORE_STACK;
+ return collapse_mask;
+}
+
+/** Decode pulse vector and combine the result with the pitch vector to produce
+ the final normalised signal in the current band. */
+unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,
+ ec_dec *dec, opus_val16 gain)
+{
+ int i;
+ opus_val32 Ryy;
+ unsigned collapse_mask;
+ VARDECL(int, iy);
+ SAVE_STACK;
+
+ celt_assert2(K>0, "alg_unquant() needs at least one pulse");
+ celt_assert2(N>1, "alg_unquant() needs at least two dimensions");
+ ALLOC(iy, N, int);
+ decode_pulses(iy, N, K, dec);
+ Ryy = 0;
+ i=0;
+ do {
+ Ryy = MAC16_16(Ryy, iy[i], iy[i]);
+ } while (++i < N);
+ normalise_residual(iy, X, N, Ryy, gain);
+ exp_rotation(X, N, -1, B, K, spread);
+ collapse_mask = extract_collapse_mask(iy, N, B);
+ RESTORE_STACK;
+ return collapse_mask;
+}
+
+void renormalise_vector(celt_norm *X, int N, opus_val16 gain)
+{
+ int i;
+#ifdef FIXED_POINT
+ int k;
+#endif
+ opus_val32 E = EPSILON;
+ opus_val16 g;
+ opus_val32 t;
+ celt_norm *xptr = X;
+ for (i=0;i<N;i++)
+ {
+ E = MAC16_16(E, *xptr, *xptr);
+ xptr++;
+ }
+#ifdef FIXED_POINT
+ k = celt_ilog2(E)>>1;
+#endif
+ t = VSHR32(E, 2*(k-7));
+ g = MULT16_16_P15(celt_rsqrt_norm(t),gain);
+
+ xptr = X;
+ for (i=0;i<N;i++)
+ {
+ *xptr = EXTRACT16(PSHR32(MULT16_16(g, *xptr), k+1));
+ xptr++;
+ }
+ /*return celt_sqrt(E);*/
+}
+
+int stereo_itheta(celt_norm *X, celt_norm *Y, int stereo, int N)
+{
+ int i;
+ int itheta;
+ opus_val16 mid, side;
+ opus_val32 Emid, Eside;
+
+ Emid = Eside = EPSILON;
+ if (stereo)
+ {
+ for (i=0;i<N;i++)
+ {
+ celt_norm m, s;
+ m = ADD16(SHR16(X[i],1),SHR16(Y[i],1));
+ s = SUB16(SHR16(X[i],1),SHR16(Y[i],1));
+ Emid = MAC16_16(Emid, m, m);
+ Eside = MAC16_16(Eside, s, s);
+ }
+ } else {
+ for (i=0;i<N;i++)
+ {
+ celt_norm m, s;
+ m = X[i];
+ s = Y[i];
+ Emid = MAC16_16(Emid, m, m);
+ Eside = MAC16_16(Eside, s, s);
+ }
+ }
+ mid = celt_sqrt(Emid);
+ side = celt_sqrt(Eside);
+#ifdef FIXED_POINT
+ /* 0.63662 = 2/pi */
+ itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid));
+#else
+ itheta = (int)floor(.5f+16384*0.63662f*atan2(side,mid));
+#endif
+
+ return itheta;
+}
diff --git a/lib/rbcodec/codecs/libopus/celt/vq.h b/lib/rbcodec/codecs/libopus/celt/vq.h
new file mode 100644
index 0000000000..1ceeeeb268
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/vq.h
@@ -0,0 +1,73 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/**
+ @file vq.h
+ @brief Vector quantisation of the residual
+ */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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 VQ_H
+#define VQ_H
+
+#include "entenc.h"
+#include "entdec.h"
+#include "modes.h"
+
+/** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of
+ * the pitch and a combination of pulses such that its norm is still equal
+ * to 1. This is the function that will typically require the most CPU.
+ * @param x Residual signal to quantise/encode (returns quantised version)
+ * @param W Perceptual weight to use when optimising (currently unused)
+ * @param N Number of samples to encode
+ * @param K Number of pulses to use
+ * @param p Pitch vector (it is assumed that p+x is a unit vector)
+ * @param enc Entropy encoder state
+ * @ret A mask indicating which blocks in the band received pulses
+*/
+unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B,
+ ec_enc *enc
+#ifdef RESYNTH
+ , opus_val16 gain
+#endif
+ );
+
+/** Algebraic pulse decoder
+ * @param x Decoded normalised spectrum (returned)
+ * @param N Number of samples to decode
+ * @param K Number of pulses to use
+ * @param p Pitch vector (automatically added to x)
+ * @param dec Entropy decoder state
+ * @ret A mask indicating which blocks in the band received pulses
+ */
+unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,
+ ec_dec *dec, opus_val16 gain);
+
+void renormalise_vector(celt_norm *X, int N, opus_val16 gain);
+
+int stereo_itheta(celt_norm *X, celt_norm *Y, int stereo, int N);
+
+#endif /* VQ_H */
diff --git a/lib/rbcodec/codecs/libopus/libopus.make b/lib/rbcodec/codecs/libopus/libopus.make
new file mode 100644
index 0000000000..1df52dbe4f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/libopus.make
@@ -0,0 +1,24 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id$
+#
+
+# libopus
+OPUSLIB := $(CODECDIR)/libopus.a
+OPUSLIB_SRC := $(call preprocess, $(RBCODECLIB_DIR)/codecs/libopus/SOURCES)
+OPUSLIB_OBJ := $(call c2obj, $(OPUSLIB_SRC))
+
+# codec specific compilation flags
+$(OPUSLIB) : CODECFLAGS += -DHAVE_CONFIG_H \
+ -I$(RBCODECLIB_DIR)/codecs/libopus \
+ -I$(RBCODECLIB_DIR)/codecs/libopus/celt \
+ -I$(RBCODECLIB_DIR)/codecs/libopus/silk \
+ -I$(RBCODECLIB_DIR)/codecs/libopus/silk/fixed
+
+$(OPUSLIB): $(OPUSLIB_OBJ)
+ $(SILENT)$(shell rm -f $@)
+ $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null
diff --git a/lib/rbcodec/codecs/libopus/ogg/framing.c b/lib/rbcodec/codecs/libopus/ogg/framing.c
new file mode 100644
index 0000000000..f007de176a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/ogg/framing.c
@@ -0,0 +1,1025 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: code raw packets into framed OggSquish stream and
+ decode Ogg streams back into raw packets
+ last mod: $Id: framing.c 18052 2011-08-04 17:57:02Z giles $
+
+ note: The CRC code is directly derived from public domain code by
+ Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html
+ for details.
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ogg/ogg.h>
+
+/* A complete description of Ogg framing exists in docs/framing.html */
+
+int ogg_page_version(const ogg_page *og){
+ return((int)(og->header[4]));
+}
+
+int ogg_page_continued(const ogg_page *og){
+ return((int)(og->header[5]&0x01));
+}
+
+int ogg_page_bos(const ogg_page *og){
+ return((int)(og->header[5]&0x02));
+}
+
+int ogg_page_eos(const ogg_page *og){
+ return((int)(og->header[5]&0x04));
+}
+
+ogg_int64_t ogg_page_granulepos(const ogg_page *og){
+ unsigned char *page=og->header;
+ ogg_int64_t granulepos=page[13]&(0xff);
+ granulepos= (granulepos<<8)|(page[12]&0xff);
+ granulepos= (granulepos<<8)|(page[11]&0xff);
+ granulepos= (granulepos<<8)|(page[10]&0xff);
+ granulepos= (granulepos<<8)|(page[9]&0xff);
+ granulepos= (granulepos<<8)|(page[8]&0xff);
+ granulepos= (granulepos<<8)|(page[7]&0xff);
+ granulepos= (granulepos<<8)|(page[6]&0xff);
+ return(granulepos);
+}
+
+int ogg_page_serialno(const ogg_page *og){
+ return(og->header[14] |
+ (og->header[15]<<8) |
+ (og->header[16]<<16) |
+ (og->header[17]<<24));
+}
+
+long ogg_page_pageno(const ogg_page *og){
+ return(og->header[18] |
+ (og->header[19]<<8) |
+ (og->header[20]<<16) |
+ (og->header[21]<<24));
+}
+
+
+
+/* returns the number of packets that are completed on this page (if
+ the leading packet is begun on a previous page, but ends on this
+ page, it's counted */
+
+/* NOTE:
+ If a page consists of a packet begun on a previous page, and a new
+ packet begun (but not completed) on this page, the return will be:
+ ogg_page_packets(page) ==1,
+ ogg_page_continued(page) !=0
+
+ If a page happens to be a single packet that was begun on a
+ previous page, and spans to the next page (in the case of a three or
+ more page packet), the return will be:
+ ogg_page_packets(page) ==0,
+ ogg_page_continued(page) !=0
+*/
+
+int ogg_page_packets(const ogg_page *og){
+ int i,n=og->header[26],count=0;
+ for(i=0;i<n;i++)
+ if(og->header[27+i]<255)count++;
+ return(count);
+}
+
+
+#if 0
+/* helper to initialize lookup for direct-table CRC (illustrative; we
+ use the static init below) */
+
+static ogg_uint32_t _ogg_crc_entry(unsigned long index){
+ int i;
+ unsigned long r;
+
+ r = index << 24;
+ for (i=0; i<8; i++)
+ if (r & 0x80000000UL)
+ r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator
+ polynomial, although we use an
+ unreflected alg and an init/final
+ of 0, not 0xffffffff */
+ else
+ r<<=1;
+ return (r & 0xffffffffUL);
+}
+#endif
+
+static const ogg_uint32_t crc_lookup[256]={
+ 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
+ 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
+ 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
+ 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
+ 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
+ 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
+ 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
+ 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
+ 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
+ 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
+ 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
+ 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
+ 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
+ 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
+ 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
+ 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
+ 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
+ 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
+ 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
+ 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
+ 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
+ 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
+ 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
+ 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
+ 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
+ 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
+ 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
+ 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
+ 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
+ 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
+ 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
+ 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
+ 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
+ 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
+ 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
+ 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
+ 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
+ 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
+ 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
+ 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
+ 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
+ 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
+ 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
+ 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
+ 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
+ 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
+ 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
+ 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
+ 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
+ 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
+ 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
+ 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
+ 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
+ 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
+ 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
+ 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
+ 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
+ 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
+ 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
+ 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
+ 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
+ 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
+ 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
+ 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
+
+/* init the encode/decode logical stream state */
+
+int ogg_stream_init(ogg_stream_state *os,int serialno){
+ if(os){
+ memset(os,0,sizeof(*os));
+ os->body_storage=16*1024;
+ os->lacing_storage=1024;
+
+ os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data));
+ os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
+ os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals));
+
+ if(!os->body_data || !os->lacing_vals || !os->granule_vals){
+ ogg_stream_clear(os);
+ return -1;
+ }
+
+ os->serialno=serialno;
+
+ return(0);
+ }
+ return(-1);
+}
+
+/* async/delayed error detection for the ogg_stream_state */
+int ogg_stream_check(ogg_stream_state *os){
+ if(!os || !os->body_data) return -1;
+ return 0;
+}
+
+/* _clear does not free os, only the non-flat storage within */
+int ogg_stream_clear(ogg_stream_state *os){
+ if(os){
+ if(os->body_data)_ogg_free(os->body_data);
+ if(os->lacing_vals)_ogg_free(os->lacing_vals);
+ if(os->granule_vals)_ogg_free(os->granule_vals);
+
+ memset(os,0,sizeof(*os));
+ }
+ return(0);
+}
+
+int ogg_stream_destroy(ogg_stream_state *os){
+ if(os){
+ ogg_stream_clear(os);
+ _ogg_free(os);
+ }
+ return(0);
+}
+
+/* Helpers for ogg_stream_encode; this keeps the structure and
+ what's happening fairly clear */
+
+static int _os_body_expand(ogg_stream_state *os,int needed){
+ if(os->body_storage<=os->body_fill+needed){
+ void *ret;
+ ret=_ogg_realloc(os->body_data,(os->body_storage+needed+1024)*
+ sizeof(*os->body_data));
+ if(!ret){
+ ogg_stream_clear(os);
+ return -1;
+ }
+ os->body_storage+=(needed+1024);
+ os->body_data=ret;
+ }
+ return 0;
+}
+
+static int _os_lacing_expand(ogg_stream_state *os,int needed){
+ if(os->lacing_storage<=os->lacing_fill+needed){
+ void *ret;
+ ret=_ogg_realloc(os->lacing_vals,(os->lacing_storage+needed+32)*
+ sizeof(*os->lacing_vals));
+ if(!ret){
+ ogg_stream_clear(os);
+ return -1;
+ }
+ os->lacing_vals=ret;
+ ret=_ogg_realloc(os->granule_vals,(os->lacing_storage+needed+32)*
+ sizeof(*os->granule_vals));
+ if(!ret){
+ ogg_stream_clear(os);
+ return -1;
+ }
+ os->granule_vals=ret;
+ os->lacing_storage+=(needed+32);
+ }
+ return 0;
+}
+
+/* checksum the page */
+/* Direct table CRC; note that this will be faster in the future if we
+ perform the checksum simultaneously with other copies */
+
+void ogg_page_checksum_set(ogg_page *og){
+ if(og){
+ ogg_uint32_t crc_reg=0;
+ int i;
+
+ /* safety; needed for API behavior, but not framing code */
+ og->header[22]=0;
+ og->header[23]=0;
+ og->header[24]=0;
+ og->header[25]=0;
+
+ for(i=0;i<og->header_len;i++)
+ crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
+ for(i=0;i<og->body_len;i++)
+ crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
+
+ og->header[22]=(unsigned char)(crc_reg&0xff);
+ og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
+ og->header[24]=(unsigned char)((crc_reg>>16)&0xff);
+ og->header[25]=(unsigned char)((crc_reg>>24)&0xff);
+ }
+}
+
+/* submit data to the internal buffer of the framing engine */
+int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
+ long e_o_s, ogg_int64_t granulepos){
+
+ int bytes = 0, lacing_vals, i;
+
+ if(ogg_stream_check(os)) return -1;
+ if(!iov) return 0;
+
+ for (i = 0; i < count; ++i) bytes += (int)iov[i].iov_len;
+ lacing_vals=bytes/255+1;
+
+ if(os->body_returned){
+ /* advance packet data according to the body_returned pointer. We
+ had to keep it around to return a pointer into the buffer last
+ call */
+
+ os->body_fill-=os->body_returned;
+ if(os->body_fill)
+ memmove(os->body_data,os->body_data+os->body_returned,
+ os->body_fill);
+ os->body_returned=0;
+ }
+
+ /* make sure we have the buffer storage */
+ if(_os_body_expand(os,bytes) || _os_lacing_expand(os,lacing_vals))
+ return -1;
+
+ /* Copy in the submitted packet. Yes, the copy is a waste; this is
+ the liability of overly clean abstraction for the time being. It
+ will actually be fairly easy to eliminate the extra copy in the
+ future */
+
+ for (i = 0; i < count; ++i) {
+ memcpy(os->body_data+os->body_fill, iov[i].iov_base, iov[i].iov_len);
+ os->body_fill += (int)iov[i].iov_len;
+ }
+
+ /* Store lacing vals for this packet */
+ for(i=0;i<lacing_vals-1;i++){
+ os->lacing_vals[os->lacing_fill+i]=255;
+ os->granule_vals[os->lacing_fill+i]=os->granulepos;
+ }
+ os->lacing_vals[os->lacing_fill+i]=bytes%255;
+ os->granulepos=os->granule_vals[os->lacing_fill+i]=granulepos;
+
+ /* flag the first segment as the beginning of the packet */
+ os->lacing_vals[os->lacing_fill]|= 0x100;
+
+ os->lacing_fill+=lacing_vals;
+
+ /* for the sake of completeness */
+ os->packetno++;
+
+ if(e_o_s)os->e_o_s=1;
+
+ return(0);
+}
+
+int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
+ ogg_iovec_t iov;
+ iov.iov_base = op->packet;
+ iov.iov_len = op->bytes;
+ return ogg_stream_iovecin(os, &iov, 1, op->e_o_s, op->granulepos);
+}
+
+/* Conditionally flush a page; force==0 will only flush nominal-size
+ pages, force==1 forces us to flush a page regardless of page size
+ so long as there's any data available at all. */
+static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int nfill){
+ int i;
+ int vals=0;
+ int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
+ int bytes=0;
+ long acc=0;
+ ogg_int64_t granule_pos=-1;
+
+ if(ogg_stream_check(os)) return(0);
+ if(maxvals==0) return(0);
+
+ /* construct a page */
+ /* decide how many segments to include */
+
+ /* If this is the initial header case, the first page must only include
+ the initial header packet */
+ if(os->b_o_s==0){ /* 'initial header page' case */
+ granule_pos=0;
+ for(vals=0;vals<maxvals;vals++){
+ if((os->lacing_vals[vals]&0x0ff)<255){
+ vals++;
+ break;
+ }
+ }
+ }else{
+
+ /* The extra packets_done, packet_just_done logic here attempts to do two things:
+ 1) Don't unneccessarily span pages.
+ 2) Unless necessary, don't flush pages if there are less than four packets on
+ them; this expands page size to reduce unneccessary overhead if incoming packets
+ are large.
+ These are not necessary behaviors, just 'always better than naive flushing'
+ without requiring an application to explicitly request a specific optimized
+ behavior. We'll want an explicit behavior setup pathway eventually as well. */
+
+ int packets_done=0;
+ int packet_just_done=0;
+ for(vals=0;vals<maxvals;vals++){
+ if(acc>nfill && packet_just_done>=4){
+ force=1;
+ break;
+ }
+ acc+=os->lacing_vals[vals]&0x0ff;
+ if((os->lacing_vals[vals]&0xff)<255){
+ granule_pos=os->granule_vals[vals];
+ packet_just_done=++packets_done;
+ }else
+ packet_just_done=0;
+ }
+ if(vals==255)force=1;
+ }
+
+ if(!force) return(0);
+
+ /* construct the header in temp storage */
+ memcpy(os->header,"OggS",4);
+
+ /* stream structure version */
+ os->header[4]=0x00;
+
+ /* continued packet flag? */
+ os->header[5]=0x00;
+ if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
+ /* first page flag? */
+ if(os->b_o_s==0)os->header[5]|=0x02;
+ /* last page flag? */
+ if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04;
+ os->b_o_s=1;
+
+ /* 64 bits of PCM position */
+ for(i=6;i<14;i++){
+ os->header[i]=(unsigned char)(granule_pos&0xff);
+ granule_pos>>=8;
+ }
+
+ /* 32 bits of stream serial number */
+ {
+ long serialno=os->serialno;
+ for(i=14;i<18;i++){
+ os->header[i]=(unsigned char)(serialno&0xff);
+ serialno>>=8;
+ }
+ }
+
+ /* 32 bits of page counter (we have both counter and page header
+ because this val can roll over) */
+ if(os->pageno==-1)os->pageno=0; /* because someone called
+ stream_reset; this would be a
+ strange thing to do in an
+ encode stream, but it has
+ plausible uses */
+ {
+ long pageno=os->pageno++;
+ for(i=18;i<22;i++){
+ os->header[i]=(unsigned char)(pageno&0xff);
+ pageno>>=8;
+ }
+ }
+
+ /* zero for computation; filled in later */
+ os->header[22]=0;
+ os->header[23]=0;
+ os->header[24]=0;
+ os->header[25]=0;
+
+ /* segment table */
+ os->header[26]=(unsigned char)(vals&0xff);
+ for(i=0;i<vals;i++)
+ bytes+=os->header[i+27]=(unsigned char)(os->lacing_vals[i]&0xff);
+
+ /* set pointers in the ogg_page struct */
+ og->header=os->header;
+ og->header_len=os->header_fill=vals+27;
+ og->body=os->body_data+os->body_returned;
+ og->body_len=bytes;
+
+ /* advance the lacing data and set the body_returned pointer */
+
+ os->lacing_fill-=vals;
+ memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
+ memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
+ os->body_returned+=bytes;
+
+ /* calculate the checksum */
+
+ ogg_page_checksum_set(og);
+
+ /* done */
+ return(1);
+}
+
+/* This will flush remaining packets into a page (returning nonzero),
+ even if there is not enough data to trigger a flush normally
+ (undersized page). If there are no packets or partial packets to
+ flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will
+ try to flush a normal sized page like ogg_stream_pageout; a call to
+ ogg_stream_flush does not guarantee that all packets have flushed.
+ Only a return value of 0 from ogg_stream_flush indicates all packet
+ data is flushed into pages.
+
+ since ogg_stream_flush will flush the last page in a stream even if
+ it's undersized, you almost certainly want to use ogg_stream_pageout
+ (and *not* ogg_stream_flush) unless you specifically need to flush
+ a page regardless of size in the middle of a stream. */
+
+int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){
+ return ogg_stream_flush_i(os,og,1,4096);
+}
+
+/* Like the above, but an argument is provided to adjust the nominal
+ page size for applications which are smart enough to provide their
+ own delay based flushing */
+
+int ogg_stream_flush_fill(ogg_stream_state *os,ogg_page *og, int nfill){
+ return ogg_stream_flush_i(os,og,1,nfill);
+}
+
+/* This constructs pages from buffered packet segments. The pointers
+returned are to static buffers; do not free. The returned buffers are
+good only until the next call (using the same ogg_stream_state) */
+
+int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
+ int force=0;
+ if(ogg_stream_check(os)) return 0;
+
+ if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */
+ (os->lacing_fill&&!os->b_o_s)) /* 'initial header page' case */
+ force=1;
+
+ return(ogg_stream_flush_i(os,og,force,4096));
+}
+
+/* Like the above, but an argument is provided to adjust the nominal
+page size for applications which are smart enough to provide their
+own delay based flushing */
+
+int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill){
+ int force=0;
+ if(ogg_stream_check(os)) return 0;
+
+ if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */
+ (os->lacing_fill&&!os->b_o_s)) /* 'initial header page' case */
+ force=1;
+
+ return(ogg_stream_flush_i(os,og,force,nfill));
+}
+
+int ogg_stream_eos(ogg_stream_state *os){
+ if(ogg_stream_check(os)) return 1;
+ return os->e_o_s;
+}
+
+/* DECODING PRIMITIVES: packet streaming layer **********************/
+
+/* This has two layers to place more of the multi-serialno and paging
+ control in the application's hands. First, we expose a data buffer
+ using ogg_sync_buffer(). The app either copies into the
+ buffer, or passes it directly to read(), etc. We then call
+ ogg_sync_wrote() to tell how many bytes we just added.
+
+ Pages are returned (pointers into the buffer in ogg_sync_state)
+ by ogg_sync_pageout(). The page is then submitted to
+ ogg_stream_pagein() along with the appropriate
+ ogg_stream_state* (ie, matching serialno). We then get raw
+ packets out calling ogg_stream_packetout() with a
+ ogg_stream_state. */
+
+/* initialize the struct to a known state */
+int ogg_sync_init(ogg_sync_state *oy){
+ if(oy){
+ oy->storage = -1; /* used as a readiness flag */
+ memset(oy,0,sizeof(*oy));
+ }
+ return(0);
+}
+
+/* clear non-flat storage within */
+int ogg_sync_clear(ogg_sync_state *oy){
+ if(oy){
+ if(oy->data)_ogg_free(oy->data);
+ memset(oy,0,sizeof(*oy));
+ }
+ return(0);
+}
+
+int ogg_sync_destroy(ogg_sync_state *oy){
+ if(oy){
+ ogg_sync_clear(oy);
+ _ogg_free(oy);
+ }
+ return(0);
+}
+
+int ogg_sync_check(ogg_sync_state *oy){
+ if(oy->storage<0) return -1;
+ return 0;
+}
+
+char *ogg_sync_buffer(ogg_sync_state *oy, long size){
+ if(ogg_sync_check(oy)) return NULL;
+
+ /* first, clear out any space that has been previously returned */
+ if(oy->returned){
+ oy->fill-=oy->returned;
+ if(oy->fill>0)
+ memmove(oy->data,oy->data+oy->returned,oy->fill);
+ oy->returned=0;
+ }
+
+ if(size>oy->storage-oy->fill){
+ /* We need to extend the internal buffer */
+ long newsize=size+oy->fill+4096; /* an extra page to be nice */
+ void *ret;
+
+ if(oy->data)
+ ret=_ogg_realloc(oy->data,newsize);
+ else
+ ret=_ogg_malloc(newsize);
+ if(!ret){
+ ogg_sync_clear(oy);
+ return NULL;
+ }
+ oy->data=ret;
+ oy->storage=newsize;
+ }
+
+ /* expose a segment at least as large as requested at the fill mark */
+ return((char *)oy->data+oy->fill);
+}
+
+int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
+ if(ogg_sync_check(oy))return -1;
+ if(oy->fill+bytes>oy->storage)return -1;
+ oy->fill+=bytes;
+ return(0);
+}
+
+/* sync the stream. This is meant to be useful for finding page
+ boundaries.
+
+ return values for this:
+ -n) skipped n bytes
+ 0) page not ready; more data (no bytes skipped)
+ n) page synced at current location; page length n bytes
+
+*/
+
+long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
+ unsigned char *page=oy->data+oy->returned;
+ unsigned char *next;
+ long bytes=oy->fill-oy->returned;
+
+ if(ogg_sync_check(oy))return 0;
+
+ if(oy->headerbytes==0){
+ int headerbytes,i;
+ if(bytes<27)return(0); /* not enough for a header */
+
+ /* verify capture pattern */
+ if(memcmp(page,"OggS",4))goto sync_fail;
+
+ headerbytes=page[26]+27;
+ if(bytes<headerbytes)return(0); /* not enough for header + seg table */
+
+ /* count up body length in the segment table */
+
+ for(i=0;i<page[26];i++)
+ oy->bodybytes+=page[27+i];
+ oy->headerbytes=headerbytes;
+ }
+
+ if(oy->bodybytes+oy->headerbytes>bytes)return(0);
+
+ /* The whole test page is buffered. Verify the checksum */
+ if (0) {
+ /* Grab the checksum bytes, set the header field to zero */
+ char chksum[4];
+ ogg_page log;
+
+ memcpy(chksum,page+22,4);
+ memset(page+22,0,4);
+
+ /* set up a temp page struct and recompute the checksum */
+ log.header=page;
+ log.header_len=oy->headerbytes;
+ log.body=page+oy->headerbytes;
+ log.body_len=oy->bodybytes;
+ ogg_page_checksum_set(&log);
+
+ /* Compare */
+ if(memcmp(chksum,page+22,4)){
+ /* D'oh. Mismatch! Corrupt page (or miscapture and not a page
+ at all) */
+ /* replace the computed checksum with the one actually read in */
+ memcpy(page+22,chksum,4);
+
+ /* Bad checksum. Lose sync */
+ goto sync_fail;
+ }
+ }
+
+ /* yes, have a whole page all ready to go */
+ {
+ unsigned char *page=oy->data+oy->returned;
+ long bytes;
+
+ if(og){
+ og->header=page;
+ og->header_len=oy->headerbytes;
+ og->body=page+oy->headerbytes;
+ og->body_len=oy->bodybytes;
+ }
+
+ oy->unsynced=0;
+ oy->returned+=(bytes=oy->headerbytes+oy->bodybytes);
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+ return(bytes);
+ }
+
+ sync_fail:
+
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+
+ /* search for possible capture */
+ next=memchr(page+1,'O',bytes-1);
+ if(!next)
+ next=oy->data+oy->fill;
+
+ oy->returned=(int)(next-oy->data);
+ return((long)-(next-page));
+}
+
+/* sync the stream and get a page. Keep trying until we find a page.
+ Suppress 'sync errors' after reporting the first.
+
+ return values:
+ -1) recapture (hole in data)
+ 0) need more data
+ 1) page returned
+
+ Returns pointers into buffered data; invalidated by next call to
+ _stream, _clear, _init, or _buffer */
+
+int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
+
+ if(ogg_sync_check(oy))return 0;
+
+ /* all we need to do is verify a page at the head of the stream
+ buffer. If it doesn't verify, we look for the next potential
+ frame */
+
+ for(;;){
+ long ret=ogg_sync_pageseek(oy,og);
+ if(ret>0){
+ /* have a page */
+ return(1);
+ }
+ if(ret==0){
+ /* need more data */
+ return(0);
+ }
+
+ /* head did not start a synced page... skipped some bytes */
+ if(!oy->unsynced){
+ oy->unsynced=1;
+ return(-1);
+ }
+
+ /* loop. keep looking */
+ }
+}
+
+/* add the incoming page to the stream state; we decompose the page
+ into packet segments here as well. */
+
+int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
+ unsigned char *header=og->header;
+ unsigned char *body=og->body;
+ long bodysize=og->body_len;
+ int segptr=0;
+
+ int version=ogg_page_version(og);
+ int continued=ogg_page_continued(og);
+ int bos=ogg_page_bos(og);
+ int eos=ogg_page_eos(og);
+ ogg_int64_t granulepos=ogg_page_granulepos(og);
+ int serialno=ogg_page_serialno(og);
+ long pageno=ogg_page_pageno(og);
+ int segments=header[26];
+
+ if(ogg_stream_check(os)) return -1;
+
+ /* clean up 'returned data' */
+ {
+ long lr=os->lacing_returned;
+ long br=os->body_returned;
+
+ /* body data */
+ if(br){
+ os->body_fill-=br;
+ if(os->body_fill)
+ memmove(os->body_data,os->body_data+br,os->body_fill);
+ os->body_returned=0;
+ }
+
+ if(lr){
+ /* segment table */
+ if(os->lacing_fill-lr){
+ memmove(os->lacing_vals,os->lacing_vals+lr,
+ (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
+ memmove(os->granule_vals,os->granule_vals+lr,
+ (os->lacing_fill-lr)*sizeof(*os->granule_vals));
+ }
+ os->lacing_fill-=lr;
+ os->lacing_packet-=lr;
+ os->lacing_returned=0;
+ }
+ }
+
+ /* check the serial number */
+ if(serialno!=os->serialno)return(-1);
+ if(version>0)return(-1);
+
+ if(_os_lacing_expand(os,segments+1)) return -1;
+
+ /* are we in sequence? */
+ if(pageno!=os->pageno){
+ int i;
+
+ /* unroll previous partial packet (if any) */
+ for(i=os->lacing_packet;i<os->lacing_fill;i++)
+ os->body_fill-=os->lacing_vals[i]&0xff;
+ os->lacing_fill=os->lacing_packet;
+
+ /* make a note of dropped data in segment table */
+ if(os->pageno!=-1){
+ os->lacing_vals[os->lacing_fill++]=0x400;
+ os->lacing_packet++;
+ }
+ }
+
+ /* are we a 'continued packet' page? If so, we may need to skip
+ some segments */
+ if(continued){
+ if(os->lacing_fill<1 ||
+ os->lacing_vals[os->lacing_fill-1]==0x400){
+ bos=0;
+ for(;segptr<segments;segptr++){
+ int val=header[27+segptr];
+ body+=val;
+ bodysize-=val;
+ if(val<255){
+ segptr++;
+ break;
+ }
+ }
+ }
+ }
+
+ if(bodysize){
+ if(_os_body_expand(os,bodysize)) return -1;
+ memcpy(os->body_data+os->body_fill,body,bodysize);
+ os->body_fill+=bodysize;
+ }
+
+ {
+ int saved=-1;
+ while(segptr<segments){
+ int val=header[27+segptr];
+ os->lacing_vals[os->lacing_fill]=val;
+ os->granule_vals[os->lacing_fill]=-1;
+
+ if(bos){
+ os->lacing_vals[os->lacing_fill]|=0x100;
+ bos=0;
+ }
+
+ if(val<255)saved=os->lacing_fill;
+
+ os->lacing_fill++;
+ segptr++;
+
+ if(val<255)os->lacing_packet=os->lacing_fill;
+ }
+
+ /* set the granulepos on the last granuleval of the last full packet */
+ if(saved!=-1){
+ os->granule_vals[saved]=granulepos;
+ }
+
+ }
+
+ if(eos){
+ os->e_o_s=1;
+ if(os->lacing_fill>0)
+ os->lacing_vals[os->lacing_fill-1]|=0x200;
+ }
+
+ os->pageno=pageno+1;
+
+ return(0);
+}
+
+/* clear things to an initial state. Good to call, eg, before seeking */
+int ogg_sync_reset(ogg_sync_state *oy){
+ if(ogg_sync_check(oy))return -1;
+
+ oy->fill=0;
+ oy->returned=0;
+ oy->unsynced=0;
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+ return(0);
+}
+
+int ogg_stream_reset(ogg_stream_state *os){
+ if(ogg_stream_check(os)) return -1;
+
+ os->body_fill=0;
+ os->body_returned=0;
+
+ os->lacing_fill=0;
+ os->lacing_packet=0;
+ os->lacing_returned=0;
+
+ os->header_fill=0;
+
+ os->e_o_s=0;
+ os->b_o_s=0;
+ os->pageno=-1;
+ os->packetno=0;
+ os->granulepos=0;
+
+ return(0);
+}
+
+int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){
+ if(ogg_stream_check(os)) return -1;
+ ogg_stream_reset(os);
+ os->serialno=serialno;
+ return(0);
+}
+
+static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){
+
+ /* The last part of decode. We have the stream broken into packet
+ segments. Now we need to group them into packets (or return the
+ out of sync markers) */
+
+ int ptr=os->lacing_returned;
+
+ if(os->lacing_packet<=ptr)return(0);
+
+ if(os->lacing_vals[ptr]&0x400){
+ /* we need to tell the codec there's a gap; it might need to
+ handle previous packet dependencies. */
+ os->lacing_returned++;
+ os->packetno++;
+ return(-1);
+ }
+
+ if(!op && !adv)return(1); /* just using peek as an inexpensive way
+ to ask if there's a whole packet
+ waiting */
+
+ /* Gather the whole packet. We'll have no holes or a partial packet */
+ {
+ int size=os->lacing_vals[ptr]&0xff;
+ long bytes=size;
+ int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */
+ int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */
+
+ while(size==255){
+ int val=os->lacing_vals[++ptr];
+ size=val&0xff;
+ if(val&0x200)eos=0x200;
+ bytes+=size;
+ }
+
+ if(op){
+ op->e_o_s=eos;
+ op->b_o_s=bos;
+ op->packet=os->body_data+os->body_returned;
+ op->packetno=os->packetno;
+ op->granulepos=os->granule_vals[ptr];
+ op->bytes=bytes;
+ }
+
+ if(adv){
+ os->body_returned+=bytes;
+ os->lacing_returned=ptr+1;
+ os->packetno++;
+ }
+ }
+ return(1);
+}
+
+int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){
+ if(ogg_stream_check(os)) return 0;
+ return _packetout(os,op,1);
+}
+
+int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){
+ if(ogg_stream_check(os)) return 0;
+ return _packetout(os,op,0);
+}
+
+void ogg_packet_clear(ogg_packet *op) {
+ _ogg_free(op->packet);
+ memset(op, 0, sizeof(*op));
+}
+
diff --git a/lib/rbcodec/codecs/libopus/ogg/ogg.h b/lib/rbcodec/codecs/libopus/ogg/ogg.h
new file mode 100644
index 0000000000..00975ca354
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/ogg/ogg.h
@@ -0,0 +1,210 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: toplevel libogg include
+ last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $
+
+ ********************************************************************/
+#ifndef _OGG_H
+#define _OGG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include "os_types.h"
+
+typedef struct {
+ void *iov_base;
+ size_t iov_len;
+} ogg_iovec_t;
+
+typedef struct {
+ long endbyte;
+ int endbit;
+
+ unsigned char *buffer;
+ unsigned char *ptr;
+ long storage;
+} oggpack_buffer;
+
+/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
+
+typedef struct {
+ unsigned char *header;
+ long header_len;
+ unsigned char *body;
+ long body_len;
+} ogg_page;
+
+/* ogg_stream_state contains the current encode/decode state of a logical
+ Ogg bitstream **********************************************************/
+
+typedef struct {
+ unsigned char *body_data; /* bytes from packet bodies */
+ long body_storage; /* storage elements allocated */
+ long body_fill; /* elements stored; fill mark */
+ long body_returned; /* elements of fill returned */
+
+
+ int *lacing_vals; /* The values that will go to the segment table */
+ ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
+ this way, but it is simple coupled to the
+ lacing fifo */
+ long lacing_storage;
+ long lacing_fill;
+ long lacing_packet;
+ long lacing_returned;
+
+ unsigned char header[282]; /* working space for header encode */
+ int header_fill;
+
+ int e_o_s; /* set when we have buffered the last packet in the
+ logical bitstream */
+ int b_o_s; /* set after we've written the initial page
+ of a logical bitstream */
+ long serialno;
+ long pageno;
+ ogg_int64_t packetno; /* sequence number for decode; the framing
+ knows where there's a hole in the data,
+ but we need coupling so that the codec
+ (which is in a separate abstraction
+ layer) also knows about the gap */
+ ogg_int64_t granulepos;
+
+} ogg_stream_state;
+
+/* ogg_packet is used to encapsulate the data and metadata belonging
+ to a single raw Ogg/Vorbis packet *************************************/
+
+typedef struct {
+ unsigned char *packet;
+ long bytes;
+ long b_o_s;
+ long e_o_s;
+
+ ogg_int64_t granulepos;
+
+ ogg_int64_t packetno; /* sequence number for decode; the framing
+ knows where there's a hole in the data,
+ but we need coupling so that the codec
+ (which is in a separate abstraction
+ layer) also knows about the gap */
+} ogg_packet;
+
+typedef struct {
+ unsigned char *data;
+ int storage;
+ int fill;
+ int returned;
+
+ int unsynced;
+ int headerbytes;
+ int bodybytes;
+} ogg_sync_state;
+
+/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
+
+extern void oggpack_writeinit(oggpack_buffer *b);
+extern int oggpack_writecheck(oggpack_buffer *b);
+extern void oggpack_writetrunc(oggpack_buffer *b,long bits);
+extern void oggpack_writealign(oggpack_buffer *b);
+extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
+extern void oggpack_reset(oggpack_buffer *b);
+extern void oggpack_writeclear(oggpack_buffer *b);
+extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
+extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
+extern long oggpack_look(oggpack_buffer *b,int bits);
+extern long oggpack_look1(oggpack_buffer *b);
+extern void oggpack_adv(oggpack_buffer *b,int bits);
+extern void oggpack_adv1(oggpack_buffer *b);
+extern long oggpack_read(oggpack_buffer *b,int bits);
+extern long oggpack_read1(oggpack_buffer *b);
+extern long oggpack_bytes(oggpack_buffer *b);
+extern long oggpack_bits(oggpack_buffer *b);
+extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
+
+extern void oggpackB_writeinit(oggpack_buffer *b);
+extern int oggpackB_writecheck(oggpack_buffer *b);
+extern void oggpackB_writetrunc(oggpack_buffer *b,long bits);
+extern void oggpackB_writealign(oggpack_buffer *b);
+extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
+extern void oggpackB_reset(oggpack_buffer *b);
+extern void oggpackB_writeclear(oggpack_buffer *b);
+extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
+extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
+extern long oggpackB_look(oggpack_buffer *b,int bits);
+extern long oggpackB_look1(oggpack_buffer *b);
+extern void oggpackB_adv(oggpack_buffer *b,int bits);
+extern void oggpackB_adv1(oggpack_buffer *b);
+extern long oggpackB_read(oggpack_buffer *b,int bits);
+extern long oggpackB_read1(oggpack_buffer *b);
+extern long oggpackB_bytes(oggpack_buffer *b);
+extern long oggpackB_bits(oggpack_buffer *b);
+extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
+
+/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
+
+extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
+extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
+ int count, long e_o_s, ogg_int64_t granulepos);
+extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
+extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill);
+extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
+extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill);
+
+/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
+
+extern int ogg_sync_init(ogg_sync_state *oy);
+extern int ogg_sync_clear(ogg_sync_state *oy);
+extern int ogg_sync_reset(ogg_sync_state *oy);
+extern int ogg_sync_destroy(ogg_sync_state *oy);
+extern int ogg_sync_check(ogg_sync_state *oy);
+
+extern char *ogg_sync_buffer(ogg_sync_state *oy, long size);
+extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
+extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
+extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
+extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
+extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
+extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);
+
+/* Ogg BITSTREAM PRIMITIVES: general ***************************/
+
+extern int ogg_stream_init(ogg_stream_state *os,int serialno);
+extern int ogg_stream_clear(ogg_stream_state *os);
+extern int ogg_stream_reset(ogg_stream_state *os);
+extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
+extern int ogg_stream_destroy(ogg_stream_state *os);
+extern int ogg_stream_check(ogg_stream_state *os);
+extern int ogg_stream_eos(ogg_stream_state *os);
+
+extern void ogg_page_checksum_set(ogg_page *og);
+
+extern int ogg_page_version(const ogg_page *og);
+extern int ogg_page_continued(const ogg_page *og);
+extern int ogg_page_bos(const ogg_page *og);
+extern int ogg_page_eos(const ogg_page *og);
+extern ogg_int64_t ogg_page_granulepos(const ogg_page *og);
+extern int ogg_page_serialno(const ogg_page *og);
+extern long ogg_page_pageno(const ogg_page *og);
+extern int ogg_page_packets(const ogg_page *og);
+
+extern void ogg_packet_clear(ogg_packet *op);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OGG_H */
diff --git a/lib/rbcodec/codecs/libopus/ogg/os_types.h b/lib/rbcodec/codecs/libopus/ogg/os_types.h
new file mode 100644
index 0000000000..55f0bf559c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/ogg/os_types.h
@@ -0,0 +1,56 @@
+#include "config.h"
+#include <stdint.h>
+#include "codeclib.h"
+
+#ifdef SIMULATOR
+
+#include <stdio.h>
+
+static inline void* _ogg_malloc(size_t size)
+{
+ void *buf;
+
+ printf("ogg_malloc %d", size);
+ buf = codec_malloc(size);
+ printf(" = %p\n", buf);
+
+ return buf;
+}
+
+static inline void* _ogg_calloc(size_t nmemb, size_t size)
+{
+ printf("ogg_calloc %d %d\n", nmemb, size);
+ return codec_calloc(nmemb, size);
+}
+
+static inline void* _ogg_realloc(void *ptr, size_t size)
+{
+ void *buf;
+
+ printf("ogg_realloc %p %d", ptr, size);
+ buf = codec_realloc(ptr, size);
+ printf(" = %p\n", buf);
+ return buf;
+}
+
+static inline void _ogg_free(void *ptr)
+{
+ printf("ogg_free %p\n", ptr);
+ codec_free(ptr);
+}
+
+#else
+
+#define _ogg_malloc codec_malloc
+#define _ogg_calloc codec_calloc
+#define _ogg_realloc codec_realloc
+#define _ogg_free codec_free
+
+#endif
+
+typedef int16_t ogg_int16_t;
+typedef uint16_t ogg_uint16_t;
+typedef int32_t ogg_int32_t;
+typedef uint32_t ogg_uint32_t;
+typedef int64_t ogg_int64_t;
+
diff --git a/lib/rbcodec/codecs/libopus/opus.h b/lib/rbcodec/codecs/libopus/opus.h
new file mode 100644
index 0000000000..c242fec0e7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus.h
@@ -0,0 +1,882 @@
+/* Copyright (c) 2010-2011 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+/**
+ * @file opus.h
+ * @brief Opus reference implementation API
+ */
+
+#ifndef OPUS_H
+#define OPUS_H
+
+#include "opus_types.h"
+#include "opus_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @mainpage Opus
+ *
+ * The Opus codec is designed for interactive speech and audio transmission over the Internet.
+ * It is designed by the IETF Codec Working Group and incorporates technology from
+ * Skype's SILK codec and Xiph.Org's CELT codec.
+ *
+ * The Opus codec is designed to handle a wide range of interactive audio applications,
+ * including Voice over IP, videoconferencing, in-game chat, and even remote live music
+ * performances. It can scale from low bit-rate narrowband speech to very high quality
+ * stereo music. Its main features are:
+
+ * @li Sampling rates from 8 to 48 kHz
+ * @li Bit-rates from 6 kb/s to 510 kb/s
+ * @li Support for both constant bit-rate (CBR) and variable bit-rate (VBR)
+ * @li Audio bandwidth from narrowband to full-band
+ * @li Support for speech and music
+ * @li Support for mono and stereo
+ * @li Support for multichannel (up to 255 channels)
+ * @li Frame sizes from 2.5 ms to 60 ms
+ * @li Good loss robustness and packet loss concealment (PLC)
+ * @li Floating point and fixed-point implementation
+ *
+ * Documentation sections:
+ * @li @ref opus_encoder
+ * @li @ref opus_decoder
+ * @li @ref opus_repacketizer
+ * @li @ref opus_multistream
+ * @li @ref opus_libinfo
+ * @li @ref opus_custom
+ */
+
+/** @defgroup opus_encoder Opus Encoder
+ * @{
+ *
+ * @brief This page describes the process and functions used to encode Opus.
+ *
+ * Since Opus is a stateful codec, the encoding process starts with creating an encoder
+ * state. This can be done with:
+ *
+ * @code
+ * int error;
+ * OpusEncoder *enc;
+ * enc = opus_encoder_create(Fs, channels, application, &error);
+ * @endcode
+ *
+ * From this point, @c enc can be used for encoding an audio stream. An encoder state
+ * @b must @b not be used for more than one stream at the same time. Similarly, the encoder
+ * state @b must @b not be re-initialized for each frame.
+ *
+ * While opus_encoder_create() allocates memory for the state, it's also possible
+ * to initialize pre-allocated memory:
+ *
+ * @code
+ * int size;
+ * int error;
+ * OpusEncoder *enc;
+ * size = opus_encoder_get_size(channels);
+ * enc = malloc(size);
+ * error = opus_encoder_init(enc, Fs, channels, application);
+ * @endcode
+ *
+ * where opus_encoder_get_size() returns the required size for the encoder state. Note that
+ * future versions of this code may change the size, so no assuptions should be made about it.
+ *
+ * The encoder state is always continuous in memory and only a shallow copy is sufficient
+ * to copy it (e.g. memcpy())
+ *
+ * It is possible to change some of the encoder's settings using the opus_encoder_ctl()
+ * interface. All these settings already default to the recommended value, so they should
+ * only be changed when necessary. The most common settings one may want to change are:
+ *
+ * @code
+ * opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate));
+ * opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
+ * opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type));
+ * @endcode
+ *
+ * where
+ *
+ * @arg bitrate is in bits per second (b/s)
+ * @arg complexity is a value from 1 to 10, where 1 is the lowest complexity and 10 is the highest
+ * @arg signal_type is either OPUS_AUTO (default), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC
+ *
+ * See @ref opus_encoderctls and @ref opus_genericctls for a complete list of parameters that can be set or queried. Most parameters can be set or changed at any time during a stream.
+ *
+ * To encode a frame, opus_encode() or opus_encode_float() must be called with exactly one frame (2.5, 5, 10, 20, 40 or 60 ms) of audio data:
+ * @code
+ * len = opus_encode(enc, audio_frame, frame_size, packet, max_packet);
+ * @endcode
+ *
+ * where
+ * <ul>
+ * <li>audio_frame is the audio data in opus_int16 (or float for opus_encode_float())</li>
+ * <li>frame_size is the duration of the frame in samples (per channel)</li>
+ * <li>packet is the byte array to which the compressed data is written</li>
+ * <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended)</li>
+ * </ul>
+ *
+ * opus_encode() and opus_encode_frame() return the number of bytes actually written to the packet.
+ * The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value
+ * is 1 byte, then the packet does not need to be transmitted (DTX).
+ *
+ * Once the encoder state if no longer needed, it can be destroyed with
+ *
+ * @code
+ * opus_encoder_destroy(enc);
+ * @endcode
+ *
+ * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(),
+ * then no action is required aside from potentially freeing the memory that was manually
+ * allocated for it (calling free(enc) for the example above)
+ *
+ */
+
+/** Opus encoder state.
+ * This contains the complete state of an Opus encoder.
+ * It is position independent and can be freely copied.
+ * @see opus_encoder_create,opus_encoder_init
+ */
+typedef struct OpusEncoder OpusEncoder;
+
+/** Gets the size of an <code>OpusEncoder</code> structure.
+ * @param[in] channels <tt>int</tt>: Number of channels.
+ * This must be 1 or 2.
+ * @returns The size in bytes.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels);
+
+/**
+ */
+
+/** Allocates and initializes an encoder state.
+ * There are three coding modes:
+ *
+ * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice
+ * signals. It enhances the input signal by high-pass filtering and
+ * emphasizing formants and harmonics. Optionally it includes in-band
+ * forward error correction to protect against packet loss. Use this
+ * mode for typical VoIP applications. Because of the enhancement,
+ * even at high bitrates the output may sound different from the input.
+ *
+ * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most
+ * non-voice signals like music. Use this mode for music and mixed
+ * (music/voice) content, broadcast, and applications requiring less
+ * than 15 ms of coding delay.
+ *
+ * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that
+ * disables the speech-optimized mode in exchange for slightly reduced delay.
+ * This mode can only be set on an newly initialized or freshly reset encoder
+ * because it changes the codec delay.
+ *
+ * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution).
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal
+ * @param [in] application <tt>int</tt>: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY)
+ * @param [out] error <tt>int*</tt>: @ref opus_errorcodes
+ * @note Regardless of the sampling rate and number channels selected, the Opus encoder
+ * can switch to a lower audio bandwidth or number of channels if the bitrate
+ * selected is too low. This also means that it is safe to always use 48 kHz stereo input
+ * and let the encoder optimize the encoding.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create(
+ opus_int32 Fs,
+ int channels,
+ int application,
+ int *error
+);
+
+/** Initializes a previously allocated encoder state
+ * The memory pointed to by st must be at least the size returned by opus_encoder_get_size().
+ * This is intended for applications which use their own allocator instead of malloc.
+ * @see opus_encoder_create(),opus_encoder_get_size()
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal
+ * @param [in] application <tt>int</tt>: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY)
+ * @retval #OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_EXPORT int opus_encoder_init(
+ OpusEncoder *st,
+ opus_int32 Fs,
+ int channels,
+ int application
+) OPUS_ARG_NONNULL(1);
+
+/** Encodes an Opus frame.
+ * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>opus_int16*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16)
+ * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
+ * input signal.
+ * This must be an Opus frame size for
+ * the encoder's sampling rate.
+ * For example, at 48 kHz the permitted
+ * values are 120, 240, 480, 960, 1920,
+ * and 2880.
+ * Passing in a duration of less than
+ * 10 ms (480 samples at 48 kHz) will
+ * prevent the encoder from using the LPC
+ * or hybrid modes.
+ * @param [out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the variable bitrate, but should
+ * not be used as the only bitrate
+ * control.
+ * @returns The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode(
+ OpusEncoder *st,
+ const opus_int16 *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Encodes an Opus frame from floating point input.
+ * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>float*</tt>: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0.
+ * Samples with a range beyond +/-1.0 are supported but will
+ * be clipped by decoders using the integer API and should
+ * only be used if it is known that the far end supports
+ * extended dynamic range.
+ * length is frame_size*channels*sizeof(float)
+ * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
+ * input signal.
+ * This must be an Opus frame size for
+ * the encoder's sampling rate.
+ * For example, at 48 kHz the permitted
+ * values are 120, 240, 480, 960, 1920,
+ * and 2880.
+ * Passing in a duration of less than
+ * 10 ms (480 samples at 48 kHz) will
+ * prevent the encoder from using the LPC
+ * or hybrid modes.
+ * @param [out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the variable bitrate, but should
+ * not be used as the only bitrate
+ * control.
+ * @returns The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float(
+ OpusEncoder *st,
+ const float *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Frees an <code>OpusEncoder</code> allocated by opus_encoder_create().
+ * @param[in] st <tt>OpusEncoder*</tt>: State to be freed.
+ */
+OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st);
+
+/** Perform a CTL function on an Opus encoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @param st <tt>OpusEncoder*</tt>: Encoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls or
+ * @ref opus_encoderctls.
+ * @see opus_genericctls
+ * @see opus_encoderctls
+ */
+OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
+/**@}*/
+
+/** @defgroup opus_decoder Opus Decoder
+ * @{
+ *
+ * @brief This page describes the process and functions used to decode Opus.
+ *
+ * The decoding process also starts with creating a decoder
+ * state. This can be done with:
+ * @code
+ * int error;
+ * OpusDecoder *dec;
+ * dec = opus_decoder_create(Fs, channels, &error);
+ * @endcode
+ * where
+ * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000
+ * @li channels is the number of channels (1 or 2)
+ * @li error will hold the error code in case or failure (or #OPUS_OK on success)
+ * @li the return value is a newly created decoder state to be used for decoding
+ *
+ * While opus_decoder_create() allocates memory for the state, it's also possible
+ * to initialize pre-allocated memory:
+ * @code
+ * int size;
+ * int error;
+ * OpusDecoder *dec;
+ * size = opus_decoder_get_size(channels);
+ * dec = malloc(size);
+ * error = opus_decoder_init(dec, Fs, channels);
+ * @endcode
+ * where opus_decoder_get_size() returns the required size for the decoder state. Note that
+ * future versions of this code may change the size, so no assuptions should be made about it.
+ *
+ * The decoder state is always continuous in memory and only a shallow copy is sufficient
+ * to copy it (e.g. memcpy())
+ *
+ * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data:
+ * @code
+ * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0);
+ * @endcode
+ * where
+ *
+ * @li packet is the byte array containing the compressed data
+ * @li len is the exact number of bytes contained in the packet
+ * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float())
+ * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array
+ *
+ * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet.
+ * If that value is negative, then an error has occured. This can occur if the packet is corrupted or if the audio
+ * buffer is too small to hold the decoded audio.
+ *
+ * Opus is a stateful codec with overlapping blocks and as a result Opus
+ * packets are not coded independently of each other. Packets must be
+ * passed into the decoder serially and in the correct order for a correct
+ * decode. Lost packets can be replaced with loss concealment by calling
+ * the decoder with a null pointer and zero length for the missing packet.
+ *
+ * A single codec state may only be accessed from a single thread at
+ * a time and any required locking must be performed by the caller. Separate
+ * streams must be decoded with separate decoder states and can be decoded
+ * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK
+ * defined.
+ *
+ */
+
+/** Opus decoder state.
+ * This contains the complete state of an Opus decoder.
+ * It is position independent and can be freely copied.
+ * @see opus_decoder_create,opus_decoder_init
+ */
+typedef struct OpusDecoder OpusDecoder;
+
+/** Gets the size of an <code>OpusDecoder</code> structure.
+ * @param [in] channels <tt>int</tt>: Number of channels.
+ * This must be 1 or 2.
+ * @returns The size in bytes.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels);
+
+/** Allocates and initializes a decoder state.
+ * @param [in] Fs <tt>opus_int32</tt>: Sample rate to decode at (Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode
+ * @param [out] error <tt>int*</tt>: #OPUS_OK Success or @ref opus_errorcodes
+ *
+ * Internally Opus stores data at 48000 Hz, so that should be the default
+ * value for Fs. However, the decoder can efficiently decode to buffers
+ * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use
+ * data at the full sample rate, or knows the compressed data doesn't
+ * use the full frequency range, it can request decoding at a reduced
+ * rate. Likewise, the decoder is capable of filling in either mono or
+ * interleaved stereo pcm buffers, at the caller's request.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create(
+ opus_int32 Fs,
+ int channels,
+ int *error
+);
+
+/** Initializes a previously allocated decoder state.
+ * The state must be at least the size returned by opus_decoder_get_size().
+ * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusDecoder*</tt>: Decoder state.
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate to decode to (Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode
+ * @retval #OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_EXPORT int opus_decoder_init(
+ OpusDecoder *st,
+ opus_int32 Fs,
+ int channels
+) OPUS_ARG_NONNULL(1);
+
+/** Decode an Opus packet.
+ * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload*
+ * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(opus_int16)
+ * @param [in] frame_size Number of samples per channel of available space in \a pcm.
+ * If this is less than the maximum frame size (120 ms), this function will
+ * not be capable of decoding some packets.
+ * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
+ * decoded. If no such data is available, the frame is decoded as if it were lost.
+ * @returns Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode(
+ OpusDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ opus_int16 *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Decode an Opus packet with floating point output.
+ * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload
+ * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(float)
+ * @param [in] frame_size Number of samples per channel of available space in *pcm,
+ * if less than the maximum frame size (120ms) some frames can not be decoded
+ * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
+ * decoded. If no such data is available the frame is decoded as if it were lost.
+ * @returns Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float(
+ OpusDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ float *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on an Opus decoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @param st <tt>OpusDecoder*</tt>: Decoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls or
+ * @ref opus_decoderctls.
+ * @see opus_genericctls
+ * @see opus_decoderctls
+ */
+OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
+
+/** Frees an <code>OpusDecoder</code> allocated by opus_decoder_create().
+ * @param[in] st <tt>OpusDecoder*</tt>: State to be freed.
+ */
+OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
+
+/** Parse an opus packet into one or more frames.
+ * Opus_decode will perform this operation internally so most applications do
+ * not need to use this function.
+ * This function does not copy the frames, the returned pointers are pointers into
+ * the input packet.
+ * @param [in] data <tt>char*</tt>: Opus packet to be parsed
+ * @param [in] len <tt>opus_int32</tt>: size of data
+ * @param [out] out_toc <tt>char*</tt>: TOC pointer
+ * @param [out] frames <tt>char*[48]</tt> encapsulated frames
+ * @param [out] size <tt>short[48]</tt> sizes of the encapsulated frames
+ * @param [out] payload_offset <tt>int*</tt>: returns the position of the payload within the packet (in bytes)
+ * @returns number of frames
+ */
+OPUS_EXPORT int opus_packet_parse(
+ const unsigned char *data,
+ opus_int32 len,
+ unsigned char *out_toc,
+ const unsigned char *frames[48],
+ short size[48],
+ int *payload_offset
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Gets the bandwidth of an Opus packet.
+ * @param [in] data <tt>char*</tt>: Opus packet
+ * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass)
+ * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass)
+ * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass)
+ * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass)
+ * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass)
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of samples per frame from an Opus packet.
+ * @param [in] data <tt>char*</tt>: Opus packet.
+ * This must contain at least one byte of
+ * data.
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.
+ * This must be a multiple of 400, or
+ * inaccurate results will be returned.
+ * @returns Number of samples per frame.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of channels from an Opus packet.
+ * @param [in] data <tt>char*</tt>: Opus packet
+ * @returns Number of channels
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of frames in an Opus packet.
+ * @param [in] packet <tt>char*</tt>: Opus packet
+ * @param [in] len <tt>opus_int32</tt>: Length of packet
+ * @returns Number of frames
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of samples of an Opus packet.
+ * @param [in] dec <tt>OpusDecoder*</tt>: Decoder state
+ * @param [in] packet <tt>char*</tt>: Opus packet
+ * @param [in] len <tt>opus_int32</tt>: Length of packet
+ * @returns Number of samples
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+/**@}*/
+
+/** @defgroup opus_repacketizer Repacketizer
+ * @{
+ *
+ * The repacketizer can be used to merge multiple Opus packets into a single
+ * packet or alternatively to split Opus packets that have previously been
+ * merged. Splitting valid Opus packets is always guaranteed to succeed,
+ * whereas merging valid packets only succeeds if all frames have the same
+ * mode, bandwidth, and frame size, and when the total duration of the merged
+ * packet is no more than 120 ms.
+ * The repacketizer currently only operates on elementary Opus
+ * streams. It will not manipualte multistream packets successfully, except in
+ * the degenerate case where they consist of data from a single stream.
+ *
+ * The repacketizing process starts with creating a repacketizer state, either
+ * by calling opus_repacketizer_create() or by allocating the memory yourself,
+ * e.g.,
+ * @code
+ * OpusRepacketizer *rp;
+ * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size());
+ * if (rp != NULL)
+ * opus_repacketizer_init(rp);
+ * @endcode
+ *
+ * Then the application should submit packets with opus_repacketizer_cat(),
+ * extract new packets with opus_repacketizer_out() or
+ * opus_repacketizer_out_range(), and then reset the state for the next set of
+ * input packets via opus_repacketizer_init().
+ *
+ * For example, to split a sequence of packets into individual frames:
+ * @code
+ * unsigned char *data;
+ * int len;
+ * while (get_next_packet(&data, &len))
+ * {
+ * unsigned char out[1276];
+ * opus_int32 out_len;
+ * int nb_frames;
+ * int err;
+ * int i;
+ * err = opus_repacketizer_cat(rp, data, len);
+ * if (err != OPUS_OK)
+ * {
+ * release_packet(data);
+ * return err;
+ * }
+ * nb_frames = opus_repacketizer_get_nb_frames(rp);
+ * for (i = 0; i < nb_frames; i++)
+ * {
+ * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out));
+ * if (out_len < 0)
+ * {
+ * release_packet(data);
+ * return (int)out_len;
+ * }
+ * output_next_packet(out, out_len);
+ * }
+ * opus_repacketizer_init(rp);
+ * release_packet(data);
+ * }
+ * @endcode
+ *
+ * Alternatively, to combine a sequence of frames into packets that each
+ * contain up to <code>TARGET_DURATION_MS</code> milliseconds of data:
+ * @code
+ * // The maximum number of packets with duration TARGET_DURATION_MS occurs
+ * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5)
+ * // packets.
+ * unsigned char *data[(TARGET_DURATION_MS*2/5)+1];
+ * opus_int32 len[(TARGET_DURATION_MS*2/5)+1];
+ * int nb_packets;
+ * unsigned char out[1277*(TARGET_DURATION_MS*2/2)];
+ * opus_int32 out_len;
+ * int prev_toc;
+ * nb_packets = 0;
+ * while (get_next_packet(data+nb_packets, len+nb_packets))
+ * {
+ * int nb_frames;
+ * int err;
+ * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]);
+ * if (nb_frames < 1)
+ * {
+ * release_packets(data, nb_packets+1);
+ * return nb_frames;
+ * }
+ * nb_frames += opus_repacketizer_get_nb_frames(rp);
+ * // If adding the next packet would exceed our target, or it has an
+ * // incompatible TOC sequence, output the packets we already have before
+ * // submitting it.
+ * // N.B., The nb_packets > 0 check ensures we've submitted at least one
+ * // packet since the last call to opus_repacketizer_init(). Otherwise a
+ * // single packet longer than TARGET_DURATION_MS would cause us to try to
+ * // output an (invalid) empty packet. It also ensures that prev_toc has
+ * // been set to a valid value. Additionally, len[nb_packets] > 0 is
+ * // guaranteed by the call to opus_packet_get_nb_frames() above, so the
+ * // reference to data[nb_packets][0] should be valid.
+ * if (nb_packets > 0 && (
+ * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) ||
+ * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames >
+ * TARGET_DURATION_MS*48))
+ * {
+ * out_len = opus_repacketizer_out(rp, out, sizeof(out));
+ * if (out_len < 0)
+ * {
+ * release_packets(data, nb_packets+1);
+ * return (int)out_len;
+ * }
+ * output_next_packet(out, out_len);
+ * opus_repacketizer_init(rp);
+ * release_packets(data, nb_packets);
+ * data[0] = data[nb_packets];
+ * len[0] = len[nb_packets];
+ * nb_packets = 0;
+ * }
+ * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]);
+ * if (err != OPUS_OK)
+ * {
+ * release_packets(data, nb_packets+1);
+ * return err;
+ * }
+ * prev_toc = data[nb_packets][0];
+ * nb_packets++;
+ * }
+ * // Output the final, partial packet.
+ * if (nb_packets > 0)
+ * {
+ * out_len = opus_repacketizer_out(rp, out, sizeof(out));
+ * release_packets(data, nb_packets);
+ * if (out_len < 0)
+ * return (int)out_len;
+ * output_next_packet(out, out_len);
+ * }
+ * @endcode
+ *
+ * An alternate way of merging packets is to simply call opus_repacketizer_cat()
+ * unconditionally until it fails. At that point, the merged packet can be
+ * obtained with opus_repacketizer_out() and the input packet for which
+ * opus_repacketizer_cat() needs to be re-added to a newly reinitialized
+ * repacketizer state.
+ */
+
+typedef struct OpusRepacketizer OpusRepacketizer;
+
+/** Gets the size of an <code>OpusRepacketizer</code> structure.
+ * @returns The size in bytes.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void);
+
+/** (Re)initializes a previously allocated repacketizer state.
+ * The state must be at least the size returned by opus_repacketizer_get_size().
+ * This can be used for applications which use their own allocator instead of
+ * malloc().
+ * It must also be called to reset the queue of packets waiting to be
+ * repacketized, which is necessary if the maximum packet duration of 120 ms
+ * is reached or if you wish to submit packets with a different Opus
+ * configuration (coding mode, audio bandwidth, frame size, or channel count).
+ * Failure to do so will prevent a new packet from being added with
+ * opus_repacketizer_cat().
+ * @see opus_repacketizer_create
+ * @see opus_repacketizer_get_size
+ * @see opus_repacketizer_cat
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to
+ * (re)initialize.
+ * @returns A pointer to the same repacketizer state that was passed in.
+ */
+OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);
+
+/** Allocates memory and initializes the new repacketizer with
+ * opus_repacketizer_init().
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void);
+
+/** Frees an <code>OpusRepacketizer</code> allocated by
+ * opus_repacketizer_create().
+ * @param[in] rp <tt>OpusRepacketizer*</tt>: State to be freed.
+ */
+OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp);
+
+/** Add a packet to the current repacketizer state.
+ * This packet must match the configuration of any packets already submitted
+ * for repacketization since the last call to opus_repacketizer_init().
+ * This means that it must have the same coding mode, audio bandwidth, frame
+ * size, and channel count.
+ * This can be checked in advance by examining the top 6 bits of the first
+ * byte of the packet, and ensuring they match the top 6 bits of the first
+ * byte of any previously submitted packet.
+ * The total duration of audio in the repacketizer state also must not exceed
+ * 120 ms, the maximum duration of a single packet, after adding this packet.
+ *
+ * The contents of the current repacketizer state can be extracted into new
+ * packets using opus_repacketizer_out() or opus_repacketizer_out_range().
+ *
+ * In order to add a packet with a different configuration or to add more
+ * audio beyond 120 ms, you must clear the repacketizer state by calling
+ * opus_repacketizer_init().
+ * If a packet is too large to add to the current repacketizer state, no part
+ * of it is added, even if it contains multiple frames, some of which might
+ * fit.
+ * If you wish to be able to add parts of such packets, you should first use
+ * another repacketizer to split the packet into pieces and add them
+ * individually.
+ * @see opus_repacketizer_out_range
+ * @see opus_repacketizer_out
+ * @see opus_repacketizer_init
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to which to
+ * add the packet.
+ * @param[in] data <tt>const unsigned char*</tt>: The packet data.
+ * The application must ensure
+ * this pointer remains valid
+ * until the next call to
+ * opus_repacketizer_init() or
+ * opus_repacketizer_destroy().
+ * @param len <tt>opus_int32</tt>: The number of bytes in the packet data.
+ * @returns An error code indicating whether or not the operation succeeded.
+ * @retval #OPUS_OK The packet's contents have been added to the repacketizer
+ * state.
+ * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence,
+ * the packet's TOC sequence was not compatible
+ * with previously submitted packets (because
+ * the coding mode, audio bandwidth, frame size,
+ * or channel count did not match), or adding
+ * this packet would increase the total amount of
+ * audio stored in the repacketizer state to more
+ * than 120 ms.
+ */
+OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+
+
+/** Construct a new packet from data previously submitted to the repacketizer
+ * state via opus_repacketizer_cat().
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to
+ * construct the new packet.
+ * @param begin <tt>int</tt>: The index of the first frame in the current
+ * repacketizer state to include in the output.
+ * @param end <tt>int</tt>: One past the index of the last frame in the
+ * current repacketizer state to include in the
+ * output.
+ * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to
+ * store the output packet.
+ * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in
+ * the output buffer. In order to guarantee
+ * success, this should be at least
+ * <code>1276</code> for a single frame,
+ * or for multiple frames,
+ * <code>1277*(end-begin)</code>.
+ * However, <code>1*(end-begin)</code> plus
+ * the size of all packet data submitted to
+ * the repacketizer since the last call to
+ * opus_repacketizer_init() or
+ * opus_repacketizer_create() is also
+ * sufficient, and possibly much smaller.
+ * @returns The total size of the output packet on success, or an error code
+ * on failure.
+ * @retval #OPUS_BAD_ARG <code>[begin,end)</code> was an invalid range of
+ * frames (begin < 0, begin >= end, or end >
+ * opus_repacketizer_get_nb_frames()).
+ * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the
+ * complete output packet.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Return the total number of frames contained in packet data submitted to
+ * the repacketizer state so far via opus_repacketizer_cat() since the last
+ * call to opus_repacketizer_init() or opus_repacketizer_create().
+ * This defines the valid range of packets that can be extracted with
+ * opus_repacketizer_out_range() or opus_repacketizer_out().
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state containing the
+ * frames.
+ * @returns The total number of frames contained in the packet data submitted
+ * to the repacketizer state.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);
+
+/** Construct a new packet from data previously submitted to the repacketizer
+ * state via opus_repacketizer_cat().
+ * This is a convenience routine that returns all the data submitted so far
+ * in a single packet.
+ * It is equivalent to calling
+ * @code
+ * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp),
+ * data, maxlen)
+ * @endcode
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to
+ * construct the new packet.
+ * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to
+ * store the output packet.
+ * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in
+ * the output buffer. In order to guarantee
+ * success, this should be at least
+ * <code>1277*opus_repacketizer_get_nb_frames(rp)</code>.
+ * However,
+ * <code>1*opus_repacketizer_get_nb_frames(rp)</code>
+ * plus the size of all packet data
+ * submitted to the repacketizer since the
+ * last call to opus_repacketizer_init() or
+ * opus_repacketizer_create() is also
+ * sufficient, and possibly much smaller.
+ * @returns The total size of the output packet on success, or an error code
+ * on failure.
+ * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the
+ * complete output packet.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_H */
diff --git a/lib/rbcodec/codecs/libopus/opus_config.h b/lib/rbcodec/codecs/libopus/opus_config.h
new file mode 100644
index 0000000000..86210df52b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_config.h
@@ -0,0 +1,42 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "config.h"
+#include "codeclib.h"
+
+/* general stuff */
+#define OPUS_BUILD
+
+/* alloc stuff */
+#define NONTHREADSAFE_PSEUDOSTACK
+
+#define OVERRIDE_OPUS_ALLOC
+#define OVERRIDE_OPUS_FREE
+#define OVERRIDE_OPUS_ALLOC_SCRATCH
+
+#define opus_alloc codec_malloc
+#define opus_free codec_free
+#define opus_alloc_scratch codec_malloc
+
+/* lrint */
+#define HAVE_LRINTF 0
+#define HAVE_LRINT 0
+
+/* embedded stuff */
+#define FIXED_POINT
+#define DISABLE_FLOAT_API
+#define EMBEDDED_ARM 1
+
+/* undefinitions */
+#ifdef ABS
+#undef ABS
+#endif
+#ifdef MIN
+#undef MIN
+#endif
+#ifdef MAX
+#undef MAX
+#endif
+
+#endif /* CONFIG_H */
+
diff --git a/lib/rbcodec/codecs/libopus/opus_custom.h b/lib/rbcodec/codecs/libopus/opus_custom.h
new file mode 100644
index 0000000000..e7861d6f0a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_custom.h
@@ -0,0 +1,329 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2008-2012 Gregory Maxwell
+ Written by Jean-Marc Valin and Gregory Maxwell */
+/*
+ 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+/**
+ @file opus_custom.h
+ @brief Opus-Custom reference implementation API
+ */
+
+#ifndef OPUS_CUSTOM_H
+#define OPUS_CUSTOM_H
+
+#include "opus_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef CUSTOM_MODES
+#define OPUS_CUSTOM_EXPORT OPUS_EXPORT
+#define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT
+#else
+#define OPUS_CUSTOM_EXPORT
+#ifdef CELT_C
+#define OPUS_CUSTOM_EXPORT_STATIC static inline
+#else
+#define OPUS_CUSTOM_EXPORT_STATIC
+#endif
+#endif
+
+/** @defgroup opus_custom Opus Custom
+ * @{
+ * Opus Custom is an optional part of the Opus specification and
+ * reference implementation which uses a distinct API from the regular
+ * API and supports frame sizes that are not normally supported.\ Use
+ * of Opus Custom is discouraged for all but very special applications
+ * for which a frame size different from 2.5, 5, 10, or 20 ms is needed
+ * (for either complexity or latency reasons) and where interoperability
+ * is less important.
+ *
+ * In addition to the interoperability limitations the use of Opus custom
+ * disables a substantial chunk of the codec and generally lowers the
+ * quality available at a given bitrate. Normally when an application needs
+ * a different frame size from the codec it should buffer to match the
+ * sizes but this adds a small amount of delay which may be important
+ * in some very low latency applications. Some transports (especially
+ * constant rate RF transports) may also work best with frames of
+ * particular durations.
+ *
+ * Libopus only supports custom modes if they are enabled at compile time.
+ *
+ * The Opus Custom API is similar to the regular API but the
+ * @ref opus_encoder_create and @ref opus_decoder_create calls take
+ * an additional mode parameter which is a structure produced by
+ * a call to @ref opus_custom_mode_create. Both the encoder and decoder
+ * must create a mode using the same sample rate (fs) and frame size
+ * (frame size) so these parameters must either be signaled out of band
+ * or fixed in a particular implementation.
+ *
+ * Similar to regular Opus the custom modes support on the fly frame size
+ * switching, but the sizes available depend on the particular frame size in
+ * use. For some initial frame sizes on a single on the fly size is available.
+ */
+
+/** Contains the state of an encoder. One encoder state is needed
+ for each stream. It is initialized once at the beginning of the
+ stream. Do *not* re-initialize the state for every frame.
+ @brief Encoder state
+ */
+typedef struct OpusCustomEncoder OpusCustomEncoder;
+
+/** State of the decoder. One decoder state is needed for each stream.
+ It is initialized once at the beginning of the stream. Do *not*
+ re-initialize the state for every frame.
+ @brief Decoder state
+ */
+typedef struct OpusCustomDecoder OpusCustomDecoder;
+
+/** The mode contains all the information necessary to create an
+ encoder. Both the encoder and decoder need to be initialized
+ with exactly the same mode, otherwise the output will be
+ corrupted.
+ @brief Mode configuration
+ */
+typedef struct OpusCustomMode OpusCustomMode;
+
+/** Creates a new mode struct. This will be passed to an encoder or
+ * decoder. The mode MUST NOT BE DESTROYED until the encoders and
+ * decoders that use it are destroyed as well.
+ * @param [in] Fs <tt>int</tt>: Sampling rate (8000 to 96000 Hz)
+ * @param [in] frame_size <tt>int</tt>: Number of samples (per channel) to encode in each
+ * packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes)
+ * @param [out] error <tt>int*</tt>: Returned error code (if NULL, no error will be returned)
+ * @return A newly created mode
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error);
+
+/** Destroys a mode struct. Only call this after all encoders and
+ * decoders using this mode are destroyed as well.
+ * @param [in] mode <tt>OpusCustomMode*</tt>: Mode to be freed.
+ */
+OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode);
+
+/* Encoder */
+/** Gets the size of an OpusCustomEncoder structure.
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Mode configuration
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @returns size
+ */
+OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size(
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1);
+
+/** Creates a new encoder state. Each stream needs its own encoder
+ * state (can't be shared across simultaneous streams).
+ * @param [in] mode <tt>OpusCustomMode*</tt>: Contains all the information about the characteristics of
+ * the stream (must be the same characteristics as used for the
+ * decoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @param [out] error <tt>int*</tt>: Returns an error code
+ * @return Newly created encoder state.
+*/
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create(
+ const OpusCustomMode *mode,
+ int channels,
+ int *error
+) OPUS_ARG_NONNULL(1);
+
+/** Initializes a previously allocated encoder state
+ * The memory pointed to by st must be the size returned by opus_custom_encoder_get_size.
+ * This is intended for applications which use their own allocator instead of malloc.
+ * @see opus_custom_encoder_create(),opus_custom_encoder_get_size()
+ * To reset a previously initialized state use the OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Contains all the information about the characteristics of
+ * the stream (must be the same characteristics as used for the
+ * decoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @return OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT_STATIC int opus_custom_encoder_init(
+ OpusCustomEncoder *st,
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+
+/** Destroys a an encoder state.
+ * @param[in] st <tt>OpusCustomEncoder*</tt>: State to be freed.
+ */
+OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st);
+
+/** Encodes a frame of audio.
+ * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>float*</tt>: PCM audio in float format, with a normal range of +/-1.0.
+ * Samples with a range beyond +/-1.0 are supported but will
+ * be clipped by decoders using the integer API and should
+ * only be used if it is known that the far end supports
+ * extended dynamic range. There must be exactly
+ * frame_size samples per channel.
+ * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
+ * @param [out] compressed <tt>char *</tt>: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long.
+ * @param [in] maxCompressedBytes <tt>int</tt>: Maximum number of bytes to use for compressing the frame
+ * (can change from one frame to another)
+ * @return Number of bytes written to "compressed".
+ * If negative, an error has occurred (see error codes). It is IMPORTANT that
+ * the length returned be somehow transmitted to the decoder. Otherwise, no
+ * decoding is possible.
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float(
+ OpusCustomEncoder *st,
+ const float *pcm,
+ int frame_size,
+ unsigned char *compressed,
+ int maxCompressedBytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Encodes a frame of audio.
+ * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>opus_int16*</tt>: PCM audio in signed 16-bit format (native endian).
+ * There must be exactly frame_size samples per channel.
+ * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
+ * @param [out] compressed <tt>char *</tt>: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long.
+ * @param [in] maxCompressedBytes <tt>int</tt>: Maximum number of bytes to use for compressing the frame
+ * (can change from one frame to another)
+ * @return Number of bytes written to "compressed".
+ * If negative, an error has occurred (see error codes). It is IMPORTANT that
+ * the length returned be somehow transmitted to the decoder. Otherwise, no
+ * decoding is possible.
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode(
+ OpusCustomEncoder *st,
+ const opus_int16 *pcm,
+ int frame_size,
+ unsigned char *compressed,
+ int maxCompressedBytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on an Opus custom encoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @see opus_encoderctls
+ */
+OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1);
+
+/* Decoder */
+
+/** Gets the size of an OpusCustomDecoder structure.
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Mode configuration
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @returns size
+ */
+OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size(
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1);
+
+/** Creates a new decoder state. Each stream needs its own decoder state (can't
+ * be shared across simultaneous streams).
+ * @param [in] mode <tt>OpusCustomMode</tt>: Contains all the information about the characteristics of the
+ * stream (must be the same characteristics as used for the encoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @param [out] error <tt>int*</tt>: Returns an error code
+ * @return Newly created decoder state.
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create(
+ const OpusCustomMode *mode,
+ int channels,
+ int *error
+) OPUS_ARG_NONNULL(1);
+
+/** Initializes a previously allocated decoder state
+ * The memory pointed to by st must be the size returned by opus_custom_decoder_get_size.
+ * This is intended for applications which use their own allocator instead of malloc.
+ * @see opus_custom_decoder_create(),opus_custom_decoder_get_size()
+ * To reset a previously initialized state use the OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Contains all the information about the characteristics of
+ * the stream (must be the same characteristics as used for the
+ * encoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @return OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init(
+ OpusCustomDecoder *st,
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+
+/** Destroys a an decoder state.
+ * @param[in] st <tt>OpusCustomDecoder*</tt>: State to be freed.
+ */
+OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st);
+
+/** Decode an opus custom frame with floating point output
+ * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>int</tt>: Number of bytes in payload
+ * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(float)
+ * @param [in] frame_size Number of samples per channel of available space in *pcm.
+ * @returns Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float(
+ OpusCustomDecoder *st,
+ const unsigned char *data,
+ int len,
+ float *pcm,
+ int frame_size
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Decode an opus custom frame
+ * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>int</tt>: Number of bytes in payload
+ * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(opus_int16)
+ * @param [in] frame_size Number of samples per channel of available space in *pcm.
+ * @returns Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode(
+ OpusCustomDecoder *st,
+ const unsigned char *data,
+ int len,
+ opus_int16 *pcm,
+ int frame_size
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on an Opus custom decoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @see opus_genericctls
+ */
+OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_CUSTOM_H */
diff --git a/lib/rbcodec/codecs/libopus/opus_decoder.c b/lib/rbcodec/codecs/libopus/opus_decoder.c
new file mode 100644
index 0000000000..7103b183b8
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_decoder.c
@@ -0,0 +1,999 @@
+/* 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.
+
+ 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 COPYRIGHT OWNER
+ 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 "opus_config.h"
+#endif
+
+#ifndef OPUS_BUILD
+#error "OPUS_BUILD _MUST_ be defined to build Opus and you probably want a decent config.h, see README for more details."
+#endif
+
+#include <stdarg.h>
+#include "celt.h"
+#include "opus.h"
+#include "entdec.h"
+#include "modes.h"
+#include "API.h"
+#include "stack_alloc.h"
+#include "float_cast.h"
+#include "opus_private.h"
+#include "os_support.h"
+#include "structs.h"
+#include "define.h"
+#include "mathops.h"
+
+struct OpusDecoder {
+ int celt_dec_offset;
+ int silk_dec_offset;
+ int channels;
+ opus_int32 Fs; /** Sampling rate (at the API level) */
+ silk_DecControlStruct DecControl;
+ int decode_gain;
+
+ /* Everything beyond this point gets cleared on a reset */
+#define OPUS_DECODER_RESET_START stream_channels
+ int stream_channels;
+
+ int bandwidth;
+ int mode;
+ int prev_mode;
+ int frame_size;
+ int prev_redundancy;
+
+ opus_uint32 rangeFinal;
+};
+
+#ifdef FIXED_POINT
+static inline opus_int16 SAT16(opus_int32 x) {
+ return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x;
+}
+#endif
+
+
+int opus_decoder_get_size(int channels)
+{
+ int silkDecSizeBytes, celtDecSizeBytes;
+ int ret;
+ if (channels<1 || channels > 2)
+ return 0;
+ ret = silk_Get_Decoder_Size( &silkDecSizeBytes );
+ if(ret)
+ return 0;
+ silkDecSizeBytes = align(silkDecSizeBytes);
+ celtDecSizeBytes = celt_decoder_get_size(channels);
+ return align(sizeof(OpusDecoder))+silkDecSizeBytes+celtDecSizeBytes;
+}
+
+int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
+{
+ void *silk_dec;
+ CELTDecoder *celt_dec;
+ int ret, silkDecSizeBytes;
+
+ if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)
+ || (channels!=1&&channels!=2))
+ return OPUS_BAD_ARG;
+
+ OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
+ /* Initialize SILK encoder */
+ ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
+ if (ret)
+ return OPUS_INTERNAL_ERROR;
+
+ silkDecSizeBytes = align(silkDecSizeBytes);
+ st->silk_dec_offset = align(sizeof(OpusDecoder));
+ st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes;
+ silk_dec = (char*)st+st->silk_dec_offset;
+ celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
+ st->stream_channels = st->channels = channels;
+
+ st->Fs = Fs;
+ st->DecControl.API_sampleRate = st->Fs;
+ st->DecControl.nChannelsAPI = st->channels;
+
+ /* Reset decoder */
+ ret = silk_InitDecoder( silk_dec );
+ if(ret)return OPUS_INTERNAL_ERROR;
+
+ /* Initialize CELT decoder */
+ ret = celt_decoder_init(celt_dec, Fs, channels);
+ if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR;
+
+ celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));
+
+ st->prev_mode = 0;
+ st->frame_size = Fs/400;
+ return OPUS_OK;
+}
+
+OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
+{
+ int ret;
+ OpusDecoder *st;
+ if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)
+ || (channels!=1&&channels!=2))
+ {
+ if (error)
+ *error = OPUS_BAD_ARG;
+ return NULL;
+ }
+ st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));
+ if (st == NULL)
+ {
+ if (error)
+ *error = OPUS_ALLOC_FAIL;
+ return NULL;
+ }
+ ret = opus_decoder_init(st, Fs, channels);
+ if (error)
+ *error = ret;
+ if (ret != OPUS_OK)
+ {
+ opus_free(st);
+ st = NULL;
+ }
+ return st;
+}
+
+static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2,
+ opus_val16 *out, int overlap, int channels,
+ const opus_val16 *window, opus_int32 Fs)
+{
+ int i, c;
+ int inc = 48000/Fs;
+ for (c=0;c<channels;c++)
+ {
+ for (i=0;i<overlap;i++)
+ {
+ opus_val16 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
+ out[i*channels+c] = SHR32(MAC16_16(MULT16_16(w,in2[i*channels+c]),
+ Q15ONE-w, in1[i*channels+c]), 15);
+ }
+ }
+}
+
+static int opus_packet_get_mode(const unsigned char *data)
+{
+ int mode;
+ if (data[0]&0x80)
+ {
+ mode = MODE_CELT_ONLY;
+ } else if ((data[0]&0x60) == 0x60)
+ {
+ mode = MODE_HYBRID;
+ } else {
+ mode = MODE_SILK_ONLY;
+ }
+ return mode;
+}
+
+static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
+ opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
+{
+ void *silk_dec;
+ CELTDecoder *celt_dec;
+ int i, silk_ret=0, celt_ret=0;
+ ec_dec dec;
+ opus_int32 silk_frame_size;
+ VARDECL(opus_int16, pcm_silk);
+ VARDECL(opus_val16, pcm_transition);
+ VARDECL(opus_val16, redundant_audio);
+
+ int audiosize;
+ int mode;
+ int transition=0;
+ int start_band;
+ int redundancy=0;
+ int redundancy_bytes = 0;
+ int celt_to_silk=0;
+ int c;
+ int F2_5, F5, F10, F20;
+ const opus_val16 *window;
+ opus_uint32 redundant_rng = 0;
+ ALLOC_STACK;
+
+ silk_dec = (char*)st+st->silk_dec_offset;
+ celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
+ F20 = st->Fs/50;
+ F10 = F20>>1;
+ F5 = F10>>1;
+ F2_5 = F5>>1;
+ if (frame_size < F2_5)
+ {
+ RESTORE_STACK;
+ return OPUS_BUFFER_TOO_SMALL;
+ }
+ /* Limit frame_size to avoid excessive stack allocations. */
+ frame_size = IMIN(frame_size, st->Fs/25*3);
+ /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */
+ if (len<=1)
+ {
+ data = NULL;
+ /* In that case, don't conceal more than what the ToC says */
+ frame_size = IMIN(frame_size, st->frame_size);
+ }
+ if (data != NULL)
+ {
+ audiosize = st->frame_size;
+ mode = st->mode;
+ ec_dec_init(&dec,(unsigned char*)data,len);
+ } else {
+ audiosize = frame_size;
+
+ if (st->prev_mode == 0)
+ {
+ /* If we haven't got any packet yet, all we can do is return zeros */
+ for (i=0;i<audiosize*st->channels;i++)
+ pcm[i] = 0;
+ RESTORE_STACK;
+ return audiosize;
+ } else {
+ mode = st->prev_mode;
+ }
+ }
+
+ /* For CELT/hybrid PLC of more than 20 ms, do multiple calls */
+ if (data==NULL && frame_size > F20 && mode != MODE_SILK_ONLY)
+ {
+ int nb_samples = 0;
+ do {
+ int ret = opus_decode_frame(st, NULL, 0, pcm, F20, 0);
+ if (ret != F20)
+ {
+ RESTORE_STACK;
+ return OPUS_INTERNAL_ERROR;
+ }
+ pcm += F20*st->channels;
+ nb_samples += F20;
+ } while (nb_samples < frame_size);
+ RESTORE_STACK;
+ return frame_size;
+ }
+ ALLOC(pcm_transition, F5*st->channels, opus_val16);
+
+ if (data!=NULL && st->prev_mode > 0 && (
+ (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy)
+ || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) )
+ )
+ {
+ transition = 1;
+ if (mode == MODE_CELT_ONLY)
+ opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
+ }
+ if (audiosize > frame_size)
+ {
+ /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/
+ RESTORE_STACK;
+ return OPUS_BAD_ARG;
+ } else {
+ frame_size = audiosize;
+ }
+
+ ALLOC(pcm_silk, IMAX(F10, frame_size)*st->channels, opus_int16);
+ ALLOC(redundant_audio, F5*st->channels, opus_val16);
+
+ /* SILK processing */
+ if (mode != MODE_CELT_ONLY)
+ {
+ int lost_flag, decoded_samples;
+ opus_int16 *pcm_ptr = pcm_silk;
+
+ if (st->prev_mode==MODE_CELT_ONLY)
+ silk_InitDecoder( silk_dec );
+
+ /* The SILK PLC cannot produce frames of less than 10 ms */
+ st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs);
+
+ if (data != NULL)
+ {
+ st->DecControl.nChannelsInternal = st->stream_channels;
+ if( mode == MODE_SILK_ONLY ) {
+ if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
+ st->DecControl.internalSampleRate = 8000;
+ } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
+ st->DecControl.internalSampleRate = 12000;
+ } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
+ st->DecControl.internalSampleRate = 16000;
+ } else {
+ st->DecControl.internalSampleRate = 16000;
+ silk_assert( 0 );
+ }
+ } else {
+ /* Hybrid mode */
+ st->DecControl.internalSampleRate = 16000;
+ }
+ }
+
+ lost_flag = data == NULL ? 1 : 2 * decode_fec;
+ decoded_samples = 0;
+ do {
+ /* Call SILK decoder */
+ int first_frame = decoded_samples == 0;
+ silk_ret = silk_Decode( silk_dec, &st->DecControl,
+ lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size );
+ if( silk_ret ) {
+ if (lost_flag) {
+ /* PLC failure should not be fatal */
+ silk_frame_size = frame_size;
+ for (i=0;i<frame_size*st->channels;i++)
+ pcm_ptr[i] = 0;
+ } else {
+ RESTORE_STACK;
+ return OPUS_INVALID_PACKET;
+ }
+ }
+ pcm_ptr += silk_frame_size * st->channels;
+ decoded_samples += silk_frame_size;
+ } while( decoded_samples < frame_size );
+ }
+
+ start_band = 0;
+ if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL
+ && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len)
+ {
+ /* Check if we have a redundant 0-8 kHz band */
+ if (mode == MODE_HYBRID)
+ redundancy = ec_dec_bit_logp(&dec, 12);
+ else
+ redundancy = 1;
+ if (redundancy)
+ {
+ celt_to_silk = ec_dec_bit_logp(&dec, 1);
+ /* redundancy_bytes will be at least two, in the non-hybrid
+ case due to the ec_tell() check above */
+ redundancy_bytes = mode==MODE_HYBRID ?
+ (opus_int32)ec_dec_uint(&dec, 256)+2 :
+ len-((ec_tell(&dec)+7)>>3);
+ len -= redundancy_bytes;
+ /* This is a sanity check. It should never happen for a valid
+ packet, so the exact behaviour is not normative. */
+ if (len*8 < ec_tell(&dec))
+ {
+ len = 0;
+ redundancy_bytes = 0;
+ redundancy = 0;
+ }
+ /* Shrink decoder because of raw bits */
+ dec.storage -= redundancy_bytes;
+ }
+ }
+ if (mode != MODE_CELT_ONLY)
+ start_band = 17;
+
+ {
+ int endband=21;
+
+ switch(st->bandwidth)
+ {
+ case OPUS_BANDWIDTH_NARROWBAND:
+ endband = 13;
+ break;
+ case OPUS_BANDWIDTH_MEDIUMBAND:
+ case OPUS_BANDWIDTH_WIDEBAND:
+ endband = 17;
+ break;
+ case OPUS_BANDWIDTH_SUPERWIDEBAND:
+ endband = 19;
+ break;
+ case OPUS_BANDWIDTH_FULLBAND:
+ endband = 21;
+ break;
+ }
+ celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband));
+ celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels));
+ }
+
+ if (redundancy)
+ transition = 0;
+
+ if (transition && mode != MODE_CELT_ONLY)
+ opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
+
+ /* 5 ms redundant frame for CELT->SILK*/
+ if (redundancy && celt_to_silk)
+ {
+ celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
+ celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,
+ redundant_audio, F5, NULL);
+ celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
+ }
+
+ /* MUST be after PLC */
+ celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));
+
+ if (mode != MODE_SILK_ONLY)
+ {
+ int celt_frame_size = IMIN(F20, frame_size);
+ /* Make sure to discard any previous CELT state */
+ if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)
+ celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
+ /* Decode CELT */
+ celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data,
+ len, pcm, celt_frame_size, &dec);
+ } else {
+ unsigned char silence[2] = {0xFF, 0xFF};
+ for (i=0;i<frame_size*st->channels;i++)
+ pcm[i] = 0;
+ /* For hybrid -> SILK transitions, we let the CELT MDCT
+ do a fade-out by decoding a silence frame */
+ if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) )
+ {
+ celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
+ celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL);
+ }
+ }
+
+ if (mode != MODE_CELT_ONLY)
+ {
+#ifdef FIXED_POINT
+ for (i=0;i<frame_size*st->channels;i++)
+ pcm[i] = SAT16(pcm[i] + pcm_silk[i]);
+#else
+ for (i=0;i<frame_size*st->channels;i++)
+ pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]);
+#endif
+ }
+
+ {
+ const CELTMode *celt_mode;
+ celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode));
+ window = celt_mode->window;
+ }
+
+ /* 5 ms redundant frame for SILK->CELT */
+ if (redundancy && !celt_to_silk)
+ {
+ celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
+ celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
+
+ celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL);
+ celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
+ smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
+ pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
+ }
+ if (redundancy && celt_to_silk)
+ {
+ for (c=0;c<st->channels;c++)
+ {
+ for (i=0;i<F2_5;i++)
+ pcm[st->channels*i+c] = redundant_audio[st->channels*i+c];
+ }
+ smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5,
+ pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs);
+ }
+ if (transition)
+ {
+ if (audiosize >= F5)
+ {
+ for (i=0;i<st->channels*F2_5;i++)
+ pcm[i] = pcm_transition[i];
+ smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5,
+ pcm+st->channels*F2_5, F2_5,
+ st->channels, window, st->Fs);
+ } else {
+ /* Not enough time to do a clean transition, but we do it anyway
+ This will not preserve amplitude perfectly and may introduce
+ a bit of temporal aliasing, but it shouldn't be too bad and
+ that's pretty much the best we can do. In any case, generating this
+ transition it pretty silly in the first place */
+ smooth_fade(pcm_transition, pcm,
+ pcm, F2_5,
+ st->channels, window, st->Fs);
+ }
+ }
+
+ if(st->decode_gain)
+ {
+ opus_val32 gain;
+ gain = celt_exp2(MULT16_16_P15(QCONST16(6.48814081e-4f, 25), st->decode_gain));
+ for (i=0;i<frame_size*st->channels;i++)
+ {
+ opus_val32 x;
+ x = MULT16_32_P16(pcm[i],gain);
+ pcm[i] = SATURATE(x, 32767);
+ }
+ }
+
+ if (len <= 1)
+ st->rangeFinal = 0;
+ else
+ st->rangeFinal = dec.rng ^ redundant_rng;
+
+ st->prev_mode = mode;
+ st->prev_redundancy = redundancy && !celt_to_silk;
+ RESTORE_STACK;
+ return celt_ret < 0 ? celt_ret : audiosize;
+
+}
+
+static int parse_size(const unsigned char *data, opus_int32 len, short *size)
+{
+ if (len<1)
+ {
+ *size = -1;
+ return -1;
+ } else if (data[0]<252)
+ {
+ *size = data[0];
+ return 1;
+ } else if (len<2)
+ {
+ *size = -1;
+ return -1;
+ } else {
+ *size = 4*data[1] + data[0];
+ return 2;
+ }
+}
+
+static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
+ int self_delimited, unsigned char *out_toc,
+ const unsigned char *frames[48], short size[48], int *payload_offset)
+{
+ int i, bytes;
+ int count;
+ int cbr;
+ unsigned char ch, toc;
+ int framesize;
+ int last_size;
+ const unsigned char *data0 = data;
+
+ if (size==NULL)
+ return OPUS_BAD_ARG;
+
+ framesize = opus_packet_get_samples_per_frame(data, 48000);
+
+ cbr = 0;
+ toc = *data++;
+ len--;
+ last_size = len;
+ switch (toc&0x3)
+ {
+ /* One frame */
+ case 0:
+ count=1;
+ break;
+ /* Two CBR frames */
+ case 1:
+ count=2;
+ cbr = 1;
+ if (!self_delimited)
+ {
+ if (len&0x1)
+ return OPUS_INVALID_PACKET;
+ size[0] = last_size = len/2;
+ }
+ break;
+ /* Two VBR frames */
+ case 2:
+ count = 2;
+ bytes = parse_size(data, len, size);
+ len -= bytes;
+ if (size[0]<0 || size[0] > len)
+ return OPUS_INVALID_PACKET;
+ data += bytes;
+ last_size = len-size[0];
+ break;
+ /* Multiple CBR/VBR frames (from 0 to 120 ms) */
+ default: /*case 3:*/
+ if (len<1)
+ return OPUS_INVALID_PACKET;
+ /* Number of frames encoded in bits 0 to 5 */
+ ch = *data++;
+ count = ch&0x3F;
+ if (count <= 0 || framesize*count > 5760)
+ return OPUS_INVALID_PACKET;
+ len--;
+ /* Padding flag is bit 6 */
+ if (ch&0x40)
+ {
+ int padding=0;
+ int p;
+ do {
+ if (len<=0)
+ return OPUS_INVALID_PACKET;
+ p = *data++;
+ len--;
+ padding += p==255 ? 254: p;
+ } while (p==255);
+ len -= padding;
+ }
+ if (len<0)
+ return OPUS_INVALID_PACKET;
+ /* VBR flag is bit 7 */
+ cbr = !(ch&0x80);
+ if (!cbr)
+ {
+ /* VBR case */
+ last_size = len;
+ for (i=0;i<count-1;i++)
+ {
+ bytes = parse_size(data, len, size+i);
+ len -= bytes;
+ if (size[i]<0 || size[i] > len)
+ return OPUS_INVALID_PACKET;
+ data += bytes;
+ last_size -= bytes+size[i];
+ }
+ if (last_size<0)
+ return OPUS_INVALID_PACKET;
+ } else if (!self_delimited)
+ {
+ /* CBR case */
+ last_size = len/count;
+ if (last_size*count!=len)
+ return OPUS_INVALID_PACKET;
+ for (i=0;i<count-1;i++)
+ size[i] = last_size;
+ }
+ break;
+ }
+ /* Self-delimited framing has an extra size for the last frame. */
+ if (self_delimited)
+ {
+ bytes = parse_size(data, len, size+count-1);
+ len -= bytes;
+ if (size[count-1]<0 || size[count-1] > len)
+ return OPUS_INVALID_PACKET;
+ data += bytes;
+ /* For CBR packets, apply the size to all the frames. */
+ if (cbr)
+ {
+ if (size[count-1]*count > len)
+ return OPUS_INVALID_PACKET;
+ for (i=0;i<count-1;i++)
+ size[i] = size[count-1];
+ } else if(size[count-1] > last_size)
+ return OPUS_INVALID_PACKET;
+ } else
+ {
+ /* Because it's not encoded explicitly, it's possible the size of the
+ last packet (or all the packets, for the CBR case) is larger than
+ 1275. Reject them here.*/
+ if (last_size > 1275)
+ return OPUS_INVALID_PACKET;
+ size[count-1] = last_size;
+ }
+
+ if (frames)
+ {
+ for (i=0;i<count;i++)
+ {
+ frames[i] = data;
+ data += size[i];
+ }
+ }
+
+ if (out_toc)
+ *out_toc = toc;
+
+ if (payload_offset)
+ *payload_offset = data-data0;
+
+ return count;
+}
+
+int opus_packet_parse(const unsigned char *data, opus_int32 len,
+ unsigned char *out_toc, const unsigned char *frames[48],
+ short size[48], int *payload_offset)
+{
+ return opus_packet_parse_impl(data, len, 0, out_toc,
+ frames, size, payload_offset);
+}
+
+int opus_decode_native(OpusDecoder *st, const unsigned char *data,
+ opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,
+ int self_delimited, int *packet_offset)
+{
+ int i, nb_samples;
+ int count, offset;
+ unsigned char toc;
+ int tot_offset;
+ /* 48 x 2.5 ms = 120 ms */
+ short size[48];
+ if (decode_fec<0 || decode_fec>1)
+ return OPUS_BAD_ARG;
+ if (len==0 || data==NULL)
+ return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0);
+ else if (len<0)
+ return OPUS_BAD_ARG;
+
+ tot_offset = 0;
+ st->mode = opus_packet_get_mode(data);
+ st->bandwidth = opus_packet_get_bandwidth(data);
+ st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
+ st->stream_channels = opus_packet_get_nb_channels(data);
+
+ count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset);
+ if (count < 0)
+ return count;
+
+ data += offset;
+ tot_offset += offset;
+
+ if (count*st->frame_size > frame_size)
+ return OPUS_BUFFER_TOO_SMALL;
+ nb_samples=0;
+ for (i=0;i<count;i++)
+ {
+ int ret;
+ ret = opus_decode_frame(st, data, size[i], pcm, frame_size-nb_samples, decode_fec);
+ if (ret<0)
+ return ret;
+ data += size[i];
+ tot_offset += size[i];
+ pcm += ret*st->channels;
+ nb_samples += ret;
+ }
+ if (packet_offset != NULL)
+ *packet_offset = tot_offset;
+ return nb_samples;
+}
+
+#ifdef FIXED_POINT
+
+int opus_decode(OpusDecoder *st, const unsigned char *data,
+ opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
+{
+ return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL);
+}
+
+#ifndef DISABLE_FLOAT_API
+int opus_decode_float(OpusDecoder *st, const unsigned char *data,
+ opus_int32 len, float *pcm, int frame_size, int decode_fec)
+{
+ VARDECL(opus_int16, out);
+ int ret, i;
+ ALLOC_STACK;
+
+ ALLOC(out, frame_size*st->channels, opus_int16);
+
+ ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL);
+ if (ret > 0)
+ {
+ for (i=0;i<ret*st->channels;i++)
+ pcm[i] = (1.f/32768.f)*(out[i]);
+ }
+ RESTORE_STACK;
+ return ret;
+}
+#endif
+
+
+#else
+int opus_decode(OpusDecoder *st, const unsigned char *data,
+ opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
+{
+ VARDECL(float, out);
+ int ret, i;
+ ALLOC_STACK;
+
+ if(frame_size<0)
+ {
+ RESTORE_STACK;
+ return OPUS_BAD_ARG;
+ }
+
+ ALLOC(out, frame_size*st->channels, float);
+
+ ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL);
+ if (ret > 0)
+ {
+ for (i=0;i<ret*st->channels;i++)
+ pcm[i] = FLOAT2INT16(out[i]);
+ }
+ RESTORE_STACK;
+ return ret;
+}
+
+int opus_decode_float(OpusDecoder *st, const unsigned char *data,
+ opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
+{
+ return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL);
+}
+
+#endif
+
+int opus_decoder_ctl(OpusDecoder *st, int request, ...)
+{
+ int ret = OPUS_OK;
+ va_list ap;
+ void *silk_dec;
+ CELTDecoder *celt_dec;
+
+ silk_dec = (char*)st+st->silk_dec_offset;
+ celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
+
+
+ va_start(ap, request);
+
+ switch (request)
+ {
+ case OPUS_GET_BANDWIDTH_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ *value = st->bandwidth;
+ }
+ break;
+ case OPUS_GET_FINAL_RANGE_REQUEST:
+ {
+ opus_uint32 *value = va_arg(ap, opus_uint32*);
+ *value = st->rangeFinal;
+ }
+ break;
+ case OPUS_RESET_STATE:
+ {
+ OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START,
+ sizeof(OpusDecoder)-
+ ((char*)&st->OPUS_DECODER_RESET_START - (char*)st));
+
+ celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
+ silk_InitDecoder( silk_dec );
+ st->stream_channels = st->channels;
+ st->frame_size = st->Fs/400;
+ }
+ break;
+ case OPUS_GET_SAMPLE_RATE_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (value==NULL)
+ {
+ ret = OPUS_BAD_ARG;
+ break;
+ }
+ *value = st->Fs;
+ }
+ break;
+ case OPUS_GET_PITCH_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (value==NULL)
+ {
+ ret = OPUS_BAD_ARG;
+ break;
+ }
+ if (st->prev_mode == MODE_CELT_ONLY)
+ celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
+ else
+ *value = st->DecControl.prevPitchLag;
+ }
+ break;
+ case OPUS_GET_GAIN_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (value==NULL)
+ {
+ ret = OPUS_BAD_ARG;
+ break;
+ }
+ *value = st->decode_gain;
+ }
+ break;
+ case OPUS_SET_GAIN_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value<-32768 || value>32767)
+ {
+ ret = OPUS_BAD_ARG;
+ break;
+ }
+ st->decode_gain = value;
+ }
+ break;
+ default:
+ /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
+ ret = OPUS_UNIMPLEMENTED;
+ break;
+ }
+
+ va_end(ap);
+ return ret;
+}
+
+void opus_decoder_destroy(OpusDecoder *st)
+{
+ opus_free(st);
+}
+
+
+int opus_packet_get_bandwidth(const unsigned char *data)
+{
+ int bandwidth;
+ if (data[0]&0x80)
+ {
+ bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3);
+ if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
+ bandwidth = OPUS_BANDWIDTH_NARROWBAND;
+ } else if ((data[0]&0x60) == 0x60)
+ {
+ bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND :
+ OPUS_BANDWIDTH_SUPERWIDEBAND;
+ } else {
+ bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3);
+ }
+ return bandwidth;
+}
+
+int opus_packet_get_samples_per_frame(const unsigned char *data,
+ opus_int32 Fs)
+{
+ int audiosize;
+ if (data[0]&0x80)
+ {
+ audiosize = ((data[0]>>3)&0x3);
+ audiosize = (Fs<<audiosize)/400;
+ } else if ((data[0]&0x60) == 0x60)
+ {
+ audiosize = (data[0]&0x08) ? Fs/50 : Fs/100;
+ } else {
+ audiosize = ((data[0]>>3)&0x3);
+ if (audiosize == 3)
+ audiosize = Fs*60/1000;
+ else
+ audiosize = (Fs<<audiosize)/100;
+ }
+ return audiosize;
+}
+
+int opus_packet_get_nb_channels(const unsigned char *data)
+{
+ return (data[0]&0x4) ? 2 : 1;
+}
+
+int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len)
+{
+ int count;
+ if (len<1)
+ return OPUS_BAD_ARG;
+ count = packet[0]&0x3;
+ if (count==0)
+ return 1;
+ else if (count!=3)
+ return 2;
+ else if (len<2)
+ return OPUS_INVALID_PACKET;
+ else
+ return packet[1]&0x3F;
+}
+
+int opus_decoder_get_nb_samples(const OpusDecoder *dec,
+ const unsigned char packet[], opus_int32 len)
+{
+ int samples;
+ int count = opus_packet_get_nb_frames(packet, len);
+
+ if (count<0)
+ return count;
+
+ samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs);
+ /* Can't have more than 120 ms */
+ if (samples*25 > dec->Fs*3)
+ return OPUS_INVALID_PACKET;
+ else
+ return samples;
+}
diff --git a/lib/rbcodec/codecs/libopus/opus_defines.h b/lib/rbcodec/codecs/libopus/opus_defines.h
new file mode 100644
index 0000000000..830d225f14
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_defines.h
@@ -0,0 +1,644 @@
+/* Copyright (c) 2010-2011 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.
+
+ 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 COPYRIGHT OWNER
+ 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.
+*/
+
+/**
+ * @file opus_defines.h
+ * @brief Opus reference implementation constants
+ */
+
+#ifndef OPUS_DEFINES_H
+#define OPUS_DEFINES_H
+
+#include "opus_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup opus_errorcodes Error codes
+ * @{
+ */
+/** No error @hideinitializer*/
+#define OPUS_OK 0
+/** One or more invalid/out of range arguments @hideinitializer*/
+#define OPUS_BAD_ARG -1
+/** The mode struct passed is invalid @hideinitializer*/
+#define OPUS_BUFFER_TOO_SMALL -2
+/** An internal error was detected @hideinitializer*/
+#define OPUS_INTERNAL_ERROR -3
+/** The compressed data passed is corrupted @hideinitializer*/
+#define OPUS_INVALID_PACKET -4
+/** Invalid/unsupported request number @hideinitializer*/
+#define OPUS_UNIMPLEMENTED -5
+/** An encoder or decoder structure is invalid or already freed @hideinitializer*/
+#define OPUS_INVALID_STATE -6
+/** Memory allocation has failed @hideinitializer*/
+#define OPUS_ALLOC_FAIL -7
+/**@}*/
+
+/** @cond OPUS_INTERNAL_DOC */
+/**Export control for opus functions */
+
+#if defined(__GNUC__) && defined(OPUS_BUILD)
+# define OPUS_EXPORT __attribute__ ((visibility ("default")))
+#elif defined(WIN32) && !defined(__MINGW32__)
+# ifdef OPUS_BUILD
+# define OPUS_EXPORT __declspec(dllexport)
+# else
+# define OPUS_EXPORT
+# endif
+#else
+# define OPUS_EXPORT
+#endif
+
+# if !defined(OPUS_GNUC_PREREQ)
+# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
+# define OPUS_GNUC_PREREQ(_maj,_min) \
+ ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
+# else
+# define OPUS_GNUC_PREREQ(_maj,_min) 0
+# endif
+# endif
+
+#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
+# if OPUS_GNUC_PREREQ(3,0)
+# define OPUS_RESTRICT __restrict__
+# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
+# define OPUS_RESTRICT __restrict
+# else
+# define OPUS_RESTRICT
+# endif
+#else
+# define OPUS_RESTRICT restrict
+#endif
+
+/**Warning attributes for opus functions
+ * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out
+ * some paranoid null checks. */
+#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)
+# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
+#else
+# define OPUS_WARN_UNUSED_RESULT
+#endif
+#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)
+# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x)))
+#else
+# define OPUS_ARG_NONNULL(_x)
+#endif
+
+/** These are the actual Encoder CTL ID numbers.
+ * They should not be used directly by applications.
+ * In general, SETs should be even and GETs should be odd.*/
+#define OPUS_SET_APPLICATION_REQUEST 4000
+#define OPUS_GET_APPLICATION_REQUEST 4001
+#define OPUS_SET_BITRATE_REQUEST 4002
+#define OPUS_GET_BITRATE_REQUEST 4003
+#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004
+#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005
+#define OPUS_SET_VBR_REQUEST 4006
+#define OPUS_GET_VBR_REQUEST 4007
+#define OPUS_SET_BANDWIDTH_REQUEST 4008
+#define OPUS_GET_BANDWIDTH_REQUEST 4009
+#define OPUS_SET_COMPLEXITY_REQUEST 4010
+#define OPUS_GET_COMPLEXITY_REQUEST 4011
+#define OPUS_SET_INBAND_FEC_REQUEST 4012
+#define OPUS_GET_INBAND_FEC_REQUEST 4013
+#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014
+#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015
+#define OPUS_SET_DTX_REQUEST 4016
+#define OPUS_GET_DTX_REQUEST 4017
+#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020
+#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021
+#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022
+#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023
+#define OPUS_SET_SIGNAL_REQUEST 4024
+#define OPUS_GET_SIGNAL_REQUEST 4025
+#define OPUS_GET_LOOKAHEAD_REQUEST 4027
+/* #define OPUS_RESET_STATE 4028 */
+#define OPUS_GET_SAMPLE_RATE_REQUEST 4029
+#define OPUS_GET_FINAL_RANGE_REQUEST 4031
+#define OPUS_GET_PITCH_REQUEST 4033
+#define OPUS_SET_GAIN_REQUEST 4034
+#define OPUS_GET_GAIN_REQUEST 4045
+#define OPUS_SET_LSB_DEPTH_REQUEST 4036
+#define OPUS_GET_LSB_DEPTH_REQUEST 4037
+
+/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
+#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
+#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
+#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))
+/** @endcond */
+
+/** @defgroup opus_ctlvalues Pre-defined values for CTL interface
+ * @see opus_genericctls, opus_encoderctls
+ * @{
+ */
+/* Values for the various encoder CTLs */
+#define OPUS_AUTO -1000 /**<Auto/default setting @hideinitializer*/
+#define OPUS_BITRATE_MAX -1 /**<Maximum bitrate @hideinitializer*/
+
+/** Best for most VoIP/videoconference applications where listening quality and intelligibility matter most
+ * @hideinitializer */
+#define OPUS_APPLICATION_VOIP 2048
+/** Best for broadcast/high-fidelity application where the decoded audio should be as close as possible to the input
+ * @hideinitializer */
+#define OPUS_APPLICATION_AUDIO 2049
+/** Only use when lowest-achievable latency is what matters most. Voice-optimized modes cannot be used.
+ * @hideinitializer */
+#define OPUS_APPLICATION_RESTRICTED_LOWDELAY 2051
+
+#define OPUS_SIGNAL_VOICE 3001 /**< Signal being encoded is voice */
+#define OPUS_SIGNAL_MUSIC 3002 /**< Signal being encoded is music */
+#define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_SUPERWIDEBAND 1104 /**<12 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_FULLBAND 1105 /**<20 kHz bandpass @hideinitializer*/
+
+/**@}*/
+
+
+/** @defgroup opus_encoderctls Encoder related CTLs
+ *
+ * These are convenience macros for use with the \c opus_encode_ctl
+ * interface. They are used to generate the appropriate series of
+ * arguments for that call, passing the correct type, size and so
+ * on as expected for each particular request.
+ *
+ * Some usage examples:
+ *
+ * @code
+ * int ret;
+ * ret = opus_encoder_ctl(enc_ctx, OPUS_SET_BANDWIDTH(OPUS_AUTO));
+ * if (ret != OPUS_OK) return ret;
+ *
+ * opus_int32 rate;
+ * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&rate));
+ *
+ * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);
+ * @endcode
+ *
+ * @see opus_genericctls, opus_encoder
+ * @{
+ */
+
+/** Configures the encoder's computational complexity.
+ * The supported range is 0-10 inclusive with 10 representing the highest complexity.
+ * @see OPUS_GET_COMPLEXITY
+ * @param[in] x <tt>opus_int32</tt>: Allowed values: 0-10, inclusive.
+ *
+ * @hideinitializer */
+#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x)
+/** Gets the encoder's complexity configuration.
+ * @see OPUS_SET_COMPLEXITY
+ * @param[out] x <tt>opus_int32 *</tt>: Returns a value in the range 0-10,
+ * inclusive.
+ * @hideinitializer */
+#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the bitrate in the encoder.
+ * Rates from 500 to 512000 bits per second are meaningful, as well as the
+ * special values #OPUS_AUTO and #OPUS_BITRATE_MAX.
+ * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much
+ * rate as it can, which is useful for controlling the rate by adjusting the
+ * output buffer size.
+ * @see OPUS_GET_BITRATE
+ * @param[in] x <tt>opus_int32</tt>: Bitrate in bits per second. The default
+ * is determined based on the number of
+ * channels and the input sampling rate.
+ * @hideinitializer */
+#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x)
+/** Gets the encoder's bitrate configuration.
+ * @see OPUS_SET_BITRATE
+ * @param[out] x <tt>opus_int32 *</tt>: Returns the bitrate in bits per second.
+ * The default is determined based on the
+ * number of channels and the input
+ * sampling rate.
+ * @hideinitializer */
+#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x)
+
+/** Enables or disables variable bitrate (VBR) in the encoder.
+ * The configured bitrate may not be met exactly because frames must
+ * be an integer number of bytes in length.
+ * @warning Only the MDCT mode of Opus can provide hard CBR behavior.
+ * @see OPUS_GET_VBR
+ * @see OPUS_SET_VBR_CONSTRAINT
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Hard CBR. For LPC/hybrid modes at very low bit-rate, this can
+ * cause noticeable quality degradation.</dd>
+ * <dt>1</dt><dd>VBR (default). The exact type of VBR is controlled by
+ * #OPUS_SET_VBR_CONSTRAINT.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x)
+/** Determine if variable bitrate (VBR) is enabled in the encoder.
+ * @see OPUS_SET_VBR
+ * @see OPUS_GET_VBR_CONSTRAINT
+ * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Hard CBR.</dd>
+ * <dt>1</dt><dd>VBR (default). The exact type of VBR may be retrieved via
+ * #OPUS_GET_VBR_CONSTRAINT.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x)
+
+/** Enables or disables constrained VBR in the encoder.
+ * This setting is ignored when the encoder is in CBR mode.
+ * @warning Only the MDCT mode of Opus currently heeds the constraint.
+ * Speech mode ignores it completely, hybrid mode may fail to obey it
+ * if the LPC layer uses more bitrate than the constraint would have
+ * permitted.
+ * @see OPUS_GET_VBR_CONSTRAINT
+ * @see OPUS_SET_VBR
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Unconstrained VBR.</dd>
+ * <dt>1</dt><dd>Constrained VBR (default). This creates a maximum of one
+ * frame of buffering delay assuming a transport with a
+ * serialization speed of the nominal bitrate.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x)
+/** Determine if constrained VBR is enabled in the encoder.
+ * @see OPUS_SET_VBR_CONSTRAINT
+ * @see OPUS_GET_VBR
+ * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Unconstrained VBR.</dd>
+ * <dt>1</dt><dd>Constrained VBR (default).</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures mono/stereo forcing in the encoder.
+ * This can force the encoder to produce packets encoded as either mono or
+ * stereo, regardless of the format of the input audio. This is useful when
+ * the caller knows that the input signal is currently a mono source embedded
+ * in a stereo stream.
+ * @see OPUS_GET_FORCE_CHANNELS
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>
+ * <dt>1</dt> <dd>Forced mono</dd>
+ * <dt>2</dt> <dd>Forced stereo</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x)
+/** Gets the encoder's forced channel configuration.
+ * @see OPUS_SET_FORCE_CHANNELS
+ * @param[out] x <tt>opus_int32 *</tt>:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>
+ * <dt>1</dt> <dd>Forced mono</dd>
+ * <dt>2</dt> <dd>Forced stereo</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the maximum bandpass that the encoder will select automatically.
+ * Applications should normally use this instead of #OPUS_SET_BANDWIDTH
+ * (leaving that set to the default, #OPUS_AUTO). This allows the
+ * application to set an upper bound based on the type of input it is
+ * providing, but still gives the encoder the freedom to reduce the bandpass
+ * when the bitrate becomes too low, for better overall quality.
+ * @see OPUS_GET_MAX_BANDWIDTH
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x)
+
+/** Gets the encoder's configured maximum allowed bandpass.
+ * @see OPUS_SET_MAX_BANDWIDTH
+ * @param[out] x <tt>opus_int32 *</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
+
+/** Sets the encoder's bandpass to a specific value.
+ * This prevents the encoder from automatically selecting the bandpass based
+ * on the available bitrate. If an application knows the bandpass of the input
+ * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH
+ * instead, which still gives the encoder the freedom to reduce the bandpass
+ * when the bitrate becomes too low, for better overall quality.
+ * @see OPUS_GET_BANDWIDTH
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x)
+
+/** Configures the type of signal being encoded.
+ * This is a hint which helps the encoder's mode selection.
+ * @see OPUS_GET_SIGNAL
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>
+ * <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured signal type.
+ * @see OPUS_SET_SIGNAL
+ * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>
+ * <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x)
+
+
+/** Configures the encoder's intended application.
+ * The initial value is a mandatory argument to the encoder_create function.
+ * @see OPUS_GET_APPLICATION
+ * @param[in] x <tt>opus_int32</tt>: Returns one of the following values:
+ * <dl>
+ * <dt>#OPUS_APPLICATION_VOIP</dt>
+ * <dd>Process signal for improved speech intelligibility.</dd>
+ * <dt>#OPUS_APPLICATION_AUDIO</dt>
+ * <dd>Favor faithfulness to the original input.</dd>
+ * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+ * <dd>Configure the minimum possible coding delay by disabling certain modes
+ * of operation.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured application.
+ * @see OPUS_SET_APPLICATION
+ * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
+ * <dl>
+ * <dt>#OPUS_APPLICATION_VOIP</dt>
+ * <dd>Process signal for improved speech intelligibility.</dd>
+ * <dt>#OPUS_APPLICATION_AUDIO</dt>
+ * <dd>Favor faithfulness to the original input.</dd>
+ * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+ * <dd>Configure the minimum possible coding delay by disabling certain modes
+ * of operation.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the sampling rate the encoder or decoder was initialized with.
+ * This simply returns the <code>Fs</code> value passed to opus_encoder_init()
+ * or opus_decoder_init().
+ * @param[out] x <tt>opus_int32 *</tt>: Sampling rate of encoder or decoder.
+ * @hideinitializer
+ */
+#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the total samples of delay added by the entire codec.
+ * This can be queried by the encoder and then the provided number of samples can be
+ * skipped on from the start of the decoder's output to provide time aligned input
+ * and output. From the perspective of a decoding application the real data begins this many
+ * samples late.
+ *
+ * The decoder contribution to this delay is identical for all decoders, but the
+ * encoder portion of the delay may vary from implementation to implementation,
+ * version to version, or even depend on the encoder's initial configuration.
+ * Applications needing delay compensation should call this CTL rather than
+ * hard-coding a value.
+ * @param[out] x <tt>opus_int32 *</tt>: Number of lookahead samples
+ * @hideinitializer */
+#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's use of inband forward error correction (FEC).
+ * @note This is only applicable to the LPC layer
+ * @see OPUS_GET_INBAND_FEC
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Disable inband FEC (default).</dd>
+ * <dt>1</dt><dd>Enable inband FEC.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x)
+/** Gets encoder's configured use of inband forward error correction.
+ * @see OPUS_SET_INBAND_FEC
+ * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Inband FEC disabled (default).</dd>
+ * <dt>1</dt><dd>Inband FEC enabled.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's expected packet loss percentage.
+ * Higher values with trigger progressively more loss resistant behavior in the encoder
+ * at the expense of quality at a given bitrate in the lossless case, but greater quality
+ * under loss.
+ * @see OPUS_GET_PACKET_LOSS_PERC
+ * @param[in] x <tt>opus_int32</tt>: Loss percentage in the range 0-100, inclusive (default: 0).
+ * @hideinitializer */
+#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured packet loss percentage.
+ * @see OPUS_SET_PACKET_LOSS_PERC
+ * @param[out] x <tt>opus_int32 *</tt>: Returns the configured loss percentage
+ * in the range 0-100, inclusive (default: 0).
+ * @hideinitializer */
+#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's use of discontinuous transmission (DTX).
+ * @note This is only applicable to the LPC layer
+ * @see OPUS_GET_DTX
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Disable DTX (default).</dd>
+ * <dt>1</dt><dd>Enabled DTX.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x)
+/** Gets encoder's configured use of discontinuous transmission.
+ * @see OPUS_SET_DTX
+ * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>DTX disabled (default).</dd>
+ * <dt>1</dt><dd>DTX enabled.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x)
+/**@}*/
+
+/** @defgroup opus_genericctls Generic CTLs
+ *
+ * These macros are used with the \c opus_decoder_ctl and
+ * \c opus_encoder_ctl calls to generate a particular
+ * request.
+ *
+ * When called on an \c OpusDecoder they apply to that
+ * particular decoder instance. When called on an
+ * \c OpusEncoder they apply to the corresponding setting
+ * on that encoder instance, if present.
+ *
+ * Some usage examples:
+ *
+ * @code
+ * int ret;
+ * opus_int32 pitch;
+ * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch));
+ * if (ret == OPUS_OK) return ret;
+ *
+ * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);
+ * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE);
+ *
+ * opus_int32 enc_bw, dec_bw;
+ * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw));
+ * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw));
+ * if (enc_bw != dec_bw) {
+ * printf("packet bandwidth mismatch!\n");
+ * }
+ * @endcode
+ *
+ * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls
+ * @{
+ */
+
+/** Resets the codec state to be equivalent to a freshly initialized state.
+ * This should be called when switching streams in order to prevent
+ * the back to back decoding from giving different results from
+ * one at a time decoding.
+ * @hideinitializer */
+#define OPUS_RESET_STATE 4028
+
+/** Gets the final state of the codec's entropy coder.
+ * This is used for testing purposes,
+ * The encoder and decoder state should be identical after coding a payload
+ * (assuming no data corruption or software bugs)
+ *
+ * @param[out] x <tt>opus_uint32 *</tt>: Entropy coder state
+ *
+ * @hideinitializer */
+#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x)
+
+/** Gets the pitch of the last decoded frame, if available.
+ * This can be used for any post-processing algorithm requiring the use of pitch,
+ * e.g. time stretching/shortening. If the last frame was not voiced, or if the
+ * pitch was not coded in the frame, then zero is returned.
+ *
+ * This CTL is only implemented for decoder instances.
+ *
+ * @param[out] x <tt>opus_int32 *</tt>: pitch period at 48 kHz (or 0 if not available)
+ *
+ * @hideinitializer */
+#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the encoder's configured bandpass or the decoder's last bandpass.
+ * @see OPUS_SET_BANDWIDTH
+ * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
+ * <dl>
+ * <dt>#OP