aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-28 21:17:26 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-28 21:17:26 +0000
commit6b6bee25314cfac02cc555cddedb9680c63a26d6 (patch)
tree237d6cc1ffccbe6e8d5de6dc95c699934878e774
parent79181daa729bbfd77c8bf51dbcac8aac1593ccba (diff)
downloadsrc-6b6bee25314cfac02cc555cddedb9680c63a26d6.tar.gz
Update Opus to 1.0.2.
This update contains improvements for PLC, and various other fixes. TBR=wez@chromium.org Review URL: https://codereview.chromium.org/12388030 git-svn-id: svn://svn.chromium.org/chrome/trunk/deps/third_party/opus@185324 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--COPYING4
-rw-r--r--Makefile.am12
-rw-r--r--Makefile.in69
-rw-r--r--README4
-rw-r--r--aclocal.m46
-rw-r--r--celt/bands.c4
-rw-r--r--celt/celt.c216
-rw-r--r--celt/cwrs.c2
-rw-r--r--celt/ecintrin.h2
-rw-r--r--celt/entcode.c5
-rw-r--r--celt/pitch.c2
-rw-r--r--celt/quant_bands.c9
-rw-r--r--celt/rate.c22
-rw-r--r--celt/tests/test_unit_cwrs32.c28
-rw-r--r--celt/tests/test_unit_dft.c27
-rw-r--r--celt/tests/test_unit_entropy.c28
-rw-r--r--celt/tests/test_unit_laplace.c27
-rw-r--r--celt/tests/test_unit_mathops.c28
-rw-r--r--celt/tests/test_unit_mdct.c27
-rw-r--r--celt/tests/test_unit_rotation.c27
-rw-r--r--celt/tests/test_unit_types.c27
-rw-r--r--celt_headers.mk31
-rw-r--r--celt_sources.mk16
-rwxr-xr-xcompile91
-rwxr-xr-xconfig.guess16
-rw-r--r--config.h.in18
-rwxr-xr-xconfig.sub19
-rwxr-xr-xconfigure259
-rw-r--r--configure.ac35
-rwxr-xr-xdepcomp124
-rw-r--r--doc/Doxyfile.in2
-rw-r--r--doc/Makefile.am3
-rw-r--r--doc/Makefile.in29
-rw-r--r--include/opus.h465
-rw-r--r--include/opus_defines.h57
-rw-r--r--include/opus_multistream.h624
-rw-r--r--opus-uninstalled.pc.in8
-rw-r--r--opus.m42
-rw-r--r--opus.pc.in5
-rw-r--r--opus_headers.mk4
-rw-r--r--opus_sources.mk5
-rw-r--r--silk/API.h8
-rw-r--r--silk/NLSF_stabilize.c2
-rw-r--r--silk/PLC.c15
-rw-r--r--silk/SigProc_FIX.h4
-rw-r--r--silk/control_audio_bandwidth.c4
-rw-r--r--silk/control_codec.c12
-rw-r--r--silk/dec_API.c21
-rw-r--r--silk/decode_core.c16
-rw-r--r--silk/decode_frame.c27
-rw-r--r--silk/enc_API.c10
-rw-r--r--silk/fixed/LTP_analysis_filter_FIX.c4
-rw-r--r--silk/fixed/burg_modified_FIX.c4
-rw-r--r--silk/fixed/find_pitch_lags_FIX.c4
-rw-r--r--silk/fixed/main_FIX.h6
-rw-r--r--silk/fixed/noise_shape_analysis_FIX.c2
-rw-r--r--silk/fixed/pitch_analysis_core_FIX.c2
-rw-r--r--silk/fixed/residual_energy_FIX.c4
-rw-r--r--silk/float/LTP_analysis_filter_FLP.c4
-rw-r--r--silk/float/SigProc_FLP.h2
-rw-r--r--silk/float/burg_modified_FLP.c4
-rw-r--r--silk/float/find_pitch_lags_FLP.c4
-rw-r--r--silk/float/main_FLP.h6
-rw-r--r--silk/float/noise_shape_analysis_FLP.c2
-rw-r--r--silk/float/pitch_analysis_core_FLP.c2
-rw-r--r--silk/float/prefilter_FLP.c2
-rw-r--r--silk/float/residual_energy_FLP.c2
-rw-r--r--silk/float/wrappers_FLP.c2
-rw-r--r--silk/resampler_rom.c10
-rw-r--r--silk/resampler_rom.h8
-rw-r--r--silk/tables_LTP.c18
-rw-r--r--silk/tables_NLSF_CB_NB_MB.c14
-rw-r--r--silk/tables_NLSF_CB_WB.c14
-rw-r--r--silk/tables_other.c4
-rw-r--r--silk/tuning_parameters.h2
-rw-r--r--silk_headers.mk26
-rw-r--r--silk_sources.mk138
-rw-r--r--src/opus_compare.c27
-rw-r--r--src/opus_decoder.c124
-rw-r--r--src/opus_demo.c26
-rw-r--r--src/opus_encoder.c33
-rw-r--r--src/opus_multistream.c32
-rwxr-xr-xtests/run_vectors.sh33
-rw-r--r--tests/test_opus_api.c224
-rw-r--r--tests/test_opus_decode.c35
-rw-r--r--tests/test_opus_encode.c42
-rw-r--r--version.mk2
-rw-r--r--win32/config.h28
88 files changed, 2455 insertions, 949 deletions
diff --git a/COPYING b/COPYING
index 3167a00..f4159e6 100644
--- a/COPYING
+++ b/COPYING
@@ -37,8 +37,8 @@ specified at:
Xiph.Org Foundation:
https://datatracker.ietf.org/ipr/1524/
-Skype Limited:
-https://datatracker.ietf.org/ipr/1602/
+Microsoft Corporation:
+https://datatracker.ietf.org/ipr/1914/
Broadcom Corporation:
https://datatracker.ietf.org/ipr/1526/
diff --git a/Makefile.am b/Makefile.am
index db37d99..85909ce 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -126,24 +126,24 @@ install-opus: install
# Or just the docs
docs:
- cd doc && $(MAKE) $(AM_MAKEFLAGS)
+ ( cd doc && $(MAKE) $(AM_MAKEFLAGS) )
install-docs:
- cd doc && $(MAKE) $(AM_MAKEFLAGS) install
+ ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install )
# Or everything (by default)
all-local:
- @[ -n "$(NO_DOXYGEN)" ] || cd doc && $(MAKE) $(AM_MAKEFLAGS)
+ @[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) )
install-data-local:
- @[ -n "$(NO_DOXYGEN)" ] || cd doc && $(MAKE) $(AM_MAKEFLAGS) install
+ @[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install )
clean-local:
- -cd doc && $(MAKE) $(AM_MAKEFLAGS) clean
+ -( cd doc && $(MAKE) $(AM_MAKEFLAGS) clean )
uninstall-local:
- cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall
+ ( cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall )
.PHONY: opus check-opus install-opus docs install-docs
diff --git a/Makefile.in b/Makefile.in
index 07cb8eb..38b5021 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -19,6 +19,23 @@
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -405,6 +422,11 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
DATA = $(m4data_DATA) $(pkgconfig_DATA)
am__pkginclude_HEADERS_DIST = include/opus.h \
include/opus_multistream.h include/opus_types.h \
@@ -522,6 +544,8 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
+PC_BUILD = @PC_BUILD@
+PC_LIBM = @PC_LIBM@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
@@ -894,7 +918,6 @@ opus-uninstalled.pc: $(top_builddir)/config.status $(srcdir)/opus-uninstalled.pc
cd $(top_builddir) && $(SHELL) ./config.status $@
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -902,6 +925,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
@@ -1861,8 +1886,11 @@ distclean-libtool:
-rm -f libtool config.lt
install-m4dataDATA: $(m4data_DATA)
@$(NORMAL_INSTALL)
- test -z "$(m4datadir)" || $(MKDIR_P) "$(DESTDIR)$(m4datadir)"
@list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(m4datadir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(m4datadir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -1879,8 +1907,11 @@ uninstall-m4dataDATA:
dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir)
install-pkgconfigDATA: $(pkgconfig_DATA)
@$(NORMAL_INSTALL)
- test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -1897,8 +1928,11 @@ uninstall-pkgconfigDATA:
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
- test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)"
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -2176,13 +2210,10 @@ distdir: $(DISTFILES)
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
@@ -2268,7 +2299,7 @@ distcheck: dist
*.zip*) \
unzip $(distdir).zip ;;\
esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
+ chmod -R a-w $(distdir); chmod u+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
@@ -2499,23 +2530,23 @@ install-opus: install
# Or just the docs
docs:
- cd doc && $(MAKE) $(AM_MAKEFLAGS)
+ ( cd doc && $(MAKE) $(AM_MAKEFLAGS) )
install-docs:
- cd doc && $(MAKE) $(AM_MAKEFLAGS) install
+ ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install )
# Or everything (by default)
all-local:
- @[ -n "$(NO_DOXYGEN)" ] || cd doc && $(MAKE) $(AM_MAKEFLAGS)
+ @[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) )
install-data-local:
- @[ -n "$(NO_DOXYGEN)" ] || cd doc && $(MAKE) $(AM_MAKEFLAGS) install
+ @[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install )
clean-local:
- -cd doc && $(MAKE) $(AM_MAKEFLAGS) clean
+ -( cd doc && $(MAKE) $(AM_MAKEFLAGS) clean )
uninstall-local:
- cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall
+ ( cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall )
.PHONY: opus check-opus install-opus docs install-docs
diff --git a/README b/README
index ea68fe3..655c6b4 100644
--- a/README
+++ b/README
@@ -59,6 +59,10 @@ To build from the git repository, the following steps are necessary:
% ./configure
% make
+3) Install the codec libraries (optional)
+
+% sudo make install
+
Once you have compiled the codec, there will be a opus_demo executable
in the top directory.
diff --git a/aclocal.m4 b/aclocal.m4
index 6158f7b..3b2c931 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.11.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
@@ -8629,7 +8629,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.11'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.3], [],
+m4_if([$1], [1.11.6], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -8645,7 +8645,7 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.3])dnl
+[AM_AUTOMAKE_VERSION([1.11.6])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
diff --git a/celt/bands.c b/celt/bands.c
index f38b662..3be543c 100644
--- a/celt/bands.c
+++ b/celt/bands.c
@@ -905,8 +905,8 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
fill &= ((1<<B)-1)<<B;
delta = 16384;
} else {
- imid = bitexact_cos(itheta);
- iside = bitexact_cos(16384-itheta);
+ imid = bitexact_cos((opus_int16)itheta);
+ iside = bitexact_cos((opus_int16)(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));
diff --git a/celt/celt.c b/celt/celt.c
index adb9737..9bbe852 100644
--- a/celt/celt.c
+++ b/celt/celt.c
@@ -193,9 +193,13 @@ struct OpusCustomEncoder {
#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 */
+ /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_MAXPERIOD */
+ /* opus_val16 oldBandE[], Size = channels*mode->nbEBands */
+ /* opus_val16 oldLogE[], Size = channels*mode->nbEBands */
+ /* opus_val16 oldLogE2[], Size = channels*mode->nbEBands */
+#ifdef RESYNTH
+ /* opus_val16 overlap_mem[], Size = channels*overlap */
+#endif
};
int celt_encoder_get_size(int channels)
@@ -207,9 +211,14 @@ int celt_encoder_get_size(int 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);
+ + (channels*mode->overlap-1)*sizeof(celt_sig) /* celt_sig in_mem[channels*mode->overlap]; */
+ + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */
+ + 3*channels*mode->nbEBands*sizeof(opus_val16); /* opus_val16 oldBandE[channels*mode->nbEBands]; */
+ /* opus_val16 oldLogE[channels*mode->nbEBands]; */
+ /* opus_val16 oldLogE2[channels*mode->nbEBands]; */
+#ifdef RESYNTH
+ size += channels*mode->overlap*sizeof(celt_sig); /* celt_sig overlap_mem[channels*mode->nbEBands]; */
+#endif
return size;
}
@@ -563,7 +572,7 @@ static opus_val32 l1_metric(const celt_norm *tmp, int N, int LM, int width)
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 start, int *tf_sum)
{
int i;
VARDECL(int, metric);
@@ -576,7 +585,7 @@ static int tf_analysis(const CELTMode *m, int len, int C, int isTransient,
int tf_select=0;
SAVE_STACK;
- if (nbCompressedBytes<15*C)
+ if (nbCompressedBytes<15*C || start!=0)
{
*tf_sum = 0;
for (i=0;i<len;i++)
@@ -944,7 +953,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
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));
+ oldBandE = (opus_val16*)(st->in_mem+CC*(st->overlap+COMBFILTER_MAXPERIOD));
oldLogE = oldBandE + CC*st->mode->nbEBands;
oldLogE2 = oldLogE + CC*st->mode->nbEBands;
@@ -1266,7 +1275,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
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);
+ tf_select = tf_analysis(st->mode, effEnd, C, isTransient, tf_res, effectiveBytes, X, N, LM, st->start, &tf_sum);
for (i=effEnd;i<st->end;i++)
tf_res[i] = tf_res[effEnd-1];
@@ -1278,13 +1287,15 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
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 (shortBlocks || st->complexity < 3
+ || nbAvailableBytes < 10*C || st->start!=0)
{
if (st->complexity == 0)
st->spread_decision = SPREAD_NONE;
+ else
+ st->spread_decision = SPREAD_NORMAL;
} else {
st->spread_decision = spreading_decision(st->mode, X,
&st->tonal_average, st->spread_decision, &st->hf_average,
@@ -1588,7 +1599,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
if (CC==2)
out_mem[1] = st->syn_mem[1]+MAX_PERIOD;
- overlap_mem[0] = prefilter_mem+CC*COMBFILTER_MAXPERIOD;
+ overlap_mem[0] = (celt_sig*)(oldLogE2 + CC*st->mode->nbEBands);
if (CC==2)
overlap_mem[1] = overlap_mem[0] + st->overlap;
@@ -1843,7 +1854,7 @@ int opus_custom_encoder_ctl(CELTEncoder * OPUS_RESTRICT st, int request, ...)
{
int i;
opus_val16 *oldBandE, *oldLogE, *oldLogE2;
- oldBandE = (opus_val16*)(st->in_mem+st->channels*(2*st->overlap+COMBFILTER_MAXPERIOD));
+ oldBandE = (opus_val16*)(st->in_mem+st->channels*(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,
@@ -2028,7 +2039,6 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
{
int c;
int pitch_index;
- int overlap = st->mode->overlap;
opus_val16 fade = Q15ONE;
int i, len;
const int C = st->channels;
@@ -2039,8 +2049,17 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
opus_val16 *lpc;
opus_val32 *out_syn[2];
opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
+ const OpusCustomMode *mode;
+ int nbEBands;
+ int overlap;
+ const opus_int16 *eBands;
SAVE_STACK;
+ mode = st->mode;
+ nbEBands = mode->nbEBands;
+ overlap = mode->overlap;
+ eBands = mode->eBands;
+
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;
@@ -2048,15 +2067,15 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
} 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;
+ oldLogE = oldBandE + 2*nbEBands;
+ oldLogE2 = oldLogE + 2*nbEBands;
+ backgroundLogE = oldLogE2 + 2*nbEBands;
- out_syn[0] = out_mem[0]+MAX_PERIOD-N;
- if (C==2)
- out_syn[1] = out_mem[1]+MAX_PERIOD-N;
+ c=0; do {
+ out_syn[c] = out_mem[c]+MAX_PERIOD-N;
+ } while (++c<C);
- len = N+st->mode->overlap;
+ len = N+overlap;
if (st->loss_count >= 5 || st->start!=0)
{
@@ -2068,37 +2087,37 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
int effEnd;
effEnd = st->end;
- if (effEnd > st->mode->effEBands)
- effEnd = st->mode->effEBands;
+ if (effEnd > mode->effEBands)
+ effEnd = 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);
+ ALLOC(bandE, nbEBands*C, celt_ener);
if (st->loss_count >= 5)
- log2Amp(st->mode, st->start, st->end, bandE, backgroundLogE, C);
+ log2Amp(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;
+ oldBandE[c*nbEBands+i] -= decay;
} while (++c<C);
- log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
+ log2Amp(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++)
+ for (i=st->start;i<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;
+ boffs = N*c+(eBands[i]<<LM);
+ blen = (eBands[i+1]-eBands[i])<<LM;
for (j=0;j<blen;j++)
{
seed = celt_lcg_rand(seed);
@@ -2111,22 +2130,27 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
}
st->rng = seed;
- denormalise_bands(st->mode, X, freq, bandE, st->mode->effEBands, C, 1<<LM);
+ denormalise_bands(mode, X, freq, bandE, 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;
+ int bound = 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);
+ c=0; do {
+ OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap);
+ } while (++c<C);
+ compute_inv_mdcts(mode, 0, freq, out_syn, overlap_mem, C, LM);
} else {
/* Pitch-based PLC */
+ VARDECL(opus_val32, etmp);
+
if (st->loss_count == 0)
{
opus_val16 pitch_buf[DECODE_BUFFER_SIZE>>1];
@@ -2144,23 +2168,26 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
fade = QCONST16(.8f,15);
}
+ ALLOC(etmp, overlap, opus_val32);
c=0; do {
- VARDECL(opus_val32, e);
opus_val16 exc[MAX_PERIOD];
opus_val32 ac[LPC_ORDER+1];
- opus_val16 decay = 1;
+ opus_val16 decay;
+ opus_val16 attenuation;
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};
+ opus_val32 *e = out_syn[c];
- 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);
+ /* Compute LPC coefficients for the last MAX_PERIOD samples before the loss so we can
+ work in the excitation-filter domain */
if (st->loss_count == 0)
{
- _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
+ _celt_autocorr(exc, ac, mode->window, overlap,
LPC_ORDER, MAX_PERIOD);
/* Noise floor -40 dB */
@@ -2182,11 +2209,15 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
_celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
}
+ /* Samples just before the beginning of exc */
for (i=0;i<LPC_ORDER;i++)
- mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
+ mem[i] = ROUND16(out_mem[c][-1-i], SIG_SHIFT);
+ /* Compute the excitation for MAX_PERIOD samples before the loss */
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) */
+
+ /* Check if the waveform is decaying (and if so how fast)
+ We do this to avoid adding energy when concealing in a segment
+ with decaying energy */
{
opus_val32 E1=1, E2=1;
int period;
@@ -2202,30 +2233,43 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
if (E1 > E2)
E1 = E2;
decay = celt_sqrt(frac_div32(SHR32(E1,1),E2));
+ attenuation = decay;
}
- /* Copy excitation, taking decay into account */
- for (i=0;i<len+st->mode->overlap;i++)
+ /* Move memory one frame to the left */
+ OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap);
+
+ /* Extrapolate excitation with the right period, taking decay into account */
+ for (i=0;i<len;i++)
{
opus_val16 tmp;
if (offset+i >= MAX_PERIOD)
{
offset -= pitch_index;
- decay = MULT16_16_Q15(decay, decay);
+ attenuation = MULT16_16_Q15(attenuation, decay);
}
- e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
- tmp = ROUND16(out_mem[c][offset+i],SIG_SHIFT);
+ e[i] = SHL32(EXTEND32(MULT16_16_Q15(attenuation, exc[offset+i])), SIG_SHIFT);
+ /* Compute the energy of the previously decoded signal whose
+ excitation we're copying */
+ tmp = ROUND16(out_mem[c][-N+offset+i],SIG_SHIFT);
S1 += SHR32(MULT16_16(tmp,tmp),8);
}
+
+ /* Copy the last decoded samples (prior to the overlap region) to
+ synthesis filter memory so we can have a continuous signal. */
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++)
+ mem[i] = ROUND16(out_mem[c][MAX_PERIOD-N-1-i], SIG_SHIFT);
+ /* Apply the fading if not the first loss */
+ for (i=0;i<len;i++)
e[i] = MULT16_32_Q15(fade, e[i]);
- celt_iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
+ /* Synthesis filter -- back in the signal domain */
+ celt_iir(e, lpc+c*LPC_ORDER, e, len, LPC_ORDER, mem);
+ /* Check if the synthesis energy is higher than expected, which can
+ happen with the signal changes during our window. If so, attenuate. */
{
opus_val32 S2=0;
- for (i=0;i<len+overlap;i++)
+ for (i=0;i<len;i++)
{
opus_val16 tmp = ROUND16(e[i],SIG_SHIFT);
S2 += SHR32(MULT16_16(tmp,tmp),8);
@@ -2234,51 +2278,45 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
#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))
+ /* Float test is written this way to catch NaNs at the same time */
+ if (!(S1 > 0.2f*S2))
#endif
+ {
+ for (i=0;i<len;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<overlap;i++)
{
- 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]);
+ opus_val16 tmp_g = Q15ONE - MULT16_16_Q15(mode->window[i], Q15ONE-ratio);
+ e[i] = MULT16_32_Q15(tmp_g, e[i]);
}
+ for (i=overlap;i<len;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,
+ /* Apply pre-filter to the MDCT overlap for the next frame because the
+ post-filter will be re-applied in the decoder after the MDCT overlap */
+ comb_filter(etmp, 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 */
+ /* Simulate TDAC on the concealed audio so that it blends with the
+ MDCT of 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);
+ tmp = MULT16_32_Q15(mode->window[i], etmp[overlap-1-i]) +
+ MULT16_32_Q15(mode->window[overlap-i-1], etmp[i ]);
+ out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(mode->window[overlap-i-1], tmp);
+ out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(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);
+ deemphasis(out_syn, pcm, N, C, st->downsample, mode->preemph, st->preemph_memD);
st->loss_count++;
@@ -2387,6 +2425,13 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
if (effEnd > st->mode->effEBands)
effEnd = st->mode->effEBands;
+ if (data == NULL || len<=1)
+ {
+ celt_decode_lost(st, pcm, N, LM);
+ RESTORE_STACK;
+ return frame_size/st->downsample;
+ }
+
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);
@@ -2399,13 +2444,6 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
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);
@@ -2800,7 +2838,6 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
*value = st->postfilter_period;
}
break;
-#ifdef OPUS_BUILD
case CELT_GET_MODE_REQUEST:
{
const CELTMode ** value = va_arg(ap, const CELTMode**);
@@ -2823,7 +2860,6 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
*value=st->rng;
}
break;
-#endif
default:
goto bad_request;
}
diff --git a/celt/cwrs.c b/celt/cwrs.c
index ac81a7e..8edc919 100644
--- a/celt/cwrs.c
+++ b/celt/cwrs.c
@@ -337,7 +337,7 @@ static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){
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);
diff --git a/celt/ecintrin.h b/celt/ecintrin.h
index 3dffa5f..be57dd4 100644
--- a/celt/ecintrin.h
+++ b/celt/ecintrin.h
@@ -48,7 +48,7 @@
/*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)
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
# include <intrin.h>
/*In _DEBUG mode this is not an intrinsic by default.*/
# pragma intrinsic(_BitScanReverse)
diff --git a/celt/entcode.c b/celt/entcode.c
index 02ac690..fa5d7c7 100644
--- a/celt/entcode.c
+++ b/celt/entcode.c
@@ -33,6 +33,11 @@
#include "arch.h"
#if !defined(EC_CLZ)
+/*This is a fallback for systems where we don't know how to access
+ a BSR or CLZ instruction (see ecintrin.h).
+ If you are optimizing Opus on a new platform and it has a native CLZ or
+ BZR (e.g. cell, MIPS, x86, etc) then making it available to Opus will be
+ an easy performance win.*/
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
diff --git a/celt/pitch.c b/celt/pitch.c
index c2f08ec..ca0f523 100644
--- a/celt/pitch.c
+++ b/celt/pitch.c
@@ -77,7 +77,7 @@ static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len,
#ifndef FIXED_POINT
/* Considering the range of xcorr16, this should avoid both underflows
and overflows (inf) when squaring xcorr16 */
- xcorr16 *= 1e-12;
+ xcorr16 *= 1e-12f;
#endif
num = MULT16_16_Q15(xcorr16,xcorr16);
if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy))
diff --git a/celt/quant_bands.c b/celt/quant_bands.c
index b1d4eb1..66f1f5f 100644
--- a/celt/quant_bands.c
+++ b/celt/quant_bands.c
@@ -283,12 +283,15 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
/* Encode the global flags using a simple probability model
(first symbols in the stream) */
+ max_decay = QCONST16(16.f,DB_SHIFT);
+ if (end-start>10)
+ {
#ifdef FIXED_POINT
- max_decay = MIN32(QCONST16(16.f,DB_SHIFT), SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3));
+ max_decay = MIN32(max_decay, SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3));
#else
- max_decay = MIN32(16.f, .125f*nbAvailableBytes);
+ max_decay = MIN32(max_decay, .125f*nbAvailableBytes);
#endif
-
+ }
enc_start_state = *enc;
ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16);
diff --git a/celt/rate.c b/celt/rate.c
index 32fe9ac..4e96787 100644
--- a/celt/rate.c
+++ b/celt/rate.c
@@ -84,7 +84,7 @@ void compute_pulse_cache(CELTMode *m, int LM)
unsigned char *bits;
unsigned char *cap;
- cindex = opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2));
+ cindex = (opus_int16 *)opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2));
cache->index = cindex;
/* Scan for all unique band sizes */
@@ -124,7 +124,7 @@ void compute_pulse_cache(CELTMode *m, int LM)
}
}
}
- bits = opus_alloc(sizeof(unsigned char)*curr);
+ bits = (unsigned char *)opus_alloc(sizeof(unsigned char)*curr);
cache->bits = bits;
cache->size = curr;
/* Compute the cache for all unique sizes */
@@ -140,7 +140,7 @@ void compute_pulse_cache(CELTMode *m, int LM)
/* Compute the maximum rate for each band at which we'll reliably use as
many bits as we ask for. */
- cache->caps = cap = opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands);
+ 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++)
@@ -259,7 +259,7 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
int alloc_floor;
opus_int32 left, percoeff;
int done;
- int balance;
+ opus_int32 balance;
SAVE_STACK;
alloc_floor = C<<BITRES;
@@ -353,7 +353,7 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
#ifdef FUZZING
if ((rand()&0x1) == 0)
#else
- if (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
+ if (codedBands<=start+2 || band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
#endif
{
ec_enc_bit_logp(ec, 1, 1);
@@ -432,17 +432,17 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
int N0, N, den;
int offset;
int NClogN;
- int excess;
+ opus_int32 excess, bit;
celt_assert(bits[j] >= 0);
N0 = m->eBands[j+1]-m->eBands[j];
N=N0<<LM;
- bits[j] += balance;
+ bit = (opus_int32)bits[j]+balance;
if (N>1)
{
- excess = IMAX(bits[j]-cap[j],0);
- bits[j] -= excess;
+ 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));
@@ -483,8 +483,8 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
} else {
/* For N=1, all bits go to fine energy except for a single sign bit */
- excess = IMAX(0,bits[j]-(C<<BITRES));
- bits[j] -= excess;
+ excess = MAX32(0,bit-(C<<BITRES));
+ bits[j] = bit-excess;
ebits[j] = 0;
fine_priority[j] = 1;
}
diff --git a/celt/tests/test_unit_cwrs32.c b/celt/tests/test_unit_cwrs32.c
index 905714e..4695f2d 100644
--- a/celt/tests/test_unit_cwrs32.c
+++ b/celt/tests/test_unit_cwrs32.c
@@ -1,3 +1,31 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
+ Gregory Maxwell
+ Written by Jean-Marc Valin, Gregory Maxwell, and 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 "config.h"
#endif
diff --git a/celt/tests/test_unit_dft.c b/celt/tests/test_unit_dft.c
index 5ca38ed..7ff0be0 100644
--- a/celt/tests/test_unit_dft.c
+++ b/celt/tests/test_unit_dft.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 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.
+*/
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
diff --git a/celt/tests/test_unit_entropy.c b/celt/tests/test_unit_entropy.c
index 5cba4fe..bd83986 100644
--- a/celt/tests/test_unit_entropy.c
+++ b/celt/tests/test_unit_entropy.c
@@ -1,3 +1,31 @@
+/* Copyright (c) 2007-2011 Xiph.Org Foundation, Mozilla Corporation,
+ Gregory Maxwell
+ Written by Jean-Marc Valin, Gregory Maxwell, and 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 "config.h"
#endif
diff --git a/celt/tests/test_unit_laplace.c b/celt/tests/test_unit_laplace.c
index 5c80c19..b0f5935 100644
--- a/celt/tests/test_unit_laplace.c
+++ b/celt/tests/test_unit_laplace.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation
+ Written by Jean-Marc Valin and 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 "config.h"
#endif
diff --git a/celt/tests/test_unit_mathops.c b/celt/tests/test_unit_mathops.c
index ea0af49..c11f0ad 100644
--- a/celt/tests/test_unit_mathops.c
+++ b/celt/tests/test_unit_mathops.c
@@ -1,3 +1,31 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
+ Gregory Maxwell
+ Written by Jean-Marc Valin, Gregory Maxwell, and 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 "config.h"
#endif
diff --git a/celt/tests/test_unit_mdct.c b/celt/tests/test_unit_mdct.c
index 0de3d54..f8fb9ac 100644
--- a/celt/tests/test_unit_mdct.c
+++ b/celt/tests/test_unit_mdct.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2008-2011 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 "config.h"
#endif
diff --git a/celt/tests/test_unit_rotation.c b/celt/tests/test_unit_rotation.c
index 29082b6..ce5f096 100644
--- a/celt/tests/test_unit_rotation.c
+++ b/celt/tests/test_unit_rotation.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2008-2011 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 "config.h"
#endif
diff --git a/celt/tests/test_unit_types.c b/celt/tests/test_unit_types.c
index 1c3357e..67a0fb8 100644
--- a/celt/tests/test_unit_types.c
+++ b/celt/tests/test_unit_types.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2008-2011 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 "config.h"
#endif
diff --git a/celt_headers.mk b/celt_headers.mk
new file mode 100644
index 0000000..f89d66a
--- /dev/null
+++ b/celt_headers.mk
@@ -0,0 +1,31 @@
+CELT_HEAD = \
+celt/arch.h \
+celt/bands.h \
+celt/celt.h \
+include/opus_types.h \
+include/opus_defines.h \
+include/opus_custom.h \
+celt/cwrs.h \
+celt/ecintrin.h \
+celt/entcode.h \
+celt/entdec.h \
+celt/entenc.h \
+celt/fixed_debug.h \
+celt/fixed_generic.h \
+celt/float_cast.h \
+celt/_kiss_fft_guts.h \
+celt/kiss_fft.h \
+celt/laplace.h \
+celt/mathops.h \
+celt/mdct.h \
+celt/mfrngcod.h \
+celt/modes.h \
+celt/os_support.h \
+celt/pitch.h \
+celt/celt_lpc.h \
+celt/quant_bands.h \
+celt/rate.h \
+celt/stack_alloc.h \
+celt/vq.h \
+celt/static_modes_float.h \
+celt/static_modes_fixed.h
diff --git a/celt_sources.mk b/celt_sources.mk
new file mode 100644
index 0000000..6f0a90e
--- /dev/null
+++ b/celt_sources.mk
@@ -0,0 +1,16 @@
+CELT_SOURCES = celt/bands.c \
+celt/celt.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/celt_lpc.c \
+celt/quant_bands.c \
+celt/rate.c \
+celt/vq.c
diff --git a/compile b/compile
index b1f4749..862a14e 100755
--- a/compile
+++ b/compile
@@ -1,7 +1,7 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
-scriptversion=2012-01-04.17; # UTC
+scriptversion=2012-03-05.13; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free
# Software Foundation, Inc.
@@ -79,6 +79,48 @@ func_file_conv ()
esac
}
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
@@ -109,43 +151,34 @@ func_cl_wrapper ()
;;
esac
;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
-l*)
- lib=${1#-l}
- found=no
- save_IFS=$IFS
- IFS=';'
- for dir in $lib_path $LIB
- do
- IFS=$save_IFS
- if $shared && test -f "$dir/$lib.dll.lib"; then
- found=yes
- set x "$@" "$dir/$lib.dll.lib"
- break
- fi
- if test -f "$dir/$lib.lib"; then
- found=yes
- set x "$@" "$dir/$lib.lib"
- break
- fi
- done
- IFS=$save_IFS
-
- test "$found" != yes && set x "$@" "$lib.lib"
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
shift
;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
-L*)
- func_file_conv "${1#-L}"
- if test -z "$lib_path"; then
- lib_path=$file
- else
- lib_path="$lib_path;$file"
- fi
- linker_opts="$linker_opts -LIBPATH:$file"
+ func_cl_dashL "${1#-L}"
;;
-static)
shared=false
diff --git a/config.guess b/config.guess
index 49ba16f..d622a44 100755
--- a/config.guess
+++ b/config.guess
@@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
-timestamp='2012-01-01'
+timestamp='2012-02-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -17,9 +17,7 @@ timestamp='2012-01-01'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -863,6 +861,13 @@ EOF
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
@@ -1320,6 +1325,9 @@ EOF
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
diff --git a/config.h.in b/config.h.in
index bf3b61a..a5e9503 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,8 +1,5 @@
/* config.h.in. Generated from configure.ac by autoheader. */
-/* Define if building universal (internal helper macro) */
-#undef AC_APPLE_UNIVERSAL_BUILD
-
/* Custom modes */
#undef CUSTOM_MODES
@@ -15,9 +12,6 @@
/* Compile as fixed-point (for machines without a fast enough FPU) */
#undef FIXED_POINT
-/* Compile as floating-point (for machines with a fast enough FPU) */
-#undef FLOATING_POINT
-
/* Float approximations */
#undef FLOAT_APPROX
@@ -121,18 +115,6 @@
/* Use C99 variable-size arrays */
#undef VAR_ARRAYS
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
- significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-# define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-# undef WORDS_BIGENDIAN
-# endif
-#endif
-
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
diff --git a/config.sub b/config.sub
index d6b6b3c..c894da4 100755
--- a/config.sub
+++ b/config.sub
@@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
-timestamp='2012-01-01'
+timestamp='2012-02-10'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -21,9 +21,7 @@ timestamp='2012-01-01'
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -132,6 +130,10 @@ case $maybe_os in
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -247,6 +249,7 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
+ | aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
@@ -319,7 +322,7 @@ case $basic_machine in
c6x)
basic_machine=tic6x-unknown
;;
- m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -332,7 +335,10 @@ case $basic_machine in
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
-
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
xscaleeb)
basic_machine=armeb-unknown
;;
@@ -355,6 +361,7 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
+ | aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
diff --git a/configure b/configure
index bcb9c7a..00405ba 100755
--- a/configure
+++ b/configure
@@ -613,6 +613,8 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
+PC_LIBM
+PC_BUILD
CUSTOM_MODES_FALSE
CUSTOM_MODES_TRUE
FIXED_POINT_FALSE
@@ -1393,7 +1395,7 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-silent-rules less verbose build output (undo: `make V=1')
--disable-silent-rules verbose build output (undo: `make V=0')
- --enable-maintainer-mode enable make rules and dependencies not useful
+ --disable-maintainer-mode disable make rules and dependencies not useful
(and sometimes confusing) to the casual installer
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=yes]
@@ -2484,9 +2486,9 @@ _ACEOF
# For libtool.
-OPUS_LT_CURRENT=2
+OPUS_LT_CURRENT=3
OPUS_LT_REVISION=0
-OPUS_LT_AGE=2
+OPUS_LT_AGE=3
@@ -2997,7 +2999,7 @@ $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles
if test "${enable_maintainer_mode+set}" = set; then :
enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
else
- USE_MAINTAINER_MODE=no
+ USE_MAINTAINER_MODE=yes
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
@@ -11887,230 +11889,6 @@ if test "x$ac_cv_prog_cc_c99" != xno; then :
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
-$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
-if ${ac_cv_c_bigendian+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_c_bigendian=unknown
- # See if we're dealing with a universal compiler.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifndef __APPLE_CC__
- not a universal capable compiler
- #endif
- typedef int dummy;
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
- # Check for potential -arch flags. It is not universal unless
- # there are at least two -arch flags with different values.
- ac_arch=
- ac_prev=
- for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
- if test -n "$ac_prev"; then
- case $ac_word in
- i?86 | x86_64 | ppc | ppc64)
- if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
- ac_arch=$ac_word
- else
- ac_cv_c_bigendian=universal
- break
- fi
- ;;
- esac
- ac_prev=
- elif test "x$ac_word" = "x-arch"; then
- ac_prev=arch
- fi
- done
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- if test $ac_cv_c_bigendian = unknown; then
- # See if sys/param.h defines the BYTE_ORDER macro.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- #include <sys/param.h>
-
-int
-main ()
-{
-#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
- && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
- && LITTLE_ENDIAN)
- bogus endian macros
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- # It does; now see whether it defined to BIG_ENDIAN or not.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- #include <sys/param.h>
-
-int
-main ()
-{
-#if BYTE_ORDER != BIG_ENDIAN
- not big endian
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_c_bigendian=yes
-else
- ac_cv_c_bigendian=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- if test $ac_cv_c_bigendian = unknown; then
- # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <limits.h>
-
-int
-main ()
-{
-#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
- bogus endian macros
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- # It does; now see whether it defined to _BIG_ENDIAN or not.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <limits.h>
-
-int
-main ()
-{
-#ifndef _BIG_ENDIAN
- not big endian
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_c_bigendian=yes
-else
- ac_cv_c_bigendian=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- if test $ac_cv_c_bigendian = unknown; then
- # Compile a test program.
- if test "$cross_compiling" = yes; then :
- # Try to guess by grepping values from an object file.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-short int ascii_mm[] =
- { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
- short int ascii_ii[] =
- { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
- int use_ascii (int i) {
- return ascii_mm[i] + ascii_ii[i];
- }
- short int ebcdic_ii[] =
- { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
- short int ebcdic_mm[] =
- { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
- int use_ebcdic (int i) {
- return ebcdic_mm[i] + ebcdic_ii[i];
- }
- extern int foo;
-
-int
-main ()
-{
-return use_ascii (foo) == use_ebcdic (foo);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
- ac_cv_c_bigendian=yes
- fi
- if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
- if test "$ac_cv_c_bigendian" = unknown; then
- ac_cv_c_bigendian=no
- else
- # finding both strings is unlikely to happen, but who knows?
- ac_cv_c_bigendian=unknown
- fi
- fi
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-
- /* Are we little or big endian? From Harbison&Steele. */
- union
- {
- long int l;
- char c[sizeof (long int)];
- } u;
- u.l = 1;
- return u.c[sizeof (long int) - 1] == 1;
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- ac_cv_c_bigendian=no
-else
- ac_cv_c_bigendian=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
-$as_echo "$ac_cv_c_bigendian" >&6; }
- case $ac_cv_c_bigendian in #(
- yes)
- $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
-;; #(
- no)
- ;; #(
- universal)
-
-$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
-
- ;; #(
- *)
- as_fn_error $? "unknown endianness
- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
- esac
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
if ${ac_cv_c_const+:} false; then :
@@ -12428,15 +12206,7 @@ if test "${enable_fixed_point+set}" = set; then :
$as_echo "#define FIXED_POINT 1" >>confdefs.h
-else
-
-$as_echo "#define FLOATING_POINT /**/" >>confdefs.h
-
fi
-else
-
-$as_echo "#define FLOATING_POINT /**/" >>confdefs.h
-
fi
@@ -12820,8 +12590,24 @@ else
fi
+if test x$ac_enable_float = xyes; then
+ PC_BUILD="floating-point"
+ PC_LIBM=$LIBM
+else
+ PC_BUILD="fixed-point"
+ PC_LIBM=
+fi
+if test x$ac_enable_custom_modes = xyes; then
+ PC_BUILD="${PC_BUILD}, custom modes"
+ PC_LIBM=$LIBM
+fi
+
+
+
+
ac_config_files="$ac_config_files Makefile opus.pc opus-uninstalled.pc doc/Makefile doc/Doxyfile"
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@@ -12951,7 +12737,6 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
-
if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then
as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/configure.ac b/configure.ac
index 0773c37..6394e2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,16 +53,16 @@ AC_DEFINE_UNQUOTED([OPUS_VERSION], ["$OPUS_VERSION"],
# For libtool.
dnl Please update these for releases.
-OPUS_LT_CURRENT=2
+OPUS_LT_CURRENT=3
OPUS_LT_REVISION=0
-OPUS_LT_AGE=2
+OPUS_LT_AGE=3
AC_SUBST(OPUS_LT_CURRENT)
AC_SUBST(OPUS_LT_REVISION)
AC_SUBST(OPUS_LT_AGE)
AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
-AM_MAINTAINER_MODE
+AM_MAINTAINER_MODE([enable])
AC_CANONICAL_HOST
AC_MINGW32
@@ -70,7 +70,6 @@ AM_PROG_LIBTOOL
AM_PROG_CC_C_O
AC_PROG_CC_C99
-AC_C_BIGENDIAN
AC_C_CONST
AC_C_INLINE
@@ -159,10 +158,7 @@ AC_ARG_ENABLE(fixed-point, [ --enable-fixed-point compile without floatin
ac_enable_fixed="yes";
ac_enable_float="no";
AC_DEFINE([FIXED_POINT], [1], [Compile as fixed-point (for machines without a fast enough FPU)])
-else
- AC_DEFINE([FLOATING_POINT], , [Compile as floating-point (for machines with a fast enough FPU)])
-fi],
-AC_DEFINE([FLOATING_POINT], , [Compile as floating-point (for machines with a fast enough FPU)]))
+fi])
ac_enable_fixed_debug="no"
AC_ARG_ENABLE(fixed-point-debug, [ --enable-fixed-point-debug debug fixed-point implementation],
@@ -278,8 +274,27 @@ AC_SUBST(SIZE32)
AM_CONDITIONAL([FIXED_POINT], [test x$ac_enable_fixed = xyes])
AM_CONDITIONAL([CUSTOM_MODES], [test x$ac_enable_custom_modes = xyes])
-AC_OUTPUT([Makefile opus.pc opus-uninstalled.pc
- doc/Makefile doc/Doxyfile])
+dnl subsitutions for the pkg-config files
+if test x$ac_enable_float = xyes; then
+ PC_BUILD="floating-point"
+ PC_LIBM=$LIBM
+else
+ PC_BUILD="fixed-point"
+ PC_LIBM=
+fi
+dnl opus_custom requires libm as well
+if test x$ac_enable_custom_modes = xyes; then
+ PC_BUILD="${PC_BUILD}, custom modes"
+ PC_LIBM=$LIBM
+fi
+AC_SUBST([PC_BUILD])
+AC_SUBST([PC_LIBM])
+
+
+AC_CONFIG_FILES([Makefile opus.pc opus-uninstalled.pc
+ doc/Makefile doc/Doxyfile])
+
+AC_OUTPUT
AC_MSG_RESULT([
------------------------------------------------------------------------
diff --git a/depcomp b/depcomp
index bd0ac08..25a39e6 100755
--- a/depcomp
+++ b/depcomp
@@ -1,10 +1,10 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
-scriptversion=2011-12-04.11; # UTC
+scriptversion=2012-03-27.16; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
-# 2011 Free Software Foundation, Inc.
+# 2011, 2012 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@ scriptversion=2011-12-04.11; # UTC
case $1 in
'')
- echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
@@ -40,8 +40,8 @@ as side-effects.
Environment variables:
depmode Dependency tracking mode.
- source Source file read by `PROGRAMS ARGS'.
- object Object file output by `PROGRAMS ARGS'.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
@@ -57,6 +57,12 @@ EOF
;;
esac
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
@@ -102,6 +108,12 @@ if test "$depmode" = msvc7msys; then
depmode=msvc7
fi
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
+fi
+
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
@@ -156,15 +168,14 @@ gcc)
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
-## This next piece of magic avoids the `deleted header file' problem.
+## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
- tr ' ' '
-' < "$tmpdepfile" |
-## Some versions of gcc put a space before the `:'. On the theory
+ tr ' ' "$nl" < "$tmpdepfile" |
+## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
@@ -203,18 +214,15 @@ sgi)
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
- # the IRIX cc adds comments like `#:fec' to the end of the
+ # the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
- tr ' ' '
-' < "$tmpdepfile" \
+ tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
- tr '
-' ' ' >> "$depfile"
+ tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
- tr ' ' '
-' < "$tmpdepfile" \
+ tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
@@ -226,10 +234,17 @@ sgi)
rm -f "$tmpdepfile"
;;
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
- # current directory. Also, the AIX compiler puts `$object:' at the
+ # current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
@@ -259,12 +274,11 @@ aix)
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
- # Each line is of the form `foo.o: dependent.h'.
+ # Each line is of the form 'foo.o: dependent.h'.
# Do two passes, one to just change these to
- # `$object: dependent.h' and one to simply `dependent.h:'.
+ # '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
@@ -275,23 +289,26 @@ aix)
;;
icc)
- # Intel's C compiler understands `-MD -MF file'. However on
- # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
+ # However on
+ # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
- # which is wrong. We want:
+ # which is wrong. We want
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
- # and will wrap long lines using \ :
+ # and will wrap long lines using '\':
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
-
+ # tcc 0.9.26 (FIXME still under development at the moment of writing)
+ # will emit a similar output, but also prepend the continuation lines
+ # with horizontal tabulation characters.
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
@@ -300,15 +317,21 @@ icc)
exit $stat
fi
rm -f "$depfile"
- # Each line is of the form `foo.o: dependent.h',
- # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Each line is of the form 'foo.o: dependent.h',
+ # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
# Do two passes, one to just change these to
- # `$object: dependent.h' and one to simply `dependent.h:'.
- sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
- # Some versions of the HPUX 10.20 sed can't process this invocation
- # correctly. Breaking it into two sed invocations is a workaround.
- sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
- sed -e 's/$/ :/' >> "$depfile"
+ # '$object: dependent.h' and one to simply 'dependent.h:'.
+ sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
+ < "$tmpdepfile" > "$depfile"
+ sed '
+ s/[ '"$tab"'][ '"$tab"']*/ /g
+ s/^ *//
+ s/ *\\*$//
+ s/^[^:]*: *//
+ /^$/d
+ /:$/d
+ s/$/ :/
+ ' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -344,7 +367,7 @@ hp2)
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
- # Add `dependent.h:' lines.
+ # Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
@@ -359,9 +382,9 @@ hp2)
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
- # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
- # dependencies in `foo.d' instead, so we check for that too.
+ # dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
@@ -407,8 +430,7 @@ tru64)
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
@@ -443,11 +465,11 @@ msvc7)
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
-s/\(.*\)/ \1 \\/p
+s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
- s/.*/ /
+ s/.*/'"$tab"'/
G
p
}' >> "$depfile"
@@ -478,7 +500,7 @@ dashmstdout)
shift
fi
- # Remove `-o $object'.
+ # Remove '-o $object'.
IFS=" "
for arg
do
@@ -498,15 +520,14 @@ dashmstdout)
done
test -z "$dashmflag" && dashmflag=-M
- # Require at least two characters before searching for `:'
+ # Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
- # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
- sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
- tr ' ' '
-' < "$tmpdepfile" | \
+ tr ' ' "$nl" < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
@@ -562,8 +583,7 @@ makedepend)
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
- sed '1,2d' "$tmpdepfile" | tr ' ' '
-' | \
+ sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
@@ -583,7 +603,7 @@ cpp)
shift
fi
- # Remove `-o $object'.
+ # Remove '-o $object'.
IFS=" "
for arg
do
@@ -652,8 +672,8 @@ msvisualcpp)
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
- sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
- echo " " >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index 328a06e..7f5f7dc 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -835,7 +835,7 @@ HTML_FILE_EXTENSION = .html
# standard header. Note that when using a custom header you are responsible
# for the proper inclusion of any scripts and style sheets that doxygen
# needs, which is dependent on the configuration options used.
-# It is adviced to generate a default header using "doxygen -w html
+# It is advised to generate a default header using "doxygen -w html
# header.html footer.html stylesheet.css YourConfigFile" and then modify
# that header. Note that the header is subject to change so you typically
# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW!
diff --git a/doc/Makefile.am b/doc/Makefile.am
index ba6f64c..cf5908a 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -22,7 +22,8 @@ doxygen-build.stamp: Doxyfile $(DOCINPUTS)
install-data-local:
for f in `find html -type f \! -name "installdox"`; do \
- $(INSTALL_DATA) -D $$f $(DESTDIR)$(docdir)/$$f; \
+ $(INSTALL) -d $(DESTDIR)$(docdir)/html/search; \
+ $(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$f; \
done
$(INSTALL) -d $(DESTDIR)$(mandir)/man3
diff --git a/doc/Makefile.in b/doc/Makefile.in
index a40d72c..1eb4436 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -15,6 +15,23 @@
@SET_MAKE@
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -52,6 +69,11 @@ am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
SOURCES =
DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -116,6 +138,8 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
+PC_BUILD = @PC_BUILD@
+PC_LIBM = @PC_LIBM@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
@@ -393,7 +417,8 @@ uninstall-am: uninstall-local
@HAVE_DOXYGEN_TRUE@install-data-local:
@HAVE_DOXYGEN_TRUE@ for f in `find html -type f \! -name "installdox"`; do \
-@HAVE_DOXYGEN_TRUE@ $(INSTALL_DATA) -D $$f $(DESTDIR)$(docdir)/$$f; \
+@HAVE_DOXYGEN_TRUE@ $(INSTALL) -d $(DESTDIR)$(docdir)/html/search; \
+@HAVE_DOXYGEN_TRUE@ $(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$f; \
@HAVE_DOXYGEN_TRUE@ done
@HAVE_DOXYGEN_TRUE@ $(INSTALL) -d $(DESTDIR)$(mandir)/man3
diff --git a/include/opus.h b/include/opus.h
index a1f0156..847a07c 100644
--- a/include/opus.h
+++ b/include/opus.h
@@ -67,6 +67,7 @@ extern "C" {
* @li @ref opus_encoder
* @li @ref opus_decoder
* @li @ref opus_repacketizer
+ * @li @ref opus_multistream
* @li @ref opus_libinfo
* @li @ref opus_custom
*/
@@ -135,10 +136,11 @@ extern "C" {
* <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>
+ * <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended).
+ * Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.</li>
* </ul>
*
- * opus_encode() and opus_encode_frame() return the number of bytes actually written to the packet.
+ * opus_encode() and opus_encode_float() 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).
*
@@ -161,6 +163,11 @@ extern "C" {
*/
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);
/**
@@ -188,11 +195,13 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels);
*
* 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)
- * @param [in] channels <tt>int</tt>: Number of channels (1/2) in input signal
+ * 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 audio bandwidth or number of channels if the bitrate
+ * 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.
*/
@@ -204,15 +213,17 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create(
);
/** Initializes a previously allocated encoder state
- * The memory pointed to by st must be the size returned by opus_encoder_get_size.
+ * 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.
+ * 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)
- * @param [in] channels <tt>int</tt>: Number of channels (1/2) in input signal
+ * 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
+ * @retval #OPUS_OK Success or @ref opus_errorcodes
*/
OPUS_EXPORT int opus_encoder_init(
OpusEncoder *st,
@@ -222,16 +233,32 @@ OPUS_EXPORT int opus_encoder_init(
) OPUS_ARG_NONNULL(1);
/** Encodes an Opus frame.
- * The passed frame_size must an opus frame size for the encoder's sampling rate.
- * For example, at 48kHz the permitted values are 120, 240, 480, 960, 1920, and 2880.
- * Passing in a duration of less than 10ms (480 samples at 48kHz) will
- * prevent the encoder from using the LPC or hybrid modes.
* @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 frame of input signal
- * @param [out] data <tt>char*</tt>: Output payload (at least max_data_bytes long)
- * @param [in] max_data_bytes <tt>opus_int32</tt>: Allocated memory for payload; don't use for controlling bitrate
- * @returns length of the data payload (in bytes) or @ref opus_errorcodes
+ * @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 instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @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,
@@ -242,10 +269,6 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode(
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes an Opus frame from floating point input.
- * The passed frame_size must an opus frame size for the encoder's sampling rate.
- * For example, at 48kHz the permitted values are 120, 240, 480, 960, 1920, and 2880.
- * Passing in a duration of less than 10ms (480 samples at 48kHz) will
- * prevent the encoder from using the LPC or hybrid modes.
* @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
@@ -253,10 +276,30 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode(
* 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 frame of input signal
- * @param [out] data <tt>char*</tt>: Output payload (at least max_data_bytes long)
- * @param [in] max_data_bytes <tt>opus_int32</tt>: Allocated memory for payload; don't use for controlling bitrate
- * @returns length of the data payload (in bytes) or @ref opus_errorcodes
+ * @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 instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @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,
@@ -266,7 +309,7 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float(
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
-/** Frees an OpusEncoder allocated by opus_encoder_create.
+/** 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);
@@ -275,6 +318,11 @@ OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st);
*
* 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);
@@ -295,7 +343,7 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NON
* 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 error will hold the error code in case of 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
@@ -326,7 +374,7 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NON
* @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
+ * If that value is negative, then an error has occurred. 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
@@ -350,16 +398,19 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NON
*/
typedef struct OpusDecoder OpusDecoder;
-/** Gets the size of an OpusDecoder structure.
- * @param [in] channels <tt>int</tt>: Number of channels
- * @returns size
+/** 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)
- * @param [in] channels <tt>int</tt>: Number of channels (1/2) to decode
- * @param [out] error <tt>int*</tt>: OPUS_OK Success or @ref opus_errorcodes
+ * @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
@@ -376,13 +427,15 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create(
);
/** Initializes a previously allocated decoder state.
- * The state must be the size returned by opus_decoder_get_size.
+ * 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.
+ * 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)
- * @param [in] channels <tt>int</tt>: Number of channels (1/2) to decode
- * @retval OPUS_OK Success or @ref opus_errorcodes
+ * @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,
@@ -390,16 +443,20 @@ OPUS_EXPORT int opus_decoder_init(
int channels
) OPUS_ARG_NONNULL(1);
-/** Decode an Opus frame
+/** 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 *pcm,
- * if less than the maximum frame size (120ms) some frames can not be decoded
- * @param [in] decode_fec <tt>int</tt>: Flag (0/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.
+ * @param [in] frame_size Number of samples per channel of available space in \a pcm.
+ * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
+ * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
+ * then frame_size needs to be exactly the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
+ * FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
+ * @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(
@@ -411,15 +468,19 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode(
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
-/** Decode an opus frame with floating point output
+/** 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/1) to request that any in-band forward error correction data be
+ * @param [in] frame_size Number of samples per channel of available space in \a pcm.
+ * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
+ * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
+ * then frame_size needs to be exactly the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
+ * FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
+ * @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
*/
@@ -436,11 +497,16 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float(
*
* 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 OpusDecoder allocated by opus_decoder_create.
+/** 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);
@@ -479,10 +545,13 @@ OPUS_EXPORT int opus_packet_parse(
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
- * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz
- * @returns Number of samples per frame
- * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ * @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);
@@ -502,6 +571,17 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsign
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] packet <tt>char*</tt>: Opus packet
+ * @param [in] len <tt>opus_int32</tt>: Length of packet
+ * @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
+ * @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_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) 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
@@ -514,27 +594,304 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDe
/** @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.
+ * 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);
/**@}*/
diff --git a/include/opus_defines.h b/include/opus_defines.h
index 82a5f06..cdde061 100644
--- a/include/opus_defines.h
+++ b/include/opus_defines.h
@@ -63,20 +63,18 @@ extern "C" {
/** @cond OPUS_INTERNAL_DOC */
/**Export control for opus functions */
-#if !defined(OPUS_EXPORT)
-
-#if defined(__GNUC__) && defined(OPUS_BUILD)
-# define OPUS_EXPORT __attribute__ ((visibility ("default")))
-#elif defined(WIN32) && !defined(__MINGW32__)
-# ifdef OPUS_BUILD
+#ifndef OPUS_EXPORT
+# 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
+# else
# define OPUS_EXPORT
+# endif
+# else
+# define OPUS_EXPORT
# endif
-#else
-# define OPUS_EXPORT
-#endif
-
#endif
# if !defined(OPUS_GNUC_PREREQ)
@@ -147,10 +145,14 @@ extern "C" {
#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_GET_GAIN_REQUEST 4045 /* Should have been 4035 */
#define OPUS_SET_LSB_DEPTH_REQUEST 4036
#define OPUS_GET_LSB_DEPTH_REQUEST 4037
+#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039
+
+/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
+
/* 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)))
@@ -505,6 +507,24 @@ extern "C" {
* </dl>
* @hideinitializer */
#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x)
+/** Configures the depth of signal being encoded.
+ * This is a hint which helps the encoder identify silence and near-silence.
+ * @see OPUS_GET_LSB_DEPTH
+ * @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24
+ * (default: 24).
+ * @hideinitializer */
+#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured signal depth.
+ * @see OPUS_SET_LSB_DEPTH
+ * @param[out] x <tt>opus_int32 *</tt>: Input precision in bits, between 8 and
+ * 24 (default: 24).
+ * @hideinitializer */
+#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the duration (in samples) of the last packet successfully decoded or concealed.
+ * @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate).
+ * @hideinitializer */
+#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x)
/**@}*/
/** @defgroup opus_genericctls Generic CTLs
@@ -584,19 +604,6 @@ extern "C" {
* @hideinitializer */
#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
-/** Configures the depth of signal being encoded.
- * This is a hint which helps the encoder identify silence and near-silence.
- * @see OPUS_GET_LSB_DEPTH
- * @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24
- * (default: 24).
- * @hideinitializer */
-#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x)
-/** Gets the encoder's configured signal depth.
- * @see OPUS_SET_LSB_DEPTH
- * @param[out] x <tt>opus_int32 *</tt>: Input precision in bits, between 8 and
- * 24 (default: 24).
- * @hideinitializer */
-#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x)
/**@}*/
/** @defgroup opus_decoderctls Decoder related CTLs
diff --git a/include/opus_multistream.h b/include/opus_multistream.h
index 5e5364a..658067f 100644
--- a/include/opus_multistream.h
+++ b/include/opus_multistream.h
@@ -39,132 +39,592 @@
extern "C" {
#endif
-typedef struct OpusMSEncoder OpusMSEncoder;
-typedef struct OpusMSDecoder OpusMSDecoder;
+/** @cond OPUS_INTERNAL_DOC */
+/** Macros to trigger compilation errors when the wrong types are provided to a
+ * CTL. */
+/**@{*/
#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr)))
#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr)))
+/**@}*/
+/** These are the actual encoder and decoder CTL ID numbers.
+ * They should not be used directly by applications.
+ * In general, SETs should be even and GETs should be odd.*/
+/**@{*/
#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120
#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122
+/**@}*/
+
+/** @endcond */
+/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs
+ *
+ * These are convenience macros that are specific to the
+ * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl()
+ * interface.
+ * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and
+ * @ref opus_decoderctls may be applied to a multistream encoder or decoder as
+ * well.
+ * In addition, you may retrieve the encoder or decoder state for an specific
+ * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or
+ * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually.
+ */
+/**@{*/
+
+/** Gets the encoder state for an individual stream of a multistream encoder.
+ * @param[in] x <tt>opus_int32</tt>: The index of the stream whose encoder you
+ * wish to retrieve.
+ * This must be non-negative and less than
+ * the <code>streams</code> parameter used
+ * to initialize the encoder.
+ * @param[out] y <tt>OpusEncoder**</tt>: Returns a pointer to the given
+ * encoder state.
+ * @retval OPUS_BAD_ARG The index of the requested stream was out of range.
+ * @hideinitializer
+ */
#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y)
+
+/** Gets the decoder state for an individual stream of a multistream decoder.
+ * @param[in] x <tt>opus_int32</tt>: The index of the stream whose decoder you
+ * wish to retrieve.
+ * This must be non-negative and less than
+ * the <code>streams</code> parameter used
+ * to initialize the decoder.
+ * @param[out] y <tt>OpusDecoder**</tt>: Returns a pointer to the given
+ * decoder state.
+ * @retval OPUS_BAD_ARG The index of the requested stream was out of range.
+ * @hideinitializer
+ */
#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y)
-/** Allocate and initialize a multistream encoder state object.
- * Call opus_multistream_encoder_destroy() to release
- * this object when finished. */
+/**@}*/
+
+/** @defgroup opus_multistream Opus Multistream API
+ * @{
+ *
+ * The multistream API allows individual Opus streams to be combined into a
+ * single packet, enabling support for up to 255 channels. Unlike an
+ * elementary Opus stream, the encoder and decoder must negotiate the channel
+ * configuration before the decoder can successfully interpret the data in the
+ * packets produced by the encoder. Some basic information, such as packet
+ * duration, can be computed without any special negotiation.
+ *
+ * The format for multistream Opus packets is defined in the
+ * <a href="http://tools.ietf.org/html/draft-terriberry-oggopus">Ogg
+ * encapsulation specification</a> and is based on the self-delimited Opus
+ * framing described in Appendix B of <a href="http://tools.ietf.org/html/rfc6716">RFC 6716</a>.
+ * Normal Opus packets are just a degenerate case of multistream Opus packets,
+ * and can be encoded or decoded with the multistream API by setting
+ * <code>streams</code> to <code>1</code> when initializing the encoder or
+ * decoder.
+ *
+ * Multistream Opus streams can contain up to 255 elementary Opus streams.
+ * These may be either "uncoupled" or "coupled", indicating that the decoder
+ * is configured to decode them to either 1 or 2 channels, respectively.
+ * The streams are ordered so that all coupled streams appear at the
+ * beginning.
+ *
+ * A <code>mapping</code> table defines which decoded channel <code>i</code>
+ * should be used for each input/output (I/O) channel <code>j</code>. This table is
+ * typically provided as an unsigned char array.
+ * Let <code>i = mapping[j]</code> be the index for I/O channel <code>j</code>.
+ * If <code>i < 2*coupled_streams</code>, then I/O channel <code>j</code> is
+ * encoded as the left channel of stream <code>(i/2)</code> if <code>i</code>
+ * is even, or as the right channel of stream <code>(i/2)</code> if
+ * <code>i</code> is odd. Otherwise, I/O channel <code>j</code> is encoded as
+ * mono in stream <code>(i - coupled_streams)</code>, unless it has the special
+ * value 255, in which case it is omitted from the encoding entirely (the
+ * decoder will reproduce it as silence). Each value <code>i</code> must either
+ * be the special value 255 or be less than <code>streams + coupled_streams</code>.
+ *
+ * The output channels specified by the encoder
+ * should use the
+ * <a href="http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9">Vorbis
+ * channel ordering</a>. A decoder may wish to apply an additional permutation
+ * to the mapping the encoder used to achieve a different output channel
+ * order (e.g. for outputing in WAV order).
+ *
+ * Each multistream packet contains an Opus packet for each stream, and all of
+ * the Opus packets in a single multistream packet must have the same
+ * duration. Therefore the duration of a multistream packet can be extracted
+ * from the TOC sequence of the first stream, which is located at the
+ * beginning of the packet, just like an elementary Opus stream:
+ *
+ * @code
+ * int nb_samples;
+ * int nb_frames;
+ * nb_frames = opus_packet_get_nb_frames(data, len);
+ * if (nb_frames < 1)
+ * return nb_frames;
+ * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames;
+ * @endcode
+ *
+ * The general encoding and decoding process proceeds exactly the same as in
+ * the normal @ref opus_encoder and @ref opus_decoder APIs.
+ * See their documentation for an overview of how to use the corresponding
+ * multistream functions.
+ */
+
+/** Opus multistream encoder state.
+ * This contains the complete state of a multistream Opus encoder.
+ * It is position independent and can be freely copied.
+ * @see opus_multistream_encoder_create
+ * @see opus_multistream_encoder_init
+ */
+typedef struct OpusMSEncoder OpusMSEncoder;
+
+/** Opus multistream decoder state.
+ * This contains the complete state of a multistream Opus decoder.
+ * It is position independent and can be freely copied.
+ * @see opus_multistream_decoder_create
+ * @see opus_multistream_decoder_init
+ */
+typedef struct OpusMSDecoder OpusMSDecoder;
+
+/**\name Multistream encoder functions */
+/**@{*/
+
+/** Gets the size of an OpusMSEncoder structure.
+ * @param streams <tt>int</tt>: The total number of streams to encode from the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+ * to encode.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * encoded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @returns The size in bytes on success, or a negative error code
+ * (see @ref opus_errorcodes) on error.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size(
+ int streams,
+ int coupled_streams
+);
+
+/** Allocates and initializes a multistream encoder state.
+ * Call opus_multistream_encoder_destroy() to release
+ * this object when finished.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels in the input signal.
+ * This must be at most 255.
+ * It may be greater than the number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams to encode from the
+ * input.
+ * This must be no more than the number of channels.
+ * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+ * to encode.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * encoded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than the number of input channels.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * encoded channels to input channels, as described in
+ * @ref opus_multistream. As an extra constraint, the
+ * multistream encoder does not allow encoding coupled
+ * streams for which one channel is unused since this
+ * is never a good idea.
+ * @param application <tt>int</tt>: The target encoder application.
+ * This must be one of the following:
+ * <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>
+ * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
+ * code (see @ref opus_errorcodes) on
+ * failure.
+ */
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create(
- opus_int32 Fs, /**< Sampling rate of input signal (Hz) */
- int channels, /**< Number of channels in the input signal */
- int streams, /**< Total number of streams to encode from the input */
- int coupled_streams, /**< Number of coupled (stereo) streams to encode */
- const unsigned char *mapping, /**< Encoded mapping between channels and streams */
- int application, /**< Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
- int *error /**< Error code */
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping,
+ int application,
+ int *error
) OPUS_ARG_NONNULL(5);
-/** Initialize an already allocated multistream encoder state. */
+/** Initialize a previously allocated multistream encoder state.
+ * The memory pointed to by \a st must be at least the size returned by
+ * opus_multistream_encoder_get_size().
+ * This is intended for applications which use their own allocator instead of
+ * malloc.
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @see opus_multistream_encoder_create
+ * @see opus_multistream_encoder_get_size
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels in the input signal.
+ * This must be at most 255.
+ * It may be greater than the number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams to encode from the
+ * input.
+ * This must be no more than the number of channels.
+ * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+ * to encode.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * encoded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than the number of input channels.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * encoded channels to input channels, as described in
+ * @ref opus_multistream. As an extra constraint, the
+ * multistream encoder does not allow encoding coupled
+ * streams for which one channel is unused since this
+ * is never a good idea.
+ * @param application <tt>int</tt>: The target encoder application.
+ * This must be one of the following:
+ * <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>
+ * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
+ * on failure.
+ */
OPUS_EXPORT int opus_multistream_encoder_init(
- OpusMSEncoder *st, /**< Encoder state */
- opus_int32 Fs, /**< Sampling rate of input signal (Hz) */
- int channels, /**< Number of channels in the input signal */
- int streams, /**< Total number of streams to encode from the input */
- int coupled_streams, /**< Number of coupled (stereo) streams to encode */
- const unsigned char *mapping, /**< Encoded mapping between channels and streams */
- int application /**< Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
+ OpusMSEncoder *st,
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping,
+ int application
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
-/** Returns length of the data payload (in bytes) or a negative error code */
+/** Encodes a multistream Opus frame.
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+ * @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
+ * samples.
+ * This must contain
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param 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 instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @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 int opus_multistream_encode(
- OpusMSEncoder *st, /**< Encoder state */
- const opus_int16 *pcm, /**< Input signal as interleaved samples. Length is frame_size*channels */
- int frame_size, /**< Number of samples per frame of input signal */
- unsigned char *data, /**< Output buffer for the compressed payload (no more than max_data_bytes long) */
- opus_int32 max_data_bytes /**< Allocated memory for payload; don't use for controlling bitrate */
+ OpusMSEncoder *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);
-/** Returns length of the data payload (in bytes) or a negative error code. */
+/** Encodes a multistream Opus frame from floating point input.
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+ * @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
+ * samples 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.
+ * This must contain
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param 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 instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @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 int opus_multistream_encode_float(
- OpusMSEncoder *st, /**< Encoder state */
- const float *pcm, /**< Input signal interleaved in channel order. length is frame_size*channels */
- int frame_size, /**< Number of samples per frame of input signal */
- unsigned char *data, /**< Output buffer for the compressed payload (no more than max_data_bytes long) */
- opus_int32 max_data_bytes /**< Allocated memory for payload; don't use for controlling bitrate */
+ OpusMSEncoder *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);
-/** Gets the size of an OpusMSEncoder structure.
- * @returns size
+/** Frees an <code>OpusMSEncoder</code> allocated by
+ * opus_multistream_encoder_create().
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to be freed.
*/
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size(
- int streams, /**< Total number of coded streams */
- int coupled_streams /**< Number of coupled (stereo) streams */
-);
-
-/** Deallocate a multstream encoder state */
OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st);
-/** Get or set options on a multistream encoder state */
+/** Perform a CTL function on a multistream Opus encoder.
+ *
+ * Generally the request and subsequent arguments are generated by a
+ * convenience macro.
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls,
+ * @ref opus_encoderctls, or @ref opus_multistream_ctls.
+ * @see opus_genericctls
+ * @see opus_encoderctls
+ * @see opus_multistream_ctls
+ */
OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
-/** Allocate and initialize a multistream decoder state object.
- * Call opus_multistream_decoder_destroy() to release
- * this object when finished. */
+/**@}*/
+
+/**\name Multistream decoder functions */
+/**@{*/
+
+/** Gets the size of an <code>OpusMSDecoder</code> structure.
+ * @param streams <tt>int</tt>: The total number of streams coded in the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number streams to decode as coupled
+ * (2 channel) streams.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @returns The size in bytes on success, or a negative error code
+ * (see @ref opus_errorcodes) on error.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size(
+ int streams,
+ int coupled_streams
+);
+
+/** Allocates and initializes a multistream decoder state.
+ * Call opus_multistream_decoder_destroy() to release
+ * this object when finished.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels to output.
+ * This must be at most 255.
+ * It may be different from the number of coded
+ * channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams coded in the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
+ * (2 channel) streams.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * coded channels to output channels, as described in
+ * @ref opus_multistream.
+ * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
+ * code (see @ref opus_errorcodes) on
+ * failure.
+ */
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create(
- opus_int32 Fs, /**< Sampling rate to decode at (Hz) */
- int channels, /**< Number of channels to decode */
- int streams, /**< Total number of coded streams in the multistream */
- int coupled_streams, /**< Number of coupled (stereo) streams in the multistream */
- const unsigned char *mapping, /**< Stream to channel mapping table */
- int *error /**< Error code */
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping,
+ int *error
) OPUS_ARG_NONNULL(5);
-/** Intialize a previously allocated decoder state object. */
+/** Intialize a previously allocated decoder state object.
+ * The memory pointed to by \a st must be at least the size returned by
+ * opus_multistream_encoder_get_size().
+ * This is intended for applications which use their own allocator instead of
+ * malloc.
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @see opus_multistream_decoder_create
+ * @see opus_multistream_deocder_get_size
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels to output.
+ * This must be at most 255.
+ * It may be different from the number of coded
+ * channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams coded in the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
+ * (2 channel) streams.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * coded channels to output channels, as described in
+ * @ref opus_multistream.
+ * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
+ * on failure.
+ */
OPUS_EXPORT int opus_multistream_decoder_init(
- OpusMSDecoder *st, /**< Encoder state */
- opus_int32 Fs, /**< Sample rate of input signal (Hz) */
- int channels, /**< Number of channels in the input signal */
- int streams, /**< Total number of coded streams */
- int coupled_streams, /**< Number of coupled (stereo) streams */
- const unsigned char *mapping /**< Stream to channel mapping table */
+ OpusMSDecoder *st,
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
-/** Returns the number of samples decoded or a negative error code */
+/** Decode a multistream Opus packet.
+ * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+ * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+ * Use a <code>NULL</code>
+ * pointer to indicate packet
+ * loss.
+ * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+ * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
+ * samples.
+ * This must contain room for
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: The number of samples per channel of
+ * available space in \a pcm.
+ * If this is less than the maximum packet duration
+ * (120 ms; 5760 for 48kHz), this function will not be capable
+ * of decoding some packets. In the case of PLC (data==NULL)
+ * or FEC (decode_fec=1), then frame_size needs to be exactly
+ * the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the
+ * next incoming packet. For the PLC and FEC cases, frame_size
+ * <b>must</b> be a multiple of 2.5 ms.
+ * @param 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 samples decoded on success or a negative error code
+ * (see @ref opus_errorcodes) on failure.
+ */
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(
- OpusMSDecoder *st, /**< Decoder state */
- const unsigned char *data, /**< Input payload. Use a NULL pointer to indicate packet loss */
- opus_int32 len, /**< Number of bytes in payload */
- opus_int16 *pcm, /**< Output signal, samples interleaved in channel order . length is frame_size*channels */
- int frame_size, /**< Number of samples per frame of input signal */
- int decode_fec /**< Flag (0/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. */
+ OpusMSDecoder *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);
-/** Returns the number of samples decoded or a negative error code */
+/** Decode a multistream Opus packet with floating point output.
+ * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+ * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+ * Use a <code>NULL</code>
+ * pointer to indicate packet
+ * loss.
+ * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+ * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
+ * samples.
+ * This must contain room for
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: The number of samples per channel of
+ * available space in \a pcm.
+ * If this is less than the maximum packet duration
+ * (120 ms; 5760 for 48kHz), this function will not be capable
+ * of decoding some packets. In the case of PLC (data==NULL)
+ * or FEC (decode_fec=1), then frame_size needs to be exactly
+ * the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the
+ * next incoming packet. For the PLC and FEC cases, frame_size
+ * <b>must</b> be a multiple of 2.5 ms.
+ * @param 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 samples decoded on success or a negative error code
+ * (see @ref opus_errorcodes) on failure.
+ */
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float(
- OpusMSDecoder *st, /**< Decoder state */
- const unsigned char *data, /**< Input payload buffer. Use a NULL pointer to indicate packet loss */
- opus_int32 len, /**< Number of payload bytes in data */
- float *pcm, /**< Buffer for the output signal (interleaved iin channel order). length is frame_size*channels */
- int frame_size, /**< Number of samples per frame of input signal */
- int decode_fec /**< Flag (0/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. */
+ OpusMSDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ float *pcm,
+ int frame_size,
+ int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
-/** Gets the size of an OpusMSDecoder structure.
- * @returns size
+/** Perform a CTL function on a multistream Opus decoder.
+ *
+ * Generally the request and subsequent arguments are generated by a
+ * convenience macro.
+ * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls,
+ * @ref opus_decoderctls, or @ref opus_multistream_ctls.
+ * @see opus_genericctls
+ * @see opus_decoderctls
+ * @see opus_multistream_ctls
*/
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size(
- int streams, /**< Total number of coded streams */
- int coupled_streams /**< Number of coupled (stereo) streams */
-);
-
-/** Get or set options on a multistream decoder state */
OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
-/** Deallocate a multistream decoder state object */
+/** Frees an <code>OpusMSDecoder</code> allocated by
+ * opus_multistream_decoder_create().
+ * @param st <tt>OpusMSDecoder</tt>: Multistream decoder state to be freed.
+ */
OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st);
+/**@}*/
+
+/**@}*/
+
#ifdef __cplusplus
}
#endif
diff --git a/opus-uninstalled.pc.in b/opus-uninstalled.pc.in
index 7361028..36e8db6 100644
--- a/opus-uninstalled.pc.in
+++ b/opus-uninstalled.pc.in
@@ -1,12 +1,12 @@
-# opus codec reference implementation uninstalled pkg-config file
+# Opus codec reference implementation uninstalled pkg-config file
libdir=${pcfiledir}/.libs
includedir=${pcfiledir}
Name: opus uninstalled
-Description: Opus IETF audio codec (not installed)
+Description: Opus IETF audio codec (not installed, @PC_BUILD@)
Version: @VERSION@
Requires:
Conflicts:
-Libs: ${libdir}/libopus.a
-Cflags: -I${includedir}/include
+Libs: ${libdir}/libopus.a @PC_LIBM@
+Cflags: -I${pcfiledir}/@top_srcdir@/include
diff --git a/opus.m4 b/opus.m4
index 20f166b..47f5ec4 100644
--- a/opus.m4
+++ b/opus.m4
@@ -102,7 +102,7 @@ int main ()
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
[ echo "*** The test program failed to compile or link. See the file config.log for the"
- echo "*** exact error that occured. This usually means Opus was incorrectly installed"
+ echo "*** exact error that occurred. This usually means Opus was incorrectly installed"
echo "*** or that you have moved Opus since it was installed." ])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
diff --git a/opus.pc.in b/opus.pc.in
index f702969..b7d4083 100644
--- a/opus.pc.in
+++ b/opus.pc.in
@@ -1,4 +1,4 @@
-# opus codec reference implementation pkg-config file
+# Opus codec reference implementation pkg-config file
prefix=@prefix@
exec_prefix=@exec_prefix@
@@ -6,10 +6,11 @@ libdir=@libdir@
includedir=@includedir@
Name: Opus
-Description: Opus IETF low-latency audio codec
+Description: Opus IETF audio codec (@PC_BUILD@ build)
URL: http://opus-codec.org/
Version: @VERSION@
Requires:
Conflicts:
Libs: -L${libdir} -lopus
+Libs.private: @PC_LIBM@
Cflags: -I${includedir}/opus
diff --git a/opus_headers.mk b/opus_headers.mk
new file mode 100644
index 0000000..f160710
--- /dev/null
+++ b/opus_headers.mk
@@ -0,0 +1,4 @@
+OPUS_HEAD = \
+include/opus.h \
+include/opus_multistream.h \
+src/opus_private.h
diff --git a/opus_sources.mk b/opus_sources.mk
new file mode 100644
index 0000000..384b036
--- /dev/null
+++ b/opus_sources.mk
@@ -0,0 +1,5 @@
+OPUS_SOURCES = src/opus.c \
+src/opus_decoder.c \
+src/opus_encoder.c \
+src/opus_multistream.c \
+src/repacketizer.c
diff --git a/silk/API.h b/silk/API.h
index c77ad2f..4b8ca12 100644
--- a/silk/API.h
+++ b/silk/API.h
@@ -67,14 +67,6 @@ opus_int silk_InitEncoder( /* O Returns error co
silk_EncControlStruct *encStatus /* O Encoder Status */
);
-/***************************************/
-/* Read control structure from encoder */
-/***************************************/
-opus_int silk_QueryEncoder( /* O Returns error code */
- const void *encState, /* I State */
- silk_EncControlStruct *encStatus /* O Encoder Status */
-);
-
/**************************/
/* Encode frame with Silk */
/**************************/
diff --git a/silk/NLSF_stabilize.c b/silk/NLSF_stabilize.c
index fc642af..7498b54 100644
--- a/silk/NLSF_stabilize.c
+++ b/silk/NLSF_stabilize.c
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
/* NLSF stabilizer: */
/* */
-/* - Moves NLSFs futher apart if they are too close */
+/* - Moves NLSFs further apart if they are too close */
/* - Moves NLSFs away from borders if they are too close */
/* - High effort to achieve a modification with minimum */
/* Euclidean distance to input vector */
diff --git a/silk/PLC.c b/silk/PLC.c
index 1b93d06..8d54729 100644
--- a/silk/PLC.c
+++ b/silk/PLC.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include "main.h"
+#include "stack_alloc.h"
#include "PLC.h"
#define NB_ATT 2
@@ -178,12 +179,17 @@ static inline void silk_PLC_conceal(
opus_int16 rand_scale_Q14;
opus_int16 *B_Q14, *exc_buf_ptr;
opus_int32 *sLPC_Q14_ptr;
- opus_int16 exc_buf[ 2 * MAX_SUB_FRAME_LENGTH ];
+ VARDECL( opus_int16, exc_buf );
opus_int16 A_Q12[ MAX_LPC_ORDER ];
- opus_int16 sLTP[ MAX_FRAME_LENGTH ];
- opus_int32 sLTP_Q14[ 2 * MAX_FRAME_LENGTH ];
+ VARDECL( opus_int16, sLTP );
+ VARDECL( opus_int32, sLTP_Q14 );
silk_PLC_struct *psPLC = &psDec->sPLC;
opus_int32 prevGain_Q10[2];
+ SAVE_STACK;
+
+ ALLOC( exc_buf, 2*psPLC->subfr_length, opus_int16 );
+ ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );
+ ALLOC( sLTP_Q14, psDec->ltp_mem_length + psDec->frame_length, opus_int32 );
prevGain_Q10[0] = silk_RSHIFT( psPLC->prevGain_Q16[ 0 ], 6);
prevGain_Q10[1] = silk_RSHIFT( psPLC->prevGain_Q16[ 1 ], 6);
@@ -354,9 +360,10 @@ static inline void silk_PLC_conceal(
for( i = 0; i < MAX_NB_SUBFR; i++ ) {
psDecCtrl->pitchL[ i ] = lag;
}
+ RESTORE_STACK;
}
-/* Glues concealed frames with new good recieved frames */
+/* Glues concealed frames with new good received frames */
void silk_PLC_glue_frames(
silk_decoder_state *psDec, /* I/O decoder state */
opus_int16 frame[], /* I/O signal */
diff --git a/silk/SigProc_FIX.h b/silk/SigProc_FIX.h
index 72ec26a..daa5fd0 100644
--- a/silk/SigProc_FIX.h
+++ b/silk/SigProc_FIX.h
@@ -313,7 +313,7 @@ void silk_burg_modified(
opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
- const opus_int subfr_length, /* I Input signal subframe length (incl. D preceeding samples) */
+ const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
const opus_int nb_subfr, /* I Number of subframes stacked in x */
const opus_int D /* I Order */
);
@@ -379,7 +379,7 @@ static inline opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
}
}
-/* Allocate opus_int16 alligned to 4-byte memory address */
+/* Allocate opus_int16 aligned to 4-byte memory address */
#if EMBEDDED_ARM
#define silk_DWORD_ALIGN __attribute__((aligned(4)))
#else
diff --git a/silk/control_audio_bandwidth.c b/silk/control_audio_bandwidth.c
index a9af913..b645dd5 100644
--- a/silk/control_audio_bandwidth.c
+++ b/silk/control_audio_bandwidth.c
@@ -80,6 +80,8 @@ opus_int silk_control_audio_bandwidth(
} else {
if( psEncC->sLP.transition_frame_no <= 0 ) {
encControl->switchReady = 1;
+ /* Make room for redundancy */
+ encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
} else {
/* Direction: down (at double speed) */
psEncC->sLP.mode = -2;
@@ -106,6 +108,8 @@ opus_int silk_control_audio_bandwidth(
} else {
if( psEncC->sLP.mode == 0 ) {
encControl->switchReady = 1;
+ /* Make room for redundancy */
+ encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
} else {
/* Direction: up */
psEncC->sLP.mode = 1;
diff --git a/silk/control_codec.c b/silk/control_codec.c
index d0ed528..ecc338c 100644
--- a/silk/control_codec.c
+++ b/silk/control_codec.c
@@ -38,18 +38,18 @@ POSSIBILITY OF SUCH DAMAGE.
#include "tuning_parameters.h"
#include "pitch_est_defines.h"
-opus_int silk_setup_resamplers(
+static opus_int silk_setup_resamplers(
silk_encoder_state_Fxx *psEnc, /* I/O */
opus_int fs_kHz /* I */
);
-opus_int silk_setup_fs(
+static opus_int silk_setup_fs(
silk_encoder_state_Fxx *psEnc, /* I/O */
opus_int fs_kHz, /* I */
opus_int PacketSize_ms /* I */
);
-opus_int silk_setup_complexity(
+static opus_int silk_setup_complexity(
silk_encoder_state *psEncC, /* I/O */
opus_int Complexity /* I */
);
@@ -131,7 +131,7 @@ opus_int silk_control_encoder(
return ret;
}
-opus_int silk_setup_resamplers(
+static opus_int silk_setup_resamplers(
silk_encoder_state_Fxx *psEnc, /* I/O */
opus_int fs_kHz /* I */
)
@@ -186,7 +186,7 @@ opus_int silk_setup_resamplers(
return ret;
}
-opus_int silk_setup_fs(
+static opus_int silk_setup_fs(
silk_encoder_state_Fxx *psEnc, /* I/O */
opus_int fs_kHz, /* I */
opus_int PacketSize_ms /* I */
@@ -299,7 +299,7 @@ opus_int silk_setup_fs(
return ret;
}
-opus_int silk_setup_complexity(
+static opus_int silk_setup_complexity(
silk_encoder_state *psEncC, /* I/O */
opus_int Complexity /* I */
)
diff --git a/silk/dec_API.c b/silk/dec_API.c
index 60beef6..68403b7 100644
--- a/silk/dec_API.c
+++ b/silk/dec_API.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include "API.h"
#include "main.h"
+#include "stack_alloc.h"
/************************/
/* Decoder Super Struct */
@@ -85,14 +86,16 @@ opus_int silk_Decode( /* O Returns error co
{
opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR;
opus_int32 nSamplesOutDec, LBRR_symbol;
- opus_int16 samplesOut1_tmp[ 2 ][ MAX_FS_KHZ * MAX_FRAME_LENGTH_MS + 2 ];
- opus_int16 samplesOut2_tmp[ MAX_API_FS_KHZ * MAX_FRAME_LENGTH_MS ];
+ opus_int16 *samplesOut1_tmp[ 2 ];
+ VARDECL( opus_int16, samplesOut1_tmp_storage );
+ VARDECL( opus_int16, samplesOut2_tmp );
opus_int32 MS_pred_Q13[ 2 ] = { 0 };
opus_int16 *resample_out_ptr;
silk_decoder *psDec = ( silk_decoder * )decState;
silk_decoder_state *channel_state = psDec->channel_state;
opus_int has_side;
opus_int stereo_to_mono;
+ SAVE_STACK;
/**********************************/
/* Test if first frame in payload */
@@ -132,11 +135,13 @@ opus_int silk_Decode( /* O Returns error co
channel_state[ n ].nb_subfr = 4;
} else {
silk_assert( 0 );
+ RESTORE_STACK;
return SILK_DEC_INVALID_FRAME_SIZE;
}
fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1;
if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) {
silk_assert( 0 );
+ RESTORE_STACK;
return SILK_DEC_INVALID_SAMPLING_FREQUENCY;
}
ret += silk_decoder_set_fs( &channel_state[ n ], fs_kHz_dec, decControl->API_sampleRate );
@@ -153,6 +158,7 @@ opus_int silk_Decode( /* O Returns error co
if( decControl->API_sampleRate > (opus_int32)MAX_API_FS_KHZ * 1000 || decControl->API_sampleRate < 8000 ) {
ret = SILK_DEC_INVALID_SAMPLING_FREQUENCY;
+ RESTORE_STACK;
return( ret );
}
@@ -240,6 +246,14 @@ opus_int silk_Decode( /* O Returns error co
psDec->channel_state[ 1 ].first_frame_after_reset = 1;
}
+ ALLOC( samplesOut1_tmp_storage,
+ decControl->nChannelsInternal*(
+ channel_state[ 0 ].frame_length + 2 ),
+ opus_int16 );
+ samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage;
+ samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage
+ + channel_state[ 0 ].frame_length + 2;
+
if( lostFlag == FLAG_DECODE_NORMAL ) {
has_side = !decode_only_middle;
} else {
@@ -285,6 +299,8 @@ opus_int silk_Decode( /* O Returns error co
*nSamplesOut = silk_DIV32( nSamplesOutDec * decControl->API_sampleRate, silk_SMULBB( channel_state[ 0 ].fs_kHz, 1000 ) );
/* Set up pointers to temp buffers */
+ ALLOC( samplesOut2_tmp,
+ decControl->nChannelsAPI == 2 ? *nSamplesOut : 0, opus_int16 );
if( decControl->nChannelsAPI == 2 ) {
resample_out_ptr = samplesOut2_tmp;
} else {
@@ -337,6 +353,7 @@ opus_int silk_Decode( /* O Returns error co
} else {
psDec->prev_decode_only_middle = decode_only_middle;
}
+ RESTORE_STACK;
return ret;
}
diff --git a/silk/decode_core.c b/silk/decode_core.c
index 2142dd4..0365ffd 100644
--- a/silk/decode_core.c
+++ b/silk/decode_core.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include "main.h"
+#include "stack_alloc.h"
/**********************************************************/
/* Core decoder. Performs inverse NSQ operation LTP + LPC */
@@ -43,15 +44,21 @@ void silk_decode_core(
{
opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType;
opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ];
- opus_int16 sLTP[ MAX_FRAME_LENGTH ];
- opus_int32 sLTP_Q15[ 2 * MAX_FRAME_LENGTH ];
+ VARDECL( opus_int16, sLTP );
+ VARDECL( opus_int32, sLTP_Q15 );
opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10;
opus_int32 *pred_lag_ptr, *pexc_Q14, *pres_Q14;
- opus_int32 res_Q14[ MAX_SUB_FRAME_LENGTH ];
- opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
+ VARDECL( opus_int32, res_Q14 );
+ VARDECL( opus_int32, sLPC_Q14 );
+ SAVE_STACK;
silk_assert( psDec->prev_gain_Q16 != 0 );
+ ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );
+ ALLOC( sLTP_Q15, psDec->ltp_mem_length + psDec->frame_length, opus_int32 );
+ ALLOC( res_Q14, psDec->subfr_length, opus_int32 );
+ ALLOC( sLPC_Q14, psDec->subfr_length + MAX_LPC_ORDER, opus_int32 );
+
offset_Q10 = silk_Quantization_Offsets_Q10[ psDec->indices.signalType >> 1 ][ psDec->indices.quantOffsetType ];
if( psDec->indices.NLSFInterpCoef_Q2 < 1 << 2 ) {
@@ -227,4 +234,5 @@ void silk_decode_core(
/* Save LPC state */
silk_memcpy( psDec->sLPC_Q14_buf, sLPC_Q14, MAX_LPC_ORDER * sizeof( opus_int32 ) );
+ RESTORE_STACK;
}
diff --git a/silk/decode_frame.c b/silk/decode_frame.c
index 9db93d8..3e4a6e2 100644
--- a/silk/decode_frame.c
+++ b/silk/decode_frame.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include "main.h"
+#include "stack_alloc.h"
#include "PLC.h"
/****************/
@@ -44,12 +45,16 @@ opus_int silk_decode_frame(
opus_int condCoding /* I The type of conditional coding to use */
)
{
- silk_decoder_control sDecCtrl;
+ VARDECL( silk_decoder_control, psDecCtrl );
opus_int L, mv_len, ret = 0;
- opus_int pulses[ MAX_FRAME_LENGTH ];
+ VARDECL( opus_int, pulses );
+ SAVE_STACK;
L = psDec->frame_length;
- sDecCtrl.LTP_scale_Q14 = 0;
+ ALLOC( psDecCtrl, 1, silk_decoder_control );
+ ALLOC( pulses, (L + SHELL_CODEC_FRAME_LENGTH - 1) &
+ ~(SHELL_CODEC_FRAME_LENGTH - 1), opus_int );
+ psDecCtrl->LTP_scale_Q14 = 0;
/* Safety checks */
silk_assert( L > 0 && L <= MAX_FRAME_LENGTH );
@@ -71,20 +76,17 @@ opus_int silk_decode_frame(
/********************************************/
/* Decode parameters and pulse signal */
/********************************************/
- silk_decode_parameters( psDec, &sDecCtrl, condCoding );
-
- /* Update length. Sampling frequency may have changed */
- L = psDec->frame_length;
+ silk_decode_parameters( psDec, psDecCtrl, condCoding );
/********************************************************/
/* Run inverse NSQ */
/********************************************************/
- silk_decode_core( psDec, &sDecCtrl, pOut, pulses );
+ silk_decode_core( psDec, psDecCtrl, pOut, pulses );
/********************************************************/
/* Update PLC state */
/********************************************************/
- silk_PLC( psDec, &sDecCtrl, pOut, 0 );
+ silk_PLC( psDec, psDecCtrl, pOut, 0 );
psDec->lossCnt = 0;
psDec->prevSignalType = psDec->indices.signalType;
@@ -94,7 +96,7 @@ opus_int silk_decode_frame(
psDec->first_frame_after_reset = 0;
} else {
/* Handle packet loss by extrapolation */
- silk_PLC( psDec, &sDecCtrl, pOut, 1 );
+ silk_PLC( psDec, psDecCtrl, pOut, 1 );
}
/*************************/
@@ -113,13 +115,14 @@ opus_int silk_decode_frame(
/************************************************/
/* Comfort noise generation / estimation */
/************************************************/
- silk_CNG( psDec, &sDecCtrl, pOut, L );
+ silk_CNG( psDec, psDecCtrl, pOut, L );
/* Update some decoder state variables */
- psDec->lagPrev = sDecCtrl.pitchL[ psDec->nb_subfr - 1 ];
+ psDec->lagPrev = psDecCtrl->pitchL[ psDec->nb_subfr - 1 ];
/* Set output frame length */
*pN = L;
+ RESTORE_STACK;
return ret;
}
diff --git a/silk/enc_API.c b/silk/enc_API.c
index c0143fd..ec7915c 100644
--- a/silk/enc_API.c
+++ b/silk/enc_API.c
@@ -40,6 +40,14 @@ POSSIBILITY OF SUCH DAMAGE.
#include "main_FLP.h"
#endif
+/***************************************/
+/* Read control structure from encoder */
+/***************************************/
+static opus_int silk_QueryEncoder( /* O Returns error code */
+ const void *encState, /* I State */
+ silk_EncControlStruct *encStatus /* O Encoder Status */
+);
+
/****************************************/
/* Encoder functions */
/****************************************/
@@ -90,7 +98,7 @@ opus_int silk_InitEncoder( /* O Returns error co
/***************************************/
/* Read control structure from encoder */
/***************************************/
-opus_int silk_QueryEncoder( /* O Returns error code */
+static opus_int silk_QueryEncoder( /* O Returns error code */
const void *encState, /* I State */
silk_EncControlStruct *encStatus /* O Encoder Status */
)
diff --git a/silk/fixed/LTP_analysis_filter_FIX.c b/silk/fixed/LTP_analysis_filter_FIX.c
index 155eea8..a8fee55 100644
--- a/silk/fixed/LTP_analysis_filter_FIX.c
+++ b/silk/fixed/LTP_analysis_filter_FIX.c
@@ -33,13 +33,13 @@ POSSIBILITY OF SUCH DAMAGE.
void silk_LTP_analysis_filter_FIX(
opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */
- const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceeding samples */
+ const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */
const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */
const opus_int subfr_length, /* I Length of each subframe */
const opus_int nb_subfr, /* I Number of subframes */
- const opus_int pre_length /* I Length of the preceeding samples starting at &x[0] for each subframe */
+ const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */
)
{
const opus_int16 *x_ptr, *x_lag_ptr;
diff --git a/silk/fixed/burg_modified_FIX.c b/silk/fixed/burg_modified_FIX.c
index ecbba03..26a66b1 100644
--- a/silk/fixed/burg_modified_FIX.c
+++ b/silk/fixed/burg_modified_FIX.c
@@ -47,7 +47,7 @@ void silk_burg_modified(
opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
- const opus_int subfr_length, /* I Input signal subframe length (incl. D preceeding samples) */
+ const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
const opus_int nb_subfr, /* I Number of subframes stacked in x */
const opus_int D /* I Order */
)
@@ -238,7 +238,7 @@ void silk_burg_modified(
/* Scale coefficients */
A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
}
- /* Subtract energy of preceeding samples from C0 */
+ /* Subtract energy of preceding samples from C0 */
if( rshifts > 0 ) {
for( s = 0; s < nb_subfr; s++ ) {
x_ptr = x + s * subfr_length;
diff --git a/silk/fixed/find_pitch_lags_FIX.c b/silk/fixed/find_pitch_lags_FIX.c
index a323411..39c3048 100644
--- a/silk/fixed/find_pitch_lags_FIX.c
+++ b/silk/fixed/find_pitch_lags_FIX.c
@@ -54,7 +54,7 @@ void silk_find_pitch_lags_FIX(
/******************************************/
buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
- /* Safty check */
+ /* Safety check */
silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
x_buf = x - psEnc->sCmn.ltp_mem_length;
@@ -101,7 +101,7 @@ void silk_find_pitch_lags_FIX(
}
/* Do BWE */
- silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWITH_EXPANSION, 16 ) );
+ silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) );
/*****************************************/
/* LPC analysis filtering */
diff --git a/silk/fixed/main_FIX.h b/silk/fixed/main_FIX.h
index 1e60f88..369b31e 100644
--- a/silk/fixed/main_FIX.h
+++ b/silk/fixed/main_FIX.h
@@ -168,17 +168,17 @@ void silk_find_LTP_FIX(
void silk_LTP_analysis_filter_FIX(
opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */
- const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceeding samples */
+ const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */
const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */
const opus_int subfr_length, /* I Length of each subframe */
const opus_int nb_subfr, /* I Number of subframes */
- const opus_int pre_length /* I Length of the preceeding samples starting at &x[0] for each subframe */
+ const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */
);
/* Calculates residual energies of input subframes where all subframes have LPC_order */
-/* of preceeding samples */
+/* of preceding samples */
void silk_residual_energy_FIX(
opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */
diff --git a/silk/fixed/noise_shape_analysis_FIX.c b/silk/fixed/noise_shape_analysis_FIX.c
index b0e35de..d230e48 100644
--- a/silk/fixed/noise_shape_analysis_FIX.c
+++ b/silk/fixed/noise_shape_analysis_FIX.c
@@ -199,7 +199,7 @@ void silk_noise_shape_analysis_FIX(
/*************************/
/* Set quantizer offset */
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
- /* Initally set to 0; may be overruled in process_gains(..) */
+ /* Initially set to 0; may be overruled in process_gains(..) */
psEnc->sCmn.indices.quantOffsetType = 0;
psEncCtrl->sparseness_Q8 = 0;
} else {
diff --git a/silk/fixed/pitch_analysis_core_FIX.c b/silk/fixed/pitch_analysis_core_FIX.c
index bb9166e..d43f444 100644
--- a/silk/fixed/pitch_analysis_core_FIX.c
+++ b/silk/fixed/pitch_analysis_core_FIX.c
@@ -500,7 +500,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
silk_assert( lag == silk_SAT16( lag ) );
contour_bias_Q20 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 20 ), lag );
- /* Set up codebook parameters acording to complexity setting and frame length */
+ /* Set up codebook parameters according to complexity setting and frame length */
if( nb_subfr == PE_MAX_NB_SUBFR ) {
nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
cbk_size = PE_NB_CBKS_STAGE3_MAX;
diff --git a/silk/fixed/residual_energy_FIX.c b/silk/fixed/residual_energy_FIX.c
index 912b16b..f284e51 100644
--- a/silk/fixed/residual_energy_FIX.c
+++ b/silk/fixed/residual_energy_FIX.c
@@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "main_FIX.h"
/* Calculates residual energies of input subframes where all subframes have LPC_order */
-/* of preceeding samples */
+/* of preceding samples */
void silk_residual_energy_FIX(
opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */
@@ -54,7 +54,7 @@ void silk_residual_energy_FIX(
/* Filter input to create the LPC residual for each frame half, and measure subframe energies */
for( i = 0; i < nb_subfr >> 1; i++ ) {
- /* Calculate half frame LPC residual signal including preceeding samples */
+ /* Calculate half frame LPC residual signal including preceding samples */
silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order );
/* Point to first subframe of the just calculated LPC residual signal */
diff --git a/silk/float/LTP_analysis_filter_FLP.c b/silk/float/LTP_analysis_filter_FLP.c
index 297c813..d3a6a5a 100644
--- a/silk/float/LTP_analysis_filter_FLP.c
+++ b/silk/float/LTP_analysis_filter_FLP.c
@@ -33,13 +33,13 @@ POSSIBILITY OF SUCH DAMAGE.
void silk_LTP_analysis_filter_FLP(
silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */
- const silk_float *x, /* I Input signal, with preceeding samples */
+ const silk_float *x, /* I Input signal, with preceding samples */
const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */
const opus_int subfr_length, /* I Length of each subframe */
const opus_int nb_subfr, /* I number of subframes */
- const opus_int pre_length /* I Preceeding samples for each subframe */
+ const opus_int pre_length /* I Preceding samples for each subframe */
)
{
const silk_float *x_ptr, *x_lag_ptr;
diff --git a/silk/float/SigProc_FLP.h b/silk/float/SigProc_FLP.h
index 18e2571..036b46d 100644
--- a/silk/float/SigProc_FLP.h
+++ b/silk/float/SigProc_FLP.h
@@ -109,7 +109,7 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy
silk_float A[], /* O prediction coefficients (length order) */
const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
const silk_float minInvGain, /* I minimum inverse prediction gain */
- const opus_int subfr_length, /* I input signal subframe length (incl. D preceeding samples) */
+ const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */
const opus_int nb_subfr, /* I number of subframes stacked in x */
const opus_int D /* I order */
);
diff --git a/silk/float/burg_modified_FLP.c b/silk/float/burg_modified_FLP.c
index 0add3a6..31c9b22 100644
--- a/silk/float/burg_modified_FLP.c
+++ b/silk/float/burg_modified_FLP.c
@@ -40,7 +40,7 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy
silk_float A[], /* O prediction coefficients (length order) */
const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
const silk_float minInvGain, /* I minimum inverse prediction gain */
- const opus_int subfr_length, /* I input signal subframe length (incl. D preceeding samples) */
+ const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */
const opus_int nb_subfr, /* I number of subframes stacked in x */
const opus_int D /* I order */
)
@@ -162,7 +162,7 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy
for( k = 0; k < D; k++ ) {
A[ k ] = (silk_float)( -Af[ k ] );
}
- /* Subtract energy of preceeding samples from C0 */
+ /* Subtract energy of preceding samples from C0 */
for( s = 0; s < nb_subfr; s++ ) {
C0 -= silk_energy_FLP( x + s * subfr_length, D );
}
diff --git a/silk/float/find_pitch_lags_FLP.c b/silk/float/find_pitch_lags_FLP.c
index b3ade8f..00862a6 100644
--- a/silk/float/find_pitch_lags_FLP.c
+++ b/silk/float/find_pitch_lags_FLP.c
@@ -54,7 +54,7 @@ void silk_find_pitch_lags_FLP(
/******************************************/
buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
- /* Safty check */
+ /* Safety check */
silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
x_buf = x - psEnc->sCmn.ltp_mem_length;
@@ -96,7 +96,7 @@ void silk_find_pitch_lags_FLP(
silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder );
/* Bandwidth expansion */
- silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWITH_EXPANSION );
+ silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWIDTH_EXPANSION );
/*****************************************/
/* LPC analysis filtering */
diff --git a/silk/float/main_FLP.h b/silk/float/main_FLP.h
index 202a7fe..93455d4 100644
--- a/silk/float/main_FLP.h
+++ b/silk/float/main_FLP.h
@@ -164,17 +164,17 @@ void silk_find_LTP_FLP(
void silk_LTP_analysis_filter_FLP(
silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */
- const silk_float *x, /* I Input signal, with preceeding samples */
+ const silk_float *x, /* I Input signal, with preceding samples */
const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */
const opus_int subfr_length, /* I Length of each subframe */
const opus_int nb_subfr, /* I number of subframes */
- const opus_int pre_length /* I Preceeding samples for each subframe */
+ const opus_int pre_length /* I Preceding samples for each subframe */
);
/* Calculates residual energies of input subframes where all subframes have LPC_order */
-/* of preceeding samples */
+/* of preceding samples */
void silk_residual_energy_FLP(
silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
const silk_float x[], /* I Input signal */
diff --git a/silk/float/noise_shape_analysis_FLP.c b/silk/float/noise_shape_analysis_FLP.c
index 1c203b3..33bfd20 100644
--- a/silk/float/noise_shape_analysis_FLP.c
+++ b/silk/float/noise_shape_analysis_FLP.c
@@ -174,7 +174,7 @@ void silk_noise_shape_analysis_FLP(
/*************************/
/* Set quantizer offset */
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
- /* Initally set to 0; may be overruled in process_gains(..) */
+ /* Initially set to 0; may be overruled in process_gains(..) */
psEnc->sCmn.indices.quantOffsetType = 0;
psEncCtrl->sparseness = 0.0f;
} else {
diff --git a/silk/float/pitch_analysis_core_FLP.c b/silk/float/pitch_analysis_core_FLP.c
index d23e4ee..fbff90c 100644
--- a/silk/float/pitch_analysis_core_FLP.c
+++ b/silk/float/pitch_analysis_core_FLP.c
@@ -419,7 +419,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
silk_assert( lag == silk_SAT16( lag ) );
contour_bias = PE_FLATCONTOUR_BIAS / lag;
- /* Set up cbk parameters acording to complexity setting and frame length */
+ /* Set up cbk parameters according to complexity setting and frame length */
if( nb_subfr == PE_MAX_NB_SUBFR ) {
nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
cbk_size = PE_NB_CBKS_STAGE3_MAX;
diff --git a/silk/float/prefilter_FLP.c b/silk/float/prefilter_FLP.c
index 95b32da..d6c8439 100644
--- a/silk/float/prefilter_FLP.c
+++ b/silk/float/prefilter_FLP.c
@@ -47,7 +47,7 @@ static inline void silk_prefilt_FLP(
opus_int length /* I */
);
-void silk_warped_LPC_analysis_filter_FLP(
+static void silk_warped_LPC_analysis_filter_FLP(
silk_float state[], /* I/O State [order + 1] */
silk_float res[], /* O Residual signal [length] */
const silk_float coef[], /* I Coefficients [order] */
diff --git a/silk/float/residual_energy_FLP.c b/silk/float/residual_energy_FLP.c
index 4fa0e67..e65457a 100644
--- a/silk/float/residual_energy_FLP.c
+++ b/silk/float/residual_energy_FLP.c
@@ -87,7 +87,7 @@ silk_float silk_residual_energy_covar_FLP( /* O
}
/* Calculates residual energies of input subframes where all subframes have LPC_order */
-/* of preceeding samples */
+/* of preceding samples */
void silk_residual_energy_FLP(
silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
const silk_float x[], /* I Input signal */
diff --git a/silk/float/wrappers_FLP.c b/silk/float/wrappers_FLP.c
index 5500425..4259e90 100644
--- a/silk/float/wrappers_FLP.c
+++ b/silk/float/wrappers_FLP.c
@@ -155,7 +155,7 @@ void silk_NSQ_wrapper_FLP(
/* Convert input to fix */
for( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
- x_Q3[ i ] = silk_float2int( 8.0 * x[ i ] );
+ x_Q3[ i ] = silk_float2int( 8.0f * x[ i ] );
}
/* Call NSQ */
diff --git a/silk/resampler_rom.c b/silk/resampler_rom.c
index a09d188..b50af2e 100644
--- a/silk/resampler_rom.c
+++ b/silk/resampler_rom.c
@@ -34,18 +34,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include "resampler_private.h"
-/* Tables for 2x downsampler */
-const opus_int16 silk_resampler_down2_0 = 9872;
-const opus_int16 silk_resampler_down2_1 = 39809 - 65536;
-
-/* Tables for 2x upsampler, high quality */
-const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 };
-const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 };
-
/* Matlab code for the notch filter coefficients: */
/* B = [1, 0.147, 1]; A = [1, 0.107, 0.89]; G = 0.93; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]) */
/* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */
-const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634, -7012, 7209, 30474 };
+/* const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634, -7012, 7209, 30474 }; */
/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */
silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {
diff --git a/silk/resampler_rom.h b/silk/resampler_rom.h
index 0ad0686..473b24a 100644
--- a/silk/resampler_rom.h
+++ b/silk/resampler_rom.h
@@ -42,12 +42,12 @@ extern "C"
#define RESAMPLER_ORDER_FIR_12 8
/* Tables for 2x downsampler */
-extern const opus_int16 silk_resampler_down2_0;
-extern const opus_int16 silk_resampler_down2_1;
+static const opus_int16 silk_resampler_down2_0 = 9872;
+static const opus_int16 silk_resampler_down2_1 = 39809 - 65536;
/* Tables for 2x upsampler, high quality */
-extern const opus_int16 silk_resampler_up2_hq_0[ 3 ];
-extern const opus_int16 silk_resampler_up2_hq_1[ 3 ];
+static const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 };
+static const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 };
/* Tables with IIR and FIR coefficients for fractional downsamplers */
extern const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ];
diff --git a/silk/tables_LTP.c b/silk/tables_LTP.c
index 5522e32..dd1fb55 100644
--- a/silk/tables_LTP.c
+++ b/silk/tables_LTP.c
@@ -35,16 +35,16 @@ const opus_uint8 silk_LTP_per_index_iCDF[3] = {
179, 99, 0
};
-const opus_uint8 silk_LTP_gain_iCDF_0[8] = {
+static const opus_uint8 silk_LTP_gain_iCDF_0[8] = {
71, 56, 43, 30, 21, 12, 6, 0
};
-const opus_uint8 silk_LTP_gain_iCDF_1[16] = {
+static const opus_uint8 silk_LTP_gain_iCDF_1[16] = {
199, 165, 144, 124, 109, 96, 84, 71,
61, 51, 42, 32, 23, 15, 8, 0
};
-const opus_uint8 silk_LTP_gain_iCDF_2[32] = {
+static const opus_uint8 silk_LTP_gain_iCDF_2[32] = {
241, 225, 211, 199, 187, 175, 164, 153,
142, 132, 123, 114, 105, 96, 88, 80,
72, 64, 57, 50, 44, 38, 33, 29,
@@ -53,16 +53,16 @@ const opus_uint8 silk_LTP_gain_iCDF_2[32] = {
const opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304;
-const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = {
+static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = {
15, 131, 138, 138, 155, 155, 173, 173
};
-const opus_uint8 silk_LTP_gain_BITS_Q5_1[16] = {
+static const opus_uint8 silk_LTP_gain_BITS_Q5_1[16] = {
69, 93, 115, 118, 131, 138, 141, 138,
150, 150, 155, 150, 155, 160, 166, 160
};
-const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = {
+static const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = {
131, 128, 134, 141, 141, 141, 145, 145,
145, 150, 155, 155, 155, 155, 160, 160,
160, 160, 166, 166, 173, 173, 182, 192,
@@ -81,7 +81,7 @@ const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = {
silk_LTP_gain_BITS_Q5_2
};
-const opus_int8 silk_LTP_gain_vq_0[8][5] =
+static const opus_int8 silk_LTP_gain_vq_0[8][5] =
{
{
4, 6, 24, 7, 5
@@ -109,7 +109,7 @@ const opus_int8 silk_LTP_gain_vq_0[8][5] =
}
};
-const opus_int8 silk_LTP_gain_vq_1[16][5] =
+static const opus_int8 silk_LTP_gain_vq_1[16][5] =
{
{
13, 22, 39, 23, 12
@@ -161,7 +161,7 @@ const opus_int8 silk_LTP_gain_vq_1[16][5] =
}
};
-const opus_int8 silk_LTP_gain_vq_2[32][5] =
+static const opus_int8 silk_LTP_gain_vq_2[32][5] =
{
{
-6, 27, 61, 39, 5
diff --git a/silk/tables_NLSF_CB_NB_MB.c b/silk/tables_NLSF_CB_NB_MB.c
index 57bb817..7548052 100644
--- a/silk/tables_NLSF_CB_NB_MB.c
+++ b/silk/tables_NLSF_CB_NB_MB.c
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "tables.h"
-const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = {
+static const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = {
12, 35, 60, 83, 108, 132, 157, 180,
206, 228, 15, 32, 55, 77, 101, 125,
151, 175, 201, 225, 19, 42, 66, 89,
@@ -74,7 +74,7 @@ const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = {
64, 84, 104, 118, 156, 177, 201, 230
};
-const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = {
+static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = {
212, 178, 148, 129, 108, 96, 85, 82,
79, 77, 61, 59, 57, 56, 51, 49,
48, 45, 42, 41, 40, 38, 36, 34,
@@ -85,7 +85,7 @@ const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = {
28, 20, 19, 18, 12, 11, 5, 0
};
-const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = {
+static const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = {
16, 0, 0, 0, 0, 99, 66, 36,
36, 34, 36, 34, 34, 34, 34, 83,
69, 36, 52, 34, 116, 102, 70, 68,
@@ -108,7 +108,7 @@ const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = {
171, 137, 139, 137, 155, 218, 219, 139
};
-const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = {
+static const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = {
255, 254, 253, 238, 14, 3, 2, 1,
0, 255, 254, 252, 218, 35, 3, 2,
1, 0, 255, 254, 250, 208, 59, 4,
@@ -120,7 +120,7 @@ const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = {
254, 236, 173, 95, 37, 7, 1, 0
};
-const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = {
+static const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = {
255, 255, 255, 131, 6, 145, 255, 255,
255, 255, 255, 236, 93, 15, 96, 255,
255, 255, 255, 255, 194, 83, 25, 71,
@@ -132,13 +132,13 @@ const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = {
251, 123, 65, 55, 68, 100, 171, 255
};
-const opus_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = {
+static const opus_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = {
179, 138, 140, 148, 151, 149, 153, 151,
163, 116, 67, 82, 59, 92, 72, 100,
89, 92
};
-const opus_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = {
+static const opus_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = {
250, 3, 6, 3, 3, 3, 4, 3,
3, 3, 461
};
diff --git a/silk/tables_NLSF_CB_WB.c b/silk/tables_NLSF_CB_WB.c
index 00b68f7..3d6052e 100644
--- a/silk/tables_NLSF_CB_WB.c
+++ b/silk/tables_NLSF_CB_WB.c
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "tables.h"
-const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = {
+static const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = {
7, 23, 38, 54, 69, 85, 100, 116,
131, 147, 162, 178, 193, 208, 223, 239,
13, 25, 41, 55, 69, 83, 98, 112,
@@ -98,7 +98,7 @@ const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = {
110, 119, 129, 141, 175, 198, 218, 237
};
-const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = {
+static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = {
225, 204, 201, 184, 183, 175, 158, 154,
153, 135, 119, 115, 113, 110, 109, 99,
98, 95, 79, 68, 52, 50, 48, 45,
@@ -109,7 +109,7 @@ const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = {
24, 21, 11, 6, 5, 4, 3, 0
};
-const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = {
+static const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = {
0, 0, 0, 0, 0, 0, 0, 1,
100, 102, 102, 68, 68, 36, 34, 96,
164, 107, 158, 185, 180, 185, 139, 102,
@@ -144,7 +144,7 @@ const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = {
100, 107, 120, 119, 36, 197, 24, 0
};
-const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = {
+static const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = {
255, 254, 253, 244, 12, 3, 2, 1,
0, 255, 254, 252, 224, 38, 3, 2,
1, 0, 255, 254, 251, 209, 57, 4,
@@ -156,7 +156,7 @@ const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = {
248, 227, 177, 100, 19, 2, 1, 0
};
-const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = {
+static const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = {
255, 255, 255, 156, 4, 154, 255, 255,
255, 255, 255, 227, 102, 15, 92, 255,
255, 255, 255, 255, 213, 83, 24, 72,
@@ -168,14 +168,14 @@ const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = {
166, 116, 76, 55, 53, 125, 255, 255
};
-const opus_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = {
+static const opus_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = {
175, 148, 160, 176, 178, 173, 174, 164,
177, 174, 196, 182, 198, 192, 182, 68,
62, 66, 60, 72, 117, 85, 90, 118,
136, 151, 142, 160, 142, 155
};
-const opus_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = {
+static const opus_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = {
100, 3, 40, 3, 3, 3, 5, 14,
14, 10, 11, 3, 8, 9, 7, 3,
347
diff --git a/silk/tables_other.c b/silk/tables_other.c
index dedff26..3dc68d4 100644
--- a/silk/tables_other.c
+++ b/silk/tables_other.c
@@ -67,8 +67,8 @@ const opus_uint8 silk_stereo_pred_joint_iCDF[ 25 ] = {
const opus_uint8 silk_stereo_only_code_mid_iCDF[ 2 ] = { 64, 0 };
/* Tables for LBRR flags */
-const opus_uint8 silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 };
-const opus_uint8 silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 };
+static const opus_uint8 silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 };
+static const opus_uint8 silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 };
const opus_uint8 * const silk_LBRR_flags_iCDF_ptr[ 2 ] = {
silk_LBRR_flags_2_iCDF,
silk_LBRR_flags_3_iCDF
diff --git a/silk/tuning_parameters.h b/silk/tuning_parameters.h
index 0b0b774..a26de4d 100644
--- a/silk/tuning_parameters.h
+++ b/silk/tuning_parameters.h
@@ -44,7 +44,7 @@ extern "C"
#define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f
/* Bandwidth expansion for whitening filter in pitch analysis */
-#define FIND_PITCH_BANDWITH_EXPANSION 0.99f
+#define FIND_PITCH_BANDWIDTH_EXPANSION 0.99f
/*********************/
/* Linear prediction */
diff --git a/silk_headers.mk b/silk_headers.mk
new file mode 100644
index 0000000..45c6985
--- /dev/null
+++ b/silk_headers.mk
@@ -0,0 +1,26 @@
+SILK_HEAD = \
+silk/debug.h \
+silk/control.h \
+silk/errors.h \
+silk/API.h \
+silk/typedef.h \
+silk/define.h \
+silk/main.h \
+silk/PLC.h \
+silk/structs.h \
+silk/tables.h \
+silk/tuning_parameters.h \
+silk/Inlines.h \
+silk/MacroCount.h \
+silk/MacroDebug.h \
+silk/macros.h \
+silk/pitch_est_defines.h \
+silk/resampler_private.h \
+silk/resampler_rom.h \
+silk/resampler_structs.h \
+silk/SigProc_FIX.h \
+silk/fixed/main_FIX.h \
+silk/fixed/structs_FIX.h \
+silk/float/main_FLP.h \
+silk/float/structs_FLP.h \
+silk/float/SigProc_FLP.h
diff --git a/silk_sources.mk b/silk_sources.mk
new file mode 100644
index 0000000..0de367b
--- /dev/null
+++ b/silk_sources.mk
@@ -0,0 +1,138 @@
+SILK_SOURCES = \
+silk/CNG.c \
+silk/code_signs.c \
+silk/init_decoder.c \
+silk/decode_core.c \
+silk/decode_frame.c \
+silk/decode_parameters.c \
+silk/decode_indices.c \
+silk/decode_pulses.c \
+silk/decoder_set_fs.c \
+silk/dec_API.c \
+silk/enc_API.c \
+silk/encode_indices.c \
+silk/encode_pulses.c \
+silk/gain_quant.c \
+silk/interpolate.c \
+silk/LP_variable_cutoff.c \
+silk/NLSF_decode.c \
+silk/NSQ.c \
+silk/NSQ_del_dec.c \
+silk/PLC.c \
+silk/shell_coder.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 \
+silk/VAD.c \
+silk/control_audio_bandwidth.c \
+silk/quant_LTP_gains.c \
+silk/VQ_WMat_EC.c \
+silk/HP_variable_cutoff.c \
+silk/NLSF_encode.c \
+silk/NLSF_VQ.c \
+silk/NLSF_unpack.c \
+silk/NLSF_del_dec_quant.c \
+silk/process_NLSFs.c \
+silk/stereo_LR_to_MS.c \
+silk/stereo_MS_to_LR.c \
+silk/check_control_input.c \
+silk/control_SNR.c \
+silk/init_encoder.c \
+silk/control_codec.c \
+silk/A2NLSF.c \
+silk/ana_filt_bank_1.c \
+silk/biquad_alt.c \
+silk/bwexpander_32.c \
+silk/bwexpander.c \
+silk/debug.c \
+silk/decode_pitch.c \
+silk/inner_prod_aligned.c \
+silk/lin2log.c \
+silk/log2lin.c \
+silk/LPC_analysis_filter.c \
+silk/LPC_inv_pred_gain.c \
+silk/table_LSF_cos.c \
+silk/NLSF2A.c \
+silk/NLSF_stabilize.c \
+silk/NLSF_VQ_weights_laroia.c \
+silk/pitch_est_tables.c \
+silk/resampler.c \
+silk/resampler_down2_3.c \
+silk/resampler_down2.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/sigm_Q15.c \
+silk/sort.c \
+silk/sum_sqr_shift.c \
+silk/stereo_decode_pred.c \
+silk/stereo_encode_pred.c \
+silk/stereo_find_predictor.c \
+silk/stereo_quant_pred.c
+
+
+SILK_SOURCES_FIXED = \
+silk/fixed/LTP_analysis_filter_FIX.c \
+silk/fixed/LTP_scale_ctrl_FIX.c \
+silk/fixed/corrMatrix_FIX.c \
+silk/fixed/encode_frame_FIX.c \
+silk/fixed/find_LPC_FIX.c \
+silk/fixed/find_LTP_FIX.c \
+silk/fixed/find_pitch_lags_FIX.c \
+silk/fixed/find_pred_coefs_FIX.c \
+silk/fixed/noise_shape_analysis_FIX.c \
+silk/fixed/prefilter_FIX.c \
+silk/fixed/process_gains_FIX.c \
+silk/fixed/regularize_correlations_FIX.c \
+silk/fixed/residual_energy16_FIX.c \
+silk/fixed/residual_energy_FIX.c \
+silk/fixed/solve_LS_FIX.c \
+silk/fixed/warped_autocorrelation_FIX.c \
+silk/fixed/apply_sine_window_FIX.c \
+silk/fixed/autocorr_FIX.c \
+silk/fixed/burg_modified_FIX.c \
+silk/fixed/k2a_FIX.c \
+silk/fixed/k2a_Q16_FIX.c \
+silk/fixed/pitch_analysis_core_FIX.c \
+silk/fixed/vector_ops_FIX.c \
+silk/fixed/schur64_FIX.c \
+silk/fixed/schur_FIX.c
+
+SILK_SOURCES_FLOAT = \
+silk/float/apply_sine_window_FLP.c \
+silk/float/corrMatrix_FLP.c \
+silk/float/encode_frame_FLP.c \
+silk/float/find_LPC_FLP.c \
+silk/float/find_LTP_FLP.c \
+silk/float/find_pitch_lags_FLP.c \
+silk/float/find_pred_coefs_FLP.c \
+silk/float/LPC_analysis_filter_FLP.c \
+silk/float/LTP_analysis_filter_FLP.c \
+silk/float/LTP_scale_ctrl_FLP.c \
+silk/float/noise_shape_analysis_FLP.c \
+silk/float/prefilter_FLP.c \
+silk/float/process_gains_FLP.c \
+silk/float/regularize_correlations_FLP.c \
+silk/float/residual_energy_FLP.c \
+silk/float/solve_LS_FLP.c \
+silk/float/warped_autocorrelation_FLP.c \
+silk/float/wrappers_FLP.c \
+silk/float/autocorrelation_FLP.c \
+silk/float/burg_modified_FLP.c \
+silk/float/bwexpander_FLP.c \
+silk/float/energy_FLP.c \
+silk/float/inner_product_FLP.c \
+silk/float/k2a_FLP.c \
+silk/float/levinsondurbin_FLP.c \
+silk/float/LPC_inv_pred_gain_FLP.c \
+silk/float/pitch_analysis_core_FLP.c \
+silk/float/scale_copy_vector_FLP.c \
+silk/float/scale_vector_FLP.c \
+silk/float/schur_FLP.c \
+silk/float/sort_FLP.c
diff --git a/src/opus_compare.c b/src/opus_compare.c
index b8a1620..06c67d7 100644
--- a/src/opus_compare.c
+++ b/src/opus_compare.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2011-2012 Xiph.Org Foundation, Mozilla Corporation
+ Written by Jean-Marc Valin and 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.
+*/
+
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index f0188cd..ad5f747 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -30,7 +30,7 @@
#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."
+#error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you need other defines as well, as in a config.h. See the included build files for details."
#endif
#include <stdarg.h>
@@ -64,6 +64,7 @@ struct OpusDecoder {
int prev_mode;
int frame_size;
int prev_redundancy;
+ int last_packet_duration;
opus_uint32 rangeFinal;
};
@@ -257,23 +258,10 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
}
}
- /* 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;
- }
+ /* For CELT/hybrid PLC of more than 20 ms, opus_decode_native() will do
+ multiple calls */
+ if (data==NULL && mode != MODE_SILK_ONLY)
+ frame_size = IMIN(frame_size, F20);
ALLOC(pcm_transition, F5*st->channels, opus_val16);
if (data!=NULL && st->prev_mode > 0 && (
@@ -560,7 +548,7 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
int cbr;
unsigned char ch, toc;
int framesize;
- int last_size;
+ opus_int32 last_size;
const unsigned char *data0 = data;
if (size==NULL)
@@ -586,7 +574,9 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
{
if (len&0x1)
return OPUS_INVALID_PACKET;
- size[0] = last_size = len/2;
+ last_size = len/2;
+ /* If last_size doesn't fit in size[0], we'll catch it later */
+ size[0] = (short)last_size;
}
break;
/* Two VBR frames */
@@ -647,7 +637,7 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
if (last_size*count!=len)
return OPUS_INVALID_PACKET;
for (i=0;i<count-1;i++)
- size[i] = last_size;
+ size[i] = (short)last_size;
}
break;
}
@@ -675,7 +665,7 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
1275. Reject them here.*/
if (last_size > 1275)
return OPUS_INVALID_PACKET;
- size[count-1] = last_size;
+ size[count-1] = (short)last_size;
}
if (frames)
@@ -712,30 +702,81 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
int count, offset;
unsigned char toc;
int tot_offset;
+ int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
/* 48 x 2.5 ms = 120 ms */
short size[48];
if (decode_fec<0 || decode_fec>1)
return OPUS_BAD_ARG;
+ /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
+ if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0)
+ return OPUS_BAD_ARG;
if (len==0 || data==NULL)
- return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0);
- else if (len<0)
+ {
+ int pcm_count=0;
+ do {
+ int ret;
+ ret = opus_decode_frame(st, NULL, 0, pcm, frame_size-pcm_count, 0);
+ if (ret<0)
+ return ret;
+ pcm += st->channels*ret;
+ pcm_count += ret;
+ } while (pcm_count < frame_size);
+ st->last_packet_duration = pcm_count;
+ return pcm_count;
+ } 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);
+ packet_mode = opus_packet_get_mode(data);
+ packet_bandwidth = opus_packet_get_bandwidth(data);
+ packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
+ packet_stream_channels = opus_packet_get_nb_channels(data);
count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset);
+
+ data += offset;
+
+ if (decode_fec)
+ {
+ int duration_copy;
+ int ret;
+ /* If no FEC can be present, run the PLC (recursive call) */
+ if (frame_size <= packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY)
+ return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL);
+ /* Otherwise, run the PLC on everything except the size for which we might have FEC */
+ duration_copy = st->last_packet_duration;
+ ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL);
+ if (ret<0)
+ {
+ st->last_packet_duration = duration_copy;
+ return ret;
+ }
+ /* Complete with FEC */
+ st->mode = packet_mode;
+ st->bandwidth = packet_bandwidth;
+ st->frame_size = packet_frame_size;
+ st->stream_channels = packet_stream_channels;
+ ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size),
+ packet_frame_size, 1);
+ if (ret<0)
+ return ret;
+ st->last_packet_duration = frame_size;
+ return frame_size;
+ }
+ tot_offset = 0;
if (count < 0)
return count;
- data += offset;
tot_offset += offset;
- if (count*st->frame_size > frame_size)
+ if (count*packet_frame_size > frame_size)
return OPUS_BUFFER_TOO_SMALL;
+
+ /* Update the state as the last step to avoid updating it on an invalid packet */
+ st->mode = packet_mode;
+ st->bandwidth = packet_bandwidth;
+ st->frame_size = packet_frame_size;
+ st->stream_channels = packet_stream_channels;
+
nb_samples=0;
for (i=0;i<count;i++)
{
@@ -750,6 +791,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
}
if (packet_offset != NULL)
*packet_offset = tot_offset;
+ st->last_packet_duration = nb_samples;
return nb_samples;
}
@@ -903,6 +945,12 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
st->decode_gain = value;
}
break;
+ case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
+ {
+ opus_uint32 *value = va_arg(ap, opus_uint32*);
+ *value = st->last_packet_duration;
+ }
+ break;
default:
/*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
ret = OPUS_UNIMPLEMENTED;
@@ -979,8 +1027,8 @@ int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len)
return packet[1]&0x3F;
}
-int opus_decoder_get_nb_samples(const OpusDecoder *dec,
- const unsigned char packet[], opus_int32 len)
+int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len,
+ opus_int32 Fs)
{
int samples;
int count = opus_packet_get_nb_frames(packet, len);
@@ -988,10 +1036,16 @@ int opus_decoder_get_nb_samples(const OpusDecoder *dec,
if (count<0)
return count;
- samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs);
+ samples = count*opus_packet_get_samples_per_frame(packet, Fs);
/* Can't have more than 120 ms */
- if (samples*25 > dec->Fs*3)
+ if (samples*25 > Fs*3)
return OPUS_INVALID_PACKET;
else
return samples;
}
+
+int opus_decoder_get_nb_samples(const OpusDecoder *dec,
+ const unsigned char packet[], opus_int32 len)
+{
+ return opus_packet_get_nb_samples(packet, len, dec->Fs);
+}
diff --git a/src/opus_demo.c b/src/opus_demo.c
index 20bebba..09b12a3 100644
--- a/src/opus_demo.c
+++ b/src/opus_demo.c
@@ -95,7 +95,7 @@ static void check_encoder_option(int decode_only, const char *opt)
}
}
-int silk8_test[][4] = {
+static const int silk8_test[][4] = {
{MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1},
@@ -106,7 +106,7 @@ int silk8_test[][4] = {
{MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2}
};
-int silk12_test[][4] = {
+static const int silk12_test[][4] = {
{MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 1},
@@ -117,7 +117,7 @@ int silk12_test[][4] = {
{MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 2}
};
-int silk16_test[][4] = {
+static const int silk16_test[][4] = {
{MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1},
@@ -128,21 +128,21 @@ int silk16_test[][4] = {
{MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2}
};
-int hybrid24_test[][4] = {
+static const int hybrid24_test[][4] = {
{MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}
};
-int hybrid48_test[][4] = {
+static const int hybrid48_test[][4] = {
{MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
{MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}
};
-int celt_test[][4] = {
+static const int celt_test[][4] = {
{MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
{MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
{MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1},
@@ -185,7 +185,7 @@ int celt_test[][4] = {
};
-int celt_hq_test[][4] = {
+static const int celt_hq_test[][4] = {
{MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
{MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2},
{MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2},
@@ -234,7 +234,7 @@ int main(int argc, char *argv[])
int random_framesize=0, newsize=0, delayed_celt=0;
int sweep_max=0, sweep_min=0;
int random_fec=0;
- int (*mode_list)[4]=NULL;
+ const int (*mode_list)[4]=NULL;
int nb_modes_in_list=0;
int curr_mode=0;
int curr_mode_count=0;
@@ -684,18 +684,22 @@ int main(int argc, char *argv[])
} else {
int output_samples;
lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
+ if (lost)
+ opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
+ else
+ output_samples = max_frame_size;
if( count >= use_inbandfec ) {
/* delay by one packet when using in-band FEC */
if( use_inbandfec ) {
if( lost_prev ) {
/* attempt to decode with in-band FEC from next packet */
- output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 1);
+ output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1);
} else {
/* regular decode */
- output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, max_frame_size, 0);
+ output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0);
}
} else {
- output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 0);
+ output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0);
}
if (output_samples>0)
{
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index b77e48e..aae3125 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -291,7 +291,7 @@ static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channel
}
#ifndef FIXED_POINT
-void silk_biquad_float(
+static void silk_biquad_float(
const opus_val16 *in, /* I: Input signal */
const opus_int32 *B_Q28, /* I: MA coefficients [3] */
const opus_int32 *A_Q28, /* I: AR coefficients [2] */
@@ -458,20 +458,20 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
int prefill=0;
int start_band = 0;
int redundancy = 0;
- int redundancy_bytes = 0;
+ int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */
int celt_to_silk = 0;
VARDECL(opus_val16, pcm_buf);
int nb_compr_bytes;
int to_celt = 0;
opus_uint32 redundant_rng = 0;
int cutoff_Hz, hp_freq_smth1;
- int voice_est;
+ int voice_est; /* Probability of voice in Q7 */
opus_int32 equiv_rate;
int delay_compensation;
int frame_rate;
- opus_int32 max_rate;
+ opus_int32 max_rate; /* Max bitrate we're allowed to use */
int curr_bandwidth;
- opus_int32 max_data_bytes;
+ opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */
VARDECL(opus_val16, tmp_prefill);
ALLOC_STACK;
@@ -652,6 +652,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
}
}
}
+ /* For the first frame at a new SILK bandwidth */
if (st->silk_bw_switch)
{
redundancy = 1;
@@ -659,6 +660,15 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
st->silk_bw_switch = 0;
}
+ if (redundancy)
+ {
+ /* Fair share of the max size allowed */
+ redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200));
+ /* For VBR, target the actual bitrate (subject to the limit above) */
+ if (st->use_vbr)
+ redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600);
+ }
+
if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
{
silk_EncControlStruct dummy;
@@ -823,7 +833,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
st->mode = MODE_SILK_ONLY;
/* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
- bytes_target = IMIN(max_data_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
+ bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
data += 1;
@@ -929,7 +939,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
st->silk_mode.useCBR = !st->use_vbr;
/* Call SILK encoder for the low band */
- nBytes = IMIN(1275, max_data_bytes-1);
+ nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes);
st->silk_mode.maxBits = nBytes*8;
/* Only allow up to 90% of the bits for hybrid mode*/
@@ -941,8 +951,6 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
/* Reduce the initial target to make it easier to reach the CBR rate */
st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000);
}
- if (redundancy)
- st->silk_mode.maxBits -= st->silk_mode.maxBits/(1 + frame_size/(st->Fs/200));
if (prefill)
{
@@ -990,6 +998,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
}
st->silk_mode.opusCanSwitch = st->silk_mode.switchReady;
+ /* FIXME: How do we allocate the redundancy for CBR? */
if (st->silk_mode.opusCanSwitch)
{
redundancy = 1;
@@ -1047,7 +1056,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1));
celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint));
celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps));
- nb_compr_bytes = max_data_bytes-1;
+ nb_compr_bytes = max_data_bytes-1-redundancy_bytes;
} else {
nb_compr_bytes = bytes_target;
}
@@ -1119,8 +1128,10 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
}
if (!redundancy)
+ {
st->silk_bw_switch = 0;
-
+ redundancy_bytes = 0;
+ }
if (st->mode != MODE_CELT_ONLY)start_band=17;
if (st->mode == MODE_SILK_ONLY)
diff --git a/src/opus_multistream.c b/src/opus_multistream.c
index 955dc81..a7f25a5 100644
--- a/src/opus_multistream.c
+++ b/src/opus_multistream.c
@@ -159,7 +159,7 @@ int opus_multistream_encoder_init(
{
int coupled_size;
int mono_size;
- int i;
+ int i, ret;
char *ptr;
if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
@@ -180,12 +180,14 @@ int opus_multistream_encoder_init(
for (i=0;i<st->layout.nb_coupled_streams;i++)
{
- opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
+ ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
+ if(ret!=OPUS_OK)return ret;
ptr += align(coupled_size);
}
for (;i<st->layout.nb_streams;i++)
{
- opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
+ ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
+ if(ret!=OPUS_OK)return ret;
ptr += align(mono_size);
}
return OPUS_OK;
@@ -202,7 +204,15 @@ OpusMSEncoder *opus_multistream_encoder_create(
)
{
int ret;
- OpusMSEncoder *st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
+ OpusMSEncoder *st;
+ if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
+ (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
+ {
+ if (error)
+ *error = OPUS_BAD_ARG;
+ return NULL;
+ }
+ st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
if (st==NULL)
{
if (error)
@@ -647,7 +657,15 @@ OpusMSDecoder *opus_multistream_decoder_create(
)
{
int ret;
- OpusMSDecoder *st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
+ OpusMSDecoder *st;
+ if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
+ (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
+ {
+ if (error)
+ *error = OPUS_BAD_ARG;
+ return NULL;
+ }
+ st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
if (st==NULL)
{
if (error)
@@ -663,8 +681,6 @@ OpusMSDecoder *opus_multistream_decoder_create(
st = NULL;
}
return st;
-
-
}
typedef void (*opus_copy_channel_out_func)(
@@ -908,6 +924,8 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
{
case OPUS_GET_BANDWIDTH_REQUEST:
case OPUS_GET_SAMPLE_RATE_REQUEST:
+ case OPUS_GET_GAIN_REQUEST:
+ case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
{
OpusDecoder *dec;
/* For int32* GET params, just query the first stream */
diff --git a/tests/run_vectors.sh b/tests/run_vectors.sh
index 3e021af..1cc445d 100755
--- a/tests/run_vectors.sh
+++ b/tests/run_vectors.sh
@@ -1,5 +1,38 @@
#!/bin/sh
+# Copyright (c) 2011-2012 Jean-Marc Valin
+#
+# This file is extracted from RFC6716. Please see that RFC for additional
+# information.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# - Neither the name of Internet Society, IETF or IETF Trust, nor the
+# names of specific contributors, may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 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.
+
rm logs_mono.txt
rm logs_stereo.txt
diff --git a/tests/test_opus_api.c b/tests/test_opus_api.c
index b5348c3..c2d7e10 100644
--- a/tests/test_opus_api.c
+++ b/tests/test_opus_api.c
@@ -126,6 +126,9 @@ opus_int32 test_dec_api(void)
dec = opus_decoder_create(fs, c, &err);
if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
cfgs++;
+ dec = opus_decoder_create(fs, c, 0);
+ if(dec!=NULL)test_failed();
+ cfgs++;
dec=malloc(opus_decoder_get_size(2));
if(dec==NULL)test_failed();
err = opus_decoder_init(dec,fs,c);
@@ -224,12 +227,19 @@ opus_int32 test_dec_api(void)
VG_UNDEF(packet,sizeof(packet));
packet[0]=0;
if(opus_decoder_get_nb_samples(dec,packet,1)!=480)test_failed();
- cfgs++;
+ if(opus_packet_get_nb_samples(packet,1,48000)!=480)test_failed();
+ if(opus_packet_get_nb_samples(packet,1,96000)!=960)test_failed();
+ if(opus_packet_get_nb_samples(packet,1,32000)!=320)test_failed();
+ if(opus_packet_get_nb_samples(packet,1,8000)!=80)test_failed();
+ packet[0]=3;
+ if(opus_packet_get_nb_samples(packet,1,24000)!=OPUS_INVALID_PACKET)test_failed();
packet[0]=(63<<2)|3;
packet[1]=63;
+ if(opus_packet_get_nb_samples(packet,0,24000)!=OPUS_BAD_ARG)test_failed();
+ if(opus_packet_get_nb_samples(packet,2,48000)!=OPUS_INVALID_PACKET)test_failed();
if(opus_decoder_get_nb_samples(dec,packet,2)!=OPUS_INVALID_PACKET)test_failed();
- fprintf(stdout," opus_decoder_get_nb_samples() ................ OK.\n");
- cfgs++;
+ fprintf(stdout," opus_{packet,decoder}_get_nb_samples() ....... OK.\n");
+ cfgs+=9;
if(OPUS_BAD_ARG!=opus_packet_get_nb_frames(packet,0))test_failed();
for(i=0;i<256;i++) {
@@ -366,6 +376,9 @@ opus_int32 test_msdec_api(void)
dec = opus_multistream_decoder_create(fs, c, 1, c-1, mapping, &err);
if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
cfgs++;
+ dec = opus_multistream_decoder_create(fs, c, 1, c-1, mapping, 0);
+ if(dec!=NULL)test_failed();
+ cfgs++;
dec=malloc(opus_multistream_decoder_get_size(1,1));
if(dec==NULL)test_failed();
err = opus_multistream_decoder_init(dec,fs,c,1,c-1, mapping);
@@ -375,116 +388,128 @@ opus_int32 test_msdec_api(void)
}
}
- VG_UNDEF(&err,sizeof(err));
- dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err==OPUS_OK || dec!=NULL)test_failed();
- cfgs++;
+ for(c=0;c<2;c++)
+ {
+ int *ret_err;
+ ret_err = c?0:&err;
- VG_UNDEF(&err,sizeof(err));
- mapping[0]=mapping[1]=0;
- dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_OK || dec==NULL)test_failed();
- cfgs++;
- opus_multistream_decoder_destroy(dec);
- cfgs++;
+ mapping[0]=0;
+ mapping[1]=1;
+ for(i=2;i<256;i++)VG_UNDEF(&mapping[i],sizeof(unsigned char));
- VG_UNDEF(&err,sizeof(err));
- dec = opus_multistream_decoder_create(48000, 1, 4, 1, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_OK || dec==NULL)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+ cfgs++;
- err = opus_multistream_decoder_init(dec,48000, 1, 0, 0, mapping);
- if(err!=OPUS_BAD_ARG)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ mapping[0]=mapping[1]=0;
+ dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();
+ cfgs++;
+ opus_multistream_decoder_destroy(dec);
+ cfgs++;
- err = opus_multistream_decoder_init(dec,48000, 1, 1, -1, mapping);
- if(err!=OPUS_BAD_ARG)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ dec = opus_multistream_decoder_create(48000, 1, 4, 1, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();
+ cfgs++;
- opus_multistream_decoder_destroy(dec);
- cfgs++;
+ err = opus_multistream_decoder_init(dec,48000, 1, 0, 0, mapping);
+ if(err!=OPUS_BAD_ARG)test_failed();
+ cfgs++;
- VG_UNDEF(&err,sizeof(err));
- dec = opus_multistream_decoder_create(48000, 2, 1, 1, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_OK || dec==NULL)test_failed();
- cfgs++;
- opus_multistream_decoder_destroy(dec);
- cfgs++;
+ err = opus_multistream_decoder_init(dec,48000, 1, 1, -1, mapping);
+ if(err!=OPUS_BAD_ARG)test_failed();
+ cfgs++;
- VG_UNDEF(&err,sizeof(err));
- dec = opus_multistream_decoder_create(48000, 255, 255, 1, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
- cfgs++;
+ opus_multistream_decoder_destroy(dec);
+ cfgs++;
- VG_UNDEF(&err,sizeof(err));
- dec = opus_multistream_decoder_create(48000, -1, 1, 1, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ dec = opus_multistream_decoder_create(48000, 2, 1, 1, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();
+ cfgs++;
+ opus_multistream_decoder_destroy(dec);
+ cfgs++;
- VG_UNDEF(&err,sizeof(err));
- dec = opus_multistream_decoder_create(48000, 0, 1, 1, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ dec = opus_multistream_decoder_create(48000, 255, 255, 1, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+ cfgs++;
- VG_UNDEF(&err,sizeof(err));
- dec = opus_multistream_decoder_create(48000, 1, -1, 2, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ dec = opus_multistream_decoder_create(48000, -1, 1, 1, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+ cfgs++;
- VG_UNDEF(&err,sizeof(err));
- dec = opus_multistream_decoder_create(48000, 1, -1, -1, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ dec = opus_multistream_decoder_create(48000, 0, 1, 1, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+ cfgs++;
- VG_UNDEF(&err,sizeof(err));
- dec = opus_multistream_decoder_create(48000, 256, 255, 1, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ dec = opus_multistream_decoder_create(48000, 1, -1, 2, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+ cfgs++;
- VG_UNDEF(&err,sizeof(err));
- dec = opus_multistream_decoder_create(48000, 256, 255, 0, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ dec = opus_multistream_decoder_create(48000, 1, -1, -1, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+ cfgs++;
- VG_UNDEF(&err,sizeof(err));
- mapping[0]=255;
- mapping[1]=1;
- mapping[2]=2;
- dec = opus_multistream_decoder_create(48000, 3, 2, 0, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ dec = opus_multistream_decoder_create(48000, 256, 255, 1, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+ cfgs++;
- VG_UNDEF(&err,sizeof(err));
- mapping[0]=0;
- mapping[1]=0;
- mapping[2]=0;
- dec = opus_multistream_decoder_create(48000, 3, 2, 1, mapping, &err);
- VG_CHECK(&err,sizeof(err));
- if(err!=OPUS_OK || dec==NULL)test_failed();
- cfgs++;
- opus_multistream_decoder_destroy(dec);
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ dec = opus_multistream_decoder_create(48000, 256, 255, 0, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+ cfgs++;
- mapping[0]=0;
- mapping[1]=255;
- mapping[2]=1;
- mapping[3]=2;
- mapping[4]=3;
- dec = opus_multistream_decoder_create(48001, 5, 4, 1, mapping, 0);
- if(dec!=NULL)test_failed();
- cfgs++;
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ mapping[0]=255;
+ mapping[1]=1;
+ mapping[2]=2;
+ dec = opus_multistream_decoder_create(48000, 3, 2, 0, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+ cfgs++;
+
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ mapping[0]=0;
+ mapping[1]=0;
+ mapping[2]=0;
+ dec = opus_multistream_decoder_create(48000, 3, 2, 1, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();
+ cfgs++;
+ opus_multistream_decoder_destroy(dec);
+ cfgs++;
+
+ VG_UNDEF(ret_err,sizeof(*ret_err));
+ mapping[0]=0;
+ mapping[1]=255;
+ mapping[2]=1;
+ mapping[3]=2;
+ mapping[4]=3;
+ dec = opus_multistream_decoder_create(48001, 5, 4, 1, mapping, ret_err);
+ if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+ if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+ cfgs++;
+ }
VG_UNDEF(&err,sizeof(err));
mapping[0]=0;
@@ -1061,6 +1086,9 @@ opus_int32 test_enc_api(void)
enc = opus_encoder_create(fs, c, OPUS_APPLICATION_VOIP, &err);
if(err!=OPUS_BAD_ARG || enc!=NULL)test_failed();
cfgs++;
+ enc = opus_encoder_create(fs, c, OPUS_APPLICATION_VOIP, 0);
+ if(enc!=NULL)test_failed();
+ cfgs++;
opus_encoder_destroy(enc);
enc=malloc(opus_encoder_get_size(2));
if(enc==NULL)test_failed();
@@ -1538,7 +1566,7 @@ int test_repacketizer_api(void)
#ifdef MALLOC_FAIL
/* GLIBC 2.14 declares __malloc_hook as deprecated, generating a warning
* under GCC. However, this is the cleanest way to test malloc failure
- * handling in our codebase, and the lack of thread saftey isn't an
+ * handling in our codebase, and the lack of thread safety isn't an
* issue here. We therefore disable the warning for this function.
*/
#if OPUS_GNUC_PREREQ(4,6)
diff --git a/tests/test_opus_decode.c b/tests/test_opus_decode.c
index 2c6a872..e2c04c2 100644
--- a/tests/test_opus_decode.c
+++ b/tests/test_opus_decode.c
@@ -38,13 +38,15 @@
#include <time.h>
#if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__)
#include <unistd.h>
+#else
+#include <process.h>
+#define getpid _getpid
#endif
#include "opus.h"
#include "test_opus_common.h"
#define MAX_PACKET (1500)
#define MAX_FRAME_SAMP (5760)
-extern int jackpot;
int test_decoder_code0(int no_fuzz)
{
@@ -102,22 +104,27 @@ int test_decoder_code0(int no_fuzz)
int factor=48000/fsv[t>>1];
for(fec=0;fec<2;fec++)
{
+ int dur;
/*Test PLC on a fresh decoder*/
- out_samples = opus_decode(dec[t], 0, 0, outbuf, MAX_FRAME_SAMP, fec);
+ out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, fec);
if(out_samples!=120/factor)test_failed();
+ if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+ if(dur!=120/factor)test_failed();
/*Test null pointer input*/
- out_samples = opus_decode(dec[t], 0, -1, outbuf, MAX_FRAME_SAMP, fec);
+ out_samples = opus_decode(dec[t], 0, -1, outbuf, 120/factor, fec);
if(out_samples!=120/factor)test_failed();
- out_samples = opus_decode(dec[t], 0, 1, outbuf, MAX_FRAME_SAMP, fec);
+ out_samples = opus_decode(dec[t], 0, 1, outbuf, 120/factor, fec);
if(out_samples!=120/factor)test_failed();
- out_samples = opus_decode(dec[t], 0, 10, outbuf, MAX_FRAME_SAMP, fec);
+ out_samples = opus_decode(dec[t], 0, 10, outbuf, 120/factor, fec);
if(out_samples!=120/factor)test_failed();
- out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, MAX_FRAME_SAMP, fec);
+ out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, 120/factor, fec);
if(out_samples!=120/factor)test_failed();
+ if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+ if(dur!=120/factor)test_failed();
/*Zero lengths*/
- out_samples = opus_decode(dec[t], packet, 0, outbuf, MAX_FRAME_SAMP, fec);
+ out_samples = opus_decode(dec[t], packet, 0, outbuf, 120/factor, fec);
if(out_samples!=120/factor)test_failed();
/*Zero buffer*/
@@ -149,6 +156,7 @@ int test_decoder_code0(int no_fuzz)
/*Count code 0 tests*/
for(i=0;i<64;i++)
{
+ int dur;
int j,expected[5*2];
packet[0]=i<<2;
packet[1]=255;
@@ -168,6 +176,8 @@ int test_decoder_code0(int no_fuzz)
{
out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0);
if(out_samples!=expected[t])test_failed();
+ if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+ if(dur!=out_samples)test_failed();
opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
if(t==0)dec_final_range2=dec_final_range1;
else if(dec_final_range1!=dec_final_range2)test_failed();
@@ -179,8 +189,10 @@ int test_decoder_code0(int no_fuzz)
/* The PLC is run for 6 frames in order to get better PLC coverage. */
for(j=0;j<6;j++)
{
- out_samples = opus_decode(dec[t], 0, 0, outbuf, MAX_FRAME_SAMP, 0);
+ out_samples = opus_decode(dec[t], 0, 0, outbuf, expected[t], 0);
if(out_samples!=expected[t])test_failed();
+ if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+ if(dur!=out_samples)test_failed();
}
/* Run the PLC once at 2.5ms, as a simulation of someone trying to
do small drift corrections. */
@@ -188,6 +200,8 @@ int test_decoder_code0(int no_fuzz)
{
out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0);
if(out_samples!=120/factor)test_failed();
+ if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+ if(dur!=out_samples)test_failed();
}
out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0);
if(out_samples>0)test_failed();
@@ -289,17 +303,20 @@ int test_decoder_code0(int no_fuzz)
for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,plen);
for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
memcpy(decbak,dec[0],decsize);
- if(opus_decode(decbak, packet, plen+1, outbuf, MAX_FRAME_SAMP, 1)!=expected[0])test_failed();
+ if(opus_decode(decbak, packet, plen+1, outbuf, expected[0], 1)!=expected[0])test_failed();
memcpy(decbak,dec[0],decsize);
if(opus_decode(decbak, 0, 0, outbuf, MAX_FRAME_SAMP, 1)<20)test_failed();
memcpy(decbak,dec[0],decsize);
if(opus_decode(decbak, 0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed();
for(t=0;t<5*2;t++)
{
+ int dur;
out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
if(out_samples!=expected[t])test_failed();
if(t==0)dec_final_range2=dec_final_range1;
else if(dec_final_range1!=dec_final_range2)test_failed();
+ if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+ if(dur!=out_samples)test_failed();
}
}
fprintf(stdout," dec[all] random packets, all mode pairs (4096), %d bytes/frame OK.\n",plen+1);
diff --git a/tests/test_opus_encode.c b/tests/test_opus_encode.c
index ad63453..b80def3 100644
--- a/tests/test_opus_encode.c
+++ b/tests/test_opus_encode.c
@@ -38,6 +38,9 @@
#include <time.h>
#if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__)
#include <unistd.h>
+#else
+#include <process.h>
+#define getpid _getpid
#endif
#include "opus_multistream.h"
#include "opus.h"
@@ -141,11 +144,44 @@ int run_test1(int no_fuzz)
enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, &err);
if(err != OPUS_OK || enc==NULL)test_failed();
+ for(i=0;i<2;i++)
+ {
+ int *ret_err;
+ ret_err = i?0:&err;
+ MSenc = opus_multistream_encoder_create(8000, 2, 2, 0, mapping, OPUS_UNIMPLEMENTED, ret_err);
+ if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+
+ MSenc = opus_multistream_encoder_create(8000, 0, 1, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
+ if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+
+ MSenc = opus_multistream_encoder_create(44100, 2, 2, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
+ if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+
+ MSenc = opus_multistream_encoder_create(8000, 2, 2, 3, mapping, OPUS_APPLICATION_VOIP, ret_err);
+ if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+
+ MSenc = opus_multistream_encoder_create(8000, 2, -1, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
+ if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+
+ MSenc = opus_multistream_encoder_create(8000, 256, 2, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
+ if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+ }
+
MSenc = opus_multistream_encoder_create(8000, 2, 2, 0, mapping, OPUS_APPLICATION_AUDIO, &err);
if(err != OPUS_OK || MSenc==NULL)test_failed();
+ /*Some multistream encoder API tests*/
if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_BITRATE(&i))!=OPUS_OK)test_failed();
if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_LSB_DEPTH(&i))!=OPUS_OK)test_failed();
+ if(i<16)test_failed();
+
+ {
+ OpusEncoder *tmp_enc;
+ if(opus_multistream_encoder_ctl(MSenc, OPUS_MULTISTREAM_GET_ENCODER_STATE(1,&tmp_enc))!=OPUS_OK)test_failed();
+ if(opus_encoder_ctl(tmp_enc, OPUS_GET_LSB_DEPTH(&j))!=OPUS_OK)test_failed();
+ if(i!=j)test_failed();
+ if(opus_multistream_encoder_ctl(MSenc, OPUS_MULTISTREAM_GET_ENCODER_STATE(2,&tmp_enc))!=OPUS_BAD_ARG)test_failed();
+ }
dec = opus_decoder_create(48000, 2, &err);
if(err != OPUS_OK || dec==NULL)test_failed();
@@ -233,7 +269,7 @@ int run_test1(int no_fuzz)
if(opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range))!=OPUS_OK)test_failed();
if(enc_final_range!=dec_final_range)test_failed();
/*LBRR decode*/
- out_samples = opus_decode(dec_err[0], packet, len, out2buf, MAX_FRAME_SAMP, (fast_rand()&3)!=0);
+ out_samples = opus_decode(dec_err[0], packet, len, out2buf, frame_size, (fast_rand()&3)!=0);
if(out_samples!=frame_size)test_failed();
out_samples = opus_decode(dec_err[1], packet, (fast_rand()&3)==0?0:len, out2buf, MAX_FRAME_SAMP, (fast_rand()&7)!=0);
if(out_samples<120)test_failed();
@@ -281,8 +317,8 @@ int run_test1(int no_fuzz)
if(enc_final_range!=dec_final_range)test_failed();
/*LBRR decode*/
loss=(fast_rand()&63)==0;
- out_samples = opus_multistream_decode(MSdec_err, packet, loss?0:len, out2buf, MAX_FRAME_SAMP, (fast_rand()&3)!=0);
- if(loss?out_samples<120:out_samples!=(frame_size*6))test_failed();
+ out_samples = opus_multistream_decode(MSdec_err, packet, loss?0:len, out2buf, frame_size*6, (fast_rand()&3)!=0);
+ if(out_samples!=(frame_size*6))test_failed();
i+=frame_size;
count++;
}while(i<(SSAMPLES/12-MAX_FRAME_SAMP));
diff --git a/version.mk b/version.mk
new file mode 100644
index 0000000..ef30573
--- /dev/null
+++ b/version.mk
@@ -0,0 +1,2 @@
+# static version string; update manually every release.
+OPUS_VERSION = "1.0.2"
diff --git a/win32/config.h b/win32/config.h
index 6d32620..8450d23 100644
--- a/win32/config.h
+++ b/win32/config.h
@@ -1,10 +1,36 @@
+/***********************************************************************
+Copyright (c) 2011, Skype Limited. 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.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE 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 CONFIG_H
#define CONFIG_H
#define CELT_BUILD 1
#define inline __inline
-#define getpid _getpid
#define USE_ALLOCA 1