Added iSAC codec support based on lib WebRTC.
git-svn-id: http://voip.null.ro/svn/yate@4952 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
50e4c9521a
commit
1c60b4ba27
63
configure.in
63
configure.in
|
@ -314,6 +314,35 @@ AC_MSG_RESULT([$want_atomics])
|
|||
fi
|
||||
AC_SUBST(ATOMIC_OPS)
|
||||
|
||||
|
||||
# Check for sse2 operations
|
||||
SSE2_OPS=no
|
||||
AC_ARG_ENABLE(sse2,AC_HELP_STRING([--enable-sse2],[Enable sse2 operations (default: no)]),want_sse2=$enableval,want_sse2=no)
|
||||
AC_MSG_CHECKING([whether to use sse2 operations])
|
||||
if [[ "x$want_sse2" != "xno" ]]; then
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_C
|
||||
SAVE_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Wall -Werror -msse2"
|
||||
AC_TRY_LINK([#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include<emmintrin.h>
|
||||
],[
|
||||
float ef[2][2];
|
||||
const __m128 k1e_10f = _mm_set1_ps(1e-10f);
|
||||
_mm_storeu_ps(&ef[0][0], k1e_10f);
|
||||
return (int) ef[0][0];
|
||||
],
|
||||
SSE2_OPS="yes",
|
||||
want_sse2="no (missing -march ?)"
|
||||
)
|
||||
CFLAGS="$SAVE_CFLAGS"
|
||||
AC_LANG_RESTORE
|
||||
fi
|
||||
AC_MSG_RESULT([$want_sse2])
|
||||
AC_SUBST(SSE2_OPS)
|
||||
|
||||
|
||||
FDSIZE_HACK=""
|
||||
AC_ARG_WITH(fdsize,AC_HELP_STRING([--with-fdsize=NNNN],[set FD_SIZE to NNNN (default 8192)]),[ac_cv_use_fdsize=$withval],[ac_cv_use_fdsize=8192])
|
||||
if [[ "x$ac_cv_use_fdsize" != "xno" ]]; then
|
||||
|
@ -788,6 +817,39 @@ fi
|
|||
AC_SUBST(HAVE_ILBC)
|
||||
AC_SUBST(ILBC_INC)
|
||||
|
||||
HAVE_ISAC=no
|
||||
ISAC_INC=""
|
||||
AC_ARG_ENABLE(isac-float,AC_HELP_STRING([--enable-isac-float],[Enable iSAC float codec (default: yes)]),want_isac=$enableval,want_isac=yes)
|
||||
if [[ "x$want_isac" = "xyes" ]]; then
|
||||
AC_MSG_CHECKING([for iSAC in libs])
|
||||
basedir=`cd "$srcdir" && pwd`
|
||||
incisac="libs/miniwebrtc/audio/coding_isac/main"
|
||||
if [[ -f "$basedir/$incisac/isac.h" ]]; then
|
||||
HAVE_ISAC=yes
|
||||
basedir=`echo "$basedir" | sed 's/\([[^\]]\)\([[[:space:]\$\"'\'']]\)/\1\\\2/g'`
|
||||
ISAC_INC="-I$basedir/$incisac"
|
||||
fi
|
||||
AC_MSG_RESULT([$HAVE_ISAC])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(isac-fixed,AC_HELP_STRING([--enable-isac-fixed],[Enable iSAC fixed codec (default: no)]),want_isac_fixed=$enableval,want_isac_fixed=no)
|
||||
if [[ "x$want_isac_fixed" = "xyes" ]]; then
|
||||
if [[ x$HAVE_ISAC = "xyes" ]]; then
|
||||
AC_ERROR([iSAC Fixed and iSAC Float can not be enabled both at the same time])
|
||||
else
|
||||
AC_MSG_CHECKING([for iSAC fixed in libs])
|
||||
basedir=`cd "$srcdir" && pwd`
|
||||
incisac="libs/miniwebrtc/audio/coding_isac/fix"
|
||||
if [[ -f "$basedir/$incisac/isacfix.h" ]]; then
|
||||
HAVE_ISAC=yes
|
||||
basedir=`echo "$basedir" | sed 's/\([[^\]]\)\([[[:space:]\$\"'\'']]\)/\1\\\2/g'`
|
||||
ISAC_INC="-I$basedir/$incisac -DISAC_FIXED"
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT([$HAVE_ISAC])
|
||||
fi
|
||||
AC_SUBST(HAVE_ISAC)
|
||||
AC_SUBST(ISAC_INC)
|
||||
|
||||
HAVE_SPEEX=no
|
||||
SPEEX_INC=""
|
||||
|
@ -1424,6 +1486,7 @@ AC_CONFIG_FILES([packing/rpm/yate.spec
|
|||
libs/ymodem/Makefile
|
||||
libs/yasn/Makefile
|
||||
libs/ysnmp/Makefile
|
||||
libs/miniwebrtc/Makefile
|
||||
share/Makefile
|
||||
share/scripts/Makefile
|
||||
share/skins/Makefile
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
# Makefile
|
||||
# This file holds the make rules for the libyatexml
|
||||
|
||||
DEBUG :=
|
||||
|
||||
CXX := @CXX@ -Wall
|
||||
CC := @CC@ -Wall
|
||||
AR := ar
|
||||
DEFS :=
|
||||
INCLUDES := -I@srcdir@ -I@srcdir@/audio/common/processing \
|
||||
-I@srcdir@/audio/common/vad -I@srcdir@/audio/processing/aec \
|
||||
-I@srcdir@/audio/processing/aecm -I@srcdir@/audio/processing/agc \
|
||||
-I@srcdir@/audio/processing/ns -I@srcdir@/audio/processing/utility \
|
||||
-I@srcdir@/system_wrappers
|
||||
|
||||
CFLAGS := @CFLAGS@ @MODULE_CFLAGS@ @INLINE_FLAGS@ -DWEBRTC_NS_FLOAT=true
|
||||
CPPFLAGS := @CFLAGS@ @MODULE_CPPFLAGS@ @INLINE_FLAGS@ -DWEBRTC_NS_FLOAT=true
|
||||
LDFLAGS:= @LDFLAGS@
|
||||
|
||||
LIBS = libminiwebrtc.a
|
||||
OBJS := audio/common/resampler/resampler.o \
|
||||
audio/common/processing/auto_correlation.o \
|
||||
audio/common/processing/auto_corr_to_refl_coef.o \
|
||||
audio/common/processing/complex_bit_reverse.o \
|
||||
audio/common/processing/complex_fft.o \
|
||||
audio/common/processing/copy_set_operations.o \
|
||||
audio/common/processing/cross_correlation.o \
|
||||
audio/common/processing/division_operations.o \
|
||||
audio/common/processing/dot_product_with_scale.o \
|
||||
audio/common/processing/downsample_fast.o \
|
||||
audio/common/processing/energy.o \
|
||||
audio/common/processing/filter_ar.o \
|
||||
audio/common/processing/filter_ar_fast_q12.o \
|
||||
audio/common/processing/filter_ma_fast_q12.o \
|
||||
audio/common/processing/get_hanning_window.o \
|
||||
audio/common/processing/get_scaling_square.o \
|
||||
audio/common/processing/ilbc_specific_functions.o \
|
||||
audio/common/processing/levinson_durbin.o \
|
||||
audio/common/processing/lpc_to_refl_coef.o \
|
||||
audio/common/processing/min_max_operations.o \
|
||||
audio/common/processing/randomization_functions.o \
|
||||
audio/common/processing/refl_coef_to_lpc.o \
|
||||
audio/common/processing/resample.o \
|
||||
audio/common/processing/resample_48khz.o \
|
||||
audio/common/processing/resample_by_2.o \
|
||||
audio/common/processing/resample_by_2_internal.o \
|
||||
audio/common/processing/resample_fractional.o \
|
||||
audio/common/processing/splitting_filter.o \
|
||||
audio/common/processing/spl_sqrt.o \
|
||||
audio/common/processing/spl_sqrt_floor.o \
|
||||
audio/common/processing/spl_version.o \
|
||||
audio/common/processing/sqrt_of_one_minus_x_squared.o \
|
||||
audio/common/processing/vector_scaling_operations.o \
|
||||
audio/common/processing/webrtc_fft_t_1024_8.o \
|
||||
audio/common/processing/webrtc_fft_t_rad.o \
|
||||
audio/common/vad/vad_core.o \
|
||||
audio/common/vad/vad_filterbank.o \
|
||||
audio/common/vad/vad_gmm.o \
|
||||
audio/common/vad/vad_sp.o \
|
||||
audio/common/vad/webrtc_vad.o \
|
||||
audio/coding_isac/fix/arith_routines.o \
|
||||
audio/coding_isac/fix/arith_routines_hist.o \
|
||||
audio/coding_isac/fix/arith_routines_logist.o \
|
||||
audio/coding_isac/fix/bandwidth_estimator.o \
|
||||
audio/coding_isac/fix/decode.o \
|
||||
audio/coding_isac/fix/decode_bwe.o \
|
||||
audio/coding_isac/fix/decode_plc.o \
|
||||
audio/coding_isac/fix/encode.o \
|
||||
audio/coding_isac/fix/entropy_coding.o \
|
||||
audio/coding_isac/fix/fft.o \
|
||||
audio/coding_isac/fix/filterbanks.o \
|
||||
audio/coding_isac/fix/filterbank_tables.o \
|
||||
audio/coding_isac/fix/filters.o \
|
||||
audio/coding_isac/fix/initialize.o \
|
||||
audio/coding_isac/fix/isacfix.o \
|
||||
audio/coding_isac/fix/lattice.o \
|
||||
audio/coding_isac/fix/lattice_c.o \
|
||||
audio/coding_isac/fix/lpc_masking_model.o \
|
||||
audio/coding_isac/fix/lpc_tables.o \
|
||||
audio/coding_isac/fix/pitch_estimator.o \
|
||||
audio/coding_isac/fix/pitch_filter.o \
|
||||
audio/coding_isac/fix/pitch_gain_tables.o \
|
||||
audio/coding_isac/fix/pitch_lag_tables.o \
|
||||
audio/coding_isac/fix/spectrum_ar_model_tables.o \
|
||||
audio/coding_isac/fix/transform.o \
|
||||
audio/coding_isac/main/arith_routines.o \
|
||||
audio/coding_isac/main/arith_routines_hist.o \
|
||||
audio/coding_isac/main/arith_routines_logist.o \
|
||||
audio/coding_isac/main/bandwidth_estimator.o \
|
||||
audio/coding_isac/main/crc.o \
|
||||
audio/coding_isac/main/decode.o \
|
||||
audio/coding_isac/main/decode_bwe.o \
|
||||
audio/coding_isac/main/encode.o \
|
||||
audio/coding_isac/main/encode_lpc_swb.o \
|
||||
audio/coding_isac/main/entropy_coding.o \
|
||||
audio/coding_isac/main/fft.o \
|
||||
audio/coding_isac/main/filterbanks.o \
|
||||
audio/coding_isac/main/filterbank_tables.o \
|
||||
audio/coding_isac/main/filter_functions.o \
|
||||
audio/coding_isac/main/intialize.o \
|
||||
audio/coding_isac/main/isac.o \
|
||||
audio/coding_isac/main/lattice.o \
|
||||
audio/coding_isac/main/lpc_analysis.o \
|
||||
audio/coding_isac/main/lpc_gain_swb_tables.o \
|
||||
audio/coding_isac/main/lpc_shape_swb12_tables.o \
|
||||
audio/coding_isac/main/lpc_shape_swb16_tables.o \
|
||||
audio/coding_isac/main/lpc_tables.o \
|
||||
audio/coding_isac/main/pitch_estimator.o \
|
||||
audio/coding_isac/main/pitch_filter.o \
|
||||
audio/coding_isac/main/pitch_gain_tables.o \
|
||||
audio/coding_isac/main/pitch_lag_tables.o \
|
||||
audio/coding_isac/main/spectrum_ar_model_tables.o \
|
||||
audio/coding_isac/main/transform.o \
|
||||
audio/processing/audio_buffer.o \
|
||||
audio/processing/audio_processing_impl.o \
|
||||
audio/processing/echo_cancellation_impl.o \
|
||||
audio/processing/echo_control_mobile_impl.o \
|
||||
audio/processing/gain_control_impl.o \
|
||||
audio/processing/high_pass_filter_impl.o \
|
||||
audio/processing/level_estimator_impl.o \
|
||||
audio/processing/noise_suppression_impl.o \
|
||||
audio/processing/processing_component.o \
|
||||
audio/processing/splitting_filter.o \
|
||||
audio/processing/voice_detection_impl.o \
|
||||
audio/processing/aec/aec_core.o \
|
||||
audio/processing/aec/aec_rdft.o \
|
||||
audio/processing/aec/aec_resampler.o \
|
||||
audio/processing/aec/echo_cancellation.o \
|
||||
audio/processing/aecm/aecm_core.o \
|
||||
audio/processing/aecm/echo_control_mobile.o \
|
||||
audio/processing/agc/analog_agc.o \
|
||||
audio/processing/agc/digital_agc.o \
|
||||
audio/processing/ns/noise_suppression.o \
|
||||
audio/processing/ns/ns_core.o \
|
||||
audio/processing/utility/delay_estimator.o \
|
||||
audio/processing/utility/delay_estimator_wrapper.o \
|
||||
audio/processing/utility/fft4g.o \
|
||||
audio/processing/utility/ring_buffer.o \
|
||||
system_wrappers/cpu_features.o \
|
||||
system_wrappers/critical_section.o \
|
||||
system_wrappers/critical_section_posix.o \
|
||||
system_wrappers/file_impl.o
|
||||
|
||||
ifneq (@SSE2_OPS@,no)
|
||||
OBJS := $(OBJS) audio/processing/aec/aec_rdft_sse2.o \
|
||||
audio/processing/aec/aec_core_sse2.o
|
||||
CC := $(CC) -msse2
|
||||
CFLAGS := $(CFLAGS) -DSSE2_OPS=true
|
||||
endif
|
||||
|
||||
|
||||
LOCALFLAGS =
|
||||
MKDEPS := ../../config.status
|
||||
LOCALLIBS =
|
||||
COMPILE = $(CXX) $(DEFS) $(DEBUG) $(INCLUDES) $(CPPFLAGS)
|
||||
CCOMPILE = $(CC) $(DEFS) $(INCLUDES) $(CFLAGS)
|
||||
LINK = $(CXX) $(LDFLAGS)
|
||||
MODCOMP = $(COMPILE) $(LDFLAGS)
|
||||
MODCCOMP = $(COMPILE) $(LDFLAGS)
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
# include optional local make rules
|
||||
-include YateLocal.mak
|
||||
|
||||
.PHONY: all debug ddebug xdebug
|
||||
all: $(LIBS)
|
||||
|
||||
debug:
|
||||
$(MAKE) all DEBUG=-g3 MODSTRIP=
|
||||
|
||||
ddebug:
|
||||
$(MAKE) all DEBUG='-g3 -DDEBUG' MODSTRIP=
|
||||
|
||||
xdebug:
|
||||
$(MAKE) all DEBUG='-g3 -DXDEBUG' MODSTRIP=
|
||||
|
||||
.PHONY: strip
|
||||
strip: all
|
||||
strip --strip-debug --discard-locals $(PROGS)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@-$(RM) $(PROGS) $(LIBS) $(OBJS) $(AEC) core 2>/dev/null
|
||||
|
||||
%.o: @srcdir@/%.c $(MKDEPS) $(INCFILES)
|
||||
$(CCOMPILE) -c -o $@ $<
|
||||
|
||||
%.o: @srcdir@/%.cc $(MKDEPS) $(INCFILES)
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
Makefile: @srcdir@/Makefile.in ../../config.status
|
||||
cd ../.. && ./config.status
|
||||
|
||||
libminiwebrtc.a: $(OBJS)
|
||||
$(AR) rcs $@ $^
|
||||
|
|
@ -0,0 +1 @@
|
|||
WebRTC SVN version : 1768
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* arith_routins.c
|
||||
*
|
||||
* This C file contains a function for finalizing the bitstream
|
||||
* after arithmetic coding.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "arith_routins.h"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_EncTerminate(...)
|
||||
*
|
||||
* Final call to the arithmetic coder for an encoder call. This function
|
||||
* terminates and return byte stream.
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
*
|
||||
* Return value : number of bytes in the stream
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData)
|
||||
{
|
||||
WebRtc_UWord16 *streamPtr;
|
||||
WebRtc_UWord16 negCarry;
|
||||
|
||||
/* point to the right place in the stream buffer */
|
||||
streamPtr = streamData->stream + streamData->stream_index;
|
||||
|
||||
/* find minimum length (determined by current interval width) */
|
||||
if ( streamData->W_upper > 0x01FFFFFF )
|
||||
{
|
||||
streamData->streamval += 0x01000000;
|
||||
|
||||
/* if result is less than the added value we must take care of the carry */
|
||||
if (streamData->streamval < 0x01000000)
|
||||
{
|
||||
/* propagate carry */
|
||||
if (streamData->full == 0) {
|
||||
/* Add value to current value */
|
||||
negCarry = *streamPtr;
|
||||
negCarry += 0x0100;
|
||||
*streamPtr = negCarry;
|
||||
|
||||
/* if value is too big, propagate carry to next byte, and so on */
|
||||
while (!(negCarry))
|
||||
{
|
||||
negCarry = *--streamPtr;
|
||||
negCarry++;
|
||||
*streamPtr = negCarry;
|
||||
}
|
||||
} else {
|
||||
/* propagate carry by adding one to the previous byte in the
|
||||
* stream if that byte is 0xFFFF we need to propagate the carry
|
||||
* furhter back in the stream */
|
||||
while ( !(++(*--streamPtr)) );
|
||||
}
|
||||
|
||||
/* put pointer back to the old value */
|
||||
streamPtr = streamData->stream + streamData->stream_index;
|
||||
}
|
||||
/* write remaining data to bitstream, if "full == 0" first byte has data */
|
||||
if (streamData->full == 0) {
|
||||
*streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
|
||||
streamData->full = 1;
|
||||
} else {
|
||||
*streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_W32(
|
||||
WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8);
|
||||
streamData->full = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
streamData->streamval += 0x00010000;
|
||||
|
||||
/* if result is less than the added value we must take care of the carry */
|
||||
if (streamData->streamval < 0x00010000)
|
||||
{
|
||||
/* propagate carry */
|
||||
if (streamData->full == 0) {
|
||||
/* Add value to current value */
|
||||
negCarry = *streamPtr;
|
||||
negCarry += 0x0100;
|
||||
*streamPtr = negCarry;
|
||||
|
||||
/* if value to big, propagate carry to next byte, and so on */
|
||||
while (!(negCarry))
|
||||
{
|
||||
negCarry = *--streamPtr;
|
||||
negCarry++;
|
||||
*streamPtr = negCarry;
|
||||
}
|
||||
} else {
|
||||
/* Add carry to previous byte */
|
||||
while ( !(++(*--streamPtr)) );
|
||||
}
|
||||
|
||||
/* put pointer back to the old value */
|
||||
streamPtr = streamData->stream + streamData->stream_index;
|
||||
}
|
||||
/* write remaining data (2 bytes) to bitstream */
|
||||
if (streamData->full) {
|
||||
*streamPtr++ = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 16);
|
||||
} else {
|
||||
*streamPtr++ |= (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
|
||||
*streamPtr = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 8)
|
||||
& 0xFF00;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate stream length in bytes */
|
||||
return (((streamPtr - streamData->stream)<<1) + !(streamData->full));
|
||||
}
|
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* arith_routinshist.c
|
||||
*
|
||||
* This C file contains arithmetic encoding and decoding.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "arith_routins.h"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_EncHistMulti(...)
|
||||
*
|
||||
* Encode the histogram interval
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
* - data : data vector
|
||||
* - cdf : array of cdf arrays
|
||||
* - lenData : data vector length
|
||||
*
|
||||
* Return value : 0 if ok
|
||||
* <0 if error detected
|
||||
*/
|
||||
int WebRtcIsacfix_EncHistMulti(Bitstr_enc *streamData,
|
||||
const WebRtc_Word16 *data,
|
||||
const WebRtc_UWord16 **cdf,
|
||||
const WebRtc_Word16 lenData)
|
||||
{
|
||||
WebRtc_UWord32 W_lower;
|
||||
WebRtc_UWord32 W_upper;
|
||||
WebRtc_UWord32 W_upper_LSB;
|
||||
WebRtc_UWord32 W_upper_MSB;
|
||||
WebRtc_UWord16 *streamPtr;
|
||||
WebRtc_UWord16 negCarry;
|
||||
WebRtc_UWord16 *maxStreamPtr;
|
||||
WebRtc_UWord16 *streamPtrCarry;
|
||||
WebRtc_UWord32 cdfLo;
|
||||
WebRtc_UWord32 cdfHi;
|
||||
int k;
|
||||
|
||||
|
||||
/* point to beginning of stream buffer
|
||||
* and set maximum streamPtr value */
|
||||
streamPtr = streamData->stream + streamData->stream_index;
|
||||
maxStreamPtr = streamData->stream + STREAM_MAXW16_60MS - 1;
|
||||
|
||||
W_upper = streamData->W_upper;
|
||||
|
||||
for (k = lenData; k > 0; k--)
|
||||
{
|
||||
/* fetch cdf_lower and cdf_upper from cdf tables */
|
||||
cdfLo = (WebRtc_UWord32) *(*cdf + (WebRtc_UWord32)*data);
|
||||
cdfHi = (WebRtc_UWord32) *(*cdf++ + (WebRtc_UWord32)*data++ + 1);
|
||||
|
||||
/* update interval */
|
||||
W_upper_LSB = W_upper & 0x0000FFFF;
|
||||
W_upper_MSB = WEBRTC_SPL_RSHIFT_W32(W_upper, 16);
|
||||
W_lower = WEBRTC_SPL_UMUL(W_upper_MSB, cdfLo);
|
||||
W_lower += WEBRTC_SPL_UMUL_RSFT16(W_upper_LSB, cdfLo);
|
||||
W_upper = WEBRTC_SPL_UMUL(W_upper_MSB, cdfHi);
|
||||
W_upper += WEBRTC_SPL_UMUL_RSFT16(W_upper_LSB, cdfHi);
|
||||
|
||||
/* shift interval such that it begins at zero */
|
||||
W_upper -= ++W_lower;
|
||||
|
||||
/* add integer to bitstream */
|
||||
streamData->streamval += W_lower;
|
||||
|
||||
/* handle carry */
|
||||
if (streamData->streamval < W_lower)
|
||||
{
|
||||
/* propagate carry */
|
||||
streamPtrCarry = streamPtr;
|
||||
if (streamData->full == 0) {
|
||||
negCarry = *streamPtrCarry;
|
||||
negCarry += 0x0100;
|
||||
*streamPtrCarry = negCarry;
|
||||
while (!(negCarry))
|
||||
{
|
||||
negCarry = *--streamPtrCarry;
|
||||
negCarry++;
|
||||
*streamPtrCarry = negCarry;
|
||||
}
|
||||
} else {
|
||||
while ( !(++(*--streamPtrCarry)) );
|
||||
}
|
||||
}
|
||||
|
||||
/* renormalize interval, store most significant byte of streamval and update streamval
|
||||
* W_upper < 2^24 */
|
||||
while ( !(W_upper & 0xFF000000) )
|
||||
{
|
||||
W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
|
||||
if (streamData->full == 0) {
|
||||
*streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
|
||||
streamData->full = 1;
|
||||
} else {
|
||||
*streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_W32(
|
||||
WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8);
|
||||
streamData->full = 0;
|
||||
}
|
||||
|
||||
if( streamPtr > maxStreamPtr ) {
|
||||
return -ISAC_DISALLOWED_BITSTREAM_LENGTH;
|
||||
}
|
||||
streamData->streamval = WEBRTC_SPL_LSHIFT_W32(streamData->streamval, 8);
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate new stream_index */
|
||||
streamData->stream_index = streamPtr - streamData->stream;
|
||||
streamData->W_upper = W_upper;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_DecHistBisectMulti(...)
|
||||
*
|
||||
* Function to decode more symbols from the arithmetic bytestream, using
|
||||
* method of bisection cdf tables should be of size 2^k-1 (which corresponds
|
||||
* to an alphabet size of 2^k-2)
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
* - cdf : array of cdf arrays
|
||||
* - cdfSize : array of cdf table sizes+1 (power of two: 2^k)
|
||||
* - lenData : data vector length
|
||||
*
|
||||
* Output:
|
||||
* - data : data vector
|
||||
*
|
||||
* Return value : number of bytes in the stream
|
||||
* <0 if error detected
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsacfix_DecHistBisectMulti(WebRtc_Word16 *data,
|
||||
Bitstr_dec *streamData,
|
||||
const WebRtc_UWord16 **cdf,
|
||||
const WebRtc_UWord16 *cdfSize,
|
||||
const WebRtc_Word16 lenData)
|
||||
{
|
||||
WebRtc_UWord32 W_lower = 0;
|
||||
WebRtc_UWord32 W_upper;
|
||||
WebRtc_UWord32 W_tmp;
|
||||
WebRtc_UWord32 W_upper_LSB;
|
||||
WebRtc_UWord32 W_upper_MSB;
|
||||
WebRtc_UWord32 streamval;
|
||||
const WebRtc_UWord16 *streamPtr;
|
||||
const WebRtc_UWord16 *cdfPtr;
|
||||
WebRtc_Word16 sizeTmp;
|
||||
int k;
|
||||
|
||||
|
||||
streamPtr = streamData->stream + streamData->stream_index;
|
||||
W_upper = streamData->W_upper;
|
||||
|
||||
/* Error check: should not be possible in normal operation */
|
||||
if (W_upper == 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* first time decoder is called for this stream */
|
||||
if (streamData->stream_index == 0)
|
||||
{
|
||||
/* read first word from bytestream */
|
||||
streamval = WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)*streamPtr++, 16);
|
||||
streamval |= *streamPtr++;
|
||||
} else {
|
||||
streamval = streamData->streamval;
|
||||
}
|
||||
|
||||
for (k = lenData; k > 0; k--)
|
||||
{
|
||||
/* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
|
||||
W_upper_LSB = W_upper & 0x0000FFFF;
|
||||
W_upper_MSB = WEBRTC_SPL_RSHIFT_W32(W_upper, 16);
|
||||
|
||||
/* start halfway the cdf range */
|
||||
sizeTmp = WEBRTC_SPL_RSHIFT_W16(*cdfSize++, 1);
|
||||
cdfPtr = *cdf + (sizeTmp - 1);
|
||||
|
||||
/* method of bisection */
|
||||
for ( ;; )
|
||||
{
|
||||
W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
|
||||
W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
|
||||
sizeTmp = WEBRTC_SPL_RSHIFT_W16(sizeTmp, 1);
|
||||
if (sizeTmp == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (streamval > W_tmp)
|
||||
{
|
||||
W_lower = W_tmp;
|
||||
cdfPtr += sizeTmp;
|
||||
} else {
|
||||
W_upper = W_tmp;
|
||||
cdfPtr -= sizeTmp;
|
||||
}
|
||||
}
|
||||
if (streamval > W_tmp)
|
||||
{
|
||||
W_lower = W_tmp;
|
||||
*data++ = cdfPtr - *cdf++;
|
||||
} else {
|
||||
W_upper = W_tmp;
|
||||
*data++ = cdfPtr - *cdf++ - 1;
|
||||
}
|
||||
|
||||
/* shift interval to start at zero */
|
||||
W_upper -= ++W_lower;
|
||||
|
||||
/* add integer to bitstream */
|
||||
streamval -= W_lower;
|
||||
|
||||
/* renormalize interval and update streamval */
|
||||
/* W_upper < 2^24 */
|
||||
while ( !(W_upper & 0xFF000000) )
|
||||
{
|
||||
/* read next byte from stream */
|
||||
if (streamData->full == 0) {
|
||||
streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) |
|
||||
(*streamPtr++ & 0x00FF);
|
||||
streamData->full = 1;
|
||||
} else {
|
||||
streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) |
|
||||
WEBRTC_SPL_RSHIFT_W16(*streamPtr, 8);
|
||||
streamData->full = 0;
|
||||
}
|
||||
W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
|
||||
}
|
||||
|
||||
|
||||
/* Error check: should not be possible in normal operation */
|
||||
if (W_upper == 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
streamData->stream_index = streamPtr - streamData->stream;
|
||||
streamData->W_upper = W_upper;
|
||||
streamData->streamval = streamval;
|
||||
|
||||
if ( W_upper > 0x01FFFFFF ) {
|
||||
return (streamData->stream_index*2 - 3 + !streamData->full);
|
||||
} else {
|
||||
return (streamData->stream_index*2 - 2 + !streamData->full);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_DecHistOneStepMulti(...)
|
||||
*
|
||||
* Function to decode more symbols from the arithmetic bytestream, taking
|
||||
* single step up or down at a time.
|
||||
* cdf tables can be of arbitrary size, but large tables may take a lot of
|
||||
* iterations.
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
* - cdf : array of cdf arrays
|
||||
* - initIndex : vector of initial cdf table search entries
|
||||
* - lenData : data vector length
|
||||
*
|
||||
* Output:
|
||||
* - data : data vector
|
||||
*
|
||||
* Return value : number of bytes in original stream
|
||||
* <0 if error detected
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsacfix_DecHistOneStepMulti(WebRtc_Word16 *data,
|
||||
Bitstr_dec *streamData,
|
||||
const WebRtc_UWord16 **cdf,
|
||||
const WebRtc_UWord16 *initIndex,
|
||||
const WebRtc_Word16 lenData)
|
||||
{
|
||||
WebRtc_UWord32 W_lower;
|
||||
WebRtc_UWord32 W_upper;
|
||||
WebRtc_UWord32 W_tmp;
|
||||
WebRtc_UWord32 W_upper_LSB;
|
||||
WebRtc_UWord32 W_upper_MSB;
|
||||
WebRtc_UWord32 streamval;
|
||||
const WebRtc_UWord16 *streamPtr;
|
||||
const WebRtc_UWord16 *cdfPtr;
|
||||
int k;
|
||||
|
||||
|
||||
streamPtr = streamData->stream + streamData->stream_index;
|
||||
W_upper = streamData->W_upper;
|
||||
/* Error check: Should not be possible in normal operation */
|
||||
if (W_upper == 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Check if it is the first time decoder is called for this stream */
|
||||
if (streamData->stream_index == 0)
|
||||
{
|
||||
/* read first word from bytestream */
|
||||
streamval = WEBRTC_SPL_LSHIFT_U32(*streamPtr++, 16);
|
||||
streamval |= *streamPtr++;
|
||||
} else {
|
||||
streamval = streamData->streamval;
|
||||
}
|
||||
|
||||
for (k = lenData; k > 0; k--)
|
||||
{
|
||||
/* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
|
||||
W_upper_LSB = W_upper & 0x0000FFFF;
|
||||
W_upper_MSB = WEBRTC_SPL_RSHIFT_U32(W_upper, 16);
|
||||
|
||||
/* start at the specified table entry */
|
||||
cdfPtr = *cdf + (*initIndex++);
|
||||
W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
|
||||
W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
|
||||
|
||||
if (streamval > W_tmp)
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
W_lower = W_tmp;
|
||||
|
||||
/* range check */
|
||||
if (cdfPtr[0] == 65535) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *++cdfPtr);
|
||||
W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
|
||||
|
||||
if (streamval <= W_tmp) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
W_upper = W_tmp;
|
||||
*data++ = cdfPtr - *cdf++ - 1;
|
||||
} else {
|
||||
for ( ;; )
|
||||
{
|
||||
W_upper = W_tmp;
|
||||
--cdfPtr;
|
||||
|
||||
/* range check */
|
||||
if (cdfPtr < *cdf) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
|
||||
W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
|
||||
|
||||
if (streamval > W_tmp) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
W_lower = W_tmp;
|
||||
*data++ = cdfPtr - *cdf++;
|
||||
}
|
||||
|
||||
/* shift interval to start at zero */
|
||||
W_upper -= ++W_lower;
|
||||
|
||||
/* add integer to bitstream */
|
||||
streamval -= W_lower;
|
||||
|
||||
/* renormalize interval and update streamval */
|
||||
/* W_upper < 2^24 */
|
||||
while ( !(W_upper & 0xFF000000) )
|
||||
{
|
||||
/* read next byte from stream */
|
||||
if (streamData->full == 0) {
|
||||
streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) | (*streamPtr++ & 0x00FF);
|
||||
streamData->full = 1;
|
||||
} else {
|
||||
streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) | (*streamPtr >> 8);
|
||||
streamData->full = 0;
|
||||
}
|
||||
W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
|
||||
}
|
||||
}
|
||||
|
||||
streamData->stream_index = streamPtr - streamData->stream;
|
||||
streamData->W_upper = W_upper;
|
||||
streamData->streamval = streamval;
|
||||
|
||||
/* find number of bytes in original stream (determined by current interval width) */
|
||||
if ( W_upper > 0x01FFFFFF ) {
|
||||
return (streamData->stream_index*2 - 3 + !streamData->full);
|
||||
} else {
|
||||
return (streamData->stream_index*2 - 2 + !streamData->full);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* arith_routinslogist.c
|
||||
*
|
||||
* This C file contains arithmetic encode and decode logistic
|
||||
*
|
||||
*/
|
||||
|
||||
#include "arith_routins.h"
|
||||
|
||||
|
||||
/* Tables for piecewise linear cdf functions: y = k*x */
|
||||
|
||||
/* x Points for function piecewise() in Q15 */
|
||||
static const WebRtc_Word32 kHistEdges[51] = {
|
||||
-327680, -314573, -301466, -288359, -275252, -262144, -249037, -235930, -222823, -209716,
|
||||
-196608, -183501, -170394, -157287, -144180, -131072, -117965, -104858, -91751, -78644,
|
||||
-65536, -52429, -39322, -26215, -13108, 0, 13107, 26214, 39321, 52428,
|
||||
65536, 78643, 91750, 104857, 117964, 131072, 144179, 157286, 170393, 183500,
|
||||
196608, 209715, 222822, 235929, 249036, 262144, 275251, 288358, 301465, 314572,
|
||||
327680
|
||||
};
|
||||
|
||||
|
||||
/* k Points for function piecewise() in Q0 */
|
||||
static const WebRtc_UWord16 kCdfSlope[51] = {
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 13, 23, 47, 87, 154, 315, 700, 1088,
|
||||
2471, 6064, 14221, 21463, 36634, 36924, 19750, 13270, 5806, 2312,
|
||||
1095, 660, 316, 145, 86, 41, 32, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 2,
|
||||
0
|
||||
};
|
||||
|
||||
/* y Points for function piecewise() in Q0 */
|
||||
static const WebRtc_UWord16 kCdfLogistic[51] = {
|
||||
0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
|
||||
20, 22, 24, 29, 38, 57, 92, 153, 279, 559,
|
||||
994, 1983, 4408, 10097, 18682, 33336, 48105, 56005, 61313, 63636,
|
||||
64560, 64998, 65262, 65389, 65447, 65481, 65497, 65510, 65512, 65514,
|
||||
65516, 65518, 65520, 65522, 65524, 65526, 65528, 65530, 65532, 65534,
|
||||
65535
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_Piecewise(...)
|
||||
*
|
||||
* Piecewise linear function
|
||||
*
|
||||
* Input:
|
||||
* - xinQ15 : input value x in Q15
|
||||
*
|
||||
* Return value : korresponding y-value in Q0
|
||||
*/
|
||||
|
||||
|
||||
static __inline WebRtc_UWord16 WebRtcIsacfix_Piecewise(WebRtc_Word32 xinQ15) {
|
||||
WebRtc_Word32 ind;
|
||||
WebRtc_Word32 qtmp1;
|
||||
WebRtc_UWord16 qtmp2;
|
||||
|
||||
/* Find index for x-value */
|
||||
qtmp1 = WEBRTC_SPL_SAT(kHistEdges[50],xinQ15,kHistEdges[0]);
|
||||
ind = WEBRTC_SPL_MUL(5, qtmp1 - kHistEdges[0]);
|
||||
ind = WEBRTC_SPL_RSHIFT_W32(ind, 16);
|
||||
|
||||
/* Calculate corresponding y-value ans return*/
|
||||
qtmp1 = qtmp1 - kHistEdges[ind];
|
||||
qtmp2 = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(
|
||||
WEBRTC_SPL_UMUL_32_16(qtmp1,kCdfSlope[ind]), 15);
|
||||
return (kCdfLogistic[ind] + qtmp2);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_EncLogisticMulti2(...)
|
||||
*
|
||||
* Arithmetic coding of spectrum.
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
* - dataQ7 : data vector in Q7
|
||||
* - envQ8 : side info vector defining the width of the pdf
|
||||
* in Q8
|
||||
* - lenData : data vector length
|
||||
*
|
||||
* Return value : 0 if ok,
|
||||
* <0 otherwise.
|
||||
*/
|
||||
int WebRtcIsacfix_EncLogisticMulti2(Bitstr_enc *streamData,
|
||||
WebRtc_Word16 *dataQ7,
|
||||
const WebRtc_UWord16 *envQ8,
|
||||
const WebRtc_Word16 lenData)
|
||||
{
|
||||
WebRtc_UWord32 W_lower;
|
||||
WebRtc_UWord32 W_upper;
|
||||
WebRtc_UWord16 W_upper_LSB;
|
||||
WebRtc_UWord16 W_upper_MSB;
|
||||
WebRtc_UWord16 *streamPtr;
|
||||
WebRtc_UWord16 *maxStreamPtr;
|
||||
WebRtc_UWord16 *streamPtrCarry;
|
||||
WebRtc_UWord16 negcarry;
|
||||
WebRtc_UWord32 cdfLo;
|
||||
WebRtc_UWord32 cdfHi;
|
||||
int k;
|
||||
|
||||
/* point to beginning of stream buffer
|
||||
* and set maximum streamPtr value */
|
||||
streamPtr = streamData->stream + streamData->stream_index;
|
||||
maxStreamPtr = streamData->stream + STREAM_MAXW16_60MS - 1;
|
||||
W_upper = streamData->W_upper;
|
||||
|
||||
for (k = 0; k < lenData; k++)
|
||||
{
|
||||
/* compute cdf_lower and cdf_upper by evaluating the
|
||||
* WebRtcIsacfix_Piecewise linear cdf */
|
||||
cdfLo = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(*dataQ7 - 64, *envQ8));
|
||||
cdfHi = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(*dataQ7 + 64, *envQ8));
|
||||
|
||||
/* test and clip if probability gets too small */
|
||||
while ((cdfLo + 1) >= cdfHi) {
|
||||
/* clip */
|
||||
if (*dataQ7 > 0) {
|
||||
*dataQ7 -= 128;
|
||||
cdfHi = cdfLo;
|
||||
cdfLo = WebRtcIsacfix_Piecewise(
|
||||
WEBRTC_SPL_MUL_16_U16(*dataQ7 - 64, *envQ8));
|
||||
} else {
|
||||
*dataQ7 += 128;
|
||||
cdfLo = cdfHi;
|
||||
cdfHi = WebRtcIsacfix_Piecewise(
|
||||
WEBRTC_SPL_MUL_16_U16(*dataQ7 + 64, *envQ8));
|
||||
}
|
||||
}
|
||||
|
||||
dataQ7++;
|
||||
/* increment only once per 4 iterations */
|
||||
envQ8 += (k & 1) & (k >> 1);
|
||||
|
||||
|
||||
/* update interval */
|
||||
W_upper_LSB = (WebRtc_UWord16)W_upper;
|
||||
W_upper_MSB = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(W_upper, 16);
|
||||
W_lower = WEBRTC_SPL_UMUL_32_16(cdfLo, W_upper_MSB);
|
||||
W_lower += WEBRTC_SPL_UMUL_32_16_RSFT16(cdfLo, W_upper_LSB);
|
||||
W_upper = WEBRTC_SPL_UMUL_32_16(cdfHi, W_upper_MSB);
|
||||
W_upper += WEBRTC_SPL_UMUL_32_16_RSFT16(cdfHi, W_upper_LSB);
|
||||
|
||||
/* shift interval such that it begins at zero */
|
||||
W_upper -= ++W_lower;
|
||||
|
||||
/* add integer to bitstream */
|
||||
streamData->streamval += W_lower;
|
||||
|
||||
/* handle carry */
|
||||
if (streamData->streamval < W_lower)
|
||||
{
|
||||
/* propagate carry */
|
||||
streamPtrCarry = streamPtr;
|
||||
if (streamData->full == 0) {
|
||||
negcarry = *streamPtrCarry;
|
||||
negcarry += 0x0100;
|
||||
*streamPtrCarry = negcarry;
|
||||
while (!(negcarry))
|
||||
{
|
||||
negcarry = *--streamPtrCarry;
|
||||
negcarry++;
|
||||
*streamPtrCarry = negcarry;
|
||||
}
|
||||
} else {
|
||||
while (!(++(*--streamPtrCarry)));
|
||||
}
|
||||
}
|
||||
|
||||
/* renormalize interval, store most significant byte of streamval and update streamval
|
||||
* W_upper < 2^24 */
|
||||
while ( !(W_upper & 0xFF000000) )
|
||||
{
|
||||
W_upper = WEBRTC_SPL_LSHIFT_U32(W_upper, 8);
|
||||
if (streamData->full == 0) {
|
||||
*streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_U32(
|
||||
streamData->streamval, 24);
|
||||
streamData->full = 1;
|
||||
} else {
|
||||
*streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_U32(
|
||||
WEBRTC_SPL_RSHIFT_U32(streamData->streamval, 24), 8);
|
||||
streamData->full = 0;
|
||||
}
|
||||
|
||||
if( streamPtr > maxStreamPtr )
|
||||
return -ISAC_DISALLOWED_BITSTREAM_LENGTH;
|
||||
|
||||
streamData->streamval = WEBRTC_SPL_LSHIFT_U32(streamData->streamval, 8);
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate new stream_index */
|
||||
streamData->stream_index = streamPtr - streamData->stream;
|
||||
streamData->W_upper = W_upper;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_DecLogisticMulti2(...)
|
||||
*
|
||||
* Arithmetic decoding of spectrum.
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
* - envQ8 : side info vector defining the width of the pdf
|
||||
* in Q8
|
||||
* - lenData : data vector length
|
||||
*
|
||||
* Input/Output:
|
||||
* - dataQ7 : input: dither vector, output: data vector
|
||||
*
|
||||
* Return value : number of bytes in the stream so far
|
||||
* -1 if error detected
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsacfix_DecLogisticMulti2(WebRtc_Word16 *dataQ7,
|
||||
Bitstr_dec *streamData,
|
||||
const WebRtc_Word32 *envQ8,
|
||||
const WebRtc_Word16 lenData)
|
||||
{
|
||||
WebRtc_UWord32 W_lower;
|
||||
WebRtc_UWord32 W_upper;
|
||||
WebRtc_UWord32 W_tmp;
|
||||
WebRtc_UWord16 W_upper_LSB;
|
||||
WebRtc_UWord16 W_upper_MSB;
|
||||
WebRtc_UWord32 streamVal;
|
||||
WebRtc_UWord16 cdfTmp;
|
||||
WebRtc_Word32 res;
|
||||
WebRtc_Word32 inSqrt;
|
||||
WebRtc_Word32 newRes;
|
||||
const WebRtc_UWord16 *streamPtr;
|
||||
WebRtc_Word16 candQ7;
|
||||
WebRtc_Word16 envCount;
|
||||
WebRtc_UWord16 tmpARSpecQ8 = 0;
|
||||
int k, i;
|
||||
|
||||
|
||||
/* point to beginning of stream buffer */
|
||||
streamPtr = streamData->stream + streamData->stream_index;
|
||||
W_upper = streamData->W_upper;
|
||||
|
||||
/* Check if it is first time decoder is called for this stream */
|
||||
if (streamData->stream_index == 0)
|
||||
{
|
||||
/* read first word from bytestream */
|
||||
streamVal = WEBRTC_SPL_LSHIFT_U32(*streamPtr++, 16);
|
||||
streamVal |= *streamPtr++;
|
||||
|
||||
} else {
|
||||
streamVal = streamData->streamval;
|
||||
}
|
||||
|
||||
|
||||
res = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1,
|
||||
WEBRTC_SPL_RSHIFT_W16(WebRtcSpl_GetSizeInBits(envQ8[0]), 1));
|
||||
envCount = 0;
|
||||
|
||||
/* code assumes lenData%4 == 0 */
|
||||
for (k = 0; k < lenData; k += 4)
|
||||
{
|
||||
int k4;
|
||||
|
||||
/* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */
|
||||
inSqrt = envQ8[envCount];
|
||||
i = 10;
|
||||
|
||||
/* For safty reasons */
|
||||
if (inSqrt < 0)
|
||||
inSqrt=-inSqrt;
|
||||
|
||||
newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(inSqrt, res) + res, 1);
|
||||
do
|
||||
{
|
||||
res = newRes;
|
||||
newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(inSqrt, res) + res, 1);
|
||||
} while (newRes != res && i-- > 0);
|
||||
|
||||
tmpARSpecQ8 = (WebRtc_UWord16)newRes;
|
||||
|
||||
for(k4 = 0; k4 < 4; k4++)
|
||||
{
|
||||
/* find the integer *data for which streamVal lies in [W_lower+1, W_upper] */
|
||||
W_upper_LSB = (WebRtc_UWord16) (W_upper & 0x0000FFFF);
|
||||
W_upper_MSB = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_U32(W_upper, 16);
|
||||
|
||||
/* find first candidate by inverting the logistic cdf
|
||||
* Input dither value collected from io-stream */
|
||||
candQ7 = - *dataQ7 + 64;
|
||||
cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
|
||||
|
||||
W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
|
||||
W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB);
|
||||
|
||||
if (streamVal > W_tmp)
|
||||
{
|
||||
W_lower = W_tmp;
|
||||
candQ7 += 128;
|
||||
cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
|
||||
|
||||
W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
|
||||
W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB);
|
||||
|
||||
while (streamVal > W_tmp)
|
||||
{
|
||||
W_lower = W_tmp;
|
||||
candQ7 += 128;
|
||||
cdfTmp = WebRtcIsacfix_Piecewise(
|
||||
WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
|
||||
|
||||
W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
|
||||
W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB);
|
||||
|
||||
/* error check */
|
||||
if (W_lower == W_tmp) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
W_upper = W_tmp;
|
||||
|
||||
/* Output value put in dataQ7: another sample decoded */
|
||||
*dataQ7 = candQ7 - 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
W_upper = W_tmp;
|
||||
candQ7 -= 128;
|
||||
cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
|
||||
|
||||
W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
|
||||
W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB);
|
||||
|
||||
while ( !(streamVal > W_tmp) )
|
||||
{
|
||||
W_upper = W_tmp;
|
||||
candQ7 -= 128;
|
||||
cdfTmp = WebRtcIsacfix_Piecewise(
|
||||
WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
|
||||
|
||||
W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
|
||||
W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB);
|
||||
|
||||
/* error check */
|
||||
if (W_upper == W_tmp){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
W_lower = W_tmp;
|
||||
|
||||
/* Output value put in dataQ7: another sample decoded */
|
||||
*dataQ7 = candQ7 + 64;
|
||||
}
|
||||
|
||||
dataQ7++;
|
||||
|
||||
/* shift interval to start at zero */
|
||||
W_upper -= ++W_lower;
|
||||
|
||||
/* add integer to bitstream */
|
||||
streamVal -= W_lower;
|
||||
|
||||
/* renormalize interval and update streamVal
|
||||
* W_upper < 2^24 */
|
||||
while ( !(W_upper & 0xFF000000) )
|
||||
{
|
||||
/* read next byte from stream */
|
||||
if (streamData->full == 0) {
|
||||
streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) | (*streamPtr++ & 0x00FF);
|
||||
streamData->full = 1;
|
||||
} else {
|
||||
streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) |
|
||||
WEBRTC_SPL_RSHIFT_U16(*streamPtr, 8);
|
||||
streamData->full = 0;
|
||||
}
|
||||
W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
|
||||
}
|
||||
}
|
||||
envCount++;
|
||||
}
|
||||
|
||||
streamData->stream_index = streamPtr - streamData->stream;
|
||||
streamData->W_upper = W_upper;
|
||||
streamData->streamval = streamVal;
|
||||
|
||||
/* find number of bytes in original stream (determined by current interval width) */
|
||||
if ( W_upper > 0x01FFFFFF )
|
||||
return (streamData->stream_index*2 - 3 + !streamData->full);
|
||||
else
|
||||
return (streamData->stream_index*2 - 2 + !streamData->full);
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* arith_routins.h
|
||||
*
|
||||
* Functions for arithmetic coding.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ARITH_ROUTINS_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ARITH_ROUTINS_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_EncLogisticMulti2(...)
|
||||
*
|
||||
* Arithmetic coding of spectrum.
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
* - dataQ7 : data vector in Q7
|
||||
* - envQ8 : side info vector defining the width of the pdf
|
||||
* in Q8
|
||||
* - lenData : data vector length
|
||||
*
|
||||
* Return value : 0 if ok,
|
||||
* <0 otherwise.
|
||||
*/
|
||||
int WebRtcIsacfix_EncLogisticMulti2(
|
||||
Bitstr_enc *streamData,
|
||||
WebRtc_Word16 *dataQ7,
|
||||
const WebRtc_UWord16 *env,
|
||||
const WebRtc_Word16 lenData);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_EncTerminate(...)
|
||||
*
|
||||
* Final call to the arithmetic coder for an encoder call. This function
|
||||
* terminates and return byte stream.
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
*
|
||||
* Return value : number of bytes in the stream
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_DecLogisticMulti2(...)
|
||||
*
|
||||
* Arithmetic decoding of spectrum.
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
* - envQ8 : side info vector defining the width of the pdf
|
||||
* in Q8
|
||||
* - lenData : data vector length
|
||||
*
|
||||
* Input/Output:
|
||||
* - dataQ7 : input: dither vector, output: data vector, in Q7
|
||||
*
|
||||
* Return value : number of bytes in the stream so far
|
||||
* <0 if error detected
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsacfix_DecLogisticMulti2(
|
||||
WebRtc_Word16 *data,
|
||||
Bitstr_dec *streamData,
|
||||
const WebRtc_Word32 *env,
|
||||
const WebRtc_Word16 lenData);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_EncHistMulti(...)
|
||||
*
|
||||
* Encode the histogram interval
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
* - data : data vector
|
||||
* - cdf : array of cdf arrays
|
||||
* - lenData : data vector length
|
||||
*
|
||||
* Return value : 0 if ok
|
||||
* <0 if error detected
|
||||
*/
|
||||
int WebRtcIsacfix_EncHistMulti(
|
||||
Bitstr_enc *streamData,
|
||||
const WebRtc_Word16 *data,
|
||||
const WebRtc_UWord16 **cdf,
|
||||
const WebRtc_Word16 lenData);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_DecHistBisectMulti(...)
|
||||
*
|
||||
* Function to decode more symbols from the arithmetic bytestream, using
|
||||
* method of bisection.
|
||||
* C df tables should be of size 2^k-1 (which corresponds to an
|
||||
* alphabet size of 2^k-2)
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
* - cdf : array of cdf arrays
|
||||
* - cdfSize : array of cdf table sizes+1 (power of two: 2^k)
|
||||
* - lenData : data vector length
|
||||
*
|
||||
* Output:
|
||||
* - data : data vector
|
||||
*
|
||||
* Return value : number of bytes in the stream
|
||||
* <0 if error detected
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsacfix_DecHistBisectMulti(
|
||||
WebRtc_Word16 *data,
|
||||
Bitstr_dec *streamData,
|
||||
const WebRtc_UWord16 **cdf,
|
||||
const WebRtc_UWord16 *cdfSize,
|
||||
const WebRtc_Word16 lenData);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_DecHistOneStepMulti(...)
|
||||
*
|
||||
* Function to decode more symbols from the arithmetic bytestream, taking
|
||||
* single step up or down at a time.
|
||||
* cdf tables can be of arbitrary size, but large tables may take a lot of
|
||||
* iterations.
|
||||
*
|
||||
* Input:
|
||||
* - streamData : in-/output struct containing bitstream
|
||||
* - cdf : array of cdf arrays
|
||||
* - initIndex : vector of initial cdf table search entries
|
||||
* - lenData : data vector length
|
||||
*
|
||||
* Output:
|
||||
* - data : data vector
|
||||
*
|
||||
* Return value : number of bytes in original stream
|
||||
* <0 if error detected
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsacfix_DecHistOneStepMulti(
|
||||
WebRtc_Word16 *data,
|
||||
Bitstr_dec *streamData,
|
||||
const WebRtc_UWord16 **cdf,
|
||||
const WebRtc_UWord16 *initIndex,
|
||||
const WebRtc_Word16 lenData);
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ARITH_ROUTINS_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* bandwidth_estimator.h
|
||||
*
|
||||
* This header file contains the API for the Bandwidth Estimator
|
||||
* designed for iSAC.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_BANDWIDTH_ESTIMATOR_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_BANDWIDTH_ESTIMATOR_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_InitBandwidthEstimator(...)
|
||||
*
|
||||
* This function initializes the struct for the bandwidth estimator
|
||||
*
|
||||
* Input/Output:
|
||||
* - bwest_str : Struct containing bandwidth information.
|
||||
*
|
||||
* Return value : 0
|
||||
*/
|
||||
|
||||
WebRtc_Word32 WebRtcIsacfix_InitBandwidthEstimator(BwEstimatorstr *bwest_str);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_UpdateUplinkBwImpl(...)
|
||||
*
|
||||
* This function updates bottle neck rate received from other side in payload
|
||||
* and calculates a new bottle neck to send to the other side.
|
||||
*
|
||||
* Input/Output:
|
||||
* - bweStr : struct containing bandwidth information.
|
||||
* - rtpNumber : value from RTP packet, from NetEq
|
||||
* - frameSize : length of signal frame in ms, from iSAC decoder
|
||||
* - sendTime : value in RTP header giving send time in samples
|
||||
* - arrivalTime : value given by timeGetTime() time of arrival in
|
||||
* samples of packet from NetEq
|
||||
* - pksize : size of packet in bytes, from NetEq
|
||||
* - Index : integer (range 0...23) indicating bottle neck &
|
||||
* jitter as estimated by other side
|
||||
*
|
||||
* Return value : 0 if everything went fine,
|
||||
* -1 otherwise
|
||||
*/
|
||||
|
||||
WebRtc_Word32 WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bwest_str,
|
||||
const WebRtc_UWord16 rtp_number,
|
||||
const WebRtc_Word16 frameSize,
|
||||
const WebRtc_UWord32 send_ts,
|
||||
const WebRtc_UWord32 arr_ts,
|
||||
const WebRtc_Word16 pksize,
|
||||
const WebRtc_UWord16 Index);
|
||||
|
||||
/* Update receiving estimates. Used when we only receive BWE index, no iSAC data packet. */
|
||||
WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bwest_str,
|
||||
const WebRtc_Word16 Index);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_GetDownlinkBwIndexImpl(...)
|
||||
*
|
||||
* This function calculates and returns the bandwidth/jitter estimation code
|
||||
* (integer 0...23) to put in the sending iSAC payload.
|
||||
*
|
||||
* Input:
|
||||
* - bweStr : BWE struct
|
||||
*
|
||||
* Return:
|
||||
* bandwith and jitter index (0..23)
|
||||
*/
|
||||
WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bwest_str);
|
||||
|
||||
/* Returns the bandwidth estimation (in bps) */
|
||||
WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bwest_str);
|
||||
|
||||
/* Returns the bandwidth that iSAC should send with in bps */
|
||||
WebRtc_Word16 WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr *bwest_str);
|
||||
|
||||
/* Returns the max delay (in ms) */
|
||||
WebRtc_Word16 WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bwest_str);
|
||||
|
||||
/* Returns the max delay value from the other side in ms */
|
||||
WebRtc_Word16 WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr *bwest_str);
|
||||
|
||||
/*
|
||||
* update amount of data in bottle neck buffer and burst handling
|
||||
* returns minimum payload size (bytes)
|
||||
*/
|
||||
WebRtc_UWord16 WebRtcIsacfix_GetMinBytes(RateModel *State,
|
||||
WebRtc_Word16 StreamSize, /* bytes in bitstream */
|
||||
const WebRtc_Word16 FrameLen, /* ms per frame */
|
||||
const WebRtc_Word16 BottleNeck, /* bottle neck rate; excl headers (bps) */
|
||||
const WebRtc_Word16 DelayBuildUp); /* max delay from bottle neck buffering (ms) */
|
||||
|
||||
/*
|
||||
* update long-term average bitrate and amount of data in buffer
|
||||
*/
|
||||
void WebRtcIsacfix_UpdateRateModel(RateModel *State,
|
||||
WebRtc_Word16 StreamSize, /* bytes in bitstream */
|
||||
const WebRtc_Word16 FrameSamples, /* samples per frame */
|
||||
const WebRtc_Word16 BottleNeck); /* bottle neck rate; excl headers (bps) */
|
||||
|
||||
|
||||
void WebRtcIsacfix_InitRateModel(RateModel *State);
|
||||
|
||||
/* Returns the new framelength value (input argument: bottle_neck) */
|
||||
WebRtc_Word16 WebRtcIsacfix_GetNewFrameLength(WebRtc_Word16 bottle_neck, WebRtc_Word16 current_framelength);
|
||||
|
||||
/* Returns the new SNR value (input argument: bottle_neck) */
|
||||
//returns snr in Q10
|
||||
WebRtc_Word16 WebRtcIsacfix_GetSnr(WebRtc_Word16 bottle_neck, WebRtc_Word16 framesamples);
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_BANDWIDTH_ESTIMATOR_H_ */
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* codec.h
|
||||
*
|
||||
* This header file contains the calls to the internal encoder
|
||||
* and decoder functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_CODEC_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_CODEC_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
int WebRtcIsacfix_EstimateBandwidth(BwEstimatorstr *bwest_str,
|
||||
Bitstr_dec *streamdata,
|
||||
WebRtc_Word32 packet_size,
|
||||
WebRtc_UWord16 rtp_seq_number,
|
||||
WebRtc_UWord32 send_ts,
|
||||
WebRtc_UWord32 arr_ts);
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_DecodeImpl(WebRtc_Word16 *signal_out16,
|
||||
ISACFIX_DecInst_t *ISACdec_obj,
|
||||
WebRtc_Word16 *current_framesamples);
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_DecodePlcImpl(WebRtc_Word16 *decoded,
|
||||
ISACFIX_DecInst_t *ISACdec_obj,
|
||||
WebRtc_Word16 *current_framesample );
|
||||
|
||||
int WebRtcIsacfix_EncodeImpl(WebRtc_Word16 *in,
|
||||
ISACFIX_EncInst_t *ISACenc_obj,
|
||||
BwEstimatorstr *bw_estimatordata,
|
||||
WebRtc_Word16 CodingMode);
|
||||
|
||||
int WebRtcIsacfix_EncodeStoredData(ISACFIX_EncInst_t *ISACenc_obj,
|
||||
int BWnumber,
|
||||
float scale);
|
||||
|
||||
/************************** initialization functions *************************/
|
||||
|
||||
void WebRtcIsacfix_InitMaskingEnc(MaskFiltstr_enc *maskdata);
|
||||
void WebRtcIsacfix_InitMaskingDec(MaskFiltstr_dec *maskdata);
|
||||
|
||||
void WebRtcIsacfix_InitPreFilterbank(PreFiltBankstr *prefiltdata);
|
||||
|
||||
void WebRtcIsacfix_InitPostFilterbank(PostFiltBankstr *postfiltdata);
|
||||
|
||||
void WebRtcIsacfix_InitPitchFilter(PitchFiltstr *pitchfiltdata);
|
||||
|
||||
void WebRtcIsacfix_InitPitchAnalysis(PitchAnalysisStruct *State);
|
||||
|
||||
void WebRtcIsacfix_InitPlc( PLCstr *State );
|
||||
|
||||
|
||||
/**************************** transform functions ****************************/
|
||||
|
||||
void WebRtcIsacfix_InitTransform();
|
||||
|
||||
|
||||
void WebRtcIsacfix_Time2Spec(WebRtc_Word16 *inre1Q9,
|
||||
WebRtc_Word16 *inre2Q9,
|
||||
WebRtc_Word16 *outre,
|
||||
WebRtc_Word16 *outim);
|
||||
|
||||
|
||||
|
||||
void WebRtcIsacfix_Spec2Time(WebRtc_Word16 *inreQ7,
|
||||
WebRtc_Word16 *inimQ7,
|
||||
WebRtc_Word32 *outre1Q16,
|
||||
WebRtc_Word32 *outre2Q16);
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************** filterbank functions **************************/
|
||||
|
||||
|
||||
|
||||
void WebRtcIsacfix_SplitAndFilter1(WebRtc_Word16 *in,
|
||||
WebRtc_Word16 *LP16,
|
||||
WebRtc_Word16 *HP16,
|
||||
PreFiltBankstr *prefiltdata);
|
||||
|
||||
void WebRtcIsacfix_FilterAndCombine1(WebRtc_Word16 *tempin_ch1,
|
||||
WebRtc_Word16 *tempin_ch2,
|
||||
WebRtc_Word16 *out16,
|
||||
PostFiltBankstr *postfiltdata);
|
||||
|
||||
#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
|
||||
void WebRtcIsacfix_SplitAndFilter2(WebRtc_Word16 *in,
|
||||
WebRtc_Word16 *LP16,
|
||||
WebRtc_Word16 *HP16,
|
||||
PreFiltBankstr *prefiltdata);
|
||||
|
||||
void WebRtcIsacfix_FilterAndCombine2(WebRtc_Word16 *tempin_ch1,
|
||||
WebRtc_Word16 *tempin_ch2,
|
||||
WebRtc_Word16 *out16,
|
||||
PostFiltBankstr *postfiltdata,
|
||||
WebRtc_Word16 len);
|
||||
|
||||
#endif
|
||||
|
||||
/************************* normalized lattice filters ************************/
|
||||
|
||||
|
||||
void WebRtcIsacfix_NormLatticeFilterMa(WebRtc_Word16 orderCoef,
|
||||
WebRtc_Word32 *stateGQ15,
|
||||
WebRtc_Word16 *lat_inQ0,
|
||||
WebRtc_Word16 *filt_coefQ15,
|
||||
WebRtc_Word32 *gain_lo_hiQ17,
|
||||
WebRtc_Word16 lo_hi,
|
||||
WebRtc_Word16 *lat_outQ9);
|
||||
|
||||
void WebRtcIsacfix_NormLatticeFilterAr(WebRtc_Word16 orderCoef,
|
||||
WebRtc_Word16 *stateGQ0,
|
||||
WebRtc_Word32 *lat_inQ25,
|
||||
WebRtc_Word16 *filt_coefQ15,
|
||||
WebRtc_Word32 *gain_lo_hiQ17,
|
||||
WebRtc_Word16 lo_hi,
|
||||
WebRtc_Word16 *lat_outQ0);
|
||||
|
||||
int WebRtcIsacfix_AutocorrC(WebRtc_Word32* __restrict r,
|
||||
const WebRtc_Word16* __restrict x,
|
||||
WebRtc_Word16 N,
|
||||
WebRtc_Word16 order,
|
||||
WebRtc_Word16* __restrict scale);
|
||||
|
||||
void WebRtcIsacfix_FilterMaLoopC(int16_t input0,
|
||||
int16_t input1,
|
||||
int32_t input2,
|
||||
int32_t* ptr0,
|
||||
int32_t* ptr1,
|
||||
int32_t* ptr2);
|
||||
|
||||
// Functions for ARM-Neon platforms, in place of the above two generic C ones.
|
||||
#if (defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM_NEON))
|
||||
int WebRtcIsacfix_AutocorrNeon(WebRtc_Word32* __restrict r,
|
||||
const WebRtc_Word16* __restrict x,
|
||||
WebRtc_Word16 N,
|
||||
WebRtc_Word16 order,
|
||||
WebRtc_Word16* __restrict scale);
|
||||
|
||||
void WebRtcIsacfix_FilterMaLoopNeon(int16_t input0,
|
||||
int16_t input1,
|
||||
int32_t input2,
|
||||
int32_t* ptr0,
|
||||
int32_t* ptr1,
|
||||
int32_t* ptr2);
|
||||
#endif
|
||||
|
||||
/**** Function pointers associated with
|
||||
**** WebRtcIsacfix_AutocorrC() / WebRtcIsacfix_AutocorrNeon()
|
||||
**** and WebRtcIsacfix_FilterMaLoopC() / WebRtcIsacfix_FilterMaLoopNeon().
|
||||
****/
|
||||
|
||||
typedef int (*AutocorrFix)(WebRtc_Word32* __restrict r,
|
||||
const WebRtc_Word16* __restrict x,
|
||||
WebRtc_Word16 N,
|
||||
WebRtc_Word16 order,
|
||||
WebRtc_Word16* __restrict scale);
|
||||
extern AutocorrFix WebRtcIsacfix_AutocorrFix;
|
||||
|
||||
typedef void (*FilterMaLoopFix)(int16_t input0,
|
||||
int16_t input1,
|
||||
int32_t input2,
|
||||
int32_t* ptr0,
|
||||
int32_t* ptr1,
|
||||
int32_t* ptr2);
|
||||
extern FilterMaLoopFix WebRtcIsacfix_FilterMaLoopFix;
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_CODEC_H_ */
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* decode.c
|
||||
*
|
||||
* This C file contains the internal decoding function.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bandwidth_estimator.h"
|
||||
#include "codec.h"
|
||||
#include "entropy_coding.h"
|
||||
#include "pitch_estimator.h"
|
||||
#include "settings.h"
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_DecodeImpl(WebRtc_Word16 *signal_out16,
|
||||
ISACFIX_DecInst_t *ISACdec_obj,
|
||||
WebRtc_Word16 *current_framesamples)
|
||||
{
|
||||
int k;
|
||||
int err;
|
||||
WebRtc_Word16 BWno;
|
||||
WebRtc_Word16 len = 0;
|
||||
|
||||
WebRtc_Word16 model;
|
||||
|
||||
|
||||
WebRtc_Word16 Vector_Word16_1[FRAMESAMPLES/2];
|
||||
WebRtc_Word16 Vector_Word16_2[FRAMESAMPLES/2];
|
||||
|
||||
WebRtc_Word32 Vector_Word32_1[FRAMESAMPLES/2];
|
||||
WebRtc_Word32 Vector_Word32_2[FRAMESAMPLES/2];
|
||||
|
||||
WebRtc_Word16 lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs
|
||||
WebRtc_Word16 hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs
|
||||
WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES];
|
||||
|
||||
WebRtc_Word16 PitchLags_Q7[PITCH_SUBFRAMES];
|
||||
WebRtc_Word16 PitchGains_Q12[PITCH_SUBFRAMES];
|
||||
WebRtc_Word16 AvgPitchGain_Q12;
|
||||
|
||||
WebRtc_Word16 tmp_1, tmp_2;
|
||||
WebRtc_Word32 tmp32a, tmp32b;
|
||||
WebRtc_Word16 gainQ13;
|
||||
|
||||
|
||||
WebRtc_Word16 frame_nb; /* counter */
|
||||
WebRtc_Word16 frame_mode; /* 0 for 20ms and 30ms, 1 for 60ms */
|
||||
WebRtc_Word16 processed_samples;
|
||||
|
||||
/* PLC */
|
||||
WebRtc_Word16 overlapWin[ 240 ];
|
||||
|
||||
(ISACdec_obj->bitstr_obj).W_upper = 0xFFFFFFFF;
|
||||
(ISACdec_obj->bitstr_obj).streamval = 0;
|
||||
(ISACdec_obj->bitstr_obj).stream_index = 0;
|
||||
(ISACdec_obj->bitstr_obj).full = 1;
|
||||
|
||||
|
||||
/* decode framelength and BW estimation - not used, only for stream pointer*/
|
||||
err = WebRtcIsacfix_DecodeFrameLen(&ISACdec_obj->bitstr_obj, current_framesamples);
|
||||
if (err<0) // error check
|
||||
return err;
|
||||
|
||||
frame_mode = (WebRtc_Word16)WEBRTC_SPL_DIV(*current_framesamples, MAX_FRAMESAMPLES); /* 0, or 1 */
|
||||
processed_samples = (WebRtc_Word16)WEBRTC_SPL_DIV(*current_framesamples, frame_mode+1); /* either 320 (20ms) or 480 (30, 60 ms) */
|
||||
|
||||
err = WebRtcIsacfix_DecodeSendBandwidth(&ISACdec_obj->bitstr_obj, &BWno);
|
||||
if (err<0) // error check
|
||||
return err;
|
||||
|
||||
/* one loop if it's one frame (20 or 30ms), 2 loops if 2 frames bundled together (60ms) */
|
||||
for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {
|
||||
|
||||
/* decode & dequantize pitch parameters */
|
||||
err = WebRtcIsacfix_DecodePitchGain(&(ISACdec_obj->bitstr_obj), PitchGains_Q12);
|
||||
if (err<0) // error check
|
||||
return err;
|
||||
|
||||
err = WebRtcIsacfix_DecodePitchLag(&ISACdec_obj->bitstr_obj, PitchGains_Q12, PitchLags_Q7);
|
||||
if (err<0) // error check
|
||||
return err;
|
||||
|
||||
AvgPitchGain_Q12 = (WebRtc_Word16)(((WebRtc_Word32)PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3])>>2);
|
||||
|
||||
/* decode & dequantize FiltCoef */
|
||||
err = WebRtcIsacfix_DecodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
|
||||
&ISACdec_obj->bitstr_obj, &model);
|
||||
|
||||
if (err<0) // error check
|
||||
return err;
|
||||
|
||||
/* decode & dequantize spectrum */
|
||||
len = WebRtcIsacfix_DecodeSpec(&ISACdec_obj->bitstr_obj, Vector_Word16_1, Vector_Word16_2, AvgPitchGain_Q12);
|
||||
if (len < 0) // error check
|
||||
return len;
|
||||
|
||||
// Why does this need Q16 in and out? /JS
|
||||
WebRtcIsacfix_Spec2Time(Vector_Word16_1, Vector_Word16_2, Vector_Word32_1, Vector_Word32_2);
|
||||
|
||||
for (k=0; k<FRAMESAMPLES/2; k++) {
|
||||
Vector_Word16_1[k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(Vector_Word32_1[k]+64, 7); //Q16 -> Q9
|
||||
}
|
||||
|
||||
/* ---- If this is recovery frame ---- */
|
||||
if( (ISACdec_obj->plcstr_obj).used == PLC_WAS_USED )
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).used = PLC_NOT_USED;
|
||||
if( (ISACdec_obj->plcstr_obj).B < 1000 )
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffPriodic = 4000;
|
||||
}
|
||||
|
||||
ISACdec_obj->plcstr_obj.decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX; /* DECAY_RATE is in Q15 */
|
||||
ISACdec_obj->plcstr_obj.decayCoeffNoise = WEBRTC_SPL_WORD16_MAX; /* DECAY_RATE is in Q15 */
|
||||
ISACdec_obj->plcstr_obj.pitchCycles = 0;
|
||||
|
||||
PitchGains_Q12[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[0], 700, 10 );
|
||||
|
||||
/* ---- Add-overlap ---- */
|
||||
WebRtcSpl_GetHanningWindow( overlapWin, RECOVERY_OVERLAP );
|
||||
for( k = 0; k < RECOVERY_OVERLAP; k++ )
|
||||
Vector_Word16_1[k] = WEBRTC_SPL_ADD_SAT_W16(
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( (ISACdec_obj->plcstr_obj).overlapLP[k], overlapWin[RECOVERY_OVERLAP - k - 1], 14),
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( Vector_Word16_1[k], overlapWin[k], 14) );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* --- Store side info --- */
|
||||
if( frame_nb == frame_mode )
|
||||
{
|
||||
/* --- LPC info */
|
||||
WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).lofilt_coefQ15, &lofilt_coefQ15[(SUBFRAMES-1)*ORDERLO], ORDERLO );
|
||||
WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).hifilt_coefQ15, &hifilt_coefQ15[(SUBFRAMES-1)*ORDERHI], ORDERHI );
|
||||
(ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0] = gain_lo_hiQ17[(SUBFRAMES-1) * 2];
|
||||
(ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1] = gain_lo_hiQ17[(SUBFRAMES-1) * 2 + 1];
|
||||
|
||||
/* --- LTP info */
|
||||
(ISACdec_obj->plcstr_obj).AvgPitchGain_Q12 = PitchGains_Q12[3];
|
||||
(ISACdec_obj->plcstr_obj).lastPitchGain_Q12 = PitchGains_Q12[3];
|
||||
(ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = PitchLags_Q7[3];
|
||||
|
||||
if( PitchLags_Q7[3] < 3000 )
|
||||
(ISACdec_obj->plcstr_obj).lastPitchLag_Q7 += PitchLags_Q7[3];
|
||||
|
||||
WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvIn, Vector_Word16_1, FRAMESAMPLES/2 );
|
||||
|
||||
}
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/* inverse pitch filter */
|
||||
WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, &ISACdec_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 4);
|
||||
|
||||
if( frame_nb == frame_mode )
|
||||
{
|
||||
WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvOut, &(Vector_Word16_2[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10)]), PITCH_MAX_LAG );
|
||||
}
|
||||
|
||||
|
||||
/* reduce gain to compensate for pitch enhancer */
|
||||
/* gain = 1.0f - 0.45f * AvgPitchGain; */
|
||||
tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(AvgPitchGain_Q12, 29, 0); // Q18
|
||||
tmp32b = 262144 - tmp32a; // Q18
|
||||
gainQ13 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q13
|
||||
|
||||
for (k = 0; k < FRAMESAMPLES/2; k++)
|
||||
{
|
||||
Vector_Word32_1[k] = (WebRtc_Word32) WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(Vector_Word16_2[k], gainQ13), 3); // Q25
|
||||
}
|
||||
|
||||
|
||||
/* perceptual post-filtering (using normalized lattice filter) */
|
||||
WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0,
|
||||
Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1);
|
||||
|
||||
/* --- Store Highpass Residual --- */
|
||||
for (k = 0; k < FRAMESAMPLES/2; k++)
|
||||
Vector_Word32_1[k] = WEBRTC_SPL_LSHIFT_W32(Vector_Word32_2[k], 9); // Q16 -> Q25
|
||||
|
||||
for( k = 0; k < PITCH_MAX_LAG + 10; k++ )
|
||||
(ISACdec_obj->plcstr_obj).prevHP[k] = Vector_Word32_1[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10) + k];
|
||||
|
||||
|
||||
WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0,
|
||||
Vector_Word32_1, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2);
|
||||
|
||||
/* recombine the 2 bands */
|
||||
|
||||
/* Form the polyphase signals, and compensate for DC offset */
|
||||
for (k=0;k<FRAMESAMPLES/2;k++) {
|
||||
tmp_1 = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(((WebRtc_Word32)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)); /* Construct a new upper channel signal*/
|
||||
tmp_2 = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(((WebRtc_Word32)Vector_Word16_1[k]-Vector_Word16_2[k])); /* Construct a new lower channel signal*/
|
||||
Vector_Word16_1[k] = tmp_1;
|
||||
Vector_Word16_2[k] = tmp_2;
|
||||
}
|
||||
|
||||
WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1, Vector_Word16_2, signal_out16 + frame_nb * processed_samples, &ISACdec_obj->postfiltbankstr_obj);
|
||||
|
||||
}
|
||||
return len;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* decode_bwe.c
|
||||
*
|
||||
* This C file contains the internal decode bandwidth estimate function.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bandwidth_estimator.h"
|
||||
#include "codec.h"
|
||||
#include "entropy_coding.h"
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
|
||||
|
||||
int WebRtcIsacfix_EstimateBandwidth(BwEstimatorstr *bwest_str,
|
||||
Bitstr_dec *streamdata,
|
||||
WebRtc_Word32 packet_size,
|
||||
WebRtc_UWord16 rtp_seq_number,
|
||||
WebRtc_UWord32 send_ts,
|
||||
WebRtc_UWord32 arr_ts)
|
||||
{
|
||||
WebRtc_Word16 index;
|
||||
WebRtc_Word16 frame_samples;
|
||||
int err;
|
||||
|
||||
/* decode framelength */
|
||||
err = WebRtcIsacfix_DecodeFrameLen(streamdata, &frame_samples);
|
||||
/* error check */
|
||||
if (err<0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* decode BW estimation */
|
||||
err = WebRtcIsacfix_DecodeSendBandwidth(streamdata, &index);
|
||||
/* error check */
|
||||
if (err<0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Update BWE with received data */
|
||||
err = WebRtcIsacfix_UpdateUplinkBwImpl(
|
||||
bwest_str,
|
||||
rtp_seq_number,
|
||||
(WebRtc_UWord16)WEBRTC_SPL_UDIV(WEBRTC_SPL_UMUL(frame_samples,1000), FS),
|
||||
send_ts,
|
||||
arr_ts,
|
||||
(WebRtc_Word16) packet_size, /* in bytes */
|
||||
index);
|
||||
|
||||
/* error check */
|
||||
if (err<0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Succesful */
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,830 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* decode_plc.c
|
||||
*
|
||||
* Packet Loss Concealment.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "settings.h"
|
||||
#include "entropy_coding.h"
|
||||
#include "pitch_estimator.h"
|
||||
#include "bandwidth_estimator.h"
|
||||
#include "structs.h"
|
||||
#include "codec.h"
|
||||
|
||||
|
||||
#define NO_OF_PRIMES 8
|
||||
#define NOISE_FILTER_LEN 30
|
||||
|
||||
/*
|
||||
* function to decode the bitstream
|
||||
* returns the total number of bytes in the stream
|
||||
*/
|
||||
|
||||
static WebRtc_Word16 plc_filterma_Fast(
|
||||
WebRtc_Word16 *In, /* (i) Vector to be filtered. InOut[-orderCoef+1]
|
||||
to InOut[-1] contains state */
|
||||
WebRtc_Word16 *Out, /* (o) Filtered vector */
|
||||
WebRtc_Word16 *B, /* (i) The filter coefficients (in Q0) */
|
||||
WebRtc_Word16 Blen, /* (i) Number of B coefficients */
|
||||
WebRtc_Word16 len, /* (i) Number of samples to be filtered */
|
||||
WebRtc_Word16 reduceDecay,
|
||||
WebRtc_Word16 decay,
|
||||
WebRtc_Word16 rshift )
|
||||
{
|
||||
int i, j;
|
||||
WebRtc_Word32 o;
|
||||
WebRtc_Word32 lim;
|
||||
|
||||
lim = WEBRTC_SPL_LSHIFT_W32( (WebRtc_Word32)1, 15 + rshift )-1;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
G_CONST WebRtc_Word16 *b_ptr = &B[0];
|
||||
G_CONST WebRtc_Word16 *x_ptr = &In[i];
|
||||
|
||||
o = (WebRtc_Word32)0;
|
||||
|
||||
for (j = 0;j < Blen; j++)
|
||||
{
|
||||
o = WEBRTC_SPL_ADD_SAT_W32( o, WEBRTC_SPL_MUL_16_16( *b_ptr, *x_ptr) );
|
||||
b_ptr++;
|
||||
x_ptr--;
|
||||
}
|
||||
|
||||
/* to round off correctly */
|
||||
o = WEBRTC_SPL_ADD_SAT_W32( o, WEBRTC_SPL_LSHIFT_W32( 1, (rshift-1) ) );
|
||||
|
||||
/* saturate according to the domain of the filter coefficients */
|
||||
o = WEBRTC_SPL_SAT((WebRtc_Word32)lim, o, (WebRtc_Word32)-lim);
|
||||
|
||||
/* o should be in the range of WebRtc_Word16 */
|
||||
o = WEBRTC_SPL_RSHIFT_W32( o, rshift );
|
||||
|
||||
/* decay the output signal; this is specific to plc */
|
||||
*Out++ = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16)o, decay, 15); // ((o + (WebRtc_Word32)2048) >> 12);
|
||||
|
||||
/* change the decay */
|
||||
decay -= reduceDecay;
|
||||
if( decay < 0 )
|
||||
decay = 0;
|
||||
}
|
||||
return( decay );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline WebRtc_Word32 log2_Q8_T( WebRtc_UWord32 x ) {
|
||||
|
||||
WebRtc_Word32 zeros, lg2;
|
||||
WebRtc_Word16 frac;
|
||||
|
||||
zeros=WebRtcSpl_NormU32(x);
|
||||
frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(((WebRtc_UWord32)WEBRTC_SPL_LSHIFT_W32(x, zeros)&0x7FFFFFFF), 23);
|
||||
/* log2(magn(i)) */
|
||||
|
||||
lg2= (WEBRTC_SPL_LSHIFT_W16((31-zeros), 8)+frac);
|
||||
return lg2;
|
||||
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word16 exp2_Q10_T(WebRtc_Word16 x) { // Both in and out in Q10
|
||||
|
||||
WebRtc_Word16 tmp16_1, tmp16_2;
|
||||
|
||||
tmp16_2=(WebRtc_Word16)(0x0400|(x&0x03FF));
|
||||
tmp16_1=-(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(x,10);
|
||||
if(tmp16_1>0)
|
||||
return (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
|
||||
else
|
||||
return (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This is a fixed-point version of the above code with limLow = 700 and limHigh = 5000,
|
||||
hard-coded. The values 700 and 5000 were experimentally obtained.
|
||||
|
||||
The function implements membership values for two sets. The mebership functions are
|
||||
of second orders corresponding to half-bell-shapped pulses.
|
||||
*/
|
||||
static void MemshipValQ15( WebRtc_Word16 in, WebRtc_Word16 *A, WebRtc_Word16 *B )
|
||||
{
|
||||
WebRtc_Word16 x;
|
||||
|
||||
in -= 700; /* translate the lowLim to 0, limHigh = 5000 - 700, M = 2150 */
|
||||
|
||||
if( in <= 2150 )
|
||||
{
|
||||
if( in > 0 )
|
||||
{
|
||||
/* b = in^2 / (2 * M^2), a = 1 - b in Q0.
|
||||
We have to compute in Q15 */
|
||||
|
||||
/* x = in / 2150 {in Q15} = x * 15.2409 {in Q15} =
|
||||
x*15 + (x*983)/(2^12); note that 983/2^12 = 0.23999 */
|
||||
|
||||
/* we are sure that x is in the range of WebRtc_Word16 */
|
||||
x = (WebRtc_Word16)( WEBRTC_SPL_MUL_16_16( in, 15 ) +
|
||||
WEBRTC_SPL_MUL_16_16_RSFT( in, 983, 12) );
|
||||
/* b = x^2 / 2 {in Q15} so a shift of 16 is required to
|
||||
be in correct domain and one more for the division by 2 */
|
||||
*B = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( WEBRTC_SPL_MUL_16_16( x, x ) + 0x00010000, 17 );
|
||||
*A = WEBRTC_SPL_WORD16_MAX - *B;
|
||||
}
|
||||
else
|
||||
{
|
||||
*B = 0;
|
||||
*A = WEBRTC_SPL_WORD16_MAX;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( in < 4300 )
|
||||
{
|
||||
/* This is a mirror case of the above */
|
||||
in = 4300 - in;
|
||||
x = (WebRtc_Word16)( WEBRTC_SPL_MUL_16_16( in, 15 ) +
|
||||
WEBRTC_SPL_MUL_16_16_RSFT( in, 983, 12) );
|
||||
/* b = x^2 / 2 {in Q15} so a shift of 16 is required to
|
||||
be in correct domain and one more for the division by 2 */
|
||||
*A = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( WEBRTC_SPL_MUL_16_16( x, x ) + 0x00010000, 17 );
|
||||
*B = WEBRTC_SPL_WORD16_MAX - *A;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
*A = 0;
|
||||
*B = WEBRTC_SPL_WORD16_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void LinearResampler( WebRtc_Word16 *in, WebRtc_Word16 *out, WebRtc_Word16 lenIn, WebRtc_Word16 lenOut )
|
||||
{
|
||||
WebRtc_Word32 n;
|
||||
WebRtc_Word16 resOut, i, j, relativePos, diff; /* */
|
||||
WebRtc_UWord16 udiff;
|
||||
|
||||
if( lenIn == lenOut )
|
||||
{
|
||||
WEBRTC_SPL_MEMCPY_W16( out, in, lenIn );
|
||||
return;
|
||||
}
|
||||
|
||||
n = WEBRTC_SPL_MUL_16_16( (WebRtc_Word16)(lenIn-1), RESAMP_RES );
|
||||
resOut = WebRtcSpl_DivW32W16ResW16( n, (WebRtc_Word16)(lenOut-1) );
|
||||
|
||||
out[0] = in[0];
|
||||
for( i = 1, j = 0, relativePos = 0; i < lenOut; i++ )
|
||||
{
|
||||
|
||||
relativePos += resOut;
|
||||
while( relativePos > RESAMP_RES )
|
||||
{
|
||||
j++;
|
||||
relativePos -= RESAMP_RES;
|
||||
}
|
||||
|
||||
|
||||
/* an overflow may happen and the differce in sample values may
|
||||
* require more than 16 bits. We like to avoid 32 bit arithmatic
|
||||
* as much as possible */
|
||||
|
||||
if( (in[ j ] > 0) && (in[j + 1] < 0) )
|
||||
{
|
||||
udiff = (WebRtc_UWord16)(in[ j ] - in[j + 1]);
|
||||
out[ i ] = in[ j ] - (WebRtc_UWord16)( ((WebRtc_Word32)( udiff * relativePos )) >> RESAMP_RES_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (in[j] < 0) && (in[j+1] > 0) )
|
||||
{
|
||||
udiff = (WebRtc_UWord16)( in[j + 1] - in[ j ] );
|
||||
out[ i ] = in[ j ] + (WebRtc_UWord16)( ((WebRtc_Word32)( udiff * relativePos )) >> RESAMP_RES_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
diff = in[ j + 1 ] - in[ j ];
|
||||
out[ i ] = in[ j ] + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( diff, relativePos, RESAMP_RES_BIT );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_DecodePlcImpl(WebRtc_Word16 *signal_out16,
|
||||
ISACFIX_DecInst_t *ISACdec_obj,
|
||||
WebRtc_Word16 *current_framesamples )
|
||||
{
|
||||
int subframecnt;
|
||||
WebRtc_Word16 len = 0;
|
||||
|
||||
WebRtc_Word16* Vector_Word16_1;
|
||||
WebRtc_Word16 Vector_Word16_Extended_1[FRAMESAMPLES_HALF + NOISE_FILTER_LEN];
|
||||
WebRtc_Word16* Vector_Word16_2;
|
||||
WebRtc_Word16 Vector_Word16_Extended_2[FRAMESAMPLES_HALF + NOISE_FILTER_LEN];
|
||||
|
||||
WebRtc_Word32 Vector_Word32_1[FRAMESAMPLES_HALF];
|
||||
WebRtc_Word32 Vector_Word32_2[FRAMESAMPLES_HALF];
|
||||
|
||||
WebRtc_Word16 lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs
|
||||
WebRtc_Word16 hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs
|
||||
|
||||
WebRtc_Word16 pitchLags_Q7[PITCH_SUBFRAMES];
|
||||
WebRtc_Word16 pitchGains_Q12[PITCH_SUBFRAMES];
|
||||
|
||||
WebRtc_Word16 tmp_1, tmp_2;
|
||||
WebRtc_Word32 tmp32a, tmp32b;
|
||||
WebRtc_Word16 gainQ13;
|
||||
|
||||
WebRtc_Word16 myDecayRate;
|
||||
|
||||
/* ---------- PLC variables ------------ */
|
||||
WebRtc_Word16 lag0, i, k, noiseIndex;
|
||||
WebRtc_Word16 stretchPitchLP[PITCH_MAX_LAG + 10], stretchPitchLP1[PITCH_MAX_LAG + 10];
|
||||
|
||||
WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES];
|
||||
|
||||
WebRtc_Word16 nLP, pLP, wNoisyLP, wPriodicLP, tmp16, minIdx;
|
||||
WebRtc_Word32 nHP, pHP, wNoisyHP, wPriodicHP, corr, minCorr, maxCoeff;
|
||||
WebRtc_Word16 noise1, rshift;
|
||||
|
||||
|
||||
WebRtc_Word16 ltpGain, pitchGain, myVoiceIndicator, myAbs, maxAbs;
|
||||
WebRtc_Word32 varIn, varOut, logVarIn, logVarOut, Q, logMaxAbs;
|
||||
int rightShiftIn, rightShiftOut;
|
||||
|
||||
|
||||
/* ------------------------------------- */
|
||||
|
||||
|
||||
myDecayRate = (DECAY_RATE);
|
||||
Vector_Word16_1 = &Vector_Word16_Extended_1[NOISE_FILTER_LEN];
|
||||
Vector_Word16_2 = &Vector_Word16_Extended_2[NOISE_FILTER_LEN];
|
||||
|
||||
|
||||
/* ----- Simply Copy Previous LPC parameters ------ */
|
||||
for( subframecnt = 0; subframecnt < SUBFRAMES; subframecnt++ )
|
||||
{
|
||||
/* lower Band */
|
||||
WEBRTC_SPL_MEMCPY_W16(&lofilt_coefQ15[ subframecnt * ORDERLO ],
|
||||
(ISACdec_obj->plcstr_obj).lofilt_coefQ15, ORDERLO);
|
||||
gain_lo_hiQ17[2*subframecnt] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0];
|
||||
|
||||
/* Upper Band */
|
||||
WEBRTC_SPL_MEMCPY_W16(&hifilt_coefQ15[ subframecnt * ORDERHI ],
|
||||
(ISACdec_obj->plcstr_obj).hifilt_coefQ15, ORDERHI);
|
||||
gain_lo_hiQ17[2*subframecnt + 1] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
lag0 = WEBRTC_SPL_RSHIFT_W16(
|
||||
(ISACdec_obj->plcstr_obj).lastPitchLag_Q7 + 64, 7 ) + 1;
|
||||
|
||||
|
||||
if( (ISACdec_obj->plcstr_obj).used != PLC_WAS_USED )
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).pitchCycles = 0;
|
||||
|
||||
(ISACdec_obj->plcstr_obj).lastPitchLP =
|
||||
&((ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0]);
|
||||
minCorr = WEBRTC_SPL_WORD32_MAX;
|
||||
|
||||
if ( (FRAMESAMPLES_HALF - 2*lag0 - 10) > 0 )
|
||||
{
|
||||
minIdx = 11;
|
||||
for( i = 0; i < 21; i++ )
|
||||
{
|
||||
corr = 0;
|
||||
for( k = 0; k < lag0; k++ )
|
||||
{
|
||||
corr = WEBRTC_SPL_ADD_SAT_W32( corr, WEBRTC_SPL_ABS_W32(
|
||||
WEBRTC_SPL_SUB_SAT_W16(
|
||||
(ISACdec_obj->plcstr_obj).lastPitchLP[k],
|
||||
(ISACdec_obj->plcstr_obj).prevPitchInvIn[
|
||||
FRAMESAMPLES_HALF - 2*lag0 - 10 + i + k ] ) ) );
|
||||
}
|
||||
if( corr < minCorr )
|
||||
{
|
||||
minCorr = corr;
|
||||
minIdx = i;
|
||||
}
|
||||
}
|
||||
(ISACdec_obj->plcstr_obj).prevPitchLP =
|
||||
&( (ISACdec_obj->plcstr_obj).prevPitchInvIn[
|
||||
FRAMESAMPLES_HALF - lag0*2 - 10 + minIdx] );
|
||||
}
|
||||
else
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).prevPitchLP =
|
||||
(ISACdec_obj->plcstr_obj).lastPitchLP;
|
||||
}
|
||||
pitchGain = (ISACdec_obj->plcstr_obj).lastPitchGain_Q12;
|
||||
|
||||
WebRtcSpl_AutoCorrelation(
|
||||
&(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0],
|
||||
lag0, 0, &varIn, &rightShiftIn);
|
||||
WebRtcSpl_AutoCorrelation(
|
||||
&(ISACdec_obj->plcstr_obj).prevPitchInvOut[PITCH_MAX_LAG + 10 - lag0],
|
||||
lag0, 0, &varOut, &rightShiftOut);
|
||||
|
||||
maxAbs = 0;
|
||||
for( i = 0; i< lag0; i++)
|
||||
{
|
||||
myAbs = WEBRTC_SPL_ABS_W16(
|
||||
(ISACdec_obj->plcstr_obj).prevPitchInvOut[
|
||||
PITCH_MAX_LAG + 10 - lag0 + i] );
|
||||
maxAbs = (myAbs > maxAbs)? myAbs:maxAbs;
|
||||
}
|
||||
logVarIn = log2_Q8_T( (WebRtc_UWord32)( varIn ) ) +
|
||||
(WebRtc_Word32)(rightShiftIn << 8);
|
||||
logVarOut = log2_Q8_T( (WebRtc_UWord32)( varOut ) ) +
|
||||
(WebRtc_Word32)(rightShiftOut << 8);
|
||||
logMaxAbs = log2_Q8_T( (WebRtc_UWord32)( maxAbs ) );
|
||||
|
||||
ltpGain = (WebRtc_Word16)(logVarOut - logVarIn);
|
||||
Q = 2 * logMaxAbs - ( logVarOut - 1512 );
|
||||
|
||||
/*
|
||||
* ---
|
||||
* We are computing sqrt( (VarIn/lag0) / var( noise ) )
|
||||
* var( noise ) is almost 256. we have already computed log2( VarIn ) in Q8
|
||||
* so we actually compute 2^( 0.5*(log2( VarIn ) - log2( lag0 ) - log2( var(noise ) ) ).
|
||||
* Note that put log function is in Q8 but the exponential function is in Q10.
|
||||
* --
|
||||
*/
|
||||
|
||||
logVarIn -= log2_Q8_T( (WebRtc_UWord32)( lag0 ) );
|
||||
tmp16 = (WebRtc_Word16)((logVarIn<<1) - (4<<10) );
|
||||
rightShiftIn = 0;
|
||||
if( tmp16 > 4096 )
|
||||
{
|
||||
tmp16 -= 4096;
|
||||
tmp16 = exp2_Q10_T( tmp16 );
|
||||
tmp16 >>= 6;
|
||||
}
|
||||
else
|
||||
tmp16 = exp2_Q10_T( tmp16 )>>10;
|
||||
|
||||
(ISACdec_obj->plcstr_obj).std = tmp16 - 4;
|
||||
|
||||
if( (ltpGain < 110) || (ltpGain > 230) )
|
||||
{
|
||||
if( ltpGain < 100 && (pitchGain < 1800) )
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).A = WEBRTC_SPL_WORD16_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).A = ((ltpGain < 110) && (Q < 800)
|
||||
)? WEBRTC_SPL_WORD16_MAX:0;
|
||||
}
|
||||
(ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX -
|
||||
(ISACdec_obj->plcstr_obj).A;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (pitchGain < 450) || (pitchGain > 1600) )
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).A = ((pitchGain < 450)
|
||||
)? WEBRTC_SPL_WORD16_MAX:0;
|
||||
(ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX -
|
||||
(ISACdec_obj->plcstr_obj).A;
|
||||
}
|
||||
else
|
||||
{
|
||||
myVoiceIndicator = ltpGain * 2 + pitchGain;
|
||||
MemshipValQ15( myVoiceIndicator,
|
||||
&(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
myVoiceIndicator = ltpGain * 16 + pitchGain * 2 + (pitchGain >> 8);
|
||||
MemshipValQ15( myVoiceIndicator,
|
||||
&(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B );
|
||||
|
||||
|
||||
|
||||
(ISACdec_obj->plcstr_obj).stretchLag = lag0;
|
||||
(ISACdec_obj->plcstr_obj).pitchIndex = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
myDecayRate = (DECAY_RATE<<2);
|
||||
}
|
||||
|
||||
if( (ISACdec_obj->plcstr_obj).B < 1000 )
|
||||
{
|
||||
myDecayRate += (DECAY_RATE<<3);
|
||||
}
|
||||
|
||||
/* ------------ reconstructing the residual signal ------------------ */
|
||||
|
||||
LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP,
|
||||
stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
|
||||
/* inverse pitch filter */
|
||||
|
||||
pitchLags_Q7[0] = pitchLags_Q7[1] = pitchLags_Q7[2] = pitchLags_Q7[3] =
|
||||
((ISACdec_obj->plcstr_obj).stretchLag<<7);
|
||||
pitchGains_Q12[3] = ( (ISACdec_obj->plcstr_obj).lastPitchGain_Q12);
|
||||
pitchGains_Q12[2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
|
||||
pitchGains_Q12[3], 1010, 10 );
|
||||
pitchGains_Q12[1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
|
||||
pitchGains_Q12[2], 1010, 10 );
|
||||
pitchGains_Q12[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
|
||||
pitchGains_Q12[1], 1010, 10 );
|
||||
|
||||
|
||||
/* most of the time either B or A are zero so seperating */
|
||||
if( (ISACdec_obj->plcstr_obj).B == 0 )
|
||||
{
|
||||
for( i = 0; i < FRAMESAMPLES_HALF; i++ )
|
||||
{
|
||||
/* --- Low Pass */
|
||||
(ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
|
||||
(ISACdec_obj->plcstr_obj).seed );
|
||||
Vector_Word16_1[i] = WEBRTC_SPL_RSHIFT_W16(
|
||||
(ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
|
||||
|
||||
/* --- Highpass */
|
||||
(ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
|
||||
(ISACdec_obj->plcstr_obj).seed );
|
||||
Vector_Word16_2[i] = WEBRTC_SPL_RSHIFT_W16(
|
||||
(ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
|
||||
|
||||
}
|
||||
for( i = 1; i < NOISE_FILTER_LEN; i++ )
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
|
||||
(ISACdec_obj->plcstr_obj).seed );
|
||||
Vector_Word16_Extended_1[ i ] = WEBRTC_SPL_RSHIFT_W16(
|
||||
(ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
|
||||
|
||||
(ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
|
||||
(ISACdec_obj->plcstr_obj).seed );
|
||||
Vector_Word16_Extended_2[ i ] = WEBRTC_SPL_RSHIFT_W16(
|
||||
(ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
|
||||
}
|
||||
plc_filterma_Fast(Vector_Word16_1, Vector_Word16_Extended_1,
|
||||
&(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF -
|
||||
NOISE_FILTER_LEN], (WebRtc_Word16) NOISE_FILTER_LEN,
|
||||
(WebRtc_Word16) FRAMESAMPLES_HALF, (WebRtc_Word16)(5),
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffNoise, (WebRtc_Word16)(6));
|
||||
|
||||
maxCoeff = WebRtcSpl_MaxAbsValueW32(
|
||||
&(ISACdec_obj->plcstr_obj).prevHP[
|
||||
PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN], NOISE_FILTER_LEN );
|
||||
|
||||
rshift = 0;
|
||||
while( maxCoeff > WEBRTC_SPL_WORD16_MAX )
|
||||
{
|
||||
maxCoeff = WEBRTC_SPL_RSHIFT_W32(maxCoeff, 1);
|
||||
rshift++;
|
||||
}
|
||||
for( i = 0; i < NOISE_FILTER_LEN; i++ ) {
|
||||
Vector_Word16_1[ FRAMESAMPLES_HALF - NOISE_FILTER_LEN + i] =
|
||||
(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(ISACdec_obj->plcstr_obj).prevHP[
|
||||
PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN + i], rshift);
|
||||
}
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffNoise = plc_filterma_Fast(
|
||||
Vector_Word16_2,
|
||||
Vector_Word16_Extended_2,
|
||||
&Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN],
|
||||
(WebRtc_Word16) NOISE_FILTER_LEN,
|
||||
(WebRtc_Word16) FRAMESAMPLES_HALF,
|
||||
(WebRtc_Word16) (5),
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffNoise,
|
||||
(WebRtc_Word16) (7) );
|
||||
|
||||
for( i = 0; i < FRAMESAMPLES_HALF; i++ )
|
||||
Vector_Word32_2[i] = WEBRTC_SPL_LSHIFT_W32(
|
||||
(WebRtc_Word32)Vector_Word16_Extended_2[i], rshift );
|
||||
|
||||
Vector_Word16_1 = Vector_Word16_Extended_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (ISACdec_obj->plcstr_obj).A == 0 )
|
||||
{
|
||||
/* ------ Periodic Vector --- */
|
||||
for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ )
|
||||
{
|
||||
/* --- Lowpass */
|
||||
pLP = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
|
||||
stretchPitchLP[(ISACdec_obj->plcstr_obj).pitchIndex],
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15 );
|
||||
|
||||
/* --- Highpass */
|
||||
pHP = (WebRtc_Word32)WEBRTC_SPL_MUL_16_32_RSFT15(
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffPriodic,
|
||||
(ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 -
|
||||
(ISACdec_obj->plcstr_obj).stretchLag +
|
||||
(ISACdec_obj->plcstr_obj).pitchIndex] );
|
||||
|
||||
/* --- lower the muliplier (more decay at next sample) --- */
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate);
|
||||
if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 )
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0;
|
||||
|
||||
(ISACdec_obj->plcstr_obj).pitchIndex++;
|
||||
|
||||
if( (ISACdec_obj->plcstr_obj).pitchIndex ==
|
||||
(ISACdec_obj->plcstr_obj).stretchLag )
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).pitchIndex = 0;
|
||||
(ISACdec_obj->plcstr_obj).pitchCycles++;
|
||||
|
||||
if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) )
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).stretchLag = lag0;
|
||||
}
|
||||
|
||||
(ISACdec_obj->plcstr_obj).stretchLag = (
|
||||
(ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG
|
||||
)? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag;
|
||||
|
||||
LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP,
|
||||
stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
|
||||
|
||||
LinearResampler( (ISACdec_obj->plcstr_obj).prevPitchLP,
|
||||
stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
|
||||
|
||||
switch( (ISACdec_obj->plcstr_obj).pitchCycles )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
|
||||
{
|
||||
stretchPitchLP[k] = (WebRtc_Word16)((
|
||||
(WebRtc_Word32)stretchPitchLP[k]* 3 +
|
||||
(WebRtc_Word32)stretchPitchLP1[k])>>2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
|
||||
{
|
||||
stretchPitchLP[k] = (WebRtc_Word16)((
|
||||
(WebRtc_Word32)stretchPitchLP[k] +
|
||||
(WebRtc_Word32)stretchPitchLP1[k] )>>1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
|
||||
{
|
||||
stretchPitchLP[k] = (WebRtc_Word16)((stretchPitchLP[k] +
|
||||
(WebRtc_Word32)stretchPitchLP1[k]*3 )>>2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 )
|
||||
{
|
||||
myDecayRate += 35; //(myDecayRate>>1);
|
||||
(ISACdec_obj->plcstr_obj).pitchCycles = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------ Sum the noisy and periodic signals ------ */
|
||||
Vector_Word16_1[i] = pLP;
|
||||
Vector_Word32_2[i] = pHP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ )
|
||||
{
|
||||
|
||||
(ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
|
||||
(ISACdec_obj->plcstr_obj).seed );
|
||||
|
||||
noise1 = WEBRTC_SPL_RSHIFT_W16(
|
||||
(ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
|
||||
|
||||
nLP = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
|
||||
(WebRtc_Word16)((noise1)*(ISACdec_obj->plcstr_obj).std),
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffNoise, 15 );
|
||||
|
||||
/* --- Highpass */
|
||||
(ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
|
||||
(ISACdec_obj->plcstr_obj).seed );
|
||||
noise1 = WEBRTC_SPL_RSHIFT_W16(
|
||||
(ISACdec_obj->plcstr_obj).seed, 11 ) - 8;
|
||||
|
||||
nHP = (WebRtc_Word32)WEBRTC_SPL_MUL_16_32_RSFT15(
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffNoise,
|
||||
(WebRtc_Word32)(noise1*(ISACdec_obj->plcstr_obj).std) );
|
||||
|
||||
/* --- lower the muliplier (more decay at next sample) --- */
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffNoise -= (myDecayRate);
|
||||
if( (ISACdec_obj->plcstr_obj).decayCoeffNoise < 0 )
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffNoise = 0;
|
||||
|
||||
/* ------ Periodic Vector --- */
|
||||
/* --- Lowpass */
|
||||
pLP = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
|
||||
stretchPitchLP[(ISACdec_obj->plcstr_obj).pitchIndex],
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15 );
|
||||
|
||||
/* --- Highpass */
|
||||
pHP = (WebRtc_Word32)WEBRTC_SPL_MUL_16_32_RSFT15(
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffPriodic,
|
||||
(ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 -
|
||||
(ISACdec_obj->plcstr_obj).stretchLag +
|
||||
(ISACdec_obj->plcstr_obj).pitchIndex] );
|
||||
|
||||
/* --- lower the muliplier (more decay at next sample) --- */
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate);
|
||||
if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 )
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0;
|
||||
}
|
||||
|
||||
/* ------ Weighting the noisy and periodic vectors ------- */
|
||||
wNoisyLP = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT(
|
||||
(ISACdec_obj->plcstr_obj).A, nLP, 15 ) );
|
||||
wNoisyHP = (WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT15(
|
||||
(ISACdec_obj->plcstr_obj).A, (nHP) ) );
|
||||
|
||||
wPriodicLP = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT(
|
||||
(ISACdec_obj->plcstr_obj).B, pLP, 15));
|
||||
wPriodicHP = (WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT15(
|
||||
(ISACdec_obj->plcstr_obj).B, pHP));
|
||||
|
||||
(ISACdec_obj->plcstr_obj).pitchIndex++;
|
||||
|
||||
if((ISACdec_obj->plcstr_obj).pitchIndex ==
|
||||
(ISACdec_obj->plcstr_obj).stretchLag)
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).pitchIndex = 0;
|
||||
(ISACdec_obj->plcstr_obj).pitchCycles++;
|
||||
|
||||
if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) )
|
||||
(ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1;
|
||||
else
|
||||
(ISACdec_obj->plcstr_obj).stretchLag = lag0;
|
||||
|
||||
(ISACdec_obj->plcstr_obj).stretchLag = (
|
||||
(ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG
|
||||
)? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag;
|
||||
LinearResampler(
|
||||
(ISACdec_obj->plcstr_obj).lastPitchLP,
|
||||
stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
|
||||
|
||||
LinearResampler((ISACdec_obj->plcstr_obj).prevPitchLP,
|
||||
stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
|
||||
|
||||
switch((ISACdec_obj->plcstr_obj).pitchCycles)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
|
||||
{
|
||||
stretchPitchLP[k] = (WebRtc_Word16)((
|
||||
(WebRtc_Word32)stretchPitchLP[k]* 3 +
|
||||
(WebRtc_Word32)stretchPitchLP1[k] )>>2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
|
||||
{
|
||||
stretchPitchLP[k] = (WebRtc_Word16)((
|
||||
(WebRtc_Word32)stretchPitchLP[k] +
|
||||
(WebRtc_Word32)stretchPitchLP1[k])>>1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
|
||||
{
|
||||
stretchPitchLP[k] = (WebRtc_Word16)(
|
||||
(stretchPitchLP[k] +
|
||||
(WebRtc_Word32)stretchPitchLP1[k]*3 )>>2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 )
|
||||
{
|
||||
myDecayRate += 55; //(myDecayRate>>1);
|
||||
(ISACdec_obj->plcstr_obj).pitchCycles = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------ Sum the noisy and periodic signals ------ */
|
||||
Vector_Word16_1[i] = (WebRtc_Word16)WEBRTC_SPL_ADD_SAT_W16(
|
||||
wNoisyLP, wPriodicLP );
|
||||
Vector_Word32_2[i] = (WebRtc_Word32)WEBRTC_SPL_ADD_SAT_W32(
|
||||
wNoisyHP, wPriodicHP );
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ----------------- residual signal is reconstructed ------------------ */
|
||||
|
||||
k = (ISACdec_obj->plcstr_obj).pitchIndex;
|
||||
/* --- Write one pitch cycle for recovery block --- */
|
||||
|
||||
for( i = 0; i < RECOVERY_OVERLAP; i++ )
|
||||
{
|
||||
(ISACdec_obj->plcstr_obj).overlapLP[i] = (WebRtc_Word16)(
|
||||
WEBRTC_SPL_MUL_16_16_RSFT(stretchPitchLP[k],
|
||||
(ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15) );
|
||||
k = ( k < ((ISACdec_obj->plcstr_obj).stretchLag - 1) )? (k+1):0;
|
||||
}
|
||||
|
||||
(ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = (ISACdec_obj->plcstr_obj).stretchLag << 7;
|
||||
|
||||
|
||||
/* --- Inverse Pitch Filter --- */
|
||||
WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2,
|
||||
&ISACdec_obj->pitchfiltstr_obj, pitchLags_Q7, pitchGains_Q12, 4);
|
||||
|
||||
/* reduce gain to compensate for pitch enhancer */
|
||||
/* gain = 1.0f - 0.45f * AvgPitchGain; */
|
||||
tmp32a = WEBRTC_SPL_MUL_16_16_RSFT((ISACdec_obj->plcstr_obj).AvgPitchGain_Q12,
|
||||
29, 0); // Q18
|
||||
tmp32b = 262144 - tmp32a; // Q18
|
||||
gainQ13 = (WebRtc_Word16) (tmp32b >> 5); // Q13
|
||||
|
||||
/* perceptual post-filtering (using normalized lattice filter) */
|
||||
for (k = 0; k < FRAMESAMPLES_HALF; k++)
|
||||
Vector_Word32_1[k] = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16(
|
||||
Vector_Word16_2[k], gainQ13) << 3; // Q25
|
||||
|
||||
|
||||
WebRtcIsacfix_NormLatticeFilterAr(ORDERLO,
|
||||
(ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0,
|
||||
Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1);
|
||||
|
||||
WebRtcIsacfix_NormLatticeFilterAr(ORDERHI,
|
||||
(ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0,
|
||||
Vector_Word32_2, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2);
|
||||
|
||||
/* recombine the 2 bands */
|
||||
|
||||
/* Form the polyphase signals, and compensate for DC offset */
|
||||
for (k=0;k<FRAMESAMPLES_HALF;k++)
|
||||
{
|
||||
/* Construct a new upper channel signal*/
|
||||
tmp_1 = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(
|
||||
((WebRtc_Word32)Vector_Word16_1[k]+Vector_Word16_2[k] + 1));
|
||||
/* Construct a new lower channel signal*/
|
||||
tmp_2 = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(
|
||||
((WebRtc_Word32)Vector_Word16_1[k]-Vector_Word16_2[k]));
|
||||
Vector_Word16_1[k] = tmp_1;
|
||||
Vector_Word16_2[k] = tmp_2;
|
||||
}
|
||||
|
||||
|
||||
WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1,
|
||||
Vector_Word16_2, signal_out16, &ISACdec_obj->postfiltbankstr_obj);
|
||||
|
||||
(ISACdec_obj->plcstr_obj).used = PLC_WAS_USED;
|
||||
*current_framesamples = 480;
|
||||
|
||||
return len;
|
||||
}
|
|
@ -0,0 +1,626 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* encode.c
|
||||
*
|
||||
* Encoding function for the iSAC coder.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "arith_routins.h"
|
||||
#include "bandwidth_estimator.h"
|
||||
#include "codec.h"
|
||||
#include "pitch_gain_tables.h"
|
||||
#include "pitch_lag_tables.h"
|
||||
#include "entropy_coding.h"
|
||||
#include "lpc_tables.h"
|
||||
#include "lpc_masking_model.h"
|
||||
#include "pitch_estimator.h"
|
||||
#include "structs.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int WebRtcIsacfix_EncodeImpl(WebRtc_Word16 *in,
|
||||
ISACFIX_EncInst_t *ISACenc_obj,
|
||||
BwEstimatorstr *bw_estimatordata,
|
||||
WebRtc_Word16 CodingMode)
|
||||
{
|
||||
WebRtc_Word16 stream_length = 0;
|
||||
WebRtc_Word16 usefulstr_len = 0;
|
||||
int k;
|
||||
WebRtc_Word16 BWno;
|
||||
|
||||
WebRtc_Word16 lofilt_coefQ15[(ORDERLO)*SUBFRAMES];
|
||||
WebRtc_Word16 hifilt_coefQ15[(ORDERHI)*SUBFRAMES];
|
||||
WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES];
|
||||
|
||||
WebRtc_Word16 LPandHP[FRAMESAMPLES/2 + QLOOKAHEAD];
|
||||
WebRtc_Word16 LP16a[FRAMESAMPLES/2 + QLOOKAHEAD];
|
||||
WebRtc_Word16 HP16a[FRAMESAMPLES/2 + QLOOKAHEAD];
|
||||
|
||||
WebRtc_Word16 PitchLags_Q7[PITCH_SUBFRAMES];
|
||||
WebRtc_Word16 PitchGains_Q12[PITCH_SUBFRAMES];
|
||||
WebRtc_Word16 AvgPitchGain_Q12;
|
||||
|
||||
WebRtc_Word16 frame_mode; /* 0 for 30ms, 1 for 60ms */
|
||||
WebRtc_Word16 processed_samples;
|
||||
int status;
|
||||
|
||||
WebRtc_Word32 bits_gainsQ11;
|
||||
WebRtc_Word16 MinBytes;
|
||||
WebRtc_Word16 bmodel;
|
||||
|
||||
transcode_obj transcodingParam;
|
||||
WebRtc_Word16 payloadLimitBytes;
|
||||
WebRtc_Word16 arithLenBeforeEncodingDFT;
|
||||
WebRtc_Word16 iterCntr;
|
||||
|
||||
/* copy new frame length and bottle neck rate only for the first 10 ms data */
|
||||
if (ISACenc_obj->buffer_index == 0) {
|
||||
/* set the framelength for the next packet */
|
||||
ISACenc_obj->current_framesamples = ISACenc_obj->new_framelength;
|
||||
}
|
||||
|
||||
frame_mode = ISACenc_obj->current_framesamples/MAX_FRAMESAMPLES; /* 0 (30 ms) or 1 (60 ms) */
|
||||
processed_samples = ISACenc_obj->current_framesamples/(frame_mode+1); /* 480 (30, 60 ms) */
|
||||
|
||||
/* buffer speech samples (by 10ms packet) until the framelength is reached (30 or 60 ms) */
|
||||
/**************************************************************************************/
|
||||
/* fill the buffer with 10ms input data */
|
||||
for(k=0; k<FRAMESAMPLES_10ms; k++) {
|
||||
ISACenc_obj->data_buffer_fix[k + ISACenc_obj->buffer_index] = in[k];
|
||||
}
|
||||
/* if buffersize is not equal to current framesize, and end of file is not reached yet, */
|
||||
/* increase index and go back to main to get more speech samples */
|
||||
if (ISACenc_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) {
|
||||
ISACenc_obj->buffer_index = ISACenc_obj->buffer_index + FRAMESAMPLES_10ms;
|
||||
return 0;
|
||||
}
|
||||
/* if buffer reached the right size, reset index and continue with encoding the frame */
|
||||
ISACenc_obj->buffer_index = 0;
|
||||
|
||||
/* end of buffer function */
|
||||
/**************************/
|
||||
|
||||
/* encoding */
|
||||
/************/
|
||||
|
||||
if (frame_mode == 0 || ISACenc_obj->frame_nb == 0 )
|
||||
{
|
||||
/* reset bitstream */
|
||||
ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF;
|
||||
ISACenc_obj->bitstr_obj.streamval = 0;
|
||||
ISACenc_obj->bitstr_obj.stream_index = 0;
|
||||
ISACenc_obj->bitstr_obj.full = 1;
|
||||
|
||||
if (CodingMode == 0) {
|
||||
ISACenc_obj->BottleNeck = WebRtcIsacfix_GetUplinkBandwidth(bw_estimatordata);
|
||||
ISACenc_obj->MaxDelay = WebRtcIsacfix_GetUplinkMaxDelay(bw_estimatordata);
|
||||
}
|
||||
if (CodingMode == 0 && frame_mode == 0 && (ISACenc_obj->enforceFrameSize == 0)) {
|
||||
ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck,
|
||||
ISACenc_obj->current_framesamples);
|
||||
}
|
||||
|
||||
// multiply the bottleneck by 0.88 before computing SNR, 0.88 is tuned by experimenting on TIMIT
|
||||
// 901/1024 is 0.87988281250000
|
||||
ISACenc_obj->s2nr = WebRtcIsacfix_GetSnr((WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ISACenc_obj->BottleNeck, 901, 10),
|
||||
ISACenc_obj->current_framesamples);
|
||||
|
||||
/* encode frame length */
|
||||
status = WebRtcIsacfix_EncodeFrameLen(ISACenc_obj->current_framesamples, &ISACenc_obj->bitstr_obj);
|
||||
if (status < 0)
|
||||
{
|
||||
/* Wrong frame size */
|
||||
if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
|
||||
{
|
||||
// If this is the second 30ms of a 60ms frame reset this such that in the next call
|
||||
// encoder starts fresh.
|
||||
ISACenc_obj->frame_nb = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Save framelength for multiple packets memory */
|
||||
if (ISACenc_obj->SaveEnc_ptr != NULL) {
|
||||
(ISACenc_obj->SaveEnc_ptr)->framelength=ISACenc_obj->current_framesamples;
|
||||
}
|
||||
|
||||
/* bandwidth estimation and coding */
|
||||
BWno = WebRtcIsacfix_GetDownlinkBwIndexImpl(bw_estimatordata);
|
||||
status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj);
|
||||
if (status < 0)
|
||||
{
|
||||
if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
|
||||
{
|
||||
// If this is the second 30ms of a 60ms frame reset this such that in the next call
|
||||
// encoder starts fresh.
|
||||
ISACenc_obj->frame_nb = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* split signal in two bands */
|
||||
WebRtcIsacfix_SplitAndFilter1(ISACenc_obj->data_buffer_fix, LP16a, HP16a, &ISACenc_obj->prefiltbankstr_obj );
|
||||
|
||||
/* estimate pitch parameters and pitch-filter lookahead signal */
|
||||
WebRtcIsacfix_PitchAnalysis(LP16a+QLOOKAHEAD, LPandHP,
|
||||
&ISACenc_obj->pitchanalysisstr_obj, PitchLags_Q7, PitchGains_Q12); /* LPandHP = LP_lookahead_pfQ0, */
|
||||
|
||||
/* Set where to store data in multiple packets memory */
|
||||
if (ISACenc_obj->SaveEnc_ptr != NULL) {
|
||||
if (frame_mode == 0 || ISACenc_obj->frame_nb == 0)
|
||||
{
|
||||
(ISACenc_obj->SaveEnc_ptr)->startIdx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
(ISACenc_obj->SaveEnc_ptr)->startIdx = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* quantize & encode pitch parameters */
|
||||
status = WebRtcIsacfix_EncodePitchGain(PitchGains_Q12, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr);
|
||||
if (status < 0)
|
||||
{
|
||||
if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
|
||||
{
|
||||
// If this is the second 30ms of a 60ms frame reset this such that in the next call
|
||||
// encoder starts fresh.
|
||||
ISACenc_obj->frame_nb = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
status = WebRtcIsacfix_EncodePitchLag(PitchLags_Q7 , PitchGains_Q12, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr);
|
||||
if (status < 0)
|
||||
{
|
||||
if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
|
||||
{
|
||||
// If this is the second 30ms of a 60ms frame reset this such that in the next call
|
||||
// encoder starts fresh.
|
||||
ISACenc_obj->frame_nb = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
AvgPitchGain_Q12 = WEBRTC_SPL_RSHIFT_W32(PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3], 2);
|
||||
|
||||
/* find coefficients for perceptual pre-filters */
|
||||
WebRtcIsacfix_GetLpcCoef(LPandHP, HP16a+QLOOKAHEAD, &ISACenc_obj->maskfiltstr_obj,
|
||||
ISACenc_obj->s2nr, PitchGains_Q12,
|
||||
gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15); /*LPandHP = LP_lookahead_pfQ0*/
|
||||
|
||||
// record LPC Gains for possible bit-rate reduction
|
||||
for(k = 0; k < KLT_ORDER_GAIN; k++)
|
||||
{
|
||||
transcodingParam.lpcGains[k] = gain_lo_hiQ17[k];
|
||||
}
|
||||
|
||||
/* code LPC model and shape - gains not quantized yet */
|
||||
status = WebRtcIsacfix_EncodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
|
||||
&bmodel, &bits_gainsQ11, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr, &transcodingParam);
|
||||
if (status < 0)
|
||||
{
|
||||
if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
|
||||
{
|
||||
// If this is the second 30ms of a 60ms frame reset this such that in the next call
|
||||
// encoder starts fresh.
|
||||
ISACenc_obj->frame_nb = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full);
|
||||
|
||||
/* low-band filtering */
|
||||
WebRtcIsacfix_NormLatticeFilterMa(ORDERLO, ISACenc_obj->maskfiltstr_obj.PreStateLoGQ15,
|
||||
LP16a, lofilt_coefQ15, gain_lo_hiQ17, 0, LPandHP);/* LPandHP = LP16b */
|
||||
|
||||
/* pitch filter */
|
||||
WebRtcIsacfix_PitchFilter(LPandHP, LP16a, &ISACenc_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 1);/* LPandHP = LP16b */
|
||||
|
||||
/* high-band filtering */
|
||||
WebRtcIsacfix_NormLatticeFilterMa(ORDERHI, ISACenc_obj->maskfiltstr_obj.PreStateHiGQ15,
|
||||
HP16a, hifilt_coefQ15, gain_lo_hiQ17, 1, LPandHP);/*LPandHP = HP16b*/
|
||||
|
||||
/* transform */
|
||||
WebRtcIsacfix_Time2Spec(LP16a, LPandHP, LP16a, LPandHP); /*LPandHP = HP16b*/
|
||||
|
||||
/* Save data for multiple packets memory */
|
||||
if (ISACenc_obj->SaveEnc_ptr != NULL) {
|
||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||
(ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k];
|
||||
(ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k];
|
||||
}
|
||||
(ISACenc_obj->SaveEnc_ptr)->AvgPitchGain[(ISACenc_obj->SaveEnc_ptr)->startIdx] = AvgPitchGain_Q12;
|
||||
}
|
||||
|
||||
/* quantization and lossless coding */
|
||||
status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12);
|
||||
if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/
|
||||
{
|
||||
if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
|
||||
{
|
||||
// If this is the second 30ms of a 60ms frame reset this such that in the next call
|
||||
// encoder starts fresh.
|
||||
ISACenc_obj->frame_nb = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0))
|
||||
{
|
||||
// it is a 60ms and we are in the first 30ms
|
||||
// then the limit at this point should be half of the assigned value
|
||||
payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 >> 1;
|
||||
}
|
||||
else if (frame_mode == 0)
|
||||
{
|
||||
// it is a 30ms frame
|
||||
payloadLimitBytes = (ISACenc_obj->payloadLimitBytes30) - 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is the second half of a 60ms frame.
|
||||
payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 - 3; // subract 3 because termination process may add 3 bytes
|
||||
}
|
||||
|
||||
iterCntr = 0;
|
||||
while((((ISACenc_obj->bitstr_obj.stream_index) << 1) > payloadLimitBytes) ||
|
||||
(status == -ISAC_DISALLOWED_BITSTREAM_LENGTH))
|
||||
{
|
||||
WebRtc_Word16 arithLenDFTByte;
|
||||
WebRtc_Word16 bytesLeftQ5;
|
||||
WebRtc_Word16 ratioQ5[8] = {0, 6, 9, 12, 16, 19, 22, 25};
|
||||
|
||||
// According to experiments on TIMIT the following is proper for audio, but it is not agressive enough for tonal inputs
|
||||
// such as DTMF, sweep-sine, ...
|
||||
//
|
||||
// (0.55 - (0.8 - ratio[i]/32) * 5 / 6) * 2^14
|
||||
// WebRtc_Word16 scaleQ14[8] = {0, 648, 1928, 3208, 4915, 6195, 7475, 8755};
|
||||
|
||||
|
||||
// This is a supper-agressive scaling passed the tests (tonal inputs) tone with one iteration for payload limit
|
||||
// of 120 (32kbps bottleneck), number of frames needed a rate-reduction was 58403
|
||||
//
|
||||
WebRtc_Word16 scaleQ14[8] = {0, 348, 828, 1408, 2015, 3195, 3500, 3500};
|
||||
WebRtc_Word16 idx;
|
||||
|
||||
if(iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION)
|
||||
{
|
||||
// We were not able to limit the payload size
|
||||
|
||||
if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0))
|
||||
{
|
||||
// This was the first 30ms of a 60ms frame. Although the payload is larger than it
|
||||
// should be but we let the second 30ms be encoded. Maybe togetehr we won't exceed
|
||||
// the limit.
|
||||
ISACenc_obj->frame_nb = 1;
|
||||
return 0;
|
||||
}
|
||||
else if((frame_mode == 1) && (ISACenc_obj->frame_nb == 1))
|
||||
{
|
||||
ISACenc_obj->frame_nb = 0;
|
||||
}
|
||||
|
||||
if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)
|
||||
{
|
||||
return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)
|
||||
{
|
||||
arithLenDFTByte = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full) - arithLenBeforeEncodingDFT;
|
||||
bytesLeftQ5 = (payloadLimitBytes - arithLenBeforeEncodingDFT) << 5;
|
||||
|
||||
// bytesLeft / arithLenDFTBytes indicates how much scaling is required a rough estimate (agressive)
|
||||
// scale = 0.55 - (0.8 - bytesLeft / arithLenDFTBytes) * 5 / 6
|
||||
// bytesLeft / arithLenDFTBytes below 0.2 will have a scale of zero and above 0.8 are treated as 0.8
|
||||
// to avoid division we do more simplification.
|
||||
//
|
||||
// values of (bytesLeft / arithLenDFTBytes)*32 between ratioQ5[i] and ratioQ5[i+1] are rounded to ratioQ5[i]
|
||||
// and the corresponding scale is chosen
|
||||
|
||||
// we compare bytesLeftQ5 with ratioQ5[]*arithLenDFTByte;
|
||||
idx = 4;
|
||||
idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 2:-2;
|
||||
idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 1:-1;
|
||||
idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 0:-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are here because the bit-stream did not fit into the buffer, in this case, the stream_index is not
|
||||
// trustable, especially if the is the first 30ms of a packet. Thereforem, we will go for the most agressive
|
||||
// case.
|
||||
idx = 0;
|
||||
}
|
||||
// scale FFT coefficients to reduce the bit-rate
|
||||
for(k = 0; k < FRAMESAMPLES_HALF; k++)
|
||||
{
|
||||
LP16a[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(LP16a[k], scaleQ14[idx], 14);
|
||||
LPandHP[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(LPandHP[k], scaleQ14[idx], 14);
|
||||
}
|
||||
|
||||
// Save data for multiple packets memory
|
||||
if (ISACenc_obj->SaveEnc_ptr != NULL)
|
||||
{
|
||||
for(k = 0; k < FRAMESAMPLES_HALF; k++)
|
||||
{
|
||||
(ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k];
|
||||
(ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k];
|
||||
}
|
||||
}
|
||||
|
||||
// scale the unquantized LPC gains and save the scaled version for the future use
|
||||
for(k = 0; k < KLT_ORDER_GAIN; k++)
|
||||
{
|
||||
gain_lo_hiQ17[k] = WEBRTC_SPL_MUL_16_32_RSFT14(scaleQ14[idx], transcodingParam.lpcGains[k]);//transcodingParam.lpcGains[k]; //
|
||||
transcodingParam.lpcGains[k] = gain_lo_hiQ17[k];
|
||||
}
|
||||
|
||||
// reset the bit-stream object to the state which it had before encoding LPC Gains
|
||||
ISACenc_obj->bitstr_obj.full = transcodingParam.full;
|
||||
ISACenc_obj->bitstr_obj.stream_index = transcodingParam.stream_index;
|
||||
ISACenc_obj->bitstr_obj.streamval = transcodingParam.streamval;
|
||||
ISACenc_obj->bitstr_obj.W_upper = transcodingParam.W_upper;
|
||||
ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index-1] = transcodingParam.beforeLastWord;
|
||||
ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index] = transcodingParam.lastWord;
|
||||
|
||||
|
||||
// quantize and encode LPC gain
|
||||
WebRtcIsacfix_EstCodeLpcGain(gain_lo_hiQ17, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr);
|
||||
arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full);
|
||||
status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12);
|
||||
if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/
|
||||
{
|
||||
if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
|
||||
{
|
||||
// If this is the second 30ms of a 60ms frame reset this such that in the next call
|
||||
// encoder starts fresh.
|
||||
ISACenc_obj->frame_nb = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
iterCntr++;
|
||||
}
|
||||
|
||||
if (frame_mode == 1 && ISACenc_obj->frame_nb == 0)
|
||||
/* i.e. 60 ms framesize and just processed the first 30ms, */
|
||||
/* go back to main function to buffer the other 30ms speech frame */
|
||||
{
|
||||
ISACenc_obj->frame_nb = 1;
|
||||
return 0;
|
||||
}
|
||||
else if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
|
||||
{
|
||||
ISACenc_obj->frame_nb = 0;
|
||||
/* also update the framelength for next packet, in Adaptive mode only */
|
||||
if (CodingMode == 0 && (ISACenc_obj->enforceFrameSize == 0)) {
|
||||
ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck,
|
||||
ISACenc_obj->current_framesamples);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* complete arithmetic coding */
|
||||
stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj);
|
||||
/* can this be negative? */
|
||||
|
||||
if(CodingMode == 0)
|
||||
{
|
||||
|
||||
/* update rate model and get minimum number of bytes in this packet */
|
||||
MinBytes = WebRtcIsacfix_GetMinBytes(&ISACenc_obj->rate_data_obj, (WebRtc_Word16) stream_length,
|
||||
ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck, ISACenc_obj->MaxDelay);
|
||||
|
||||
/* if bitstream is too short, add garbage at the end */
|
||||
|
||||
/* Store length of coded data */
|
||||
usefulstr_len = stream_length;
|
||||
|
||||
/* Make sure MinBytes does not exceed packet size limit */
|
||||
if ((ISACenc_obj->frame_nb == 0) && (MinBytes > ISACenc_obj->payloadLimitBytes30)) {
|
||||
MinBytes = ISACenc_obj->payloadLimitBytes30;
|
||||
} else if ((ISACenc_obj->frame_nb == 1) && (MinBytes > ISACenc_obj->payloadLimitBytes60)) {
|
||||
MinBytes = ISACenc_obj->payloadLimitBytes60;
|
||||
}
|
||||
|
||||
/* Make sure we don't allow more than 255 bytes of garbage data.
|
||||
We store the length of the garbage data in 8 bits in the bitstream,
|
||||
255 is the max garbage lenght we can signal using 8 bits. */
|
||||
if( MinBytes > usefulstr_len + 255 ) {
|
||||
MinBytes = usefulstr_len + 255;
|
||||
}
|
||||
|
||||
/* Save data for creation of multiple bitstreams */
|
||||
if (ISACenc_obj->SaveEnc_ptr != NULL) {
|
||||
(ISACenc_obj->SaveEnc_ptr)->minBytes = MinBytes;
|
||||
}
|
||||
|
||||
while (stream_length < MinBytes)
|
||||
{
|
||||
if (stream_length & 0x0001){
|
||||
ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed );
|
||||
ISACenc_obj->bitstr_obj.stream[ WEBRTC_SPL_RSHIFT_W16(stream_length, 1) ] |= (WebRtc_UWord16)(ISACenc_obj->bitstr_seed & 0xFF);
|
||||
} else {
|
||||
ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed );
|
||||
ISACenc_obj->bitstr_obj.stream[ WEBRTC_SPL_RSHIFT_W16(stream_length, 1) ] = WEBRTC_SPL_LSHIFT_U16(ISACenc_obj->bitstr_seed, 8);
|
||||
}
|
||||
stream_length++;
|
||||
}
|
||||
|
||||
/* to get the real stream_length, without garbage */
|
||||
if (usefulstr_len & 0x0001) {
|
||||
ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0xFF00;
|
||||
ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] += (MinBytes - usefulstr_len) & 0x00FF;
|
||||
}
|
||||
else {
|
||||
ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0x00FF;
|
||||
ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] += WEBRTC_SPL_LSHIFT_U16((MinBytes - usefulstr_len) & 0x00FF, 8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* update rate model */
|
||||
WebRtcIsacfix_UpdateRateModel(&ISACenc_obj->rate_data_obj, (WebRtc_Word16) stream_length,
|
||||
ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck);
|
||||
}
|
||||
return stream_length;
|
||||
}
|
||||
|
||||
/* This function is used to create a new bitstream with new BWE.
|
||||
The same data as previously encoded with the fucntion WebRtcIsacfix_EncodeImpl()
|
||||
is used. The data needed is taken from the struct, where it was stored
|
||||
when calling the encoder. */
|
||||
int WebRtcIsacfix_EncodeStoredData(ISACFIX_EncInst_t *ISACenc_obj,
|
||||
int BWnumber,
|
||||
float scale)
|
||||
{
|
||||
int ii;
|
||||
int status;
|
||||
WebRtc_Word16 BWno = BWnumber;
|
||||
int stream_length = 0;
|
||||
|
||||
WebRtc_Word16 model;
|
||||
const WebRtc_UWord16 *Q_PitchGain_cdf_ptr[1];
|
||||
const WebRtc_UWord16 **cdf;
|
||||
const ISAC_SaveEncData_t *SaveEnc_str;
|
||||
WebRtc_Word32 tmpLPCcoeffs_g[KLT_ORDER_GAIN<<1];
|
||||
WebRtc_Word16 tmpLPCindex_g[KLT_ORDER_GAIN<<1];
|
||||
WebRtc_Word16 tmp_fre[FRAMESAMPLES];
|
||||
WebRtc_Word16 tmp_fim[FRAMESAMPLES];
|
||||
|
||||
SaveEnc_str = ISACenc_obj->SaveEnc_ptr;
|
||||
|
||||
/* Check if SaveEnc memory exists */
|
||||
if (SaveEnc_str == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Sanity Check - possible values for BWnumber is 0 - 23 */
|
||||
if ((BWnumber < 0) || (BWnumber > 23)) {
|
||||
return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
|
||||
}
|
||||
|
||||
/* reset bitstream */
|
||||
ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF;
|
||||
ISACenc_obj->bitstr_obj.streamval = 0;
|
||||
ISACenc_obj->bitstr_obj.stream_index = 0;
|
||||
ISACenc_obj->bitstr_obj.full = 1;
|
||||
|
||||
/* encode frame length */
|
||||
status = WebRtcIsacfix_EncodeFrameLen(SaveEnc_str->framelength, &ISACenc_obj->bitstr_obj);
|
||||
if (status < 0) {
|
||||
/* Wrong frame size */
|
||||
return status;
|
||||
}
|
||||
|
||||
/* encode bandwidth estimate */
|
||||
status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Transcoding */
|
||||
/* If scale < 1, rescale data to produce lower bitrate signal */
|
||||
if ((0.0 < scale) && (scale < 1.0)) {
|
||||
/* Compensate LPC gain */
|
||||
for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) {
|
||||
tmpLPCcoeffs_g[ii] = (WebRtc_Word32) ((scale) * (float) SaveEnc_str->LPCcoeffs_g[ii]);
|
||||
}
|
||||
|
||||
/* Scale DFT */
|
||||
for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) {
|
||||
tmp_fre[ii] = (WebRtc_Word16) ((scale) * (float) SaveEnc_str->fre[ii]) ;
|
||||
tmp_fim[ii] = (WebRtc_Word16) ((scale) * (float) SaveEnc_str->fim[ii]) ;
|
||||
}
|
||||
} else {
|
||||
for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) {
|
||||
tmpLPCindex_g[ii] = SaveEnc_str->LPCindex_g[ii];
|
||||
}
|
||||
|
||||
for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) {
|
||||
tmp_fre[ii] = SaveEnc_str->fre[ii];
|
||||
tmp_fim[ii] = SaveEnc_str->fim[ii];
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop over number of 30 msec */
|
||||
for (ii = 0; ii <= SaveEnc_str->startIdx; ii++)
|
||||
{
|
||||
|
||||
/* encode pitch gains */
|
||||
*Q_PitchGain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf;
|
||||
status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->pitchGain_index[ii],
|
||||
Q_PitchGain_cdf_ptr, 1);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* entropy coding of quantization pitch lags */
|
||||
/* voicing classificiation */
|
||||
if (SaveEnc_str->meanGain[ii] <= 819) {
|
||||
cdf = WebRtcIsacfix_kPitchLagPtrLo;
|
||||
} else if (SaveEnc_str->meanGain[ii] <= 1638) {
|
||||
cdf = WebRtcIsacfix_kPitchLagPtrMid;
|
||||
} else {
|
||||
cdf = WebRtcIsacfix_kPitchLagPtrHi;
|
||||
}
|
||||
status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj,
|
||||
&SaveEnc_str->pitchIndex[PITCH_SUBFRAMES*ii], cdf, PITCH_SUBFRAMES);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* LPC */
|
||||
/* entropy coding of model number */
|
||||
model = 0;
|
||||
status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &model,
|
||||
WebRtcIsacfix_kModelCdfPtr, 1);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* entropy coding of quantization indices - LPC shape only */
|
||||
status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->LPCindex_s[KLT_ORDER_SHAPE*ii],
|
||||
WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* If transcoding, get new LPC gain indices */
|
||||
if (scale < 1.0) {
|
||||
WebRtcIsacfix_TranscodeLpcCoef(&tmpLPCcoeffs_g[KLT_ORDER_GAIN*ii], &tmpLPCindex_g[KLT_ORDER_GAIN*ii]);
|
||||
}
|
||||
|
||||
/* entropy coding of quantization indices - LPC gain */
|
||||
status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN*ii],
|
||||
WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* quantization and lossless coding */
|
||||
status = WebRtcIsacfix_EncodeSpec(&tmp_fre[ii*FRAMESAMPLES_HALF], &tmp_fim[ii*FRAMESAMPLES_HALF],
|
||||
&ISACenc_obj->bitstr_obj, SaveEnc_str->AvgPitchGain[ii]);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* complete arithmetic coding */
|
||||
stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj);
|
||||
|
||||
return stream_length;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* entropy_coding.h
|
||||
*
|
||||
* This header file contains all of the functions used to arithmetically
|
||||
* encode the iSAC bistream
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ENTROPY_CODING_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ENTROPY_CODING_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
/* decode complex spectrum (return number of bytes in stream) */
|
||||
WebRtc_Word16 WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata,
|
||||
WebRtc_Word16 *frQ7,
|
||||
WebRtc_Word16 *fiQ7,
|
||||
WebRtc_Word16 AvgPitchGain_Q12);
|
||||
|
||||
/* encode complex spectrum */
|
||||
int WebRtcIsacfix_EncodeSpec(const WebRtc_Word16 *fr,
|
||||
const WebRtc_Word16 *fi,
|
||||
Bitstr_enc *streamdata,
|
||||
WebRtc_Word16 AvgPitchGain_Q12);
|
||||
|
||||
|
||||
/* decode & dequantize LPC Coef */
|
||||
int WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata,
|
||||
WebRtc_Word32 *LPCCoefQ17,
|
||||
WebRtc_Word32 *gain_lo_hiQ17,
|
||||
WebRtc_Word16 *outmodel);
|
||||
|
||||
int WebRtcIsacfix_DecodeLpc(WebRtc_Word32 *gain_lo_hiQ17,
|
||||
WebRtc_Word16 *LPCCoef_loQ15,
|
||||
WebRtc_Word16 *LPCCoef_hiQ15,
|
||||
Bitstr_dec *streamdata,
|
||||
WebRtc_Word16 *outmodel);
|
||||
|
||||
/* quantize & code LPC Coef */
|
||||
int WebRtcIsacfix_EncodeLpc(WebRtc_Word32 *gain_lo_hiQ17,
|
||||
WebRtc_Word16 *LPCCoef_loQ15,
|
||||
WebRtc_Word16 *LPCCoef_hiQ15,
|
||||
WebRtc_Word16 *model,
|
||||
WebRtc_Word32 *sizeQ11,
|
||||
Bitstr_enc *streamdata,
|
||||
ISAC_SaveEncData_t* encData,
|
||||
transcode_obj *transcodeParam);
|
||||
|
||||
int WebRtcIsacfix_EstCodeLpcGain(WebRtc_Word32 *gain_lo_hiQ17,
|
||||
Bitstr_enc *streamdata,
|
||||
ISAC_SaveEncData_t* encData);
|
||||
/* decode & dequantize RC */
|
||||
int WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata,
|
||||
WebRtc_Word16 *RCQ15);
|
||||
|
||||
/* quantize & code RC */
|
||||
int WebRtcIsacfix_EncodeRcCoef(WebRtc_Word16 *RCQ15,
|
||||
Bitstr_enc *streamdata);
|
||||
|
||||
/* decode & dequantize squared Gain */
|
||||
int WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata,
|
||||
WebRtc_Word32 *Gain2);
|
||||
|
||||
/* quantize & code squared Gain (input is squared gain) */
|
||||
int WebRtcIsacfix_EncodeGain2(WebRtc_Word32 *gain2,
|
||||
Bitstr_enc *streamdata);
|
||||
|
||||
int WebRtcIsacfix_EncodePitchGain(WebRtc_Word16 *PitchGains_Q12,
|
||||
Bitstr_enc *streamdata,
|
||||
ISAC_SaveEncData_t* encData);
|
||||
|
||||
int WebRtcIsacfix_EncodePitchLag(WebRtc_Word16 *PitchLagQ7,
|
||||
WebRtc_Word16 *PitchGain_Q12,
|
||||
Bitstr_enc *streamdata,
|
||||
ISAC_SaveEncData_t* encData);
|
||||
|
||||
int WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata,
|
||||
WebRtc_Word16 *PitchGain_Q12);
|
||||
|
||||
int WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata,
|
||||
WebRtc_Word16 *PitchGain_Q12,
|
||||
WebRtc_Word16 *PitchLagQ7);
|
||||
|
||||
int WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata,
|
||||
WebRtc_Word16 *framelength);
|
||||
|
||||
|
||||
int WebRtcIsacfix_EncodeFrameLen(WebRtc_Word16 framelength,
|
||||
Bitstr_enc *streamdata);
|
||||
|
||||
int WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata,
|
||||
WebRtc_Word16 *BWno);
|
||||
|
||||
|
||||
int WebRtcIsacfix_EncodeReceiveBandwidth(WebRtc_Word16 *BWno,
|
||||
Bitstr_enc *streamdata);
|
||||
|
||||
void WebRtcIsacfix_TranscodeLpcCoef(WebRtc_Word32 *tmpcoeffs_gQ6,
|
||||
WebRtc_Word16 *index_gQQ);
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ENTROPY_CODING_H_ */
|
|
@ -0,0 +1,415 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* fft.c
|
||||
*
|
||||
* Fast Fourier Transform
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "fft.h"
|
||||
|
||||
const WebRtc_Word16 kSortTabFft[240] = {
|
||||
0, 60, 120, 180, 20, 80, 140, 200, 40, 100, 160, 220,
|
||||
4, 64, 124, 184, 24, 84, 144, 204, 44, 104, 164, 224,
|
||||
8, 68, 128, 188, 28, 88, 148, 208, 48, 108, 168, 228,
|
||||
12, 72, 132, 192, 32, 92, 152, 212, 52, 112, 172, 232,
|
||||
16, 76, 136, 196, 36, 96, 156, 216, 56, 116, 176, 236,
|
||||
1, 61, 121, 181, 21, 81, 141, 201, 41, 101, 161, 221,
|
||||
5, 65, 125, 185, 25, 85, 145, 205, 45, 105, 165, 225,
|
||||
9, 69, 129, 189, 29, 89, 149, 209, 49, 109, 169, 229,
|
||||
13, 73, 133, 193, 33, 93, 153, 213, 53, 113, 173, 233,
|
||||
17, 77, 137, 197, 37, 97, 157, 217, 57, 117, 177, 237,
|
||||
2, 62, 122, 182, 22, 82, 142, 202, 42, 102, 162, 222,
|
||||
6, 66, 126, 186, 26, 86, 146, 206, 46, 106, 166, 226,
|
||||
10, 70, 130, 190, 30, 90, 150, 210, 50, 110, 170, 230,
|
||||
14, 74, 134, 194, 34, 94, 154, 214, 54, 114, 174, 234,
|
||||
18, 78, 138, 198, 38, 98, 158, 218, 58, 118, 178, 238,
|
||||
3, 63, 123, 183, 23, 83, 143, 203, 43, 103, 163, 223,
|
||||
7, 67, 127, 187, 27, 87, 147, 207, 47, 107, 167, 227,
|
||||
11, 71, 131, 191, 31, 91, 151, 211, 51, 111, 171, 231,
|
||||
15, 75, 135, 195, 35, 95, 155, 215, 55, 115, 175, 235,
|
||||
19, 79, 139, 199, 39, 99, 159, 219, 59, 119, 179, 239
|
||||
};
|
||||
|
||||
/* Cosine table in Q14 */
|
||||
const WebRtc_Word16 kCosTabFfftQ14[240] = {
|
||||
16384, 16378, 16362, 16333, 16294, 16244, 16182, 16110, 16026, 15931, 15826, 15709,
|
||||
15582, 15444, 15296, 15137, 14968, 14788, 14598, 14399, 14189, 13970, 13741, 13502,
|
||||
13255, 12998, 12733, 12458, 12176, 11885, 11585, 11278, 10963, 10641, 10311, 9974,
|
||||
9630, 9280, 8923, 8561, 8192, 7818, 7438, 7053, 6664, 6270, 5872, 5469,
|
||||
5063, 4653, 4240, 3825, 3406, 2986, 2563, 2139, 1713, 1285, 857, 429,
|
||||
0, -429, -857, -1285, -1713, -2139, -2563, -2986, -3406, -3825, -4240, -4653,
|
||||
-5063, -5469, -5872, -6270, -6664, -7053, -7438, -7818, -8192, -8561, -8923, -9280,
|
||||
-9630, -9974, -10311, -10641, -10963, -11278, -11585, -11885, -12176, -12458, -12733, -12998,
|
||||
-13255, -13502, -13741, -13970, -14189, -14399, -14598, -14788, -14968, -15137, -15296, -15444,
|
||||
-15582, -15709, -15826, -15931, -16026, -16110, -16182, -16244, -16294, -16333, -16362, -16378,
|
||||
-16384, -16378, -16362, -16333, -16294, -16244, -16182, -16110, -16026, -15931, -15826, -15709,
|
||||
-15582, -15444, -15296, -15137, -14968, -14788, -14598, -14399, -14189, -13970, -13741, -13502,
|
||||
-13255, -12998, -12733, -12458, -12176, -11885, -11585, -11278, -10963, -10641, -10311, -9974,
|
||||
-9630, -9280, -8923, -8561, -8192, -7818, -7438, -7053, -6664, -6270, -5872, -5469,
|
||||
-5063, -4653, -4240, -3825, -3406, -2986, -2563, -2139, -1713, -1285, -857, -429,
|
||||
0, 429, 857, 1285, 1713, 2139, 2563, 2986, 3406, 3825, 4240, 4653,
|
||||
5063, 5469, 5872, 6270, 6664, 7053, 7438, 7818, 8192, 8561, 8923, 9280,
|
||||
9630, 9974, 10311, 10641, 10963, 11278, 11585, 11885, 12176, 12458, 12733, 12998,
|
||||
13255, 13502, 13741, 13970, 14189, 14399, 14598, 14788, 14968, 15137, 15296, 15444,
|
||||
15582, 15709, 15826, 15931, 16026, 16110, 16182, 16244, 16294, 16333, 16362, 16378
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Uses 16x16 mul, without rounding, which is faster. Uses WEBRTC_SPL_MUL_16_16_RSFT */
|
||||
WebRtc_Word16 WebRtcIsacfix_FftRadix16Fastest(WebRtc_Word16 RexQx[], WebRtc_Word16 ImxQx[], WebRtc_Word16 iSign) {
|
||||
|
||||
WebRtc_Word16 dd, ee, ff, gg, hh, ii;
|
||||
WebRtc_Word16 k0, k1, k2, k3, k4, kk;
|
||||
WebRtc_Word16 tmp116, tmp216;
|
||||
|
||||
WebRtc_Word16 ccc1Q14, ccc2Q14, ccc3Q14, sss1Q14, sss2Q14, sss3Q14;
|
||||
WebRtc_Word16 sss60Q14, ccc72Q14, sss72Q14;
|
||||
WebRtc_Word16 aaQx, ajQx, akQx, ajmQx, ajpQx, akmQx, akpQx;
|
||||
WebRtc_Word16 bbQx, bjQx, bkQx, bjmQx, bjpQx, bkmQx, bkpQx;
|
||||
|
||||
WebRtc_Word16 ReDATAQx[240], ImDATAQx[240];
|
||||
|
||||
sss60Q14 = kCosTabFfftQ14[20];
|
||||
ccc72Q14 = kCosTabFfftQ14[48];
|
||||
sss72Q14 = kCosTabFfftQ14[12];
|
||||
|
||||
if (iSign < 0) {
|
||||
sss72Q14 = -sss72Q14;
|
||||
sss60Q14 = -sss60Q14;
|
||||
}
|
||||
/* Complexity is: 10 cycles */
|
||||
|
||||
/* compute fourier transform */
|
||||
|
||||
// transform for factor of 4
|
||||
for (kk=0; kk<60; kk++) {
|
||||
k0 = kk;
|
||||
k1 = k0 + 60;
|
||||
k2 = k1 + 60;
|
||||
k3 = k2 + 60;
|
||||
|
||||
akpQx = RexQx[k0] + RexQx[k2];
|
||||
akmQx = RexQx[k0] - RexQx[k2];
|
||||
ajpQx = RexQx[k1] + RexQx[k3];
|
||||
ajmQx = RexQx[k1] - RexQx[k3];
|
||||
bkpQx = ImxQx[k0] + ImxQx[k2];
|
||||
bkmQx = ImxQx[k0] - ImxQx[k2];
|
||||
bjpQx = ImxQx[k1] + ImxQx[k3];
|
||||
bjmQx = ImxQx[k1] - ImxQx[k3];
|
||||
|
||||
RexQx[k0] = akpQx + ajpQx;
|
||||
ImxQx[k0] = bkpQx + bjpQx;
|
||||
ajpQx = akpQx - ajpQx;
|
||||
bjpQx = bkpQx - bjpQx;
|
||||
if (iSign < 0) {
|
||||
akpQx = akmQx + bjmQx;
|
||||
bkpQx = bkmQx - ajmQx;
|
||||
akmQx -= bjmQx;
|
||||
bkmQx += ajmQx;
|
||||
} else {
|
||||
akpQx = akmQx - bjmQx;
|
||||
bkpQx = bkmQx + ajmQx;
|
||||
akmQx += bjmQx;
|
||||
bkmQx -= ajmQx;
|
||||
}
|
||||
|
||||
ccc1Q14 = kCosTabFfftQ14[kk];
|
||||
ccc2Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(2, kk)];
|
||||
ccc3Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(3, kk)];
|
||||
sss1Q14 = kCosTabFfftQ14[kk+60];
|
||||
sss2Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(2, kk)+60];
|
||||
sss3Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(3, kk)+60];
|
||||
if (iSign==1) {
|
||||
sss1Q14 = -sss1Q14;
|
||||
sss2Q14 = -sss2Q14;
|
||||
sss3Q14 = -sss3Q14;
|
||||
}
|
||||
|
||||
//Do several multiplications like Q14*Q16>>14 = Q16
|
||||
// RexQ16[k1] = akpQ16 * ccc1Q14 - bkpQ16 * sss1Q14;
|
||||
// RexQ16[k2] = ajpQ16 * ccc2Q14 - bjpQ16 * sss2Q14;
|
||||
// RexQ16[k3] = akmQ16 * ccc3Q14 - bkmQ16 * sss3Q14;
|
||||
// ImxQ16[k1] = akpQ16 * sss1Q14 + bkpQ16 * ccc1Q14;
|
||||
// ImxQ16[k2] = ajpQ16 * sss2Q14 + bjpQ16 * ccc2Q14;
|
||||
// ImxQ16[k3] = akmQ16 * sss3Q14 + bkmQ16 * ccc3Q14;
|
||||
|
||||
RexQx[k1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc1Q14, akpQx, 14) -
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss1Q14, bkpQx, 14); // 6 non-mul + 2 mul cycles, i.e. 8 cycles (6+2*7=20 cycles if 16x32mul)
|
||||
RexQx[k2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, ajpQx, 14) -
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bjpQx, 14);
|
||||
RexQx[k3] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc3Q14, akmQx, 14) -
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss3Q14, bkmQx, 14);
|
||||
ImxQx[k1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss1Q14, akpQx, 14) +
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc1Q14, bkpQx, 14);
|
||||
ImxQx[k2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, ajpQx, 14) +
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bjpQx, 14);
|
||||
ImxQx[k3] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss3Q14, akmQx, 14) +
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc3Q14, bkmQx, 14);
|
||||
//This mul segment needs 6*8 = 48 cycles for 16x16 muls, but 6*20 = 120 cycles for 16x32 muls
|
||||
|
||||
|
||||
}
|
||||
/* Complexity is: 51+48 = 99 cycles for 16x16 muls, but 51+120 = 171 cycles for 16x32 muls*/
|
||||
|
||||
// transform for factor of 3
|
||||
kk=0;
|
||||
k1=20;
|
||||
k2=40;
|
||||
|
||||
for (hh=0; hh<4; hh++) {
|
||||
for (ii=0; ii<20; ii++) {
|
||||
akQx = RexQx[kk];
|
||||
bkQx = ImxQx[kk];
|
||||
ajQx = RexQx[k1] + RexQx[k2];
|
||||
bjQx = ImxQx[k1] + ImxQx[k2];
|
||||
RexQx[kk] = akQx + ajQx;
|
||||
ImxQx[kk] = bkQx + bjQx;
|
||||
tmp116 = WEBRTC_SPL_RSHIFT_W16(ajQx, 1);
|
||||
tmp216 = WEBRTC_SPL_RSHIFT_W16(bjQx, 1);
|
||||
akQx = akQx - tmp116;
|
||||
bkQx = bkQx - tmp216;
|
||||
tmp116 = RexQx[k1] - RexQx[k2];
|
||||
tmp216 = ImxQx[k1] - ImxQx[k2];
|
||||
|
||||
ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss60Q14, tmp116, 14); // Q14*Qx>>14 = Qx
|
||||
bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss60Q14, tmp216, 14); // Q14*Qx>>14 = Qx
|
||||
RexQx[k1] = akQx - bjQx;
|
||||
RexQx[k2] = akQx + bjQx;
|
||||
ImxQx[k1] = bkQx + ajQx;
|
||||
ImxQx[k2] = bkQx - ajQx;
|
||||
|
||||
kk++;
|
||||
k1++;
|
||||
k2++;
|
||||
}
|
||||
/* Complexity : (31+6)*20 = 740 cycles for 16x16 muls, but (31+18)*20 = 980 cycles for 16x32 muls*/
|
||||
kk=kk+40;
|
||||
k1=k1+40;
|
||||
k2=k2+40;
|
||||
}
|
||||
/* Complexity : 4*(740+3) = 2972 cycles for 16x16 muls, but 4*(980+3) = 3932 cycles for 16x32 muls*/
|
||||
|
||||
/* multiply by rotation factor for odd factor 3 or 5 (not for 4)
|
||||
Same code (duplicated) for both ii=2 and ii=3 */
|
||||
kk = 1;
|
||||
ee = 0;
|
||||
ff = 0;
|
||||
|
||||
for (gg=0; gg<19; gg++) {
|
||||
kk += 20;
|
||||
ff = ff+4;
|
||||
for (hh=0; hh<2; hh++) {
|
||||
ee = ff + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(hh, ff);
|
||||
dd = ee + 60;
|
||||
ccc2Q14 = kCosTabFfftQ14[ee];
|
||||
sss2Q14 = kCosTabFfftQ14[dd];
|
||||
if (iSign==1) {
|
||||
sss2Q14 = -sss2Q14;
|
||||
}
|
||||
for (ii=0; ii<4; ii++) {
|
||||
akQx = RexQx[kk];
|
||||
bkQx = ImxQx[kk];
|
||||
RexQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akQx, 14) - // Q14*Qx>>14 = Qx
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkQx, 14);
|
||||
ImxQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akQx, 14) + // Q14*Qx>>14 = Qx
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkQx, 14);
|
||||
|
||||
|
||||
kk += 60;
|
||||
}
|
||||
kk = kk - 220;
|
||||
}
|
||||
// Complexity: 2*(13+5+4*13+2) = 144 for 16x16 muls, but 2*(13+5+4*33+2) = 304 cycles for 16x32 muls
|
||||
kk = kk - 59;
|
||||
}
|
||||
// Complexity: 19*144 = 2736 for 16x16 muls, but 19*304 = 5776 cycles for 16x32 muls
|
||||
|
||||
// transform for factor of 5
|
||||
kk = 0;
|
||||
ccc2Q14 = kCosTabFfftQ14[96];
|
||||
sss2Q14 = kCosTabFfftQ14[84];
|
||||
if (iSign==1) {
|
||||
sss2Q14 = -sss2Q14;
|
||||
}
|
||||
|
||||
for (hh=0; hh<4; hh++) {
|
||||
for (ii=0; ii<12; ii++) {
|
||||
k1 = kk + 4;
|
||||
k2 = k1 + 4;
|
||||
k3 = k2 + 4;
|
||||
k4 = k3 + 4;
|
||||
|
||||
akpQx = RexQx[k1] + RexQx[k4];
|
||||
akmQx = RexQx[k1] - RexQx[k4];
|
||||
bkpQx = ImxQx[k1] + ImxQx[k4];
|
||||
bkmQx = ImxQx[k1] - ImxQx[k4];
|
||||
ajpQx = RexQx[k2] + RexQx[k3];
|
||||
ajmQx = RexQx[k2] - RexQx[k3];
|
||||
bjpQx = ImxQx[k2] + ImxQx[k3];
|
||||
bjmQx = ImxQx[k2] - ImxQx[k3];
|
||||
aaQx = RexQx[kk];
|
||||
bbQx = ImxQx[kk];
|
||||
RexQx[kk] = aaQx + akpQx + ajpQx;
|
||||
ImxQx[kk] = bbQx + bkpQx + bjpQx;
|
||||
|
||||
akQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, akpQx, 14) +
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, ajpQx, 14) + aaQx;
|
||||
bkQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, bkpQx, 14) +
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bjpQx, 14) + bbQx;
|
||||
ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, akmQx, 14) +
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, ajmQx, 14);
|
||||
bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, bkmQx, 14) +
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bjmQx, 14);
|
||||
// 32+4*8=64 or 32+4*20=112
|
||||
|
||||
RexQx[k1] = akQx - bjQx;
|
||||
RexQx[k4] = akQx + bjQx;
|
||||
ImxQx[k1] = bkQx + ajQx;
|
||||
ImxQx[k4] = bkQx - ajQx;
|
||||
|
||||
akQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akpQx, 14) +
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, ajpQx, 14) + aaQx;
|
||||
bkQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkpQx, 14) +
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, bjpQx, 14) + bbQx;
|
||||
ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akmQx, 14) -
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, ajmQx, 14);
|
||||
bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkmQx, 14) -
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, bjmQx, 14);
|
||||
// 8+4*8=40 or 8+4*20=88
|
||||
|
||||
RexQx[k2] = akQx - bjQx;
|
||||
RexQx[k3] = akQx + bjQx;
|
||||
ImxQx[k2] = bkQx + ajQx;
|
||||
ImxQx[k3] = bkQx - ajQx;
|
||||
|
||||
kk = k4 + 4;
|
||||
}
|
||||
// Complexity: 12*(64+40+10) = 1368 for 16x16 muls, but 12*(112+88+10) = 2520 cycles for 16x32 muls
|
||||
kk -= 239;
|
||||
}
|
||||
// Complexity: 4*1368 = 5472 for 16x16 muls, but 4*2520 = 10080 cycles for 16x32 muls
|
||||
|
||||
/* multiply by rotation factor for odd factor 3 or 5 (not for 4)
|
||||
Same code (duplicated) for both ii=2 and ii=3 */
|
||||
kk = 1;
|
||||
ee=0;
|
||||
|
||||
for (gg=0; gg<3; gg++) {
|
||||
kk += 4;
|
||||
dd = 12 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(12, gg);
|
||||
ff = 0;
|
||||
for (hh=0; hh<4; hh++) {
|
||||
ff = ff+dd;
|
||||
ee = ff+60;
|
||||
for (ii=0; ii<12; ii++) {
|
||||
akQx = RexQx[kk];
|
||||
bkQx = ImxQx[kk];
|
||||
|
||||
ccc2Q14 = kCosTabFfftQ14[ff];
|
||||
sss2Q14 = kCosTabFfftQ14[ee];
|
||||
|
||||
if (iSign==1) {
|
||||
sss2Q14 = -sss2Q14;
|
||||
}
|
||||
|
||||
RexQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akQx, 14) -
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkQx, 14);
|
||||
ImxQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akQx, 14) +
|
||||
(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkQx, 14);
|
||||
|
||||
kk += 20;
|
||||
}
|
||||
kk = kk - 236;
|
||||
// Complexity: 12*(12+12) = 288 for 16x16 muls, but 12*(12+32) = 528 cycles for 16x32 muls
|
||||
}
|
||||
kk = kk - 19;
|
||||
// Complexity: 4*288+6 for 16x16 muls, but 4*528+6 cycles for 16x32 muls
|
||||
}
|
||||
// Complexity: 3*4*288+6 = 3462 for 16x16 muls, but 3*4*528+6 = 6342 cycles for 16x32 muls
|
||||
|
||||
|
||||
// last transform for factor of 4 */
|
||||
for (kk=0; kk<240; kk=kk+4) {
|
||||
k1 = kk + 1;
|
||||
k2 = k1 + 1;
|
||||
k3 = k2 + 1;
|
||||
|
||||
akpQx = RexQx[kk] + RexQx[k2];
|
||||
akmQx = RexQx[kk] - RexQx[k2];
|
||||
ajpQx = RexQx[k1] + RexQx[k3];
|
||||
ajmQx = RexQx[k1] - RexQx[k3];
|
||||
bkpQx = ImxQx[kk] + ImxQx[k2];
|
||||
bkmQx = ImxQx[kk] - ImxQx[k2];
|
||||
bjpQx = ImxQx[k1] + ImxQx[k3];
|
||||
bjmQx = ImxQx[k1] - ImxQx[k3];
|
||||
RexQx[kk] = akpQx + ajpQx;
|
||||
ImxQx[kk] = bkpQx + bjpQx;
|
||||
ajpQx = akpQx - ajpQx;
|
||||
bjpQx = bkpQx - bjpQx;
|
||||
if (iSign < 0) {
|
||||
akpQx = akmQx + bjmQx;
|
||||
bkpQx = bkmQx - ajmQx;
|
||||
akmQx -= bjmQx;
|
||||
bkmQx += ajmQx;
|
||||
} else {
|
||||
akpQx = akmQx - bjmQx;
|
||||
bkpQx = bkmQx + ajmQx;
|
||||
akmQx += bjmQx;
|
||||
bkmQx -= ajmQx;
|
||||
}
|
||||
RexQx[k1] = akpQx;
|
||||
RexQx[k2] = ajpQx;
|
||||
RexQx[k3] = akmQx;
|
||||
ImxQx[k1] = bkpQx;
|
||||
ImxQx[k2] = bjpQx;
|
||||
ImxQx[k3] = bkmQx;
|
||||
}
|
||||
// Complexity: 60*45 = 2700 for 16x16 muls, but 60*45 = 2700 cycles for 16x32 muls
|
||||
|
||||
/* permute the results to normal order */
|
||||
for (ii=0; ii<240; ii++) {
|
||||
ReDATAQx[ii]=RexQx[ii];
|
||||
ImDATAQx[ii]=ImxQx[ii];
|
||||
}
|
||||
// Complexity: 240*2=480 cycles
|
||||
|
||||
for (ii=0; ii<240; ii++) {
|
||||
RexQx[ii]=ReDATAQx[kSortTabFft[ii]];
|
||||
ImxQx[ii]=ImDATAQx[kSortTabFft[ii]];
|
||||
}
|
||||
// Complexity: 240*2*2=960 cycles
|
||||
|
||||
// Total complexity:
|
||||
// 16x16 16x32
|
||||
// Complexity: 10 10
|
||||
// Complexity: 99 171
|
||||
// Complexity: 2972 3932
|
||||
// Complexity: 2736 5776
|
||||
// Complexity: 5472 10080
|
||||
// Complexity: 3462 6342
|
||||
// Complexity: 2700 2700
|
||||
// Complexity: 480 480
|
||||
// Complexity: 960 960
|
||||
// =======================
|
||||
// 18891 30451
|
||||
//
|
||||
// If this FFT is called 2 time each frame, i.e. 67 times per second, it will correspond to
|
||||
// a C54 complexity of 67*18891/1000000 = 1.27 MIPS with 16x16-muls, and 67*30451/1000000 =
|
||||
// = 2.04 MIPS with 16x32-muls. Note that this routine somtimes is called 6 times during the
|
||||
// encoding of a frame, i.e. the max complexity would be 7/2*1.27 = 4.4 MIPS for the 16x16 mul case.
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*--------------------------------*-C-*---------------------------------*
|
||||
* File:
|
||||
* fft.h
|
||||
* ---------------------------------------------------------------------*
|
||||
* Re[]: real value array
|
||||
* Im[]: imaginary value array
|
||||
* nTotal: total number of complex values
|
||||
* nPass: number of elements involved in this pass of transform
|
||||
* nSpan: nspan/nPass = number of bytes to increment pointer
|
||||
* in Re[] and Im[]
|
||||
* isign: exponent: +1 = forward -1 = reverse
|
||||
* scaling: normalizing constant by which the final result is *divided*
|
||||
* scaling == -1, normalize by total dimension of the transform
|
||||
* scaling < -1, normalize by the square-root of the total dimension
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
* See the comments in the code for correct usage!
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FFT_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FFT_H_
|
||||
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_FftRadix16Fastest(WebRtc_Word16 RexQx[], WebRtc_Word16 ImxQx[], WebRtc_Word16 iSign);
|
||||
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FFT_H_ */
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* filterbank_tables.c
|
||||
*
|
||||
* This file contains variables that are used in
|
||||
* filterbanks.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "filterbank_tables.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
/* HPstcoeff_in_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2};
|
||||
* In float, they are:
|
||||
* {-1.94895953203325f, 0.94984516000000f, -0.05101826139794f, 0.05015484000000f};
|
||||
*/
|
||||
const WebRtc_Word16 WebRtcIsacfix_kHpStCoeffInQ30[8] = {
|
||||
-31932, 16189, /* Q30 hi/lo pair */
|
||||
15562, 17243, /* Q30 hi/lo pair */
|
||||
-26748, -17186, /* Q35 hi/lo pair */
|
||||
26296, -27476 /* Q35 hi/lo pair */
|
||||
};
|
||||
|
||||
/* HPstcoeff_out_1_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2};
|
||||
* In float, they are:
|
||||
* {-1.99701049409000f, 0.99714204490000f, 0.01701049409000f, -0.01704204490000f};
|
||||
*/
|
||||
const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut1Q30[8] = {
|
||||
-32719, -1306, /* Q30 hi/lo pair */
|
||||
16337, 11486, /* Q30 hi/lo pair */
|
||||
8918, 26078, /* Q35 hi/lo pair */
|
||||
-8935, 3956 /* Q35 hi/lo pair */
|
||||
};
|
||||
|
||||
/* HPstcoeff_out_2_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2};
|
||||
* In float, they are:
|
||||
* {-1.98645294509837f, 0.98672435560000f, 0.00645294509837f, -0.00662435560000f};
|
||||
*/
|
||||
const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut2Q30[8] = {
|
||||
-32546, -2953, /* Q30 hi/lo pair */
|
||||
16166, 32233, /* Q30 hi/lo pair */
|
||||
3383, 13217, /* Q35 hi/lo pair */
|
||||
-3473, -4597 /* Q35 hi/lo pair */
|
||||
};
|
||||
|
||||
/* The upper channel all-pass filter factors */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kUpperApFactorsQ15[2] = {
|
||||
1137, 12537
|
||||
};
|
||||
|
||||
/* The lower channel all-pass filter factors */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kLowerApFactorsQ15[2] = {
|
||||
5059, 24379
|
||||
};
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* filterbank_tables.h
|
||||
*
|
||||
* Header file for variables that are defined in
|
||||
* filterbank_tables.c.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
/********************* Coefficient Tables ************************/
|
||||
|
||||
/* HPstcoeff_in_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kHpStCoeffInQ30[8]; /* [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */
|
||||
|
||||
/* HPstcoeff_out_1_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut1Q30[8]; /* [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */
|
||||
|
||||
/* HPstcoeff_out_2_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut2Q30[8]; /* [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */
|
||||
|
||||
/* The upper channel all-pass filter factors */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kUpperApFactorsQ15[2];
|
||||
|
||||
/* The lower channel all-pass filter factors */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kLowerApFactorsQ15[2];
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_ */
|
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* filterbanks.c
|
||||
*
|
||||
* This file contains function
|
||||
* WebRtcIsacfix_SplitAndFilter, and WebRtcIsacfix_FilterAndCombine
|
||||
* which implement filterbanks that produce decimated lowpass and
|
||||
* highpass versions of a signal, and performs reconstruction.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "codec.h"
|
||||
#include "filterbank_tables.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
static void AllpassFilter2FixDec16(WebRtc_Word16 *InOut16, //Q0
|
||||
const WebRtc_Word16 *APSectionFactors, //Q15
|
||||
WebRtc_Word16 lengthInOut,
|
||||
WebRtc_Word16 NumberOfSections,
|
||||
WebRtc_Word32 *FilterState) //Q16
|
||||
{
|
||||
int n, j;
|
||||
WebRtc_Word32 a, b;
|
||||
|
||||
for (j=0; j<NumberOfSections; j++) {
|
||||
for (n=0;n<lengthInOut;n++) {
|
||||
|
||||
|
||||
a = WEBRTC_SPL_MUL_16_16(APSectionFactors[j], InOut16[n]); //Q15*Q0=Q15
|
||||
a = WEBRTC_SPL_LSHIFT_W32(a, 1); // Q15 -> Q16
|
||||
b = WEBRTC_SPL_ADD_SAT_W32(a, FilterState[j]); //Q16+Q16=Q16
|
||||
a = WEBRTC_SPL_MUL_16_16_RSFT(-APSectionFactors[j], (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16), 0); //Q15*Q0=Q15
|
||||
FilterState[j] = WEBRTC_SPL_ADD_SAT_W32(WEBRTC_SPL_LSHIFT_W32(a,1), WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)InOut16[n],16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16
|
||||
InOut16[n] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16); //Save as Q0
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void HighpassFilterFixDec32(
|
||||
WebRtc_Word16 *io, /* Q0:input Q0: Output */
|
||||
WebRtc_Word16 len, /* length of input, Input */
|
||||
const WebRtc_Word16 *coeff, /* Coeff: [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */
|
||||
WebRtc_Word32 *state) /* Q4:filter state Input/Output */
|
||||
{
|
||||
int k;
|
||||
WebRtc_Word32 a, b, c, in;
|
||||
|
||||
|
||||
|
||||
for (k=0; k<len; k++) {
|
||||
in = (WebRtc_Word32)io[k];
|
||||
/* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */
|
||||
a = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*2], coeff[2*2+1], state[0]);
|
||||
b = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*3], coeff[2*3+1], state[1]);
|
||||
|
||||
c = ((WebRtc_Word32)in) + WEBRTC_SPL_RSHIFT_W32(a+b, 7); // Q0
|
||||
//c = WEBRTC_SPL_RSHIFT_W32(c, 1); // Q-1
|
||||
io[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(c); // Write output as Q0
|
||||
|
||||
/* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */
|
||||
a = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*0], coeff[2*0+1], state[0]);
|
||||
b = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*1], coeff[2*1+1], state[1]);
|
||||
|
||||
c = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in, 2) - a - b; // New state in Q2
|
||||
c= (WebRtc_Word32)WEBRTC_SPL_SAT((WebRtc_Word32)536870911, c, (WebRtc_Word32)-536870912); // Check for wrap-around
|
||||
|
||||
state[1] = state[0];
|
||||
state[0] = WEBRTC_SPL_LSHIFT_W32(c, 2); // Write state as Q4
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsacfix_SplitAndFilter1(WebRtc_Word16 *pin,
|
||||
WebRtc_Word16 *LP16,
|
||||
WebRtc_Word16 *HP16,
|
||||
PreFiltBankstr *prefiltdata)
|
||||
{
|
||||
/* Function WebRtcIsacfix_SplitAndFilter */
|
||||
/* This function creates low-pass and high-pass decimated versions of part of
|
||||
the input signal, and part of the signal in the input 'lookahead buffer'. */
|
||||
|
||||
int k;
|
||||
|
||||
WebRtc_Word16 tempin_ch1[FRAMESAMPLES/2 + QLOOKAHEAD];
|
||||
WebRtc_Word16 tempin_ch2[FRAMESAMPLES/2 + QLOOKAHEAD];
|
||||
WebRtc_Word32 tmpState[WEBRTC_SPL_MUL_16_16(2,(QORDER-1))]; /* 4 */
|
||||
|
||||
|
||||
/* High pass filter */
|
||||
HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
|
||||
|
||||
|
||||
/* First Channel */
|
||||
for (k=0;k<FRAMESAMPLES/2;k++) {
|
||||
tempin_ch1[QLOOKAHEAD + k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
|
||||
}
|
||||
for (k=0;k<QLOOKAHEAD;k++) {
|
||||
tempin_ch1[k]=prefiltdata->INLABUF1_fix[k];
|
||||
prefiltdata->INLABUF1_fix[k]=pin[FRAMESAMPLES+1-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
|
||||
}
|
||||
|
||||
/* Second Channel. This is exactly like the first channel, except that the
|
||||
even samples are now filtered instead (lower channel). */
|
||||
for (k=0;k<FRAMESAMPLES/2;k++) {
|
||||
tempin_ch2[QLOOKAHEAD+k] = pin[WEBRTC_SPL_MUL_16_16(2, k)];
|
||||
}
|
||||
for (k=0;k<QLOOKAHEAD;k++) {
|
||||
tempin_ch2[k]=prefiltdata->INLABUF2_fix[k];
|
||||
prefiltdata->INLABUF2_fix[k]=pin[FRAMESAMPLES-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
|
||||
}
|
||||
|
||||
|
||||
/*obtain polyphase components by forward all-pass filtering through each channel */
|
||||
/* The all pass filtering automatically updates the filter states which are exported in the
|
||||
prefiltdata structure */
|
||||
AllpassFilter2FixDec16(tempin_ch1,WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_fix);
|
||||
AllpassFilter2FixDec16(tempin_ch2,WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_fix);
|
||||
|
||||
for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++)
|
||||
tmpState[k] = prefiltdata->INSTAT1_fix[k];
|
||||
AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2,WebRtcIsacfix_kUpperApFactorsQ15, QLOOKAHEAD , NUMBEROFCHANNELAPSECTIONS, tmpState);
|
||||
for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++)
|
||||
tmpState[k] = prefiltdata->INSTAT2_fix[k];
|
||||
AllpassFilter2FixDec16(tempin_ch2 + FRAMESAMPLES/2,WebRtcIsacfix_kLowerApFactorsQ15, QLOOKAHEAD , NUMBEROFCHANNELAPSECTIONS, tmpState);
|
||||
|
||||
|
||||
/* Now Construct low-pass and high-pass signals as combinations of polyphase components */
|
||||
for (k=0; k<FRAMESAMPLES/2 + QLOOKAHEAD; k++) {
|
||||
WebRtc_Word32 tmp1, tmp2, tmp3;
|
||||
tmp1 = (WebRtc_Word32)tempin_ch1[k]; // Q0 -> Q0
|
||||
tmp2 = (WebRtc_Word32)tempin_ch2[k]; // Q0 -> Q0
|
||||
tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
|
||||
LP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
|
||||
tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
|
||||
HP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
|
||||
}
|
||||
|
||||
}/*end of WebRtcIsacfix_SplitAndFilter */
|
||||
|
||||
|
||||
#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
|
||||
/* Without lookahead */
|
||||
void WebRtcIsacfix_SplitAndFilter2(WebRtc_Word16 *pin,
|
||||
WebRtc_Word16 *LP16,
|
||||
WebRtc_Word16 *HP16,
|
||||
PreFiltBankstr *prefiltdata)
|
||||
{
|
||||
/* Function WebRtcIsacfix_SplitAndFilter2 */
|
||||
/* This function creates low-pass and high-pass decimated versions of part of
|
||||
the input signal. */
|
||||
|
||||
int k;
|
||||
|
||||
WebRtc_Word16 tempin_ch1[FRAMESAMPLES/2];
|
||||
WebRtc_Word16 tempin_ch2[FRAMESAMPLES/2];
|
||||
|
||||
|
||||
/* High pass filter */
|
||||
HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
|
||||
|
||||
|
||||
/* First Channel */
|
||||
for (k=0;k<FRAMESAMPLES/2;k++) {
|
||||
tempin_ch1[k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
|
||||
}
|
||||
|
||||
/* Second Channel. This is exactly like the first channel, except that the
|
||||
even samples are now filtered instead (lower channel). */
|
||||
for (k=0;k<FRAMESAMPLES/2;k++) {
|
||||
tempin_ch2[k] = pin[WEBRTC_SPL_MUL_16_16(2, k)];
|
||||
}
|
||||
|
||||
|
||||
/*obtain polyphase components by forward all-pass filtering through each channel */
|
||||
/* The all pass filtering automatically updates the filter states which are exported in the
|
||||
prefiltdata structure */
|
||||
AllpassFilter2FixDec16(tempin_ch1,WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_fix);
|
||||
AllpassFilter2FixDec16(tempin_ch2,WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_fix);
|
||||
|
||||
|
||||
/* Now Construct low-pass and high-pass signals as combinations of polyphase components */
|
||||
for (k=0; k<FRAMESAMPLES/2; k++) {
|
||||
WebRtc_Word32 tmp1, tmp2, tmp3;
|
||||
tmp1 = (WebRtc_Word32)tempin_ch1[k]; // Q0 -> Q0
|
||||
tmp2 = (WebRtc_Word32)tempin_ch2[k]; // Q0 -> Q0
|
||||
tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
|
||||
LP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
|
||||
tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
|
||||
HP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
|
||||
}
|
||||
|
||||
}/*end of WebRtcIsacfix_SplitAndFilter */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
////////// Combining
|
||||
/* Function WebRtcIsacfix_FilterAndCombine */
|
||||
/* This is a decoder function that takes the decimated
|
||||
length FRAMESAMPLES/2 input low-pass and
|
||||
high-pass signals and creates a reconstructed fullband
|
||||
output signal of length FRAMESAMPLES. WebRtcIsacfix_FilterAndCombine
|
||||
is the sibling function of WebRtcIsacfix_SplitAndFilter */
|
||||
/* INPUTS:
|
||||
inLP: a length FRAMESAMPLES/2 array of input low-pass
|
||||
samples.
|
||||
inHP: a length FRAMESAMPLES/2 array of input high-pass
|
||||
samples.
|
||||
postfiltdata: input data structure containing the filterbank
|
||||
states from the previous decoding iteration.
|
||||
OUTPUTS:
|
||||
Out: a length FRAMESAMPLES array of output reconstructed
|
||||
samples (fullband) based on the input low-pass and
|
||||
high-pass signals.
|
||||
postfiltdata: the input data structure containing the filterbank
|
||||
states is updated for the next decoding iteration */
|
||||
void WebRtcIsacfix_FilterAndCombine1(WebRtc_Word16 *tempin_ch1,
|
||||
WebRtc_Word16 *tempin_ch2,
|
||||
WebRtc_Word16 *out16,
|
||||
PostFiltBankstr *postfiltdata)
|
||||
{
|
||||
int k;
|
||||
WebRtc_Word16 in[FRAMESAMPLES];
|
||||
|
||||
/* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors
|
||||
that were used as a lower channel at the encoding side. So at the decoder, the
|
||||
corresponding all-pass filter factors for each channel are swapped.*/
|
||||
|
||||
AllpassFilter2FixDec16(tempin_ch1, WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_fix);
|
||||
|
||||
/* Now, all-pass filter the new lower channel signal. But since all-pass filter factors
|
||||
at the decoder are swapped from the ones at the encoder, the 'upper' channel
|
||||
all-pass filter factors (kUpperApFactors) are used to filter this new lower channel signal */
|
||||
|
||||
AllpassFilter2FixDec16(tempin_ch2, WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_fix);
|
||||
|
||||
/* Merge outputs to form the full length output signal.*/
|
||||
for (k=0;k<FRAMESAMPLES/2;k++) {
|
||||
in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
|
||||
in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
|
||||
}
|
||||
|
||||
/* High pass filter */
|
||||
HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
|
||||
HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
|
||||
|
||||
for (k=0;k<FRAMESAMPLES;k++) {
|
||||
out16[k] = in[k];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
/* Function WebRtcIsacfix_FilterAndCombine */
|
||||
/* This is a decoder function that takes the decimated
|
||||
length len/2 input low-pass and
|
||||
high-pass signals and creates a reconstructed fullband
|
||||
output signal of length len. WebRtcIsacfix_FilterAndCombine
|
||||
is the sibling function of WebRtcIsacfix_SplitAndFilter */
|
||||
/* INPUTS:
|
||||
inLP: a length len/2 array of input low-pass
|
||||
samples.
|
||||
inHP: a length len/2 array of input high-pass
|
||||
samples.
|
||||
postfiltdata: input data structure containing the filterbank
|
||||
states from the previous decoding iteration.
|
||||
OUTPUTS:
|
||||
Out: a length len array of output reconstructed
|
||||
samples (fullband) based on the input low-pass and
|
||||
high-pass signals.
|
||||
postfiltdata: the input data structure containing the filterbank
|
||||
states is updated for the next decoding iteration */
|
||||
void WebRtcIsacfix_FilterAndCombine2(WebRtc_Word16 *tempin_ch1,
|
||||
WebRtc_Word16 *tempin_ch2,
|
||||
WebRtc_Word16 *out16,
|
||||
PostFiltBankstr *postfiltdata,
|
||||
WebRtc_Word16 len)
|
||||
{
|
||||
int k;
|
||||
WebRtc_Word16 in[FRAMESAMPLES];
|
||||
|
||||
/* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors
|
||||
that were used as a lower channel at the encoding side. So at the decoder, the
|
||||
corresponding all-pass filter factors for each channel are swapped.*/
|
||||
|
||||
AllpassFilter2FixDec16(tempin_ch1, WebRtcIsacfix_kLowerApFactorsQ15,(WebRtc_Word16) (len/2), NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_fix);
|
||||
|
||||
/* Now, all-pass filter the new lower channel signal. But since all-pass filter factors
|
||||
at the decoder are swapped from the ones at the encoder, the 'upper' channel
|
||||
all-pass filter factors (kUpperApFactors) are used to filter this new lower channel signal */
|
||||
|
||||
AllpassFilter2FixDec16(tempin_ch2, WebRtcIsacfix_kUpperApFactorsQ15, (WebRtc_Word16) (len/2), NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_fix);
|
||||
|
||||
/* Merge outputs to form the full length output signal.*/
|
||||
for (k=0;k<len/2;k++) {
|
||||
in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
|
||||
in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
|
||||
}
|
||||
|
||||
/* High pass filter */
|
||||
HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
|
||||
HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
|
||||
|
||||
for (k=0;k<len;k++) {
|
||||
out16[k] = in[k];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* filters.c
|
||||
*
|
||||
* This file contains function WebRtcIsacfix_AutocorrC,
|
||||
* AllpassFilterForDec32, and WebRtcIsacfix_DecimateAllpass32
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pitch_estimator.h"
|
||||
#include "lpc_masking_model.h"
|
||||
#include "codec.h"
|
||||
|
||||
// Autocorrelation function in fixed point.
|
||||
// NOTE! Different from SPLIB-version in how it scales the signal.
|
||||
int WebRtcIsacfix_AutocorrC(WebRtc_Word32* __restrict r,
|
||||
const WebRtc_Word16* __restrict x,
|
||||
WebRtc_Word16 N,
|
||||
WebRtc_Word16 order,
|
||||
WebRtc_Word16* __restrict scale) {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int16_t scaling = 0;
|
||||
int32_t sum = 0;
|
||||
uint32_t temp = 0;
|
||||
int64_t prod = 0;
|
||||
|
||||
// Calculate r[0].
|
||||
for (i = 0; i < N; i++) {
|
||||
prod += WEBRTC_SPL_MUL_16_16(x[i], x[i]);
|
||||
}
|
||||
|
||||
// Calculate scaling (the value of shifting).
|
||||
temp = (uint32_t)(prod >> 31);
|
||||
if(temp == 0) {
|
||||
scaling = 0;
|
||||
} else {
|
||||
scaling = 32 - WebRtcSpl_NormU32(temp);
|
||||
}
|
||||
r[0] = (int32_t)(prod >> scaling);
|
||||
|
||||
// Perform the actual correlation calculation.
|
||||
for (i = 1; i < order + 1; i++) {
|
||||
prod = 0;
|
||||
for (j = 0; j < N - i; j++) {
|
||||
prod += WEBRTC_SPL_MUL_16_16(x[j], x[i + j]);
|
||||
}
|
||||
sum = (int32_t)(prod >> scaling);
|
||||
r[i] = sum;
|
||||
}
|
||||
|
||||
*scale = scaling;
|
||||
|
||||
return(order + 1);
|
||||
}
|
||||
|
||||
static const WebRtc_Word32 kApUpperQ15[ALLPASSSECTIONS] = { 1137, 12537 };
|
||||
static const WebRtc_Word32 kApLowerQ15[ALLPASSSECTIONS] = { 5059, 24379 };
|
||||
|
||||
|
||||
static void AllpassFilterForDec32(WebRtc_Word16 *InOut16, //Q0
|
||||
const WebRtc_Word32 *APSectionFactors, //Q15
|
||||
WebRtc_Word16 lengthInOut,
|
||||
WebRtc_Word32 *FilterState) //Q16
|
||||
{
|
||||
int n, j;
|
||||
WebRtc_Word32 a, b;
|
||||
|
||||
for (j=0; j<ALLPASSSECTIONS; j++) {
|
||||
for (n=0;n<lengthInOut;n+=2){
|
||||
a = WEBRTC_SPL_MUL_16_32_RSFT16(InOut16[n], APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15
|
||||
a = WEBRTC_SPL_LSHIFT_W32(a, 1); // Q15 -> Q16
|
||||
b = WEBRTC_SPL_ADD_SAT_W32(a, FilterState[j]); //Q16+Q16=Q16
|
||||
a = WEBRTC_SPL_MUL_16_32_RSFT16(
|
||||
(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16),
|
||||
-APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15
|
||||
FilterState[j] = WEBRTC_SPL_ADD_SAT_W32(
|
||||
WEBRTC_SPL_LSHIFT_W32(a,1),
|
||||
WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)InOut16[n], 16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16
|
||||
InOut16[n] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16); //Save as Q0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void WebRtcIsacfix_DecimateAllpass32(const WebRtc_Word16 *in,
|
||||
WebRtc_Word32 *state_in, /* array of size: 2*ALLPASSSECTIONS+1 */
|
||||
WebRtc_Word16 N, /* number of input samples */
|
||||
WebRtc_Word16 *out) /* array of size N/2 */
|
||||
{
|
||||
int n;
|
||||
WebRtc_Word16 data_vec[PITCH_FRAME_LEN];
|
||||
|
||||
/* copy input */
|
||||
memcpy(data_vec+1, in, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), (N-1)));
|
||||
|
||||
|
||||
data_vec[0] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)],16); //the z^(-1) state
|
||||
state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)] = WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)in[N-1],16);
|
||||
|
||||
|
||||
|
||||
AllpassFilterForDec32(data_vec+1, kApUpperQ15, N, state_in);
|
||||
AllpassFilterForDec32(data_vec, kApLowerQ15, N, state_in+ALLPASSSECTIONS);
|
||||
|
||||
for (n=0;n<N/2;n++) {
|
||||
out[n]=WEBRTC_SPL_ADD_SAT_W16(data_vec[WEBRTC_SPL_MUL_16_16(2, n)], data_vec[WEBRTC_SPL_MUL_16_16(2, n)+1]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* filters_neon.c
|
||||
*
|
||||
* This file contains function WebRtcIsacfix_AutocorrNeon, optimized for
|
||||
* ARM Neon platform.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "codec.h"
|
||||
|
||||
// Autocorrelation function in fixed point.
|
||||
// NOTE! Different from SPLIB-version in how it scales the signal.
|
||||
int WebRtcIsacfix_AutocorrNeon(
|
||||
WebRtc_Word32* __restrict r,
|
||||
const WebRtc_Word16* __restrict x,
|
||||
WebRtc_Word16 N,
|
||||
WebRtc_Word16 order,
|
||||
WebRtc_Word16* __restrict scale) {
|
||||
|
||||
// The 1st for loop assumed N % 4 == 0.
|
||||
assert(N % 4 == 0);
|
||||
|
||||
int i = 0;
|
||||
int zeros_low = 0;
|
||||
int zeros_high = 0;
|
||||
int16_t scaling = 0;
|
||||
int32_t sum = 0;
|
||||
|
||||
// Step 1, calculate r[0] and how much scaling is needed.
|
||||
|
||||
int16x4_t reg16x4;
|
||||
int64x1_t reg64x1a;
|
||||
int64x1_t reg64x1b;
|
||||
int32x4_t reg32x4;
|
||||
int64x2_t reg64x2 = vdupq_n_s64(0); // zeros
|
||||
|
||||
// Loop over the samples and do:
|
||||
// sum += WEBRTC_SPL_MUL_16_16(x[i], x[i]);
|
||||
for (i = 0; i < N; i += 4) {
|
||||
reg16x4 = vld1_s16(&x[i]);
|
||||
reg32x4 = vmull_s16(reg16x4, reg16x4);
|
||||
reg64x2 = vpadalq_s32(reg64x2, reg32x4);
|
||||
}
|
||||
reg64x1a = vget_low_s64(reg64x2);
|
||||
reg64x1b = vget_high_s64(reg64x2);
|
||||
reg64x1a = vadd_s64(reg64x1a, reg64x1b);
|
||||
|
||||
// Calculate the value of shifting (scaling).
|
||||
__asm__ __volatile__(
|
||||
"vmov %[z_l], %[z_h], %P[reg]\n\t"
|
||||
"clz %[z_l], %[z_l]\n\t"
|
||||
"clz %[z_h], %[z_h]\n\t"
|
||||
:[z_l]"+r"(zeros_low),
|
||||
[z_h]"+r"(zeros_high)
|
||||
:[reg]"w"(reg64x1a)
|
||||
);
|
||||
if (zeros_high != 32) {
|
||||
scaling = (32 - zeros_high + 1);
|
||||
} else if (zeros_low == 0) {
|
||||
scaling = 1;
|
||||
}
|
||||
reg64x1b = -scaling;
|
||||
reg64x1a = vshl_s64(reg64x1a, reg64x1b);
|
||||
|
||||
// Record the result.
|
||||
r[0] = (int32_t)vget_lane_s64(reg64x1a, 0);
|
||||
|
||||
|
||||
// Step 2, perform the actual correlation calculation.
|
||||
|
||||
/* Original C code (for the rest of the function):
|
||||
for (i = 1; i < order + 1; i++) {
|
||||
prod = 0;
|
||||
for (j = 0; j < N - i; j++) {
|
||||
prod += WEBRTC_SPL_MUL_16_16(x[j], x[i + j]);
|
||||
}
|
||||
sum = (int32_t)(prod >> scaling);
|
||||
r[i] = sum;
|
||||
}
|
||||
*/
|
||||
|
||||
for (i = 1; i < order + 1; i++) {
|
||||
int32_t prod_lower = 0;
|
||||
int32_t prod_upper = 0;
|
||||
int16_t* ptr0 = &x[0];
|
||||
int16_t* ptr1 = &x[i];
|
||||
int32_t tmp = 0;
|
||||
|
||||
// Initialize the sum (q9) to zero.
|
||||
__asm__ __volatile__("vmov.i32 q9, #0\n\t":::"q9");
|
||||
|
||||
// Calculate the major block of the samples (a multiple of 8).
|
||||
for (; ptr0 < &x[N - i - 7];) {
|
||||
__asm__ __volatile__(
|
||||
"vld1.16 {d20, d21}, [%[ptr0]]!\n\t"
|
||||
"vld1.16 {d22, d23}, [%[ptr1]]!\n\t"
|
||||
"vmull.s16 q12, d20, d22\n\t"
|
||||
"vmull.s16 q13, d21, d23\n\t"
|
||||
"vpadal.s32 q9, q12\n\t"
|
||||
"vpadal.s32 q9, q13\n\t"
|
||||
|
||||
// Specify constraints.
|
||||
:[ptr0]"+r"(ptr0),
|
||||
[ptr1]"+r"(ptr1)
|
||||
:
|
||||
:"d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27"
|
||||
);
|
||||
}
|
||||
|
||||
// Calculate the rest of the samples.
|
||||
for (; ptr0 < &x[N - i]; ptr0++, ptr1++) {
|
||||
__asm__ __volatile__(
|
||||
"smulbb %[tmp], %[ptr0], %[ptr1]\n\t"
|
||||
"adds %[prod_lower], %[prod_lower], %[tmp]\n\t"
|
||||
"adc %[prod_upper], %[prod_upper], %[tmp], asr #31\n\t"
|
||||
|
||||
// Specify constraints.
|
||||
:[prod_lower]"+r"(prod_lower),
|
||||
[prod_upper]"+r"(prod_upper),
|
||||
[tmp]"+r"(tmp)
|
||||
:[ptr0]"r"(*ptr0),
|
||||
[ptr1]"r"(*ptr1)
|
||||
);
|
||||
}
|
||||
|
||||
// Sum the results up, and do shift.
|
||||
__asm__ __volatile__(
|
||||
"vadd.i64 d18, d19\n\t"
|
||||
"vmov.32 d17[0], %[prod_lower]\n\t"
|
||||
"vmov.32 d17[1], %[prod_upper]\n\t"
|
||||
"vadd.i64 d17, d18\n\t"
|
||||
"mov %[tmp], %[scaling], asr #31\n\t"
|
||||
"vmov.32 d16, %[scaling], %[tmp]\n\t"
|
||||
"vshl.s64 d17, d16\n\t"
|
||||
"vmov.32 %[sum], d17[0]\n\t"
|
||||
|
||||
// Specify constraints.
|
||||
:[sum]"=r"(sum),
|
||||
[tmp]"+r"(tmp)
|
||||
:[prod_upper]"r"(prod_upper),
|
||||
[prod_lower]"r"(prod_lower),
|
||||
[scaling]"r"(-scaling)
|
||||
:"d16", "d17", "d18", "d19"
|
||||
);
|
||||
|
||||
// Record the result.
|
||||
r[i] = sum;
|
||||
}
|
||||
|
||||
// Record the result.
|
||||
*scale = scaling;
|
||||
|
||||
return(order + 1);
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* initialize.c
|
||||
*
|
||||
* Internal initfunctions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "codec.h"
|
||||
#include "structs.h"
|
||||
#include "pitch_estimator.h"
|
||||
|
||||
|
||||
void WebRtcIsacfix_InitMaskingEnc(MaskFiltstr_enc *maskdata) {
|
||||
|
||||
int k;
|
||||
|
||||
for (k = 0; k < WINLEN; k++) {
|
||||
maskdata->DataBufferLoQ0[k] = (WebRtc_Word16) 0;
|
||||
maskdata->DataBufferHiQ0[k] = (WebRtc_Word16) 0;
|
||||
}
|
||||
for (k = 0; k < ORDERLO+1; k++) {
|
||||
maskdata->CorrBufLoQQ[k] = (WebRtc_Word32) 0;
|
||||
maskdata->CorrBufLoQdom[k] = 0;
|
||||
|
||||
maskdata->PreStateLoGQ15[k] = 0;
|
||||
|
||||
}
|
||||
for (k = 0; k < ORDERHI+1; k++) {
|
||||
maskdata->CorrBufHiQQ[k] = (WebRtc_Word32) 0;
|
||||
maskdata->CorrBufHiQdom[k] = 0;
|
||||
maskdata->PreStateHiGQ15[k] = 0;
|
||||
}
|
||||
|
||||
maskdata->OldEnergy = 10;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void WebRtcIsacfix_InitMaskingDec(MaskFiltstr_dec *maskdata) {
|
||||
|
||||
int k;
|
||||
|
||||
for (k = 0; k < ORDERLO+1; k++)
|
||||
{
|
||||
maskdata->PostStateLoGQ0[k] = 0;
|
||||
}
|
||||
for (k = 0; k < ORDERHI+1; k++)
|
||||
{
|
||||
maskdata->PostStateHiGQ0[k] = 0;
|
||||
}
|
||||
|
||||
maskdata->OldEnergy = 10;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void WebRtcIsacfix_InitPreFilterbank(PreFiltBankstr *prefiltdata)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < QLOOKAHEAD; k++) {
|
||||
prefiltdata->INLABUF1_fix[k] = 0;
|
||||
prefiltdata->INLABUF2_fix[k] = 0;
|
||||
}
|
||||
for (k = 0; k < WEBRTC_SPL_MUL_16_16(2,(QORDER-1)); k++) {
|
||||
|
||||
prefiltdata->INSTAT1_fix[k] = 0;
|
||||
prefiltdata->INSTAT2_fix[k] = 0;
|
||||
}
|
||||
|
||||
/* High pass filter states */
|
||||
prefiltdata->HPstates_fix[0] = 0;
|
||||
prefiltdata->HPstates_fix[1] = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void WebRtcIsacfix_InitPostFilterbank(PostFiltBankstr *postfiltdata)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < WEBRTC_SPL_MUL_16_16(2, POSTQORDER); k++) {
|
||||
|
||||
postfiltdata->STATE_0_LOWER_fix[k] = 0;
|
||||
postfiltdata->STATE_0_UPPER_fix[k] = 0;
|
||||
}
|
||||
|
||||
/* High pass filter states */
|
||||
|
||||
postfiltdata->HPstates1_fix[0] = 0;
|
||||
postfiltdata->HPstates1_fix[1] = 0;
|
||||
|
||||
postfiltdata->HPstates2_fix[0] = 0;
|
||||
postfiltdata->HPstates2_fix[1] = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsacfix_InitPitchFilter(PitchFiltstr *pitchfiltdata)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < PITCH_BUFFSIZE; k++)
|
||||
pitchfiltdata->ubufQQ[k] = 0;
|
||||
for (k = 0; k < (PITCH_DAMPORDER); k++)
|
||||
pitchfiltdata->ystateQQ[k] = 0;
|
||||
|
||||
pitchfiltdata->oldlagQ7 = 6400; /* 50.0 in Q7 */
|
||||
pitchfiltdata->oldgainQ12 = 0;
|
||||
}
|
||||
|
||||
void WebRtcIsacfix_InitPitchAnalysis(PitchAnalysisStruct *State)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; k++) {
|
||||
State->dec_buffer16[k] = 0;
|
||||
}
|
||||
for (k = 0; k < WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)+1; k++) {
|
||||
State->decimator_state32[k] = 0;
|
||||
}
|
||||
|
||||
for (k = 0; k < QLOOKAHEAD; k++)
|
||||
State->inbuf[k] = 0;
|
||||
|
||||
WebRtcIsacfix_InitPitchFilter(&(State->PFstr_wght));
|
||||
|
||||
WebRtcIsacfix_InitPitchFilter(&(State->PFstr));
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsacfix_InitPlc( PLCstr *State )
|
||||
{
|
||||
State->decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX;
|
||||
State->decayCoeffNoise = WEBRTC_SPL_WORD16_MAX;
|
||||
|
||||
State->used = PLC_WAS_USED;
|
||||
|
||||
WebRtcSpl_ZerosArrayW16(State->overlapLP, RECOVERY_OVERLAP);
|
||||
WebRtcSpl_ZerosArrayW16(State->lofilt_coefQ15, ORDERLO);
|
||||
WebRtcSpl_ZerosArrayW16(State->hifilt_coefQ15, ORDERHI );
|
||||
|
||||
State->AvgPitchGain_Q12 = 0;
|
||||
State->lastPitchGain_Q12 = 0;
|
||||
State->lastPitchLag_Q7 = 0;
|
||||
State->gain_lo_hiQ17[0]=State->gain_lo_hiQ17[1] = 0;
|
||||
WebRtcSpl_ZerosArrayW16(State->prevPitchInvIn, FRAMESAMPLES/2);
|
||||
WebRtcSpl_ZerosArrayW16(State->prevPitchInvOut, PITCH_MAX_LAG + 10 );
|
||||
WebRtcSpl_ZerosArrayW32(State->prevHP, PITCH_MAX_LAG + 10 );
|
||||
State->pitchCycles = 0;
|
||||
State->A = 0;
|
||||
State->B = 0;
|
||||
State->pitchIndex = 0;
|
||||
State->stretchLag = 240;
|
||||
State->seed = 4447;
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,633 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_ISACFIX_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_ISACFIX_H_
|
||||
|
||||
/*
|
||||
* Define the fixpoint numeric formats
|
||||
*/
|
||||
#include "typedefs.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
void *dummy;
|
||||
} ISACFIX_MainStruct;
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* WebRtcIsacfix_AssignSize(...)
|
||||
*
|
||||
* Functions used when malloc is not allowed
|
||||
* Output the number of bytes needed to allocate for iSAC struct.
|
||||
*
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_AssignSize(int *sizeinbytes);
|
||||
|
||||
/**************************************************************************
|
||||
* WebRtcIsacfix_Assign(...)
|
||||
*
|
||||
* Functions used when malloc is not allowed, it
|
||||
* places a struct at the given address.
|
||||
*
|
||||
* Input:
|
||||
* - *ISAC_main_inst : a pointer to the coder instance.
|
||||
* - ISACFIX_inst_Addr : address of the memory where a space is
|
||||
* for iSAC structure.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_Assign(ISACFIX_MainStruct **inst,
|
||||
void *ISACFIX_inst_Addr);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_Create(...)
|
||||
*
|
||||
* This function creates an ISAC instance, which will contain the state
|
||||
* information for one coding/decoding channel.
|
||||
*
|
||||
* Input:
|
||||
* - *ISAC_main_inst : a pointer to the coder instance.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_Create(ISACFIX_MainStruct **ISAC_main_inst);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_Free(...)
|
||||
*
|
||||
* This function frees the ISAC instance created at the beginning.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : a ISAC instance.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_Free(ISACFIX_MainStruct *ISAC_main_inst);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_EncoderInit(...)
|
||||
*
|
||||
* This function initializes an ISAC instance prior to the encoder calls.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - CodingMode : 0 - Bit rate and frame length are automatically
|
||||
* adjusted to available bandwidth on
|
||||
* transmission channel.
|
||||
* 1 - User sets a frame length and a target bit
|
||||
* rate which is taken as the maximum short-term
|
||||
* average bit rate.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
WebRtc_Word16 CodingMode);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_Encode(...)
|
||||
*
|
||||
* This function encodes 10ms frame(s) and inserts it into a package.
|
||||
* Input speech length has to be 160 samples (10ms). The encoder buffers those
|
||||
* 10ms frames until it reaches the chosen Framesize (480 or 960 samples
|
||||
* corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - speechIn : input speech vector.
|
||||
*
|
||||
* Output:
|
||||
* - encoded : the encoded data vector
|
||||
*
|
||||
* Return value : >0 - Length (in bytes) of coded data
|
||||
* 0 - The buffer didn't reach the chosen framesize
|
||||
* so it keeps buffering speech samples.
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
const WebRtc_Word16 *speechIn,
|
||||
WebRtc_Word16 *encoded);
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_EncodeNb(...)
|
||||
*
|
||||
* This function encodes 10ms narrow band (8 kHz sampling) frame(s) and inserts
|
||||
* it into a package. Input speech length has to be 80 samples (10ms). The encoder
|
||||
* interpolates into wide-band (16 kHz sampling) buffers those
|
||||
* 10ms frames until it reaches the chosen Framesize (480 or 960 wide-band samples
|
||||
* corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
|
||||
*
|
||||
* The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - speechIn : input speech vector.
|
||||
*
|
||||
* Output:
|
||||
* - encoded : the encoded data vector
|
||||
*
|
||||
* Return value : >0 - Length (in bytes) of coded data
|
||||
* 0 - The buffer didn't reach the chosen framesize
|
||||
* so it keeps buffering speech samples.
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
|
||||
#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
WebRtc_Word16 WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
const WebRtc_Word16 *speechIn,
|
||||
WebRtc_Word16 *encoded);
|
||||
#endif // WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_DecoderInit(...)
|
||||
*
|
||||
* This function initializes an ISAC instance prior to the decoder calls.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
*
|
||||
* Return value
|
||||
* : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_UpdateBwEstimate1(...)
|
||||
*
|
||||
* This function updates the estimate of the bandwidth.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - encoded : encoded ISAC frame(s).
|
||||
* - packet_size : size of the packet.
|
||||
* - rtp_seq_number : the RTP number of the packet.
|
||||
* - arr_ts : the arrival time of the packet (from NetEq)
|
||||
* in samples.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
const WebRtc_UWord16 *encoded,
|
||||
WebRtc_Word32 packet_size,
|
||||
WebRtc_UWord16 rtp_seq_number,
|
||||
WebRtc_UWord32 arr_ts);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_UpdateBwEstimate(...)
|
||||
*
|
||||
* This function updates the estimate of the bandwidth.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - encoded : encoded ISAC frame(s).
|
||||
* - packet_size : size of the packet.
|
||||
* - rtp_seq_number : the RTP number of the packet.
|
||||
* - send_ts : the send time of the packet from RTP header,
|
||||
* in samples.
|
||||
* - arr_ts : the arrival time of the packet (from NetEq)
|
||||
* in samples.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
const WebRtc_UWord16 *encoded,
|
||||
WebRtc_Word32 packet_size,
|
||||
WebRtc_UWord16 rtp_seq_number,
|
||||
WebRtc_UWord32 send_ts,
|
||||
WebRtc_UWord32 arr_ts);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_Decode(...)
|
||||
*
|
||||
* This function decodes an ISAC frame. Output speech length
|
||||
* will be a multiple of 480 samples: 480 or 960 samples,
|
||||
* depending on the framesize (30 or 60 ms).
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - encoded : encoded ISAC frame(s)
|
||||
* - len : bytes in encoded vector
|
||||
*
|
||||
* Output:
|
||||
* - decoded : The decoded vector
|
||||
*
|
||||
* Return value : >0 - number of samples in decoded vector
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
const WebRtc_UWord16 *encoded,
|
||||
WebRtc_Word16 len,
|
||||
WebRtc_Word16 *decoded,
|
||||
WebRtc_Word16 *speechType);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_DecodeNb(...)
|
||||
*
|
||||
* This function decodes a ISAC frame in narrow-band (8 kHz sampling).
|
||||
* Output speech length will be a multiple of 240 samples: 240 or 480 samples,
|
||||
* depending on the framesize (30 or 60 ms).
|
||||
*
|
||||
* The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - encoded : encoded ISAC frame(s)
|
||||
* - len : bytes in encoded vector
|
||||
*
|
||||
* Output:
|
||||
* - decoded : The decoded vector
|
||||
*
|
||||
* Return value : >0 - number of samples in decoded vector
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
WebRtc_Word16 WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
const WebRtc_UWord16 *encoded,
|
||||
WebRtc_Word16 len,
|
||||
WebRtc_Word16 *decoded,
|
||||
WebRtc_Word16 *speechType);
|
||||
#endif // WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_DecodePlcNb(...)
|
||||
*
|
||||
* This function conducts PLC for ISAC frame(s) in narrow-band (8kHz sampling).
|
||||
* Output speech length will be "240*noOfLostFrames" samples
|
||||
* that equevalent of "30*noOfLostFrames" millisecond.
|
||||
*
|
||||
* The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - noOfLostFrames : Number of PLC frames (240 sample=30ms) to produce
|
||||
* NOTE! Maximum number is 2 (480 samples = 60ms)
|
||||
*
|
||||
* Output:
|
||||
* - decoded : The decoded vector
|
||||
*
|
||||
* Return value : >0 - number of samples in decoded PLC vector
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
WebRtc_Word16 WebRtcIsacfix_DecodePlcNb(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
WebRtc_Word16 *decoded,
|
||||
WebRtc_Word16 noOfLostFrames );
|
||||
#endif // WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_DecodePlc(...)
|
||||
*
|
||||
* This function conducts PLC for ISAC frame(s) in wide-band (16kHz sampling).
|
||||
* Output speech length will be "480*noOfLostFrames" samples
|
||||
* that is equevalent of "30*noOfLostFrames" millisecond.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - noOfLostFrames : Number of PLC frames (480sample = 30ms)
|
||||
* to produce
|
||||
* NOTE! Maximum number is 2 (960 samples = 60ms)
|
||||
*
|
||||
* Output:
|
||||
* - decoded : The decoded vector
|
||||
*
|
||||
* Return value : >0 - number of samples in decoded PLC vector
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
WebRtc_Word16 *decoded,
|
||||
WebRtc_Word16 noOfLostFrames );
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_ReadFrameLen(...)
|
||||
*
|
||||
* This function returns the length of the frame represented in the packet.
|
||||
*
|
||||
* Input:
|
||||
* - encoded : Encoded bitstream
|
||||
*
|
||||
* Output:
|
||||
* - frameLength : Length of frame in packet (in samples)
|
||||
*
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_ReadFrameLen(const WebRtc_Word16* encoded,
|
||||
WebRtc_Word16* frameLength);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_Control(...)
|
||||
*
|
||||
* This function sets the limit on the short-term average bit rate and the
|
||||
* frame length. Should be used only in Instantaneous mode.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - rate : limit on the short-term average bit rate,
|
||||
* in bits/second (between 10000 and 32000)
|
||||
* - framesize : number of milliseconds per frame (30 or 60)
|
||||
*
|
||||
* Return value : 0 - ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_Control(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
WebRtc_Word16 rate,
|
||||
WebRtc_Word16 framesize);
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_ControlBwe(...)
|
||||
*
|
||||
* This function sets the initial values of bottleneck and frame-size if
|
||||
* iSAC is used in channel-adaptive mode. Through this API, users can
|
||||
* enforce a frame-size for all values of bottleneck. Then iSAC will not
|
||||
* automatically change the frame-size.
|
||||
*
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - rateBPS : initial value of bottleneck in bits/second
|
||||
* 10000 <= rateBPS <= 32000 is accepted
|
||||
* - frameSizeMs : number of milliseconds per frame (30 or 60)
|
||||
* - enforceFrameSize : 1 to enforce the given frame-size through out
|
||||
* the adaptation process, 0 to let iSAC change
|
||||
* the frame-size if required.
|
||||
*
|
||||
* Return value : 0 - ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
WebRtc_Word16 rateBPS,
|
||||
WebRtc_Word16 frameSizeMs,
|
||||
WebRtc_Word16 enforceFrameSize);
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_version(...)
|
||||
*
|
||||
* This function returns the version number.
|
||||
*
|
||||
* Output:
|
||||
* - version : Pointer to character string
|
||||
*
|
||||
*/
|
||||
|
||||
void WebRtcIsacfix_version(char *version);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_GetErrorCode(...)
|
||||
*
|
||||
* This function can be used to check the error code of an iSAC instance. When
|
||||
* a function returns -1 a error code will be set for that instance. The
|
||||
* function below extract the code of the last error that occured in the
|
||||
* specified instance.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance
|
||||
*
|
||||
* Return value : Error code
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct *ISAC_main_inst);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_GetUplinkBw(...)
|
||||
*
|
||||
* This function return iSAC send bitrate
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC instance
|
||||
*
|
||||
* Return value : <0 Error code
|
||||
* else bitrate
|
||||
*/
|
||||
|
||||
WebRtc_Word32 WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct *ISAC_main_inst);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_SetMaxPayloadSize(...)
|
||||
*
|
||||
* This function sets a limit for the maximum payload size of iSAC. The same
|
||||
* value is used both for 30 and 60 msec packets.
|
||||
* The absolute max will be valid until next time the function is called.
|
||||
* NOTE! This function may override the function WebRtcIsacfix_SetMaxRate()
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC instance
|
||||
* - maxPayloadBytes : maximum size of the payload in bytes
|
||||
* valid values are between 100 and 400 bytes
|
||||
*
|
||||
*
|
||||
* Return value : 0 if sucessful
|
||||
* -1 if error happens
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
WebRtc_Word16 maxPayloadBytes);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_SetMaxRate(...)
|
||||
*
|
||||
* This function sets the maximum rate which the codec may not exceed for a
|
||||
* singel packet. The maximum rate is set in bits per second.
|
||||
* The codec has an absolute maximum rate of 53400 bits per second (200 bytes
|
||||
* per 30 msec).
|
||||
* It is possible to set a maximum rate between 32000 and 53400 bits per second.
|
||||
*
|
||||
* The rate limit is valid until next time the function is called.
|
||||
*
|
||||
* NOTE! Packet size will never go above the value set if calling
|
||||
* WebRtcIsacfix_SetMaxPayloadSize() (default max packet size is 400 bytes).
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC instance
|
||||
* - maxRateInBytes : maximum rate in bits per second,
|
||||
* valid values are 32000 to 53400 bits
|
||||
*
|
||||
* Return value : 0 if sucessful
|
||||
* -1 if error happens
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
WebRtc_Word32 maxRate);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_CreateInternal(...)
|
||||
*
|
||||
* This function creates the memory that is used to store data in the encoder
|
||||
*
|
||||
* Input:
|
||||
* - *ISAC_main_inst : a pointer to the coder instance.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct *ISAC_main_inst);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_FreeInternal(...)
|
||||
*
|
||||
* This function frees the internal memory for storing encoder data.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : an ISAC instance.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_GetNewBitStream(...)
|
||||
*
|
||||
* This function returns encoded data, with the recieved bwe-index in the
|
||||
* stream. It should always return a complete packet, i.e. only called once
|
||||
* even for 60 msec frames
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - bweIndex : index of bandwidth estimate to put in new bitstream
|
||||
* - scale : factor for rate change (0.4 ~=> half the rate, 1 no change).
|
||||
*
|
||||
* Output:
|
||||
* - encoded : the encoded data vector
|
||||
*
|
||||
* Return value : >0 - Length (in bytes) of coded data
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
WebRtc_Word16 bweIndex,
|
||||
float scale,
|
||||
WebRtc_Word16 *encoded);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_GetDownLinkBwIndex(...)
|
||||
*
|
||||
* This function returns index representing the Bandwidth estimate from
|
||||
* other side to this side.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC struct
|
||||
*
|
||||
* Output:
|
||||
* - rateIndex : Bandwidth estimate to transmit to other side.
|
||||
*
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct* ISAC_main_inst,
|
||||
WebRtc_Word16* rateIndex);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_UpdateUplinkBw(...)
|
||||
*
|
||||
* This function takes an index representing the Bandwidth estimate from
|
||||
* this side to other side and updates BWE.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC struct
|
||||
* - rateIndex : Bandwidth estimate from other side.
|
||||
*
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst,
|
||||
WebRtc_Word16 rateIndex);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_ReadBwIndex(...)
|
||||
*
|
||||
* This function returns the index of the Bandwidth estimate from the bitstream.
|
||||
*
|
||||
* Input:
|
||||
* - encoded : Encoded bitstream
|
||||
*
|
||||
* Output:
|
||||
* - rateIndex : Bandwidth estimate in bitstream
|
||||
*
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_ReadBwIndex(const WebRtc_Word16* encoded,
|
||||
WebRtc_Word16* rateIndex);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsacfix_GetNewFrameLen(...)
|
||||
*
|
||||
* This function return the next frame length (in samples) of iSAC.
|
||||
*
|
||||
* Input:
|
||||
* -ISAC_main_inst : iSAC instance
|
||||
*
|
||||
* Return value : frame lenght in samples
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct *ISAC_main_inst);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_ISACFIX_H_ */
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* lattice.c
|
||||
*
|
||||
* Contains the normalized lattice filter routines (MA and AR) for iSAC codec
|
||||
*
|
||||
*/
|
||||
|
||||
#include "codec.h"
|
||||
#include "settings.h"
|
||||
|
||||
#define LATTICE_MUL_32_32_RSFT16(a32a, a32b, b32) \
|
||||
((WebRtc_Word32)(WEBRTC_SPL_MUL(a32a, b32) + (WEBRTC_SPL_MUL_16_32_RSFT16(a32b, b32))))
|
||||
/* This macro is FORBIDDEN to use elsewhere than in a function in this file and
|
||||
its corresponding neon version. It might give unpredictable results, since a
|
||||
general WebRtc_Word32*WebRtc_Word32 multiplication results in a 64 bit value.
|
||||
The result is then shifted just 16 steps to the right, giving need for 48
|
||||
bits, i.e. in the generel case, it will NOT fit in a WebRtc_Word32. In the
|
||||
cases used in here, the WebRtc_Word32 will be enough, since (for a good
|
||||
reason) the involved multiplicands aren't big enough to overflow a
|
||||
WebRtc_Word32 after shifting right 16 bits. I have compared the result of a
|
||||
multiplication between t32 and tmp32, done in two ways:
|
||||
1) Using (WebRtc_Word32) (((float)(tmp32))*((float)(tmp32b))/65536.0);
|
||||
2) Using LATTICE_MUL_32_32_RSFT16(t16a, t16b, tmp32b);
|
||||
By running 25 files, I haven't found any bigger diff than 64 - this was in the
|
||||
case when method 1) gave 650235648 and 2) gave 650235712.
|
||||
*/
|
||||
|
||||
/* Function prototype: filtering ar_g_Q0[] and ar_f_Q0[] through an AR filter
|
||||
with coefficients cth_Q15[] and sth_Q15[].
|
||||
Implemented for both generic and ARMv7 platforms.
|
||||
*/
|
||||
void WebRtcIsacfix_FilterArLoop(int16_t* ar_g_Q0,
|
||||
int16_t* ar_f_Q0,
|
||||
int16_t* cth_Q15,
|
||||
int16_t* sth_Q15,
|
||||
int16_t order_coef);
|
||||
|
||||
/* Inner loop used for function WebRtcIsacfix_NormLatticeFilterMa().
|
||||
It does:
|
||||
for 0 <= n < HALF_SUBFRAMELEN - 1:
|
||||
*ptr2 = input2 * (*ptr2) + input0 * (*ptr0));
|
||||
*ptr1 = input1 * (*ptr0) + input0 * (*ptr2);
|
||||
*/
|
||||
void WebRtcIsacfix_FilterMaLoopC(int16_t input0, // Filter coefficient
|
||||
int16_t input1, // Filter coefficient
|
||||
int32_t input2, // Inverse coeff. (1/input1)
|
||||
int32_t* ptr0, // Sample buffer
|
||||
int32_t* ptr1, // Sample buffer
|
||||
int32_t* ptr2) { // Sample buffer
|
||||
int n = 0;
|
||||
|
||||
// Separate the 32-bit variable input2 into two 16-bit integers (high 16 and
|
||||
// low 16 bits), for using LATTICE_MUL_32_32_RSFT16 in the loop.
|
||||
int16_t t16a = (int16_t)(input2 >> 16);
|
||||
int16_t t16b = (int16_t)input2;
|
||||
if (t16b < 0) t16a++;
|
||||
|
||||
// The loop filtering the samples *ptr0, *ptr1, *ptr2 with filter coefficients
|
||||
// input0, input1, and input2.
|
||||
for(n = 0; n < HALF_SUBFRAMELEN - 1; n++, ptr0++, ptr1++, ptr2++) {
|
||||
int32_t tmp32a = 0;
|
||||
int32_t tmp32b = 0;
|
||||
|
||||
// Calculate *ptr2 = input2 * (*ptr2 + input0 * (*ptr0));
|
||||
tmp32a = WEBRTC_SPL_MUL_16_32_RSFT15(input0, *ptr0); // Q15 * Q15 >> 15 = Q15
|
||||
tmp32b = *ptr2 + tmp32a; // Q15 + Q15 = Q15
|
||||
*ptr2 = LATTICE_MUL_32_32_RSFT16(t16a, t16b, tmp32b);
|
||||
|
||||
// Calculate *ptr1 = input1 * (*ptr0) + input0 * (*ptr2);
|
||||
tmp32a = WEBRTC_SPL_MUL_16_32_RSFT15(input1, *ptr0); // Q15*Q15>>15 = Q15
|
||||
tmp32b = WEBRTC_SPL_MUL_16_32_RSFT15(input0, *ptr2); // Q15*Q15>>15 = Q15
|
||||
*ptr1 = tmp32a + tmp32b; // Q15 + Q15 = Q15
|
||||
}
|
||||
}
|
||||
|
||||
// Declare a function pointer.
|
||||
FilterMaLoopFix WebRtcIsacfix_FilterMaLoopFix;
|
||||
|
||||
/* filter the signal using normalized lattice filter */
|
||||
/* MA filter */
|
||||
void WebRtcIsacfix_NormLatticeFilterMa(WebRtc_Word16 orderCoef,
|
||||
WebRtc_Word32 *stateGQ15,
|
||||
WebRtc_Word16 *lat_inQ0,
|
||||
WebRtc_Word16 *filt_coefQ15,
|
||||
WebRtc_Word32 *gain_lo_hiQ17,
|
||||
WebRtc_Word16 lo_hi,
|
||||
WebRtc_Word16 *lat_outQ9)
|
||||
{
|
||||
WebRtc_Word16 sthQ15[MAX_AR_MODEL_ORDER];
|
||||
WebRtc_Word16 cthQ15[MAX_AR_MODEL_ORDER];
|
||||
|
||||
int u, i, k, n;
|
||||
WebRtc_Word16 temp2,temp3;
|
||||
WebRtc_Word16 ord_1 = orderCoef+1;
|
||||
WebRtc_Word32 inv_cthQ16[MAX_AR_MODEL_ORDER];
|
||||
|
||||
WebRtc_Word32 gain32, fQtmp;
|
||||
WebRtc_Word16 gain16;
|
||||
WebRtc_Word16 gain_sh;
|
||||
|
||||
WebRtc_Word32 tmp32, tmp32b;
|
||||
WebRtc_Word32 fQ15vec[HALF_SUBFRAMELEN];
|
||||
WebRtc_Word32 gQ15[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN];
|
||||
WebRtc_Word16 sh;
|
||||
WebRtc_Word16 t16a;
|
||||
WebRtc_Word16 t16b;
|
||||
|
||||
for (u=0;u<SUBFRAMES;u++)
|
||||
{
|
||||
int32_t temp1 = WEBRTC_SPL_MUL_16_16(u, HALF_SUBFRAMELEN);
|
||||
|
||||
/* set the Direct Form coefficients */
|
||||
temp2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(u, orderCoef);
|
||||
temp3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(2, u)+lo_hi;
|
||||
|
||||
/* compute lattice filter coefficients */
|
||||
memcpy(sthQ15, &filt_coefQ15[temp2], orderCoef * sizeof(WebRtc_Word16));
|
||||
|
||||
WebRtcSpl_SqrtOfOneMinusXSquared(sthQ15, orderCoef, cthQ15);
|
||||
|
||||
/* compute the gain */
|
||||
gain32 = gain_lo_hiQ17[temp3];
|
||||
gain_sh = WebRtcSpl_NormW32(gain32);
|
||||
gain32 = WEBRTC_SPL_LSHIFT_W32(gain32, gain_sh); //Q(17+gain_sh)
|
||||
|
||||
for (k=0;k<orderCoef;k++)
|
||||
{
|
||||
gain32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[k], gain32); //Q15*Q(17+gain_sh)>>15 = Q(17+gain_sh)
|
||||
inv_cthQ16[k] = WebRtcSpl_DivW32W16((WebRtc_Word32)2147483647, cthQ15[k]); // 1/cth[k] in Q31/Q15 = Q16
|
||||
}
|
||||
gain16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(gain32, 16); //Q(1+gain_sh)
|
||||
|
||||
/* normalized lattice filter */
|
||||
/*****************************/
|
||||
|
||||
/* initial conditions */
|
||||
for (i=0;i<HALF_SUBFRAMELEN;i++)
|
||||
{
|
||||
fQ15vec[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)lat_inQ0[i + temp1], 15); //Q15
|
||||
gQ15[0][i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)lat_inQ0[i + temp1], 15); //Q15
|
||||
}
|
||||
|
||||
|
||||
fQtmp = fQ15vec[0];
|
||||
|
||||
/* get the state of f&g for the first input, for all orders */
|
||||
for (i=1;i<ord_1;i++)
|
||||
{
|
||||
// Calculate f[i][0] = inv_cth[i-1]*(f[i-1][0] + sth[i-1]*stateG[i-1]);
|
||||
tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(sthQ15[i-1], stateGQ15[i-1]);//Q15*Q15>>15 = Q15
|
||||
tmp32b= fQtmp + tmp32; //Q15+Q15=Q15
|
||||
tmp32 = inv_cthQ16[i-1]; //Q16
|
||||
t16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
|
||||
t16b = (WebRtc_Word16) (tmp32-WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)t16a), 16));
|
||||
if (t16b<0) t16a++;
|
||||
tmp32 = LATTICE_MUL_32_32_RSFT16(t16a, t16b, tmp32b);
|
||||
fQtmp = tmp32; // Q15
|
||||
|
||||
// Calculate g[i][0] = cth[i-1]*stateG[i-1] + sth[i-1]* f[i][0];
|
||||
tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[i-1], stateGQ15[i-1]); //Q15*Q15>>15 = Q15
|
||||
tmp32b = WEBRTC_SPL_MUL_16_32_RSFT15(sthQ15[i-1], fQtmp); //Q15*Q15>>15 = Q15
|
||||
tmp32 = tmp32 + tmp32b;//Q15+Q15 = Q15
|
||||
gQ15[i][0] = tmp32; // Q15
|
||||
}
|
||||
|
||||
/* filtering */
|
||||
/* save the states */
|
||||
for(k=0;k<orderCoef;k++)
|
||||
{
|
||||
// for 0 <= n < HALF_SUBFRAMELEN - 1:
|
||||
// f[k+1][n+1] = inv_cth[k]*(f[k][n+1] + sth[k]*g[k][n]);
|
||||
// g[k+1][n+1] = cth[k]*g[k][n] + sth[k]* f[k+1][n+1];
|
||||
WebRtcIsacfix_FilterMaLoopFix(sthQ15[k], cthQ15[k], inv_cthQ16[k],
|
||||
&gQ15[k][0], &gQ15[k+1][1], &fQ15vec[1]);
|
||||
}
|
||||
|
||||
fQ15vec[0] = fQtmp;
|
||||
|
||||
for(n=0;n<HALF_SUBFRAMELEN;n++)
|
||||
{
|
||||
//gain32 = WEBRTC_SPL_RSHIFT_W32(gain32, gain_sh); // Q(17+gain_sh) -> Q17
|
||||
tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(gain16, fQ15vec[n]); //Q(1+gain_sh)*Q15>>16 = Q(gain_sh)
|
||||
sh = 9-gain_sh; //number of needed shifts to reach Q9
|
||||
t16a = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(tmp32, sh);
|
||||
lat_outQ9[n + temp1] = t16a;
|
||||
}
|
||||
|
||||
/* save the states */
|
||||
for (i=0;i<ord_1;i++)
|
||||
{
|
||||
stateGQ15[i] = gQ15[i][HALF_SUBFRAMELEN-1];
|
||||
}
|
||||
//process next frame
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ----------------AR filter-------------------------*/
|
||||
/* filter the signal using normalized lattice filter */
|
||||
void WebRtcIsacfix_NormLatticeFilterAr(WebRtc_Word16 orderCoef,
|
||||
WebRtc_Word16 *stateGQ0,
|
||||
WebRtc_Word32 *lat_inQ25,
|
||||
WebRtc_Word16 *filt_coefQ15,
|
||||
WebRtc_Word32 *gain_lo_hiQ17,
|
||||
WebRtc_Word16 lo_hi,
|
||||
WebRtc_Word16 *lat_outQ0)
|
||||
{
|
||||
int ii,n,k,i,u;
|
||||
WebRtc_Word16 sthQ15[MAX_AR_MODEL_ORDER];
|
||||
WebRtc_Word16 cthQ15[MAX_AR_MODEL_ORDER];
|
||||
WebRtc_Word32 tmp32;
|
||||
|
||||
|
||||
WebRtc_Word16 tmpAR;
|
||||
WebRtc_Word16 ARfQ0vec[HALF_SUBFRAMELEN];
|
||||
WebRtc_Word16 ARgQ0vec[MAX_AR_MODEL_ORDER+1];
|
||||
|
||||
WebRtc_Word32 inv_gain32;
|
||||
WebRtc_Word16 inv_gain16;
|
||||
WebRtc_Word16 den16;
|
||||
WebRtc_Word16 sh;
|
||||
|
||||
WebRtc_Word16 temp2,temp3;
|
||||
WebRtc_Word16 ord_1 = orderCoef+1;
|
||||
|
||||
for (u=0;u<SUBFRAMES;u++)
|
||||
{
|
||||
int32_t temp1 = WEBRTC_SPL_MUL_16_16(u, HALF_SUBFRAMELEN);
|
||||
|
||||
//set the denominator and numerator of the Direct Form
|
||||
temp2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(u, orderCoef);
|
||||
temp3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(2, u) + lo_hi;
|
||||
|
||||
for (ii=0; ii<orderCoef; ii++) {
|
||||
sthQ15[ii] = filt_coefQ15[temp2+ii];
|
||||
}
|
||||
|
||||
WebRtcSpl_SqrtOfOneMinusXSquared(sthQ15, orderCoef, cthQ15);
|
||||
|
||||
/* Simulation of the 25 files shows that maximum value in
|
||||
the vector gain_lo_hiQ17[] is 441344, which means that
|
||||
it is log2((2^31)/441344) = 12.2 shifting bits from
|
||||
saturation. Therefore, it should be safe to use Q27 instead
|
||||
of Q17. */
|
||||
|
||||
tmp32 = WEBRTC_SPL_LSHIFT_W32(gain_lo_hiQ17[temp3], 10); // Q27
|
||||
|
||||
for (k=0;k<orderCoef;k++) {
|
||||
tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[k], tmp32); // Q15*Q27>>15 = Q27
|
||||
}
|
||||
|
||||
sh = WebRtcSpl_NormW32(tmp32); // tmp32 is the gain
|
||||
den16 = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(tmp32, sh-16); //Q(27+sh-16) = Q(sh+11) (all 16 bits are value bits)
|
||||
inv_gain32 = WebRtcSpl_DivW32W16((WebRtc_Word32)2147483647, den16); // 1/gain in Q31/Q(sh+11) = Q(20-sh)
|
||||
|
||||
//initial conditions
|
||||
inv_gain16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(inv_gain32, 2); // 1/gain in Q(20-sh-2) = Q(18-sh)
|
||||
|
||||
for (i=0;i<HALF_SUBFRAMELEN;i++)
|
||||
{
|
||||
|
||||
tmp32 = WEBRTC_SPL_LSHIFT_W32(lat_inQ25[i + temp1], 1); //Q25->Q26
|
||||
tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(inv_gain16, tmp32); //lat_in[]*inv_gain in (Q(18-sh)*Q26)>>16 = Q(28-sh)
|
||||
tmp32 = WEBRTC_SPL_SHIFT_W32(tmp32, -(28-sh)); // lat_in[]*inv_gain in Q0
|
||||
|
||||
ARfQ0vec[i] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32); // Q0
|
||||
}
|
||||
|
||||
for (i=orderCoef-1;i>=0;i--) //get the state of f&g for the first input, for all orders
|
||||
{
|
||||
tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(cthQ15[i],ARfQ0vec[0])) - (WEBRTC_SPL_MUL_16_16(sthQ15[i],stateGQ0[i])) + 16384), 15);
|
||||
tmpAR = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32); // Q0
|
||||
|
||||
tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(sthQ15[i],ARfQ0vec[0])) + (WEBRTC_SPL_MUL_16_16(cthQ15[i], stateGQ0[i])) + 16384), 15);
|
||||
ARgQ0vec[i+1] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32); // Q0
|
||||
ARfQ0vec[0] = tmpAR;
|
||||
}
|
||||
ARgQ0vec[0] = ARfQ0vec[0];
|
||||
|
||||
// Filter ARgQ0vec[] and ARfQ0vec[] through coefficients cthQ15[] and sthQ15[].
|
||||
WebRtcIsacfix_FilterArLoop(ARgQ0vec, ARfQ0vec, cthQ15, sthQ15, orderCoef);
|
||||
|
||||
for(n=0;n<HALF_SUBFRAMELEN;n++)
|
||||
{
|
||||
lat_outQ0[n + temp1] = ARfQ0vec[n];
|
||||
}
|
||||
|
||||
|
||||
/* cannot use memcpy in the following */
|
||||
|
||||
for (i=0;i<ord_1;i++)
|
||||
{
|
||||
stateGQ0[i] = ARgQ0vec[i];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Contains the core loop function for the lattice filter AR routine
|
||||
* for iSAC codec.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
#include "signal_processing_library.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
/* Filter ar_g_Q0[] and ar_f_Q0[] through an AR filter with coefficients
|
||||
* cth_Q15[] and sth_Q15[].
|
||||
*/
|
||||
void WebRtcIsacfix_FilterArLoop(int16_t* ar_g_Q0, // Input samples
|
||||
int16_t* ar_f_Q0, // Input samples
|
||||
int16_t* cth_Q15, // Filter coefficients
|
||||
int16_t* sth_Q15, // Filter coefficients
|
||||
int16_t order_coef) { // order of the filter
|
||||
int n = 0;
|
||||
|
||||
for (n = 0; n < HALF_SUBFRAMELEN - 1; n++) {
|
||||
int k = 0;
|
||||
int16_t tmpAR = 0;
|
||||
int32_t tmp32 = 0;
|
||||
int32_t tmp32_2 = 0;
|
||||
|
||||
tmpAR = ar_f_Q0[n + 1];
|
||||
for (k = order_coef - 1; k >= 0; k--) {
|
||||
tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(cth_Q15[k], tmpAR))
|
||||
- (WEBRTC_SPL_MUL_16_16(sth_Q15[k], ar_g_Q0[k])) + 16384), 15);
|
||||
tmp32_2 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(sth_Q15[k], tmpAR))
|
||||
+ (WEBRTC_SPL_MUL_16_16(cth_Q15[k], ar_g_Q0[k])) + 16384), 15);
|
||||
tmpAR = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32);
|
||||
ar_g_Q0[k + 1] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32_2);
|
||||
}
|
||||
ar_f_Q0[n + 1] = tmpAR;
|
||||
ar_g_Q0[0] = tmpAR;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* lpc_masking_model.h
|
||||
*
|
||||
* LPC functions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_MASKING_MODEL_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_MASKING_MODEL_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
void WebRtcIsacfix_GetVars(const WebRtc_Word16 *input,
|
||||
const WebRtc_Word16 *pitchGains_Q12,
|
||||
WebRtc_UWord32 *oldEnergy,
|
||||
WebRtc_Word16 *varscale);
|
||||
|
||||
void WebRtcIsacfix_GetLpcCoef(WebRtc_Word16 *inLoQ0,
|
||||
WebRtc_Word16 *inHiQ0,
|
||||
MaskFiltstr_enc *maskdata,
|
||||
WebRtc_Word16 snrQ10,
|
||||
const WebRtc_Word16 *pitchGains_Q12,
|
||||
WebRtc_Word32 *gain_lo_hiQ17,
|
||||
WebRtc_Word16 *lo_coeffQ15,
|
||||
WebRtc_Word16 *hi_coeffQ15);
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_MASKING_MODEL_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* lpc_tables.h
|
||||
*
|
||||
* header file for coding tables for the LPC coefficients
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
|
||||
/* indices of KLT coefficients used */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kSelIndGain[12];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kSelIndShape[108];
|
||||
|
||||
/* cdf array for model indicator */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kModelCdf[KLT_NUM_MODELS+1];
|
||||
|
||||
/* pointer to cdf array for model indicator */
|
||||
extern const WebRtc_UWord16 *WebRtcIsacfix_kModelCdfPtr[1];
|
||||
|
||||
/* initial cdf index for decoder of model indicator */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kModelInitIndex[1];
|
||||
|
||||
/* offset to go from rounded value to quantization index */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kQuantMinGain[12];
|
||||
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kQuantMinShape[108];
|
||||
|
||||
/* maximum quantization index */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kMaxIndGain[12];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kMaxIndShape[108];
|
||||
|
||||
/* index offset */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kOffsetGain[KLT_NUM_MODELS][12];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kOffsetShape[KLT_NUM_MODELS][108];
|
||||
|
||||
/* initial cdf index for KLT coefficients */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndexGain[KLT_NUM_MODELS][12];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndexShape[KLT_NUM_MODELS][108];
|
||||
|
||||
/* offsets for quantizer representation levels */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kOfLevelsGain[3];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kOfLevelsShape[3];
|
||||
|
||||
/* quantizer representation levels */
|
||||
extern const WebRtc_Word32 WebRtcIsacfix_kLevelsGainQ17[1176];
|
||||
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kLevelsShapeQ10[1735];
|
||||
|
||||
/* cdf tables for quantizer indices */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kCdfGain[1212];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kCdfShape[2059];
|
||||
|
||||
/* pointers to cdf tables for quantizer indices */
|
||||
extern const WebRtc_UWord16 *WebRtcIsacfix_kCdfGainPtr[KLT_NUM_MODELS][12];
|
||||
|
||||
extern const WebRtc_UWord16 *WebRtcIsacfix_kCdfShapePtr[KLT_NUM_MODELS][108];
|
||||
|
||||
/* code length for all coefficients using different models */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kCodeLenGainQ11[392];
|
||||
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kCodeLenShapeQ11[577];
|
||||
|
||||
/* left KLT transforms */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kT1GainQ15[KLT_NUM_MODELS][4];
|
||||
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kT1ShapeQ15[KLT_NUM_MODELS][324];
|
||||
|
||||
/* right KLT transforms */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kT2GainQ15[KLT_NUM_MODELS][36];
|
||||
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kT2ShapeQ15[KLT_NUM_MODELS][36];
|
||||
|
||||
/* means of log gains and LAR coefficients */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kMeansGainQ8[KLT_NUM_MODELS][12];
|
||||
|
||||
extern const WebRtc_Word32 WebRtcIsacfix_kMeansShapeQ17[3][108];
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_ */
|
|
@ -0,0 +1,519 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_estimator.c
|
||||
*
|
||||
* Pitch filter functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "pitch_estimator.h"
|
||||
|
||||
/* log2[0.2, 0.5, 0.98] in Q8 */
|
||||
static const WebRtc_Word16 kLogLagWinQ8[3] = {
|
||||
-594, -256, -7
|
||||
};
|
||||
|
||||
/* [1 -0.75 0.25] in Q12 */
|
||||
static const WebRtc_Word16 kACoefQ12[3] = {
|
||||
4096, -3072, 1024
|
||||
};
|
||||
|
||||
|
||||
|
||||
static __inline WebRtc_Word32 Log2Q8( WebRtc_UWord32 x ) {
|
||||
|
||||
WebRtc_Word32 zeros, lg2;
|
||||
WebRtc_Word16 frac;
|
||||
|
||||
zeros=WebRtcSpl_NormU32(x);
|
||||
frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(((WebRtc_UWord32)(WEBRTC_SPL_LSHIFT_W32(x, zeros))&0x7FFFFFFF), 23);
|
||||
/* log2(magn(i)) */
|
||||
|
||||
lg2= (WEBRTC_SPL_LSHIFT_W32((31-zeros), 8)+frac);
|
||||
return lg2;
|
||||
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word16 Exp2Q10(WebRtc_Word16 x) { // Both in and out in Q10
|
||||
|
||||
WebRtc_Word16 tmp16_1, tmp16_2;
|
||||
|
||||
tmp16_2=(WebRtc_Word16)(0x0400|(x&0x03FF));
|
||||
tmp16_1=-(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(x,10);
|
||||
if(tmp16_1>0)
|
||||
return (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
|
||||
else
|
||||
return (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 1D parabolic interpolation . All input and output values are in Q8 */
|
||||
static __inline void Intrp1DQ8(WebRtc_Word32 *x, WebRtc_Word32 *fx, WebRtc_Word32 *y, WebRtc_Word32 *fy) {
|
||||
|
||||
WebRtc_Word16 sign1=1, sign2=1;
|
||||
WebRtc_Word32 r32, q32, t32, nom32, den32;
|
||||
WebRtc_Word16 t16, tmp16, tmp16_1;
|
||||
|
||||
if ((fx[0]>0) && (fx[2]>0)) {
|
||||
r32=fx[1]-fx[2];
|
||||
q32=fx[0]-fx[1];
|
||||
nom32=q32+r32;
|
||||
den32=WEBRTC_SPL_MUL_32_16((q32-r32), 2);
|
||||
if (nom32<0)
|
||||
sign1=-1;
|
||||
if (den32<0)
|
||||
sign2=-1;
|
||||
|
||||
/* t = (q32+r32)/(2*(q32-r32)) = (fx[0]-fx[1] + fx[1]-fx[2])/(2 * fx[0]-fx[1] - (fx[1]-fx[2]))*/
|
||||
/* (Signs are removed because WebRtcSpl_DivResultInQ31 can't handle negative numbers) */
|
||||
t32=WebRtcSpl_DivResultInQ31(WEBRTC_SPL_MUL_32_16(nom32, sign1),WEBRTC_SPL_MUL_32_16(den32, sign2)); /* t in Q31, without signs */
|
||||
|
||||
t16=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(t32, 23); /* Q8 */
|
||||
t16=t16*sign1*sign2; /* t in Q8 with signs */
|
||||
|
||||
*y = x[0]+t16; /* Q8 */
|
||||
// *y = x[1]+t16; /* Q8 */
|
||||
|
||||
/* The following code calculates fy in three steps */
|
||||
/* fy = 0.5 * t * (t-1) * fx[0] + (1-t*t) * fx[1] + 0.5 * t * (t+1) * fx[2]; */
|
||||
|
||||
/* Part I: 0.5 * t * (t-1) * fx[0] */
|
||||
tmp16_1=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16(t16,t16); /* Q8*Q8=Q16 */
|
||||
tmp16_1 = WEBRTC_SPL_RSHIFT_W16(tmp16_1,2); /* Q16>>2 = Q14 */
|
||||
t16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(t16, 64); /* Q8<<6 = Q14 */
|
||||
tmp16 = tmp16_1-t16;
|
||||
*fy = WEBRTC_SPL_MUL_16_32_RSFT15(tmp16, fx[0]); /* (Q14 * Q8 >>15)/2 = Q8 */
|
||||
|
||||
/* Part II: (1-t*t) * fx[1] */
|
||||
tmp16 = 16384-tmp16_1; /* 1 in Q14 - Q14 */
|
||||
*fy += WEBRTC_SPL_MUL_16_32_RSFT14(tmp16, fx[1]);/* Q14 * Q8 >> 14 = Q8 */
|
||||
|
||||
/* Part III: 0.5 * t * (t+1) * fx[2] */
|
||||
tmp16 = tmp16_1+t16;
|
||||
*fy += WEBRTC_SPL_MUL_16_32_RSFT15(tmp16, fx[2]);/* (Q14 * Q8 >>15)/2 = Q8 */
|
||||
} else {
|
||||
*y = x[0];
|
||||
*fy= fx[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void FindFour32(WebRtc_Word32 *in, WebRtc_Word16 length, WebRtc_Word16 *bestind)
|
||||
{
|
||||
WebRtc_Word32 best[4]= {-100, -100, -100, -100};
|
||||
WebRtc_Word16 k;
|
||||
|
||||
for (k=0; k<length; k++) {
|
||||
if (in[k] > best[3]) {
|
||||
if (in[k] > best[2]) {
|
||||
if (in[k] > best[1]) {
|
||||
if (in[k] > best[0]) { // The Best
|
||||
best[3] = best[2];
|
||||
bestind[3] = bestind[2];
|
||||
best[2] = best[1];
|
||||
bestind[2] = bestind[1];
|
||||
best[1] = best[0];
|
||||
bestind[1] = bestind[0];
|
||||
best[0] = in[k];
|
||||
bestind[0] = k;
|
||||
} else { // 2nd best
|
||||
best[3] = best[2];
|
||||
bestind[3] = bestind[2];
|
||||
best[2] = best[1];
|
||||
bestind[2] = bestind[1];
|
||||
best[1] = in[k];
|
||||
bestind[1] = k;
|
||||
}
|
||||
} else { // 3rd best
|
||||
best[3] = best[2];
|
||||
bestind[3] = bestind[2];
|
||||
best[2] = in[k];
|
||||
bestind[2] = k;
|
||||
}
|
||||
} else { // 4th best
|
||||
best[3] = in[k];
|
||||
bestind[3] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void PCorr2Q32(const WebRtc_Word16 *in, WebRtc_Word32 *logcorQ8)
|
||||
{
|
||||
WebRtc_Word16 scaling,n,k;
|
||||
WebRtc_Word32 ysum32,csum32, lys, lcs;
|
||||
WebRtc_Word32 prod32, oneQ8;
|
||||
|
||||
|
||||
const WebRtc_Word16 *x, *inptr;
|
||||
|
||||
oneQ8 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, 8); // 1.00 in Q8
|
||||
|
||||
x = in + PITCH_MAX_LAG/2 + 2;
|
||||
scaling = WebRtcSpl_GetScalingSquare ((WebRtc_Word16 *) in, PITCH_CORR_LEN2, PITCH_CORR_LEN2);
|
||||
ysum32 = 1;
|
||||
csum32 = 0;
|
||||
x = in + PITCH_MAX_LAG/2 + 2;
|
||||
for (n = 0; n < PITCH_CORR_LEN2; n++) {
|
||||
ysum32 += WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) in[n],(WebRtc_Word16) in[n], scaling); // Q0
|
||||
csum32 += WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) x[n],(WebRtc_Word16) in[n], scaling); // Q0
|
||||
}
|
||||
|
||||
logcorQ8 += PITCH_LAG_SPAN2 - 1;
|
||||
|
||||
lys=Log2Q8((WebRtc_UWord32) ysum32); // Q8
|
||||
lys=WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum);
|
||||
|
||||
if (csum32>0) {
|
||||
|
||||
lcs=Log2Q8((WebRtc_UWord32) csum32); // 2log(csum) in Q8
|
||||
|
||||
if (lcs>(lys + oneQ8) ){ // csum/sqrt(ysum) > 2 in Q8
|
||||
*logcorQ8 = lcs - lys; // log2(csum/sqrt(ysum))
|
||||
} else {
|
||||
*logcorQ8 = oneQ8; // 1.00
|
||||
}
|
||||
|
||||
} else {
|
||||
*logcorQ8 = 0;
|
||||
}
|
||||
|
||||
|
||||
for (k = 1; k < PITCH_LAG_SPAN2; k++) {
|
||||
inptr = &in[k];
|
||||
ysum32 -= WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) in[k-1],(WebRtc_Word16) in[k-1], scaling);
|
||||
ysum32 += WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) in[PITCH_CORR_LEN2 + k - 1],(WebRtc_Word16) in[PITCH_CORR_LEN2 + k - 1], scaling);
|
||||
csum32 = 0;
|
||||
prod32 = WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) x[0],(WebRtc_Word16) inptr[0], scaling);
|
||||
|
||||
for (n = 1; n < PITCH_CORR_LEN2; n++) {
|
||||
csum32 += prod32;
|
||||
prod32 = WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) x[n],(WebRtc_Word16) inptr[n], scaling);
|
||||
}
|
||||
|
||||
csum32 += prod32;
|
||||
logcorQ8--;
|
||||
|
||||
lys=Log2Q8((WebRtc_UWord32)ysum32); // Q8
|
||||
lys=WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum);
|
||||
|
||||
if (csum32>0) {
|
||||
|
||||
lcs=Log2Q8((WebRtc_UWord32) csum32); // 2log(csum) in Q8
|
||||
|
||||
if (lcs>(lys + oneQ8) ){ // csum/sqrt(ysum) > 2
|
||||
*logcorQ8 = lcs - lys; // log2(csum/sqrt(ysum))
|
||||
} else {
|
||||
*logcorQ8 = oneQ8; // 1.00
|
||||
}
|
||||
|
||||
} else {
|
||||
*logcorQ8 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WebRtcIsacfix_InitialPitch(const WebRtc_Word16 *in, /* Q0 */
|
||||
PitchAnalysisStruct *State,
|
||||
WebRtc_Word16 *lagsQ7 /* Q7 */
|
||||
)
|
||||
{
|
||||
WebRtc_Word16 buf_dec16[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2+2];
|
||||
WebRtc_Word32 *crrvecQ8_1,*crrvecQ8_2;
|
||||
WebRtc_Word32 cv1q[PITCH_LAG_SPAN2+2],cv2q[PITCH_LAG_SPAN2+2], peakvq[PITCH_LAG_SPAN2+2];
|
||||
int k;
|
||||
WebRtc_Word16 peaks_indq;
|
||||
WebRtc_Word16 peakiq[PITCH_LAG_SPAN2];
|
||||
WebRtc_Word32 corr;
|
||||
WebRtc_Word32 corr32, corr_max32, corr_max_o32;
|
||||
WebRtc_Word16 npkq;
|
||||
WebRtc_Word16 best4q[4]={0,0,0,0};
|
||||
WebRtc_Word32 xq[3],yq[1],fyq[1];
|
||||
WebRtc_Word32 *fxq;
|
||||
WebRtc_Word32 best_lag1q, best_lag2q;
|
||||
WebRtc_Word32 tmp32a,tmp32b,lag32,ratq;
|
||||
WebRtc_Word16 start;
|
||||
WebRtc_Word16 oldgQ12, tmp16a, tmp16b, gain_bias16,tmp16c, tmp16d, bias16;
|
||||
WebRtc_Word32 tmp32c,tmp32d, tmp32e;
|
||||
WebRtc_Word16 old_lagQ;
|
||||
WebRtc_Word32 old_lagQ8;
|
||||
WebRtc_Word32 lagsQ8[4];
|
||||
|
||||
old_lagQ = State->PFstr_wght.oldlagQ7; // Q7
|
||||
old_lagQ8= WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)old_lagQ,1); //Q8
|
||||
|
||||
oldgQ12= State->PFstr_wght.oldgainQ12;
|
||||
|
||||
crrvecQ8_1=&cv1q[1];
|
||||
crrvecQ8_2=&cv2q[1];
|
||||
|
||||
|
||||
/* copy old values from state buffer */
|
||||
memcpy(buf_dec16, State->dec_buffer16, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2)));
|
||||
|
||||
/* decimation; put result after the old values */
|
||||
WebRtcIsacfix_DecimateAllpass32(in, State->decimator_state32, PITCH_FRAME_LEN,
|
||||
&buf_dec16[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2]);
|
||||
|
||||
/* low-pass filtering */
|
||||
start= PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2;
|
||||
WebRtcSpl_FilterARFastQ12(&buf_dec16[start],&buf_dec16[start],(WebRtc_Word16*)kACoefQ12,3, PITCH_FRAME_LEN/2);
|
||||
|
||||
/* copy end part back into state buffer */
|
||||
for (k = 0; k < (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2); k++)
|
||||
State->dec_buffer16[k] = buf_dec16[k+PITCH_FRAME_LEN/2];
|
||||
|
||||
|
||||
/* compute correlation for first and second half of the frame */
|
||||
PCorr2Q32(buf_dec16, crrvecQ8_1);
|
||||
PCorr2Q32(buf_dec16 + PITCH_CORR_STEP2, crrvecQ8_2);
|
||||
|
||||
|
||||
/* bias towards pitch lag of previous frame */
|
||||
tmp32a = Log2Q8((WebRtc_UWord32) old_lagQ8) - 2304; // log2(0.5*oldlag) in Q8
|
||||
tmp32b = WEBRTC_SPL_MUL_16_16_RSFT(oldgQ12,oldgQ12, 10); //Q12 & * 4.0;
|
||||
gain_bias16 = (WebRtc_Word16) tmp32b; //Q12
|
||||
if (gain_bias16 > 3276) gain_bias16 = 3276; // 0.8 in Q12
|
||||
|
||||
|
||||
for (k = 0; k < PITCH_LAG_SPAN2; k++)
|
||||
{
|
||||
if (crrvecQ8_1[k]>0) {
|
||||
tmp32b = Log2Q8((WebRtc_UWord32) (k + (PITCH_MIN_LAG/2-2)));
|
||||
tmp16a = (WebRtc_Word16) (tmp32b - tmp32a); // Q8 & fabs(ratio)<4
|
||||
tmp32c = WEBRTC_SPL_MUL_16_16_RSFT(tmp16a,tmp16a, 6); //Q10
|
||||
tmp16b = (WebRtc_Word16) tmp32c; // Q10 & <8
|
||||
tmp32d = WEBRTC_SPL_MUL_16_16_RSFT(tmp16b, 177 , 8); // mult with ln2 in Q8
|
||||
tmp16c = (WebRtc_Word16) tmp32d; // Q10 & <4
|
||||
tmp16d = Exp2Q10((WebRtc_Word16) -tmp16c); //Q10
|
||||
tmp32c = WEBRTC_SPL_MUL_16_16_RSFT(gain_bias16,tmp16d,13); // Q10 & * 0.5
|
||||
bias16 = (WebRtc_Word16) (1024 + tmp32c); // Q10
|
||||
tmp32b = Log2Q8((WebRtc_UWord32) bias16) - 2560; // Q10 in -> Q8 out with 10*2^8 offset
|
||||
crrvecQ8_1[k] += tmp32b ; // -10*2^8 offset
|
||||
}
|
||||
}
|
||||
|
||||
/* taper correlation functions */
|
||||
for (k = 0; k < 3; k++) {
|
||||
crrvecQ8_1[k] += kLogLagWinQ8[k];
|
||||
crrvecQ8_2[k] += kLogLagWinQ8[k];
|
||||
|
||||
crrvecQ8_1[PITCH_LAG_SPAN2-1-k] += kLogLagWinQ8[k];
|
||||
crrvecQ8_2[PITCH_LAG_SPAN2-1-k] += kLogLagWinQ8[k];
|
||||
}
|
||||
|
||||
|
||||
/* Make zeropadded corr vectors */
|
||||
cv1q[0]=0;
|
||||
cv2q[0]=0;
|
||||
cv1q[PITCH_LAG_SPAN2+1]=0;
|
||||
cv2q[PITCH_LAG_SPAN2+1]=0;
|
||||
corr_max32 = 0;
|
||||
|
||||
for (k = 1; k <= PITCH_LAG_SPAN2; k++)
|
||||
{
|
||||
|
||||
|
||||
corr32=crrvecQ8_1[k-1];
|
||||
if (corr32 > corr_max32)
|
||||
corr_max32 = corr32;
|
||||
|
||||
corr32=crrvecQ8_2[k-1];
|
||||
corr32 += -4; // Compensate for later (log2(0.99))
|
||||
|
||||
if (corr32 > corr_max32)
|
||||
corr_max32 = corr32;
|
||||
|
||||
}
|
||||
|
||||
/* threshold value to qualify as a peak */
|
||||
// corr_max32 += -726; // log(0.14)/log(2.0) in Q8
|
||||
corr_max32 += -1000; // log(0.14)/log(2.0) in Q8
|
||||
corr_max_o32 = corr_max32;
|
||||
|
||||
|
||||
/* find peaks in corr1 */
|
||||
peaks_indq = 0;
|
||||
for (k = 1; k <= PITCH_LAG_SPAN2; k++)
|
||||
{
|
||||
corr32=cv1q[k];
|
||||
if (corr32>corr_max32) { // Disregard small peaks
|
||||
if ((corr32>=cv1q[k-1]) && (corr32>cv1q[k+1])) { // Peak?
|
||||
peakvq[peaks_indq] = corr32;
|
||||
peakiq[peaks_indq++] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* find highest interpolated peak */
|
||||
corr_max32=0;
|
||||
best_lag1q =0;
|
||||
if (peaks_indq > 0) {
|
||||
FindFour32(peakvq, (WebRtc_Word16) peaks_indq, best4q);
|
||||
npkq = WEBRTC_SPL_MIN(peaks_indq, 4);
|
||||
|
||||
for (k=0;k<npkq;k++) {
|
||||
|
||||
lag32 = peakiq[best4q[k]];
|
||||
fxq = &cv1q[peakiq[best4q[k]]-1];
|
||||
xq[0]= lag32;
|
||||
xq[0] = WEBRTC_SPL_LSHIFT_W32(xq[0], 8);
|
||||
Intrp1DQ8(xq, fxq, yq, fyq);
|
||||
|
||||
tmp32a= Log2Q8((WebRtc_UWord32) *yq) - 2048; // offset 8*2^8
|
||||
/* Bias towards short lags */
|
||||
/* log(pow(0.8, log(2.0 * *y )))/log(2.0) */
|
||||
tmp32b= WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) tmp32a, -42, 8);
|
||||
tmp32c= tmp32b + 256;
|
||||
*fyq += tmp32c;
|
||||
if (*fyq > corr_max32) {
|
||||
corr_max32 = *fyq;
|
||||
best_lag1q = *yq;
|
||||
}
|
||||
}
|
||||
tmp32a = best_lag1q - OFFSET_Q8;
|
||||
tmp32b = WEBRTC_SPL_LSHIFT_W32(tmp32a, 1);
|
||||
lagsQ8[0] = tmp32b + PITCH_MIN_LAG_Q8;
|
||||
lagsQ8[1] = lagsQ8[0];
|
||||
} else {
|
||||
lagsQ8[0] = old_lagQ8;
|
||||
lagsQ8[1] = lagsQ8[0];
|
||||
}
|
||||
|
||||
/* Bias towards constant pitch */
|
||||
tmp32a = lagsQ8[0] - PITCH_MIN_LAG_Q8;
|
||||
ratq = WEBRTC_SPL_RSHIFT_W32(tmp32a, 1) + OFFSET_Q8;
|
||||
|
||||
for (k = 1; k <= PITCH_LAG_SPAN2; k++)
|
||||
{
|
||||
tmp32a = WEBRTC_SPL_LSHIFT_W32(k, 7); // 0.5*k Q8
|
||||
tmp32b = (WebRtc_Word32) (WEBRTC_SPL_LSHIFT_W32(tmp32a, 1)) - ratq; // Q8
|
||||
tmp32c = WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) tmp32b, (WebRtc_Word16) tmp32b, 8); // Q8
|
||||
|
||||
tmp32b = (WebRtc_Word32) tmp32c + (WebRtc_Word32) WEBRTC_SPL_RSHIFT_W32(ratq, 1); // (k-r)^2 + 0.5 * r Q8
|
||||
tmp32c = Log2Q8((WebRtc_UWord32) tmp32a) - 2048; // offset 8*2^8 , log2(0.5*k) Q8
|
||||
tmp32d = Log2Q8((WebRtc_UWord32) tmp32b) - 2048; // offset 8*2^8 , log2(0.5*k) Q8
|
||||
tmp32e = tmp32c -tmp32d;
|
||||
|
||||
cv2q[k] += WEBRTC_SPL_RSHIFT_W32(tmp32e, 1);
|
||||
|
||||
}
|
||||
|
||||
/* find peaks in corr2 */
|
||||
corr_max32 = corr_max_o32;
|
||||
peaks_indq = 0;
|
||||
|
||||
for (k = 1; k <= PITCH_LAG_SPAN2; k++)
|
||||
{
|
||||
corr=cv2q[k];
|
||||
if (corr>corr_max32) { // Disregard small peaks
|
||||
if ((corr>=cv2q[k-1]) && (corr>cv2q[k+1])) { // Peak?
|
||||
peakvq[peaks_indq] = corr;
|
||||
peakiq[peaks_indq++] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* find highest interpolated peak */
|
||||
corr_max32 = 0;
|
||||
best_lag2q =0;
|
||||
if (peaks_indq > 0) {
|
||||
|
||||
FindFour32(peakvq, (WebRtc_Word16) peaks_indq, best4q);
|
||||
npkq = WEBRTC_SPL_MIN(peaks_indq, 4);
|
||||
for (k=0;k<npkq;k++) {
|
||||
|
||||
lag32 = peakiq[best4q[k]];
|
||||
fxq = &cv2q[peakiq[best4q[k]]-1];
|
||||
|
||||
xq[0]= lag32;
|
||||
xq[0] = WEBRTC_SPL_LSHIFT_W32(xq[0], 8);
|
||||
Intrp1DQ8(xq, fxq, yq, fyq);
|
||||
|
||||
/* Bias towards short lags */
|
||||
/* log(pow(0.8, log(2.0f * *y )))/log(2.0f) */
|
||||
tmp32a= Log2Q8((WebRtc_UWord32) *yq) - 2048; // offset 8*2^8
|
||||
tmp32b= WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) tmp32a, -82, 8);
|
||||
tmp32c= tmp32b + 256;
|
||||
*fyq += tmp32c;
|
||||
if (*fyq > corr_max32) {
|
||||
corr_max32 = *fyq;
|
||||
best_lag2q = *yq;
|
||||
}
|
||||
}
|
||||
|
||||
tmp32a = best_lag2q - OFFSET_Q8;
|
||||
tmp32b = WEBRTC_SPL_LSHIFT_W32(tmp32a, 1);
|
||||
lagsQ8[2] = tmp32b + PITCH_MIN_LAG_Q8;
|
||||
lagsQ8[3] = lagsQ8[2];
|
||||
} else {
|
||||
lagsQ8[2] = lagsQ8[0];
|
||||
lagsQ8[3] = lagsQ8[0];
|
||||
}
|
||||
|
||||
lagsQ7[0]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[0], 1);
|
||||
lagsQ7[1]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[1], 1);
|
||||
lagsQ7[2]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[2], 1);
|
||||
lagsQ7[3]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[3], 1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WebRtcIsacfix_PitchAnalysis(const WebRtc_Word16 *inn, /* PITCH_FRAME_LEN samples */
|
||||
WebRtc_Word16 *outQ0, /* PITCH_FRAME_LEN+QLOOKAHEAD samples */
|
||||
PitchAnalysisStruct *State,
|
||||
WebRtc_Word16 *PitchLags_Q7,
|
||||
WebRtc_Word16 *PitchGains_Q12)
|
||||
{
|
||||
WebRtc_Word16 inbufQ0[PITCH_FRAME_LEN + QLOOKAHEAD];
|
||||
WebRtc_Word16 k;
|
||||
|
||||
/* inital pitch estimate */
|
||||
WebRtcIsacfix_InitialPitch(inn, State, PitchLags_Q7);
|
||||
|
||||
|
||||
/* Calculate gain */
|
||||
WebRtcIsacfix_PitchFilterGains(inn, &(State->PFstr_wght), PitchLags_Q7, PitchGains_Q12);
|
||||
|
||||
/* concatenate previous input's end and current input */
|
||||
for (k = 0; k < QLOOKAHEAD; k++) {
|
||||
inbufQ0[k] = State->inbuf[k];
|
||||
}
|
||||
for (k = 0; k < PITCH_FRAME_LEN; k++) {
|
||||
inbufQ0[k+QLOOKAHEAD] = (WebRtc_Word16) inn[k];
|
||||
}
|
||||
|
||||
/* lookahead pitch filtering for masking analysis */
|
||||
WebRtcIsacfix_PitchFilter(inbufQ0, outQ0, &(State->PFstr), PitchLags_Q7,PitchGains_Q12, 2);
|
||||
|
||||
|
||||
/* store last part of input */
|
||||
for (k = 0; k < QLOOKAHEAD; k++) {
|
||||
State->inbuf[k] = inbufQ0[k + PITCH_FRAME_LEN];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_estimator.h
|
||||
*
|
||||
* Pitch functions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_ESTIMATOR_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_ESTIMATOR_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
|
||||
void WebRtcIsacfix_PitchAnalysis(const WebRtc_Word16 *in, /* PITCH_FRAME_LEN samples */
|
||||
WebRtc_Word16 *outQ0, /* PITCH_FRAME_LEN+QLOOKAHEAD samples */
|
||||
PitchAnalysisStruct *State,
|
||||
WebRtc_Word16 *lagsQ7,
|
||||
WebRtc_Word16 *PitchGains_Q12);
|
||||
|
||||
|
||||
void WebRtcIsacfix_InitialPitch(const WebRtc_Word16 *in,
|
||||
PitchAnalysisStruct *State,
|
||||
WebRtc_Word16 *qlags);
|
||||
|
||||
void WebRtcIsacfix_PitchFilter(WebRtc_Word16 *indatFix,
|
||||
WebRtc_Word16 *outdatQQ,
|
||||
PitchFiltstr *pfp,
|
||||
WebRtc_Word16 *lagsQ7,
|
||||
WebRtc_Word16 *gainsQ12,
|
||||
WebRtc_Word16 type);
|
||||
|
||||
void WebRtcIsacfix_PitchFilterGains(const WebRtc_Word16 *indatQ0,
|
||||
PitchFiltstr *pfp,
|
||||
WebRtc_Word16 *lagsQ7,
|
||||
WebRtc_Word16 *gainsQ12);
|
||||
|
||||
|
||||
|
||||
void WebRtcIsacfix_DecimateAllpass32(const WebRtc_Word16 *in,
|
||||
WebRtc_Word32 *state_in, /* array of size: 2*ALLPASSSECTIONS+1 */
|
||||
WebRtc_Word16 N, /* number of input samples */
|
||||
WebRtc_Word16 *out); /* array of size N/2 */
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_ESTIMATOR_H_ */
|
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_estimatorfilter.c
|
||||
*
|
||||
* Pitch filter functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pitch_estimator.h"
|
||||
|
||||
|
||||
/* Filter coefficicients in Q15 */
|
||||
static const WebRtc_Word16 kDampFilter[PITCH_DAMPORDER] = {
|
||||
-2294, 8192, 20972, 8192, -2294
|
||||
};
|
||||
|
||||
/* Interpolation coefficients; generated by design_pitch_filter.m.
|
||||
* Coefficients are stored in Q14.
|
||||
*/
|
||||
static const WebRtc_Word16 kIntrpCoef[PITCH_FRACS][PITCH_FRACORDER] = {
|
||||
{-367, 1090, -2706, 9945, 10596, -3318, 1626, -781, 287},
|
||||
{-325, 953, -2292, 7301, 12963, -3320, 1570, -743, 271},
|
||||
{-240, 693, -1622, 4634, 14809, -2782, 1262, -587, 212},
|
||||
{-125, 358, -817, 2144, 15982, -1668, 721, -329, 118},
|
||||
{ 0, 0, -1, 1, 16380, 1, -1, 0, 0},
|
||||
{ 118, -329, 721, -1668, 15982, 2144, -817, 358, -125},
|
||||
{ 212, -587, 1262, -2782, 14809, 4634, -1622, 693, -240},
|
||||
{ 271, -743, 1570, -3320, 12963, 7301, -2292, 953, -325}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline WebRtc_Word32 CalcLrIntQ(WebRtc_Word32 fixVal, WebRtc_Word16 qDomain) {
|
||||
WebRtc_Word32 intgr;
|
||||
WebRtc_Word32 roundVal;
|
||||
|
||||
roundVal = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, qDomain-1);
|
||||
intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain);
|
||||
|
||||
return intgr;
|
||||
}
|
||||
|
||||
void WebRtcIsacfix_PitchFilter(WebRtc_Word16 *indatQQ, /* Q10 if type is 1 or 4, Q0 if type is 2 */
|
||||
WebRtc_Word16 *outdatQQ,
|
||||
PitchFiltstr *pfp,
|
||||
WebRtc_Word16 *lagsQ7,
|
||||
WebRtc_Word16 *gainsQ12,
|
||||
WebRtc_Word16 type)
|
||||
{
|
||||
int k, n, m, ind;
|
||||
WebRtc_Word16 sign = 1;
|
||||
WebRtc_Word16 inystateQQ[PITCH_DAMPORDER];
|
||||
WebRtc_Word16 ubufQQ[PITCH_INTBUFFSIZE+QLOOKAHEAD];
|
||||
WebRtc_Word16 Gain = 21299; /* 1.3 in Q14 */
|
||||
WebRtc_Word16 DivFactor = 6553; /* 0.2 in Q15 */
|
||||
WebRtc_Word16 oldLagQ7, oldGainQ12,
|
||||
lagdeltaQ7, curLagQ7,
|
||||
gaindeltaQ12, curGainQ12;
|
||||
WebRtc_Word16 tmpW16, indW16=0, frcQQ, cnt=0, pos, pos2;
|
||||
const WebRtc_Word16 *fracoeffQQ=NULL;
|
||||
WebRtc_Word32 tmpW32;
|
||||
|
||||
if (type==4)
|
||||
sign = -1;
|
||||
|
||||
/* Set up buffer and states */
|
||||
memcpy(ubufQQ, pfp->ubufQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE));
|
||||
memcpy(inystateQQ, pfp->ystateQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_DAMPORDER));
|
||||
|
||||
/* Get old lag and gain value from memory */
|
||||
oldLagQ7 = pfp->oldlagQ7;
|
||||
oldGainQ12 = pfp->oldgainQ12;
|
||||
|
||||
if (type==4) {
|
||||
/* make output more periodic */
|
||||
/* Fixed 1.3 = 21299 in Q14 */
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++)
|
||||
gainsQ12[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gainsQ12[k], Gain, 14);
|
||||
}
|
||||
|
||||
/* No interpolation if pitch lag step is big */
|
||||
if ((WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(lagsQ7[0], 3), 1) < oldLagQ7) ||
|
||||
(lagsQ7[0] > WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(oldLagQ7, 3), 1))) {
|
||||
oldLagQ7 = lagsQ7[0];
|
||||
oldGainQ12 = gainsQ12[0];
|
||||
}
|
||||
|
||||
ind=0;
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++) {
|
||||
|
||||
/* Calculate interpolation steps */
|
||||
lagdeltaQ7 = lagsQ7[k]-oldLagQ7;
|
||||
lagdeltaQ7 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(lagdeltaQ7,DivFactor,15);
|
||||
curLagQ7 = oldLagQ7;
|
||||
gaindeltaQ12 = gainsQ12[k]-oldGainQ12;
|
||||
gaindeltaQ12 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gaindeltaQ12,DivFactor,15);
|
||||
|
||||
curGainQ12 = oldGainQ12;
|
||||
oldLagQ7 = lagsQ7[k];
|
||||
oldGainQ12 = gainsQ12[k];
|
||||
|
||||
|
||||
for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
|
||||
|
||||
if (cnt == 0) { /* Update parameters */
|
||||
|
||||
curGainQ12 += gaindeltaQ12;
|
||||
curLagQ7 += lagdeltaQ7;
|
||||
indW16 = (WebRtc_Word16)CalcLrIntQ(curLagQ7,7);
|
||||
tmpW16 = WEBRTC_SPL_LSHIFT_W16(indW16,7);
|
||||
tmpW16 -= curLagQ7;
|
||||
frcQQ = WEBRTC_SPL_RSHIFT_W16(tmpW16,4);
|
||||
frcQQ += 4;
|
||||
|
||||
if(frcQQ==PITCH_FRACS)
|
||||
frcQQ=0;
|
||||
fracoeffQQ = kIntrpCoef[frcQQ];
|
||||
|
||||
cnt=12;
|
||||
}
|
||||
|
||||
/* shift low pass filter state */
|
||||
for (m=PITCH_DAMPORDER-1;m>0;m--)
|
||||
inystateQQ[m] = inystateQQ[m-1];
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos2 = pos - (indW16 + 2);
|
||||
|
||||
tmpW32=0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++)
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos2+m], fracoeffQQ[m]);
|
||||
|
||||
/* Saturate to avoid overflow in tmpW16 */
|
||||
tmpW32 = WEBRTC_SPL_SAT(536862719, tmpW32, -536879104);
|
||||
tmpW32 += 8192;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,14);
|
||||
|
||||
inystateQQ[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(curGainQ12, tmpW16,12); /* Multiply with gain */
|
||||
|
||||
/* Low pass filter */
|
||||
tmpW32=0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(inystateQQ[m], kDampFilter[m]);
|
||||
|
||||
/* Saturate to avoid overflow in tmpW16 */
|
||||
tmpW32 = WEBRTC_SPL_SAT(1073725439, tmpW32, -1073758208);
|
||||
tmpW32 += 16384;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,15);
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
tmpW32 = indatQQ[ind] - WEBRTC_SPL_MUL_16_16(sign, tmpW16);
|
||||
outdatQQ[ind] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
tmpW32 = indatQQ[ind] + (WebRtc_Word32)outdatQQ[ind];
|
||||
ubufQQ[pos] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
|
||||
ind++;
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Export buffer and states */
|
||||
memcpy(pfp->ubufQQ, ubufQQ+PITCH_FRAME_LEN, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE));
|
||||
memcpy(pfp->ystateQQ, inystateQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_DAMPORDER));
|
||||
|
||||
pfp->oldlagQ7 = oldLagQ7;
|
||||
pfp->oldgainQ12 = oldGainQ12;
|
||||
|
||||
if (type==2) {
|
||||
/* Filter look-ahead segment */
|
||||
for (n=0;n<QLOOKAHEAD;n++) {
|
||||
/* shift low pass filter state */
|
||||
for (m=PITCH_DAMPORDER-1;m>0;m--)
|
||||
inystateQQ[m] = inystateQQ[m-1];
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos2= pos - (indW16 + 2);
|
||||
|
||||
tmpW32=0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++)
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos2+m], fracoeffQQ[m]);
|
||||
|
||||
if (tmpW32<536862720) {//536870912)
|
||||
tmpW32 += 8192;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,14);
|
||||
} else
|
||||
tmpW16= 32767;
|
||||
inystateQQ[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(curGainQ12, tmpW16,12); /* Multiply with gain */
|
||||
|
||||
/* Low pass filter */
|
||||
tmpW32=0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(inystateQQ[m], kDampFilter[m]);
|
||||
if (tmpW32<1073725440) { //1073741824)
|
||||
tmpW32 += 16384;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,15);
|
||||
} else
|
||||
tmpW16 = 32767;
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
tmpW32 = indatQQ[ind] - (WebRtc_Word32)tmpW16;
|
||||
outdatQQ[ind] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
tmpW32 = indatQQ[ind] + (WebRtc_Word32)outdatQQ[ind];
|
||||
ubufQQ[pos] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
|
||||
ind++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsacfix_PitchFilterGains(const WebRtc_Word16 *indatQ0,
|
||||
PitchFiltstr *pfp,
|
||||
WebRtc_Word16 *lagsQ7,
|
||||
WebRtc_Word16 *gainsQ12)
|
||||
{
|
||||
int k, n, m, ind;
|
||||
|
||||
WebRtc_Word16 ubufQQ[PITCH_INTBUFFSIZE];
|
||||
WebRtc_Word16 oldLagQ7,lagdeltaQ7, curLagQ7;
|
||||
WebRtc_Word16 DivFactor = 6553;
|
||||
const WebRtc_Word16 *fracoeffQQ = NULL;
|
||||
WebRtc_Word16 scale;
|
||||
WebRtc_Word16 cnt=0, pos, pos3QQ, frcQQ, indW16 = 0, tmpW16;
|
||||
WebRtc_Word32 tmpW32, tmp2W32, csum1QQ, esumxQQ;
|
||||
|
||||
/* Set up buffer and states */
|
||||
memcpy(ubufQQ, pfp->ubufQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE));
|
||||
oldLagQ7 = pfp->oldlagQ7;
|
||||
|
||||
/* No interpolation if pitch lag step is big */
|
||||
if ((WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(lagsQ7[0], 3), 1) < oldLagQ7) ||
|
||||
(lagsQ7[0] > WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(oldLagQ7, 3), 1))) {
|
||||
oldLagQ7 = lagsQ7[0];
|
||||
}
|
||||
|
||||
ind=0;
|
||||
scale=0;
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++) {
|
||||
|
||||
/* Calculate interpolation steps */
|
||||
lagdeltaQ7 = lagsQ7[k]-oldLagQ7;
|
||||
lagdeltaQ7 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(lagdeltaQ7,DivFactor,15);
|
||||
curLagQ7 = oldLagQ7;
|
||||
oldLagQ7 = lagsQ7[k];
|
||||
|
||||
csum1QQ=1;
|
||||
esumxQQ=1;
|
||||
|
||||
for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
|
||||
|
||||
if (cnt == 0) { /* Update parameters */
|
||||
curLagQ7 += lagdeltaQ7;
|
||||
indW16 = (WebRtc_Word16)CalcLrIntQ(curLagQ7,7);
|
||||
tmpW16 = WEBRTC_SPL_LSHIFT_W16(indW16,7);
|
||||
tmpW16 -= curLagQ7;
|
||||
frcQQ = WEBRTC_SPL_RSHIFT_W16(tmpW16,4);
|
||||
frcQQ += 4;
|
||||
|
||||
if(frcQQ==PITCH_FRACS)
|
||||
frcQQ=0;
|
||||
fracoeffQQ = kIntrpCoef[frcQQ];
|
||||
|
||||
cnt=12;
|
||||
}
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos3QQ = pos - (indW16 + 4);
|
||||
|
||||
tmpW32=0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++){
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos3QQ+m], fracoeffQQ[m]);
|
||||
}
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
ubufQQ[pos] = indatQ0[ind];
|
||||
|
||||
tmp2W32 = WEBRTC_SPL_MUL_16_32_RSFT14(indatQ0[ind], tmpW32);
|
||||
tmpW32 += 8192;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,14);
|
||||
tmpW32 = WEBRTC_SPL_MUL_16_16(tmpW16, tmpW16);
|
||||
|
||||
if ((tmp2W32>1073700000) || (csum1QQ>1073700000) || (tmpW32>1073700000) || (esumxQQ>1073700000)) {//2^30
|
||||
scale++;
|
||||
csum1QQ = WEBRTC_SPL_RSHIFT_W32(csum1QQ,1);
|
||||
esumxQQ = WEBRTC_SPL_RSHIFT_W32(esumxQQ,1);
|
||||
}
|
||||
tmp2W32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32,scale);
|
||||
csum1QQ += tmp2W32;
|
||||
tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmpW32,scale);
|
||||
esumxQQ += tmpW32;
|
||||
|
||||
ind++;
|
||||
cnt--;
|
||||
}
|
||||
|
||||
if (csum1QQ<esumxQQ) {
|
||||
tmp2W32=WebRtcSpl_DivResultInQ31(csum1QQ,esumxQQ);
|
||||
|
||||
/* Gain should be half the correlation */
|
||||
tmpW32=WEBRTC_SPL_RSHIFT_W32(tmp2W32,20);
|
||||
} else
|
||||
tmpW32=4096;
|
||||
gainsQ12[k]=(WebRtc_Word16)WEBRTC_SPL_SAT(PITCH_MAX_GAIN_Q12, tmpW32, 0);
|
||||
|
||||
}
|
||||
|
||||
/* Export buffer and states */
|
||||
memcpy(pfp->ubufQQ, ubufQQ+PITCH_FRAME_LEN, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE));
|
||||
pfp->oldlagQ7 = lagsQ7[PITCH_SUBFRAMES-1];
|
||||
pfp->oldgainQ12 = gainsQ12[PITCH_SUBFRAMES-1];
|
||||
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_gain_tables.c
|
||||
*
|
||||
* This file contains tables for the pitch filter side-info in the entropy coder.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pitch_gain_tables.h"
|
||||
|
||||
|
||||
/********************* Pitch Filter Gain Coefficient Tables ************************/
|
||||
|
||||
/* cdf for quantized pitch filter gains */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchGainCdf[255] = {
|
||||
0, 2, 4, 6, 64, 901, 903, 905, 16954, 16956,
|
||||
16961, 17360, 17362, 17364, 17366, 17368, 17370, 17372, 17374, 17411,
|
||||
17514, 17516, 17583, 18790, 18796, 18802, 20760, 20777, 20782, 21722,
|
||||
21724, 21728, 21738, 21740, 21742, 21744, 21746, 21748, 22224, 22227,
|
||||
22230, 23214, 23229, 23239, 25086, 25108, 25120, 26088, 26094, 26098,
|
||||
26175, 26177, 26179, 26181, 26183, 26185, 26484, 26507, 26522, 27705,
|
||||
27731, 27750, 29767, 29799, 29817, 30866, 30883, 30885, 31025, 31029,
|
||||
31031, 31033, 31035, 31037, 31114, 31126, 31134, 32687, 32722, 32767,
|
||||
35718, 35742, 35757, 36943, 36952, 36954, 37115, 37128, 37130, 37132,
|
||||
37134, 37136, 37143, 37145, 37152, 38843, 38863, 38897, 47458, 47467,
|
||||
47474, 49040, 49061, 49063, 49145, 49157, 49159, 49161, 49163, 49165,
|
||||
49167, 49169, 49171, 49757, 49770, 49782, 61333, 61344, 61346, 62860,
|
||||
62883, 62885, 62887, 62889, 62891, 62893, 62895, 62897, 62899, 62901,
|
||||
62903, 62905, 62907, 62909, 65496, 65498, 65500, 65521, 65523, 65525,
|
||||
65527, 65529, 65531, 65533, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535
|
||||
};
|
||||
|
||||
/* index limits and ranges */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kLowerlimiGain[3] = {
|
||||
-7, -2, -1
|
||||
};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kUpperlimitGain[3] = {
|
||||
0, 3, 1
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kMultsGain[2] = {
|
||||
18, 3
|
||||
};
|
||||
|
||||
/* size of cdf table */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kCdfTableSizeGain[1] = {
|
||||
256
|
||||
};
|
||||
|
||||
/* mean values of pitch filter gains in FIXED point Q12 */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kPitchGain1[144] = {
|
||||
843, 1092, 1336, 1222, 1405, 1656, 1500, 1815, 1843, 1838, 1839,
|
||||
1843, 1843, 1843, 1843, 1843, 1843, 1843, 814, 846, 1092, 1013,
|
||||
1174, 1383, 1391, 1511, 1584, 1734, 1753, 1843, 1843, 1843, 1843,
|
||||
1843, 1843, 1843, 524, 689, 777, 845, 947, 1069, 1090, 1263,
|
||||
1380, 1447, 1559, 1676, 1645, 1749, 1843, 1843, 1843, 1843, 81,
|
||||
477, 563, 611, 706, 806, 849, 1012, 1192, 1128, 1330, 1489,
|
||||
1425, 1576, 1826, 1741, 1843, 1843, 0, 290, 305, 356, 488,
|
||||
575, 602, 741, 890, 835, 1079, 1196, 1182, 1376, 1519, 1506,
|
||||
1680, 1843, 0, 47, 97, 69, 289, 381, 385, 474, 617,
|
||||
664, 803, 1079, 935, 1160, 1269, 1265, 1506, 1741, 0, 0,
|
||||
0, 0, 112, 120, 190, 283, 442, 343, 526, 809, 684,
|
||||
935, 1134, 1020, 1265, 1506, 0, 0, 0, 0, 0, 0,
|
||||
0, 111, 256, 87, 373, 597, 430, 684, 935, 770, 1020,
|
||||
1265
|
||||
};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kPitchGain2[144] = {
|
||||
1760, 1525, 1285, 1747, 1671, 1393, 1843, 1826, 1555, 1843, 1784,
|
||||
1606, 1843, 1843, 1711, 1843, 1843, 1814, 1389, 1275, 1040, 1564,
|
||||
1414, 1252, 1610, 1495, 1343, 1753, 1592, 1405, 1804, 1720, 1475,
|
||||
1843, 1814, 1581, 1208, 1061, 856, 1349, 1148, 994, 1390, 1253,
|
||||
1111, 1495, 1343, 1178, 1770, 1465, 1234, 1814, 1581, 1342, 1040,
|
||||
793, 713, 1053, 895, 737, 1128, 1003, 861, 1277, 1094, 981,
|
||||
1475, 1192, 1019, 1581, 1342, 1098, 855, 570, 483, 833, 648,
|
||||
540, 948, 744, 572, 1009, 844, 636, 1234, 934, 685, 1342,
|
||||
1217, 984, 537, 318, 124, 603, 423, 350, 687, 479, 322,
|
||||
791, 581, 430, 987, 671, 488, 1098, 849, 597, 283, 27,
|
||||
0, 397, 222, 38, 513, 271, 124, 624, 325, 157, 737,
|
||||
484, 233, 849, 597, 343, 27, 0, 0, 141, 0, 0,
|
||||
256, 69, 0, 370, 87, 0, 484, 229, 0, 597, 343,
|
||||
87
|
||||
};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kPitchGain3[144] = {
|
||||
1843, 1843, 1711, 1843, 1818, 1606, 1843, 1827, 1511, 1814, 1639,
|
||||
1393, 1760, 1525, 1285, 1656, 1419, 1176, 1835, 1718, 1475, 1841,
|
||||
1650, 1387, 1648, 1498, 1287, 1600, 1411, 1176, 1522, 1299, 1040,
|
||||
1419, 1176, 928, 1773, 1461, 1128, 1532, 1355, 1202, 1429, 1260,
|
||||
1115, 1398, 1151, 1025, 1172, 1080, 790, 1176, 928, 677, 1475,
|
||||
1147, 1019, 1276, 1096, 922, 1214, 1010, 901, 1057, 893, 800,
|
||||
1040, 796, 734, 928, 677, 424, 1137, 897, 753, 1120, 830,
|
||||
710, 875, 751, 601, 795, 642, 583, 790, 544, 475, 677,
|
||||
474, 140, 987, 750, 482, 697, 573, 450, 691, 487, 303,
|
||||
661, 394, 332, 537, 303, 220, 424, 168, 0, 737, 484,
|
||||
229, 624, 348, 153, 441, 261, 136, 397, 166, 51, 283,
|
||||
27, 0, 168, 0, 0, 484, 229, 0, 370, 57, 0,
|
||||
256, 43, 0, 141, 0, 0, 27, 0, 0, 0, 0,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kPitchGain4[144] = {
|
||||
1843, 1843, 1843, 1843, 1841, 1843, 1500, 1821, 1843, 1222, 1434,
|
||||
1656, 843, 1092, 1336, 504, 757, 1007, 1843, 1843, 1843, 1838,
|
||||
1791, 1843, 1265, 1505, 1599, 965, 1219, 1425, 730, 821, 1092,
|
||||
249, 504, 757, 1783, 1819, 1843, 1351, 1567, 1727, 1096, 1268,
|
||||
1409, 805, 961, 1131, 444, 670, 843, 0, 249, 504, 1425,
|
||||
1655, 1743, 1096, 1324, 1448, 822, 1019, 1199, 490, 704, 867,
|
||||
81, 450, 555, 0, 0, 249, 1247, 1428, 1530, 881, 1073,
|
||||
1283, 610, 759, 939, 278, 464, 645, 0, 200, 270, 0,
|
||||
0, 0, 935, 1163, 1410, 528, 790, 1068, 377, 499, 717,
|
||||
173, 240, 274, 0, 43, 62, 0, 0, 0, 684, 935,
|
||||
1182, 343, 551, 735, 161, 262, 423, 0, 55, 27, 0,
|
||||
0, 0, 0, 0, 0, 430, 684, 935, 87, 377, 597,
|
||||
0, 46, 256, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* transform matrix in Q12*/
|
||||
const WebRtc_Word16 WebRtcIsacfix_kTransform[4][4] = {
|
||||
{ -2048, -2048, -2048, -2048 },
|
||||
{ 2748, 916, -916, -2748 },
|
||||
{ 2048, -2048, -2048, 2048 },
|
||||
{ 916, -2748, 2748, -916 }
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_gain_tables.h
|
||||
*
|
||||
* This file contains tables for the pitch filter side-info in the entropy coder.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
|
||||
/********************* Pitch Filter Gain Coefficient Tables ************************/
|
||||
/* cdf for quantized pitch filter gains */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchGainCdf[255];
|
||||
|
||||
/* index limits and ranges */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kLowerlimiGain[3];
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kUpperlimitGain[3];
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kMultsGain[2];
|
||||
|
||||
/* mean values of pitch filter gains in Q12*/
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain1[144];
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain2[144];
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain3[144];
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain4[144];
|
||||
|
||||
/* size of cdf table */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kCdfTableSizeGain[1];
|
||||
|
||||
/* transform matrix */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kTransform[4][4];
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_ */
|
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_lag_tables.c
|
||||
*
|
||||
* This file contains tables for the pitch filter side-info in the entropy coder.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
#include "pitch_lag_tables.h"
|
||||
|
||||
|
||||
/********************* Pitch Filter Gain Coefficient Tables ************************/
|
||||
|
||||
/* tables for use with small pitch gain */
|
||||
|
||||
/* cdf for quantized pitch filter lags */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Lo[127] = {
|
||||
0, 134, 336, 549, 778, 998, 1264, 1512, 1777, 2070,
|
||||
2423, 2794, 3051, 3361, 3708, 3979, 4315, 4610, 4933, 5269,
|
||||
5575, 5896, 6155, 6480, 6816, 7129, 7477, 7764, 8061, 8358,
|
||||
8718, 9020, 9390, 9783, 10177, 10543, 10885, 11342, 11795, 12213,
|
||||
12680, 13096, 13524, 13919, 14436, 14903, 15349, 15795, 16267, 16734,
|
||||
17266, 17697, 18130, 18632, 19080, 19447, 19884, 20315, 20735, 21288,
|
||||
21764, 22264, 22723, 23193, 23680, 24111, 24557, 25022, 25537, 26082,
|
||||
26543, 27090, 27620, 28139, 28652, 29149, 29634, 30175, 30692, 31273,
|
||||
31866, 32506, 33059, 33650, 34296, 34955, 35629, 36295, 36967, 37726,
|
||||
38559, 39458, 40364, 41293, 42256, 43215, 44231, 45253, 46274, 47359,
|
||||
48482, 49678, 50810, 51853, 53016, 54148, 55235, 56263, 57282, 58363,
|
||||
59288, 60179, 61076, 61806, 62474, 63129, 63656, 64160, 64533, 64856,
|
||||
65152, 65535, 65535, 65535, 65535, 65535, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Lo[20] = {
|
||||
0, 429, 3558, 5861, 8558, 11639, 15210, 19502, 24773, 31983,
|
||||
42602, 48567, 52601, 55676, 58160, 60172, 61889, 63235, 65383, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Lo[2] = {
|
||||
0, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Lo[10] = {
|
||||
0, 2966, 6368, 11182, 19431, 37793, 48532, 55353, 60626, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrLo[4] = {
|
||||
WebRtcIsacfix_kPitchLagCdf1Lo,
|
||||
WebRtcIsacfix_kPitchLagCdf2Lo,
|
||||
WebRtcIsacfix_kPitchLagCdf3Lo,
|
||||
WebRtcIsacfix_kPitchLagCdf4Lo
|
||||
};
|
||||
|
||||
/* size of first cdf table */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeLo[1] = {
|
||||
128
|
||||
};
|
||||
|
||||
/* index limits and ranges */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kLowerLimitLo[4] = {
|
||||
-140, -9, 0, -4
|
||||
};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kUpperLimitLo[4] = {
|
||||
-20, 9, 0, 4
|
||||
};
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kInitIndLo[3] = {
|
||||
10, 1, 5
|
||||
};
|
||||
|
||||
/* mean values of pitch filter lags in Q10 */
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Lo[19] = {
|
||||
-17627, -16207, -14409, -12319, -10253, -8200, -6054, -3986, -1948, -19,
|
||||
1937, 3974, 6064, 8155, 10229, 12270, 14296, 16127, 17520
|
||||
};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Lo[9] = {
|
||||
-7949, -6063, -4036, -1941, 38, 1977, 4060, 6059
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* tables for use with medium pitch gain */
|
||||
|
||||
/* cdf for quantized pitch filter lags */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Mid[255] = {
|
||||
0, 28, 61, 88, 121, 149, 233, 331, 475, 559,
|
||||
624, 661, 689, 712, 745, 791, 815, 843, 866, 922,
|
||||
959, 1024, 1061, 1117, 1178, 1238, 1280, 1350, 1453, 1513,
|
||||
1564, 1625, 1671, 1741, 1788, 1904, 2072, 2421, 2626, 2770,
|
||||
2840, 2900, 2942, 3012, 3068, 3115, 3147, 3194, 3254, 3319,
|
||||
3366, 3520, 3678, 3780, 3850, 3911, 3957, 4032, 4106, 4185,
|
||||
4292, 4474, 4683, 4842, 5019, 5191, 5321, 5428, 5540, 5675,
|
||||
5763, 5847, 5959, 6127, 6304, 6564, 6839, 7090, 7263, 7421,
|
||||
7556, 7728, 7872, 7984, 8142, 8361, 8580, 8743, 8938, 9227,
|
||||
9409, 9539, 9674, 9795, 9930, 10060, 10177, 10382, 10614, 10861,
|
||||
11038, 11271, 11415, 11629, 11792, 12044, 12193, 12416, 12574, 12821,
|
||||
13007, 13235, 13445, 13654, 13901, 14134, 14488, 15000, 15703, 16285,
|
||||
16504, 16797, 17086, 17328, 17579, 17807, 17998, 18268, 18538, 18836,
|
||||
19087, 19274, 19474, 19716, 19935, 20270, 20833, 21303, 21532, 21741,
|
||||
21978, 22207, 22523, 22770, 23054, 23613, 23943, 24204, 24399, 24651,
|
||||
24832, 25074, 25270, 25549, 25759, 26015, 26150, 26424, 26713, 27048,
|
||||
27342, 27504, 27681, 27854, 28021, 28207, 28412, 28664, 28859, 29064,
|
||||
29278, 29548, 29748, 30107, 30377, 30656, 30856, 31164, 31452, 31755,
|
||||
32011, 32328, 32626, 32919, 33319, 33789, 34329, 34925, 35396, 35973,
|
||||
36443, 36964, 37551, 38156, 38724, 39357, 40023, 40908, 41587, 42602,
|
||||
43924, 45037, 45810, 46597, 47421, 48291, 49092, 50051, 51448, 52719,
|
||||
53440, 54241, 54944, 55977, 56676, 57299, 57872, 58389, 59059, 59688,
|
||||
60237, 60782, 61094, 61573, 61890, 62290, 62658, 63030, 63217, 63454,
|
||||
63622, 63882, 64003, 64273, 64427, 64529, 64581, 64697, 64758, 64902,
|
||||
65414, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Mid[36] = {
|
||||
0, 71, 335, 581, 836, 1039, 1323, 1795, 2258, 2608,
|
||||
3005, 3591, 4243, 5344, 7163, 10583, 16848, 28078, 49448, 57007,
|
||||
60357, 61850, 62837, 63437, 63872, 64188, 64377, 64614, 64774, 64949,
|
||||
65039, 65115, 65223, 65360, 65474, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Mid[2] = {
|
||||
0, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Mid[20] = {
|
||||
0, 28, 246, 459, 667, 1045, 1523, 2337, 4337, 11347,
|
||||
44231, 56709, 60781, 62243, 63161, 63969, 64608, 65062, 65502, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrMid[4] = {
|
||||
WebRtcIsacfix_kPitchLagCdf1Mid,
|
||||
WebRtcIsacfix_kPitchLagCdf2Mid,
|
||||
WebRtcIsacfix_kPitchLagCdf3Mid,
|
||||
WebRtcIsacfix_kPitchLagCdf4Mid
|
||||
};
|
||||
|
||||
/* size of first cdf table */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeMid[1] = {
|
||||
256
|
||||
};
|
||||
|
||||
/* index limits and ranges */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kLowerLimitMid[4] = {
|
||||
-280, -17, 0, -9
|
||||
};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kUpperLimitMid[4] = {
|
||||
-40, 17, 0, 9
|
||||
};
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kInitIndMid[3] = {
|
||||
18, 1, 10
|
||||
};
|
||||
|
||||
/* mean values of pitch filter lags in Q10 */
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Mid[35] = {
|
||||
-17297, -16250, -15416, -14343, -13341, -12363, -11270,
|
||||
-10355, -9122, -8217, -7172, -6083, -5102, -4004, -3060,
|
||||
-1982, -952, -18, 935, 1976, 3040, 4032,
|
||||
5082, 6065, 7257, 8202, 9264, 10225, 11242,
|
||||
12234, 13337, 14336, 15374, 16187, 17347
|
||||
};
|
||||
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Mid[19] = {
|
||||
-8811, -8081, -7203, -6003, -5057, -4025, -2983, -1964,
|
||||
-891, 29, 921, 1920, 2988, 4064, 5187, 6079, 7173, 8074, 8849
|
||||
};
|
||||
|
||||
|
||||
/* tables for use with large pitch gain */
|
||||
|
||||
/* cdf for quantized pitch filter lags */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Hi[511] = {
|
||||
0, 7, 18, 33, 69, 105, 156, 228, 315, 612,
|
||||
680, 691, 709, 724, 735, 738, 742, 746, 749, 753,
|
||||
756, 760, 764, 774, 782, 785, 789, 796, 800, 803,
|
||||
807, 814, 818, 822, 829, 832, 847, 854, 858, 869,
|
||||
876, 883, 898, 908, 934, 977, 1010, 1050, 1060, 1064,
|
||||
1075, 1078, 1086, 1089, 1093, 1104, 1111, 1122, 1133, 1136,
|
||||
1151, 1162, 1183, 1209, 1252, 1281, 1339, 1364, 1386, 1401,
|
||||
1411, 1415, 1426, 1430, 1433, 1440, 1448, 1455, 1462, 1477,
|
||||
1487, 1495, 1502, 1506, 1509, 1516, 1524, 1531, 1535, 1542,
|
||||
1553, 1556, 1578, 1589, 1611, 1625, 1639, 1643, 1654, 1665,
|
||||
1672, 1687, 1694, 1705, 1708, 1719, 1730, 1744, 1752, 1759,
|
||||
1791, 1795, 1820, 1867, 1886, 1915, 1936, 1943, 1965, 1987,
|
||||
2041, 2099, 2161, 2175, 2200, 2211, 2226, 2233, 2244, 2251,
|
||||
2266, 2280, 2287, 2298, 2309, 2316, 2331, 2342, 2356, 2378,
|
||||
2403, 2418, 2447, 2497, 2544, 2602, 2863, 2895, 2903, 2935,
|
||||
2950, 2971, 3004, 3011, 3018, 3029, 3040, 3062, 3087, 3127,
|
||||
3152, 3170, 3199, 3243, 3293, 3322, 3340, 3377, 3402, 3427,
|
||||
3474, 3518, 3543, 3579, 3601, 3637, 3659, 3706, 3731, 3760,
|
||||
3818, 3847, 3869, 3901, 3920, 3952, 4068, 4169, 4220, 4271,
|
||||
4524, 4571, 4604, 4632, 4672, 4730, 4777, 4806, 4857, 4904,
|
||||
4951, 5002, 5031, 5060, 5107, 5150, 5212, 5266, 5331, 5382,
|
||||
5432, 5490, 5544, 5610, 5700, 5762, 5812, 5874, 5972, 6022,
|
||||
6091, 6163, 6232, 6305, 6402, 6540, 6685, 6880, 7090, 7271,
|
||||
7379, 7452, 7542, 7625, 7687, 7770, 7843, 7911, 7966, 8024,
|
||||
8096, 8190, 8252, 8320, 8411, 8501, 8585, 8639, 8751, 8842,
|
||||
8918, 8986, 9066, 9127, 9203, 9269, 9345, 9406, 9464, 9536,
|
||||
9612, 9667, 9735, 9844, 9931, 10036, 10119, 10199, 10260, 10358,
|
||||
10441, 10514, 10666, 10734, 10872, 10951, 11053, 11125, 11223, 11324,
|
||||
11516, 11664, 11737, 11816, 11892, 12008, 12120, 12200, 12280, 12392,
|
||||
12490, 12576, 12685, 12812, 12917, 13003, 13108, 13210, 13300, 13384,
|
||||
13470, 13579, 13673, 13771, 13879, 13999, 14136, 14201, 14368, 14614,
|
||||
14759, 14867, 14958, 15030, 15121, 15189, 15280, 15385, 15461, 15555,
|
||||
15653, 15768, 15884, 15971, 16069, 16145, 16210, 16279, 16380, 16463,
|
||||
16539, 16615, 16688, 16818, 16919, 17017, 18041, 18338, 18523, 18649,
|
||||
18790, 18917, 19047, 19167, 19315, 19460, 19601, 19731, 19858, 20068,
|
||||
20173, 20318, 20466, 20625, 20741, 20911, 21045, 21201, 21396, 21588,
|
||||
21816, 22022, 22305, 22547, 22786, 23072, 23322, 23600, 23879, 24168,
|
||||
24433, 24769, 25120, 25511, 25895, 26289, 26792, 27219, 27683, 28077,
|
||||
28566, 29094, 29546, 29977, 30491, 30991, 31573, 32105, 32594, 33173,
|
||||
33788, 34497, 35181, 35833, 36488, 37255, 37921, 38645, 39275, 39894,
|
||||
40505, 41167, 41790, 42431, 43096, 43723, 44385, 45134, 45858, 46607,
|
||||
47349, 48091, 48768, 49405, 49955, 50555, 51167, 51985, 52611, 53078,
|
||||
53494, 53965, 54435, 54996, 55601, 56125, 56563, 56838, 57244, 57566,
|
||||
57967, 58297, 58771, 59093, 59419, 59647, 59886, 60143, 60461, 60693,
|
||||
60917, 61170, 61416, 61634, 61891, 62122, 62310, 62455, 62632, 62839,
|
||||
63103, 63436, 63639, 63805, 63906, 64015, 64192, 64355, 64475, 64558,
|
||||
64663, 64742, 64811, 64865, 64916, 64956, 64981, 65025, 65068, 65115,
|
||||
65195, 65314, 65419, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Hi[68] = {
|
||||
0, 7, 11, 22, 37, 52, 56, 59, 81, 85,
|
||||
89, 96, 115, 130, 137, 152, 170, 181, 193, 200,
|
||||
207, 233, 237, 259, 289, 318, 363, 433, 592, 992,
|
||||
1607, 3062, 6149, 12206, 25522, 48368, 58223, 61918, 63640, 64584,
|
||||
64943, 65098, 65206, 65268, 65294, 65335, 65350, 65372, 65387, 65402,
|
||||
65413, 65420, 65428, 65435, 65439, 65450, 65454, 65468, 65472, 65476,
|
||||
65483, 65491, 65498, 65505, 65516, 65520, 65528, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Hi[2] = {
|
||||
0, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Hi[35] = {
|
||||
0, 7, 19, 30, 41, 48, 63, 74, 82, 96,
|
||||
122, 152, 215, 330, 701, 2611, 10931, 48106, 61177, 64341,
|
||||
65112, 65238, 65309, 65338, 65364, 65379, 65401, 65427, 65453,
|
||||
65465, 65476, 65490, 65509, 65528, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrHi[4] = {
|
||||
WebRtcIsacfix_kPitchLagCdf1Hi,
|
||||
WebRtcIsacfix_kPitchLagCdf2Hi,
|
||||
WebRtcIsacfix_kPitchLagCdf3Hi,
|
||||
WebRtcIsacfix_kPitchLagCdf4Hi
|
||||
};
|
||||
|
||||
/* size of first cdf table */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeHi[1] = {
|
||||
512
|
||||
};
|
||||
|
||||
/* index limits and ranges */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kLowerLimitHi[4] = {
|
||||
-552, -34, 0, -16
|
||||
};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kUpperLimitHi[4] = {
|
||||
-80, 32, 0, 17
|
||||
};
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kInitIndHi[3] = {
|
||||
34, 1, 18
|
||||
};
|
||||
|
||||
/* mean values of pitch filter lags */
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Hi[67] = {
|
||||
-17482, -16896, -16220, -15929, -15329, -14848, -14336, -13807, -13312, -12800, -12218, -11720,
|
||||
-11307, -10649, -10396, -9742, -9148, -8668, -8297, -7718, -7155, -6656, -6231, -5600, -5129,
|
||||
-4610, -4110, -3521, -3040, -2525, -2016, -1506, -995, -477, -5, 469, 991, 1510, 2025, 2526, 3079,
|
||||
3555, 4124, 4601, 5131, 5613, 6194, 6671, 7140, 7645, 8207, 8601, 9132, 9728, 10359, 10752, 11302,
|
||||
11776, 12288, 12687, 13204, 13759, 14295, 14810, 15360, 15764, 16350
|
||||
};
|
||||
|
||||
|
||||
const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Hi[34] = {
|
||||
-8175, -7659, -7205, -6684, -6215, -5651, -5180, -4566, -4087, -3536, -3096,
|
||||
-2532, -1990, -1482, -959, -440, 11, 451, 954, 1492, 2020, 2562, 3059,
|
||||
3577, 4113, 4618, 5134, 5724, 6060, 6758, 7015, 7716, 8066, 8741
|
||||
};
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_lag_tables.h
|
||||
*
|
||||
* This file contains tables for the pitch filter side-info in the entropy coder.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_
|
||||
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
|
||||
/********************* Pitch Filter Lag Coefficient Tables ************************/
|
||||
|
||||
/* tables for use with small pitch gain */
|
||||
|
||||
/* cdfs for quantized pitch lags */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Lo[127];
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Lo[20];
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Lo[2];
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Lo[10];
|
||||
|
||||
extern const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrLo[4];
|
||||
|
||||
/* size of first cdf table */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeLo[1];
|
||||
|
||||
/* index limits and ranges */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kLowerLimitLo[4];
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kUpperLimitLo[4];
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndLo[3];
|
||||
|
||||
/* mean values of pitch filter lags */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Lo[19];
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Lo[9];
|
||||
|
||||
|
||||
|
||||
/* tables for use with medium pitch gain */
|
||||
|
||||
/* cdfs for quantized pitch lags */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Mid[255];
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Mid[36];
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Mid[2];
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Mid[20];
|
||||
|
||||
extern const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrMid[4];
|
||||
|
||||
/* size of first cdf table */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeMid[1];
|
||||
|
||||
/* index limits and ranges */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kLowerLimitMid[4];
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kUpperLimitMid[4];
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndMid[3];
|
||||
|
||||
/* mean values of pitch filter lags */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Mid[35];
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Mid[19];
|
||||
|
||||
|
||||
/* tables for use with large pitch gain */
|
||||
|
||||
/* cdfs for quantized pitch lags */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Hi[511];
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Hi[68];
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Hi[2];
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Hi[35];
|
||||
|
||||
extern const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrHi[4];
|
||||
|
||||
/* size of first cdf table */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeHi[1];
|
||||
|
||||
/* index limits and ranges */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kLowerLimitHi[4];
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kUpperLimitHi[4];
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndHi[3];
|
||||
|
||||
/* mean values of pitch filter lags */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Hi[67];
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Hi[34];
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_ */
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* settings.h
|
||||
*
|
||||
* Declaration of #defines used in the iSAC codec
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SETTINGS_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SETTINGS_H_
|
||||
|
||||
|
||||
/* sampling frequency (Hz) */
|
||||
#define FS 16000
|
||||
/* 1.5 times Sampling frequency */
|
||||
#define FS_1_HALF (WebRtc_UWord32) 24000
|
||||
/* Three times Sampling frequency */
|
||||
#define FS3 (WebRtc_UWord32) 48000
|
||||
/* Eight times Sampling frequency */
|
||||
#define FS8 (WebRtc_UWord32) 128000
|
||||
|
||||
/* number of samples per frame (either 480 (30ms) or 960 (60ms)) */
|
||||
#define INITIAL_FRAMESAMPLES 960
|
||||
|
||||
/* miliseconds */
|
||||
#define FRAMESIZE 30
|
||||
/* number of samples per frame processed in the encoder (30ms) */
|
||||
#define FRAMESAMPLES 480 /* ((FRAMESIZE*FS)/1000) */
|
||||
#define FRAMESAMPLES_HALF 240
|
||||
/* max number of samples per frame (= 60 ms frame) */
|
||||
#define MAX_FRAMESAMPLES 960
|
||||
/* number of samples per 10ms frame */
|
||||
#define FRAMESAMPLES_10ms 160 /* ((10*FS)/1000) */
|
||||
/* Number of samples per 1 ms */
|
||||
#define SAMPLES_PER_MSEC 16
|
||||
/* number of subframes */
|
||||
#define SUBFRAMES 6
|
||||
/* length of a subframe */
|
||||
#define UPDATE 80
|
||||
/* length of half a subframe (low/high band) */
|
||||
#define HALF_SUBFRAMELEN 40 /* (UPDATE/2) */
|
||||
/* samples of look ahead (in a half-band, so actually half the samples of look ahead @ FS) */
|
||||
#define QLOOKAHEAD 24 /* 3 ms */
|
||||
|
||||
/* order of AR model in spectral entropy coder */
|
||||
#define AR_ORDER 6
|
||||
#define MAX_ORDER 13
|
||||
#define LEVINSON_MAX_ORDER 12
|
||||
|
||||
/* window length (masking analysis) */
|
||||
#define WINLEN 256
|
||||
/* order of low-band pole filter used to approximate masking curve */
|
||||
#define ORDERLO 12
|
||||
/* order of hi-band pole filter used to approximate masking curve */
|
||||
#define ORDERHI 6
|
||||
|
||||
#define KLT_NUM_AVG_GAIN 0
|
||||
#define KLT_NUM_AVG_SHAPE 0
|
||||
#define KLT_NUM_MODELS 3
|
||||
#define LPC_SHAPE_ORDER 18 /* (ORDERLO + ORDERHI) */
|
||||
|
||||
#define KLT_ORDER_GAIN 12 /* (2 * SUBFRAMES) */
|
||||
#define KLT_ORDER_SHAPE 108 /* (LPC_SHAPE_ORDER * SUBFRAMES) */
|
||||
|
||||
|
||||
|
||||
/* order for post_filter_bank */
|
||||
#define POSTQORDER 3
|
||||
/* order for pre-filterbank */
|
||||
#define QORDER 3
|
||||
/* for decimator */
|
||||
#define ALLPASSSECTIONS 2
|
||||
/* The number of composite all-pass filter factors */
|
||||
#define NUMBEROFCOMPOSITEAPSECTIONS 4
|
||||
|
||||
/* The number of all-pass filter factors in an upper or lower channel*/
|
||||
#define NUMBEROFCHANNELAPSECTIONS 2
|
||||
|
||||
|
||||
|
||||
#define DPMIN_Q10 -10240 /* -10.00 in Q10 */
|
||||
#define DPMAX_Q10 10240 /* 10.00 in Q10 */
|
||||
#define MINBITS_Q10 10240 /* 10.0 in Q10 */
|
||||
|
||||
|
||||
/* array size for byte stream in number of Word16. */
|
||||
#define STREAM_MAXW16 300 /* The old maximum size still needed for the decoding */
|
||||
#define STREAM_MAXW16_30MS 100 /* 100 Word16 = 200 bytes = 53.4 kbit/s @ 30 ms.framelength */
|
||||
#define STREAM_MAXW16_60MS 200 /* 200 Word16 = 400 bytes = 53.4 kbit/s @ 60 ms.framelength */
|
||||
|
||||
|
||||
/* storage size for bit counts */
|
||||
//#define BIT_COUNTER_SIZE 30
|
||||
/* maximum order of any AR model or filter */
|
||||
#define MAX_AR_MODEL_ORDER 12
|
||||
|
||||
/* Maximum number of iterations allowed to limit payload size */
|
||||
#define MAX_PAYLOAD_LIMIT_ITERATION 1
|
||||
|
||||
/* Bandwidth estimator */
|
||||
|
||||
#define MIN_ISAC_BW 10000 /* Minimum bandwidth in bits per sec */
|
||||
#define MAX_ISAC_BW 32000 /* Maxmum bandwidth in bits per sec */
|
||||
#define MIN_ISAC_MD 5 /* Minimum Max Delay in ?? */
|
||||
#define MAX_ISAC_MD 25 /* Maxmum Max Delay in ?? */
|
||||
#define DELAY_CORRECTION_MAX 717
|
||||
#define DELAY_CORRECTION_MED 819
|
||||
#define Thld_30_60 18000
|
||||
#define Thld_60_30 27000
|
||||
|
||||
/* assumed header size; we don't know the exact number (header compression may be used) */
|
||||
#define HEADER_SIZE 35 /* bytes */
|
||||
#define INIT_FRAME_LEN 60
|
||||
#define INIT_BN_EST 20000
|
||||
#define INIT_BN_EST_Q7 2560000 /* 20 kbps in Q7 */
|
||||
#define INIT_REC_BN_EST_Q5 789312 /* INIT_BN_EST + INIT_HDR_RATE in Q5 */
|
||||
|
||||
/* 8738 in Q18 is ~ 1/30 */
|
||||
/* #define INIT_HDR_RATE (((HEADER_SIZE * 8 * 1000) * 8738) >> NUM_BITS_TO_SHIFT (INIT_FRAME_LEN)) */
|
||||
#define INIT_HDR_RATE 4666
|
||||
/* number of packets in a row for a high rate burst */
|
||||
#define BURST_LEN 3
|
||||
/* ms, max time between two full bursts */
|
||||
#define BURST_INTERVAL 800
|
||||
/* number of packets in a row for initial high rate burst */
|
||||
#define INIT_BURST_LEN 5
|
||||
/* bits/s, rate for the first BURST_LEN packets */
|
||||
#define INIT_RATE 10240000 /* INIT_BN_EST in Q9 */
|
||||
|
||||
|
||||
/* For pitch analysis */
|
||||
#define PITCH_FRAME_LEN 240 /* (FRAMESAMPLES/2) 30 ms */
|
||||
#define PITCH_MAX_LAG 140 /* 57 Hz */
|
||||
#define PITCH_MIN_LAG 20 /* 400 Hz */
|
||||
#define PITCH_MIN_LAG_Q8 5120 /* 256 * PITCH_MIN_LAG */
|
||||
#define OFFSET_Q8 768 /* 256 * 3 */
|
||||
|
||||
#define PITCH_MAX_GAIN_Q12 1843 /* 0.45 */
|
||||
#define PITCH_LAG_SPAN2 65 /* (PITCH_MAX_LAG/2-PITCH_MIN_LAG/2+5) */
|
||||
#define PITCH_CORR_LEN2 60 /* 15 ms */
|
||||
#define PITCH_CORR_STEP2 60 /* (PITCH_FRAME_LEN/4) */
|
||||
#define PITCH_SUBFRAMES 4
|
||||
#define PITCH_SUBFRAME_LEN 60 /* (PITCH_FRAME_LEN/PITCH_SUBFRAMES) */
|
||||
|
||||
/* For pitch filter */
|
||||
#define PITCH_BUFFSIZE 190 /* (PITCH_MAX_LAG + 50) Extra 50 for fraction and LP filters */
|
||||
#define PITCH_INTBUFFSIZE 430 /* (PITCH_FRAME_LEN+PITCH_BUFFSIZE) */
|
||||
#define PITCH_FRACS 8
|
||||
#define PITCH_FRACORDER 9
|
||||
#define PITCH_DAMPORDER 5
|
||||
|
||||
|
||||
/* Order of high pass filter */
|
||||
#define HPORDER 2
|
||||
|
||||
|
||||
/* PLC */
|
||||
#define DECAY_RATE 10 /* Q15, 20% of decay every lost frame apllied linearly sample by sample*/
|
||||
#define PLC_WAS_USED 1
|
||||
#define PLC_NOT_USED 3
|
||||
#define RECOVERY_OVERLAP 80
|
||||
#define RESAMP_RES 256
|
||||
#define RESAMP_RES_BIT 8
|
||||
|
||||
|
||||
|
||||
/* Define Error codes */
|
||||
/* 6000 General */
|
||||
#define ISAC_MEMORY_ALLOCATION_FAILED 6010
|
||||
#define ISAC_MODE_MISMATCH 6020
|
||||
#define ISAC_DISALLOWED_BOTTLENECK 6030
|
||||
#define ISAC_DISALLOWED_FRAME_LENGTH 6040
|
||||
/* 6200 Bandwidth estimator */
|
||||
#define ISAC_RANGE_ERROR_BW_ESTIMATOR 6240
|
||||
/* 6400 Encoder */
|
||||
#define ISAC_ENCODER_NOT_INITIATED 6410
|
||||
#define ISAC_DISALLOWED_CODING_MODE 6420
|
||||
#define ISAC_DISALLOWED_FRAME_MODE_ENCODER 6430
|
||||
#define ISAC_DISALLOWED_BITSTREAM_LENGTH 6440
|
||||
#define ISAC_PAYLOAD_LARGER_THAN_LIMIT 6450
|
||||
/* 6600 Decoder */
|
||||
#define ISAC_DECODER_NOT_INITIATED 6610
|
||||
#define ISAC_EMPTY_PACKET 6620
|
||||
#define ISAC_DISALLOWED_FRAME_MODE_DECODER 6630
|
||||
#define ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH 6640
|
||||
#define ISAC_RANGE_ERROR_DECODE_BANDWIDTH 6650
|
||||
#define ISAC_RANGE_ERROR_DECODE_PITCH_GAIN 6660
|
||||
#define ISAC_RANGE_ERROR_DECODE_PITCH_LAG 6670
|
||||
#define ISAC_RANGE_ERROR_DECODE_LPC 6680
|
||||
#define ISAC_RANGE_ERROR_DECODE_SPECTRUM 6690
|
||||
#define ISAC_LENGTH_MISMATCH 6730
|
||||
/* 6800 Call setup formats */
|
||||
#define ISAC_INCOMPATIBLE_FORMATS 6810
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SETTINGS_H_ */
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* spectrum_ar_model_tables.c
|
||||
*
|
||||
* This file contains tables with AR coefficients, Gain coefficients
|
||||
* and cosine tables.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "spectrum_ar_model_tables.h"
|
||||
#include "settings.h"
|
||||
|
||||
/********************* AR Coefficient Tables ************************/
|
||||
|
||||
/* cdf for quantized reflection coefficient 1 */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kRc1Cdf[12] = {
|
||||
0, 2, 4, 129, 7707, 57485, 65495, 65527, 65529, 65531,
|
||||
65533, 65535
|
||||
};
|
||||
|
||||
/* cdf for quantized reflection coefficient 2 */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kRc2Cdf[12] = {
|
||||
0, 2, 4, 7, 531, 25298, 64525, 65526, 65529, 65531,
|
||||
65533, 65535
|
||||
};
|
||||
|
||||
/* cdf for quantized reflection coefficient 3 */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kRc3Cdf[12] = {
|
||||
0, 2, 4, 6, 620, 22898, 64843, 65527, 65529, 65531,
|
||||
65533, 65535
|
||||
};
|
||||
|
||||
/* cdf for quantized reflection coefficient 4 */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kRc4Cdf[12] = {
|
||||
0, 2, 4, 6, 35, 10034, 60733, 65506, 65529, 65531,
|
||||
65533, 65535
|
||||
};
|
||||
|
||||
/* cdf for quantized reflection coefficient 5 */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kRc5Cdf[12] = {
|
||||
0, 2, 4, 6, 36, 7567, 56727, 65385, 65529, 65531,
|
||||
65533, 65535
|
||||
};
|
||||
|
||||
/* cdf for quantized reflection coefficient 6 */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kRc6Cdf[12] = {
|
||||
0, 2, 4, 6, 14, 6579, 57360, 65409, 65529, 65531,
|
||||
65533, 65535
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 1 */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kRc1Levels[11] = {
|
||||
-32104, -29007, -23202, -15496, -9279, -2577, 5934, 17535, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 2 */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kRc2Levels[11] = {
|
||||
-32104, -29503, -23494, -15261, -7309, -1399, 6158, 16381, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 3 */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kRc3Levels[11] = {
|
||||
-32104, -29503, -23157, -15186, -7347, -1359, 5829, 17535, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 4 */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kRc4Levels[11] = {
|
||||
-32104, -29503, -24512, -15362, -6665, -342, 6596, 14585, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 5 */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kRc5Levels[11] = {
|
||||
-32104, -29503, -24512, -15005, -6564, -106, 7123, 14920, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 6 */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kRc6Levels[11] = {
|
||||
-32104, -29503, -24512, -15096, -6656, -37, 7036, 14847, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* quantization boundary levels for reflection coefficients */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kRcBound[12] = {
|
||||
-32768, -31441, -27566, -21458, -13612, -4663,
|
||||
4663, 13612, 21458, 27566, 31441, 32767
|
||||
};
|
||||
|
||||
/* initial index for AR reflection coefficient quantizer and cdf table search */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kRcInitInd[6] = {
|
||||
5, 5, 5, 5, 5, 5
|
||||
};
|
||||
|
||||
/* pointers to AR cdf tables */
|
||||
const WebRtc_UWord16 *WebRtcIsacfix_kRcCdfPtr[AR_ORDER] = {
|
||||
WebRtcIsacfix_kRc1Cdf,
|
||||
WebRtcIsacfix_kRc2Cdf,
|
||||
WebRtcIsacfix_kRc3Cdf,
|
||||
WebRtcIsacfix_kRc4Cdf,
|
||||
WebRtcIsacfix_kRc5Cdf,
|
||||
WebRtcIsacfix_kRc6Cdf
|
||||
};
|
||||
|
||||
/* pointers to AR representation levels tables */
|
||||
const WebRtc_Word16 *WebRtcIsacfix_kRcLevPtr[AR_ORDER] = {
|
||||
WebRtcIsacfix_kRc1Levels,
|
||||
WebRtcIsacfix_kRc2Levels,
|
||||
WebRtcIsacfix_kRc3Levels,
|
||||
WebRtcIsacfix_kRc4Levels,
|
||||
WebRtcIsacfix_kRc5Levels,
|
||||
WebRtcIsacfix_kRc6Levels
|
||||
};
|
||||
|
||||
|
||||
/******************** GAIN Coefficient Tables ***********************/
|
||||
|
||||
/* cdf for Gain coefficient */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kGainCdf[19] = {
|
||||
0, 2, 4, 6, 8, 10, 12, 14, 16, 1172,
|
||||
11119, 29411, 51699, 64445, 65527, 65529, 65531, 65533, 65535
|
||||
};
|
||||
|
||||
/* representation levels for quantized squared Gain coefficient */
|
||||
const WebRtc_Word32 WebRtcIsacfix_kGain2Lev[18] = {
|
||||
128, 128, 128, 128, 128, 215, 364, 709, 1268,
|
||||
1960, 3405, 6078, 11286, 17827, 51918, 134498, 487432, 2048000
|
||||
};
|
||||
|
||||
/* quantization boundary levels for squared Gain coefficient */
|
||||
const WebRtc_Word32 WebRtcIsacfix_kGain2Bound[19] = {
|
||||
0, 21, 35, 59, 99, 166, 280, 475, 815, 1414,
|
||||
2495, 4505, 8397, 16405, 34431, 81359, 240497, 921600, 0x7FFFFFFF
|
||||
};
|
||||
|
||||
/* pointers to Gain cdf table */
|
||||
const WebRtc_UWord16 *WebRtcIsacfix_kGainPtr[1] = {
|
||||
WebRtcIsacfix_kGainCdf
|
||||
};
|
||||
|
||||
/* gain initial index for gain quantizer and cdf table search */
|
||||
const WebRtc_UWord16 WebRtcIsacfix_kGainInitInd[1] = {
|
||||
11
|
||||
};
|
||||
|
||||
|
||||
/************************* Cosine Tables ****************************/
|
||||
|
||||
/* cosine table */
|
||||
const WebRtc_Word16 WebRtcIsacfix_kCos[6][60] = {
|
||||
{ 512, 512, 511, 510, 508, 507, 505, 502, 499, 496,
|
||||
493, 489, 485, 480, 476, 470, 465, 459, 453, 447,
|
||||
440, 433, 426, 418, 410, 402, 394, 385, 376, 367,
|
||||
357, 348, 338, 327, 317, 306, 295, 284, 273, 262,
|
||||
250, 238, 226, 214, 202, 190, 177, 165, 152, 139,
|
||||
126, 113, 100, 87, 73, 60, 47, 33, 20, 7 },
|
||||
{ 512, 510, 508, 503, 498, 491, 483, 473, 462, 450,
|
||||
437, 422, 406, 389, 371, 352, 333, 312, 290, 268,
|
||||
244, 220, 196, 171, 145, 120, 93, 67, 40, 13,
|
||||
-13, -40, -67, -93, -120, -145, -171, -196, -220, -244,
|
||||
-268, -290, -312, -333, -352, -371, -389, -406, -422, -437,
|
||||
-450, -462, -473, -483, -491, -498, -503, -508, -510, -512 },
|
||||
{ 512, 508, 502, 493, 480, 465, 447, 426, 402, 376,
|
||||
348, 317, 284, 250, 214, 177, 139, 100, 60, 20,
|
||||
-20, -60, -100, -139, -177, -214, -250, -284, -317, -348,
|
||||
-376, -402, -426, -447, -465, -480, -493, -502, -508, -512,
|
||||
-512, -508, -502, -493, -480, -465, -447, -426, -402, -376,
|
||||
-348, -317, -284, -250, -214, -177, -139, -100, -60, -20 },
|
||||
{ 511, 506, 495, 478, 456, 429, 398, 362, 322, 279,
|
||||
232, 183, 133, 80, 27, -27, -80, -133, -183, -232,
|
||||
-279, -322, -362, -398, -429, -456, -478, -495, -506, -511,
|
||||
-511, -506, -495, -478, -456, -429, -398, -362, -322, -279,
|
||||
-232, -183, -133, -80, -27, 27, 80, 133, 183, 232,
|
||||
279, 322, 362, 398, 429, 456, 478, 495, 506, 511 },
|
||||
{ 511, 502, 485, 459, 426, 385, 338, 284, 226, 165,
|
||||
100, 33, -33, -100, -165, -226, -284, -338, -385, -426,
|
||||
-459, -485, -502, -511, -511, -502, -485, -459, -426, -385,
|
||||
-338, -284, -226, -165, -100, -33, 33, 100, 165, 226,
|
||||
284, 338, 385, 426, 459, 485, 502, 511, 511, 502,
|
||||
485, 459, 426, 385, 338, 284, 226, 165, 100, 33 },
|
||||
{ 510, 498, 473, 437, 389, 333, 268, 196, 120, 40,
|
||||
-40, -120, -196, -268, -333, -389, -437, -473, -498, -510,
|
||||
-510, -498, -473, -437, -389, -333, -268, -196, -120, -40,
|
||||
40, 120, 196, 268, 333, 389, 437, 473, 498, 510,
|
||||
510, 498, 473, 437, 389, 333, 268, 196, 120, 40,
|
||||
-40, -120, -196, -268, -333, -389, -437, -473, -498, -510 }
|
||||
};
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* spectrum_ar_model_tables.h
|
||||
*
|
||||
* This file contains definitions of tables with AR coefficients,
|
||||
* Gain coefficients and cosine tables.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
/********************* AR Coefficient Tables ************************/
|
||||
/* cdf for quantized reflection coefficient 1 */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kRc1Cdf[12];
|
||||
|
||||
/* cdf for quantized reflection coefficient 2 */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kRc2Cdf[12];
|
||||
|
||||
/* cdf for quantized reflection coefficient 3 */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kRc3Cdf[12];
|
||||
|
||||
/* cdf for quantized reflection coefficient 4 */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kRc4Cdf[12];
|
||||
|
||||
/* cdf for quantized reflection coefficient 5 */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kRc5Cdf[12];
|
||||
|
||||
/* cdf for quantized reflection coefficient 6 */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kRc6Cdf[12];
|
||||
|
||||
/* representation levels for quantized reflection coefficient 1 */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kRc1Levels[11];
|
||||
|
||||
/* representation levels for quantized reflection coefficient 2 */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kRc2Levels[11];
|
||||
|
||||
/* representation levels for quantized reflection coefficient 3 */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kRc3Levels[11];
|
||||
|
||||
/* representation levels for quantized reflection coefficient 4 */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kRc4Levels[11];
|
||||
|
||||
/* representation levels for quantized reflection coefficient 5 */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kRc5Levels[11];
|
||||
|
||||
/* representation levels for quantized reflection coefficient 6 */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kRc6Levels[11];
|
||||
|
||||
/* quantization boundary levels for reflection coefficients */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kRcBound[12];
|
||||
|
||||
/* initial indices for AR reflection coefficient quantizer and cdf table search */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kRcInitInd[AR_ORDER];
|
||||
|
||||
/* pointers to AR cdf tables */
|
||||
extern const WebRtc_UWord16 *WebRtcIsacfix_kRcCdfPtr[AR_ORDER];
|
||||
|
||||
/* pointers to AR representation levels tables */
|
||||
extern const WebRtc_Word16 *WebRtcIsacfix_kRcLevPtr[AR_ORDER];
|
||||
|
||||
|
||||
/******************** GAIN Coefficient Tables ***********************/
|
||||
/* cdf for Gain coefficient */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kGainCdf[19];
|
||||
|
||||
/* representation levels for quantized Gain coefficient */
|
||||
extern const WebRtc_Word32 WebRtcIsacfix_kGain2Lev[18];
|
||||
|
||||
/* squared quantization boundary levels for Gain coefficient */
|
||||
extern const WebRtc_Word32 WebRtcIsacfix_kGain2Bound[19];
|
||||
|
||||
/* pointer to Gain cdf table */
|
||||
extern const WebRtc_UWord16 *WebRtcIsacfix_kGainPtr[1];
|
||||
|
||||
/* Gain initial index for gain quantizer and cdf table search */
|
||||
extern const WebRtc_UWord16 WebRtcIsacfix_kGainInitInd[1];
|
||||
|
||||
/************************* Cosine Tables ****************************/
|
||||
/* Cosine table */
|
||||
extern const WebRtc_Word16 WebRtcIsacfix_kCos[6][60];
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_ */
|
|
@ -0,0 +1,382 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* structs.h
|
||||
*
|
||||
* This header file contains all the structs used in the ISAC codec
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_STRUCTS_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_STRUCTS_H_
|
||||
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "signal_processing_library.h"
|
||||
#include "settings.h"
|
||||
|
||||
/* Bitstream struct for decoder */
|
||||
typedef struct Bitstreamstruct_dec {
|
||||
|
||||
WebRtc_UWord16 *stream; /* Pointer to bytestream to decode */
|
||||
WebRtc_UWord32 W_upper; /* Upper boundary of interval W */
|
||||
WebRtc_UWord32 streamval;
|
||||
WebRtc_UWord16 stream_index; /* Index to the current position in bytestream */
|
||||
WebRtc_Word16 full; /* 0 - first byte in memory filled, second empty*/
|
||||
/* 1 - both bytes are empty (we just filled the previous memory */
|
||||
|
||||
} Bitstr_dec;
|
||||
|
||||
/* Bitstream struct for encoder */
|
||||
typedef struct Bitstreamstruct_enc {
|
||||
|
||||
WebRtc_UWord16 stream[STREAM_MAXW16_60MS]; /* Vector for adding encoded bytestream */
|
||||
WebRtc_UWord32 W_upper; /* Upper boundary of interval W */
|
||||
WebRtc_UWord32 streamval;
|
||||
WebRtc_UWord16 stream_index; /* Index to the current position in bytestream */
|
||||
WebRtc_Word16 full; /* 0 - first byte in memory filled, second empty*/
|
||||
/* 1 - both bytes are empty (we just filled the previous memory */
|
||||
|
||||
} Bitstr_enc;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
WebRtc_Word16 DataBufferLoQ0[WINLEN];
|
||||
WebRtc_Word16 DataBufferHiQ0[WINLEN];
|
||||
|
||||
WebRtc_Word32 CorrBufLoQQ[ORDERLO+1];
|
||||
WebRtc_Word32 CorrBufHiQQ[ORDERHI+1];
|
||||
|
||||
WebRtc_Word16 CorrBufLoQdom[ORDERLO+1];
|
||||
WebRtc_Word16 CorrBufHiQdom[ORDERHI+1];
|
||||
|
||||
WebRtc_Word32 PreStateLoGQ15[ORDERLO+1];
|
||||
WebRtc_Word32 PreStateHiGQ15[ORDERHI+1];
|
||||
|
||||
WebRtc_UWord32 OldEnergy;
|
||||
|
||||
} MaskFiltstr_enc;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
WebRtc_Word16 PostStateLoGQ0[ORDERLO+1];
|
||||
WebRtc_Word16 PostStateHiGQ0[ORDERHI+1];
|
||||
|
||||
WebRtc_UWord32 OldEnergy;
|
||||
|
||||
} MaskFiltstr_dec;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
//state vectors for each of the two analysis filters
|
||||
|
||||
WebRtc_Word32 INSTAT1_fix[2*(QORDER-1)];
|
||||
WebRtc_Word32 INSTAT2_fix[2*(QORDER-1)];
|
||||
WebRtc_Word16 INLABUF1_fix[QLOOKAHEAD];
|
||||
WebRtc_Word16 INLABUF2_fix[QLOOKAHEAD];
|
||||
|
||||
/* High pass filter */
|
||||
WebRtc_Word32 HPstates_fix[HPORDER];
|
||||
|
||||
} PreFiltBankstr;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
//state vectors for each of the two analysis filters
|
||||
WebRtc_Word32 STATE_0_LOWER_fix[2*POSTQORDER];
|
||||
WebRtc_Word32 STATE_0_UPPER_fix[2*POSTQORDER];
|
||||
|
||||
/* High pass filter */
|
||||
|
||||
WebRtc_Word32 HPstates1_fix[HPORDER];
|
||||
WebRtc_Word32 HPstates2_fix[HPORDER];
|
||||
|
||||
} PostFiltBankstr;
|
||||
|
||||
typedef struct {
|
||||
|
||||
|
||||
/* data buffer for pitch filter */
|
||||
WebRtc_Word16 ubufQQ[PITCH_BUFFSIZE];
|
||||
|
||||
/* low pass state vector */
|
||||
WebRtc_Word16 ystateQQ[PITCH_DAMPORDER];
|
||||
|
||||
/* old lag and gain */
|
||||
WebRtc_Word16 oldlagQ7;
|
||||
WebRtc_Word16 oldgainQ12;
|
||||
|
||||
} PitchFiltstr;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
//for inital estimator
|
||||
WebRtc_Word16 dec_buffer16[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2];
|
||||
WebRtc_Word32 decimator_state32[2*ALLPASSSECTIONS+1];
|
||||
WebRtc_Word16 inbuf[QLOOKAHEAD];
|
||||
|
||||
PitchFiltstr PFstr_wght;
|
||||
PitchFiltstr PFstr;
|
||||
|
||||
|
||||
} PitchAnalysisStruct;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* Parameters used in PLC to avoid re-computation */
|
||||
|
||||
/* --- residual signals --- */
|
||||
WebRtc_Word16 prevPitchInvIn[FRAMESAMPLES/2];
|
||||
WebRtc_Word16 prevPitchInvOut[PITCH_MAX_LAG + 10]; // [FRAMESAMPLES/2]; save 90
|
||||
WebRtc_Word32 prevHP[PITCH_MAX_LAG + 10]; // [FRAMESAMPLES/2]; save 90
|
||||
|
||||
|
||||
WebRtc_Word16 decayCoeffPriodic; /* how much to supress a sample */
|
||||
WebRtc_Word16 decayCoeffNoise;
|
||||
WebRtc_Word16 used; /* if PLC is used */
|
||||
|
||||
|
||||
WebRtc_Word16 *lastPitchLP; // [FRAMESAMPLES/2]; saved 240;
|
||||
|
||||
|
||||
/* --- LPC side info --- */
|
||||
WebRtc_Word16 lofilt_coefQ15[ ORDERLO ];
|
||||
WebRtc_Word16 hifilt_coefQ15[ ORDERHI ];
|
||||
WebRtc_Word32 gain_lo_hiQ17[2];
|
||||
|
||||
/* --- LTP side info --- */
|
||||
WebRtc_Word16 AvgPitchGain_Q12;
|
||||
WebRtc_Word16 lastPitchGain_Q12;
|
||||
WebRtc_Word16 lastPitchLag_Q7;
|
||||
|
||||
/* --- Add-overlap in recovery packet --- */
|
||||
WebRtc_Word16 overlapLP[ RECOVERY_OVERLAP ]; // [FRAMESAMPLES/2]; saved 160
|
||||
|
||||
WebRtc_Word16 pitchCycles;
|
||||
WebRtc_Word16 A;
|
||||
WebRtc_Word16 B;
|
||||
WebRtc_Word16 pitchIndex;
|
||||
WebRtc_Word16 stretchLag;
|
||||
WebRtc_Word16 *prevPitchLP; // [ FRAMESAMPLES/2 ]; saved 240
|
||||
WebRtc_Word16 seed;
|
||||
|
||||
WebRtc_Word16 std;
|
||||
} PLCstr;
|
||||
|
||||
|
||||
|
||||
/* Have instance of struct together with other iSAC structs */
|
||||
typedef struct {
|
||||
|
||||
WebRtc_Word16 prevFrameSizeMs; /* Previous frame size (in ms) */
|
||||
WebRtc_UWord16 prevRtpNumber; /* Previous RTP timestamp from received packet */
|
||||
/* (in samples relative beginning) */
|
||||
WebRtc_UWord32 prevSendTime; /* Send time for previous packet, from RTP header */
|
||||
WebRtc_UWord32 prevArrivalTime; /* Arrival time for previous packet (in ms using timeGetTime()) */
|
||||
WebRtc_UWord16 prevRtpRate; /* rate of previous packet, derived from RTP timestamps (in bits/s) */
|
||||
WebRtc_UWord32 lastUpdate; /* Time since the last update of the Bottle Neck estimate (in samples) */
|
||||
WebRtc_UWord32 lastReduction; /* Time sinse the last reduction (in samples) */
|
||||
WebRtc_Word32 countUpdates; /* How many times the estimate was update in the beginning */
|
||||
|
||||
/* The estimated bottle neck rate from there to here (in bits/s) */
|
||||
WebRtc_UWord32 recBw;
|
||||
WebRtc_UWord32 recBwInv;
|
||||
WebRtc_UWord32 recBwAvg;
|
||||
WebRtc_UWord32 recBwAvgQ;
|
||||
|
||||
WebRtc_UWord32 minBwInv;
|
||||
WebRtc_UWord32 maxBwInv;
|
||||
|
||||
/* The estimated mean absolute jitter value, as seen on this side (in ms) */
|
||||
WebRtc_Word32 recJitter;
|
||||
WebRtc_Word32 recJitterShortTerm;
|
||||
WebRtc_Word32 recJitterShortTermAbs;
|
||||
WebRtc_Word32 recMaxDelay;
|
||||
WebRtc_Word32 recMaxDelayAvgQ;
|
||||
|
||||
|
||||
WebRtc_Word16 recHeaderRate; /* (assumed) bitrate for headers (bps) */
|
||||
|
||||
WebRtc_UWord32 sendBwAvg; /* The estimated bottle neck rate from here to there (in bits/s) */
|
||||
WebRtc_Word32 sendMaxDelayAvg; /* The estimated mean absolute jitter value, as seen on the other siee (in ms) */
|
||||
|
||||
|
||||
WebRtc_Word16 countRecPkts; /* number of packets received since last update */
|
||||
WebRtc_Word16 highSpeedRec; /* flag for marking that a high speed network has been detected downstream */
|
||||
|
||||
/* number of consecutive pkts sent during which the bwe estimate has
|
||||
remained at a value greater than the downstream threshold for determining highspeed network */
|
||||
WebRtc_Word16 countHighSpeedRec;
|
||||
|
||||
/* flag indicating bwe should not adjust down immediately for very late pckts */
|
||||
WebRtc_Word16 inWaitPeriod;
|
||||
|
||||
/* variable holding the time of the start of a window of time when
|
||||
bwe should not adjust down immediately for very late pckts */
|
||||
WebRtc_UWord32 startWaitPeriod;
|
||||
|
||||
/* number of consecutive pkts sent during which the bwe estimate has
|
||||
remained at a value greater than the upstream threshold for determining highspeed network */
|
||||
WebRtc_Word16 countHighSpeedSent;
|
||||
|
||||
/* flag indicated the desired number of packets over threshold rate have been sent and
|
||||
bwe will assume the connection is over broadband network */
|
||||
WebRtc_Word16 highSpeedSend;
|
||||
|
||||
|
||||
|
||||
|
||||
} BwEstimatorstr;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
/* boolean, flags if previous packet exceeded B.N. */
|
||||
WebRtc_Word16 PrevExceed;
|
||||
/* ms */
|
||||
WebRtc_Word16 ExceedAgo;
|
||||
/* packets left to send in current burst */
|
||||
WebRtc_Word16 BurstCounter;
|
||||
/* packets */
|
||||
WebRtc_Word16 InitCounter;
|
||||
/* ms remaining in buffer when next packet will be sent */
|
||||
WebRtc_Word16 StillBuffered;
|
||||
|
||||
} RateModel;
|
||||
|
||||
/* The following strutc is used to store data from encoding, to make it
|
||||
fast and easy to construct a new bitstream with a different Bandwidth
|
||||
estimate. All values (except framelength and minBytes) is double size to
|
||||
handle 60 ms of data.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
/* Used to keep track of if it is first or second part of 60 msec packet */
|
||||
int startIdx;
|
||||
|
||||
/* Frame length in samples */
|
||||
WebRtc_Word16 framelength;
|
||||
|
||||
/* Pitch Gain */
|
||||
WebRtc_Word16 pitchGain_index[2];
|
||||
|
||||
/* Pitch Lag */
|
||||
WebRtc_Word32 meanGain[2];
|
||||
WebRtc_Word16 pitchIndex[PITCH_SUBFRAMES*2];
|
||||
|
||||
/* LPC */
|
||||
WebRtc_Word32 LPCcoeffs_g[12*2]; /* KLT_ORDER_GAIN = 12 */
|
||||
WebRtc_Word16 LPCindex_s[108*2]; /* KLT_ORDER_SHAPE = 108 */
|
||||
WebRtc_Word16 LPCindex_g[12*2]; /* KLT_ORDER_GAIN = 12 */
|
||||
|
||||
/* Encode Spec */
|
||||
WebRtc_Word16 fre[FRAMESAMPLES];
|
||||
WebRtc_Word16 fim[FRAMESAMPLES];
|
||||
WebRtc_Word16 AvgPitchGain[2];
|
||||
|
||||
/* Used in adaptive mode only */
|
||||
int minBytes;
|
||||
|
||||
} ISAC_SaveEncData_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
Bitstr_enc bitstr_obj;
|
||||
MaskFiltstr_enc maskfiltstr_obj;
|
||||
PreFiltBankstr prefiltbankstr_obj;
|
||||
PitchFiltstr pitchfiltstr_obj;
|
||||
PitchAnalysisStruct pitchanalysisstr_obj;
|
||||
RateModel rate_data_obj;
|
||||
|
||||
WebRtc_Word16 buffer_index;
|
||||
WebRtc_Word16 current_framesamples;
|
||||
|
||||
WebRtc_Word16 data_buffer_fix[FRAMESAMPLES]; // the size was MAX_FRAMESAMPLES
|
||||
|
||||
WebRtc_Word16 frame_nb;
|
||||
WebRtc_Word16 BottleNeck;
|
||||
WebRtc_Word16 MaxDelay;
|
||||
WebRtc_Word16 new_framelength;
|
||||
WebRtc_Word16 s2nr;
|
||||
WebRtc_UWord16 MaxBits;
|
||||
|
||||
WebRtc_Word16 bitstr_seed;
|
||||
#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
PostFiltBankstr interpolatorstr_obj;
|
||||
#endif
|
||||
|
||||
ISAC_SaveEncData_t *SaveEnc_ptr;
|
||||
WebRtc_Word16 payloadLimitBytes30; /* Maximum allowed number of bits for a 30 msec packet */
|
||||
WebRtc_Word16 payloadLimitBytes60; /* Maximum allowed number of bits for a 30 msec packet */
|
||||
WebRtc_Word16 maxPayloadBytes; /* Maximum allowed number of bits for both 30 and 60 msec packet */
|
||||
WebRtc_Word16 maxRateInBytes; /* Maximum allowed rate in bytes per 30 msec packet */
|
||||
WebRtc_Word16 enforceFrameSize; /* If set iSAC will never change packet size */
|
||||
|
||||
} ISACFIX_EncInst_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
Bitstr_dec bitstr_obj;
|
||||
MaskFiltstr_dec maskfiltstr_obj;
|
||||
PostFiltBankstr postfiltbankstr_obj;
|
||||
PitchFiltstr pitchfiltstr_obj;
|
||||
PLCstr plcstr_obj; /* TS; for packet loss concealment */
|
||||
|
||||
#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
|
||||
PreFiltBankstr decimatorstr_obj;
|
||||
#endif
|
||||
|
||||
} ISACFIX_DecInst_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
ISACFIX_EncInst_t ISACenc_obj;
|
||||
ISACFIX_DecInst_t ISACdec_obj;
|
||||
BwEstimatorstr bwestimator_obj;
|
||||
WebRtc_Word16 CodingMode; /* 0 = adaptive; 1 = instantaneous */
|
||||
WebRtc_Word16 errorcode;
|
||||
WebRtc_Word16 initflag; /* 0 = nothing initiated; 1 = encoder or decoder */
|
||||
/* not initiated; 2 = all initiated */
|
||||
} ISACFIX_SubStruct;
|
||||
|
||||
|
||||
typedef struct {
|
||||
WebRtc_Word32 lpcGains[12]; /* 6 lower-band & 6 upper-band we may need to double it for 60*/
|
||||
/* */
|
||||
WebRtc_UWord32 W_upper; /* Upper boundary of interval W */
|
||||
WebRtc_UWord32 streamval;
|
||||
WebRtc_UWord16 stream_index; /* Index to the current position in bytestream */
|
||||
WebRtc_Word16 full; /* 0 - first byte in memory filled, second empty*/
|
||||
/* 1 - both bytes are empty (we just filled the previous memory */
|
||||
WebRtc_UWord16 beforeLastWord;
|
||||
WebRtc_UWord16 lastWord;
|
||||
} transcode_obj;
|
||||
|
||||
|
||||
//Bitstr_enc myBitStr;
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_STRUCTS_H_ */
|
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* WebRtcIsacfix_kTransform.c
|
||||
*
|
||||
* Transform functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fft.h"
|
||||
#include "codec.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
/* Cosine table 1 in Q14 */
|
||||
static const WebRtc_Word16 kCosTab1[FRAMESAMPLES/2] = {
|
||||
16384, 16383, 16378, 16371, 16362, 16349, 16333, 16315, 16294, 16270,
|
||||
16244, 16214, 16182, 16147, 16110, 16069, 16026, 15980, 15931, 15880,
|
||||
15826, 15769, 15709, 15647, 15582, 15515, 15444, 15371, 15296, 15218,
|
||||
15137, 15053, 14968, 14879, 14788, 14694, 14598, 14500, 14399, 14295,
|
||||
14189, 14081, 13970, 13856, 13741, 13623, 13502, 13380, 13255, 13128,
|
||||
12998, 12867, 12733, 12597, 12458, 12318, 12176, 12031, 11885, 11736,
|
||||
11585, 11433, 11278, 11121, 10963, 10803, 10641, 10477, 10311, 10143,
|
||||
9974, 9803, 9630, 9456, 9280, 9102, 8923, 8743, 8561, 8377,
|
||||
8192, 8006, 7818, 7629, 7438, 7246, 7053, 6859, 6664, 6467,
|
||||
6270, 6071, 5872, 5671, 5469, 5266, 5063, 4859, 4653, 4447,
|
||||
4240, 4033, 3825, 3616, 3406, 3196, 2986, 2775, 2563, 2351,
|
||||
2139, 1926, 1713, 1499, 1285, 1072, 857, 643, 429, 214,
|
||||
0, -214, -429, -643, -857, -1072, -1285, -1499, -1713, -1926,
|
||||
-2139, -2351, -2563, -2775, -2986, -3196, -3406, -3616, -3825, -4033,
|
||||
-4240, -4447, -4653, -4859, -5063, -5266, -5469, -5671, -5872, -6071,
|
||||
-6270, -6467, -6664, -6859, -7053, -7246, -7438, -7629, -7818, -8006,
|
||||
-8192, -8377, -8561, -8743, -8923, -9102, -9280, -9456, -9630, -9803,
|
||||
-9974, -10143, -10311, -10477, -10641, -10803, -10963, -11121, -11278, -11433,
|
||||
-11585, -11736, -11885, -12031, -12176, -12318, -12458, -12597, -12733, -12867,
|
||||
-12998, -13128, -13255, -13380, -13502, -13623, -13741, -13856, -13970, -14081,
|
||||
-14189, -14295, -14399, -14500, -14598, -14694, -14788, -14879, -14968, -15053,
|
||||
-15137, -15218, -15296, -15371, -15444, -15515, -15582, -15647, -15709, -15769,
|
||||
-15826, -15880, -15931, -15980, -16026, -16069, -16110, -16147, -16182, -16214,
|
||||
-16244, -16270, -16294, -16315, -16333, -16349, -16362, -16371, -16378, -16383
|
||||
};
|
||||
|
||||
|
||||
/* Sine table 1 in Q14 */
|
||||
static const WebRtc_Word16 kSinTab1[FRAMESAMPLES/2] = {
|
||||
0, 214, 429, 643, 857, 1072, 1285, 1499, 1713, 1926,
|
||||
2139, 2351, 2563, 2775, 2986, 3196, 3406, 3616, 3825, 4033,
|
||||
4240, 4447, 4653, 4859, 5063, 5266, 5469, 5671, 5872, 6071,
|
||||
6270, 6467, 6664, 6859, 7053, 7246, 7438, 7629, 7818, 8006,
|
||||
8192, 8377, 8561, 8743, 8923, 9102, 9280, 9456, 9630, 9803,
|
||||
9974, 10143, 10311, 10477, 10641, 10803, 10963, 11121, 11278, 11433,
|
||||
11585, 11736, 11885, 12031, 12176, 12318, 12458, 12597, 12733, 12867,
|
||||
12998, 13128, 13255, 13380, 13502, 13623, 13741, 13856, 13970, 14081,
|
||||
14189, 14295, 14399, 14500, 14598, 14694, 14788, 14879, 14968, 15053,
|
||||
15137, 15218, 15296, 15371, 15444, 15515, 15582, 15647, 15709, 15769,
|
||||
15826, 15880, 15931, 15980, 16026, 16069, 16110, 16147, 16182, 16214,
|
||||
16244, 16270, 16294, 16315, 16333, 16349, 16362, 16371, 16378, 16383,
|
||||
16384, 16383, 16378, 16371, 16362, 16349, 16333, 16315, 16294, 16270,
|
||||
16244, 16214, 16182, 16147, 16110, 16069, 16026, 15980, 15931, 15880,
|
||||
15826, 15769, 15709, 15647, 15582, 15515, 15444, 15371, 15296, 15218,
|
||||
15137, 15053, 14968, 14879, 14788, 14694, 14598, 14500, 14399, 14295,
|
||||
14189, 14081, 13970, 13856, 13741, 13623, 13502, 13380, 13255, 13128,
|
||||
12998, 12867, 12733, 12597, 12458, 12318, 12176, 12031, 11885, 11736,
|
||||
11585, 11433, 11278, 11121, 10963, 10803, 10641, 10477, 10311, 10143,
|
||||
9974, 9803, 9630, 9456, 9280, 9102, 8923, 8743, 8561, 8377,
|
||||
8192, 8006, 7818, 7629, 7438, 7246, 7053, 6859, 6664, 6467,
|
||||
6270, 6071, 5872, 5671, 5469, 5266, 5063, 4859, 4653, 4447,
|
||||
4240, 4033, 3825, 3616, 3406, 3196, 2986, 2775, 2563, 2351,
|
||||
2139, 1926, 1713, 1499, 1285, 1072, 857, 643, 429, 214
|
||||
};
|
||||
|
||||
|
||||
/* Cosine table 2 in Q14 */
|
||||
static const WebRtc_Word16 kCosTab2[FRAMESAMPLES/4] = {
|
||||
107, -322, 536, -750, 965, -1179, 1392, -1606, 1819, -2032,
|
||||
2245, -2457, 2669, -2880, 3091, -3301, 3511, -3720, 3929, -4137,
|
||||
4344, -4550, 4756, -4961, 5165, -5368, 5570, -5771, 5971, -6171,
|
||||
6369, -6566, 6762, -6957, 7150, -7342, 7534, -7723, 7912, -8099,
|
||||
8285, -8469, 8652, -8833, 9013, -9191, 9368, -9543, 9717, -9889,
|
||||
10059, -10227, 10394, -10559, 10722, -10883, 11042, -11200, 11356, -11509,
|
||||
11661, -11810, 11958, -12104, 12247, -12389, 12528, -12665, 12800, -12933,
|
||||
13063, -13192, 13318, -13441, 13563, -13682, 13799, -13913, 14025, -14135,
|
||||
14242, -14347, 14449, -14549, 14647, -14741, 14834, -14924, 15011, -15095,
|
||||
15178, -15257, 15334, -15408, 15480, -15549, 15615, -15679, 15739, -15798,
|
||||
15853, -15906, 15956, -16003, 16048, -16090, 16129, -16165, 16199, -16229,
|
||||
16257, -16283, 16305, -16325, 16342, -16356, 16367, -16375, 16381, -16384
|
||||
};
|
||||
|
||||
|
||||
/* Sine table 2 in Q14 */
|
||||
static const WebRtc_Word16 kSinTab2[FRAMESAMPLES/4] = {
|
||||
16384, -16381, 16375, -16367, 16356, -16342, 16325, -16305, 16283, -16257,
|
||||
16229, -16199, 16165, -16129, 16090, -16048, 16003, -15956, 15906, -15853,
|
||||
15798, -15739, 15679, -15615, 15549, -15480, 15408, -15334, 15257, -15178,
|
||||
15095, -15011, 14924, -14834, 14741, -14647, 14549, -14449, 14347, -14242,
|
||||
14135, -14025, 13913, -13799, 13682, -13563, 13441, -13318, 13192, -13063,
|
||||
12933, -12800, 12665, -12528, 12389, -12247, 12104, -11958, 11810, -11661,
|
||||
11509, -11356, 11200, -11042, 10883, -10722, 10559, -10394, 10227, -10059,
|
||||
9889, -9717, 9543, -9368, 9191, -9013, 8833, -8652, 8469, -8285,
|
||||
8099, -7912, 7723, -7534, 7342, -7150, 6957, -6762, 6566, -6369,
|
||||
6171, -5971, 5771, -5570, 5368, -5165, 4961, -4756, 4550, -4344,
|
||||
4137, -3929, 3720, -3511, 3301, -3091, 2880, -2669, 2457, -2245,
|
||||
2032, -1819, 1606, -1392, 1179, -965, 750, -536, 322, -107
|
||||
};
|
||||
|
||||
|
||||
|
||||
void WebRtcIsacfix_Time2Spec(WebRtc_Word16 *inre1Q9,
|
||||
WebRtc_Word16 *inre2Q9,
|
||||
WebRtc_Word16 *outreQ7,
|
||||
WebRtc_Word16 *outimQ7)
|
||||
{
|
||||
|
||||
int k;
|
||||
WebRtc_Word32 tmpreQ16[FRAMESAMPLES/2], tmpimQ16[FRAMESAMPLES/2];
|
||||
WebRtc_Word16 tmp1rQ14, tmp1iQ14;
|
||||
WebRtc_Word32 xrQ16, xiQ16, yrQ16, yiQ16;
|
||||
WebRtc_Word32 v1Q16, v2Q16;
|
||||
WebRtc_Word16 factQ19, sh;
|
||||
|
||||
/* Multiply with complex exponentials and combine into one complex vector */
|
||||
factQ19 = 16921; // 0.5/sqrt(240) in Q19 is round(.5/sqrt(240)*(2^19)) = 16921
|
||||
for (k = 0; k < FRAMESAMPLES/2; k++) {
|
||||
tmp1rQ14 = kCosTab1[k];
|
||||
tmp1iQ14 = kSinTab1[k];
|
||||
xrQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre1Q9[k]) + WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre2Q9[k]), 7);
|
||||
xiQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre2Q9[k]) - WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre1Q9[k]), 7);
|
||||
tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xrQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16
|
||||
tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xiQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16
|
||||
}
|
||||
|
||||
|
||||
xrQ16 = WebRtcSpl_MaxAbsValueW32(tmpreQ16, FRAMESAMPLES/2);
|
||||
yrQ16 = WebRtcSpl_MaxAbsValueW32(tmpimQ16, FRAMESAMPLES/2);
|
||||
if (yrQ16>xrQ16) {
|
||||
xrQ16 = yrQ16;
|
||||
}
|
||||
|
||||
sh = WebRtcSpl_NormW32(xrQ16);
|
||||
sh = sh-24; //if sh becomes >=0, then we should shift sh steps to the left, and the domain will become Q(16+sh)
|
||||
//if sh becomes <0, then we should shift -sh steps to the right, and the domain will become Q(16+sh)
|
||||
|
||||
//"Fastest" vectors
|
||||
if (sh>=0) {
|
||||
for (k=0; k<FRAMESAMPLES/2; k++) {
|
||||
inre1Q9[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmpreQ16[k], sh); //Q(16+sh)
|
||||
inre2Q9[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmpimQ16[k], sh); //Q(16+sh)
|
||||
}
|
||||
} else {
|
||||
WebRtc_Word32 round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, -sh-1);
|
||||
for (k=0; k<FRAMESAMPLES/2; k++) {
|
||||
inre1Q9[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpreQ16[k]+round, -sh); //Q(16+sh)
|
||||
inre2Q9[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpimQ16[k]+round, -sh); //Q(16+sh)
|
||||
}
|
||||
}
|
||||
|
||||
/* Get DFT */
|
||||
WebRtcIsacfix_FftRadix16Fastest(inre1Q9, inre2Q9, -1); // real call
|
||||
|
||||
//"Fastest" vectors
|
||||
if (sh>=0) {
|
||||
for (k=0; k<FRAMESAMPLES/2; k++) {
|
||||
tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inre1Q9[k], sh); //Q(16+sh) -> Q16
|
||||
tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inre2Q9[k], sh); //Q(16+sh) -> Q16
|
||||
}
|
||||
} else {
|
||||
for (k=0; k<FRAMESAMPLES/2; k++) {
|
||||
tmpreQ16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inre1Q9[k], -sh); //Q(16+sh) -> Q16
|
||||
tmpimQ16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inre2Q9[k], -sh); //Q(16+sh) -> Q16
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Use symmetry to separate into two complex vectors and center frames in time around zero */
|
||||
for (k = 0; k < FRAMESAMPLES/4; k++) {
|
||||
xrQ16 = tmpreQ16[k] + tmpreQ16[FRAMESAMPLES/2 - 1 - k];
|
||||
yiQ16 = -tmpreQ16[k] + tmpreQ16[FRAMESAMPLES/2 - 1 - k];
|
||||
xiQ16 = tmpimQ16[k] - tmpimQ16[FRAMESAMPLES/2 - 1 - k];
|
||||
yrQ16 = tmpimQ16[k] + tmpimQ16[FRAMESAMPLES/2 - 1 - k];
|
||||
tmp1rQ14 = kCosTab2[k];
|
||||
tmp1iQ14 = kSinTab2[k];
|
||||
v1Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xiQ16);
|
||||
v2Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xiQ16);
|
||||
outreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(v1Q16, 9);
|
||||
outimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(v2Q16, 9);
|
||||
v1Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yiQ16);
|
||||
v2Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yiQ16);
|
||||
outreQ7[FRAMESAMPLES/2 - 1 - k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(v1Q16, 9); //CalcLrIntQ(v1Q16, 9);
|
||||
outimQ7[FRAMESAMPLES/2 - 1 - k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(v2Q16, 9); //CalcLrIntQ(v2Q16, 9);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsacfix_Spec2Time(WebRtc_Word16 *inreQ7, WebRtc_Word16 *inimQ7, WebRtc_Word32 *outre1Q16, WebRtc_Word32 *outre2Q16)
|
||||
{
|
||||
|
||||
int k;
|
||||
WebRtc_Word16 tmp1rQ14, tmp1iQ14;
|
||||
WebRtc_Word32 xrQ16, xiQ16, yrQ16, yiQ16;
|
||||
WebRtc_Word32 tmpInRe, tmpInIm, tmpInRe2, tmpInIm2;
|
||||
WebRtc_Word16 factQ11;
|
||||
WebRtc_Word16 sh;
|
||||
|
||||
for (k = 0; k < FRAMESAMPLES/4; k++) {
|
||||
/* Move zero in time to beginning of frames */
|
||||
tmp1rQ14 = kCosTab2[k];
|
||||
tmp1iQ14 = kSinTab2[k];
|
||||
|
||||
tmpInRe = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inreQ7[k], 9); // Q7 -> Q16
|
||||
tmpInIm = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inimQ7[k], 9); // Q7 -> Q16
|
||||
tmpInRe2 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inreQ7[FRAMESAMPLES/2 - 1 - k], 9); // Q7 -> Q16
|
||||
tmpInIm2 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inimQ7[FRAMESAMPLES/2 - 1 - k], 9); // Q7 -> Q16
|
||||
|
||||
xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInRe) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInIm);
|
||||
xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInIm) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInRe);
|
||||
yrQ16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInIm2) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInRe2);
|
||||
yiQ16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInRe2) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInIm2);
|
||||
|
||||
/* Combine into one vector, z = x + j * y */
|
||||
outre1Q16[k] = xrQ16 - yiQ16;
|
||||
outre1Q16[FRAMESAMPLES/2 - 1 - k] = xrQ16 + yiQ16;
|
||||
outre2Q16[k] = xiQ16 + yrQ16;
|
||||
outre2Q16[FRAMESAMPLES/2 - 1 - k] = -xiQ16 + yrQ16;
|
||||
}
|
||||
|
||||
/* Get IDFT */
|
||||
tmpInRe = WebRtcSpl_MaxAbsValueW32(outre1Q16, 240);
|
||||
tmpInIm = WebRtcSpl_MaxAbsValueW32(outre2Q16, 240);
|
||||
if (tmpInIm>tmpInRe) {
|
||||
tmpInRe = tmpInIm;
|
||||
}
|
||||
|
||||
sh = WebRtcSpl_NormW32(tmpInRe);
|
||||
sh = sh-24; //if sh becomes >=0, then we should shift sh steps to the left, and the domain will become Q(16+sh)
|
||||
//if sh becomes <0, then we should shift -sh steps to the right, and the domain will become Q(16+sh)
|
||||
|
||||
//"Fastest" vectors
|
||||
if (sh>=0) {
|
||||
for (k=0; k<240; k++) {
|
||||
inreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(outre1Q16[k], sh); //Q(16+sh)
|
||||
inimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(outre2Q16[k], sh); //Q(16+sh)
|
||||
}
|
||||
} else {
|
||||
WebRtc_Word32 round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, -sh-1);
|
||||
for (k=0; k<240; k++) {
|
||||
inreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(outre1Q16[k]+round, -sh); //Q(16+sh)
|
||||
inimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(outre2Q16[k]+round, -sh); //Q(16+sh)
|
||||
}
|
||||
}
|
||||
|
||||
WebRtcIsacfix_FftRadix16Fastest(inreQ7, inimQ7, 1); // real call
|
||||
|
||||
//"Fastest" vectors
|
||||
if (sh>=0) {
|
||||
for (k=0; k<240; k++) {
|
||||
outre1Q16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inreQ7[k], sh); //Q(16+sh) -> Q16
|
||||
outre2Q16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inimQ7[k], sh); //Q(16+sh) -> Q16
|
||||
}
|
||||
} else {
|
||||
for (k=0; k<240; k++) {
|
||||
outre1Q16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inreQ7[k], -sh); //Q(16+sh) -> Q16
|
||||
outre2Q16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inimQ7[k], -sh); //Q(16+sh) -> Q16
|
||||
}
|
||||
}
|
||||
|
||||
/* Divide through by the normalizing constant: */
|
||||
/* scale all values with 1/240, i.e. with 273 in Q16 */
|
||||
/* 273/65536 ~= 0.0041656 */
|
||||
/* 1/240 ~= 0.0041666 */
|
||||
for (k=0; k<240; k++) {
|
||||
outre1Q16[k] = WEBRTC_SPL_MUL_16_32_RSFT16(273, outre1Q16[k]);
|
||||
outre2Q16[k] = WEBRTC_SPL_MUL_16_32_RSFT16(273, outre2Q16[k]);
|
||||
}
|
||||
|
||||
/* Demodulate and separate */
|
||||
factQ11 = 31727; // sqrt(240) in Q11 is round(15.49193338482967*2048) = 31727
|
||||
for (k = 0; k < FRAMESAMPLES/2; k++) {
|
||||
tmp1rQ14 = kCosTab1[k];
|
||||
tmp1iQ14 = kSinTab1[k];
|
||||
xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, outre1Q16[k]) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, outre2Q16[k]);
|
||||
xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, outre2Q16[k]) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, outre1Q16[k]);
|
||||
xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xrQ16);
|
||||
xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xiQ16);
|
||||
outre2Q16[k] = xiQ16;
|
||||
outre1Q16[k] = xrQ16;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "arith_routines.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
/*
|
||||
* terminate and return byte stream;
|
||||
* returns the number of bytes in the stream
|
||||
*/
|
||||
int WebRtcIsac_EncTerminate(Bitstr *streamdata) /* in-/output struct containing bitstream */
|
||||
{
|
||||
WebRtc_UWord8 *stream_ptr;
|
||||
|
||||
|
||||
/* point to the right place in the stream buffer */
|
||||
stream_ptr = streamdata->stream + streamdata->stream_index;
|
||||
|
||||
/* find minimum length (determined by current interval width) */
|
||||
if ( streamdata->W_upper > 0x01FFFFFF )
|
||||
{
|
||||
streamdata->streamval += 0x01000000;
|
||||
/* add carry to buffer */
|
||||
if (streamdata->streamval < 0x01000000)
|
||||
{
|
||||
/* propagate carry */
|
||||
while ( !(++(*--stream_ptr)) );
|
||||
/* put pointer back to the old value */
|
||||
stream_ptr = streamdata->stream + streamdata->stream_index;
|
||||
}
|
||||
/* write remaining data to bitstream */
|
||||
*stream_ptr++ = (WebRtc_UWord8) (streamdata->streamval >> 24);
|
||||
}
|
||||
else
|
||||
{
|
||||
streamdata->streamval += 0x00010000;
|
||||
/* add carry to buffer */
|
||||
if (streamdata->streamval < 0x00010000)
|
||||
{
|
||||
/* propagate carry */
|
||||
while ( !(++(*--stream_ptr)) );
|
||||
/* put pointer back to the old value */
|
||||
stream_ptr = streamdata->stream + streamdata->stream_index;
|
||||
}
|
||||
/* write remaining data to bitstream */
|
||||
*stream_ptr++ = (WebRtc_UWord8) (streamdata->streamval >> 24);
|
||||
*stream_ptr++ = (WebRtc_UWord8) ((streamdata->streamval >> 16) & 0x00FF);
|
||||
}
|
||||
|
||||
/* calculate stream length */
|
||||
return (int)(stream_ptr - streamdata->stream);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* arith_routines.h
|
||||
*
|
||||
* Functions for arithmetic coding.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ARITH_ROUTINES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ARITH_ROUTINES_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
int WebRtcIsac_EncLogisticMulti2(
|
||||
Bitstr *streamdata, /* in-/output struct containing bitstream */
|
||||
WebRtc_Word16 *dataQ7, /* input: data vector */
|
||||
const WebRtc_UWord16 *env, /* input: side info vector defining the width of the pdf */
|
||||
const int N, /* input: data vector length */
|
||||
const WebRtc_Word16 isSWB12kHz); /* if the codec is working in 12kHz bandwidth */
|
||||
|
||||
/* returns the number of bytes in the stream */
|
||||
int WebRtcIsac_EncTerminate(Bitstr *streamdata); /* in-/output struct containing bitstream */
|
||||
|
||||
/* returns the number of bytes in the stream so far */
|
||||
int WebRtcIsac_DecLogisticMulti2(
|
||||
WebRtc_Word16 *data, /* output: data vector */
|
||||
Bitstr *streamdata, /* in-/output struct containing bitstream */
|
||||
const WebRtc_UWord16 *env, /* input: side info vector defining the width of the pdf */
|
||||
const WebRtc_Word16 *dither, /* input: dither vector */
|
||||
const int N, /* input: data vector length */
|
||||
const WebRtc_Word16 isSWB12kHz); /* if the codec is working in 12kHz bandwidth */
|
||||
|
||||
void WebRtcIsac_EncHistMulti(
|
||||
Bitstr *streamdata, /* in-/output struct containing bitstream */
|
||||
const int *data, /* input: data vector */
|
||||
const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */
|
||||
const int N); /* input: data vector length */
|
||||
|
||||
int WebRtcIsac_DecHistBisectMulti(
|
||||
int *data, /* output: data vector */
|
||||
Bitstr *streamdata, /* in-/output struct containing bitstream */
|
||||
const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */
|
||||
const WebRtc_UWord16 *cdf_size, /* input: array of cdf table sizes+1 (power of two: 2^k) */
|
||||
const int N); /* input: data vector length */
|
||||
|
||||
int WebRtcIsac_DecHistOneStepMulti(
|
||||
int *data, /* output: data vector */
|
||||
Bitstr *streamdata, /* in-/output struct containing bitstream */
|
||||
const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */
|
||||
const WebRtc_UWord16 *init_index,/* input: vector of initial cdf table search entries */
|
||||
const int N); /* input: data vector length */
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ARITH_ROUTINES_H_ */
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
#include "arith_routines.h"
|
||||
|
||||
|
||||
/*
|
||||
* code symbols into arithmetic bytestream
|
||||
*/
|
||||
void WebRtcIsac_EncHistMulti(Bitstr *streamdata, /* in-/output struct containing bitstream */
|
||||
const int *data, /* input: data vector */
|
||||
const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */
|
||||
const int N) /* input: data vector length */
|
||||
{
|
||||
WebRtc_UWord32 W_lower, W_upper;
|
||||
WebRtc_UWord32 W_upper_LSB, W_upper_MSB;
|
||||
WebRtc_UWord8 *stream_ptr;
|
||||
WebRtc_UWord8 *stream_ptr_carry;
|
||||
WebRtc_UWord32 cdf_lo, cdf_hi;
|
||||
int k;
|
||||
|
||||
|
||||
/* point to beginning of stream buffer */
|
||||
stream_ptr = streamdata->stream + streamdata->stream_index;
|
||||
W_upper = streamdata->W_upper;
|
||||
|
||||
for (k=N; k>0; k--)
|
||||
{
|
||||
/* fetch cdf_lower and cdf_upper from cdf tables */
|
||||
cdf_lo = (WebRtc_UWord32) *(*cdf + *data);
|
||||
cdf_hi = (WebRtc_UWord32) *(*cdf++ + *data++ + 1);
|
||||
|
||||
/* update interval */
|
||||
W_upper_LSB = W_upper & 0x0000FFFF;
|
||||
W_upper_MSB = W_upper >> 16;
|
||||
W_lower = W_upper_MSB * cdf_lo;
|
||||
W_lower += (W_upper_LSB * cdf_lo) >> 16;
|
||||
W_upper = W_upper_MSB * cdf_hi;
|
||||
W_upper += (W_upper_LSB * cdf_hi) >> 16;
|
||||
|
||||
/* shift interval such that it begins at zero */
|
||||
W_upper -= ++W_lower;
|
||||
|
||||
/* add integer to bitstream */
|
||||
streamdata->streamval += W_lower;
|
||||
|
||||
/* handle carry */
|
||||
if (streamdata->streamval < W_lower)
|
||||
{
|
||||
/* propagate carry */
|
||||
stream_ptr_carry = stream_ptr;
|
||||
while (!(++(*--stream_ptr_carry)));
|
||||
}
|
||||
|
||||
/* renormalize interval, store most significant byte of streamval and update streamval */
|
||||
while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */
|
||||
{
|
||||
W_upper <<= 8;
|
||||
*stream_ptr++ = (WebRtc_UWord8) (streamdata->streamval >> 24);
|
||||
streamdata->streamval <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate new stream_index */
|
||||
streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
|
||||
streamdata->W_upper = W_upper;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* function to decode more symbols from the arithmetic bytestream, using method of bisection
|
||||
* cdf tables should be of size 2^k-1 (which corresponds to an alphabet size of 2^k-2)
|
||||
*/
|
||||
int WebRtcIsac_DecHistBisectMulti(int *data, /* output: data vector */
|
||||
Bitstr *streamdata, /* in-/output struct containing bitstream */
|
||||
const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */
|
||||
const WebRtc_UWord16 *cdf_size, /* input: array of cdf table sizes+1 (power of two: 2^k) */
|
||||
const int N) /* input: data vector length */
|
||||
{
|
||||
WebRtc_UWord32 W_lower, W_upper;
|
||||
WebRtc_UWord32 W_tmp;
|
||||
WebRtc_UWord32 W_upper_LSB, W_upper_MSB;
|
||||
WebRtc_UWord32 streamval;
|
||||
const WebRtc_UWord8 *stream_ptr;
|
||||
const WebRtc_UWord16 *cdf_ptr;
|
||||
int size_tmp;
|
||||
int k;
|
||||
|
||||
W_lower = 0; //to remove warning -DH
|
||||
stream_ptr = streamdata->stream + streamdata->stream_index;
|
||||
W_upper = streamdata->W_upper;
|
||||
if (W_upper == 0)
|
||||
/* Should not be possible in normal operation */
|
||||
return -2;
|
||||
|
||||
if (streamdata->stream_index == 0) /* first time decoder is called for this stream */
|
||||
{
|
||||
/* read first word from bytestream */
|
||||
streamval = *stream_ptr << 24;
|
||||
streamval |= *++stream_ptr << 16;
|
||||
streamval |= *++stream_ptr << 8;
|
||||
streamval |= *++stream_ptr;
|
||||
} else {
|
||||
streamval = streamdata->streamval;
|
||||
}
|
||||
|
||||
for (k=N; k>0; k--)
|
||||
{
|
||||
/* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
|
||||
W_upper_LSB = W_upper & 0x0000FFFF;
|
||||
W_upper_MSB = W_upper >> 16;
|
||||
|
||||
/* start halfway the cdf range */
|
||||
size_tmp = *cdf_size++ >> 1;
|
||||
cdf_ptr = *cdf + (size_tmp - 1);
|
||||
|
||||
/* method of bisection */
|
||||
for ( ;; )
|
||||
{
|
||||
W_tmp = W_upper_MSB * *cdf_ptr;
|
||||
W_tmp += (W_upper_LSB * *cdf_ptr) >> 16;
|
||||
size_tmp >>= 1;
|
||||
if (size_tmp == 0) break;
|
||||
if (streamval > W_tmp)
|
||||
{
|
||||
W_lower = W_tmp;
|
||||
cdf_ptr += size_tmp;
|
||||
} else {
|
||||
W_upper = W_tmp;
|
||||
cdf_ptr -= size_tmp;
|
||||
}
|
||||
}
|
||||
if (streamval > W_tmp)
|
||||
{
|
||||
W_lower = W_tmp;
|
||||
*data++ = (int)(cdf_ptr - *cdf++);
|
||||
} else {
|
||||
W_upper = W_tmp;
|
||||
*data++ = (int)(cdf_ptr - *cdf++ - 1);
|
||||
}
|
||||
|
||||
/* shift interval to start at zero */
|
||||
W_upper -= ++W_lower;
|
||||
|
||||
/* add integer to bitstream */
|
||||
streamval -= W_lower;
|
||||
|
||||
/* renormalize interval and update streamval */
|
||||
while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */
|
||||
{
|
||||
/* read next byte from stream */
|
||||
streamval = (streamval << 8) | *++stream_ptr;
|
||||
W_upper <<= 8;
|
||||
}
|
||||
|
||||
if (W_upper == 0)
|
||||
/* Should not be possible in normal operation */
|
||||
return -2;
|
||||
|
||||
|
||||
}
|
||||
|
||||
streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
|
||||
streamdata->W_upper = W_upper;
|
||||
streamdata->streamval = streamval;
|
||||
|
||||
|
||||
/* find number of bytes in original stream (determined by current interval width) */
|
||||
if ( W_upper > 0x01FFFFFF )
|
||||
return streamdata->stream_index - 2;
|
||||
else
|
||||
return streamdata->stream_index - 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* function to decode more symbols from the arithmetic bytestream, taking single step up or
|
||||
* down at a time
|
||||
* cdf tables can be of arbitrary size, but large tables may take a lot of iterations
|
||||
*/
|
||||
int WebRtcIsac_DecHistOneStepMulti(int *data, /* output: data vector */
|
||||
Bitstr *streamdata, /* in-/output struct containing bitstream */
|
||||
const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */
|
||||
const WebRtc_UWord16 *init_index, /* input: vector of initial cdf table search entries */
|
||||
const int N) /* input: data vector length */
|
||||
{
|
||||
WebRtc_UWord32 W_lower, W_upper;
|
||||
WebRtc_UWord32 W_tmp;
|
||||
WebRtc_UWord32 W_upper_LSB, W_upper_MSB;
|
||||
WebRtc_UWord32 streamval;
|
||||
const WebRtc_UWord8 *stream_ptr;
|
||||
const WebRtc_UWord16 *cdf_ptr;
|
||||
int k;
|
||||
|
||||
|
||||
stream_ptr = streamdata->stream + streamdata->stream_index;
|
||||
W_upper = streamdata->W_upper;
|
||||
if (W_upper == 0)
|
||||
/* Should not be possible in normal operation */
|
||||
return -2;
|
||||
|
||||
if (streamdata->stream_index == 0) /* first time decoder is called for this stream */
|
||||
{
|
||||
/* read first word from bytestream */
|
||||
streamval = *stream_ptr << 24;
|
||||
streamval |= *++stream_ptr << 16;
|
||||
streamval |= *++stream_ptr << 8;
|
||||
streamval |= *++stream_ptr;
|
||||
} else {
|
||||
streamval = streamdata->streamval;
|
||||
}
|
||||
|
||||
|
||||
for (k=N; k>0; k--)
|
||||
{
|
||||
/* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
|
||||
W_upper_LSB = W_upper & 0x0000FFFF;
|
||||
W_upper_MSB = W_upper >> 16;
|
||||
|
||||
/* start at the specified table entry */
|
||||
cdf_ptr = *cdf + (*init_index++);
|
||||
W_tmp = W_upper_MSB * *cdf_ptr;
|
||||
W_tmp += (W_upper_LSB * *cdf_ptr) >> 16;
|
||||
if (streamval > W_tmp)
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
W_lower = W_tmp;
|
||||
if (cdf_ptr[0]==65535)
|
||||
/* range check */
|
||||
return -3;
|
||||
W_tmp = W_upper_MSB * *++cdf_ptr;
|
||||
W_tmp += (W_upper_LSB * *cdf_ptr) >> 16;
|
||||
if (streamval <= W_tmp) break;
|
||||
}
|
||||
W_upper = W_tmp;
|
||||
*data++ = (int)(cdf_ptr - *cdf++ - 1);
|
||||
} else {
|
||||
for ( ;; )
|
||||
{
|
||||
W_upper = W_tmp;
|
||||
--cdf_ptr;
|
||||
if (cdf_ptr<*cdf) {
|
||||
/* range check */
|
||||
return -3;
|
||||
}
|
||||
W_tmp = W_upper_MSB * *cdf_ptr;
|
||||
W_tmp += (W_upper_LSB * *cdf_ptr) >> 16;
|
||||
if (streamval > W_tmp) break;
|
||||
}
|
||||
W_lower = W_tmp;
|
||||
*data++ = (int)(cdf_ptr - *cdf++);
|
||||
}
|
||||
|
||||
/* shift interval to start at zero */
|
||||
W_upper -= ++W_lower;
|
||||
/* add integer to bitstream */
|
||||
streamval -= W_lower;
|
||||
|
||||
/* renormalize interval and update streamval */
|
||||
while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */
|
||||
{
|
||||
/* read next byte from stream */
|
||||
streamval = (streamval << 8) | *++stream_ptr;
|
||||
W_upper <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
|
||||
streamdata->W_upper = W_upper;
|
||||
streamdata->streamval = streamval;
|
||||
|
||||
|
||||
/* find number of bytes in original stream (determined by current interval width) */
|
||||
if ( W_upper > 0x01FFFFFF )
|
||||
return streamdata->stream_index - 2;
|
||||
else
|
||||
return streamdata->stream_index - 1;
|
||||
}
|
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* arith_routines.h
|
||||
*
|
||||
* This file contains functions for arithmatically encoding and
|
||||
* decoding DFT coefficients.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "arith_routines.h"
|
||||
|
||||
|
||||
|
||||
static const WebRtc_Word32 kHistEdgesQ15[51] = {
|
||||
-327680, -314573, -301466, -288359, -275252, -262144, -249037, -235930, -222823, -209716,
|
||||
-196608, -183501, -170394, -157287, -144180, -131072, -117965, -104858, -91751, -78644,
|
||||
-65536, -52429, -39322, -26215, -13108, 0, 13107, 26214, 39321, 52428,
|
||||
65536, 78643, 91750, 104857, 117964, 131072, 144179, 157286, 170393, 183500,
|
||||
196608, 209715, 222822, 235929, 249036, 262144, 275251, 288358, 301465, 314572,
|
||||
327680};
|
||||
|
||||
|
||||
static const int kCdfSlopeQ0[51] = { /* Q0 */
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 13, 23, 47, 87, 154, 315, 700, 1088,
|
||||
2471, 6064, 14221, 21463, 36634, 36924, 19750, 13270, 5806, 2312,
|
||||
1095, 660, 316, 145, 86, 41, 32, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 0};
|
||||
|
||||
|
||||
static const int kCdfQ16[51] = { /* Q16 */
|
||||
0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
|
||||
20, 22, 24, 29, 38, 57, 92, 153, 279, 559,
|
||||
994, 1983, 4408, 10097, 18682, 33336, 48105, 56005, 61313, 63636,
|
||||
64560, 64998, 65262, 65389, 65447, 65481, 65497, 65510, 65512, 65514,
|
||||
65516, 65518, 65520, 65522, 65524, 65526, 65528, 65530, 65532, 65534,
|
||||
65535};
|
||||
|
||||
|
||||
|
||||
/* function to be converted to fixed point */
|
||||
static __inline WebRtc_UWord32 piecewise(WebRtc_Word32 xinQ15) {
|
||||
|
||||
WebRtc_Word32 ind, qtmp1, qtmp2, qtmp3;
|
||||
WebRtc_UWord32 tmpUW32;
|
||||
|
||||
|
||||
qtmp2 = xinQ15;
|
||||
|
||||
if (qtmp2 < kHistEdgesQ15[0]) {
|
||||
qtmp2 = kHistEdgesQ15[0];
|
||||
}
|
||||
if (qtmp2 > kHistEdgesQ15[50]) {
|
||||
qtmp2 = kHistEdgesQ15[50];
|
||||
}
|
||||
|
||||
qtmp1 = qtmp2 - kHistEdgesQ15[0]; /* Q15 - Q15 = Q15 */
|
||||
ind = (qtmp1 * 5) >> 16; /* 2^16 / 5 = 0.4 in Q15 */
|
||||
/* Q15 -> Q0 */
|
||||
qtmp1 = qtmp2 - kHistEdgesQ15[ind]; /* Q15 - Q15 = Q15 */
|
||||
qtmp2 = kCdfSlopeQ0[ind] * qtmp1; /* Q0 * Q15 = Q15 */
|
||||
qtmp3 = qtmp2>>15; /* Q15 -> Q0 */
|
||||
|
||||
tmpUW32 = kCdfQ16[ind] + qtmp3; /* Q0 + Q0 = Q0 */
|
||||
return tmpUW32;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int WebRtcIsac_EncLogisticMulti2(
|
||||
Bitstr *streamdata, /* in-/output struct containing bitstream */
|
||||
WebRtc_Word16 *dataQ7, /* input: data vector */
|
||||
const WebRtc_UWord16 *envQ8, /* input: side info vector defining the width of the pdf */
|
||||
const int N, /* input: data vector length / 2 */
|
||||
const WebRtc_Word16 isSWB12kHz)
|
||||
{
|
||||
WebRtc_UWord32 W_lower, W_upper;
|
||||
WebRtc_UWord32 W_upper_LSB, W_upper_MSB;
|
||||
WebRtc_UWord8 *stream_ptr;
|
||||
WebRtc_UWord8 *maxStreamPtr;
|
||||
WebRtc_UWord8 *stream_ptr_carry;
|
||||
WebRtc_UWord32 cdf_lo, cdf_hi;
|
||||
int k;
|
||||
|
||||
/* point to beginning of stream buffer */
|
||||
stream_ptr = streamdata->stream + streamdata->stream_index;
|
||||
W_upper = streamdata->W_upper;
|
||||
|
||||
maxStreamPtr = streamdata->stream + STREAM_SIZE_MAX_60 - 1;
|
||||
for (k = 0; k < N; k++)
|
||||
{
|
||||
/* compute cdf_lower and cdf_upper by evaluating the piecewise linear cdf */
|
||||
cdf_lo = piecewise((*dataQ7 - 64) * *envQ8);
|
||||
cdf_hi = piecewise((*dataQ7 + 64) * *envQ8);
|
||||
|
||||
/* test and clip if probability gets too small */
|
||||
while (cdf_lo+1 >= cdf_hi) {
|
||||
/* clip */
|
||||
if (*dataQ7 > 0) {
|
||||
*dataQ7 -= 128;
|
||||
cdf_hi = cdf_lo;
|
||||
cdf_lo = piecewise((*dataQ7 - 64) * *envQ8);
|
||||
} else {
|
||||
*dataQ7 += 128;
|
||||
cdf_lo = cdf_hi;
|
||||
cdf_hi = piecewise((*dataQ7 + 64) * *envQ8);
|
||||
}
|
||||
}
|
||||
|
||||
dataQ7++;
|
||||
// increment only once per 4 iterations for SWB-16kHz or WB
|
||||
// increment only once per 2 iterations for SWB-12kHz
|
||||
envQ8 += (isSWB12kHz)? (k & 1):((k & 1) & (k >> 1));
|
||||
|
||||
|
||||
/* update interval */
|
||||
W_upper_LSB = W_upper & 0x0000FFFF;
|
||||
W_upper_MSB = W_upper >> 16;
|
||||
W_lower = W_upper_MSB * cdf_lo;
|
||||
W_lower += (W_upper_LSB * cdf_lo) >> 16;
|
||||
W_upper = W_upper_MSB * cdf_hi;
|
||||
W_upper += (W_upper_LSB * cdf_hi) >> 16;
|
||||
|
||||
/* shift interval such that it begins at zero */
|
||||
W_upper -= ++W_lower;
|
||||
|
||||
/* add integer to bitstream */
|
||||
streamdata->streamval += W_lower;
|
||||
|
||||
/* handle carry */
|
||||
if (streamdata->streamval < W_lower)
|
||||
{
|
||||
/* propagate carry */
|
||||
stream_ptr_carry = stream_ptr;
|
||||
while (!(++(*--stream_ptr_carry)));
|
||||
}
|
||||
|
||||
/* renormalize interval, store most significant byte of streamval and update streamval */
|
||||
while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */
|
||||
{
|
||||
W_upper <<= 8;
|
||||
*stream_ptr++ = (WebRtc_UWord8) (streamdata->streamval >> 24);
|
||||
|
||||
if(stream_ptr > maxStreamPtr)
|
||||
{
|
||||
return -ISAC_DISALLOWED_BITSTREAM_LENGTH;
|
||||
}
|
||||
streamdata->streamval <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate new stream_index */
|
||||
streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
|
||||
streamdata->W_upper = W_upper;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int WebRtcIsac_DecLogisticMulti2(
|
||||
WebRtc_Word16 *dataQ7, /* output: data vector */
|
||||
Bitstr *streamdata, /* in-/output struct containing bitstream */
|
||||
const WebRtc_UWord16 *envQ8, /* input: side info vector defining the width of the pdf */
|
||||
const WebRtc_Word16 *ditherQ7,/* input: dither vector */
|
||||
const int N, /* input: data vector length */
|
||||
const WebRtc_Word16 isSWB12kHz)
|
||||
{
|
||||
WebRtc_UWord32 W_lower, W_upper;
|
||||
WebRtc_UWord32 W_tmp;
|
||||
WebRtc_UWord32 W_upper_LSB, W_upper_MSB;
|
||||
WebRtc_UWord32 streamval;
|
||||
const WebRtc_UWord8 *stream_ptr;
|
||||
WebRtc_UWord32 cdf_tmp;
|
||||
WebRtc_Word16 candQ7;
|
||||
int k;
|
||||
|
||||
stream_ptr = streamdata->stream + streamdata->stream_index;
|
||||
W_upper = streamdata->W_upper;
|
||||
if (streamdata->stream_index == 0) /* first time decoder is called for this stream */
|
||||
{
|
||||
/* read first word from bytestream */
|
||||
streamval = *stream_ptr << 24;
|
||||
streamval |= *++stream_ptr << 16;
|
||||
streamval |= *++stream_ptr << 8;
|
||||
streamval |= *++stream_ptr;
|
||||
} else {
|
||||
streamval = streamdata->streamval;
|
||||
}
|
||||
|
||||
|
||||
for (k = 0; k < N; k++)
|
||||
{
|
||||
/* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
|
||||
W_upper_LSB = W_upper & 0x0000FFFF;
|
||||
W_upper_MSB = W_upper >> 16;
|
||||
|
||||
/* find first candidate by inverting the logistic cdf */
|
||||
candQ7 = - *ditherQ7 + 64;
|
||||
cdf_tmp = piecewise(candQ7 * *envQ8);
|
||||
|
||||
W_tmp = W_upper_MSB * cdf_tmp;
|
||||
W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
|
||||
if (streamval > W_tmp)
|
||||
{
|
||||
W_lower = W_tmp;
|
||||
candQ7 += 128;
|
||||
cdf_tmp = piecewise(candQ7 * *envQ8);
|
||||
|
||||
W_tmp = W_upper_MSB * cdf_tmp;
|
||||
W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
|
||||
while (streamval > W_tmp)
|
||||
{
|
||||
W_lower = W_tmp;
|
||||
candQ7 += 128;
|
||||
cdf_tmp = piecewise(candQ7 * *envQ8);
|
||||
|
||||
W_tmp = W_upper_MSB * cdf_tmp;
|
||||
W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
|
||||
|
||||
/* error check */
|
||||
if (W_lower == W_tmp) return -1;
|
||||
}
|
||||
W_upper = W_tmp;
|
||||
|
||||
/* another sample decoded */
|
||||
*dataQ7 = candQ7 - 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
W_upper = W_tmp;
|
||||
candQ7 -= 128;
|
||||
cdf_tmp = piecewise(candQ7 * *envQ8);
|
||||
|
||||
W_tmp = W_upper_MSB * cdf_tmp;
|
||||
W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
|
||||
while ( !(streamval > W_tmp) )
|
||||
{
|
||||
W_upper = W_tmp;
|
||||
candQ7 -= 128;
|
||||
cdf_tmp = piecewise(candQ7 * *envQ8);
|
||||
|
||||
W_tmp = W_upper_MSB * cdf_tmp;
|
||||
W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
|
||||
|
||||
/* error check */
|
||||
if (W_upper == W_tmp) return -1;
|
||||
}
|
||||
W_lower = W_tmp;
|
||||
|
||||
/* another sample decoded */
|
||||
*dataQ7 = candQ7 + 64;
|
||||
}
|
||||
ditherQ7++;
|
||||
dataQ7++;
|
||||
// increment only once per 4 iterations for SWB-16kHz or WB
|
||||
// increment only once per 2 iterations for SWB-12kHz
|
||||
envQ8 += (isSWB12kHz)? (k & 1):((k & 1) & (k >> 1));
|
||||
|
||||
/* shift interval to start at zero */
|
||||
W_upper -= ++W_lower;
|
||||
|
||||
/* add integer to bitstream */
|
||||
streamval -= W_lower;
|
||||
|
||||
/* renormalize interval and update streamval */
|
||||
while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */
|
||||
{
|
||||
/* read next byte from stream */
|
||||
streamval = (streamval << 8) | *++stream_ptr;
|
||||
W_upper <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
|
||||
streamdata->W_upper = W_upper;
|
||||
streamdata->streamval = streamval;
|
||||
|
||||
/* find number of bytes in original stream (determined by current interval width) */
|
||||
if ( W_upper > 0x01FFFFFF )
|
||||
return streamdata->stream_index - 2;
|
||||
else
|
||||
return streamdata->stream_index - 1;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* bandwidth_estimator.h
|
||||
*
|
||||
* This header file contains the API for the Bandwidth Estimator
|
||||
* designed for iSAC.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_BANDWIDTH_ESTIMATOR_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_BANDWIDTH_ESTIMATOR_H_
|
||||
|
||||
#include "structs.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
#define MIN_ISAC_BW 10000
|
||||
#define MIN_ISAC_BW_LB 10000
|
||||
#define MIN_ISAC_BW_UB 25000
|
||||
|
||||
#define MAX_ISAC_BW 56000
|
||||
#define MAX_ISAC_BW_UB 32000
|
||||
#define MAX_ISAC_BW_LB 32000
|
||||
|
||||
#define MIN_ISAC_MD 5
|
||||
#define MAX_ISAC_MD 25
|
||||
|
||||
// assumed header size, in bytes; we don't know the exact number
|
||||
// (header compression may be used)
|
||||
#define HEADER_SIZE 35
|
||||
|
||||
// Initial Frame-Size, in ms, for Wideband & Super-Wideband Mode
|
||||
#define INIT_FRAME_LEN_WB 60
|
||||
#define INIT_FRAME_LEN_SWB 30
|
||||
|
||||
// Initial Bottleneck Estimate, in bits/sec, for
|
||||
// Wideband & Super-wideband mode
|
||||
#define INIT_BN_EST_WB 20e3f
|
||||
#define INIT_BN_EST_SWB 56e3f
|
||||
|
||||
// Initial Header rate (header rate depends on frame-size),
|
||||
// in bits/sec, for Wideband & Super-Wideband mode.
|
||||
#define INIT_HDR_RATE_WB \
|
||||
((float)HEADER_SIZE * 8.0f * 1000.0f / (float)INIT_FRAME_LEN_WB)
|
||||
#define INIT_HDR_RATE_SWB \
|
||||
((float)HEADER_SIZE * 8.0f * 1000.0f / (float)INIT_FRAME_LEN_SWB)
|
||||
|
||||
// number of packets in a row for a high rate burst
|
||||
#define BURST_LEN 3
|
||||
|
||||
// ms, max time between two full bursts
|
||||
#define BURST_INTERVAL 500
|
||||
|
||||
// number of packets in a row for initial high rate burst
|
||||
#define INIT_BURST_LEN 5
|
||||
|
||||
// bits/s, rate for the first BURST_LEN packets
|
||||
#define INIT_RATE_WB INIT_BN_EST_WB
|
||||
#define INIT_RATE_SWB INIT_BN_EST_SWB
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This function initializes the struct */
|
||||
/* to be called before using the struct for anything else */
|
||||
/* returns 0 if everything went fine, -1 otherwise */
|
||||
WebRtc_Word32 WebRtcIsac_InitBandwidthEstimator(
|
||||
BwEstimatorstr* bwest_str,
|
||||
enum IsacSamplingRate encoderSampRate,
|
||||
enum IsacSamplingRate decoderSampRate);
|
||||
|
||||
/* This function updates the receiving estimate */
|
||||
/* Parameters: */
|
||||
/* rtp_number - value from RTP packet, from NetEq */
|
||||
/* frame length - length of signal frame in ms, from iSAC decoder */
|
||||
/* send_ts - value in RTP header giving send time in samples */
|
||||
/* arr_ts - value given by timeGetTime() time of arrival in samples of packet from NetEq */
|
||||
/* pksize - size of packet in bytes, from NetEq */
|
||||
/* Index - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
|
||||
/* returns 0 if everything went fine, -1 otherwise */
|
||||
WebRtc_Word16 WebRtcIsac_UpdateBandwidthEstimator(
|
||||
BwEstimatorstr* bwest_str,
|
||||
const WebRtc_UWord16 rtp_number,
|
||||
const WebRtc_Word32 frame_length,
|
||||
const WebRtc_UWord32 send_ts,
|
||||
const WebRtc_UWord32 arr_ts,
|
||||
const WebRtc_Word32 pksize);
|
||||
|
||||
/* Update receiving estimates. Used when we only receive BWE index, no iSAC data packet. */
|
||||
WebRtc_Word16 WebRtcIsac_UpdateUplinkBwImpl(
|
||||
BwEstimatorstr* bwest_str,
|
||||
WebRtc_Word16 Index,
|
||||
enum IsacSamplingRate encoderSamplingFreq);
|
||||
|
||||
/* Returns the bandwidth/jitter estimation code (integer 0...23) to put in the sending iSAC payload */
|
||||
WebRtc_UWord16 WebRtcIsac_GetDownlinkBwJitIndexImpl(
|
||||
BwEstimatorstr* bwest_str,
|
||||
WebRtc_Word16* bottleneckIndex,
|
||||
WebRtc_Word16* jitterInfo,
|
||||
enum IsacSamplingRate decoderSamplingFreq);
|
||||
|
||||
/* Returns the bandwidth estimation (in bps) */
|
||||
WebRtc_Word32 WebRtcIsac_GetDownlinkBandwidth(
|
||||
const BwEstimatorstr *bwest_str);
|
||||
|
||||
/* Returns the max delay (in ms) */
|
||||
WebRtc_Word32 WebRtcIsac_GetDownlinkMaxDelay(
|
||||
const BwEstimatorstr *bwest_str);
|
||||
|
||||
/* Returns the bandwidth that iSAC should send with in bps */
|
||||
void WebRtcIsac_GetUplinkBandwidth(
|
||||
const BwEstimatorstr* bwest_str,
|
||||
WebRtc_Word32* bitRate);
|
||||
|
||||
/* Returns the max delay value from the other side in ms */
|
||||
WebRtc_Word32 WebRtcIsac_GetUplinkMaxDelay(
|
||||
const BwEstimatorstr *bwest_str);
|
||||
|
||||
|
||||
/*
|
||||
* update amount of data in bottle neck buffer and burst handling
|
||||
* returns minimum payload size (bytes)
|
||||
*/
|
||||
int WebRtcIsac_GetMinBytes(
|
||||
RateModel* State,
|
||||
int StreamSize, /* bytes in bitstream */
|
||||
const int FrameLen, /* ms per frame */
|
||||
const double BottleNeck, /* bottle neck rate; excl headers (bps) */
|
||||
const double DelayBuildUp, /* max delay from bottleneck buffering (ms) */
|
||||
enum ISACBandwidth bandwidth
|
||||
/*,WebRtc_Word16 frequentLargePackets*/);
|
||||
|
||||
/*
|
||||
* update long-term average bitrate and amount of data in buffer
|
||||
*/
|
||||
void WebRtcIsac_UpdateRateModel(
|
||||
RateModel* State,
|
||||
int StreamSize, /* bytes in bitstream */
|
||||
const int FrameSamples, /* samples per frame */
|
||||
const double BottleNeck); /* bottle neck rate; excl headers (bps) */
|
||||
|
||||
|
||||
void WebRtcIsac_InitRateModel(
|
||||
RateModel *State);
|
||||
|
||||
/* Returns the new framelength value (input argument: bottle_neck) */
|
||||
int WebRtcIsac_GetNewFrameLength(
|
||||
double bottle_neck,
|
||||
int current_framelength);
|
||||
|
||||
/* Returns the new SNR value (input argument: bottle_neck) */
|
||||
double WebRtcIsac_GetSnr(
|
||||
double bottle_neck,
|
||||
int new_framelength);
|
||||
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_UpdateUplinkJitter(
|
||||
BwEstimatorstr* bwest_str,
|
||||
WebRtc_Word32 index);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_BANDWIDTH_ESTIMATOR_H_ */
|
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* codec.h
|
||||
*
|
||||
* This header file contains the calls to the internal encoder
|
||||
* and decoder functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CODEC_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CODEC_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
int WebRtcIsac_EstimateBandwidth(
|
||||
BwEstimatorstr* bwest_str,
|
||||
Bitstr* streamdata,
|
||||
WebRtc_Word32 packet_size,
|
||||
WebRtc_UWord16 rtp_seq_number,
|
||||
WebRtc_UWord32 send_ts,
|
||||
WebRtc_UWord32 arr_ts,
|
||||
enum IsacSamplingRate encoderSampRate,
|
||||
enum IsacSamplingRate decoderSampRate);
|
||||
|
||||
int WebRtcIsac_DecodeLb(
|
||||
float* signal_out,
|
||||
ISACLBDecStruct* ISACdec_obj,
|
||||
WebRtc_Word16* current_framesamples,
|
||||
WebRtc_Word16 isRCUPayload);
|
||||
|
||||
int WebRtcIsac_DecodeRcuLb(
|
||||
float* signal_out,
|
||||
ISACLBDecStruct* ISACdec_obj,
|
||||
WebRtc_Word16* current_framesamples);
|
||||
|
||||
int WebRtcIsac_EncodeLb(
|
||||
float* in,
|
||||
ISACLBEncStruct* ISACencLB_obj,
|
||||
WebRtc_Word16 codingMode,
|
||||
WebRtc_Word16 bottleneckIndex);
|
||||
|
||||
int WebRtcIsac_EncodeStoredDataLb(
|
||||
const ISAC_SaveEncData_t* ISACSavedEnc_obj,
|
||||
Bitstr* ISACBitStr_obj,
|
||||
int BWnumber,
|
||||
float scale);
|
||||
|
||||
|
||||
int WebRtcIsac_EncodeStoredDataUb12(
|
||||
const ISACUBSaveEncDataStruct* ISACSavedEnc_obj,
|
||||
Bitstr* bitStream,
|
||||
WebRtc_Word32 jitterInfo,
|
||||
float scale);
|
||||
|
||||
int WebRtcIsac_EncodeStoredDataUb16(
|
||||
const ISACUBSaveEncDataStruct* ISACSavedEnc_obj,
|
||||
Bitstr* bitStream,
|
||||
WebRtc_Word32 jitterInfo,
|
||||
float scale);
|
||||
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_GetRedPayloadUb(
|
||||
const ISACUBSaveEncDataStruct* ISACSavedEncObj,
|
||||
Bitstr* bitStreamObj,
|
||||
enum ISACBandwidth bandwidth);
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_RateAllocation()
|
||||
* Internal function to perform a rate-allocation for upper and lower-band,
|
||||
* given a total rate.
|
||||
*
|
||||
* Input:
|
||||
* - inRateBitPerSec : a total bit-rate in bits/sec.
|
||||
*
|
||||
* Output:
|
||||
* - rateLBBitPerSec : a bit-rate allocated to the lower-band
|
||||
* in bits/sec.
|
||||
* - rateUBBitPerSec : a bit-rate allocated to the upper-band
|
||||
* in bits/sec.
|
||||
*
|
||||
* Return value : 0 if rate allocation has been successful.
|
||||
* -1 if failed to allocate rates.
|
||||
*/
|
||||
|
||||
WebRtc_Word16
|
||||
WebRtcIsac_RateAllocation(
|
||||
WebRtc_Word32 inRateBitPerSec,
|
||||
double* rateLBBitPerSec,
|
||||
double* rateUBBitPerSec,
|
||||
enum ISACBandwidth* bandwidthKHz);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecodeUb16()
|
||||
*
|
||||
* Decode the upper-band if the codec is in 0-16 kHz mode.
|
||||
*
|
||||
* Input/Output:
|
||||
* -ISACdec_obj : pointer to the upper-band decoder object. The
|
||||
* bit-stream is stored inside the decoder object.
|
||||
*
|
||||
* Output:
|
||||
* -signal_out : decoded audio, 480 samples 30 ms.
|
||||
*
|
||||
* Return value : >0 number of decoded bytes.
|
||||
* <0 if an error occurred.
|
||||
*/
|
||||
int WebRtcIsac_DecodeUb16(
|
||||
float* signal_out,
|
||||
ISACUBDecStruct* ISACdec_obj,
|
||||
WebRtc_Word16 isRCUPayload);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecodeUb12()
|
||||
*
|
||||
* Decode the upper-band if the codec is in 0-12 kHz mode.
|
||||
*
|
||||
* Input/Output:
|
||||
* -ISACdec_obj : pointer to the upper-band decoder object. The
|
||||
* bit-stream is stored inside the decoder object.
|
||||
*
|
||||
* Output:
|
||||
* -signal_out : decoded audio, 480 samples 30 ms.
|
||||
*
|
||||
* Return value : >0 number of decoded bytes.
|
||||
* <0 if an error occurred.
|
||||
*/
|
||||
int WebRtcIsac_DecodeUb12(
|
||||
float* signal_out,
|
||||
ISACUBDecStruct* ISACdec_obj,
|
||||
WebRtc_Word16 isRCUPayload);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncodeUb16()
|
||||
*
|
||||
* Encode the upper-band if the codec is in 0-16 kHz mode.
|
||||
*
|
||||
* Input:
|
||||
* -in : upper-band audio, 160 samples (10 ms).
|
||||
*
|
||||
* Input/Output:
|
||||
* -ISACdec_obj : pointer to the upper-band encoder object. The
|
||||
* bit-stream is stored inside the encoder object.
|
||||
*
|
||||
* Return value : >0 number of encoded bytes.
|
||||
* <0 if an error occurred.
|
||||
*/
|
||||
int WebRtcIsac_EncodeUb16(
|
||||
float* in,
|
||||
ISACUBEncStruct* ISACenc_obj,
|
||||
WebRtc_Word32 jitterInfo);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncodeUb12()
|
||||
*
|
||||
* Encode the upper-band if the codec is in 0-12 kHz mode.
|
||||
*
|
||||
* Input:
|
||||
* -in : upper-band audio, 160 samples (10 ms).
|
||||
*
|
||||
* Input/Output:
|
||||
* -ISACdec_obj : pointer to the upper-band encoder object. The
|
||||
* bit-stream is stored inside the encoder object.
|
||||
*
|
||||
* Return value : >0 number of encoded bytes.
|
||||
* <0 if an error occurred.
|
||||
*/
|
||||
int WebRtcIsac_EncodeUb12(
|
||||
float* in,
|
||||
ISACUBEncStruct* ISACenc_obj,
|
||||
WebRtc_Word32 jitterInfo);
|
||||
|
||||
/************************** initialization functions *************************/
|
||||
|
||||
void WebRtcIsac_InitMasking(MaskFiltstr *maskdata);
|
||||
|
||||
void WebRtcIsac_InitPreFilterbank(PreFiltBankstr *prefiltdata);
|
||||
|
||||
void WebRtcIsac_InitPostFilterbank(PostFiltBankstr *postfiltdata);
|
||||
|
||||
void WebRtcIsac_InitPitchFilter(PitchFiltstr *pitchfiltdata);
|
||||
|
||||
void WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct *State);
|
||||
|
||||
|
||||
/**************************** transform functions ****************************/
|
||||
|
||||
void WebRtcIsac_InitTransform();
|
||||
|
||||
void WebRtcIsac_Time2Spec(double *inre1,
|
||||
double *inre2,
|
||||
WebRtc_Word16 *outre,
|
||||
WebRtc_Word16 *outim,
|
||||
FFTstr *fftstr_obj);
|
||||
|
||||
void WebRtcIsac_Spec2time(double *inre,
|
||||
double *inim,
|
||||
double *outre1,
|
||||
double *outre2,
|
||||
FFTstr *fftstr_obj);
|
||||
|
||||
|
||||
/******************************* filter functions ****************************/
|
||||
|
||||
void WebRtcIsac_AllPoleFilter(double *InOut,
|
||||
double *Coef,
|
||||
int lengthInOut,
|
||||
int orderCoef);
|
||||
|
||||
void WebRtcIsac_AllZeroFilter(double *In,
|
||||
double *Coef,
|
||||
int lengthInOut,
|
||||
int orderCoef,
|
||||
double *Out);
|
||||
|
||||
void WebRtcIsac_ZeroPoleFilter(double *In,
|
||||
double *ZeroCoef,
|
||||
double *PoleCoef,
|
||||
int lengthInOut,
|
||||
int orderCoef,
|
||||
double *Out);
|
||||
|
||||
|
||||
/***************************** filterbank functions **************************/
|
||||
|
||||
void WebRtcIsac_SplitAndFilter(double *in,
|
||||
double *LP,
|
||||
double *HP,
|
||||
double *LP_la,
|
||||
double *HP_la,
|
||||
PreFiltBankstr *prefiltdata);
|
||||
|
||||
|
||||
void WebRtcIsac_FilterAndCombine(double *InLP,
|
||||
double *InHP,
|
||||
double *Out,
|
||||
PostFiltBankstr *postfiltdata);
|
||||
|
||||
|
||||
|
||||
void WebRtcIsac_SplitAndFilterFloat(float *in,
|
||||
float *LP,
|
||||
float *HP,
|
||||
double *LP_la,
|
||||
double *HP_la,
|
||||
PreFiltBankstr *prefiltdata);
|
||||
|
||||
|
||||
void WebRtcIsac_FilterAndCombineFloat(float *InLP,
|
||||
float *InHP,
|
||||
float *Out,
|
||||
PostFiltBankstr *postfiltdata);
|
||||
|
||||
|
||||
/************************* normalized lattice filters ************************/
|
||||
|
||||
void WebRtcIsac_NormLatticeFilterMa(int orderCoef,
|
||||
float *stateF,
|
||||
float *stateG,
|
||||
float *lat_in,
|
||||
double *filtcoeflo,
|
||||
double *lat_out);
|
||||
|
||||
void WebRtcIsac_NormLatticeFilterAr(int orderCoef,
|
||||
float *stateF,
|
||||
float *stateG,
|
||||
double *lat_in,
|
||||
double *lo_filt_coef,
|
||||
float *lat_out);
|
||||
|
||||
void WebRtcIsac_Dir2Lat(double *a,
|
||||
int orderCoef,
|
||||
float *sth,
|
||||
float *cth);
|
||||
|
||||
void WebRtcIsac_AutoCorr(double *r,
|
||||
const double *x,
|
||||
int N,
|
||||
int order);
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CODEC_H_ */
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "crc.h"
|
||||
#include <stdlib.h>
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
#define POLYNOMIAL 0x04c11db7L
|
||||
|
||||
|
||||
static const WebRtc_UWord32 kCrcTable[256] = {
|
||||
0, 0x4c11db7, 0x9823b6e, 0xd4326d9, 0x130476dc, 0x17c56b6b,
|
||||
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
|
||||
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
|
||||
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
|
||||
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
|
||||
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
|
||||
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
|
||||
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
|
||||
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
|
||||
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
||||
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
|
||||
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x18aeb13, 0x54bf6a4,
|
||||
0x808d07d, 0xcc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
|
||||
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
|
||||
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
|
||||
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
|
||||
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
|
||||
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
|
||||
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
||||
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
|
||||
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
|
||||
0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
|
||||
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
|
||||
0x3f9b762c, 0x3b5a6b9b, 0x315d626, 0x7d4cb91, 0xa97ed48, 0xe56f0ff,
|
||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
|
||||
0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
|
||||
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
|
||||
0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
|
||||
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
||||
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
|
||||
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
|
||||
0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
|
||||
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
|
||||
0x18197087, 0x1cd86d30, 0x29f3d35, 0x65e2082, 0xb1d065b, 0xfdc1bec,
|
||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
|
||||
0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
|
||||
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
|
||||
0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
|
||||
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
||||
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
|
||||
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsac_GetCrc(...)
|
||||
*
|
||||
* This function returns a 32 bit CRC checksum of a bit stream
|
||||
*
|
||||
* Input:
|
||||
* - bitstream : payload bitstream
|
||||
* - len_bitstream_in_bytes : number of 8-bit words in the bit stream
|
||||
*
|
||||
* Output:
|
||||
* - crc : checksum
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_GetCrc(const WebRtc_Word16* bitstream,
|
||||
WebRtc_Word16 len_bitstream_in_bytes,
|
||||
WebRtc_UWord32* crc)
|
||||
{
|
||||
WebRtc_UWord8* bitstream_ptr_uw8;
|
||||
WebRtc_UWord32 crc_state;
|
||||
int byte_cntr;
|
||||
int crc_tbl_indx;
|
||||
|
||||
/* Sanity Check. */
|
||||
if (bitstream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
/* cast to UWord8 pointer */
|
||||
bitstream_ptr_uw8 = (WebRtc_UWord8 *)bitstream;
|
||||
|
||||
/* initialize */
|
||||
crc_state = 0xFFFFFFFF;
|
||||
|
||||
for (byte_cntr = 0; byte_cntr < len_bitstream_in_bytes; byte_cntr++) {
|
||||
crc_tbl_indx = (WEBRTC_SPL_RSHIFT_U32(crc_state, 24) ^
|
||||
bitstream_ptr_uw8[byte_cntr]) & 0xFF;
|
||||
crc_state = WEBRTC_SPL_LSHIFT_U32(crc_state, 8) ^ kCrcTable[crc_tbl_indx];
|
||||
}
|
||||
|
||||
*crc = ~crc_state;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* crc.h
|
||||
*
|
||||
* Checksum functions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsac_GetCrc(...)
|
||||
*
|
||||
* This function returns a 32 bit CRC checksum of a bit stream
|
||||
*
|
||||
* Input:
|
||||
* - encoded : payload bit stream
|
||||
* - no_of_word8s : number of 8-bit words in the bit stream
|
||||
*
|
||||
* Output:
|
||||
* - crc : checksum
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_GetCrc(
|
||||
const WebRtc_Word16* encoded,
|
||||
WebRtc_Word16 no_of_word8s,
|
||||
WebRtc_UWord32* crc);
|
||||
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_ */
|
|
@ -0,0 +1,330 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* decode_B.c
|
||||
*
|
||||
* This file contains definition of funtions for decoding.
|
||||
* Decoding of lower-band, including normal-decoding and RCU decoding.
|
||||
* Decoding of upper-band, including 8-12 kHz, when the bandwidth is
|
||||
* 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "codec.h"
|
||||
#include "entropy_coding.h"
|
||||
#include "pitch_estimator.h"
|
||||
#include "bandwidth_estimator.h"
|
||||
#include "structs.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* function to decode the bitstream
|
||||
* returns the total number of bytes in the stream
|
||||
*/
|
||||
int
|
||||
WebRtcIsac_DecodeLb(
|
||||
float* signal_out,
|
||||
ISACLBDecStruct* ISACdecLB_obj,
|
||||
WebRtc_Word16* current_framesamples,
|
||||
WebRtc_Word16 isRCUPayload)
|
||||
{
|
||||
int k, model;
|
||||
int len, err;
|
||||
WebRtc_Word16 bandwidthInd;
|
||||
|
||||
float LP_dec_float[FRAMESAMPLES_HALF];
|
||||
float HP_dec_float[FRAMESAMPLES_HALF];
|
||||
|
||||
double LPw[FRAMESAMPLES_HALF];
|
||||
double HPw[FRAMESAMPLES_HALF];
|
||||
double LPw_pf[FRAMESAMPLES_HALF];
|
||||
|
||||
double lo_filt_coef[(ORDERLO+1)*SUBFRAMES];
|
||||
double hi_filt_coef[(ORDERHI+1)*SUBFRAMES];
|
||||
|
||||
double real_f[FRAMESAMPLES_HALF];
|
||||
double imag_f[FRAMESAMPLES_HALF];
|
||||
|
||||
double PitchLags[4];
|
||||
double PitchGains[4];
|
||||
double AvgPitchGain;
|
||||
WebRtc_Word16 PitchGains_Q12[4];
|
||||
WebRtc_Word16 AvgPitchGain_Q12;
|
||||
|
||||
float gain;
|
||||
|
||||
int frame_nb; /* counter */
|
||||
int frame_mode; /* 0 for 20ms and 30ms, 1 for 60ms */
|
||||
int processed_samples;
|
||||
|
||||
(ISACdecLB_obj->bitstr_obj).W_upper = 0xFFFFFFFF;
|
||||
(ISACdecLB_obj->bitstr_obj).streamval = 0;
|
||||
(ISACdecLB_obj->bitstr_obj).stream_index = 0;
|
||||
|
||||
len = 0;
|
||||
|
||||
/* decode framelength and BW estimation - not used,
|
||||
only for stream pointer*/
|
||||
err = WebRtcIsac_DecodeFrameLen(&ISACdecLB_obj->bitstr_obj,
|
||||
current_framesamples);
|
||||
if (err < 0) { // error check
|
||||
return err;
|
||||
}
|
||||
|
||||
/* frame_mode: 0, or 1 */
|
||||
frame_mode = *current_framesamples/MAX_FRAMESAMPLES;
|
||||
/* processed_samples: either 320 (20ms) or 480 (30, 60 ms) */
|
||||
processed_samples = *current_framesamples/(frame_mode+1);
|
||||
|
||||
err = WebRtcIsac_DecodeSendBW(&ISACdecLB_obj->bitstr_obj, &bandwidthInd);
|
||||
if (err < 0) { // error check
|
||||
return err;
|
||||
}
|
||||
|
||||
/* one loop if it's one frame (20 or 30ms), 2 loops if 2 frames
|
||||
bundled together (60ms) */
|
||||
for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {
|
||||
/* decode & dequantize pitch parameters */
|
||||
err = WebRtcIsac_DecodePitchGain(&(ISACdecLB_obj->bitstr_obj),
|
||||
PitchGains_Q12);
|
||||
if (err < 0) { // error check
|
||||
return err;
|
||||
}
|
||||
|
||||
err = WebRtcIsac_DecodePitchLag(&ISACdecLB_obj->bitstr_obj,
|
||||
PitchGains_Q12, PitchLags);
|
||||
if (err < 0) { // error check
|
||||
return err;
|
||||
}
|
||||
|
||||
AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
|
||||
PitchGains_Q12[2] + PitchGains_Q12[3])>>2;
|
||||
|
||||
/* decode & dequantize FiltCoef */
|
||||
err = WebRtcIsac_DecodeLpc(&ISACdecLB_obj->bitstr_obj,
|
||||
lo_filt_coef,hi_filt_coef, &model);
|
||||
if (err < 0) { // error check
|
||||
return err;
|
||||
}
|
||||
/* decode & dequantize spectrum */
|
||||
len = WebRtcIsac_DecodeSpecLb(&ISACdecLB_obj->bitstr_obj,
|
||||
real_f, imag_f, AvgPitchGain_Q12);
|
||||
if (len < 0) { // error check
|
||||
return len;
|
||||
}
|
||||
|
||||
/* inverse transform */
|
||||
WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw,
|
||||
&ISACdecLB_obj->fftstr_obj);
|
||||
|
||||
/* convert PitchGains back to FLOAT for pitchfilter_post */
|
||||
for (k = 0; k < 4; k++) {
|
||||
PitchGains[k] = ((float)PitchGains_Q12[k])/4096;
|
||||
}
|
||||
|
||||
if(isRCUPayload)
|
||||
{
|
||||
for (k = 0; k < 240; k++) {
|
||||
LPw[k] *= RCU_TRANSCODING_SCALE_INVERSE;
|
||||
HPw[k] *= RCU_TRANSCODING_SCALE_INVERSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* inverse pitch filter */
|
||||
WebRtcIsac_PitchfilterPost(LPw, LPw_pf,
|
||||
&ISACdecLB_obj->pitchfiltstr_obj, PitchLags, PitchGains);
|
||||
/* convert AvgPitchGain back to FLOAT for computation of gain */
|
||||
AvgPitchGain = ((float)AvgPitchGain_Q12)/4096;
|
||||
gain = 1.0f - 0.45f * (float)AvgPitchGain;
|
||||
|
||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||
/* reduce gain to compensate for pitch enhancer */
|
||||
LPw_pf[ k ] *= gain;
|
||||
}
|
||||
|
||||
if(isRCUPayload)
|
||||
{
|
||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||
/* compensation for transcoding gain changes*/
|
||||
LPw_pf[k] *= RCU_TRANSCODING_SCALE;
|
||||
HPw[k] *= RCU_TRANSCODING_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
/* perceptual post-filtering (using normalized lattice filter) */
|
||||
WebRtcIsac_NormLatticeFilterAr(ORDERLO,
|
||||
ISACdecLB_obj->maskfiltstr_obj.PostStateLoF,
|
||||
(ISACdecLB_obj->maskfiltstr_obj).PostStateLoG,
|
||||
LPw_pf, lo_filt_coef, LP_dec_float);
|
||||
WebRtcIsac_NormLatticeFilterAr(ORDERHI,
|
||||
ISACdecLB_obj->maskfiltstr_obj.PostStateHiF,
|
||||
(ISACdecLB_obj->maskfiltstr_obj).PostStateHiG,
|
||||
HPw, hi_filt_coef, HP_dec_float);
|
||||
|
||||
/* recombine the 2 bands */
|
||||
WebRtcIsac_FilterAndCombineFloat( LP_dec_float, HP_dec_float,
|
||||
signal_out + frame_nb * processed_samples,
|
||||
&ISACdecLB_obj->postfiltbankstr_obj);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This decode function is called when the codec is operating in 16 kHz
|
||||
* bandwidth to decode the upperband, i.e. 8-16 kHz.
|
||||
*
|
||||
* Contrary to lower-band, the upper-band (8-16 kHz) is not split in
|
||||
* frequency, but split to 12 sub-frames, i.e. twice as lower-band.
|
||||
*/
|
||||
int
|
||||
WebRtcIsac_DecodeUb16(
|
||||
float* signal_out,
|
||||
ISACUBDecStruct* ISACdecUB_obj,
|
||||
WebRtc_Word16 isRCUPayload)
|
||||
{
|
||||
int len, err;
|
||||
|
||||
double halfFrameFirst[FRAMESAMPLES_HALF];
|
||||
double halfFrameSecond[FRAMESAMPLES_HALF];
|
||||
|
||||
double percepFilterParam[(UB_LPC_ORDER+1) * (SUBFRAMES<<1) +
|
||||
(UB_LPC_ORDER+1)];
|
||||
|
||||
double real_f[FRAMESAMPLES_HALF];
|
||||
double imag_f[FRAMESAMPLES_HALF];
|
||||
|
||||
len = 0;
|
||||
|
||||
/* decode & dequantize FiltCoef */
|
||||
memset(percepFilterParam, 0, sizeof(percepFilterParam));
|
||||
err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj,
|
||||
percepFilterParam, isac16kHz);
|
||||
if (err < 0) { // error check
|
||||
return err;
|
||||
}
|
||||
|
||||
/* decode & dequantize spectrum */
|
||||
len = WebRtcIsac_DecodeSpecUB16(&ISACdecUB_obj->bitstr_obj, real_f,
|
||||
imag_f);
|
||||
if (len < 0) { // error check
|
||||
return len;
|
||||
}
|
||||
if(isRCUPayload)
|
||||
{
|
||||
int n;
|
||||
for(n = 0; n < 240; n++)
|
||||
{
|
||||
real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
|
||||
imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* inverse transform */
|
||||
WebRtcIsac_Spec2time(real_f, imag_f, halfFrameFirst, halfFrameSecond,
|
||||
&ISACdecUB_obj->fftstr_obj);
|
||||
|
||||
/* perceptual post-filtering (using normalized lattice filter) */
|
||||
WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER,
|
||||
ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
|
||||
(ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameFirst,
|
||||
&percepFilterParam[(UB_LPC_ORDER+1)], signal_out);
|
||||
|
||||
WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER,
|
||||
ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
|
||||
(ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameSecond,
|
||||
&percepFilterParam[(UB_LPC_ORDER + 1) * SUBFRAMES + (UB_LPC_ORDER+1)],
|
||||
&signal_out[FRAMESAMPLES_HALF]);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* This decode function is called when the codec operates at 0-12 kHz
|
||||
* bandwidth to decode the upperband, i.e. 8-12 kHz.
|
||||
*
|
||||
* At the encoder the upper-band is split into two band, 8-12 kHz & 12-16
|
||||
* kHz, and only 8-12 kHz is encoded. At the decoder, 8-12 kHz band is
|
||||
* reconstructed and 12-16 kHz replaced with zeros. Then two bands
|
||||
* are combined, to reconstruct the upperband 8-16 kHz.
|
||||
*/
|
||||
int
|
||||
WebRtcIsac_DecodeUb12(
|
||||
float* signal_out,
|
||||
ISACUBDecStruct* ISACdecUB_obj,
|
||||
WebRtc_Word16 isRCUPayload)
|
||||
{
|
||||
int len, err;
|
||||
|
||||
float LP_dec_float[FRAMESAMPLES_HALF];
|
||||
float HP_dec_float[FRAMESAMPLES_HALF];
|
||||
|
||||
double LPw[FRAMESAMPLES_HALF];
|
||||
double HPw[FRAMESAMPLES_HALF];
|
||||
|
||||
double percepFilterParam[(UB_LPC_ORDER+1)*SUBFRAMES];
|
||||
|
||||
double real_f[FRAMESAMPLES_HALF];
|
||||
double imag_f[FRAMESAMPLES_HALF];
|
||||
|
||||
len = 0;
|
||||
|
||||
/* decode & dequantize FiltCoef */
|
||||
err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj,
|
||||
percepFilterParam, isac12kHz);
|
||||
if(err < 0) { // error check
|
||||
return err;
|
||||
}
|
||||
|
||||
/* decode & dequantize spectrum */
|
||||
len = WebRtcIsac_DecodeSpecUB12(&ISACdecUB_obj->bitstr_obj,
|
||||
real_f, imag_f);
|
||||
if(len < 0) { // error check
|
||||
return len;
|
||||
}
|
||||
|
||||
if(isRCUPayload)
|
||||
{
|
||||
int n;
|
||||
for(n = 0; n < 240; n++)
|
||||
{
|
||||
real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
|
||||
imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* inverse transform */
|
||||
WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw, &ISACdecUB_obj->fftstr_obj);
|
||||
|
||||
/* perceptual post-filtering (using normalized lattice filter) */
|
||||
WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER,
|
||||
ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
|
||||
(ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, LPw,
|
||||
percepFilterParam, LP_dec_float);
|
||||
|
||||
/* Zerro for upper-band */
|
||||
memset(HP_dec_float, 0, sizeof(float) * (FRAMESAMPLES_HALF));
|
||||
|
||||
/* recombine the 2 bands */
|
||||
WebRtcIsac_FilterAndCombineFloat(HP_dec_float, LP_dec_float, signal_out,
|
||||
&ISACdecUB_obj->postfiltbankstr_obj);
|
||||
|
||||
|
||||
|
||||
return len;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "structs.h"
|
||||
#include "bandwidth_estimator.h"
|
||||
#include "entropy_coding.h"
|
||||
#include "codec.h"
|
||||
|
||||
|
||||
int
|
||||
WebRtcIsac_EstimateBandwidth(
|
||||
BwEstimatorstr* bwest_str,
|
||||
Bitstr* streamdata,
|
||||
WebRtc_Word32 packet_size,
|
||||
WebRtc_UWord16 rtp_seq_number,
|
||||
WebRtc_UWord32 send_ts,
|
||||
WebRtc_UWord32 arr_ts,
|
||||
enum IsacSamplingRate encoderSampRate,
|
||||
enum IsacSamplingRate decoderSampRate)
|
||||
{
|
||||
WebRtc_Word16 index;
|
||||
WebRtc_Word16 frame_samples;
|
||||
WebRtc_UWord32 sendTimestampIn16kHz;
|
||||
WebRtc_UWord32 arrivalTimestampIn16kHz;
|
||||
WebRtc_UWord32 diffSendTime;
|
||||
WebRtc_UWord32 diffArrivalTime;
|
||||
int err;
|
||||
|
||||
/* decode framelength and BW estimation */
|
||||
err = WebRtcIsac_DecodeFrameLen(streamdata, &frame_samples);
|
||||
if(err < 0) // error check
|
||||
{
|
||||
return err;
|
||||
}
|
||||
err = WebRtcIsac_DecodeSendBW(streamdata, &index);
|
||||
if(err < 0) // error check
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
/* UPDATE ESTIMATES FROM OTHER SIDE */
|
||||
err = WebRtcIsac_UpdateUplinkBwImpl(bwest_str, index, encoderSampRate);
|
||||
if(err < 0)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
// We like BWE to work at 16 kHz sampling rate,
|
||||
// therefore, we have to change the timestamps accordingly.
|
||||
// translate the send timestamp if required
|
||||
diffSendTime = (WebRtc_UWord32)((WebRtc_UWord32)send_ts -
|
||||
(WebRtc_UWord32)bwest_str->senderTimestamp);
|
||||
bwest_str->senderTimestamp = send_ts;
|
||||
|
||||
diffArrivalTime = (WebRtc_UWord32)((WebRtc_UWord32)arr_ts -
|
||||
(WebRtc_UWord32)bwest_str->receiverTimestamp);
|
||||
bwest_str->receiverTimestamp = arr_ts;
|
||||
|
||||
if(decoderSampRate == kIsacSuperWideband)
|
||||
{
|
||||
diffArrivalTime = (WebRtc_UWord32)diffArrivalTime >> 1;
|
||||
diffSendTime = (WebRtc_UWord32)diffSendTime >> 1;
|
||||
}
|
||||
// arrival timestamp in 16 kHz
|
||||
arrivalTimestampIn16kHz = (WebRtc_UWord32)((WebRtc_UWord32)
|
||||
bwest_str->prev_rec_arr_ts + (WebRtc_UWord32)diffArrivalTime);
|
||||
// send timestamp in 16 kHz
|
||||
sendTimestampIn16kHz = (WebRtc_UWord32)((WebRtc_UWord32)
|
||||
bwest_str->prev_rec_send_ts + (WebRtc_UWord32)diffSendTime);
|
||||
|
||||
err = WebRtcIsac_UpdateBandwidthEstimator(bwest_str, rtp_seq_number,
|
||||
(frame_samples * 1000) / FS, sendTimestampIn16kHz,
|
||||
arrivalTimestampIn16kHz, packet_size);
|
||||
// error check
|
||||
if(err < 0)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,708 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* code_LPC_UB.c
|
||||
*
|
||||
* This file contains definition of functions used to
|
||||
* encode LPC parameters (Shape & gain) of the upper band.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "encode_lpc_swb.h"
|
||||
#include "typedefs.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "lpc_shape_swb12_tables.h"
|
||||
#include "lpc_shape_swb16_tables.h"
|
||||
#include "lpc_gain_swb_tables.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_RemoveLarMean()
|
||||
*
|
||||
* Remove the means from LAR coefficients.
|
||||
*
|
||||
* Input:
|
||||
* -lar : pointer to lar vectors. LAR vectors are
|
||||
* concatenated.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -lar : pointer to mean-removed LAR:s.
|
||||
*
|
||||
*
|
||||
*/
|
||||
WebRtc_Word16
|
||||
WebRtcIsac_RemoveLarMean(
|
||||
double* lar,
|
||||
WebRtc_Word16 bandwidth)
|
||||
{
|
||||
WebRtc_Word16 coeffCntr;
|
||||
WebRtc_Word16 vecCntr;
|
||||
WebRtc_Word16 numVec;
|
||||
const double* meanLAR;
|
||||
switch(bandwidth)
|
||||
{
|
||||
case isac12kHz:
|
||||
{
|
||||
numVec = UB_LPC_VEC_PER_FRAME;
|
||||
meanLAR = WebRtcIsac_kMeanLarUb12;
|
||||
break;
|
||||
}
|
||||
case isac16kHz:
|
||||
{
|
||||
numVec = UB16_LPC_VEC_PER_FRAME;
|
||||
meanLAR = WebRtcIsac_kMeanLarUb16;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(vecCntr = 0; vecCntr < numVec; vecCntr++)
|
||||
{
|
||||
for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++)
|
||||
{
|
||||
// REMOVE MEAN
|
||||
*lar++ -= meanLAR[coeffCntr];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecorrelateIntraVec()
|
||||
*
|
||||
* Remove the correlation amonge the components of LAR vectors. If LAR vectors
|
||||
* of one frame are put in a matrix where each column is a LAR vector of a
|
||||
* sub-frame, then this is equivalent to multiplying the LAR matrix with
|
||||
* a decorrelting mtrix from left.
|
||||
*
|
||||
* Input:
|
||||
* -inLar : pointer to mean-removed LAR vecrtors.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -out : decorrelated LAR vectors.
|
||||
*/
|
||||
WebRtc_Word16
|
||||
WebRtcIsac_DecorrelateIntraVec(
|
||||
const double* data,
|
||||
double* out,
|
||||
WebRtc_Word16 bandwidth)
|
||||
{
|
||||
const double* ptrData;
|
||||
const double* ptrRow;
|
||||
WebRtc_Word16 rowCntr;
|
||||
WebRtc_Word16 colCntr;
|
||||
WebRtc_Word16 larVecCntr;
|
||||
WebRtc_Word16 numVec;
|
||||
const double* decorrMat;
|
||||
switch(bandwidth)
|
||||
{
|
||||
case isac12kHz:
|
||||
{
|
||||
decorrMat = &WebRtcIsac_kIntraVecDecorrMatUb12[0][0];
|
||||
numVec = UB_LPC_VEC_PER_FRAME;
|
||||
break;
|
||||
}
|
||||
case isac16kHz:
|
||||
{
|
||||
decorrMat = &WebRtcIsac_kIintraVecDecorrMatUb16[0][0];
|
||||
numVec = UB16_LPC_VEC_PER_FRAME;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// decorrMat * data
|
||||
//
|
||||
// data is assumed to contain 'numVec' of LAR
|
||||
// vectors (mean removed) each of dimension 'UB_LPC_ORDER'
|
||||
// concatenated one after the other.
|
||||
//
|
||||
|
||||
ptrData = data;
|
||||
for(larVecCntr = 0; larVecCntr < numVec; larVecCntr++)
|
||||
{
|
||||
for(rowCntr = 0; rowCntr < UB_LPC_ORDER; rowCntr++)
|
||||
{
|
||||
ptrRow = &decorrMat[rowCntr * UB_LPC_ORDER];
|
||||
*out = 0;
|
||||
for(colCntr = 0; colCntr < UB_LPC_ORDER; colCntr++)
|
||||
{
|
||||
*out += ptrData[colCntr] * ptrRow[colCntr];
|
||||
}
|
||||
out++;
|
||||
}
|
||||
ptrData += UB_LPC_ORDER;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecorrelateInterVec()
|
||||
*
|
||||
* Remover the correlation among mean-removed LAR vectors. If LAR vectors
|
||||
* of one frame are put in a matrix where each column is a LAR vector of a
|
||||
* sub-frame, then this is equivalent to multiplying the LAR matrix with
|
||||
* a decorrelting mtrix from right.
|
||||
*
|
||||
* Input:
|
||||
* -data : pointer to matrix of LAR vectors. The matrix
|
||||
* is stored column-wise.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -out : decorrelated LAR vectors.
|
||||
*/
|
||||
WebRtc_Word16
|
||||
WebRtcIsac_DecorrelateInterVec(
|
||||
const double* data,
|
||||
double* out,
|
||||
WebRtc_Word16 bandwidth)
|
||||
{
|
||||
WebRtc_Word16 coeffCntr;
|
||||
WebRtc_Word16 rowCntr;
|
||||
WebRtc_Word16 colCntr;
|
||||
const double* decorrMat;
|
||||
WebRtc_Word16 interVecDim;
|
||||
|
||||
switch(bandwidth)
|
||||
{
|
||||
case isac12kHz:
|
||||
{
|
||||
decorrMat = &WebRtcIsac_kInterVecDecorrMatUb12[0][0];
|
||||
interVecDim = UB_LPC_VEC_PER_FRAME;
|
||||
break;
|
||||
}
|
||||
case isac16kHz:
|
||||
{
|
||||
decorrMat = &WebRtcIsac_kInterVecDecorrMatUb16[0][0];
|
||||
interVecDim = UB16_LPC_VEC_PER_FRAME;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// data * decorrMat
|
||||
//
|
||||
// data is of size 'interVecDim' * 'UB_LPC_ORDER'
|
||||
// That is 'interVecDim' of LAR vectors (mean removed)
|
||||
// in columns each of dimension 'UB_LPC_ORDER'.
|
||||
// matrix is stored column-wise.
|
||||
//
|
||||
|
||||
for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++)
|
||||
{
|
||||
for(colCntr = 0; colCntr < interVecDim; colCntr++)
|
||||
{
|
||||
out[coeffCntr + colCntr * UB_LPC_ORDER] = 0;
|
||||
for(rowCntr = 0; rowCntr < interVecDim; rowCntr++)
|
||||
{
|
||||
out[coeffCntr + colCntr * UB_LPC_ORDER] +=
|
||||
data[coeffCntr + rowCntr * UB_LPC_ORDER] *
|
||||
decorrMat[rowCntr * interVecDim + colCntr];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_QuantizeUncorrLar()
|
||||
*
|
||||
* Quantize the uncorrelated parameters.
|
||||
*
|
||||
* Input:
|
||||
* -data : uncorrelated LAR vectors.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -data : quantized version of the input.
|
||||
* -idx : pointer to quantization indices.
|
||||
*/
|
||||
double
|
||||
WebRtcIsac_QuantizeUncorrLar(
|
||||
double* data,
|
||||
int* recIdx,
|
||||
WebRtc_Word16 bandwidth)
|
||||
{
|
||||
WebRtc_Word16 cntr;
|
||||
WebRtc_Word32 idx;
|
||||
WebRtc_Word16 interVecDim;
|
||||
const double* leftRecPoint;
|
||||
double quantizationStepSize;
|
||||
const WebRtc_Word16* numQuantCell;
|
||||
switch(bandwidth)
|
||||
{
|
||||
case isac12kHz:
|
||||
{
|
||||
leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb12;
|
||||
quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb12;
|
||||
numQuantCell = WebRtcIsac_kLpcShapeNumRecPointUb12;
|
||||
interVecDim = UB_LPC_VEC_PER_FRAME;
|
||||
break;
|
||||
}
|
||||
case isac16kHz:
|
||||
{
|
||||
leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb16;
|
||||
quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb16;
|
||||
numQuantCell = WebRtcIsac_kLpcShapeNumRecPointUb16;
|
||||
interVecDim = UB16_LPC_VEC_PER_FRAME;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Quantize the parametrs.
|
||||
//
|
||||
for(cntr = 0; cntr < UB_LPC_ORDER * interVecDim; cntr++)
|
||||
{
|
||||
idx = (WebRtc_Word32)floor((*data - leftRecPoint[cntr]) /
|
||||
quantizationStepSize + 0.5);
|
||||
if(idx < 0)
|
||||
{
|
||||
idx = 0;
|
||||
}
|
||||
else if(idx >= numQuantCell[cntr])
|
||||
{
|
||||
idx = numQuantCell[cntr] - 1;
|
||||
}
|
||||
|
||||
*data++ = leftRecPoint[cntr] + idx * quantizationStepSize;
|
||||
*recIdx++ = idx;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DequantizeLpcParam()
|
||||
*
|
||||
* Get the quantized value of uncorrelated LARs given the quantization indices.
|
||||
*
|
||||
* Input:
|
||||
* -idx : pointer to quantiztion indices.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -out : pointer to quantized values.
|
||||
*/
|
||||
WebRtc_Word16
|
||||
WebRtcIsac_DequantizeLpcParam(
|
||||
const int* idx,
|
||||
double* out,
|
||||
WebRtc_Word16 bandwidth)
|
||||
{
|
||||
WebRtc_Word16 cntr;
|
||||
WebRtc_Word16 interVecDim;
|
||||
const double* leftRecPoint;
|
||||
double quantizationStepSize;
|
||||
|
||||
switch(bandwidth)
|
||||
{
|
||||
case isac12kHz:
|
||||
{
|
||||
leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb12;
|
||||
quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb12;
|
||||
interVecDim = UB_LPC_VEC_PER_FRAME;
|
||||
break;
|
||||
}
|
||||
case isac16kHz:
|
||||
{
|
||||
leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb16;
|
||||
quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb16;
|
||||
interVecDim = UB16_LPC_VEC_PER_FRAME;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Dequantize given the quantization indices
|
||||
//
|
||||
|
||||
for(cntr = 0; cntr < UB_LPC_ORDER * interVecDim; cntr++)
|
||||
{
|
||||
*out++ = leftRecPoint[cntr] + *idx++ * quantizationStepSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_CorrelateIntraVec()
|
||||
*
|
||||
* This is the inverse of WebRtcIsac_DecorrelateIntraVec().
|
||||
*
|
||||
* Input:
|
||||
* -data : uncorrelated parameters.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -out : correlated parametrs.
|
||||
*/
|
||||
WebRtc_Word16
|
||||
WebRtcIsac_CorrelateIntraVec(
|
||||
const double* data,
|
||||
double* out,
|
||||
WebRtc_Word16 bandwidth)
|
||||
{
|
||||
WebRtc_Word16 vecCntr;
|
||||
WebRtc_Word16 rowCntr;
|
||||
WebRtc_Word16 colCntr;
|
||||
WebRtc_Word16 numVec;
|
||||
const double* ptrData;
|
||||
const double* intraVecDecorrMat;
|
||||
|
||||
switch(bandwidth)
|
||||
{
|
||||
case isac12kHz:
|
||||
{
|
||||
numVec = UB_LPC_VEC_PER_FRAME;
|
||||
intraVecDecorrMat = &WebRtcIsac_kIntraVecDecorrMatUb12[0][0];
|
||||
break;
|
||||
}
|
||||
case isac16kHz:
|
||||
{
|
||||
numVec = UB16_LPC_VEC_PER_FRAME;
|
||||
intraVecDecorrMat = &WebRtcIsac_kIintraVecDecorrMatUb16[0][0];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ptrData = data;
|
||||
for(vecCntr = 0; vecCntr < numVec; vecCntr++)
|
||||
{
|
||||
for(colCntr = 0; colCntr < UB_LPC_ORDER; colCntr++)
|
||||
{
|
||||
*out = 0;
|
||||
for(rowCntr = 0; rowCntr < UB_LPC_ORDER; rowCntr++)
|
||||
{
|
||||
*out += ptrData[rowCntr] *
|
||||
intraVecDecorrMat[rowCntr * UB_LPC_ORDER + colCntr];
|
||||
}
|
||||
out++;
|
||||
}
|
||||
ptrData += UB_LPC_ORDER;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_CorrelateInterVec()
|
||||
*
|
||||
* This is the inverse of WebRtcIsac_DecorrelateInterVec().
|
||||
*
|
||||
* Input:
|
||||
* -data
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -out : correlated parametrs.
|
||||
*/
|
||||
WebRtc_Word16
|
||||
WebRtcIsac_CorrelateInterVec(
|
||||
const double* data,
|
||||
double* out,
|
||||
WebRtc_Word16 bandwidth)
|
||||
{
|
||||
WebRtc_Word16 coeffCntr;
|
||||
WebRtc_Word16 rowCntr;
|
||||
WebRtc_Word16 colCntr;
|
||||
WebRtc_Word16 interVecDim;
|
||||
double myVec[UB16_LPC_VEC_PER_FRAME];
|
||||
const double* interVecDecorrMat;
|
||||
|
||||
switch(bandwidth)
|
||||
{
|
||||
case isac12kHz:
|
||||
{
|
||||
interVecDim = UB_LPC_VEC_PER_FRAME;
|
||||
interVecDecorrMat = &WebRtcIsac_kInterVecDecorrMatUb12[0][0];
|
||||
break;
|
||||
}
|
||||
case isac16kHz:
|
||||
{
|
||||
interVecDim = UB16_LPC_VEC_PER_FRAME;
|
||||
interVecDecorrMat = &WebRtcIsac_kInterVecDecorrMatUb16[0][0];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++)
|
||||
{
|
||||
for(rowCntr = 0; rowCntr < interVecDim; rowCntr++)
|
||||
{
|
||||
myVec[rowCntr] = 0;
|
||||
for(colCntr = 0; colCntr < interVecDim; colCntr++)
|
||||
{
|
||||
myVec[rowCntr] += data[coeffCntr + colCntr * UB_LPC_ORDER] * //*ptrData *
|
||||
interVecDecorrMat[rowCntr * interVecDim + colCntr];
|
||||
//ptrData += UB_LPC_ORDER;
|
||||
}
|
||||
}
|
||||
|
||||
for(rowCntr = 0; rowCntr < interVecDim; rowCntr++)
|
||||
{
|
||||
out[coeffCntr + rowCntr * UB_LPC_ORDER] = myVec[rowCntr];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_AddLarMean()
|
||||
*
|
||||
* This is the inverse of WebRtcIsac_RemoveLarMean()
|
||||
*
|
||||
* Input:
|
||||
* -data : pointer to mean-removed LAR:s.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -data : pointer to LARs.
|
||||
*/
|
||||
WebRtc_Word16
|
||||
WebRtcIsac_AddLarMean(
|
||||
double* data,
|
||||
WebRtc_Word16 bandwidth)
|
||||
{
|
||||
WebRtc_Word16 coeffCntr;
|
||||
WebRtc_Word16 vecCntr;
|
||||
WebRtc_Word16 numVec;
|
||||
const double* meanLAR;
|
||||
|
||||
switch(bandwidth)
|
||||
{
|
||||
case isac12kHz:
|
||||
{
|
||||
numVec = UB_LPC_VEC_PER_FRAME;
|
||||
meanLAR = WebRtcIsac_kMeanLarUb12;
|
||||
break;
|
||||
}
|
||||
case isac16kHz:
|
||||
{
|
||||
numVec = UB16_LPC_VEC_PER_FRAME;
|
||||
meanLAR = WebRtcIsac_kMeanLarUb16;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(vecCntr = 0; vecCntr < numVec; vecCntr++)
|
||||
{
|
||||
for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++)
|
||||
{
|
||||
*data++ += meanLAR[coeffCntr];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_ToLogDomainRemoveMean()
|
||||
*
|
||||
* Transform the LPC gain to log domain then remove the mean value.
|
||||
*
|
||||
* Input:
|
||||
* -lpcGain : pointer to LPC Gain, expecting 6 LPC gains
|
||||
*
|
||||
* Output:
|
||||
* -lpcGain : mean-removed in log domain.
|
||||
*/
|
||||
WebRtc_Word16
|
||||
WebRtcIsac_ToLogDomainRemoveMean(
|
||||
double* data)
|
||||
{
|
||||
WebRtc_Word16 coeffCntr;
|
||||
for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++)
|
||||
{
|
||||
data[coeffCntr] = log(data[coeffCntr]) - WebRtcIsac_kMeanLpcGain;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecorrelateLPGain()
|
||||
*
|
||||
* Decorrelate LPC gains. There are 6 LPC Gains per frame. This is like
|
||||
* multiplying gain vector with decorrelating matrix.
|
||||
*
|
||||
* Input:
|
||||
* -data : LPC gain in log-domain with mean removed.
|
||||
*
|
||||
* Output:
|
||||
* -out : decorrelated parameters.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DecorrelateLPGain(
|
||||
const double* data,
|
||||
double* out)
|
||||
{
|
||||
WebRtc_Word16 rowCntr;
|
||||
WebRtc_Word16 colCntr;
|
||||
|
||||
for(colCntr = 0; colCntr < UB_LPC_GAIN_DIM; colCntr++)
|
||||
{
|
||||
*out = 0;
|
||||
for(rowCntr = 0; rowCntr < UB_LPC_GAIN_DIM; rowCntr++)
|
||||
{
|
||||
*out += data[rowCntr] * WebRtcIsac_kLpcGainDecorrMat[rowCntr][colCntr];
|
||||
}
|
||||
out++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_QuantizeLpcGain()
|
||||
*
|
||||
* Quantize the decorrelated log-domain gains.
|
||||
*
|
||||
* Input:
|
||||
* -lpcGain : uncorrelated LPC gains.
|
||||
*
|
||||
* Output:
|
||||
* -idx : quantization indices
|
||||
* -lpcGain : quantized value of the inpt.
|
||||
*/
|
||||
double WebRtcIsac_QuantizeLpcGain(
|
||||
double* data,
|
||||
int* idx)
|
||||
{
|
||||
WebRtc_Word16 coeffCntr;
|
||||
for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++)
|
||||
{
|
||||
*idx = (int)floor((*data - WebRtcIsac_kLeftRecPointLpcGain[coeffCntr]) /
|
||||
WebRtcIsac_kQSizeLpcGain + 0.5);
|
||||
|
||||
if(*idx < 0)
|
||||
{
|
||||
*idx = 0;
|
||||
}
|
||||
else if(*idx >= WebRtcIsac_kNumQCellLpcGain[coeffCntr])
|
||||
{
|
||||
*idx = WebRtcIsac_kNumQCellLpcGain[coeffCntr] - 1;
|
||||
}
|
||||
*data = WebRtcIsac_kLeftRecPointLpcGain[coeffCntr] + *idx *
|
||||
WebRtcIsac_kQSizeLpcGain;
|
||||
|
||||
data++;
|
||||
idx++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DequantizeLpcGain()
|
||||
*
|
||||
* Get the quantized values given the quantization indices.
|
||||
*
|
||||
* Input:
|
||||
* -idx : pointer to quantization indices.
|
||||
*
|
||||
* Output:
|
||||
* -lpcGains : quantized values of the given parametes.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DequantizeLpcGain(
|
||||
const int* idx,
|
||||
double* out)
|
||||
{
|
||||
WebRtc_Word16 coeffCntr;
|
||||
for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++)
|
||||
{
|
||||
*out = WebRtcIsac_kLeftRecPointLpcGain[coeffCntr] + *idx *
|
||||
WebRtcIsac_kQSizeLpcGain;
|
||||
out++;
|
||||
idx++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_CorrelateLpcGain()
|
||||
*
|
||||
* This is the inverse of WebRtcIsac_DecorrelateLPGain().
|
||||
*
|
||||
* Input:
|
||||
* -data : decorrelated parameters.
|
||||
*
|
||||
* Output:
|
||||
* -out : correlated parameters.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_CorrelateLpcGain(
|
||||
const double* data,
|
||||
double* out)
|
||||
{
|
||||
WebRtc_Word16 rowCntr;
|
||||
WebRtc_Word16 colCntr;
|
||||
|
||||
for(rowCntr = 0; rowCntr < UB_LPC_GAIN_DIM; rowCntr++)
|
||||
{
|
||||
*out = 0;
|
||||
for(colCntr = 0; colCntr < UB_LPC_GAIN_DIM; colCntr++)
|
||||
{
|
||||
*out += WebRtcIsac_kLpcGainDecorrMat[rowCntr][colCntr] * data[colCntr];
|
||||
}
|
||||
out++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_AddMeanToLinearDomain()
|
||||
*
|
||||
* This is the inverse of WebRtcIsac_ToLogDomainRemoveMean().
|
||||
*
|
||||
* Input:
|
||||
* -lpcGain : LPC gain in log-domain & mean removed
|
||||
*
|
||||
* Output:
|
||||
* -lpcGain : LPC gain in normal domain.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_AddMeanToLinearDomain(
|
||||
double* lpcGains)
|
||||
{
|
||||
WebRtc_Word16 coeffCntr;
|
||||
for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++)
|
||||
{
|
||||
lpcGains[coeffCntr] = exp(lpcGains[coeffCntr] + WebRtcIsac_kMeanLpcGain);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* encode_lpc_swb.h
|
||||
*
|
||||
* This file contains declaration of functions used to
|
||||
* encode LPC parameters (Shape & gain) of the upper band.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENCODE_LPC_SWB_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENCODE_LPC_SWB_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "settings.h"
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_RemoveLarMean()
|
||||
*
|
||||
* Remove the means from LAR coefficients.
|
||||
*
|
||||
* Input:
|
||||
* -lar : pointer to lar vectors. LAR vectors are
|
||||
* concatenated.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -lar : pointer to mean-removed LAR:s.
|
||||
*
|
||||
*
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_RemoveLarMean(
|
||||
double* lar,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecorrelateIntraVec()
|
||||
*
|
||||
* Remove the correlation amonge the components of LAR vectors. If LAR vectors
|
||||
* of one frame are put in a matrix where each column is a LAR vector of a
|
||||
* sub-frame, then this is equivalent to multiplying the LAR matrix with
|
||||
* a decorrelting mtrix from left.
|
||||
*
|
||||
* Input:
|
||||
* -inLar : pointer to mean-removed LAR vecrtors.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -out : decorrelated LAR vectors.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DecorrelateIntraVec(
|
||||
const double* inLAR,
|
||||
double* out,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecorrelateInterVec()
|
||||
*
|
||||
* Remover the correlation among mean-removed LAR vectors. If LAR vectors
|
||||
* of one frame are put in a matrix where each column is a LAR vector of a
|
||||
* sub-frame, then this is equivalent to multiplying the LAR matrix with
|
||||
* a decorrelting mtrix from right.
|
||||
*
|
||||
* Input:
|
||||
* -data : pointer to matrix of LAR vectors. The matrix
|
||||
* is stored column-wise.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -out : decorrelated LAR vectors.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DecorrelateInterVec(
|
||||
const double* data,
|
||||
double* out,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_QuantizeUncorrLar()
|
||||
*
|
||||
* Quantize the uncorrelated parameters.
|
||||
*
|
||||
* Input:
|
||||
* -data : uncorrelated LAR vectors.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -data : quantized version of the input.
|
||||
* -idx : pointer to quantization indices.
|
||||
*/
|
||||
double WebRtcIsac_QuantizeUncorrLar(
|
||||
double* data,
|
||||
int* idx,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_CorrelateIntraVec()
|
||||
*
|
||||
* This is the inverse of WebRtcIsac_DecorrelateIntraVec().
|
||||
*
|
||||
* Input:
|
||||
* -data : uncorrelated parameters.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -out : correlated parametrs.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_CorrelateIntraVec(
|
||||
const double* data,
|
||||
double* out,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_CorrelateInterVec()
|
||||
*
|
||||
* This is the inverse of WebRtcIsac_DecorrelateInterVec().
|
||||
*
|
||||
* Input:
|
||||
* -data
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -out : correlated parametrs.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_CorrelateInterVec(
|
||||
const double* data,
|
||||
double* out,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_AddLarMean()
|
||||
*
|
||||
* This is the inverse of WebRtcIsac_RemoveLarMean()
|
||||
*
|
||||
* Input:
|
||||
* -data : pointer to mean-removed LAR:s.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -data : pointer to LARs.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_AddLarMean(
|
||||
double* data,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DequantizeLpcParam()
|
||||
*
|
||||
* Get the quantized value of uncorrelated LARs given the quantization indices.
|
||||
*
|
||||
* Input:
|
||||
* -idx : pointer to quantiztion indices.
|
||||
* -bandwidth : indicates if the given LAR vectors belong
|
||||
* to SWB-12kHz or SWB-16kHz.
|
||||
*
|
||||
* Output:
|
||||
* -out : pointer to quantized values.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DequantizeLpcParam(
|
||||
const int* idx,
|
||||
double* out,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_ToLogDomainRemoveMean()
|
||||
*
|
||||
* Transform the LPC gain to log domain then remove the mean value.
|
||||
*
|
||||
* Input:
|
||||
* -lpcGain : pointer to LPC Gain, expecting 6 LPC gains
|
||||
*
|
||||
* Output:
|
||||
* -lpcGain : mean-removed in log domain.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_ToLogDomainRemoveMean(
|
||||
double* lpGains);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecorrelateLPGain()
|
||||
*
|
||||
* Decorrelate LPC gains. There are 6 LPC Gains per frame. This is like
|
||||
* multiplying gain vector with decorrelating matrix.
|
||||
*
|
||||
* Input:
|
||||
* -data : LPC gain in log-domain with mean removed.
|
||||
*
|
||||
* Output:
|
||||
* -out : decorrelated parameters.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DecorrelateLPGain(
|
||||
const double* data,
|
||||
double* out);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_QuantizeLpcGain()
|
||||
*
|
||||
* Quantize the decorrelated log-domain gains.
|
||||
*
|
||||
* Input:
|
||||
* -lpcGain : uncorrelated LPC gains.
|
||||
*
|
||||
* Output:
|
||||
* -idx : quantization indices
|
||||
* -lpcGain : quantized value of the inpt.
|
||||
*/
|
||||
double WebRtcIsac_QuantizeLpcGain(
|
||||
double* lpGains,
|
||||
int* idx);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DequantizeLpcGain()
|
||||
*
|
||||
* Get the quantized values given the quantization indices.
|
||||
*
|
||||
* Input:
|
||||
* -idx : pointer to quantization indices.
|
||||
*
|
||||
* Output:
|
||||
* -lpcGains : quantized values of the given parametes.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DequantizeLpcGain(
|
||||
const int* idx,
|
||||
double* lpGains);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_CorrelateLpcGain()
|
||||
*
|
||||
* This is the inverse of WebRtcIsac_DecorrelateLPGain().
|
||||
*
|
||||
* Input:
|
||||
* -data : decorrelated parameters.
|
||||
*
|
||||
* Output:
|
||||
* -out : correlated parameters.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_CorrelateLpcGain(
|
||||
const double* data,
|
||||
double* out);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_AddMeanToLinearDomain()
|
||||
*
|
||||
* This is the inverse of WebRtcIsac_ToLogDomainRemoveMean().
|
||||
*
|
||||
* Input:
|
||||
* -lpcGain : LPC gain in log-domain & mean removed
|
||||
*
|
||||
* Output:
|
||||
* -lpcGain : LPC gain in normal domain.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_AddMeanToLinearDomain(
|
||||
double* lpcGains);
|
||||
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENCODE_LPC_SWB_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,412 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* entropy_coding.h
|
||||
*
|
||||
* This header file declares all of the functions used to arithmetically
|
||||
* encode the iSAC bistream
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
/* decode complex spectrum (return number of bytes in stream) */
|
||||
int WebRtcIsac_DecodeSpecLb(Bitstr *streamdata,
|
||||
double *fr,
|
||||
double *fi,
|
||||
WebRtc_Word16 AvgPitchGain_Q12);
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecodeSpecUB16()
|
||||
* Decode real and imaginary part of the DFT coefficients, given a bit-stream.
|
||||
* This function is called when the codec is in 0-16 kHz bandwidth.
|
||||
* The decoded DFT coefficient can be transformed to time domain by
|
||||
* WebRtcIsac_Time2Spec().
|
||||
*
|
||||
* Input:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Output:
|
||||
* -*fr : pointer to a buffer where the real part of DFT
|
||||
* coefficients are written to.
|
||||
* -*fi : pointer to a buffer where the imaginary part
|
||||
* of DFT coefficients are written to.
|
||||
*
|
||||
* Return value : < 0 if an error occures
|
||||
* 0 if succeeded.
|
||||
*/
|
||||
int WebRtcIsac_DecodeSpecUB16(
|
||||
Bitstr* streamdata,
|
||||
double* fr,
|
||||
double* fi);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecodeSpecUB12()
|
||||
* Decode real and imaginary part of the DFT coefficients, given a bit-stream.
|
||||
* This function is called when the codec is in 0-12 kHz bandwidth.
|
||||
* The decoded DFT coefficient can be transformed to time domain by
|
||||
* WebRtcIsac_Time2Spec().
|
||||
*
|
||||
* Input:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Output:
|
||||
* -*fr : pointer to a buffer where the real part of DFT
|
||||
* coefficients are written to.
|
||||
* -*fi : pointer to a buffer where the imaginary part
|
||||
* of DFT coefficients are written to.
|
||||
*
|
||||
* Return value : < 0 if an error occures
|
||||
* 0 if succeeded.
|
||||
*/
|
||||
int WebRtcIsac_DecodeSpecUB12(
|
||||
Bitstr* streamdata,
|
||||
double* fr,
|
||||
double* fi);
|
||||
|
||||
|
||||
/* encode complex spectrum */
|
||||
int WebRtcIsac_EncodeSpecLb(const WebRtc_Word16* fr,
|
||||
const WebRtc_Word16* fi,
|
||||
Bitstr* streamdata,
|
||||
WebRtc_Word16 AvgPitchGain_Q12);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncodeSpecUB16()
|
||||
* Quantize and encode real and imaginary part of the DFT coefficients.
|
||||
* This function is called when the codec is in 0-16 kHz bandwidth.
|
||||
* The real and imaginary part are computed by calling WebRtcIsac_Time2Spec().
|
||||
*
|
||||
*
|
||||
* Input:
|
||||
* -*fr : pointer to a buffer where the real part of DFT
|
||||
* coefficients are stored.
|
||||
* -*fi : pointer to a buffer where the imaginary part
|
||||
* of DFT coefficients are stored.
|
||||
*
|
||||
* Output:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Return value : < 0 if an error occures
|
||||
* 0 if succeeded.
|
||||
*/
|
||||
int WebRtcIsac_EncodeSpecUB16(
|
||||
const WebRtc_Word16* fr,
|
||||
const WebRtc_Word16* fi,
|
||||
Bitstr* streamdata);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncodeSpecUB12()
|
||||
* Quantize and encode real and imaginary part of the DFT coefficients.
|
||||
* This function is called when the codec is in 0-12 kHz bandwidth.
|
||||
* The real and imaginary part are computed by calling WebRtcIsac_Time2Spec().
|
||||
*
|
||||
*
|
||||
* Input:
|
||||
* -*fr : pointer to a buffer where the real part of DFT
|
||||
* coefficients are stored.
|
||||
* -*fi : pointer to a buffer where the imaginary part
|
||||
* of DFT coefficients are stored.
|
||||
*
|
||||
* Output:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Return value : < 0 if an error occures
|
||||
* 0 if succeeded.
|
||||
*/
|
||||
int WebRtcIsac_EncodeSpecUB12(
|
||||
const WebRtc_Word16* fr,
|
||||
const WebRtc_Word16* fi,
|
||||
Bitstr* streamdata);
|
||||
|
||||
|
||||
/* decode & dequantize LPC Coef */
|
||||
int WebRtcIsac_DecodeLpcCoef(Bitstr *streamdata, double *LPCCoef, int *outmodel);
|
||||
int WebRtcIsac_DecodeLpcCoefUB(
|
||||
Bitstr* streamdata,
|
||||
double* lpcVecs,
|
||||
double* percepFilterGains,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
int WebRtcIsac_DecodeLpc(Bitstr *streamdata, double *LPCCoef_lo, double *LPCCoef_hi, int *outmodel);
|
||||
|
||||
/* quantize & code LPC Coef */
|
||||
void WebRtcIsac_EncodeLpcLb(double *LPCCoef_lo, double *LPCCoef_hi, int *model, double *size, Bitstr *streamdata, ISAC_SaveEncData_t* encData);
|
||||
void WebRtcIsac_EncodeLpcGainLb(double *LPCCoef_lo, double *LPCCoef_hi, int model, Bitstr *streamdata, ISAC_SaveEncData_t* encData);
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncodeLpcUB()
|
||||
* Encode LPC parameters, given as A-polynomial, of upper-band. The encoding
|
||||
* is performed in LAR domain.
|
||||
* For the upper-band, we compute and encode LPC of some sub-frames, LPC of
|
||||
* other sub-frames are computed by linear interpolation, in LAR domain. This
|
||||
* function performs the interpolation and returns the LPC of all sub-frames.
|
||||
*
|
||||
* Inputs:
|
||||
* - lpcCoef : a buffer containing A-polynomials of sub-frames
|
||||
* (excluding first coefficient that is 1).
|
||||
* - bandwidth : specifies if the codec is operating at 0-12 kHz
|
||||
* or 0-16 kHz mode.
|
||||
*
|
||||
* Input/output:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Output:
|
||||
* - interpolLPCCoeff : Decoded and interpolated LPC (A-polynomial)
|
||||
* of all sub-frames.
|
||||
* If LP analysis is of order K, and there are N
|
||||
* sub-frames then this is a buffer of size
|
||||
* (k + 1) * N, each vector starts with the LPC gain
|
||||
* of the corresponding sub-frame. The LPC gains
|
||||
* are encoded and inserted after this function is
|
||||
* called. The first A-coefficient which is 1 is not
|
||||
* included.
|
||||
*
|
||||
* Return value : 0 if encoding is successful,
|
||||
* <0 if failed to encode.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_EncodeLpcUB(
|
||||
double* lpcCoeff,
|
||||
Bitstr* streamdata,
|
||||
double* interpolLPCCoeff,
|
||||
WebRtc_Word16 bandwidth,
|
||||
ISACUBSaveEncDataStruct* encData);
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecodeInterpolLpcUb()
|
||||
* Decode LPC coefficients and interpolate to get the coefficients fo all
|
||||
* sub-frmaes.
|
||||
*
|
||||
* Inputs:
|
||||
* - bandwidth : spepecifies if the codec is in 0-12 kHz or
|
||||
* 0-16 kHz mode.
|
||||
*
|
||||
* Input/output:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Output:
|
||||
* - percepFilterParam : Decoded and interpolated LPC (A-polynomial) of
|
||||
* all sub-frames.
|
||||
* If LP analysis is of order K, and there are N
|
||||
* sub-frames then this is a buffer of size
|
||||
* (k + 1) * N, each vector starts with the LPC gain
|
||||
* of the corresponding sub-frame. The LPC gains
|
||||
* are encoded and inserted after this function is
|
||||
* called. The first A-coefficient which is 1 is not
|
||||
* included.
|
||||
*
|
||||
* Return value : 0 if encoding is successful,
|
||||
* <0 if failed to encode.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DecodeInterpolLpcUb(
|
||||
Bitstr* streamdata,
|
||||
double* percepFilterParam,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
/* decode & dequantize RC */
|
||||
int WebRtcIsac_DecodeRc(Bitstr *streamdata, WebRtc_Word16 *RCQ15);
|
||||
|
||||
/* quantize & code RC */
|
||||
void WebRtcIsac_EncodeRc(WebRtc_Word16 *RCQ15, Bitstr *streamdata);
|
||||
|
||||
/* decode & dequantize squared Gain */
|
||||
int WebRtcIsac_DecodeGain2(Bitstr *streamdata, WebRtc_Word32 *Gain2);
|
||||
|
||||
/* quantize & code squared Gain (input is squared gain) */
|
||||
int WebRtcIsac_EncodeGain2(WebRtc_Word32 *gain2, Bitstr *streamdata);
|
||||
|
||||
void WebRtcIsac_EncodePitchGain(WebRtc_Word16* PitchGains_Q12, Bitstr* streamdata, ISAC_SaveEncData_t* encData);
|
||||
|
||||
void WebRtcIsac_EncodePitchLag(double* PitchLags, WebRtc_Word16* PitchGain_Q12, Bitstr* streamdata, ISAC_SaveEncData_t* encData);
|
||||
|
||||
int WebRtcIsac_DecodePitchGain(Bitstr *streamdata, WebRtc_Word16 *PitchGain_Q12);
|
||||
int WebRtcIsac_DecodePitchLag(Bitstr *streamdata, WebRtc_Word16 *PitchGain_Q12, double *PitchLag);
|
||||
|
||||
int WebRtcIsac_DecodeFrameLen(Bitstr *streamdata, WebRtc_Word16 *framelength);
|
||||
int WebRtcIsac_EncodeFrameLen(WebRtc_Word16 framelength, Bitstr *streamdata);
|
||||
int WebRtcIsac_DecodeSendBW(Bitstr *streamdata, WebRtc_Word16 *BWno);
|
||||
void WebRtcIsac_EncodeReceiveBw(int *BWno, Bitstr *streamdata);
|
||||
|
||||
/* step-down */
|
||||
void WebRtcIsac_Poly2Rc(double *a, int N, double *RC);
|
||||
|
||||
/* step-up */
|
||||
void WebRtcIsac_Rc2Poly(double *RC, int N, double *a);
|
||||
|
||||
void WebRtcIsac_TranscodeLPCCoef(double *LPCCoef_lo, double *LPCCoef_hi, int model,
|
||||
int *index_g);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncodeLpcGainUb()
|
||||
* Encode LPC gains of sub-Frames.
|
||||
*
|
||||
* Input/outputs:
|
||||
* - lpGains : a buffer which contains 'SUBFRAME' number of
|
||||
* LP gains to be encoded. The input values are
|
||||
* overwritten by the quantized values.
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Output:
|
||||
* - lpcGainIndex : quantization indices for lpc gains, these will
|
||||
* be stored to be used for FEC.
|
||||
*/
|
||||
void WebRtcIsac_EncodeLpcGainUb(
|
||||
double* lpGains,
|
||||
Bitstr* streamdata,
|
||||
int* lpcGainIndex);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncodeLpcGainUb()
|
||||
* Store LPC gains of sub-Frames in 'streamdata'.
|
||||
*
|
||||
* Input:
|
||||
* - lpGains : a buffer which contains 'SUBFRAME' number of
|
||||
* LP gains to be encoded.
|
||||
* Input/outputs:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
*/
|
||||
void WebRtcIsac_StoreLpcGainUb(
|
||||
double* lpGains,
|
||||
Bitstr* streamdata);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecodeLpcGainUb()
|
||||
* Decode the LPC gain of sub-frames.
|
||||
*
|
||||
* Input/output:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Output:
|
||||
* - lpGains : a buffer where decoded LPC gians will be stored.
|
||||
*
|
||||
* Return value : 0 if succeeded.
|
||||
* <0 if failed.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DecodeLpcGainUb(
|
||||
double* lpGains,
|
||||
Bitstr* streamdata);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncodeBandwidth()
|
||||
* Encode if the bandwidth of encoded audio is 0-12 kHz or 0-16 kHz.
|
||||
*
|
||||
* Input:
|
||||
* - bandwidth : an enumerator specifying if the codec in is
|
||||
* 0-12 kHz or 0-16 kHz mode.
|
||||
*
|
||||
* Input/output:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Return value : 0 if succeeded.
|
||||
* <0 if failed.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_EncodeBandwidth(
|
||||
enum ISACBandwidth bandwidth,
|
||||
Bitstr* streamData);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecodeBandwidth()
|
||||
* Decode the bandwidth of the encoded audio, i.e. if the bandwidth is 0-12 kHz
|
||||
* or 0-16 kHz.
|
||||
*
|
||||
* Input/output:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Output:
|
||||
* - bandwidth : an enumerator specifying if the codec is in
|
||||
* 0-12 kHz or 0-16 kHz mode.
|
||||
*
|
||||
* Return value : 0 if succeeded.
|
||||
* <0 if failed.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DecodeBandwidth(
|
||||
Bitstr* streamData,
|
||||
enum ISACBandwidth* bandwidth);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncodeJitterInfo()
|
||||
* Decode the jitter information.
|
||||
*
|
||||
* Input/output:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Input:
|
||||
* - jitterInfo : one bit of info specifying if the channel is
|
||||
* in high/low jitter. Zero indicates low jitter
|
||||
* and one indicates high jitter.
|
||||
*
|
||||
* Return value : 0 if succeeded.
|
||||
* <0 if failed.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_EncodeJitterInfo(
|
||||
WebRtc_Word32 jitterIndex,
|
||||
Bitstr* streamData);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecodeJitterInfo()
|
||||
* Decode the jitter information.
|
||||
*
|
||||
* Input/output:
|
||||
* - streamdata : pointer to a stucture containg the encoded
|
||||
* data and theparameters needed for entropy
|
||||
* coding.
|
||||
*
|
||||
* Output:
|
||||
* - jitterInfo : one bit of info specifying if the channel is
|
||||
* in high/low jitter. Zero indicates low jitter
|
||||
* and one indicates high jitter.
|
||||
*
|
||||
* Return value : 0 if succeeded.
|
||||
* <0 if failed.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DecodeJitterInfo(
|
||||
Bitstr* streamData,
|
||||
WebRtc_Word32* jitterInfo);
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_ */
|
|
@ -0,0 +1,947 @@
|
|||
/*
|
||||
* Copyright(c)1995,97 Mark Olesen <olesen@me.QueensU.CA>
|
||||
* Queen's Univ at Kingston (Canada)
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for
|
||||
* any purpose without fee is hereby granted, provided that this
|
||||
* entire notice is included in all copies of any software which is
|
||||
* or includes a copy or modification of this software and in all
|
||||
* copies of the supporting documentation for such software.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR QUEEN'S
|
||||
* UNIVERSITY AT KINGSTON MAKES ANY REPRESENTATION OR WARRANTY OF ANY
|
||||
* KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS
|
||||
* FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*
|
||||
* All of which is to say that you can do what you like with this
|
||||
* source code provided you don't try to sell it as your own and you
|
||||
* include an unaltered copy of this message (including the
|
||||
* copyright).
|
||||
*
|
||||
* It is also implicitly understood that bug fixes and improvements
|
||||
* should make their way back to the general Internet community so
|
||||
* that everyone benefits.
|
||||
*
|
||||
* Changes:
|
||||
* Trivial type modifications by the WebRTC authors.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* File:
|
||||
* WebRtcIsac_Fftn.c
|
||||
*
|
||||
* Public:
|
||||
* WebRtcIsac_Fftn / fftnf ();
|
||||
*
|
||||
* Private:
|
||||
* WebRtcIsac_Fftradix / fftradixf ();
|
||||
*
|
||||
* Descript:
|
||||
* multivariate complex Fourier transform, computed in place
|
||||
* using mixed-radix Fast Fourier Transform algorithm.
|
||||
*
|
||||
* Fortran code by:
|
||||
* RC Singleton, Stanford Research Institute, Sept. 1968
|
||||
*
|
||||
* translated by f2c (version 19950721).
|
||||
*
|
||||
* int WebRtcIsac_Fftn (int ndim, const int dims[], REAL Re[], REAL Im[],
|
||||
* int iSign, double scaling);
|
||||
*
|
||||
* NDIM = the total number dimensions
|
||||
* DIMS = a vector of array sizes
|
||||
* if NDIM is zero then DIMS must be zero-terminated
|
||||
*
|
||||
* RE and IM hold the real and imaginary components of the data, and return
|
||||
* the resulting real and imaginary Fourier coefficients. Multidimensional
|
||||
* data *must* be allocated contiguously. There is no limit on the number
|
||||
* of dimensions.
|
||||
*
|
||||
* ISIGN = the sign of the complex exponential (ie, forward or inverse FFT)
|
||||
* the magnitude of ISIGN (normally 1) is used to determine the
|
||||
* correct indexing increment (see below).
|
||||
*
|
||||
* SCALING = normalizing constant by which the final result is *divided*
|
||||
* if SCALING == -1, normalize by total dimension of the transform
|
||||
* if SCALING < -1, normalize by the square-root of the total dimension
|
||||
*
|
||||
* example:
|
||||
* tri-variate transform with Re[n1][n2][n3], Im[n1][n2][n3]
|
||||
*
|
||||
* int dims[3] = {n1,n2,n3}
|
||||
* WebRtcIsac_Fftn (3, dims, Re, Im, 1, scaling);
|
||||
*
|
||||
*-----------------------------------------------------------------------*
|
||||
* int WebRtcIsac_Fftradix (REAL Re[], REAL Im[], size_t nTotal, size_t nPass,
|
||||
* size_t nSpan, int iSign, size_t max_factors,
|
||||
* size_t max_perm);
|
||||
*
|
||||
* RE, IM - see above documentation
|
||||
*
|
||||
* Although there is no limit on the number of dimensions, WebRtcIsac_Fftradix() must
|
||||
* be called once for each dimension, but the calls may be in any order.
|
||||
*
|
||||
* NTOTAL = the total number of complex data values
|
||||
* NPASS = the dimension of the current variable
|
||||
* NSPAN/NPASS = the spacing of consecutive data values while indexing the
|
||||
* current variable
|
||||
* ISIGN - see above documentation
|
||||
*
|
||||
* example:
|
||||
* tri-variate transform with Re[n1][n2][n3], Im[n1][n2][n3]
|
||||
*
|
||||
* WebRtcIsac_Fftradix (Re, Im, n1*n2*n3, n1, n1, 1, maxf, maxp);
|
||||
* WebRtcIsac_Fftradix (Re, Im, n1*n2*n3, n2, n1*n2, 1, maxf, maxp);
|
||||
* WebRtcIsac_Fftradix (Re, Im, n1*n2*n3, n3, n1*n2*n3, 1, maxf, maxp);
|
||||
*
|
||||
* single-variate transform,
|
||||
* NTOTAL = N = NSPAN = (number of complex data values),
|
||||
*
|
||||
* WebRtcIsac_Fftradix (Re, Im, n, n, n, 1, maxf, maxp);
|
||||
*
|
||||
* The data can also be stored in a single array with alternating real and
|
||||
* imaginary parts, the magnitude of ISIGN is changed to 2 to give correct
|
||||
* indexing increment, and data [0] and data [1] used to pass the initial
|
||||
* addresses for the sequences of real and imaginary values,
|
||||
*
|
||||
* example:
|
||||
* REAL data [2*NTOTAL];
|
||||
* WebRtcIsac_Fftradix ( &data[0], &data[1], NTOTAL, nPass, nSpan, 2, maxf, maxp);
|
||||
*
|
||||
* for temporary allocation:
|
||||
*
|
||||
* MAX_FACTORS >= the maximum prime factor of NPASS
|
||||
* MAX_PERM >= the number of prime factors of NPASS. In addition,
|
||||
* if the square-free portion K of NPASS has two or more prime
|
||||
* factors, then MAX_PERM >= (K-1)
|
||||
*
|
||||
* storage in FACTOR for a maximum of 15 prime factors of NPASS. if NPASS
|
||||
* has more than one square-free factor, the product of the square-free
|
||||
* factors must be <= 210 array storage for maximum prime factor of 23 the
|
||||
* following two constants should agree with the array dimensions.
|
||||
*
|
||||
*----------------------------------------------------------------------*/
|
||||
#include "fft.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
|
||||
/* double precision routine */
|
||||
static int
|
||||
WebRtcIsac_Fftradix (double Re[], double Im[],
|
||||
size_t nTotal, size_t nPass, size_t nSpan, int isign,
|
||||
int max_factors, unsigned int max_perm,
|
||||
FFTstr *fftstate);
|
||||
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846264338327950288
|
||||
#endif
|
||||
|
||||
#ifndef SIN60
|
||||
# define SIN60 0.86602540378443865 /* sin(60 deg) */
|
||||
# define COS72 0.30901699437494742 /* cos(72 deg) */
|
||||
# define SIN72 0.95105651629515357 /* sin(72 deg) */
|
||||
#endif
|
||||
|
||||
# define REAL double
|
||||
# define FFTN WebRtcIsac_Fftn
|
||||
# define FFTNS "fftn"
|
||||
# define FFTRADIX WebRtcIsac_Fftradix
|
||||
# define FFTRADIXS "fftradix"
|
||||
|
||||
|
||||
int WebRtcIsac_Fftns(unsigned int ndim, const int dims[],
|
||||
double Re[],
|
||||
double Im[],
|
||||
int iSign,
|
||||
double scaling,
|
||||
FFTstr *fftstate)
|
||||
{
|
||||
|
||||
size_t nSpan, nPass, nTotal;
|
||||
unsigned int i;
|
||||
int ret, max_factors, max_perm;
|
||||
|
||||
/*
|
||||
* tally the number of elements in the data array
|
||||
* and determine the number of dimensions
|
||||
*/
|
||||
nTotal = 1;
|
||||
if (ndim && dims [0])
|
||||
{
|
||||
for (i = 0; i < ndim; i++)
|
||||
{
|
||||
if (dims [i] <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
nTotal *= dims [i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ndim = 0;
|
||||
for (i = 0; dims [i]; i++)
|
||||
{
|
||||
if (dims [i] <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
nTotal *= dims [i];
|
||||
ndim++;
|
||||
}
|
||||
}
|
||||
|
||||
/* determine maximum number of factors and permuations */
|
||||
#if 1
|
||||
/*
|
||||
* follow John Beale's example, just use the largest dimension and don't
|
||||
* worry about excess allocation. May be someone else will do it?
|
||||
*/
|
||||
max_factors = max_perm = 1;
|
||||
for (i = 0; i < ndim; i++)
|
||||
{
|
||||
nSpan = dims [i];
|
||||
if ((int)nSpan > max_factors)
|
||||
{
|
||||
max_factors = (int)nSpan;
|
||||
}
|
||||
if ((int)nSpan > max_perm)
|
||||
{
|
||||
max_perm = (int)nSpan;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* use the constants used in the original Fortran code */
|
||||
max_factors = 23;
|
||||
max_perm = 209;
|
||||
#endif
|
||||
/* loop over the dimensions: */
|
||||
nPass = 1;
|
||||
for (i = 0; i < ndim; i++)
|
||||
{
|
||||
nSpan = dims [i];
|
||||
nPass *= nSpan;
|
||||
ret = FFTRADIX (Re, Im, nTotal, nSpan, nPass, iSign,
|
||||
max_factors, max_perm, fftstate);
|
||||
/* exit, clean-up already done */
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Divide through by the normalizing constant: */
|
||||
if (scaling && scaling != 1.0)
|
||||
{
|
||||
if (iSign < 0) iSign = -iSign;
|
||||
if (scaling < 0.0)
|
||||
{
|
||||
scaling = (double)nTotal;
|
||||
if (scaling < -1.0)
|
||||
scaling = sqrt (scaling);
|
||||
}
|
||||
scaling = 1.0 / scaling; /* multiply is often faster */
|
||||
for (i = 0; i < nTotal; i += iSign)
|
||||
{
|
||||
Re [i] *= scaling;
|
||||
Im [i] *= scaling;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* singleton's mixed radix routine
|
||||
*
|
||||
* could move allocation out to WebRtcIsac_Fftn(), but leave it here so that it's
|
||||
* possible to make this a standalone function
|
||||
*/
|
||||
|
||||
static int FFTRADIX (REAL Re[],
|
||||
REAL Im[],
|
||||
size_t nTotal,
|
||||
size_t nPass,
|
||||
size_t nSpan,
|
||||
int iSign,
|
||||
int max_factors,
|
||||
unsigned int max_perm,
|
||||
FFTstr *fftstate)
|
||||
{
|
||||
int ii, mfactor, kspan, ispan, inc;
|
||||
int j, jc, jf, jj, k, k1, k2, k3, k4, kk, kt, nn, ns, nt;
|
||||
|
||||
|
||||
REAL radf;
|
||||
REAL c1, c2, c3, cd, aa, aj, ak, ajm, ajp, akm, akp;
|
||||
REAL s1, s2, s3, sd, bb, bj, bk, bjm, bjp, bkm, bkp;
|
||||
|
||||
REAL *Rtmp = NULL; /* temp space for real part*/
|
||||
REAL *Itmp = NULL; /* temp space for imaginary part */
|
||||
REAL *Cos = NULL; /* Cosine values */
|
||||
REAL *Sin = NULL; /* Sine values */
|
||||
|
||||
REAL s60 = SIN60; /* sin(60 deg) */
|
||||
REAL c72 = COS72; /* cos(72 deg) */
|
||||
REAL s72 = SIN72; /* sin(72 deg) */
|
||||
REAL pi2 = M_PI; /* use PI first, 2 PI later */
|
||||
|
||||
|
||||
fftstate->SpaceAlloced = 0;
|
||||
fftstate->MaxPermAlloced = 0;
|
||||
|
||||
|
||||
// initialize to avoid warnings
|
||||
k3 = c2 = c3 = s2 = s3 = 0.0;
|
||||
|
||||
if (nPass < 2)
|
||||
return 0;
|
||||
|
||||
/* allocate storage */
|
||||
if (fftstate->SpaceAlloced < max_factors * sizeof (REAL))
|
||||
{
|
||||
#ifdef SUN_BROKEN_REALLOC
|
||||
if (!fftstate->SpaceAlloced) /* first time */
|
||||
{
|
||||
fftstate->SpaceAlloced = max_factors * sizeof (REAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
fftstate->SpaceAlloced = max_factors * sizeof (REAL);
|
||||
#ifdef SUN_BROKEN_REALLOC
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* allow full use of alloc'd space */
|
||||
max_factors = fftstate->SpaceAlloced / sizeof (REAL);
|
||||
}
|
||||
if (fftstate->MaxPermAlloced < max_perm)
|
||||
{
|
||||
#ifdef SUN_BROKEN_REALLOC
|
||||
if (!fftstate->MaxPermAlloced) /* first time */
|
||||
else
|
||||
#endif
|
||||
fftstate->MaxPermAlloced = max_perm;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* allow full use of alloc'd space */
|
||||
max_perm = fftstate->MaxPermAlloced;
|
||||
}
|
||||
if (fftstate->Tmp0 == NULL || fftstate->Tmp1 == NULL || fftstate->Tmp2 == NULL || fftstate->Tmp3 == NULL
|
||||
|| fftstate->Perm == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* assign pointers */
|
||||
Rtmp = (REAL *) fftstate->Tmp0;
|
||||
Itmp = (REAL *) fftstate->Tmp1;
|
||||
Cos = (REAL *) fftstate->Tmp2;
|
||||
Sin = (REAL *) fftstate->Tmp3;
|
||||
|
||||
/*
|
||||
* Function Body
|
||||
*/
|
||||
inc = iSign;
|
||||
if (iSign < 0) {
|
||||
s72 = -s72;
|
||||
s60 = -s60;
|
||||
pi2 = -pi2;
|
||||
inc = -inc; /* absolute value */
|
||||
}
|
||||
|
||||
/* adjust for strange increments */
|
||||
nt = inc * (int)nTotal;
|
||||
ns = inc * (int)nSpan;
|
||||
kspan = ns;
|
||||
|
||||
nn = nt - inc;
|
||||
jc = ns / (int)nPass;
|
||||
radf = pi2 * (double) jc;
|
||||
pi2 *= 2.0; /* use 2 PI from here on */
|
||||
|
||||
ii = 0;
|
||||
jf = 0;
|
||||
/* determine the factors of n */
|
||||
mfactor = 0;
|
||||
k = (int)nPass;
|
||||
while (k % 16 == 0) {
|
||||
mfactor++;
|
||||
fftstate->factor [mfactor - 1] = 4;
|
||||
k /= 16;
|
||||
}
|
||||
j = 3;
|
||||
jj = 9;
|
||||
do {
|
||||
while (k % jj == 0) {
|
||||
mfactor++;
|
||||
fftstate->factor [mfactor - 1] = j;
|
||||
k /= jj;
|
||||
}
|
||||
j += 2;
|
||||
jj = j * j;
|
||||
} while (jj <= k);
|
||||
if (k <= 4) {
|
||||
kt = mfactor;
|
||||
fftstate->factor [mfactor] = k;
|
||||
if (k != 1)
|
||||
mfactor++;
|
||||
} else {
|
||||
if (k - (k / 4 << 2) == 0) {
|
||||
mfactor++;
|
||||
fftstate->factor [mfactor - 1] = 2;
|
||||
k /= 4;
|
||||
}
|
||||
kt = mfactor;
|
||||
j = 2;
|
||||
do {
|
||||
if (k % j == 0) {
|
||||
mfactor++;
|
||||
fftstate->factor [mfactor - 1] = j;
|
||||
k /= j;
|
||||
}
|
||||
j = ((j + 1) / 2 << 1) + 1;
|
||||
} while (j <= k);
|
||||
}
|
||||
if (kt) {
|
||||
j = kt;
|
||||
do {
|
||||
mfactor++;
|
||||
fftstate->factor [mfactor - 1] = fftstate->factor [j - 1];
|
||||
j--;
|
||||
} while (j);
|
||||
}
|
||||
|
||||
/* test that mfactors is in range */
|
||||
if (mfactor > NFACTOR)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* compute fourier transform */
|
||||
for (;;) {
|
||||
sd = radf / (double) kspan;
|
||||
cd = sin(sd);
|
||||
cd = 2.0 * cd * cd;
|
||||
sd = sin(sd + sd);
|
||||
kk = 0;
|
||||
ii++;
|
||||
|
||||
switch (fftstate->factor [ii - 1]) {
|
||||
case 2:
|
||||
/* transform for factor of 2 (including rotation factor) */
|
||||
kspan /= 2;
|
||||
k1 = kspan + 2;
|
||||
do {
|
||||
do {
|
||||
k2 = kk + kspan;
|
||||
ak = Re [k2];
|
||||
bk = Im [k2];
|
||||
Re [k2] = Re [kk] - ak;
|
||||
Im [k2] = Im [kk] - bk;
|
||||
Re [kk] += ak;
|
||||
Im [kk] += bk;
|
||||
kk = k2 + kspan;
|
||||
} while (kk < nn);
|
||||
kk -= nn;
|
||||
} while (kk < jc);
|
||||
if (kk >= kspan)
|
||||
goto Permute_Results_Label; /* exit infinite loop */
|
||||
do {
|
||||
c1 = 1.0 - cd;
|
||||
s1 = sd;
|
||||
do {
|
||||
do {
|
||||
do {
|
||||
k2 = kk + kspan;
|
||||
ak = Re [kk] - Re [k2];
|
||||
bk = Im [kk] - Im [k2];
|
||||
Re [kk] += Re [k2];
|
||||
Im [kk] += Im [k2];
|
||||
Re [k2] = c1 * ak - s1 * bk;
|
||||
Im [k2] = s1 * ak + c1 * bk;
|
||||
kk = k2 + kspan;
|
||||
} while (kk < (nt-1));
|
||||
k2 = kk - nt;
|
||||
c1 = -c1;
|
||||
kk = k1 - k2;
|
||||
} while (kk > k2);
|
||||
ak = c1 - (cd * c1 + sd * s1);
|
||||
s1 = sd * c1 - cd * s1 + s1;
|
||||
c1 = 2.0 - (ak * ak + s1 * s1);
|
||||
s1 *= c1;
|
||||
c1 *= ak;
|
||||
kk += jc;
|
||||
} while (kk < k2);
|
||||
k1 += inc + inc;
|
||||
kk = (k1 - kspan + 1) / 2 + jc - 1;
|
||||
} while (kk < (jc + jc));
|
||||
break;
|
||||
|
||||
case 4: /* transform for factor of 4 */
|
||||
ispan = kspan;
|
||||
kspan /= 4;
|
||||
|
||||
do {
|
||||
c1 = 1.0;
|
||||
s1 = 0.0;
|
||||
do {
|
||||
do {
|
||||
k1 = kk + kspan;
|
||||
k2 = k1 + kspan;
|
||||
k3 = k2 + kspan;
|
||||
akp = Re [kk] + Re [k2];
|
||||
akm = Re [kk] - Re [k2];
|
||||
ajp = Re [k1] + Re [k3];
|
||||
ajm = Re [k1] - Re [k3];
|
||||
bkp = Im [kk] + Im [k2];
|
||||
bkm = Im [kk] - Im [k2];
|
||||
bjp = Im [k1] + Im [k3];
|
||||
bjm = Im [k1] - Im [k3];
|
||||
Re [kk] = akp + ajp;
|
||||
Im [kk] = bkp + bjp;
|
||||
ajp = akp - ajp;
|
||||
bjp = bkp - bjp;
|
||||
if (iSign < 0) {
|
||||
akp = akm + bjm;
|
||||
bkp = bkm - ajm;
|
||||
akm -= bjm;
|
||||
bkm += ajm;
|
||||
} else {
|
||||
akp = akm - bjm;
|
||||
bkp = bkm + ajm;
|
||||
akm += bjm;
|
||||
bkm -= ajm;
|
||||
}
|
||||
/* avoid useless multiplies */
|
||||
if (s1 == 0.0) {
|
||||
Re [k1] = akp;
|
||||
Re [k2] = ajp;
|
||||
Re [k3] = akm;
|
||||
Im [k1] = bkp;
|
||||
Im [k2] = bjp;
|
||||
Im [k3] = bkm;
|
||||
} else {
|
||||
Re [k1] = akp * c1 - bkp * s1;
|
||||
Re [k2] = ajp * c2 - bjp * s2;
|
||||
Re [k3] = akm * c3 - bkm * s3;
|
||||
Im [k1] = akp * s1 + bkp * c1;
|
||||
Im [k2] = ajp * s2 + bjp * c2;
|
||||
Im [k3] = akm * s3 + bkm * c3;
|
||||
}
|
||||
kk = k3 + kspan;
|
||||
} while (kk < nt);
|
||||
|
||||
c2 = c1 - (cd * c1 + sd * s1);
|
||||
s1 = sd * c1 - cd * s1 + s1;
|
||||
c1 = 2.0 - (c2 * c2 + s1 * s1);
|
||||
s1 *= c1;
|
||||
c1 *= c2;
|
||||
/* values of c2, c3, s2, s3 that will get used next time */
|
||||
c2 = c1 * c1 - s1 * s1;
|
||||
s2 = 2.0 * c1 * s1;
|
||||
c3 = c2 * c1 - s2 * s1;
|
||||
s3 = c2 * s1 + s2 * c1;
|
||||
kk = kk - nt + jc;
|
||||
} while (kk < kspan);
|
||||
kk = kk - kspan + inc;
|
||||
} while (kk < jc);
|
||||
if (kspan == jc)
|
||||
goto Permute_Results_Label; /* exit infinite loop */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* transform for odd factors */
|
||||
#ifdef FFT_RADIX4
|
||||
return -1;
|
||||
break;
|
||||
#else /* FFT_RADIX4 */
|
||||
k = fftstate->factor [ii - 1];
|
||||
ispan = kspan;
|
||||
kspan /= k;
|
||||
|
||||
switch (k) {
|
||||
case 3: /* transform for factor of 3 (optional code) */
|
||||
do {
|
||||
do {
|
||||
k1 = kk + kspan;
|
||||
k2 = k1 + kspan;
|
||||
ak = Re [kk];
|
||||
bk = Im [kk];
|
||||
aj = Re [k1] + Re [k2];
|
||||
bj = Im [k1] + Im [k2];
|
||||
Re [kk] = ak + aj;
|
||||
Im [kk] = bk + bj;
|
||||
ak -= 0.5 * aj;
|
||||
bk -= 0.5 * bj;
|
||||
aj = (Re [k1] - Re [k2]) * s60;
|
||||
bj = (Im [k1] - Im [k2]) * s60;
|
||||
Re [k1] = ak - bj;
|
||||
Re [k2] = ak + bj;
|
||||
Im [k1] = bk + aj;
|
||||
Im [k2] = bk - aj;
|
||||
kk = k2 + kspan;
|
||||
} while (kk < (nn - 1));
|
||||
kk -= nn;
|
||||
} while (kk < kspan);
|
||||
break;
|
||||
|
||||
case 5: /* transform for factor of 5 (optional code) */
|
||||
c2 = c72 * c72 - s72 * s72;
|
||||
s2 = 2.0 * c72 * s72;
|
||||
do {
|
||||
do {
|
||||
k1 = kk + kspan;
|
||||
k2 = k1 + kspan;
|
||||
k3 = k2 + kspan;
|
||||
k4 = k3 + kspan;
|
||||
akp = Re [k1] + Re [k4];
|
||||
akm = Re [k1] - Re [k4];
|
||||
bkp = Im [k1] + Im [k4];
|
||||
bkm = Im [k1] - Im [k4];
|
||||
ajp = Re [k2] + Re [k3];
|
||||
ajm = Re [k2] - Re [k3];
|
||||
bjp = Im [k2] + Im [k3];
|
||||
bjm = Im [k2] - Im [k3];
|
||||
aa = Re [kk];
|
||||
bb = Im [kk];
|
||||
Re [kk] = aa + akp + ajp;
|
||||
Im [kk] = bb + bkp + bjp;
|
||||
ak = akp * c72 + ajp * c2 + aa;
|
||||
bk = bkp * c72 + bjp * c2 + bb;
|
||||
aj = akm * s72 + ajm * s2;
|
||||
bj = bkm * s72 + bjm * s2;
|
||||
Re [k1] = ak - bj;
|
||||
Re [k4] = ak + bj;
|
||||
Im [k1] = bk + aj;
|
||||
Im [k4] = bk - aj;
|
||||
ak = akp * c2 + ajp * c72 + aa;
|
||||
bk = bkp * c2 + bjp * c72 + bb;
|
||||
aj = akm * s2 - ajm * s72;
|
||||
bj = bkm * s2 - bjm * s72;
|
||||
Re [k2] = ak - bj;
|
||||
Re [k3] = ak + bj;
|
||||
Im [k2] = bk + aj;
|
||||
Im [k3] = bk - aj;
|
||||
kk = k4 + kspan;
|
||||
} while (kk < (nn-1));
|
||||
kk -= nn;
|
||||
} while (kk < kspan);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (k != jf) {
|
||||
jf = k;
|
||||
s1 = pi2 / (double) k;
|
||||
c1 = cos(s1);
|
||||
s1 = sin(s1);
|
||||
if (jf > max_factors){
|
||||
return -1;
|
||||
}
|
||||
Cos [jf - 1] = 1.0;
|
||||
Sin [jf - 1] = 0.0;
|
||||
j = 1;
|
||||
do {
|
||||
Cos [j - 1] = Cos [k - 1] * c1 + Sin [k - 1] * s1;
|
||||
Sin [j - 1] = Cos [k - 1] * s1 - Sin [k - 1] * c1;
|
||||
k--;
|
||||
Cos [k - 1] = Cos [j - 1];
|
||||
Sin [k - 1] = -Sin [j - 1];
|
||||
j++;
|
||||
} while (j < k);
|
||||
}
|
||||
do {
|
||||
do {
|
||||
k1 = kk;
|
||||
k2 = kk + ispan;
|
||||
ak = aa = Re [kk];
|
||||
bk = bb = Im [kk];
|
||||
j = 1;
|
||||
k1 += kspan;
|
||||
do {
|
||||
k2 -= kspan;
|
||||
j++;
|
||||
Rtmp [j - 1] = Re [k1] + Re [k2];
|
||||
ak += Rtmp [j - 1];
|
||||
Itmp [j - 1] = Im [k1] + Im [k2];
|
||||
bk += Itmp [j - 1];
|
||||
j++;
|
||||
Rtmp [j - 1] = Re [k1] - Re [k2];
|
||||
Itmp [j - 1] = Im [k1] - Im [k2];
|
||||
k1 += kspan;
|
||||
} while (k1 < k2);
|
||||
Re [kk] = ak;
|
||||
Im [kk] = bk;
|
||||
k1 = kk;
|
||||
k2 = kk + ispan;
|
||||
j = 1;
|
||||
do {
|
||||
k1 += kspan;
|
||||
k2 -= kspan;
|
||||
jj = j;
|
||||
ak = aa;
|
||||
bk = bb;
|
||||
aj = 0.0;
|
||||
bj = 0.0;
|
||||
k = 1;
|
||||
do {
|
||||
k++;
|
||||
ak += Rtmp [k - 1] * Cos [jj - 1];
|
||||
bk += Itmp [k - 1] * Cos [jj - 1];
|
||||
k++;
|
||||
aj += Rtmp [k - 1] * Sin [jj - 1];
|
||||
bj += Itmp [k - 1] * Sin [jj - 1];
|
||||
jj += j;
|
||||
if (jj > jf) {
|
||||
jj -= jf;
|
||||
}
|
||||
} while (k < jf);
|
||||
k = jf - j;
|
||||
Re [k1] = ak - bj;
|
||||
Im [k1] = bk + aj;
|
||||
Re [k2] = ak + bj;
|
||||
Im [k2] = bk - aj;
|
||||
j++;
|
||||
} while (j < k);
|
||||
kk += ispan;
|
||||
} while (kk < nn);
|
||||
kk -= nn;
|
||||
} while (kk < kspan);
|
||||
break;
|
||||
}
|
||||
|
||||
/* multiply by rotation factor (except for factors of 2 and 4) */
|
||||
if (ii == mfactor)
|
||||
goto Permute_Results_Label; /* exit infinite loop */
|
||||
kk = jc;
|
||||
do {
|
||||
c2 = 1.0 - cd;
|
||||
s1 = sd;
|
||||
do {
|
||||
c1 = c2;
|
||||
s2 = s1;
|
||||
kk += kspan;
|
||||
do {
|
||||
do {
|
||||
ak = Re [kk];
|
||||
Re [kk] = c2 * ak - s2 * Im [kk];
|
||||
Im [kk] = s2 * ak + c2 * Im [kk];
|
||||
kk += ispan;
|
||||
} while (kk < nt);
|
||||
ak = s1 * s2;
|
||||
s2 = s1 * c2 + c1 * s2;
|
||||
c2 = c1 * c2 - ak;
|
||||
kk = kk - nt + kspan;
|
||||
} while (kk < ispan);
|
||||
c2 = c1 - (cd * c1 + sd * s1);
|
||||
s1 += sd * c1 - cd * s1;
|
||||
c1 = 2.0 - (c2 * c2 + s1 * s1);
|
||||
s1 *= c1;
|
||||
c2 *= c1;
|
||||
kk = kk - ispan + jc;
|
||||
} while (kk < kspan);
|
||||
kk = kk - kspan + jc + inc;
|
||||
} while (kk < (jc + jc));
|
||||
break;
|
||||
#endif /* FFT_RADIX4 */
|
||||
}
|
||||
}
|
||||
|
||||
/* permute the results to normal order---done in two stages */
|
||||
/* permutation for square factors of n */
|
||||
Permute_Results_Label:
|
||||
fftstate->Perm [0] = ns;
|
||||
if (kt) {
|
||||
k = kt + kt + 1;
|
||||
if (mfactor < k)
|
||||
k--;
|
||||
j = 1;
|
||||
fftstate->Perm [k] = jc;
|
||||
do {
|
||||
fftstate->Perm [j] = fftstate->Perm [j - 1] / fftstate->factor [j - 1];
|
||||
fftstate->Perm [k - 1] = fftstate->Perm [k] * fftstate->factor [j - 1];
|
||||
j++;
|
||||
k--;
|
||||
} while (j < k);
|
||||
k3 = fftstate->Perm [k];
|
||||
kspan = fftstate->Perm [1];
|
||||
kk = jc;
|
||||
k2 = kspan;
|
||||
j = 1;
|
||||
if (nPass != nTotal) {
|
||||
/* permutation for multivariate transform */
|
||||
Permute_Multi_Label:
|
||||
do {
|
||||
do {
|
||||
k = kk + jc;
|
||||
do {
|
||||
/* swap Re [kk] <> Re [k2], Im [kk] <> Im [k2] */
|
||||
ak = Re [kk]; Re [kk] = Re [k2]; Re [k2] = ak;
|
||||
bk = Im [kk]; Im [kk] = Im [k2]; Im [k2] = bk;
|
||||
kk += inc;
|
||||
k2 += inc;
|
||||
} while (kk < (k-1));
|
||||
kk += ns - jc;
|
||||
k2 += ns - jc;
|
||||
} while (kk < (nt-1));
|
||||
k2 = k2 - nt + kspan;
|
||||
kk = kk - nt + jc;
|
||||
} while (k2 < (ns-1));
|
||||
do {
|
||||
do {
|
||||
k2 -= fftstate->Perm [j - 1];
|
||||
j++;
|
||||
k2 = fftstate->Perm [j] + k2;
|
||||
} while (k2 > fftstate->Perm [j - 1]);
|
||||
j = 1;
|
||||
do {
|
||||
if (kk < (k2-1))
|
||||
goto Permute_Multi_Label;
|
||||
kk += jc;
|
||||
k2 += kspan;
|
||||
} while (k2 < (ns-1));
|
||||
} while (kk < (ns-1));
|
||||
} else {
|
||||
/* permutation for single-variate transform (optional code) */
|
||||
Permute_Single_Label:
|
||||
do {
|
||||
/* swap Re [kk] <> Re [k2], Im [kk] <> Im [k2] */
|
||||
ak = Re [kk]; Re [kk] = Re [k2]; Re [k2] = ak;
|
||||
bk = Im [kk]; Im [kk] = Im [k2]; Im [k2] = bk;
|
||||
kk += inc;
|
||||
k2 += kspan;
|
||||
} while (k2 < (ns-1));
|
||||
do {
|
||||
do {
|
||||
k2 -= fftstate->Perm [j - 1];
|
||||
j++;
|
||||
k2 = fftstate->Perm [j] + k2;
|
||||
} while (k2 >= fftstate->Perm [j - 1]);
|
||||
j = 1;
|
||||
do {
|
||||
if (kk < k2)
|
||||
goto Permute_Single_Label;
|
||||
kk += inc;
|
||||
k2 += kspan;
|
||||
} while (k2 < (ns-1));
|
||||
} while (kk < (ns-1));
|
||||
}
|
||||
jc = k3;
|
||||
}
|
||||
|
||||
if ((kt << 1) + 1 >= mfactor)
|
||||
return 0;
|
||||
ispan = fftstate->Perm [kt];
|
||||
/* permutation for square-free factors of n */
|
||||
j = mfactor - kt;
|
||||
fftstate->factor [j] = 1;
|
||||
do {
|
||||
fftstate->factor [j - 1] *= fftstate->factor [j];
|
||||
j--;
|
||||
} while (j != kt);
|
||||
kt++;
|
||||
nn = fftstate->factor [kt - 1] - 1;
|
||||
if (nn > (int) max_perm) {
|
||||
return -1;
|
||||
}
|
||||
j = jj = 0;
|
||||
for (;;) {
|
||||
k = kt + 1;
|
||||
k2 = fftstate->factor [kt - 1];
|
||||
kk = fftstate->factor [k - 1];
|
||||
j++;
|
||||
if (j > nn)
|
||||
break; /* exit infinite loop */
|
||||
jj += kk;
|
||||
while (jj >= k2) {
|
||||
jj -= k2;
|
||||
k2 = kk;
|
||||
k++;
|
||||
kk = fftstate->factor [k - 1];
|
||||
jj += kk;
|
||||
}
|
||||
fftstate->Perm [j - 1] = jj;
|
||||
}
|
||||
/* determine the permutation cycles of length greater than 1 */
|
||||
j = 0;
|
||||
for (;;) {
|
||||
do {
|
||||
j++;
|
||||
kk = fftstate->Perm [j - 1];
|
||||
} while (kk < 0);
|
||||
if (kk != j) {
|
||||
do {
|
||||
k = kk;
|
||||
kk = fftstate->Perm [k - 1];
|
||||
fftstate->Perm [k - 1] = -kk;
|
||||
} while (kk != j);
|
||||
k3 = kk;
|
||||
} else {
|
||||
fftstate->Perm [j - 1] = -j;
|
||||
if (j == nn)
|
||||
break; /* exit infinite loop */
|
||||
}
|
||||
}
|
||||
max_factors *= inc;
|
||||
/* reorder a and b, following the permutation cycles */
|
||||
for (;;) {
|
||||
j = k3 + 1;
|
||||
nt -= ispan;
|
||||
ii = nt - inc + 1;
|
||||
if (nt < 0)
|
||||
break; /* exit infinite loop */
|
||||
do {
|
||||
do {
|
||||
j--;
|
||||
} while (fftstate->Perm [j - 1] < 0);
|
||||
jj = jc;
|
||||
do {
|
||||
kspan = jj;
|
||||
if (jj > max_factors) {
|
||||
kspan = max_factors;
|
||||
}
|
||||
jj -= kspan;
|
||||
k = fftstate->Perm [j - 1];
|
||||
kk = jc * k + ii + jj;
|
||||
k1 = kk + kspan - 1;
|
||||
k2 = 0;
|
||||
do {
|
||||
k2++;
|
||||
Rtmp [k2 - 1] = Re [k1];
|
||||
Itmp [k2 - 1] = Im [k1];
|
||||
k1 -= inc;
|
||||
} while (k1 != (kk-1));
|
||||
do {
|
||||
k1 = kk + kspan - 1;
|
||||
k2 = k1 - jc * (k + fftstate->Perm [k - 1]);
|
||||
k = -fftstate->Perm [k - 1];
|
||||
do {
|
||||
Re [k1] = Re [k2];
|
||||
Im [k1] = Im [k2];
|
||||
k1 -= inc;
|
||||
k2 -= inc;
|
||||
} while (k1 != (kk-1));
|
||||
kk = k2 + 1;
|
||||
} while (k != j);
|
||||
k1 = kk + kspan - 1;
|
||||
k2 = 0;
|
||||
do {
|
||||
k2++;
|
||||
Re [k1] = Rtmp [k2 - 1];
|
||||
Im [k1] = Itmp [k2 - 1];
|
||||
k1 -= inc;
|
||||
} while (k1 != (kk-1));
|
||||
} while (jj);
|
||||
} while (j != 1);
|
||||
}
|
||||
return 0; /* exit point here */
|
||||
}
|
||||
/* ---------------------- end-of-file (c source) ---------------------- */
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*--------------------------------*-C-*---------------------------------*
|
||||
* File:
|
||||
* fftn.h
|
||||
* ---------------------------------------------------------------------*
|
||||
* Re[]: real value array
|
||||
* Im[]: imaginary value array
|
||||
* nTotal: total number of complex values
|
||||
* nPass: number of elements involved in this pass of transform
|
||||
* nSpan: nspan/nPass = number of bytes to increment pointer
|
||||
* in Re[] and Im[]
|
||||
* isign: exponent: +1 = forward -1 = reverse
|
||||
* scaling: normalizing constant by which the final result is *divided*
|
||||
* scaling == -1, normalize by total dimension of the transform
|
||||
* scaling < -1, normalize by the square-root of the total dimension
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
* See the comments in the code for correct usage!
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_
|
||||
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
/* double precision routine */
|
||||
|
||||
|
||||
int WebRtcIsac_Fftns (unsigned int ndim, const int dims[], double Re[], double Im[],
|
||||
int isign, double scaling, FFTstr *fftstate);
|
||||
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_ */
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <memory.h>
|
||||
#ifdef WEBRTC_ANDROID
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include "pitch_estimator.h"
|
||||
#include "lpc_analysis.h"
|
||||
#include "codec.h"
|
||||
|
||||
|
||||
|
||||
void WebRtcIsac_AllPoleFilter(double *InOut, double *Coef, int lengthInOut, int orderCoef){
|
||||
|
||||
/* the state of filter is assumed to be in InOut[-1] to InOut[-orderCoef] */
|
||||
double scal;
|
||||
double sum;
|
||||
int n,k;
|
||||
|
||||
//if (fabs(Coef[0]-1.0)<0.001) {
|
||||
if ( (Coef[0] > 0.9999) && (Coef[0] < 1.0001) )
|
||||
{
|
||||
for(n = 0; n < lengthInOut; n++)
|
||||
{
|
||||
sum = Coef[1] * InOut[-1];
|
||||
for(k = 2; k <= orderCoef; k++){
|
||||
sum += Coef[k] * InOut[-k];
|
||||
}
|
||||
*InOut++ -= sum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
scal = 1.0 / Coef[0];
|
||||
for(n=0;n<lengthInOut;n++)
|
||||
{
|
||||
*InOut *= scal;
|
||||
for(k=1;k<=orderCoef;k++){
|
||||
*InOut -= scal*Coef[k]*InOut[-k];
|
||||
}
|
||||
InOut++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_AllZeroFilter(double *In, double *Coef, int lengthInOut, int orderCoef, double *Out){
|
||||
|
||||
/* the state of filter is assumed to be in In[-1] to In[-orderCoef] */
|
||||
|
||||
int n, k;
|
||||
double tmp;
|
||||
|
||||
for(n = 0; n < lengthInOut; n++)
|
||||
{
|
||||
tmp = In[0] * Coef[0];
|
||||
|
||||
for(k = 1; k <= orderCoef; k++){
|
||||
tmp += Coef[k] * In[-k];
|
||||
}
|
||||
|
||||
*Out++ = tmp;
|
||||
In++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WebRtcIsac_ZeroPoleFilter(double *In, double *ZeroCoef, double *PoleCoef, int lengthInOut, int orderCoef, double *Out){
|
||||
|
||||
/* the state of the zero section is assumed to be in In[-1] to In[-orderCoef] */
|
||||
/* the state of the pole section is assumed to be in Out[-1] to Out[-orderCoef] */
|
||||
|
||||
WebRtcIsac_AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out);
|
||||
WebRtcIsac_AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef);
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_AutoCorr(
|
||||
double *r,
|
||||
const double *x,
|
||||
int N,
|
||||
int order
|
||||
)
|
||||
{
|
||||
int lag, n;
|
||||
double sum, prod;
|
||||
const double *x_lag;
|
||||
|
||||
for (lag = 0; lag <= order; lag++)
|
||||
{
|
||||
sum = 0.0f;
|
||||
x_lag = &x[lag];
|
||||
prod = x[0] * x_lag[0];
|
||||
for (n = 1; n < N - lag; n++) {
|
||||
sum += prod;
|
||||
prod = x[n] * x_lag[n];
|
||||
}
|
||||
sum += prod;
|
||||
r[lag] = sum;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_BwExpand(double *out, double *in, double coef, short length) {
|
||||
int i;
|
||||
double chirp;
|
||||
|
||||
chirp = coef;
|
||||
|
||||
out[0] = in[0];
|
||||
for (i = 1; i < length; i++) {
|
||||
out[i] = chirp * in[i];
|
||||
chirp *= coef;
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcIsac_WeightingFilter(const double *in, double *weiout, double *whiout, WeightFiltstr *wfdata) {
|
||||
|
||||
double tmpbuffer[PITCH_FRAME_LEN + PITCH_WLPCBUFLEN];
|
||||
double corr[PITCH_WLPCORDER+1], rc[PITCH_WLPCORDER+1];
|
||||
double apol[PITCH_WLPCORDER+1], apolr[PITCH_WLPCORDER+1];
|
||||
double rho=0.9, *inp, *dp, *dp2;
|
||||
double whoutbuf[PITCH_WLPCBUFLEN + PITCH_WLPCORDER];
|
||||
double weoutbuf[PITCH_WLPCBUFLEN + PITCH_WLPCORDER];
|
||||
double *weo, *who, opol[PITCH_WLPCORDER+1], ext[PITCH_WLPCWINLEN];
|
||||
int k, n, endpos, start;
|
||||
|
||||
/* Set up buffer and states */
|
||||
memcpy(tmpbuffer, wfdata->buffer, sizeof(double) * PITCH_WLPCBUFLEN);
|
||||
memcpy(tmpbuffer+PITCH_WLPCBUFLEN, in, sizeof(double) * PITCH_FRAME_LEN);
|
||||
memcpy(wfdata->buffer, tmpbuffer+PITCH_FRAME_LEN, sizeof(double) * PITCH_WLPCBUFLEN);
|
||||
|
||||
dp=weoutbuf;
|
||||
dp2=whoutbuf;
|
||||
for (k=0;k<PITCH_WLPCORDER;k++) {
|
||||
*dp++ = wfdata->weostate[k];
|
||||
*dp2++ = wfdata->whostate[k];
|
||||
opol[k]=0.0;
|
||||
}
|
||||
opol[0]=1.0;
|
||||
opol[PITCH_WLPCORDER]=0.0;
|
||||
weo=dp;
|
||||
who=dp2;
|
||||
|
||||
endpos=PITCH_WLPCBUFLEN + PITCH_SUBFRAME_LEN;
|
||||
inp=tmpbuffer + PITCH_WLPCBUFLEN;
|
||||
|
||||
for (n=0; n<PITCH_SUBFRAMES; n++) {
|
||||
/* Windowing */
|
||||
start=endpos-PITCH_WLPCWINLEN;
|
||||
for (k=0; k<PITCH_WLPCWINLEN; k++) {
|
||||
ext[k]=wfdata->window[k]*tmpbuffer[start+k];
|
||||
}
|
||||
|
||||
/* Get LPC polynomial */
|
||||
WebRtcIsac_AutoCorr(corr, ext, PITCH_WLPCWINLEN, PITCH_WLPCORDER);
|
||||
corr[0]=1.01*corr[0]+1.0; /* White noise correction */
|
||||
WebRtcIsac_LevDurb(apol, rc, corr, PITCH_WLPCORDER);
|
||||
WebRtcIsac_BwExpand(apolr, apol, rho, PITCH_WLPCORDER+1);
|
||||
|
||||
/* Filtering */
|
||||
WebRtcIsac_ZeroPoleFilter(inp, apol, apolr, PITCH_SUBFRAME_LEN, PITCH_WLPCORDER, weo);
|
||||
WebRtcIsac_ZeroPoleFilter(inp, apolr, opol, PITCH_SUBFRAME_LEN, PITCH_WLPCORDER, who);
|
||||
|
||||
inp+=PITCH_SUBFRAME_LEN;
|
||||
endpos+=PITCH_SUBFRAME_LEN;
|
||||
weo+=PITCH_SUBFRAME_LEN;
|
||||
who+=PITCH_SUBFRAME_LEN;
|
||||
}
|
||||
|
||||
/* Export filter states */
|
||||
for (k=0;k<PITCH_WLPCORDER;k++) {
|
||||
wfdata->weostate[k]=weoutbuf[PITCH_FRAME_LEN+k];
|
||||
wfdata->whostate[k]=whoutbuf[PITCH_FRAME_LEN+k];
|
||||
}
|
||||
|
||||
/* Export output data */
|
||||
memcpy(weiout, weoutbuf+PITCH_WLPCORDER, sizeof(double) * PITCH_FRAME_LEN);
|
||||
memcpy(whiout, whoutbuf+PITCH_WLPCORDER, sizeof(double) * PITCH_FRAME_LEN);
|
||||
}
|
||||
|
||||
|
||||
static const double APupper[ALLPASSSECTIONS] = {0.0347, 0.3826};
|
||||
static const double APlower[ALLPASSSECTIONS] = {0.1544, 0.744};
|
||||
|
||||
|
||||
|
||||
void WebRtcIsac_AllpassFilterForDec(double *InOut,
|
||||
const double *APSectionFactors,
|
||||
int lengthInOut,
|
||||
double *FilterState)
|
||||
{
|
||||
//This performs all-pass filtering--a series of first order all-pass sections are used
|
||||
//to filter the input in a cascade manner.
|
||||
int n,j;
|
||||
double temp;
|
||||
for (j=0; j<ALLPASSSECTIONS; j++){
|
||||
for (n=0;n<lengthInOut;n+=2){
|
||||
temp = InOut[n]; //store input
|
||||
InOut[n] = FilterState[j] + APSectionFactors[j]*temp;
|
||||
FilterState[j] = -APSectionFactors[j]*InOut[n] + temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcIsac_DecimateAllpass(const double *in,
|
||||
double *state_in, /* array of size: 2*ALLPASSSECTIONS+1 */
|
||||
int N, /* number of input samples */
|
||||
double *out) /* array of size N/2 */
|
||||
{
|
||||
int n;
|
||||
double data_vec[PITCH_FRAME_LEN];
|
||||
|
||||
/* copy input */
|
||||
memcpy(data_vec+1, in, sizeof(double) * (N-1));
|
||||
|
||||
data_vec[0] = state_in[2*ALLPASSSECTIONS]; //the z^(-1) state
|
||||
state_in[2*ALLPASSSECTIONS] = in[N-1];
|
||||
|
||||
WebRtcIsac_AllpassFilterForDec(data_vec+1, APupper, N, state_in);
|
||||
WebRtcIsac_AllpassFilterForDec(data_vec, APlower, N, state_in+ALLPASSSECTIONS);
|
||||
|
||||
for (n=0;n<N/2;n++)
|
||||
out[n] = data_vec[2*n] + data_vec[2*n+1];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* create high-pass filter ocefficients
|
||||
* z = 0.998 * exp(j*2*pi*35/8000);
|
||||
* p = 0.94 * exp(j*2*pi*140/8000);
|
||||
* HP_b = [1, -2*real(z), abs(z)^2];
|
||||
* HP_a = [1, -2*real(p), abs(p)^2]; */
|
||||
static const double a_coef[2] = { 1.86864659625574, -0.88360000000000};
|
||||
static const double b_coef[2] = {-1.99524591718270, 0.99600400000000};
|
||||
static const float a_coef_float[2] = { 1.86864659625574f, -0.88360000000000f};
|
||||
static const float b_coef_float[2] = {-1.99524591718270f, 0.99600400000000f};
|
||||
|
||||
/* second order high-pass filter */
|
||||
void WebRtcIsac_Highpass(const double *in, double *out, double *state, int N)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k=0; k<N; k++) {
|
||||
*out = *in + state[1];
|
||||
state[1] = state[0] + b_coef[0] * *in + a_coef[0] * *out;
|
||||
state[0] = b_coef[1] * *in++ + a_coef[1] * *out++;
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcIsac_Highpass_float(const float *in, double *out, double *state, int N)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k=0; k<N; k++) {
|
||||
*out = (double)*in + state[1];
|
||||
state[1] = state[0] + b_coef_float[0] * *in + a_coef_float[0] * *out;
|
||||
state[0] = b_coef_float[1] * (double)*in++ + a_coef_float[1] * *out++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/* filterbank_tables.c*/
|
||||
/* This file contains variables that are used in filterbanks.c*/
|
||||
|
||||
#include "filterbank_tables.h"
|
||||
#include "settings.h"
|
||||
|
||||
/* The composite all-pass filter factors */
|
||||
const float WebRtcIsac_kCompositeApFactorsFloat[4] = {
|
||||
0.03470000000000f, 0.15440000000000f, 0.38260000000000f, 0.74400000000000f};
|
||||
|
||||
/* The upper channel all-pass filter factors */
|
||||
const float WebRtcIsac_kUpperApFactorsFloat[2] = {
|
||||
0.03470000000000f, 0.38260000000000f};
|
||||
|
||||
/* The lower channel all-pass filter factors */
|
||||
const float WebRtcIsac_kLowerApFactorsFloat[2] = {
|
||||
0.15440000000000f, 0.74400000000000f};
|
||||
|
||||
/* The matrix for transforming the backward composite state to upper channel state */
|
||||
const float WebRtcIsac_kTransform1Float[8] = {
|
||||
-0.00158678506084f, 0.00127157815343f, -0.00104805672709f, 0.00084837248079f,
|
||||
0.00134467983258f, -0.00107756549387f, 0.00088814793277f, -0.00071893072525f};
|
||||
|
||||
/* The matrix for transforming the backward composite state to lower channel state */
|
||||
const float WebRtcIsac_kTransform2Float[8] = {
|
||||
-0.00170686041697f, 0.00136780109829f, -0.00112736532350f, 0.00091257055385f,
|
||||
0.00103094281812f, -0.00082615076557f, 0.00068092756088f, -0.00055119165484f};
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* filterbank_tables.h
|
||||
*
|
||||
* Header file for variables that are defined in
|
||||
* filterbank_tables.c.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FILTERBANK_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FILTERBANK_TABLES_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
/********************* Coefficient Tables ************************/
|
||||
/* The number of composite all-pass filter factors */
|
||||
#define NUMBEROFCOMPOSITEAPSECTIONS 4
|
||||
|
||||
/* The number of all-pass filter factors in an upper or lower channel*/
|
||||
#define NUMBEROFCHANNELAPSECTIONS 2
|
||||
|
||||
/* The composite all-pass filter factors */
|
||||
extern const float WebRtcIsac_kCompositeApFactorsFloat[4];
|
||||
|
||||
/* The upper channel all-pass filter factors */
|
||||
extern const float WebRtcIsac_kUpperApFactorsFloat[2];
|
||||
|
||||
/* The lower channel all-pass filter factors */
|
||||
extern const float WebRtcIsac_kLowerApFactorsFloat[2];
|
||||
|
||||
/* The matrix for transforming the backward composite state to upper channel state */
|
||||
extern const float WebRtcIsac_kTransform1Float[8];
|
||||
|
||||
/* The matrix for transforming the backward composite state to lower channel state */
|
||||
extern const float WebRtcIsac_kTransform2Float[8];
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FILTERBANK_TABLES_H_ */
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* filterbanks.c
|
||||
*
|
||||
* This file contains function WebRtcIsac_AllPassFilter2Float,
|
||||
* WebRtcIsac_SplitAndFilter, and WebRtcIsac_FilterAndCombine
|
||||
* which implement filterbanks that produce decimated lowpass and
|
||||
* highpass versions of a signal, and performs reconstruction.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
#include "filterbank_tables.h"
|
||||
#include "codec.h"
|
||||
|
||||
/* This function performs all-pass filtering--a series of first order all-pass
|
||||
* sections are used to filter the input in a cascade manner.
|
||||
* The input is overwritten!!
|
||||
*/
|
||||
static void WebRtcIsac_AllPassFilter2Float(float *InOut, const float *APSectionFactors,
|
||||
int lengthInOut, int NumberOfSections,
|
||||
float *FilterState)
|
||||
{
|
||||
int n, j;
|
||||
float temp;
|
||||
for (j=0; j<NumberOfSections; j++){
|
||||
for (n=0;n<lengthInOut;n++){
|
||||
temp = FilterState[j] + APSectionFactors[j] * InOut[n];
|
||||
FilterState[j] = -APSectionFactors[j] * temp + InOut[n];
|
||||
InOut[n] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* HPstcoeff_in = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
|
||||
static const float kHpStCoefInFloat[4] =
|
||||
{-1.94895953203325f, 0.94984516000000f, -0.05101826139794f, 0.05015484000000f};
|
||||
|
||||
/* Function WebRtcIsac_SplitAndFilter
|
||||
* This function creates low-pass and high-pass decimated versions of part of
|
||||
the input signal, and part of the signal in the input 'lookahead buffer'.
|
||||
|
||||
INPUTS:
|
||||
in: a length FRAMESAMPLES array of input samples
|
||||
prefiltdata: input data structure containing the filterbank states
|
||||
and lookahead samples from the previous encoding
|
||||
iteration.
|
||||
OUTPUTS:
|
||||
LP: a FRAMESAMPLES_HALF array of low-pass filtered samples that
|
||||
have been phase equalized. The first QLOOKAHEAD samples are
|
||||
based on the samples in the two prefiltdata->INLABUFx arrays
|
||||
each of length QLOOKAHEAD.
|
||||
The remaining FRAMESAMPLES_HALF-QLOOKAHEAD samples are based
|
||||
on the first FRAMESAMPLES_HALF-QLOOKAHEAD samples of the input
|
||||
array in[].
|
||||
HP: a FRAMESAMPLES_HALF array of high-pass filtered samples that
|
||||
have been phase equalized. The first QLOOKAHEAD samples are
|
||||
based on the samples in the two prefiltdata->INLABUFx arrays
|
||||
each of length QLOOKAHEAD.
|
||||
The remaining FRAMESAMPLES_HALF-QLOOKAHEAD samples are based
|
||||
on the first FRAMESAMPLES_HALF-QLOOKAHEAD samples of the input
|
||||
array in[].
|
||||
|
||||
LP_la: a FRAMESAMPLES_HALF array of low-pass filtered samples.
|
||||
These samples are not phase equalized. They are computed
|
||||
from the samples in the in[] array.
|
||||
HP_la: a FRAMESAMPLES_HALF array of high-pass filtered samples
|
||||
that are not phase equalized. They are computed from
|
||||
the in[] vector.
|
||||
prefiltdata: this input data structure's filterbank state and
|
||||
lookahead sample buffers are updated for the next
|
||||
encoding iteration.
|
||||
*/
|
||||
void WebRtcIsac_SplitAndFilterFloat(float *pin, float *LP, float *HP,
|
||||
double *LP_la, double *HP_la,
|
||||
PreFiltBankstr *prefiltdata)
|
||||
{
|
||||
int k,n;
|
||||
float CompositeAPFilterState[NUMBEROFCOMPOSITEAPSECTIONS];
|
||||
float ForTransform_CompositeAPFilterState[NUMBEROFCOMPOSITEAPSECTIONS];
|
||||
float ForTransform_CompositeAPFilterState2[NUMBEROFCOMPOSITEAPSECTIONS];
|
||||
float tempinoutvec[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
|
||||
float tempin_ch1[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
|
||||
float tempin_ch2[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
|
||||
float in[FRAMESAMPLES];
|
||||
float ftmp;
|
||||
|
||||
|
||||
/* High pass filter */
|
||||
|
||||
for (k=0;k<FRAMESAMPLES;k++) {
|
||||
in[k] = pin[k] + kHpStCoefInFloat[2] * prefiltdata->HPstates_float[0] +
|
||||
kHpStCoefInFloat[3] * prefiltdata->HPstates_float[1];
|
||||
ftmp = pin[k] - kHpStCoefInFloat[0] * prefiltdata->HPstates_float[0] -
|
||||
kHpStCoefInFloat[1] * prefiltdata->HPstates_float[1];
|
||||
prefiltdata->HPstates_float[1] = prefiltdata->HPstates_float[0];
|
||||
prefiltdata->HPstates_float[0] = ftmp;
|
||||
}
|
||||
|
||||
/*
|
||||
% backwards all-pass filtering to obtain zero-phase
|
||||
[tmp1(N2+LA:-1:LA+1, 1), state1] = filter(Q.coef, Q.coef(end:-1:1), in(N:-2:2));
|
||||
tmp1(LA:-1:1) = filter(Q.coef, Q.coef(end:-1:1), Q.LookAheadBuf1, state1);
|
||||
Q.LookAheadBuf1 = in(N:-2:N-2*LA+2);
|
||||
*/
|
||||
/*Backwards all-pass filter the odd samples of the input (upper channel)
|
||||
to eventually obtain zero phase. The composite all-pass filter (comprised of both
|
||||
the upper and lower channel all-pass filsters in series) is used for the
|
||||
filtering. */
|
||||
|
||||
/* First Channel */
|
||||
|
||||
/*initial state of composite filter is zero */
|
||||
for (k=0;k<NUMBEROFCOMPOSITEAPSECTIONS;k++){
|
||||
CompositeAPFilterState[k] = 0.0;
|
||||
}
|
||||
/* put every other sample of input into a temporary vector in reverse (backward) order*/
|
||||
for (k=0;k<FRAMESAMPLES_HALF;k++) {
|
||||
tempinoutvec[k] = in[FRAMESAMPLES-1-2*k];
|
||||
}
|
||||
|
||||
/* now all-pass filter the backwards vector. Output values overwrite the input vector. */
|
||||
WebRtcIsac_AllPassFilter2Float(tempinoutvec, WebRtcIsac_kCompositeApFactorsFloat,
|
||||
FRAMESAMPLES_HALF, NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
|
||||
|
||||
/* save the backwards filtered output for later forward filtering,
|
||||
but write it in forward order*/
|
||||
for (k=0;k<FRAMESAMPLES_HALF;k++) {
|
||||
tempin_ch1[FRAMESAMPLES_HALF+QLOOKAHEAD-1-k] = tempinoutvec[k];
|
||||
}
|
||||
|
||||
/* save the backwards filter state becaue it will be transformed
|
||||
later into a forward state */
|
||||
for (k=0; k<NUMBEROFCOMPOSITEAPSECTIONS; k++) {
|
||||
ForTransform_CompositeAPFilterState[k] = CompositeAPFilterState[k];
|
||||
}
|
||||
|
||||
/* now backwards filter the samples in the lookahead buffer. The samples were
|
||||
placed there in the encoding of the previous frame. The output samples
|
||||
overwrite the input samples */
|
||||
WebRtcIsac_AllPassFilter2Float(prefiltdata->INLABUF1_float,
|
||||
WebRtcIsac_kCompositeApFactorsFloat, QLOOKAHEAD,
|
||||
NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
|
||||
|
||||
/* save the output, but write it in forward order */
|
||||
/* write the lookahead samples for the next encoding iteration. Every other
|
||||
sample at the end of the input frame is written in reverse order for the
|
||||
lookahead length. Exported in the prefiltdata structure. */
|
||||
for (k=0;k<QLOOKAHEAD;k++) {
|
||||
tempin_ch1[QLOOKAHEAD-1-k]=prefiltdata->INLABUF1_float[k];
|
||||
prefiltdata->INLABUF1_float[k]=in[FRAMESAMPLES-1-2*k];
|
||||
}
|
||||
|
||||
/* Second Channel. This is exactly like the first channel, except that the
|
||||
even samples are now filtered instead (lower channel). */
|
||||
for (k=0;k<NUMBEROFCOMPOSITEAPSECTIONS;k++){
|
||||
CompositeAPFilterState[k] = 0.0;
|
||||
}
|
||||
|
||||
for (k=0;k<FRAMESAMPLES_HALF;k++) {
|
||||
tempinoutvec[k] = in[FRAMESAMPLES-2-2*k];
|
||||
}
|
||||
|
||||
WebRtcIsac_AllPassFilter2Float(tempinoutvec, WebRtcIsac_kCompositeApFactorsFloat,
|
||||
FRAMESAMPLES_HALF, NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
|
||||
|
||||
for (k=0;k<FRAMESAMPLES_HALF;k++) {
|
||||
tempin_ch2[FRAMESAMPLES_HALF+QLOOKAHEAD-1-k] = tempinoutvec[k];
|
||||
}
|
||||
|
||||
for (k=0; k<NUMBEROFCOMPOSITEAPSECTIONS; k++) {
|
||||
ForTransform_CompositeAPFilterState2[k] = CompositeAPFilterState[k];
|
||||
}
|
||||
|
||||
|
||||
WebRtcIsac_AllPassFilter2Float(prefiltdata->INLABUF2_float,
|
||||
WebRtcIsac_kCompositeApFactorsFloat, QLOOKAHEAD,NUMBEROFCOMPOSITEAPSECTIONS,
|
||||
CompositeAPFilterState);
|
||||
|
||||
for (k=0;k<QLOOKAHEAD;k++) {
|
||||
tempin_ch2[QLOOKAHEAD-1-k]=prefiltdata->INLABUF2_float[k];
|
||||
prefiltdata->INLABUF2_float[k]=in[FRAMESAMPLES-2-2*k];
|
||||
}
|
||||
|
||||
/* Transform filter states from backward to forward */
|
||||
/*At this point, each of the states of the backwards composite filters for the
|
||||
two channels are transformed into forward filtering states for the corresponding
|
||||
forward channel filters. Each channel's forward filtering state from the previous
|
||||
encoding iteration is added to the transformed state to get a proper forward state */
|
||||
|
||||
/* So the existing NUMBEROFCOMPOSITEAPSECTIONS x 1 (4x1) state vector is multiplied by a
|
||||
NUMBEROFCHANNELAPSECTIONSxNUMBEROFCOMPOSITEAPSECTIONS (2x4) transform matrix to get the
|
||||
new state that is added to the previous 2x1 input state */
|
||||
|
||||
for (k=0;k<NUMBEROFCHANNELAPSECTIONS;k++){ /* k is row variable */
|
||||
for (n=0; n<NUMBEROFCOMPOSITEAPSECTIONS;n++){/* n is column variable */
|
||||
prefiltdata->INSTAT1_float[k] += ForTransform_CompositeAPFilterState[n]*
|
||||
WebRtcIsac_kTransform1Float[k*NUMBEROFCHANNELAPSECTIONS+n];
|
||||
prefiltdata->INSTAT2_float[k] += ForTransform_CompositeAPFilterState2[n]*
|
||||
WebRtcIsac_kTransform2Float[k*NUMBEROFCHANNELAPSECTIONS+n];
|
||||
}
|
||||
}
|
||||
|
||||
/*obtain polyphase components by forward all-pass filtering through each channel */
|
||||
/* the backward filtered samples are now forward filtered with the corresponding channel filters */
|
||||
/* The all pass filtering automatically updates the filter states which are exported in the
|
||||
prefiltdata structure */
|
||||
WebRtcIsac_AllPassFilter2Float(tempin_ch1,WebRtcIsac_kUpperApFactorsFloat,
|
||||
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_float);
|
||||
WebRtcIsac_AllPassFilter2Float(tempin_ch2,WebRtcIsac_kLowerApFactorsFloat,
|
||||
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_float);
|
||||
|
||||
/* Now Construct low-pass and high-pass signals as combinations of polyphase components */
|
||||
for (k=0; k<FRAMESAMPLES_HALF; k++) {
|
||||
LP[k] = 0.5f*(tempin_ch1[k] + tempin_ch2[k]);/* low pass signal*/
|
||||
HP[k] = 0.5f*(tempin_ch1[k] - tempin_ch2[k]);/* high pass signal*/
|
||||
}
|
||||
|
||||
/* Lookahead LP and HP signals */
|
||||
/* now create low pass and high pass signals of the input vector. However, no
|
||||
backwards filtering is performed, and hence no phase equalization is involved.
|
||||
Also, the input contains some samples that are lookahead samples. The high pass
|
||||
and low pass signals that are created are used outside this function for analysis
|
||||
(not encoding) purposes */
|
||||
|
||||
/* set up input */
|
||||
for (k=0; k<FRAMESAMPLES_HALF; k++) {
|
||||
tempin_ch1[k]=in[2*k+1];
|
||||
tempin_ch2[k]=in[2*k];
|
||||
}
|
||||
|
||||
/* the input filter states are passed in and updated by the all-pass filtering routine and
|
||||
exported in the prefiltdata structure*/
|
||||
WebRtcIsac_AllPassFilter2Float(tempin_ch1,WebRtcIsac_kUpperApFactorsFloat,
|
||||
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTATLA1_float);
|
||||
WebRtcIsac_AllPassFilter2Float(tempin_ch2,WebRtcIsac_kLowerApFactorsFloat,
|
||||
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTATLA2_float);
|
||||
|
||||
for (k=0; k<FRAMESAMPLES_HALF; k++) {
|
||||
LP_la[k] = (float)(0.5f*(tempin_ch1[k] + tempin_ch2[k])); /*low pass */
|
||||
HP_la[k] = (double)(0.5f*(tempin_ch1[k] - tempin_ch2[k])); /* high pass */
|
||||
}
|
||||
|
||||
|
||||
}/*end of WebRtcIsac_SplitAndFilter */
|
||||
|
||||
|
||||
/* Combining */
|
||||
|
||||
/* HPstcoeff_out_1 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
|
||||
static const float kHpStCoefOut1Float[4] =
|
||||
{-1.99701049409000f, 0.99714204490000f, 0.01701049409000f, -0.01704204490000f};
|
||||
|
||||
/* HPstcoeff_out_2 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
|
||||
static const float kHpStCoefOut2Float[4] =
|
||||
{-1.98645294509837f, 0.98672435560000f, 0.00645294509837f, -0.00662435560000f};
|
||||
|
||||
|
||||
/* Function WebRtcIsac_FilterAndCombine */
|
||||
/* This is a decoder function that takes the decimated
|
||||
length FRAMESAMPLES_HALF input low-pass and
|
||||
high-pass signals and creates a reconstructed fullband
|
||||
output signal of length FRAMESAMPLES. WebRtcIsac_FilterAndCombine
|
||||
is the sibling function of WebRtcIsac_SplitAndFilter */
|
||||
/* INPUTS:
|
||||
inLP: a length FRAMESAMPLES_HALF array of input low-pass
|
||||
samples.
|
||||
inHP: a length FRAMESAMPLES_HALF array of input high-pass
|
||||
samples.
|
||||
postfiltdata: input data structure containing the filterbank
|
||||
states from the previous decoding iteration.
|
||||
OUTPUTS:
|
||||
Out: a length FRAMESAMPLES array of output reconstructed
|
||||
samples (fullband) based on the input low-pass and
|
||||
high-pass signals.
|
||||
postfiltdata: the input data structure containing the filterbank
|
||||
states is updated for the next decoding iteration */
|
||||
void WebRtcIsac_FilterAndCombineFloat(float *InLP,
|
||||
float *InHP,
|
||||
float *Out,
|
||||
PostFiltBankstr *postfiltdata)
|
||||
{
|
||||
int k;
|
||||
float tempin_ch1[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
|
||||
float tempin_ch2[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
|
||||
float ftmp, ftmp2;
|
||||
|
||||
/* Form the polyphase signals*/
|
||||
for (k=0;k<FRAMESAMPLES_HALF;k++) {
|
||||
tempin_ch1[k]=InLP[k]+InHP[k]; /* Construct a new upper channel signal*/
|
||||
tempin_ch2[k]=InLP[k]-InHP[k]; /* Construct a new lower channel signal*/
|
||||
}
|
||||
|
||||
|
||||
/* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors
|
||||
that were used as a lower channel at the encoding side. So at the decoder, the
|
||||
corresponding all-pass filter factors for each channel are swapped.*/
|
||||
WebRtcIsac_AllPassFilter2Float(tempin_ch1, WebRtcIsac_kLowerApFactorsFloat,
|
||||
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_float);
|
||||
|
||||
/* Now, all-pass filter the new lower channel signal. But since all-pass filter factors
|
||||
at the decoder are swapped from the ones at the encoder, the 'upper' channel
|
||||
all-pass filter factors (WebRtcIsac_kUpperApFactorsFloat) are used to filter this new
|
||||
lower channel signal */
|
||||
WebRtcIsac_AllPassFilter2Float(tempin_ch2, WebRtcIsac_kUpperApFactorsFloat,
|
||||
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_float);
|
||||
|
||||
|
||||
/* Merge outputs to form the full length output signal.*/
|
||||
for (k=0;k<FRAMESAMPLES_HALF;k++) {
|
||||
Out[2*k]=tempin_ch2[k];
|
||||
Out[2*k+1]=tempin_ch1[k];
|
||||
}
|
||||
|
||||
|
||||
/* High pass filter */
|
||||
|
||||
for (k=0;k<FRAMESAMPLES;k++) {
|
||||
ftmp2 = Out[k] + kHpStCoefOut1Float[2] * postfiltdata->HPstates1_float[0] +
|
||||
kHpStCoefOut1Float[3] * postfiltdata->HPstates1_float[1];
|
||||
ftmp = Out[k] - kHpStCoefOut1Float[0] * postfiltdata->HPstates1_float[0] -
|
||||
kHpStCoefOut1Float[1] * postfiltdata->HPstates1_float[1];
|
||||
postfiltdata->HPstates1_float[1] = postfiltdata->HPstates1_float[0];
|
||||
postfiltdata->HPstates1_float[0] = ftmp;
|
||||
Out[k] = ftmp2;
|
||||
}
|
||||
|
||||
for (k=0;k<FRAMESAMPLES;k++) {
|
||||
ftmp2 = Out[k] + kHpStCoefOut2Float[2] * postfiltdata->HPstates2_float[0] +
|
||||
kHpStCoefOut2Float[3] * postfiltdata->HPstates2_float[1];
|
||||
ftmp = Out[k] - kHpStCoefOut2Float[0] * postfiltdata->HPstates2_float[0] -
|
||||
kHpStCoefOut2Float[1] * postfiltdata->HPstates2_float[1];
|
||||
postfiltdata->HPstates2_float[1] = postfiltdata->HPstates2_float[0];
|
||||
postfiltdata->HPstates2_float[0] = ftmp;
|
||||
Out[k] = ftmp2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/* encode.c - Encoding function for the iSAC coder */
|
||||
|
||||
#include "structs.h"
|
||||
#include "codec.h"
|
||||
#include "pitch_estimator.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
void WebRtcIsac_InitMasking(MaskFiltstr *maskdata) {
|
||||
|
||||
int k;
|
||||
|
||||
for (k = 0; k < WINLEN; k++) {
|
||||
maskdata->DataBufferLo[k] = 0.0;
|
||||
maskdata->DataBufferHi[k] = 0.0;
|
||||
}
|
||||
for (k = 0; k < ORDERLO+1; k++) {
|
||||
maskdata->CorrBufLo[k] = 0.0;
|
||||
maskdata->PreStateLoF[k] = 0.0;
|
||||
maskdata->PreStateLoG[k] = 0.0;
|
||||
maskdata->PostStateLoF[k] = 0.0;
|
||||
maskdata->PostStateLoG[k] = 0.0;
|
||||
}
|
||||
for (k = 0; k < ORDERHI+1; k++) {
|
||||
maskdata->CorrBufHi[k] = 0.0;
|
||||
maskdata->PreStateHiF[k] = 0.0;
|
||||
maskdata->PreStateHiG[k] = 0.0;
|
||||
maskdata->PostStateHiF[k] = 0.0;
|
||||
maskdata->PostStateHiG[k] = 0.0;
|
||||
}
|
||||
|
||||
maskdata->OldEnergy = 10.0;
|
||||
|
||||
/* fill tables for transforms */
|
||||
WebRtcIsac_InitTransform();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void WebRtcIsac_InitPreFilterbank(PreFiltBankstr *prefiltdata)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < QLOOKAHEAD; k++) {
|
||||
prefiltdata->INLABUF1[k] = 0;
|
||||
prefiltdata->INLABUF2[k] = 0;
|
||||
|
||||
prefiltdata->INLABUF1_float[k] = 0;
|
||||
prefiltdata->INLABUF2_float[k] = 0;
|
||||
}
|
||||
for (k = 0; k < 2*(QORDER-1); k++) {
|
||||
prefiltdata->INSTAT1[k] = 0;
|
||||
prefiltdata->INSTAT2[k] = 0;
|
||||
prefiltdata->INSTATLA1[k] = 0;
|
||||
prefiltdata->INSTATLA2[k] = 0;
|
||||
|
||||
prefiltdata->INSTAT1_float[k] = 0;
|
||||
prefiltdata->INSTAT2_float[k] = 0;
|
||||
prefiltdata->INSTATLA1_float[k] = 0;
|
||||
prefiltdata->INSTATLA2_float[k] = 0;
|
||||
}
|
||||
|
||||
/* High pass filter states */
|
||||
prefiltdata->HPstates[0] = 0.0;
|
||||
prefiltdata->HPstates[1] = 0.0;
|
||||
|
||||
prefiltdata->HPstates_float[0] = 0.0f;
|
||||
prefiltdata->HPstates_float[1] = 0.0f;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void WebRtcIsac_InitPostFilterbank(PostFiltBankstr *postfiltdata)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < 2*POSTQORDER; k++) {
|
||||
postfiltdata->STATE_0_LOWER[k] = 0;
|
||||
postfiltdata->STATE_0_UPPER[k] = 0;
|
||||
|
||||
postfiltdata->STATE_0_LOWER_float[k] = 0;
|
||||
postfiltdata->STATE_0_UPPER_float[k] = 0;
|
||||
}
|
||||
|
||||
/* High pass filter states */
|
||||
postfiltdata->HPstates1[0] = 0.0;
|
||||
postfiltdata->HPstates1[1] = 0.0;
|
||||
|
||||
postfiltdata->HPstates2[0] = 0.0;
|
||||
postfiltdata->HPstates2[1] = 0.0;
|
||||
|
||||
postfiltdata->HPstates1_float[0] = 0.0f;
|
||||
postfiltdata->HPstates1_float[1] = 0.0f;
|
||||
|
||||
postfiltdata->HPstates2_float[0] = 0.0f;
|
||||
postfiltdata->HPstates2_float[1] = 0.0f;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_InitPitchFilter(PitchFiltstr *pitchfiltdata)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < PITCH_BUFFSIZE; k++) {
|
||||
pitchfiltdata->ubuf[k] = 0.0;
|
||||
}
|
||||
pitchfiltdata->ystate[0] = 0.0;
|
||||
for (k = 1; k < (PITCH_DAMPORDER); k++) {
|
||||
pitchfiltdata->ystate[k] = 0.0;
|
||||
}
|
||||
pitchfiltdata->oldlagp[0] = 50.0;
|
||||
pitchfiltdata->oldgainp[0] = 0.0;
|
||||
}
|
||||
|
||||
void WebRtcIsac_InitWeightingFilter(WeightFiltstr *wfdata)
|
||||
{
|
||||
int k;
|
||||
double t, dtmp, dtmp2, denum, denum2;
|
||||
|
||||
for (k=0;k<PITCH_WLPCBUFLEN;k++)
|
||||
wfdata->buffer[k]=0.0;
|
||||
|
||||
for (k=0;k<PITCH_WLPCORDER;k++) {
|
||||
wfdata->istate[k]=0.0;
|
||||
wfdata->weostate[k]=0.0;
|
||||
wfdata->whostate[k]=0.0;
|
||||
}
|
||||
|
||||
/* next part should be in Matlab, writing to a global table */
|
||||
t = 0.5;
|
||||
denum = 1.0 / ((double) PITCH_WLPCWINLEN);
|
||||
denum2 = denum * denum;
|
||||
for (k=0;k<PITCH_WLPCWINLEN;k++) {
|
||||
dtmp = PITCH_WLPCASYM * t * denum + (1-PITCH_WLPCASYM) * t * t * denum2;
|
||||
dtmp *= 3.14159265;
|
||||
dtmp2 = sin(dtmp);
|
||||
wfdata->window[k] = dtmp2 * dtmp2;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear all buffers */
|
||||
void WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct *State)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; k++)
|
||||
State->dec_buffer[k] = 0.0;
|
||||
for (k = 0; k < 2*ALLPASSSECTIONS+1; k++)
|
||||
State->decimator_state[k] = 0.0;
|
||||
for (k = 0; k < 2; k++)
|
||||
State->hp_state[k] = 0.0;
|
||||
for (k = 0; k < QLOOKAHEAD; k++)
|
||||
State->whitened_buf[k] = 0.0;
|
||||
for (k = 0; k < QLOOKAHEAD; k++)
|
||||
State->inbuf[k] = 0.0;
|
||||
|
||||
WebRtcIsac_InitPitchFilter(&(State->PFstr_wght));
|
||||
|
||||
WebRtcIsac_InitPitchFilter(&(State->PFstr));
|
||||
|
||||
WebRtcIsac_InitWeightingFilter(&(State->Wghtstr));
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,729 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_ISAC_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_ISAC_H_
|
||||
|
||||
/*
|
||||
* Define the fixed-point numeric formats
|
||||
*/
|
||||
#include "typedefs.h"
|
||||
|
||||
typedef struct WebRtcISACStruct ISACStruct;
|
||||
|
||||
enum IsacSamplingRate {kIsacWideband = 16, kIsacSuperWideband = 32};
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_AssignSize(...)
|
||||
*
|
||||
* This function returns the size of the ISAC instance, so that the instance
|
||||
* can be created outside iSAC.
|
||||
*
|
||||
* Input:
|
||||
* - samplingRate : sampling rate of the input/output audio.
|
||||
*
|
||||
* Output:
|
||||
* - sizeinbytes : number of bytes needed to allocate for the
|
||||
* instance.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_AssignSize(
|
||||
int* sizeinbytes);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_Assign(...)
|
||||
*
|
||||
* This function assignes the memory already created to the ISAC instance.
|
||||
*
|
||||
* Input:
|
||||
* - *ISAC_main_inst : a pointer to the coder instance.
|
||||
* - samplingRate : sampling rate of the input/output audio.
|
||||
* - ISAC_inst_Addr : the already allocated memory, where we put the
|
||||
* iSAC structure.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_Assign(
|
||||
ISACStruct** ISAC_main_inst,
|
||||
void* ISAC_inst_Addr);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_Create(...)
|
||||
*
|
||||
* This function creates an ISAC instance, which will contain the state
|
||||
* information for one coding/decoding channel.
|
||||
*
|
||||
* Input:
|
||||
* - *ISAC_main_inst : a pointer to the coder instance.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_Create(
|
||||
ISACStruct** ISAC_main_inst);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_Free(...)
|
||||
*
|
||||
* This function frees the ISAC instance created at the beginning.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : an ISAC instance.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_Free(
|
||||
ISACStruct* ISAC_main_inst);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncoderInit(...)
|
||||
*
|
||||
* This function initializes an ISAC instance prior to the encoder calls.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - CodingMode : 0 -> Bit rate and frame length are
|
||||
* automatically adjusted to available bandwidth
|
||||
* on transmission channel, just valid if codec
|
||||
* is created to work in wideband mode.
|
||||
* 1 -> User sets a frame length and a target bit
|
||||
* rate which is taken as the maximum
|
||||
* short-term average bit rate.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_EncoderInit(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word16 CodingMode);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_Encode(...)
|
||||
*
|
||||
* This function encodes 10ms audio blocks and inserts it into a package.
|
||||
* Input speech length has 160 samples if operating at 16 kHz sampling
|
||||
* rate, or 320 if operating at 32 kHz sampling rate. The encoder buffers the
|
||||
* input audio until the whole frame is buffered then proceeds with encoding.
|
||||
*
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - speechIn : input speech vector.
|
||||
*
|
||||
* Output:
|
||||
* - encoded : the encoded data vector
|
||||
*
|
||||
* Return value:
|
||||
* : >0 - Length (in bytes) of coded data
|
||||
* : 0 - The buffer didn't reach the chosen
|
||||
* frame-size so it keeps buffering speech
|
||||
* samples.
|
||||
* : -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_Encode(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
const WebRtc_Word16* speechIn,
|
||||
WebRtc_Word16* encoded);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecoderInit(...)
|
||||
*
|
||||
* This function initializes an ISAC instance prior to the decoder calls.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
*
|
||||
* Return value
|
||||
* : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_DecoderInit(
|
||||
ISACStruct* ISAC_main_inst);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_UpdateBwEstimate(...)
|
||||
*
|
||||
* This function updates the estimate of the bandwidth.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - encoded : encoded ISAC frame(s).
|
||||
* - packet_size : size of the packet.
|
||||
* - rtp_seq_number : the RTP number of the packet.
|
||||
* - send_ts : the RTP send timestamp, given in samples
|
||||
* - arr_ts : the arrival time of the packet (from NetEq)
|
||||
* in samples.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_UpdateBwEstimate(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
const WebRtc_UWord16* encoded,
|
||||
WebRtc_Word32 packet_size,
|
||||
WebRtc_UWord16 rtp_seq_number,
|
||||
WebRtc_UWord32 send_ts,
|
||||
WebRtc_UWord32 arr_ts);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_Decode(...)
|
||||
*
|
||||
* This function decodes an ISAC frame. At 16 kHz sampling rate, the length
|
||||
* of the output audio could be either 480 or 960 samples, equivalent to
|
||||
* 30 or 60 ms respectively. At 32 kHz sampling rate, the length of the
|
||||
* output audio is 960 samples, which is 30 ms.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - encoded : encoded ISAC frame(s).
|
||||
* - len : bytes in encoded vector.
|
||||
*
|
||||
* Output:
|
||||
* - decoded : The decoded vector.
|
||||
*
|
||||
* Return value : >0 - number of samples in decoded vector.
|
||||
* -1 - Error.
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_Decode(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
const WebRtc_UWord16* encoded,
|
||||
WebRtc_Word16 len,
|
||||
WebRtc_Word16* decoded,
|
||||
WebRtc_Word16* speechType);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecodePlc(...)
|
||||
*
|
||||
* This function conducts PLC for ISAC frame(s). Output speech length
|
||||
* will be a multiple of frames, i.e. multiples of 30 ms audio. Therefore,
|
||||
* the output is multiple of 480 samples if operating at 16 kHz and multiple
|
||||
* of 960 if operating at 32 kHz.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - noOfLostFrames : Number of PLC frames to produce.
|
||||
*
|
||||
* Output:
|
||||
* - decoded : The decoded vector.
|
||||
*
|
||||
* Return value : >0 - number of samples in decoded PLC vector
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_DecodePlc(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word16* decoded,
|
||||
WebRtc_Word16 noOfLostFrames);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_Control(...)
|
||||
*
|
||||
* This function sets the limit on the short-term average bit-rate and the
|
||||
* frame length. Should be used only in Instantaneous mode. At 16 kHz sampling
|
||||
* rate, an average bit-rate between 10000 to 32000 bps is valid and a
|
||||
* frame-size of 30 or 60 ms is acceptable. At 32 kHz, an average bit-rate
|
||||
* between 10000 to 56000 is acceptable, and the valid frame-size is 30 ms.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - rate : limit on the short-term average bit rate,
|
||||
* in bits/second.
|
||||
* - framesize : frame-size in millisecond.
|
||||
*
|
||||
* Return value : 0 - ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_Control(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word32 rate,
|
||||
WebRtc_Word16 framesize);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_ControlBwe(...)
|
||||
*
|
||||
* This function sets the initial values of bottleneck and frame-size if
|
||||
* iSAC is used in channel-adaptive mode. Therefore, this API is not
|
||||
* applicable if the codec is created to operate in super-wideband mode.
|
||||
*
|
||||
* Through this API, users can enforce a frame-size for all values of
|
||||
* bottleneck. Then iSAC will not automatically change the frame-size.
|
||||
*
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - rateBPS : initial value of bottleneck in bits/second
|
||||
* 10000 <= rateBPS <= 56000 is accepted
|
||||
* For default bottleneck set rateBPS = 0
|
||||
* - frameSizeMs : number of milliseconds per frame (30 or 60)
|
||||
* - enforceFrameSize : 1 to enforce the given frame-size through
|
||||
* out the adaptation process, 0 to let iSAC
|
||||
* change the frame-size if required.
|
||||
*
|
||||
* Return value : 0 - ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_ControlBwe(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word32 rateBPS,
|
||||
WebRtc_Word16 frameSizeMs,
|
||||
WebRtc_Word16 enforceFrameSize);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_ReadFrameLen(...)
|
||||
*
|
||||
* This function returns the length of the frame represented in the packet.
|
||||
*
|
||||
* Input:
|
||||
* - encoded : Encoded bit-stream
|
||||
*
|
||||
* Output:
|
||||
* - frameLength : Length of frame in packet (in samples)
|
||||
*
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_ReadFrameLen(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
const WebRtc_Word16* encoded,
|
||||
WebRtc_Word16* frameLength);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_version(...)
|
||||
*
|
||||
* This function returns the version number.
|
||||
*
|
||||
* Output:
|
||||
* - version : Pointer to character string
|
||||
*
|
||||
*/
|
||||
|
||||
void WebRtcIsac_version(
|
||||
char *version);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_GetErrorCode(...)
|
||||
*
|
||||
* This function can be used to check the error code of an iSAC instance. When
|
||||
* a function returns -1 a error code will be set for that instance. The
|
||||
* function below extract the code of the last error that occurred in the
|
||||
* specified instance.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance
|
||||
*
|
||||
* Return value : Error code
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_GetErrorCode(
|
||||
ISACStruct* ISAC_main_inst);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsac_GetUplinkBw(...)
|
||||
*
|
||||
* This function outputs the target bottleneck of the codec. In
|
||||
* channel-adaptive mode, the target bottleneck is specified through in-band
|
||||
* signalling retreived by bandwidth estimator.
|
||||
* In channel-independent, also called instantaneous mode, the target
|
||||
* bottleneck is provided to the encoder by calling xxx_control(...). If
|
||||
* xxx_control is never called the default values is returned. The default
|
||||
* value for bottleneck at 16 kHz encoder sampling rate is 32000 bits/sec,
|
||||
* and it is 56000 bits/sec for 32 kHz sampling rate.
|
||||
* Note that the output is the iSAC internal operating bottleneck which might
|
||||
* differ slightly from the one provided through xxx_control().
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC instance
|
||||
*
|
||||
* Output:
|
||||
* - *bottleneck : bottleneck in bits/sec
|
||||
*
|
||||
* Return value : -1 if error happens
|
||||
* 0 bit-rates computed correctly.
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_GetUplinkBw(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word32* bottleneck);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_SetMaxPayloadSize(...)
|
||||
*
|
||||
* This function sets a limit for the maximum payload size of iSAC. The same
|
||||
* value is used both for 30 and 60 ms packets. If the encoder sampling rate
|
||||
* is 16 kHz the maximum payload size is between 120 and 400 bytes. If the
|
||||
* encoder sampling rate is 32 kHz the maximum payload size is between 120
|
||||
* and 600 bytes.
|
||||
*
|
||||
* If an out of range limit is used, the function returns -1, but the closest
|
||||
* valid value will be applied.
|
||||
*
|
||||
* ---------------
|
||||
* IMPORTANT NOTES
|
||||
* ---------------
|
||||
* The size of a packet is limited to the minimum of 'max-payload-size' and
|
||||
* 'max-rate.' For instance, let's assume the max-payload-size is set to
|
||||
* 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps
|
||||
* translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms
|
||||
* frame-size. Then a packet with a frame-size of 30 ms is limited to 150,
|
||||
* i.e. min(170, 150), and a packet with 60 ms frame-size is limited to
|
||||
* 170 bytes, i.e. min(170, 300).
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC instance
|
||||
* - maxPayloadBytes : maximum size of the payload in bytes
|
||||
* valid values are between 120 and 400 bytes
|
||||
* if encoder sampling rate is 16 kHz. For
|
||||
* 32 kHz encoder sampling rate valid values
|
||||
* are between 120 and 600 bytes.
|
||||
*
|
||||
* Return value : 0 if successful
|
||||
* -1 if error happens
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_SetMaxPayloadSize(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word16 maxPayloadBytes);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_SetMaxRate(...)
|
||||
*
|
||||
* This function sets the maximum rate which the codec may not exceed for
|
||||
* any signal packet. The maximum rate is defined and payload-size per
|
||||
* frame-size in bits per second.
|
||||
*
|
||||
* The codec has a maximum rate of 53400 bits per second (200 bytes per 30
|
||||
* ms) if the encoder sampling rate is 16kHz, and 160 kbps (600 bytes/30 ms)
|
||||
* if the encoder sampling rate is 32 kHz.
|
||||
*
|
||||
* It is possible to set a maximum rate between 32000 and 53400 bits/sec
|
||||
* in wideband mode, and 32000 to 160000 bits/sec in super-wideband mode.
|
||||
*
|
||||
* If an out of range limit is used, the function returns -1, but the closest
|
||||
* valid value will be applied.
|
||||
*
|
||||
* ---------------
|
||||
* IMPORTANT NOTES
|
||||
* ---------------
|
||||
* The size of a packet is limited to the minimum of 'max-payload-size' and
|
||||
* 'max-rate.' For instance, let's assume the max-payload-size is set to
|
||||
* 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps
|
||||
* translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms
|
||||
* frame-size. Then a packet with a frame-size of 30 ms is limited to 150,
|
||||
* i.e. min(170, 150), and a packet with 60 ms frame-size is limited to
|
||||
* 170 bytes, min(170, 300).
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC instance
|
||||
* - maxRate : maximum rate in bits per second,
|
||||
* valid values are 32000 to 53400 bits/sec in
|
||||
* wideband mode, and 32000 to 160000 bits/sec in
|
||||
* super-wideband mode.
|
||||
*
|
||||
* Return value : 0 if successful
|
||||
* -1 if error happens
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_SetMaxRate(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word32 maxRate);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_DecSampRate()
|
||||
* Return the sampling rate of the decoded audio.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC instance
|
||||
*
|
||||
* Return value : enumerator representing sampling frequency
|
||||
* associated with the decoder, i.e. the
|
||||
* sampling rate of the decoded audio.
|
||||
*
|
||||
*/
|
||||
|
||||
enum IsacSamplingRate WebRtcIsac_DecSampRate(
|
||||
ISACStruct* ISAC_main_inst);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_EncSampRate()
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC instance
|
||||
*
|
||||
* Return value : enumerator representing sampling frequency
|
||||
* associated with the encoder, the input audio
|
||||
* is expected to be sampled at this rate.
|
||||
*
|
||||
*/
|
||||
|
||||
enum IsacSamplingRate WebRtcIsac_EncSampRate(
|
||||
ISACStruct* ISAC_main_inst);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_SetDecSampRate()
|
||||
* Set the sampling rate of the decoder. Initialization of the decoder WILL
|
||||
* NOT overwrite the sampling rate of the encoder. The default value is 16 kHz
|
||||
* which is set when the instance is created.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC instance
|
||||
* - sampRate : enumerator specifying the sampling rate.
|
||||
*
|
||||
* Return value : 0 if successful
|
||||
* -1 if failed.
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_SetDecSampRate(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
enum IsacSamplingRate sampRate);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_SetEncSampRate()
|
||||
* Set the sampling rate of the encoder. Initialization of the encoder WILL
|
||||
* NOT overwrite the sampling rate of the encoder. The default value is 16 kHz
|
||||
* which is set when the instance is created. The encoding-mode and the
|
||||
* bottleneck remain unchanged by this call, however, the maximum rate and
|
||||
* maximum payload-size will reset to their default value.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC instance
|
||||
* - sampRate : enumerator specifying the sampling rate.
|
||||
*
|
||||
* Return value : 0 if successful
|
||||
* -1 if failed.
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_SetEncSampRate(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
enum IsacSamplingRate sampRate);
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_GetNewBitStream(...)
|
||||
*
|
||||
* This function returns encoded data, with the recieved bwe-index in the
|
||||
* stream. If the rate is set to a value less than bottleneck of codec
|
||||
* the new bistream will be re-encoded with the given target rate.
|
||||
* It should always return a complete packet, i.e. only called once
|
||||
* even for 60 msec frames.
|
||||
*
|
||||
* NOTE 1! This function does not write in the ISACStruct, it is not allowed.
|
||||
* NOTE 2! Currently not implemented for SWB mode.
|
||||
* NOTE 3! Rates larger than the bottleneck of the codec will be limited
|
||||
* to the current bottleneck.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - bweIndex : Index of bandwidth estimate to put in new
|
||||
* bitstream
|
||||
* - rate : target rate of the transcoder is bits/sec.
|
||||
* Valid values are the accepted rate in iSAC,
|
||||
* i.e. 10000 to 56000.
|
||||
* - isRCU : if the new bit-stream is an RCU stream.
|
||||
* Note that the rate parameter always indicates
|
||||
* the target rate of the main paylaod, regardless
|
||||
* of 'isRCU' value.
|
||||
*
|
||||
* Output:
|
||||
* - encoded : The encoded data vector
|
||||
*
|
||||
* Return value : >0 - Length (in bytes) of coded data
|
||||
* -1 - Error or called in SWB mode
|
||||
* NOTE! No error code is written to
|
||||
* the struct since it is only allowed to read
|
||||
* the struct.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_GetNewBitStream(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word16 bweIndex,
|
||||
WebRtc_Word16 jitterInfo,
|
||||
WebRtc_Word32 rate,
|
||||
WebRtc_Word16* encoded,
|
||||
WebRtc_Word16 isRCU);
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsac_GetDownLinkBwIndex(...)
|
||||
*
|
||||
* This function returns index representing the Bandwidth estimate from
|
||||
* other side to this side.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC struct
|
||||
*
|
||||
* Output:
|
||||
* - bweIndex : Bandwidth estimate to transmit to other side.
|
||||
*
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_GetDownLinkBwIndex(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word16* bweIndex,
|
||||
WebRtc_Word16* jitterInfo);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsac_UpdateUplinkBw(...)
|
||||
*
|
||||
* This function takes an index representing the Bandwidth estimate from
|
||||
* this side to other side and updates BWE.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC struct
|
||||
* - bweIndex : Bandwidth estimate from other side.
|
||||
*
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_UpdateUplinkBw(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word16 bweIndex);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsac_ReadBwIndex(...)
|
||||
*
|
||||
* This function returns the index of the Bandwidth estimate from the bitstream.
|
||||
*
|
||||
* Input:
|
||||
* - encoded : Encoded bitstream
|
||||
*
|
||||
* Output:
|
||||
* - frameLength : Length of frame in packet (in samples)
|
||||
* - bweIndex : Bandwidth estimate in bitstream
|
||||
*
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_ReadBwIndex(
|
||||
const WebRtc_Word16* encoded,
|
||||
WebRtc_Word16* bweIndex);
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* WebRtcIsac_GetNewFrameLen(...)
|
||||
*
|
||||
* returns the frame lenght (in samples) of the next packet. In the case of channel-adaptive
|
||||
* mode, iSAC decides on its frame lenght based on the estimated bottleneck
|
||||
* this allows a user to prepare for the next packet (at the encoder)
|
||||
*
|
||||
* The primary usage is in CE to make the iSAC works in channel-adaptive mode
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC struct
|
||||
*
|
||||
* Return Value : frame lenght in samples
|
||||
*
|
||||
*/
|
||||
|
||||
WebRtc_Word16 WebRtcIsac_GetNewFrameLen(
|
||||
ISACStruct* ISAC_main_inst);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsac_GetRedPayload(...)
|
||||
*
|
||||
* Populates "encoded" with the redundant payload of the recently encoded
|
||||
* frame. This function has to be called once that WebRtcIsac_Encode(...)
|
||||
* returns a positive value. Regardless of the frame-size this function will
|
||||
* be called only once after encoding is completed.
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : iSAC struct
|
||||
*
|
||||
* Output:
|
||||
* - encoded : the encoded data vector
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
* : >0 - Length (in bytes) of coded data
|
||||
* : -1 - Error
|
||||
*
|
||||
*
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_GetRedPayload(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
WebRtc_Word16* encoded);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcIsac_DecodeRcu(...)
|
||||
*
|
||||
* This function decodes a redundant (RCU) iSAC frame. Function is called in
|
||||
* NetEq with a stored RCU payload i case of packet loss. Output speech length
|
||||
* will be a multiple of 480 samples: 480 or 960 samples,
|
||||
* depending on the framesize (30 or 60 ms).
|
||||
*
|
||||
* Input:
|
||||
* - ISAC_main_inst : ISAC instance.
|
||||
* - encoded : encoded ISAC RCU frame(s)
|
||||
* - len : bytes in encoded vector
|
||||
*
|
||||
* Output:
|
||||
* - decoded : The decoded vector
|
||||
*
|
||||
* Return value : >0 - number of samples in decoded vector
|
||||
* -1 - Error
|
||||
*/
|
||||
WebRtc_Word16 WebRtcIsac_DecodeRcu(
|
||||
ISACStruct* ISAC_main_inst,
|
||||
const WebRtc_UWord16* encoded,
|
||||
WebRtc_Word16 len,
|
||||
WebRtc_Word16* decoded,
|
||||
WebRtc_Word16* speechType);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_ISAC_H_ */
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* lattice.c
|
||||
*
|
||||
* contains the normalized lattice filter routines (MA and AR) for iSAC codec
|
||||
*
|
||||
*/
|
||||
#include "settings.h"
|
||||
#include "codec.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
#ifdef WEBRTC_ANDROID
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* filter the signal using normalized lattice filter */
|
||||
/* MA filter */
|
||||
void WebRtcIsac_NormLatticeFilterMa(int orderCoef,
|
||||
float *stateF,
|
||||
float *stateG,
|
||||
float *lat_in,
|
||||
double *filtcoeflo,
|
||||
double *lat_out)
|
||||
{
|
||||
int n,k,i,u,temp1;
|
||||
int ord_1 = orderCoef+1;
|
||||
float sth[MAX_AR_MODEL_ORDER];
|
||||
float cth[MAX_AR_MODEL_ORDER];
|
||||
float inv_cth[MAX_AR_MODEL_ORDER];
|
||||
double a[MAX_AR_MODEL_ORDER+1];
|
||||
float f[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN], g[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN];
|
||||
float gain1;
|
||||
|
||||
for (u=0;u<SUBFRAMES;u++)
|
||||
{
|
||||
/* set the Direct Form coefficients */
|
||||
temp1 = u*ord_1;
|
||||
a[0] = 1;
|
||||
memcpy(a+1, filtcoeflo+temp1+1, sizeof(double) * (ord_1-1));
|
||||
|
||||
/* compute lattice filter coefficients */
|
||||
WebRtcIsac_Dir2Lat(a,orderCoef,sth,cth);
|
||||
|
||||
/* compute the gain */
|
||||
gain1 = (float)filtcoeflo[temp1];
|
||||
for (k=0;k<orderCoef;k++)
|
||||
{
|
||||
gain1 *= cth[k];
|
||||
inv_cth[k] = 1/cth[k];
|
||||
}
|
||||
|
||||
/* normalized lattice filter */
|
||||
/*****************************/
|
||||
|
||||
/* initial conditions */
|
||||
for (i=0;i<HALF_SUBFRAMELEN;i++)
|
||||
{
|
||||
f[0][i] = lat_in[i + u * HALF_SUBFRAMELEN];
|
||||
g[0][i] = lat_in[i + u * HALF_SUBFRAMELEN];
|
||||
}
|
||||
|
||||
/* get the state of f&g for the first input, for all orders */
|
||||
for (i=1;i<ord_1;i++)
|
||||
{
|
||||
f[i][0] = inv_cth[i-1]*(f[i-1][0] + sth[i-1]*stateG[i-1]);
|
||||
g[i][0] = cth[i-1]*stateG[i-1] + sth[i-1]* f[i][0];
|
||||
}
|
||||
|
||||
/* filtering */
|
||||
for(k=0;k<orderCoef;k++)
|
||||
{
|
||||
for(n=0;n<(HALF_SUBFRAMELEN-1);n++)
|
||||
{
|
||||
f[k+1][n+1] = inv_cth[k]*(f[k][n+1] + sth[k]*g[k][n]);
|
||||
g[k+1][n+1] = cth[k]*g[k][n] + sth[k]* f[k+1][n+1];
|
||||
}
|
||||
}
|
||||
|
||||
for(n=0;n<HALF_SUBFRAMELEN;n++)
|
||||
{
|
||||
lat_out[n + u * HALF_SUBFRAMELEN] = gain1 * f[orderCoef][n];
|
||||
}
|
||||
|
||||
/* save the states */
|
||||
for (i=0;i<ord_1;i++)
|
||||
{
|
||||
stateF[i] = f[i][HALF_SUBFRAMELEN-1];
|
||||
stateG[i] = g[i][HALF_SUBFRAMELEN-1];
|
||||
}
|
||||
/* process next frame */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*///////////////////AR filter ///////////////////////////////*/
|
||||
/* filter the signal using normalized lattice filter */
|
||||
void WebRtcIsac_NormLatticeFilterAr(int orderCoef,
|
||||
float *stateF,
|
||||
float *stateG,
|
||||
double *lat_in,
|
||||
double *lo_filt_coef,
|
||||
float *lat_out)
|
||||
{
|
||||
int n,k,i,u,temp1;
|
||||
int ord_1 = orderCoef+1;
|
||||
float sth[MAX_AR_MODEL_ORDER];
|
||||
float cth[MAX_AR_MODEL_ORDER];
|
||||
double a[MAX_AR_MODEL_ORDER+1];
|
||||
float ARf[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN], ARg[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN];
|
||||
float gain1,inv_gain1;
|
||||
|
||||
for (u=0;u<SUBFRAMES;u++)
|
||||
{
|
||||
/* set the denominator and numerator of the Direct Form */
|
||||
temp1 = u*ord_1;
|
||||
a[0] = 1;
|
||||
|
||||
memcpy(a+1, lo_filt_coef+temp1+1, sizeof(double) * (ord_1-1));
|
||||
|
||||
WebRtcIsac_Dir2Lat(a,orderCoef,sth,cth);
|
||||
|
||||
gain1 = (float)lo_filt_coef[temp1];
|
||||
for (k=0;k<orderCoef;k++)
|
||||
{
|
||||
gain1 = cth[k]*gain1;
|
||||
}
|
||||
|
||||
/* initial conditions */
|
||||
inv_gain1 = 1/gain1;
|
||||
for (i=0;i<HALF_SUBFRAMELEN;i++)
|
||||
{
|
||||
ARf[orderCoef][i] = (float)lat_in[i + u * HALF_SUBFRAMELEN]*inv_gain1;
|
||||
}
|
||||
|
||||
|
||||
for (i=orderCoef-1;i>=0;i--) //get the state of f&g for the first input, for all orders
|
||||
{
|
||||
ARf[i][0] = cth[i]*ARf[i+1][0] - sth[i]*stateG[i];
|
||||
ARg[i+1][0] = sth[i]*ARf[i+1][0] + cth[i]* stateG[i];
|
||||
}
|
||||
ARg[0][0] = ARf[0][0];
|
||||
|
||||
for(n=0;n<(HALF_SUBFRAMELEN-1);n++)
|
||||
{
|
||||
for(k=orderCoef-1;k>=0;k--)
|
||||
{
|
||||
ARf[k][n+1] = cth[k]*ARf[k+1][n+1] - sth[k]*ARg[k][n];
|
||||
ARg[k+1][n+1] = sth[k]*ARf[k+1][n+1] + cth[k]* ARg[k][n];
|
||||
}
|
||||
ARg[0][n+1] = ARf[0][n+1];
|
||||
}
|
||||
|
||||
memcpy(lat_out+u * HALF_SUBFRAMELEN, &(ARf[0][0]), sizeof(float) * HALF_SUBFRAMELEN);
|
||||
|
||||
/* cannot use memcpy in the following */
|
||||
for (i=0;i<ord_1;i++)
|
||||
{
|
||||
stateF[i] = ARf[i][HALF_SUBFRAMELEN-1];
|
||||
stateG[i] = ARg[i][HALF_SUBFRAMELEN-1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* compute the reflection coefficients using the step-down procedure*/
|
||||
/* converts the direct form parameters to lattice form.*/
|
||||
/* a and b are vectors which contain the direct form coefficients,
|
||||
according to
|
||||
A(z) = a(1) + a(2)*z + a(3)*z^2 + ... + a(M+1)*z^M
|
||||
B(z) = b(1) + b(2)*z + b(3)*z^2 + ... + b(M+1)*z^M
|
||||
*/
|
||||
|
||||
void WebRtcIsac_Dir2Lat(double *a,
|
||||
int orderCoef,
|
||||
float *sth,
|
||||
float *cth)
|
||||
{
|
||||
int m, k;
|
||||
float tmp[MAX_AR_MODEL_ORDER];
|
||||
float tmp_inv, cth2;
|
||||
|
||||
sth[orderCoef-1] = (float)a[orderCoef];
|
||||
cth2 = 1.0f - sth[orderCoef-1] * sth[orderCoef-1];
|
||||
cth[orderCoef-1] = (float)sqrt(cth2);
|
||||
for (m=orderCoef-1; m>0; m--)
|
||||
{
|
||||
tmp_inv = 1.0f / cth2;
|
||||
for (k=1; k<=m; k++)
|
||||
{
|
||||
tmp[k] = ((float)a[k] - sth[m] * (float)a[m-k+1]) * tmp_inv;
|
||||
}
|
||||
|
||||
for (k=1; k<m; k++)
|
||||
{
|
||||
a[k] = tmp[k];
|
||||
}
|
||||
|
||||
sth[m-1] = tmp[m];
|
||||
cth2 = 1 - sth[m-1] * sth[m-1];
|
||||
cth[m-1] = (float)sqrt(cth2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,535 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "lpc_analysis.h"
|
||||
#include "settings.h"
|
||||
#include "codec.h"
|
||||
#include "entropy_coding.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LEVINSON_EPS 1.0e-10
|
||||
|
||||
|
||||
/* window */
|
||||
/* Matlab generation code:
|
||||
* t = (1:256)/257; r = 1-(1-t).^.45; w = sin(r*pi).^3; w = w/sum(w); plot((1:256)/8, w); grid;
|
||||
* for k=1:16, fprintf(1, '%.8f, ', w(k*16 + (-15:0))); fprintf(1, '\n'); end
|
||||
*/
|
||||
static const double kLpcCorrWindow[WINLEN] = {
|
||||
0.00000000, 0.00000001, 0.00000004, 0.00000010, 0.00000020,
|
||||
0.00000035, 0.00000055, 0.00000083, 0.00000118, 0.00000163,
|
||||
0.00000218, 0.00000283, 0.00000361, 0.00000453, 0.00000558, 0.00000679,
|
||||
0.00000817, 0.00000973, 0.00001147, 0.00001342, 0.00001558,
|
||||
0.00001796, 0.00002058, 0.00002344, 0.00002657, 0.00002997,
|
||||
0.00003365, 0.00003762, 0.00004190, 0.00004651, 0.00005144, 0.00005673,
|
||||
0.00006236, 0.00006837, 0.00007476, 0.00008155, 0.00008875,
|
||||
0.00009636, 0.00010441, 0.00011290, 0.00012186, 0.00013128,
|
||||
0.00014119, 0.00015160, 0.00016252, 0.00017396, 0.00018594, 0.00019846,
|
||||
0.00021155, 0.00022521, 0.00023946, 0.00025432, 0.00026978,
|
||||
0.00028587, 0.00030260, 0.00031998, 0.00033802, 0.00035674,
|
||||
0.00037615, 0.00039626, 0.00041708, 0.00043863, 0.00046092, 0.00048396,
|
||||
0.00050775, 0.00053233, 0.00055768, 0.00058384, 0.00061080,
|
||||
0.00063858, 0.00066720, 0.00069665, 0.00072696, 0.00075813,
|
||||
0.00079017, 0.00082310, 0.00085692, 0.00089164, 0.00092728, 0.00096384,
|
||||
0.00100133, 0.00103976, 0.00107914, 0.00111947, 0.00116077,
|
||||
0.00120304, 0.00124630, 0.00129053, 0.00133577, 0.00138200,
|
||||
0.00142924, 0.00147749, 0.00152676, 0.00157705, 0.00162836, 0.00168070,
|
||||
0.00173408, 0.00178850, 0.00184395, 0.00190045, 0.00195799,
|
||||
0.00201658, 0.00207621, 0.00213688, 0.00219860, 0.00226137,
|
||||
0.00232518, 0.00239003, 0.00245591, 0.00252284, 0.00259079, 0.00265977,
|
||||
0.00272977, 0.00280078, 0.00287280, 0.00294582, 0.00301984,
|
||||
0.00309484, 0.00317081, 0.00324774, 0.00332563, 0.00340446,
|
||||
0.00348421, 0.00356488, 0.00364644, 0.00372889, 0.00381220, 0.00389636,
|
||||
0.00398135, 0.00406715, 0.00415374, 0.00424109, 0.00432920,
|
||||
0.00441802, 0.00450754, 0.00459773, 0.00468857, 0.00478001,
|
||||
0.00487205, 0.00496464, 0.00505775, 0.00515136, 0.00524542, 0.00533990,
|
||||
0.00543476, 0.00552997, 0.00562548, 0.00572125, 0.00581725,
|
||||
0.00591342, 0.00600973, 0.00610612, 0.00620254, 0.00629895,
|
||||
0.00639530, 0.00649153, 0.00658758, 0.00668341, 0.00677894, 0.00687413,
|
||||
0.00696891, 0.00706322, 0.00715699, 0.00725016, 0.00734266,
|
||||
0.00743441, 0.00752535, 0.00761540, 0.00770449, 0.00779254,
|
||||
0.00787947, 0.00796519, 0.00804963, 0.00813270, 0.00821431, 0.00829437,
|
||||
0.00837280, 0.00844949, 0.00852436, 0.00859730, 0.00866822,
|
||||
0.00873701, 0.00880358, 0.00886781, 0.00892960, 0.00898884,
|
||||
0.00904542, 0.00909923, 0.00915014, 0.00919805, 0.00924283, 0.00928436,
|
||||
0.00932252, 0.00935718, 0.00938821, 0.00941550, 0.00943890,
|
||||
0.00945828, 0.00947351, 0.00948446, 0.00949098, 0.00949294,
|
||||
0.00949020, 0.00948262, 0.00947005, 0.00945235, 0.00942938, 0.00940099,
|
||||
0.00936704, 0.00932738, 0.00928186, 0.00923034, 0.00917268,
|
||||
0.00910872, 0.00903832, 0.00896134, 0.00887763, 0.00878706,
|
||||
0.00868949, 0.00858478, 0.00847280, 0.00835343, 0.00822653, 0.00809199,
|
||||
0.00794970, 0.00779956, 0.00764145, 0.00747530, 0.00730103,
|
||||
0.00711857, 0.00692787, 0.00672888, 0.00652158, 0.00630597,
|
||||
0.00608208, 0.00584994, 0.00560962, 0.00536124, 0.00510493, 0.00484089,
|
||||
0.00456935, 0.00429062, 0.00400505, 0.00371310, 0.00341532,
|
||||
0.00311238, 0.00280511, 0.00249452, 0.00218184, 0.00186864,
|
||||
0.00155690, 0.00124918, 0.00094895, 0.00066112, 0.00039320, 0.00015881
|
||||
};
|
||||
|
||||
double WebRtcIsac_LevDurb(double *a, double *k, double *r, int order)
|
||||
{
|
||||
|
||||
double sum, alpha;
|
||||
int m, m_h, i;
|
||||
alpha = 0; //warning -DH
|
||||
a[0] = 1.0;
|
||||
if (r[0] < LEVINSON_EPS) { /* if r[0] <= 0, set LPC coeff. to zero */
|
||||
for (i = 0; i < order; i++) {
|
||||
k[i] = 0;
|
||||
a[i+1] = 0;
|
||||
}
|
||||
} else {
|
||||
a[1] = k[0] = -r[1]/r[0];
|
||||
alpha = r[0] + r[1] * k[0];
|
||||
for (m = 1; m < order; m++){
|
||||
sum = r[m + 1];
|
||||
for (i = 0; i < m; i++){
|
||||
sum += a[i+1] * r[m - i];
|
||||
}
|
||||
k[m] = -sum / alpha;
|
||||
alpha += k[m] * sum;
|
||||
m_h = (m + 1) >> 1;
|
||||
for (i = 0; i < m_h; i++){
|
||||
sum = a[i+1] + k[m] * a[m - i];
|
||||
a[m - i] += k[m] * a[i+1];
|
||||
a[i+1] = sum;
|
||||
}
|
||||
a[m+1] = k[m];
|
||||
}
|
||||
}
|
||||
return alpha;
|
||||
}
|
||||
|
||||
|
||||
//was static before, but didn't work with MEX file
|
||||
void WebRtcIsac_GetVars(const double *input, const WebRtc_Word16 *pitchGains_Q12,
|
||||
double *oldEnergy, double *varscale)
|
||||
{
|
||||
double nrg[4], chng, pg;
|
||||
int k;
|
||||
|
||||
double pitchGains[4]={0,0,0,0};;
|
||||
|
||||
/* Calculate energies of first and second frame halfs */
|
||||
nrg[0] = 0.0001;
|
||||
for (k = QLOOKAHEAD/2; k < (FRAMESAMPLES_QUARTER + QLOOKAHEAD) / 2; k++) {
|
||||
nrg[0] += input[k]*input[k];
|
||||
}
|
||||
nrg[1] = 0.0001;
|
||||
for ( ; k < (FRAMESAMPLES_HALF + QLOOKAHEAD) / 2; k++) {
|
||||
nrg[1] += input[k]*input[k];
|
||||
}
|
||||
nrg[2] = 0.0001;
|
||||
for ( ; k < (FRAMESAMPLES*3/4 + QLOOKAHEAD) / 2; k++) {
|
||||
nrg[2] += input[k]*input[k];
|
||||
}
|
||||
nrg[3] = 0.0001;
|
||||
for ( ; k < (FRAMESAMPLES + QLOOKAHEAD) / 2; k++) {
|
||||
nrg[3] += input[k]*input[k];
|
||||
}
|
||||
|
||||
/* Calculate average level change */
|
||||
chng = 0.25 * (fabs(10.0 * log10(nrg[3] / nrg[2])) +
|
||||
fabs(10.0 * log10(nrg[2] / nrg[1])) +
|
||||
fabs(10.0 * log10(nrg[1] / nrg[0])) +
|
||||
fabs(10.0 * log10(nrg[0] / *oldEnergy)));
|
||||
|
||||
|
||||
/* Find average pitch gain */
|
||||
pg = 0.0;
|
||||
for (k=0; k<4; k++)
|
||||
{
|
||||
pitchGains[k] = ((float)pitchGains_Q12[k])/4096;
|
||||
pg += pitchGains[k];
|
||||
}
|
||||
pg *= 0.25;
|
||||
|
||||
/* If pitch gain is low and energy constant - increase noise level*/
|
||||
/* Matlab code:
|
||||
pg = 0:.01:.45; plot(pg, 0.0 + 1.0 * exp( -1.0 * exp(-200.0 * pg.*pg.*pg) / (1.0 + 0.4 * 0) ))
|
||||
*/
|
||||
*varscale = 0.0 + 1.0 * exp( -1.4 * exp(-200.0 * pg*pg*pg) / (1.0 + 0.4 * chng) );
|
||||
|
||||
*oldEnergy = nrg[3];
|
||||
}
|
||||
|
||||
void
|
||||
WebRtcIsac_GetVarsUB(
|
||||
const double* input,
|
||||
double* oldEnergy,
|
||||
double* varscale)
|
||||
{
|
||||
double nrg[4], chng;
|
||||
int k;
|
||||
|
||||
/* Calculate energies of first and second frame halfs */
|
||||
nrg[0] = 0.0001;
|
||||
for (k = 0; k < (FRAMESAMPLES_QUARTER) / 2; k++) {
|
||||
nrg[0] += input[k]*input[k];
|
||||
}
|
||||
nrg[1] = 0.0001;
|
||||
for ( ; k < (FRAMESAMPLES_HALF) / 2; k++) {
|
||||
nrg[1] += input[k]*input[k];
|
||||
}
|
||||
nrg[2] = 0.0001;
|
||||
for ( ; k < (FRAMESAMPLES*3/4) / 2; k++) {
|
||||
nrg[2] += input[k]*input[k];
|
||||
}
|
||||
nrg[3] = 0.0001;
|
||||
for ( ; k < (FRAMESAMPLES) / 2; k++) {
|
||||
nrg[3] += input[k]*input[k];
|
||||
}
|
||||
|
||||
/* Calculate average level change */
|
||||
chng = 0.25 * (fabs(10.0 * log10(nrg[3] / nrg[2])) +
|
||||
fabs(10.0 * log10(nrg[2] / nrg[1])) +
|
||||
fabs(10.0 * log10(nrg[1] / nrg[0])) +
|
||||
fabs(10.0 * log10(nrg[0] / *oldEnergy)));
|
||||
|
||||
|
||||
/* If pitch gain is low and energy constant - increase noise level*/
|
||||
/* Matlab code:
|
||||
pg = 0:.01:.45; plot(pg, 0.0 + 1.0 * exp( -1.0 * exp(-200.0 * pg.*pg.*pg) / (1.0 + 0.4 * 0) ))
|
||||
*/
|
||||
*varscale = exp( -1.4 / (1.0 + 0.4 * chng) );
|
||||
|
||||
*oldEnergy = nrg[3];
|
||||
}
|
||||
|
||||
void WebRtcIsac_GetLpcCoefLb(double *inLo, double *inHi, MaskFiltstr *maskdata,
|
||||
double signal_noise_ratio, const WebRtc_Word16 *pitchGains_Q12,
|
||||
double *lo_coeff, double *hi_coeff)
|
||||
{
|
||||
int k, n, j, pos1, pos2;
|
||||
double varscale;
|
||||
|
||||
double DataLo[WINLEN], DataHi[WINLEN];
|
||||
double corrlo[ORDERLO+2], corrlo2[ORDERLO+1];
|
||||
double corrhi[ORDERHI+1];
|
||||
double k_veclo[ORDERLO], k_vechi[ORDERHI];
|
||||
|
||||
double a_LO[ORDERLO+1], a_HI[ORDERHI+1];
|
||||
double tmp, res_nrg;
|
||||
|
||||
double FwdA, FwdB;
|
||||
|
||||
/* hearing threshold level in dB; higher value gives more noise */
|
||||
const double HearThresOffset = -28.0;
|
||||
|
||||
/* bandwdith expansion factors for low- and high band */
|
||||
const double gammaLo = 0.9;
|
||||
const double gammaHi = 0.8;
|
||||
|
||||
/* less-noise-at-low-frequencies factor */
|
||||
double aa;
|
||||
|
||||
|
||||
/* convert from dB to signal level */
|
||||
const double H_T_H = pow(10.0, 0.05 * HearThresOffset);
|
||||
double S_N_R = pow(10.0, 0.05 * signal_noise_ratio) / 3.46; /* divide by sqrt(12) */
|
||||
|
||||
/* change quallevel depending on pitch gains and level fluctuations */
|
||||
WebRtcIsac_GetVars(inLo, pitchGains_Q12, &(maskdata->OldEnergy), &varscale);
|
||||
|
||||
/* less-noise-at-low-frequencies factor */
|
||||
aa = 0.35 * (0.5 + 0.5 * varscale);
|
||||
|
||||
/* replace data in buffer by new look-ahead data */
|
||||
for (pos1 = 0; pos1 < QLOOKAHEAD; pos1++)
|
||||
maskdata->DataBufferLo[pos1 + WINLEN - QLOOKAHEAD] = inLo[pos1];
|
||||
|
||||
for (k = 0; k < SUBFRAMES; k++) {
|
||||
|
||||
/* Update input buffer and multiply signal with window */
|
||||
for (pos1 = 0; pos1 < WINLEN - UPDATE/2; pos1++) {
|
||||
maskdata->DataBufferLo[pos1] = maskdata->DataBufferLo[pos1 + UPDATE/2];
|
||||
maskdata->DataBufferHi[pos1] = maskdata->DataBufferHi[pos1 + UPDATE/2];
|
||||
DataLo[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1];
|
||||
DataHi[pos1] = maskdata->DataBufferHi[pos1] * kLpcCorrWindow[pos1];
|
||||
}
|
||||
pos2 = k * UPDATE/2;
|
||||
for (n = 0; n < UPDATE/2; n++, pos1++) {
|
||||
maskdata->DataBufferLo[pos1] = inLo[QLOOKAHEAD + pos2];
|
||||
maskdata->DataBufferHi[pos1] = inHi[pos2++];
|
||||
DataLo[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1];
|
||||
DataHi[pos1] = maskdata->DataBufferHi[pos1] * kLpcCorrWindow[pos1];
|
||||
}
|
||||
|
||||
/* Get correlation coefficients */
|
||||
WebRtcIsac_AutoCorr(corrlo, DataLo, WINLEN, ORDERLO+1); /* computing autocorrelation */
|
||||
WebRtcIsac_AutoCorr(corrhi, DataHi, WINLEN, ORDERHI);
|
||||
|
||||
|
||||
/* less noise for lower frequencies, by filtering/scaling autocorrelation sequences */
|
||||
corrlo2[0] = (1.0+aa*aa) * corrlo[0] - 2.0*aa * corrlo[1];
|
||||
tmp = (1.0 + aa*aa);
|
||||
for (n = 1; n <= ORDERLO; n++) {
|
||||
corrlo2[n] = tmp * corrlo[n] - aa * (corrlo[n-1] + corrlo[n+1]);
|
||||
}
|
||||
tmp = (1.0+aa) * (1.0+aa);
|
||||
for (n = 0; n <= ORDERHI; n++) {
|
||||
corrhi[n] = tmp * corrhi[n];
|
||||
}
|
||||
|
||||
/* add white noise floor */
|
||||
corrlo2[0] += 1e-6;
|
||||
corrhi[0] += 1e-6;
|
||||
|
||||
|
||||
FwdA = 0.01;
|
||||
FwdB = 0.01;
|
||||
|
||||
/* recursive filtering of correlation over subframes */
|
||||
for (n = 0; n <= ORDERLO; n++) {
|
||||
maskdata->CorrBufLo[n] = FwdA * maskdata->CorrBufLo[n] + corrlo2[n];
|
||||
corrlo2[n] = ((1.0-FwdA)*FwdB) * maskdata->CorrBufLo[n] + (1.0-FwdB) * corrlo2[n];
|
||||
}
|
||||
for (n = 0; n <= ORDERHI; n++) {
|
||||
maskdata->CorrBufHi[n] = FwdA * maskdata->CorrBufHi[n] + corrhi[n];
|
||||
corrhi[n] = ((1.0-FwdA)*FwdB) * maskdata->CorrBufHi[n] + (1.0-FwdB) * corrhi[n];
|
||||
}
|
||||
|
||||
/* compute prediction coefficients */
|
||||
WebRtcIsac_LevDurb(a_LO, k_veclo, corrlo2, ORDERLO);
|
||||
WebRtcIsac_LevDurb(a_HI, k_vechi, corrhi, ORDERHI);
|
||||
|
||||
/* bandwidth expansion */
|
||||
tmp = gammaLo;
|
||||
for (n = 1; n <= ORDERLO; n++) {
|
||||
a_LO[n] *= tmp;
|
||||
tmp *= gammaLo;
|
||||
}
|
||||
|
||||
/* residual energy */
|
||||
res_nrg = 0.0;
|
||||
for (j = 0; j <= ORDERLO; j++) {
|
||||
for (n = 0; n <= j; n++) {
|
||||
res_nrg += a_LO[j] * corrlo2[j-n] * a_LO[n];
|
||||
}
|
||||
for (n = j+1; n <= ORDERLO; n++) {
|
||||
res_nrg += a_LO[j] * corrlo2[n-j] * a_LO[n];
|
||||
}
|
||||
}
|
||||
|
||||
/* add hearing threshold and compute the gain */
|
||||
*lo_coeff++ = S_N_R / (sqrt(res_nrg) / varscale + H_T_H);
|
||||
|
||||
/* copy coefficients to output array */
|
||||
for (n = 1; n <= ORDERLO; n++) {
|
||||
*lo_coeff++ = a_LO[n];
|
||||
}
|
||||
|
||||
|
||||
/* bandwidth expansion */
|
||||
tmp = gammaHi;
|
||||
for (n = 1; n <= ORDERHI; n++) {
|
||||
a_HI[n] *= tmp;
|
||||
tmp *= gammaHi;
|
||||
}
|
||||
|
||||
/* residual energy */
|
||||
res_nrg = 0.0;
|
||||
for (j = 0; j <= ORDERHI; j++) {
|
||||
for (n = 0; n <= j; n++) {
|
||||
res_nrg += a_HI[j] * corrhi[j-n] * a_HI[n];
|
||||
}
|
||||
for (n = j+1; n <= ORDERHI; n++) {
|
||||
res_nrg += a_HI[j] * corrhi[n-j] * a_HI[n];
|
||||
}
|
||||
}
|
||||
|
||||
/* add hearing threshold and compute of the gain */
|
||||
*hi_coeff++ = S_N_R / (sqrt(res_nrg) / varscale + H_T_H);
|
||||
|
||||
/* copy coefficients to output array */
|
||||
for (n = 1; n <= ORDERHI; n++) {
|
||||
*hi_coeff++ = a_HI[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_GetLpcCoefUb()
|
||||
*
|
||||
* Compute LP coefficients and correlation coefficients. At 12 kHz LP
|
||||
* coefficients of the first and the last sub-frame is computed. At 16 kHz
|
||||
* LP coefficients of 4th, 8th and 12th sub-frames are computed. We always
|
||||
* compute correlation coefficients of all sub-frames.
|
||||
*
|
||||
* Inputs:
|
||||
* -inSignal : Input signal
|
||||
* -maskdata : a structure keeping signal from previous frame.
|
||||
* -bandwidth : specifies if the codec is in 0-16 kHz mode or
|
||||
* 0-12 kHz mode.
|
||||
*
|
||||
* Outputs:
|
||||
* -lpCoeff : pointer to a buffer where A-polynomials are
|
||||
* written to (first coeff is 1 and it is not
|
||||
* written)
|
||||
* -corrMat : a matrix where correlation coefficients of each
|
||||
* sub-frame are written to one row.
|
||||
* -varscale : a scale used to compute LPC gains.
|
||||
*/
|
||||
void
|
||||
WebRtcIsac_GetLpcCoefUb(
|
||||
double* inSignal,
|
||||
MaskFiltstr* maskdata,
|
||||
double* lpCoeff,
|
||||
double corrMat[][UB_LPC_ORDER + 1],
|
||||
double* varscale,
|
||||
WebRtc_Word16 bandwidth)
|
||||
{
|
||||
int frameCntr, activeFrameCntr, n, pos1, pos2;
|
||||
WebRtc_Word16 criterion1;
|
||||
WebRtc_Word16 criterion2;
|
||||
WebRtc_Word16 numSubFrames = SUBFRAMES * (1 + (bandwidth == isac16kHz));
|
||||
double data[WINLEN];
|
||||
double corrSubFrame[UB_LPC_ORDER+2];
|
||||
double reflecCoeff[UB_LPC_ORDER];
|
||||
|
||||
double aPolynom[UB_LPC_ORDER+1];
|
||||
double tmp;
|
||||
|
||||
/* bandwdith expansion factors */
|
||||
const double gamma = 0.9;
|
||||
|
||||
/* change quallevel depending on pitch gains and level fluctuations */
|
||||
WebRtcIsac_GetVarsUB(inSignal, &(maskdata->OldEnergy), varscale);
|
||||
|
||||
/* replace data in buffer by new look-ahead data */
|
||||
for(frameCntr = 0, activeFrameCntr = 0; frameCntr < numSubFrames;
|
||||
frameCntr++)
|
||||
{
|
||||
if(frameCntr == SUBFRAMES)
|
||||
{
|
||||
// we are in 16 kHz
|
||||
varscale++;
|
||||
WebRtcIsac_GetVarsUB(&inSignal[FRAMESAMPLES_HALF],
|
||||
&(maskdata->OldEnergy), varscale);
|
||||
}
|
||||
/* Update input buffer and multiply signal with window */
|
||||
for(pos1 = 0; pos1 < WINLEN - UPDATE/2; pos1++)
|
||||
{
|
||||
maskdata->DataBufferLo[pos1] = maskdata->DataBufferLo[pos1 +
|
||||
UPDATE/2];
|
||||
data[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1];
|
||||
}
|
||||
pos2 = frameCntr * UPDATE/2;
|
||||
for(n = 0; n < UPDATE/2; n++, pos1++, pos2++)
|
||||
{
|
||||
maskdata->DataBufferLo[pos1] = inSignal[pos2];
|
||||
data[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1];
|
||||
}
|
||||
|
||||
/* Get correlation coefficients */
|
||||
/* computing autocorrelation */
|
||||
WebRtcIsac_AutoCorr(corrSubFrame, data, WINLEN, UB_LPC_ORDER+1);
|
||||
memcpy(corrMat[frameCntr], corrSubFrame,
|
||||
(UB_LPC_ORDER+1)*sizeof(double));
|
||||
|
||||
criterion1 = ((frameCntr == 0) || (frameCntr == (SUBFRAMES - 1))) &&
|
||||
(bandwidth == isac12kHz);
|
||||
criterion2 = (((frameCntr+1) % 4) == 0) &&
|
||||
(bandwidth == isac16kHz);
|
||||
if(criterion1 || criterion2)
|
||||
{
|
||||
/* add noise */
|
||||
corrSubFrame[0] += 1e-6;
|
||||
/* compute prediction coefficients */
|
||||
WebRtcIsac_LevDurb(aPolynom, reflecCoeff, corrSubFrame,
|
||||
UB_LPC_ORDER);
|
||||
|
||||
/* bandwidth expansion */
|
||||
tmp = gamma;
|
||||
for (n = 1; n <= UB_LPC_ORDER; n++)
|
||||
{
|
||||
*lpCoeff++ = aPolynom[n] * tmp;
|
||||
tmp *= gamma;
|
||||
}
|
||||
activeFrameCntr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* WebRtcIsac_GetLpcGain()
|
||||
*
|
||||
* Compute the LPC gains for each sub-frame, given the LPC of each sub-frame
|
||||
* and the corresponding correlation coefficients.
|
||||
*
|
||||
* Inputs:
|
||||
* -signal_noise_ratio : the desired SNR in dB.
|
||||
* -numVecs : number of sub-frames
|
||||
* -corrMat : a matrix of correlation coefficients where
|
||||
* each row is a set of correlation coefficients of
|
||||
* one sub-frame.
|
||||
* -varscale : a scale computed when WebRtcIsac_GetLpcCoefUb()
|
||||
* is called.
|
||||
*
|
||||
* Outputs:
|
||||
* -gain : pointer to a buffer where LP gains are written.
|
||||
*
|
||||
*/
|
||||
void
|
||||
WebRtcIsac_GetLpcGain(
|
||||
double signal_noise_ratio,
|
||||
const double* filtCoeffVecs,
|
||||
int numVecs,
|
||||
double* gain,
|
||||
double corrMat[][UB_LPC_ORDER + 1],
|
||||
const double* varscale)
|
||||
{
|
||||
WebRtc_Word16 j, n;
|
||||
WebRtc_Word16 subFrameCntr;
|
||||
double aPolynom[ORDERLO + 1];
|
||||
double res_nrg;
|
||||
|
||||
const double HearThresOffset = -28.0;
|
||||
const double H_T_H = pow(10.0, 0.05 * HearThresOffset);
|
||||
/* divide by sqrt(12) = 3.46 */
|
||||
const double S_N_R = pow(10.0, 0.05 * signal_noise_ratio) / 3.46;
|
||||
|
||||
aPolynom[0] = 1;
|
||||
for(subFrameCntr = 0; subFrameCntr < numVecs; subFrameCntr++)
|
||||
{
|
||||
if(subFrameCntr == SUBFRAMES)
|
||||
{
|
||||
// we are in second half of a SWB frame. use new varscale
|
||||
varscale++;
|
||||
}
|
||||
memcpy(&aPolynom[1], &filtCoeffVecs[(subFrameCntr * (UB_LPC_ORDER + 1)) +
|
||||
1], sizeof(double) * UB_LPC_ORDER);
|
||||
|
||||
/* residual energy */
|
||||
res_nrg = 0.0;
|
||||
for(j = 0; j <= UB_LPC_ORDER; j++)
|
||||
{
|
||||
for(n = 0; n <= j; n++)
|
||||
{
|
||||
res_nrg += aPolynom[j] * corrMat[subFrameCntr][j-n] *
|
||||
aPolynom[n];
|
||||
}
|
||||
for(n = j+1; n <= UB_LPC_ORDER; n++)
|
||||
{
|
||||
res_nrg += aPolynom[j] * corrMat[subFrameCntr][n-j] *
|
||||
aPolynom[n];
|
||||
}
|
||||
}
|
||||
|
||||
/* add hearing threshold and compute the gain */
|
||||
gain[subFrameCntr] = S_N_R / (sqrt(res_nrg) / *varscale + H_T_H);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* lpc_analysis.h
|
||||
*
|
||||
* LPC functions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_ANALYSIS_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_ANALYSIS_H_
|
||||
|
||||
#include "settings.h"
|
||||
#include "structs.h"
|
||||
|
||||
double WebRtcIsac_LevDurb(double *a, double *k, double *r, int order);
|
||||
|
||||
void WebRtcIsac_GetVars(const double *input, const WebRtc_Word16 *pitchGains_Q12,
|
||||
double *oldEnergy, double *varscale);
|
||||
|
||||
void WebRtcIsac_GetLpcCoefLb(double *inLo, double *inHi, MaskFiltstr *maskdata,
|
||||
double signal_noise_ratio, const WebRtc_Word16 *pitchGains_Q12,
|
||||
double *lo_coeff, double *hi_coeff);
|
||||
|
||||
|
||||
void WebRtcIsac_GetLpcGain(
|
||||
double signal_noise_ratio,
|
||||
const double* filtCoeffVecs,
|
||||
int numVecs,
|
||||
double* gain,
|
||||
double corrLo[][UB_LPC_ORDER + 1],
|
||||
const double* varscale);
|
||||
|
||||
void WebRtcIsac_GetLpcCoefUb(
|
||||
double* inSignal,
|
||||
MaskFiltstr* maskdata,
|
||||
double* lpCoeff,
|
||||
double corr[][UB_LPC_ORDER + 1],
|
||||
double* varscale,
|
||||
WebRtc_Word16 bandwidth);
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_ANALYIS_H_ */
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWB_KLT_Tables_LPCGain.c
|
||||
*
|
||||
* This file defines tables used for entropy coding of LPC Gain
|
||||
* of upper-band.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lpc_gain_swb_tables.h"
|
||||
#include "settings.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
const double WebRtcIsac_kQSizeLpcGain = 0.100000;
|
||||
|
||||
const double WebRtcIsac_kMeanLpcGain = -3.3822;
|
||||
|
||||
/*
|
||||
* The smallest reconstruction points for quantiztion of
|
||||
* LPC gains.
|
||||
*/
|
||||
const double WebRtcIsac_kLeftRecPointLpcGain[SUBFRAMES] =
|
||||
{
|
||||
-0.800000, -1.000000, -1.200000, -2.200000, -3.000000, -12.700000
|
||||
};
|
||||
|
||||
/*
|
||||
* Number of reconstruction points of quantizers for LPC Gains.
|
||||
*/
|
||||
const WebRtc_Word16 WebRtcIsac_kNumQCellLpcGain[SUBFRAMES] =
|
||||
{
|
||||
17, 20, 25, 45, 77, 170
|
||||
};
|
||||
/*
|
||||
* Starting index for entropy decoder to search for the right interval,
|
||||
* one entry per LAR coefficient
|
||||
*/
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcGainEntropySearch[SUBFRAMES] =
|
||||
{
|
||||
8, 10, 12, 22, 38, 85
|
||||
};
|
||||
|
||||
/*
|
||||
* The following 6 vectors define CDF of 6 decorrelated LPC
|
||||
* gains.
|
||||
*/
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec0[18] =
|
||||
{
|
||||
0, 10, 27, 83, 234, 568, 1601, 4683, 16830, 57534, 63437,
|
||||
64767, 65229, 65408, 65483, 65514, 65527, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec1[21] =
|
||||
{
|
||||
0, 15, 33, 84, 185, 385, 807, 1619, 3529, 7850, 19488,
|
||||
51365, 62437, 64548, 65088, 65304, 65409, 65484, 65507, 65522, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec2[26] =
|
||||
{
|
||||
0, 15, 29, 54, 89, 145, 228, 380, 652, 1493, 4260,
|
||||
12359, 34133, 50749, 57224, 60814, 62927, 64078, 64742, 65103, 65311, 65418,
|
||||
65473, 65509, 65521, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec3[46] =
|
||||
{
|
||||
0, 8, 12, 16, 26, 42, 56, 76, 111, 164, 247,
|
||||
366, 508, 693, 1000, 1442, 2155, 3188, 4854, 7387, 11249, 17617,
|
||||
30079, 46711, 56291, 60127, 62140, 63258, 63954, 64384, 64690, 64891, 65031,
|
||||
65139, 65227, 65293, 65351, 65399, 65438, 65467, 65492, 65504, 65510, 65518,
|
||||
65523, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec4[78] =
|
||||
{
|
||||
0, 17, 29, 39, 51, 70, 104, 154, 234, 324, 443,
|
||||
590, 760, 971, 1202, 1494, 1845, 2274, 2797, 3366, 4088, 4905,
|
||||
5899, 7142, 8683, 10625, 12983, 16095, 20637, 28216, 38859, 47237, 51537,
|
||||
54150, 56066, 57583, 58756, 59685, 60458, 61103, 61659, 62144, 62550, 62886,
|
||||
63186, 63480, 63743, 63954, 64148, 64320, 64467, 64600, 64719, 64837, 64939,
|
||||
65014, 65098, 65160, 65211, 65250, 65290, 65325, 65344, 65366, 65391, 65410,
|
||||
65430, 65447, 65460, 65474, 65487, 65494, 65501, 65509, 65513, 65518, 65520,
|
||||
65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec5[171] =
|
||||
{
|
||||
0, 10, 12, 14, 16, 18, 23, 29, 35, 42, 51,
|
||||
58, 65, 72, 78, 87, 96, 103, 111, 122, 134, 150,
|
||||
167, 184, 202, 223, 244, 265, 289, 315, 346, 379, 414,
|
||||
450, 491, 532, 572, 613, 656, 700, 751, 802, 853, 905,
|
||||
957, 1021, 1098, 1174, 1250, 1331, 1413, 1490, 1565, 1647, 1730,
|
||||
1821, 1913, 2004, 2100, 2207, 2314, 2420, 2532, 2652, 2783, 2921,
|
||||
3056, 3189, 3327, 3468, 3640, 3817, 3993, 4171, 4362, 4554, 4751,
|
||||
4948, 5142, 5346, 5566, 5799, 6044, 6301, 6565, 6852, 7150, 7470,
|
||||
7797, 8143, 8492, 8835, 9181, 9547, 9919, 10315, 10718, 11136, 11566,
|
||||
12015, 12482, 12967, 13458, 13953, 14432, 14903, 15416, 15936, 16452, 16967,
|
||||
17492, 18024, 18600, 19173, 19736, 20311, 20911, 21490, 22041, 22597, 23157,
|
||||
23768, 24405, 25034, 25660, 26280, 26899, 27614, 28331, 29015, 29702, 30403,
|
||||
31107, 31817, 32566, 33381, 34224, 35099, 36112, 37222, 38375, 39549, 40801,
|
||||
42074, 43350, 44626, 45982, 47354, 48860, 50361, 51845, 53312, 54739, 56026,
|
||||
57116, 58104, 58996, 59842, 60658, 61488, 62324, 63057, 63769, 64285, 64779,
|
||||
65076, 65344, 65430, 65500, 65517, 65535
|
||||
};
|
||||
|
||||
/*
|
||||
* An array of pointers to CDFs of decorrelated LPC Gains
|
||||
*/
|
||||
const WebRtc_UWord16* WebRtcIsac_kLpcGainCdfMat[SUBFRAMES] =
|
||||
{
|
||||
WebRtcIsac_kLpcGainCdfVec0, WebRtcIsac_kLpcGainCdfVec1,
|
||||
WebRtcIsac_kLpcGainCdfVec2, WebRtcIsac_kLpcGainCdfVec3,
|
||||
WebRtcIsac_kLpcGainCdfVec4, WebRtcIsac_kLpcGainCdfVec5
|
||||
};
|
||||
|
||||
/*
|
||||
* A matrix to decorrellate LPC gains of subframes.
|
||||
*/
|
||||
const double WebRtcIsac_kLpcGainDecorrMat[SUBFRAMES][SUBFRAMES] =
|
||||
{
|
||||
{-0.150860, 0.327872, 0.367220, 0.504613, 0.559270, 0.409234},
|
||||
{ 0.457128, -0.613591, -0.289283, -0.029734, 0.393760, 0.418240},
|
||||
{-0.626043, 0.136489, -0.439118, -0.448323, 0.135987, 0.420869},
|
||||
{ 0.526617, 0.480187, 0.242552, -0.488754, -0.158713, 0.411331},
|
||||
{-0.302587, -0.494953, 0.588112, -0.063035, -0.404290, 0.387510},
|
||||
{ 0.086378, 0.147714, -0.428875, 0.548300, -0.570121, 0.401391}
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWB_KLT_Tables_LPCGain.h
|
||||
*
|
||||
* This file declares tables used for entropy coding of LPC Gain
|
||||
* of upper-band.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_
|
||||
|
||||
#include "settings.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
extern const double WebRtcIsac_kQSizeLpcGain;
|
||||
|
||||
extern const double WebRtcIsac_kLeftRecPointLpcGain[SUBFRAMES];
|
||||
|
||||
extern const WebRtc_Word16 WebRtcIsac_kNumQCellLpcGain[SUBFRAMES];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcGainEntropySearch[SUBFRAMES];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec0[18];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec1[21];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec2[26];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec3[46];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec4[78];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcGainCdfVec5[171];
|
||||
|
||||
extern const WebRtc_UWord16* WebRtcIsac_kLpcGainCdfMat[SUBFRAMES];
|
||||
|
||||
extern const double WebRtcIsac_kLpcGainDecorrMat[SUBFRAMES][SUBFRAMES];
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWB_KLT_Tables.c
|
||||
*
|
||||
* This file defines tables used for entropy coding of LPC shape of
|
||||
* upper-band signal if the bandwidth is 12 kHz.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lpc_shape_swb12_tables.h"
|
||||
#include "settings.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
/*
|
||||
* Mean value of LAR
|
||||
*/
|
||||
const double WebRtcIsac_kMeanLarUb12[UB_LPC_ORDER] =
|
||||
{
|
||||
0.03748928306641, 0.09453441192543, -0.01112522344398, 0.03800237516842
|
||||
};
|
||||
|
||||
/*
|
||||
* A rotation matrix to decorrelate intra-vector correlation,
|
||||
* i.e. correlation among components of LAR vector.
|
||||
*/
|
||||
const double WebRtcIsac_kIntraVecDecorrMatUb12[UB_LPC_ORDER][UB_LPC_ORDER] =
|
||||
{
|
||||
{-0.00075365493856, -0.05809964887743, -0.23397966154116, 0.97050367376411},
|
||||
{ 0.00625021257734, -0.17299965610679, 0.95977735920651, 0.22104179375008},
|
||||
{ 0.20543384258374, -0.96202143495696, -0.15301870801552, -0.09432375099565},
|
||||
{-0.97865075648479, -0.20300322280841, -0.02581111653779, -0.01913568980258}
|
||||
};
|
||||
|
||||
/*
|
||||
* A rotation matrix to remove correlation among LAR coefficients
|
||||
* of different LAR vectors. One might guess that decorrelation matrix
|
||||
* for the first component should differ from the second component
|
||||
* but we haven't observed a significant benefit of having different
|
||||
* decorrelation matrices for different components.
|
||||
*/
|
||||
const double WebRtcIsac_kInterVecDecorrMatUb12
|
||||
[UB_LPC_VEC_PER_FRAME][UB_LPC_VEC_PER_FRAME] =
|
||||
{
|
||||
{ 0.70650597970460, -0.70770707262373},
|
||||
{-0.70770707262373, -0.70650597970460}
|
||||
};
|
||||
|
||||
/*
|
||||
* LAR quantization step-size.
|
||||
*/
|
||||
const double WebRtcIsac_kLpcShapeQStepSizeUb12 = 0.150000;
|
||||
|
||||
/*
|
||||
* The smallest reconstruction points for quantiztion of LAR coefficients.
|
||||
*/
|
||||
const double WebRtcIsac_kLpcShapeLeftRecPointUb12
|
||||
[UB_LPC_ORDER*UB_LPC_VEC_PER_FRAME] =
|
||||
{
|
||||
-0.900000, -1.050000, -1.350000, -1.800000, -1.350000, -1.650000,
|
||||
-2.250000, -3.450000
|
||||
};
|
||||
|
||||
/*
|
||||
* Number of reconstruction points of quantizers for LAR coefficients.
|
||||
*/
|
||||
const WebRtc_Word16 WebRtcIsac_kLpcShapeNumRecPointUb12
|
||||
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME] =
|
||||
{
|
||||
13, 15, 19, 27, 19, 24, 32, 48
|
||||
};
|
||||
|
||||
/*
|
||||
* Starting index for entropy decoder to search for the right interval,
|
||||
* one entry per LAR coefficient
|
||||
*/
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeEntropySearchUb12
|
||||
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME] =
|
||||
{
|
||||
6, 7, 9, 13, 9, 12, 16, 24
|
||||
};
|
||||
|
||||
/*
|
||||
* The following 8 vectors define CDF of 8 decorrelated LAR
|
||||
* coefficients.
|
||||
*/
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec0Ub12[14] =
|
||||
{
|
||||
0, 13, 95, 418, 1687, 6498, 21317, 44200, 59029, 63849, 65147,
|
||||
65449, 65525, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec1Ub12[16] =
|
||||
{
|
||||
0, 10, 59, 255, 858, 2667, 8200, 22609, 42988, 57202, 62947,
|
||||
64743, 65308, 65476, 65522, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec2Ub12[20] =
|
||||
{
|
||||
0, 18, 40, 118, 332, 857, 2017, 4822, 11321, 24330, 41279,
|
||||
54342, 60637, 63394, 64659, 65184, 65398, 65482, 65518, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec3Ub12[28] =
|
||||
{
|
||||
0, 21, 38, 90, 196, 398, 770, 1400, 2589, 4650, 8211,
|
||||
14933, 26044, 39592, 50814, 57452, 60971, 62884, 63995, 64621, 65019, 65273,
|
||||
65410, 65480, 65514, 65522, 65531, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec4Ub12[20] =
|
||||
{
|
||||
0, 7, 46, 141, 403, 969, 2132, 4649, 10633, 24902, 43254,
|
||||
54665, 59928, 62674, 64173, 64938, 65293, 65464, 65523, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec5Ub12[25] =
|
||||
{
|
||||
0, 7, 22, 72, 174, 411, 854, 1737, 3545, 6774, 13165,
|
||||
25221, 40980, 52821, 58714, 61706, 63472, 64437, 64989, 65287, 65430, 65503,
|
||||
65525, 65529, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec6Ub12[33] =
|
||||
{
|
||||
0, 11, 21, 36, 65, 128, 228, 401, 707, 1241, 2126,
|
||||
3589, 6060, 10517, 18853, 31114, 42477, 49770, 54271, 57467, 59838, 61569,
|
||||
62831, 63772, 64433, 64833, 65123, 65306, 65419, 65466, 65499, 65519, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec7Ub12[49] =
|
||||
{
|
||||
0, 14, 34, 67, 107, 167, 245, 326, 449, 645, 861,
|
||||
1155, 1508, 2003, 2669, 3544, 4592, 5961, 7583, 9887, 13256, 18765,
|
||||
26519, 34077, 40034, 44349, 47795, 50663, 53262, 55473, 57458, 59122, 60592,
|
||||
61742, 62690, 63391, 63997, 64463, 64794, 65045, 65207, 65309, 65394, 65443,
|
||||
65478, 65504, 65514, 65523, 65535
|
||||
};
|
||||
|
||||
/*
|
||||
* An array of pointers to CDFs of decorrelated LARs
|
||||
*/
|
||||
const WebRtc_UWord16* WebRtcIsac_kLpcShapeCdfMatUb12
|
||||
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME] =
|
||||
{
|
||||
WebRtcIsac_kLpcShapeCdfVec0Ub12, WebRtcIsac_kLpcShapeCdfVec1Ub12,
|
||||
WebRtcIsac_kLpcShapeCdfVec2Ub12, WebRtcIsac_kLpcShapeCdfVec3Ub12,
|
||||
WebRtcIsac_kLpcShapeCdfVec4Ub12, WebRtcIsac_kLpcShapeCdfVec5Ub12,
|
||||
WebRtcIsac_kLpcShapeCdfVec6Ub12, WebRtcIsac_kLpcShapeCdfVec7Ub12
|
||||
};
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* lpc_shape_swb12_tables.h
|
||||
*
|
||||
* This file declares tables used for entropy coding of LPC shape of
|
||||
* upper-band signal if the bandwidth is 12 kHz.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_
|
||||
|
||||
#include "settings.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
extern const double WebRtcIsac_kMeanLarUb12[UB_LPC_ORDER];
|
||||
|
||||
extern const double WebRtcIsac_kMeanLpcGain;
|
||||
|
||||
extern const double WebRtcIsac_kIntraVecDecorrMatUb12[UB_LPC_ORDER][UB_LPC_ORDER];
|
||||
|
||||
extern const double WebRtcIsac_kInterVecDecorrMatUb12
|
||||
[UB_LPC_VEC_PER_FRAME][UB_LPC_VEC_PER_FRAME];
|
||||
|
||||
extern const double WebRtcIsac_kLpcShapeQStepSizeUb12;
|
||||
|
||||
extern const double WebRtcIsac_kLpcShapeLeftRecPointUb12
|
||||
[UB_LPC_ORDER*UB_LPC_VEC_PER_FRAME];
|
||||
|
||||
|
||||
extern const WebRtc_Word16 WebRtcIsac_kLpcShapeNumRecPointUb12
|
||||
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeEntropySearchUb12
|
||||
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec0Ub12[14];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec1Ub12[16];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec2Ub12[20];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec3Ub12[28];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec4Ub12[20];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec5Ub12[25];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec6Ub12[33];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec7Ub12[49];
|
||||
|
||||
extern const WebRtc_UWord16* WebRtcIsac_kLpcShapeCdfMatUb12
|
||||
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME];
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWB16_KLT_Tables.c
|
||||
*
|
||||
* This file defines tables used for entropy coding of LPC shape of
|
||||
* upper-band signal if the bandwidth is 16 kHz.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lpc_shape_swb16_tables.h"
|
||||
#include "settings.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
/*
|
||||
* Mean value of LAR
|
||||
*/
|
||||
const double WebRtcIsac_kMeanLarUb16[UB_LPC_ORDER] =
|
||||
{
|
||||
0.454978, 0.364747, 0.102999, 0.104523
|
||||
};
|
||||
|
||||
/*
|
||||
* A rotation matrix to decorrelate intra-vector correlation,
|
||||
* i.e. correlation among components of LAR vector.
|
||||
*/
|
||||
const double WebRtcIsac_kIintraVecDecorrMatUb16[UB_LPC_ORDER][UB_LPC_ORDER] =
|
||||
{
|
||||
{-0.020528, -0.085858, -0.002431, 0.996093},
|
||||
{-0.033155, 0.036102, 0.998786, 0.004866},
|
||||
{ 0.202627, 0.974853, -0.028940, 0.088132},
|
||||
{-0.978479, 0.202454, -0.039785, -0.002811}
|
||||
};
|
||||
|
||||
/*
|
||||
* A rotation matrix to remove correlation among LAR coefficients
|
||||
* of different LAR vectors. One might guess that decorrelation matrix
|
||||
* for the first component should differ from the second component
|
||||
* but we haven't observed a significant benefit of having different
|
||||
* decorrelation matrices for different components.
|
||||
*/
|
||||
const double WebRtcIsac_kInterVecDecorrMatUb16
|
||||
[UB16_LPC_VEC_PER_FRAME][UB16_LPC_VEC_PER_FRAME] =
|
||||
{
|
||||
{ 0.291675, -0.515786, 0.644927, 0.482658},
|
||||
{-0.647220, 0.479712, 0.289556, 0.516856},
|
||||
{ 0.643084, 0.485489, -0.289307, 0.516763},
|
||||
{-0.287185, -0.517823, -0.645389, 0.482553}
|
||||
};
|
||||
|
||||
/*
|
||||
* The following 16 vectors define CDF of 16 decorrelated LAR
|
||||
* coefficients.
|
||||
*/
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub16[14] =
|
||||
{
|
||||
0, 2, 20, 159, 1034, 5688, 20892, 44653,
|
||||
59849, 64485, 65383, 65518, 65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec1Ub16[16] =
|
||||
{
|
||||
0, 1, 7, 43, 276, 1496, 6681, 21653,
|
||||
43891, 58859, 64022, 65248, 65489, 65529, 65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec2Ub16[18] =
|
||||
{
|
||||
0, 1, 9, 54, 238, 933, 3192, 9461,
|
||||
23226, 42146, 56138, 62413, 64623, 65300, 65473, 65521,
|
||||
65533, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec3Ub16[30] =
|
||||
{
|
||||
0, 2, 4, 8, 17, 36, 75, 155,
|
||||
329, 683, 1376, 2662, 5047, 9508, 17526, 29027,
|
||||
40363, 48997, 55096, 59180, 61789, 63407, 64400, 64967,
|
||||
65273, 65429, 65497, 65526, 65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec4Ub16[16] =
|
||||
{
|
||||
0, 1, 10, 63, 361, 1785, 7407, 22242,
|
||||
43337, 58125, 63729, 65181, 65472, 65527, 65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec5Ub16[17] =
|
||||
{
|
||||
0, 1, 7, 29, 134, 599, 2443, 8590,
|
||||
22962, 42635, 56911, 63060, 64940, 65408, 65513, 65531,
|
||||
65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec6Ub16[21] =
|
||||
{
|
||||
0, 1, 5, 16, 57, 191, 611, 1808,
|
||||
4847, 11755, 24612, 40910, 53789, 60698, 63729, 64924,
|
||||
65346, 65486, 65523, 65532, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec7Ub16[36] =
|
||||
{
|
||||
0, 1, 4, 12, 25, 55, 104, 184,
|
||||
314, 539, 926, 1550, 2479, 3861, 5892, 8845,
|
||||
13281, 20018, 29019, 38029, 45581, 51557, 56057, 59284,
|
||||
61517, 63047, 64030, 64648, 65031, 65261, 65402, 65480,
|
||||
65518, 65530, 65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec8Ub16[21] =
|
||||
{
|
||||
0, 1, 2, 7, 26, 103, 351, 1149,
|
||||
3583, 10204, 23846, 41711, 55361, 61917, 64382, 65186,
|
||||
65433, 65506, 65528, 65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub160[21] =
|
||||
{
|
||||
0, 6, 19, 63, 205, 638, 1799, 4784,
|
||||
11721, 24494, 40803, 53805, 60886, 63822, 64931, 65333,
|
||||
65472, 65517, 65530, 65533, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub161[28] =
|
||||
{
|
||||
0, 1, 3, 11, 31, 86, 221, 506,
|
||||
1101, 2296, 4486, 8477, 15356, 26079, 38941, 49952,
|
||||
57165, 61257, 63426, 64549, 65097, 65351, 65463, 65510,
|
||||
65526, 65532, 65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub162[55] =
|
||||
{
|
||||
0, 3, 12, 23, 42, 65, 89, 115,
|
||||
150, 195, 248, 327, 430, 580, 784, 1099,
|
||||
1586, 2358, 3651, 5899, 9568, 14312, 19158, 23776,
|
||||
28267, 32663, 36991, 41153, 45098, 48680, 51870, 54729,
|
||||
57141, 59158, 60772, 62029, 63000, 63761, 64322, 64728,
|
||||
65000, 65192, 65321, 65411, 65463, 65496, 65514, 65523,
|
||||
65527, 65529, 65531, 65532, 65533, 65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub163[26] =
|
||||
{
|
||||
0, 2, 4, 10, 21, 48, 114, 280,
|
||||
701, 1765, 4555, 11270, 24267, 41213, 54285, 61003,
|
||||
63767, 64840, 65254, 65421, 65489, 65514, 65526, 65532,
|
||||
65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub164[28] =
|
||||
{
|
||||
0, 1, 3, 6, 15, 36, 82, 196,
|
||||
453, 1087, 2557, 5923, 13016, 25366, 40449, 52582,
|
||||
59539, 62896, 64389, 65033, 65316, 65442, 65494, 65519,
|
||||
65529, 65533, 65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub165[34] =
|
||||
{
|
||||
0, 2, 4, 8, 18, 35, 73, 146,
|
||||
279, 524, 980, 1789, 3235, 5784, 10040, 16998,
|
||||
27070, 38543, 48499, 55421, 59712, 62257, 63748, 64591,
|
||||
65041, 65278, 65410, 65474, 65508, 65522, 65530, 65533,
|
||||
65534, 65535
|
||||
};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub166[71] =
|
||||
{
|
||||
0, 1, 2, 6, 13, 26, 55, 92,
|
||||
141, 191, 242, 296, 355, 429, 522, 636,
|
||||
777, 947, 1162, 1428, 1753, 2137, 2605, 3140,
|
||||
3743, 4409, 5164, 6016, 6982, 8118, 9451, 10993,
|
||||
12754, 14810, 17130, 19780, 22864, 26424, 30547, 35222,
|
||||
40140, 44716, 48698, 52056, 54850, 57162, 59068, 60643,
|
||||
61877, 62827, 63561, 64113, 64519, 64807, 65019, 65167,
|
||||
65272, 65343, 65399, 65440, 65471, 65487, 65500, 65509,
|
||||
65518, 65524, 65527, 65531, 65533, 65534, 65535
|
||||
};
|
||||
|
||||
/*
|
||||
* An array of pointers to CDFs of decorrelated LARs
|
||||
*/
|
||||
const WebRtc_UWord16* WebRtcIsac_kLpcShapeCdfMatUb16
|
||||
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] = {
|
||||
WebRtcIsac_kLpcShapeCdfVec01Ub16,
|
||||
WebRtcIsac_kLpcShapeCdfVec1Ub16,
|
||||
WebRtcIsac_kLpcShapeCdfVec2Ub16,
|
||||
WebRtcIsac_kLpcShapeCdfVec3Ub16,
|
||||
WebRtcIsac_kLpcShapeCdfVec4Ub16,
|
||||
WebRtcIsac_kLpcShapeCdfVec5Ub16,
|
||||
WebRtcIsac_kLpcShapeCdfVec6Ub16,
|
||||
WebRtcIsac_kLpcShapeCdfVec7Ub16,
|
||||
WebRtcIsac_kLpcShapeCdfVec8Ub16,
|
||||
WebRtcIsac_kLpcShapeCdfVec01Ub160,
|
||||
WebRtcIsac_kLpcShapeCdfVec01Ub161,
|
||||
WebRtcIsac_kLpcShapeCdfVec01Ub162,
|
||||
WebRtcIsac_kLpcShapeCdfVec01Ub163,
|
||||
WebRtcIsac_kLpcShapeCdfVec01Ub164,
|
||||
WebRtcIsac_kLpcShapeCdfVec01Ub165,
|
||||
WebRtcIsac_kLpcShapeCdfVec01Ub166
|
||||
};
|
||||
|
||||
/*
|
||||
* The smallest reconstruction points for quantiztion of LAR coefficients.
|
||||
*/
|
||||
const double WebRtcIsac_kLpcShapeLeftRecPointUb16
|
||||
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] =
|
||||
{
|
||||
-0.8250, -0.9750, -1.1250, -2.1750, -0.9750, -1.1250, -1.4250,
|
||||
-2.6250, -1.4250, -1.2750, -1.8750, -3.6750, -1.7250, -1.8750,
|
||||
-2.3250, -5.4750
|
||||
};
|
||||
|
||||
/*
|
||||
* Number of reconstruction points of quantizers for LAR coefficients.
|
||||
*/
|
||||
const WebRtc_Word16 WebRtcIsac_kLpcShapeNumRecPointUb16
|
||||
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] =
|
||||
{
|
||||
13, 15, 17, 29, 15, 16, 20, 35, 20,
|
||||
20, 27, 54, 25, 27, 33, 70
|
||||
};
|
||||
|
||||
/*
|
||||
* Starting index for entropy decoder to search for the right interval,
|
||||
* one entry per LAR coefficient
|
||||
*/
|
||||
const WebRtc_UWord16 WebRtcIsac_kLpcShapeEntropySearchUb16
|
||||
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] =
|
||||
{
|
||||
6, 7, 8, 14, 7, 8, 10, 17, 10,
|
||||
10, 13, 27, 12, 13, 16, 35
|
||||
};
|
||||
|
||||
/*
|
||||
* LAR quantization step-size.
|
||||
*/
|
||||
const double WebRtcIsac_kLpcShapeQStepSizeUb16 = 0.150000;
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* lpc_shape_swb16_tables.h
|
||||
*
|
||||
* This file declares tables used for entropy coding of LPC shape of
|
||||
* upper-band signal if the bandwidth is 16 kHz.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_
|
||||
|
||||
#include "settings.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
|
||||
extern const double WebRtcIsac_kMeanLarUb16[UB_LPC_ORDER];
|
||||
|
||||
extern const double WebRtcIsac_kIintraVecDecorrMatUb16[UB_LPC_ORDER][UB_LPC_ORDER];
|
||||
|
||||
extern const double WebRtcIsac_kInterVecDecorrMatUb16
|
||||
[UB16_LPC_VEC_PER_FRAME][UB16_LPC_VEC_PER_FRAME];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub16[14];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec1Ub16[16];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec2Ub16[18];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec3Ub16[30];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec4Ub16[16];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec5Ub16[17];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec6Ub16[21];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec7Ub16[36];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec8Ub16[21];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub160[21];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub161[28];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub162[55];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub163[26];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub164[28];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub165[34];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeCdfVec01Ub166[71];
|
||||
|
||||
extern const WebRtc_UWord16* WebRtcIsac_kLpcShapeCdfMatUb16
|
||||
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
|
||||
|
||||
extern const double WebRtcIsac_kLpcShapeLeftRecPointUb16
|
||||
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
|
||||
|
||||
extern const WebRtc_Word16 WebRtcIsac_kLpcShapeNumRecPointUb16
|
||||
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kLpcShapeEntropySearchUb16
|
||||
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
|
||||
|
||||
extern const double WebRtcIsac_kLpcShapeQStepSizeUb16;
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* lpc_tables.h
|
||||
*
|
||||
* header file for coding tables for the LPC coefficients
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_TABLES_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
#define KLT_STEPSIZE 1.00000000
|
||||
#define KLT_NUM_AVG_GAIN 0
|
||||
#define KLT_NUM_AVG_SHAPE 0
|
||||
#define KLT_NUM_MODELS 3
|
||||
#define LPC_GAIN_SCALE 4.000f
|
||||
#define LPC_LOBAND_SCALE 2.100f
|
||||
#define LPC_LOBAND_ORDER ORDERLO
|
||||
#define LPC_HIBAND_SCALE 0.450f
|
||||
#define LPC_HIBAND_ORDER ORDERHI
|
||||
#define LPC_GAIN_ORDER 2
|
||||
|
||||
#define LPC_SHAPE_ORDER (LPC_LOBAND_ORDER + LPC_HIBAND_ORDER)
|
||||
|
||||
#define KLT_ORDER_GAIN (LPC_GAIN_ORDER * SUBFRAMES)
|
||||
#define KLT_ORDER_SHAPE (LPC_SHAPE_ORDER * SUBFRAMES)
|
||||
/* indices of KLT coefficients used */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltSelIndGain[12];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltSelIndShape[108];
|
||||
|
||||
/* cdf array for model indicator */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltModelCdf[KLT_NUM_MODELS+1];
|
||||
|
||||
/* pointer to cdf array for model indicator */
|
||||
extern const WebRtc_UWord16 *WebRtcIsac_kQKltModelCdfPtr[1];
|
||||
|
||||
/* initial cdf index for decoder of model indicator */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltModelInitIndex[1];
|
||||
|
||||
/* offset to go from rounded value to quantization index */
|
||||
extern const short WebRtcIsac_kQKltQuantMinGain[12];
|
||||
|
||||
extern const short WebRtcIsac_kQKltQuantMinShape[108];
|
||||
|
||||
/* maximum quantization index */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltMaxIndGain[12];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltMaxIndShape[108];
|
||||
|
||||
/* index offset */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltOffsetGain[KLT_NUM_MODELS][12];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltOffsetShape[KLT_NUM_MODELS][108];
|
||||
|
||||
/* initial cdf index for KLT coefficients */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltInitIndexGain[KLT_NUM_MODELS][12];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltInitIndexShape[KLT_NUM_MODELS][108];
|
||||
|
||||
/* offsets for quantizer representation levels */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltOfLevelsGain[3];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltOfLevelsShape[3];
|
||||
|
||||
/* quantizer representation levels */
|
||||
extern const double WebRtcIsac_kQKltLevelsGain[1176];
|
||||
|
||||
extern const double WebRtcIsac_kQKltLevelsShape[1735];
|
||||
|
||||
/* cdf tables for quantizer indices */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltCdfGain[1212];
|
||||
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQKltCdfShape[2059];
|
||||
|
||||
/* pointers to cdf tables for quantizer indices */
|
||||
extern const WebRtc_UWord16 *WebRtcIsac_kQKltCdfPtrGain[KLT_NUM_MODELS][12];
|
||||
|
||||
extern const WebRtc_UWord16 *WebRtcIsac_kQKltCdfPtrShape[KLT_NUM_MODELS][108];
|
||||
|
||||
/* code length for all coefficients using different models */
|
||||
extern const double WebRtcIsac_kQKltCodeLenGain[392];
|
||||
|
||||
extern const double WebRtcIsac_kQKltCodeLenShape[578];
|
||||
|
||||
/* left KLT transforms */
|
||||
extern const double WebRtcIsac_kKltT1Gain[KLT_NUM_MODELS][4];
|
||||
|
||||
extern const double WebRtcIsac_kKltT1Shape[KLT_NUM_MODELS][324];
|
||||
|
||||
/* right KLT transforms */
|
||||
extern const double WebRtcIsac_kKltT2Gain[KLT_NUM_MODELS][36];
|
||||
|
||||
extern const double WebRtcIsac_kKltT2Shape[KLT_NUM_MODELS][36];
|
||||
|
||||
/* means of log gains and LAR coefficients */
|
||||
extern const double WebRtcIsac_kLpcMeansGain[KLT_NUM_MODELS][12];
|
||||
|
||||
extern const double WebRtcIsac_kLpcMeansShape[KLT_NUM_MODELS][108];
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_TABLES_H_ */
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_OS_SPECIFIC_INLINE_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_OS_SPECIFIC_INLINE_H_
|
||||
|
||||
#include <math.h>
|
||||
#include "typedefs.h"
|
||||
|
||||
// TODO(turaj): switch to WEBRTC_POSIX when available
|
||||
#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
|
||||
#define WebRtcIsac_lrint lrint
|
||||
#elif (defined(WEBRTC_ARCH_X86) && defined(WIN32))
|
||||
static __inline long int WebRtcIsac_lrint(double x_dbl) {
|
||||
long int x_int;
|
||||
|
||||
__asm {
|
||||
fld x_dbl
|
||||
fistp x_int
|
||||
};
|
||||
|
||||
return x_int;
|
||||
}
|
||||
#else // Do a slow but correct implementation of lrint
|
||||
|
||||
static __inline long int WebRtcIsac_lrint(double x_dbl) {
|
||||
long int x_int;
|
||||
x_int = (long int)floor(x_dbl + 0.499999999999);
|
||||
return x_int;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_OS_SPECIFIC_INLINE_H_
|
|
@ -0,0 +1,622 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "pitch_estimator.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
#ifdef WEBRTC_ANDROID
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static const double kInterpolWin[8] = {-0.00067556028640, 0.02184247643159, -0.12203175715679, 0.60086484101160,
|
||||
0.60086484101160, -0.12203175715679, 0.02184247643159, -0.00067556028640};
|
||||
|
||||
/* interpolation filter */
|
||||
__inline static void IntrepolFilter(double *data_ptr, double *intrp)
|
||||
{
|
||||
*intrp = kInterpolWin[0] * data_ptr[-3];
|
||||
*intrp += kInterpolWin[1] * data_ptr[-2];
|
||||
*intrp += kInterpolWin[2] * data_ptr[-1];
|
||||
*intrp += kInterpolWin[3] * data_ptr[0];
|
||||
*intrp += kInterpolWin[4] * data_ptr[1];
|
||||
*intrp += kInterpolWin[5] * data_ptr[2];
|
||||
*intrp += kInterpolWin[6] * data_ptr[3];
|
||||
*intrp += kInterpolWin[7] * data_ptr[4];
|
||||
}
|
||||
|
||||
|
||||
/* 2D parabolic interpolation */
|
||||
/* probably some 0.5 factors can be eliminated, and the square-roots can be removed from the Cholesky fact. */
|
||||
__inline static void Intrpol2D(double T[3][3], double *x, double *y, double *peak_val)
|
||||
{
|
||||
double c, b[2], A[2][2];
|
||||
double t1, t2, d;
|
||||
double delta1, delta2;
|
||||
|
||||
|
||||
// double T[3][3] = {{-1.25, -.25,-.25}, {-.25, .75, .75}, {-.25, .75, .75}};
|
||||
// should result in: delta1 = 0.5; delta2 = 0.0; peak_val = 1.0
|
||||
|
||||
c = T[1][1];
|
||||
b[0] = 0.5 * (T[1][2] + T[2][1] - T[0][1] - T[1][0]);
|
||||
b[1] = 0.5 * (T[1][0] + T[2][1] - T[0][1] - T[1][2]);
|
||||
A[0][1] = -0.5 * (T[0][1] + T[2][1] - T[1][0] - T[1][2]);
|
||||
t1 = 0.5 * (T[0][0] + T[2][2]) - c;
|
||||
t2 = 0.5 * (T[2][0] + T[0][2]) - c;
|
||||
d = (T[0][1] + T[1][2] + T[1][0] + T[2][1]) - 4.0 * c - t1 - t2;
|
||||
A[0][0] = -t1 - 0.5 * d;
|
||||
A[1][1] = -t2 - 0.5 * d;
|
||||
|
||||
/* deal with singularities or ill-conditioned cases */
|
||||
if ( (A[0][0] < 1e-7) || ((A[0][0] * A[1][1] - A[0][1] * A[0][1]) < 1e-7) ) {
|
||||
*peak_val = T[1][1];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Cholesky decomposition: replace A by upper-triangular factor */
|
||||
A[0][0] = sqrt(A[0][0]);
|
||||
A[0][1] = A[0][1] / A[0][0];
|
||||
A[1][1] = sqrt(A[1][1] - A[0][1] * A[0][1]);
|
||||
|
||||
/* compute [x; y] = -0.5 * inv(A) * b */
|
||||
t1 = b[0] / A[0][0];
|
||||
t2 = (b[1] - t1 * A[0][1]) / A[1][1];
|
||||
delta2 = t2 / A[1][1];
|
||||
delta1 = 0.5 * (t1 - delta2 * A[0][1]) / A[0][0];
|
||||
delta2 *= 0.5;
|
||||
|
||||
/* limit norm */
|
||||
t1 = delta1 * delta1 + delta2 * delta2;
|
||||
if (t1 > 1.0) {
|
||||
delta1 /= t1;
|
||||
delta2 /= t1;
|
||||
}
|
||||
|
||||
*peak_val = 0.5 * (b[0] * delta1 + b[1] * delta2) + c;
|
||||
|
||||
*x += delta1;
|
||||
*y += delta2;
|
||||
}
|
||||
|
||||
|
||||
static void PCorr(const double *in, double *outcorr)
|
||||
{
|
||||
double sum, ysum, prod;
|
||||
const double *x, *inptr;
|
||||
int k, n;
|
||||
|
||||
//ysum = 1e-6; /* use this with float (i.s.o. double)! */
|
||||
ysum = 1e-13;
|
||||
sum = 0.0;
|
||||
x = in + PITCH_MAX_LAG/2 + 2;
|
||||
for (n = 0; n < PITCH_CORR_LEN2; n++) {
|
||||
ysum += in[n] * in[n];
|
||||
sum += x[n] * in[n];
|
||||
}
|
||||
|
||||
outcorr += PITCH_LAG_SPAN2 - 1; /* index of last element in array */
|
||||
*outcorr = sum / sqrt(ysum);
|
||||
|
||||
for (k = 1; k < PITCH_LAG_SPAN2; k++) {
|
||||
ysum -= in[k-1] * in[k-1];
|
||||
ysum += in[PITCH_CORR_LEN2 + k - 1] * in[PITCH_CORR_LEN2 + k - 1];
|
||||
sum = 0.0;
|
||||
inptr = &in[k];
|
||||
prod = x[0] * inptr[0];
|
||||
for (n = 1; n < PITCH_CORR_LEN2; n++) {
|
||||
sum += prod;
|
||||
prod = x[n] * inptr[n];
|
||||
}
|
||||
sum += prod;
|
||||
outcorr--;
|
||||
*outcorr = sum / sqrt(ysum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_InitializePitch(const double *in,
|
||||
const double old_lag,
|
||||
const double old_gain,
|
||||
PitchAnalysisStruct *State,
|
||||
double *lags)
|
||||
{
|
||||
double buf_dec[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2+2];
|
||||
double ratio, log_lag, gain_bias;
|
||||
double bias;
|
||||
double corrvec1[PITCH_LAG_SPAN2];
|
||||
double corrvec2[PITCH_LAG_SPAN2];
|
||||
int m, k;
|
||||
// Allocating 10 extra entries at the begining of the CorrSurf
|
||||
double corrSurfBuff[10 + (2*PITCH_BW+3)*(PITCH_LAG_SPAN2+4)];
|
||||
double* CorrSurf[2*PITCH_BW+3];
|
||||
double *CorrSurfPtr1, *CorrSurfPtr2;
|
||||
double LagWin[3] = {0.2, 0.5, 0.98};
|
||||
int ind1, ind2, peaks_ind, peak, max_ind;
|
||||
int peaks[PITCH_MAX_NUM_PEAKS];
|
||||
double adj, gain_tmp;
|
||||
double corr, corr_max;
|
||||
double intrp_a, intrp_b, intrp_c, intrp_d;
|
||||
double peak_vals[PITCH_MAX_NUM_PEAKS];
|
||||
double lags1[PITCH_MAX_NUM_PEAKS];
|
||||
double lags2[PITCH_MAX_NUM_PEAKS];
|
||||
double T[3][3];
|
||||
int row;
|
||||
|
||||
for(k = 0; k < 2*PITCH_BW+3; k++)
|
||||
{
|
||||
CorrSurf[k] = &corrSurfBuff[10 + k * (PITCH_LAG_SPAN2+4)];
|
||||
}
|
||||
/* reset CorrSurf matrix */
|
||||
memset(corrSurfBuff, 0, sizeof(double) * (10 + (2*PITCH_BW+3) * (PITCH_LAG_SPAN2+4)));
|
||||
|
||||
//warnings -DH
|
||||
max_ind = 0;
|
||||
peak = 0;
|
||||
|
||||
/* copy old values from state buffer */
|
||||
memcpy(buf_dec, State->dec_buffer, sizeof(double) * (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2));
|
||||
|
||||
/* decimation; put result after the old values */
|
||||
WebRtcIsac_DecimateAllpass(in, State->decimator_state, PITCH_FRAME_LEN,
|
||||
&buf_dec[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2]);
|
||||
|
||||
/* low-pass filtering */
|
||||
for (k = PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; k < PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2+2; k++)
|
||||
buf_dec[k] += 0.75 * buf_dec[k-1] - 0.25 * buf_dec[k-2];
|
||||
|
||||
/* copy end part back into state buffer */
|
||||
memcpy(State->dec_buffer, buf_dec+PITCH_FRAME_LEN/2, sizeof(double) * (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2));
|
||||
|
||||
/* compute correlation for first and second half of the frame */
|
||||
PCorr(buf_dec, corrvec1);
|
||||
PCorr(buf_dec + PITCH_CORR_STEP2, corrvec2);
|
||||
|
||||
/* bias towards pitch lag of previous frame */
|
||||
log_lag = log(0.5 * old_lag);
|
||||
gain_bias = 4.0 * old_gain * old_gain;
|
||||
if (gain_bias > 0.8) gain_bias = 0.8;
|
||||
for (k = 0; k < PITCH_LAG_SPAN2; k++)
|
||||
{
|
||||
ratio = log((double) (k + (PITCH_MIN_LAG/2-2))) - log_lag;
|
||||
bias = 1.0 + gain_bias * exp(-5.0 * ratio * ratio);
|
||||
corrvec1[k] *= bias;
|
||||
}
|
||||
|
||||
/* taper correlation functions */
|
||||
for (k = 0; k < 3; k++) {
|
||||
gain_tmp = LagWin[k];
|
||||
corrvec1[k] *= gain_tmp;
|
||||
corrvec2[k] *= gain_tmp;
|
||||
corrvec1[PITCH_LAG_SPAN2-1-k] *= gain_tmp;
|
||||
corrvec2[PITCH_LAG_SPAN2-1-k] *= gain_tmp;
|
||||
}
|
||||
|
||||
corr_max = 0.0;
|
||||
/* fill middle row of correlation surface */
|
||||
ind1 = 0;
|
||||
ind2 = 0;
|
||||
CorrSurfPtr1 = &CorrSurf[PITCH_BW][2];
|
||||
for (k = 0; k < PITCH_LAG_SPAN2; k++) {
|
||||
corr = corrvec1[ind1++] + corrvec2[ind2++];
|
||||
CorrSurfPtr1[k] = corr;
|
||||
if (corr > corr_max) {
|
||||
corr_max = corr; /* update maximum */
|
||||
max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
|
||||
}
|
||||
}
|
||||
/* fill first and last rows of correlation surface */
|
||||
ind1 = 0;
|
||||
ind2 = PITCH_BW;
|
||||
CorrSurfPtr1 = &CorrSurf[0][2];
|
||||
CorrSurfPtr2 = &CorrSurf[2*PITCH_BW][PITCH_BW+2];
|
||||
for (k = 0; k < PITCH_LAG_SPAN2-PITCH_BW; k++) {
|
||||
ratio = ((double) (ind1 + 12)) / ((double) (ind2 + 12));
|
||||
adj = 0.2 * ratio * (2.0 - ratio); /* adjustment factor; inverse parabola as a function of ratio */
|
||||
corr = adj * (corrvec1[ind1] + corrvec2[ind2]);
|
||||
CorrSurfPtr1[k] = corr;
|
||||
if (corr > corr_max) {
|
||||
corr_max = corr; /* update maximum */
|
||||
max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
|
||||
}
|
||||
corr = adj * (corrvec1[ind2++] + corrvec2[ind1++]);
|
||||
CorrSurfPtr2[k] = corr;
|
||||
if (corr > corr_max) {
|
||||
corr_max = corr; /* update maximum */
|
||||
max_ind = (int)(&CorrSurfPtr2[k] - &CorrSurf[0][0]);
|
||||
}
|
||||
}
|
||||
/* fill second and next to last rows of correlation surface */
|
||||
ind1 = 0;
|
||||
ind2 = PITCH_BW-1;
|
||||
CorrSurfPtr1 = &CorrSurf[1][2];
|
||||
CorrSurfPtr2 = &CorrSurf[2*PITCH_BW-1][PITCH_BW+1];
|
||||
for (k = 0; k < PITCH_LAG_SPAN2-PITCH_BW+1; k++) {
|
||||
ratio = ((double) (ind1 + 12)) / ((double) (ind2 + 12));
|
||||
adj = 0.9 * ratio * (2.0 - ratio); /* adjustment factor; inverse parabola as a function of ratio */
|
||||
corr = adj * (corrvec1[ind1] + corrvec2[ind2]);
|
||||
CorrSurfPtr1[k] = corr;
|
||||
if (corr > corr_max) {
|
||||
corr_max = corr; /* update maximum */
|
||||
max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
|
||||
}
|
||||
corr = adj * (corrvec1[ind2++] + corrvec2[ind1++]);
|
||||
CorrSurfPtr2[k] = corr;
|
||||
if (corr > corr_max) {
|
||||
corr_max = corr; /* update maximum */
|
||||
max_ind = (int)(&CorrSurfPtr2[k] - &CorrSurf[0][0]);
|
||||
}
|
||||
}
|
||||
/* fill remainder of correlation surface */
|
||||
for (m = 2; m < PITCH_BW; m++) {
|
||||
ind1 = 0;
|
||||
ind2 = PITCH_BW - m; /* always larger than ind1 */
|
||||
CorrSurfPtr1 = &CorrSurf[m][2];
|
||||
CorrSurfPtr2 = &CorrSurf[2*PITCH_BW-m][PITCH_BW+2-m];
|
||||
for (k = 0; k < PITCH_LAG_SPAN2-PITCH_BW+m; k++) {
|
||||
ratio = ((double) (ind1 + 12)) / ((double) (ind2 + 12));
|
||||
adj = ratio * (2.0 - ratio); /* adjustment factor; inverse parabola as a function of ratio */
|
||||
corr = adj * (corrvec1[ind1] + corrvec2[ind2]);
|
||||
CorrSurfPtr1[k] = corr;
|
||||
if (corr > corr_max) {
|
||||
corr_max = corr; /* update maximum */
|
||||
max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
|
||||
}
|
||||
corr = adj * (corrvec1[ind2++] + corrvec2[ind1++]);
|
||||
CorrSurfPtr2[k] = corr;
|
||||
if (corr > corr_max) {
|
||||
corr_max = corr; /* update maximum */
|
||||
max_ind = (int)(&CorrSurfPtr2[k] - &CorrSurf[0][0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* threshold value to qualify as a peak */
|
||||
corr_max *= 0.6;
|
||||
|
||||
peaks_ind = 0;
|
||||
/* find peaks */
|
||||
for (m = 1; m < PITCH_BW+1; m++) {
|
||||
if (peaks_ind == PITCH_MAX_NUM_PEAKS) break;
|
||||
CorrSurfPtr1 = &CorrSurf[m][2];
|
||||
for (k = 2; k < PITCH_LAG_SPAN2-PITCH_BW-2+m; k++) {
|
||||
corr = CorrSurfPtr1[k];
|
||||
if (corr > corr_max) {
|
||||
if ( (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+5)]) && (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+4)]) ) {
|
||||
if ( (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+4)]) && (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+5)]) ) {
|
||||
/* found a peak; store index into matrix */
|
||||
peaks[peaks_ind++] = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
|
||||
if (peaks_ind == PITCH_MAX_NUM_PEAKS) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (m = PITCH_BW+1; m < 2*PITCH_BW; m++) {
|
||||
if (peaks_ind == PITCH_MAX_NUM_PEAKS) break;
|
||||
CorrSurfPtr1 = &CorrSurf[m][2];
|
||||
for (k = 2+m-PITCH_BW; k < PITCH_LAG_SPAN2-2; k++) {
|
||||
corr = CorrSurfPtr1[k];
|
||||
if (corr > corr_max) {
|
||||
if ( (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+5)]) && (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+4)]) ) {
|
||||
if ( (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+4)]) && (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+5)]) ) {
|
||||
/* found a peak; store index into matrix */
|
||||
peaks[peaks_ind++] = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
|
||||
if (peaks_ind == PITCH_MAX_NUM_PEAKS) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (peaks_ind > 0) {
|
||||
/* examine each peak */
|
||||
CorrSurfPtr1 = &CorrSurf[0][0];
|
||||
for (k = 0; k < peaks_ind; k++) {
|
||||
peak = peaks[k];
|
||||
|
||||
/* compute four interpolated values around current peak */
|
||||
IntrepolFilter(&CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)], &intrp_a);
|
||||
IntrepolFilter(&CorrSurfPtr1[peak - 1 ], &intrp_b);
|
||||
IntrepolFilter(&CorrSurfPtr1[peak ], &intrp_c);
|
||||
IntrepolFilter(&CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)], &intrp_d);
|
||||
|
||||
/* determine maximum of the interpolated values */
|
||||
corr = CorrSurfPtr1[peak];
|
||||
corr_max = intrp_a;
|
||||
if (intrp_b > corr_max) corr_max = intrp_b;
|
||||
if (intrp_c > corr_max) corr_max = intrp_c;
|
||||
if (intrp_d > corr_max) corr_max = intrp_d;
|
||||
|
||||
/* determine where the peak sits and fill a 3x3 matrix around it */
|
||||
row = peak / (PITCH_LAG_SPAN2+4);
|
||||
lags1[k] = (double) ((peak - row * (PITCH_LAG_SPAN2+4)) + PITCH_MIN_LAG/2 - 4);
|
||||
lags2[k] = (double) (lags1[k] + PITCH_BW - row);
|
||||
if ( corr > corr_max ) {
|
||||
T[0][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)];
|
||||
T[2][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)];
|
||||
T[1][1] = corr;
|
||||
T[0][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)];
|
||||
T[2][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)];
|
||||
T[1][0] = intrp_a;
|
||||
T[0][1] = intrp_b;
|
||||
T[2][1] = intrp_c;
|
||||
T[1][2] = intrp_d;
|
||||
} else {
|
||||
if (intrp_a == corr_max) {
|
||||
lags1[k] -= 0.5;
|
||||
lags2[k] += 0.5;
|
||||
IntrepolFilter(&CorrSurfPtr1[peak - 2*(PITCH_LAG_SPAN2+5)], &T[0][0]);
|
||||
IntrepolFilter(&CorrSurfPtr1[peak - (2*PITCH_LAG_SPAN2+9)], &T[2][0]);
|
||||
T[1][1] = intrp_a;
|
||||
T[0][2] = intrp_b;
|
||||
T[2][2] = intrp_c;
|
||||
T[1][0] = CorrSurfPtr1[peak - (2*PITCH_LAG_SPAN2+9)];
|
||||
T[0][1] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)];
|
||||
T[2][1] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)];
|
||||
T[1][2] = corr;
|
||||
} else if (intrp_b == corr_max) {
|
||||
lags1[k] -= 0.5;
|
||||
lags2[k] -= 0.5;
|
||||
IntrepolFilter(&CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+6)], &T[0][0]);
|
||||
T[2][0] = intrp_a;
|
||||
T[1][1] = intrp_b;
|
||||
IntrepolFilter(&CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+3)], &T[0][2]);
|
||||
T[2][2] = intrp_d;
|
||||
T[1][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)];
|
||||
T[0][1] = CorrSurfPtr1[peak - 1];
|
||||
T[2][1] = corr;
|
||||
T[1][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)];
|
||||
} else if (intrp_c == corr_max) {
|
||||
lags1[k] += 0.5;
|
||||
lags2[k] += 0.5;
|
||||
T[0][0] = intrp_a;
|
||||
IntrepolFilter(&CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)], &T[2][0]);
|
||||
T[1][1] = intrp_c;
|
||||
T[0][2] = intrp_d;
|
||||
IntrepolFilter(&CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)], &T[2][2]);
|
||||
T[1][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)];
|
||||
T[0][1] = corr;
|
||||
T[2][1] = CorrSurfPtr1[peak + 1];
|
||||
T[1][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)];
|
||||
} else {
|
||||
lags1[k] += 0.5;
|
||||
lags2[k] -= 0.5;
|
||||
T[0][0] = intrp_b;
|
||||
T[2][0] = intrp_c;
|
||||
T[1][1] = intrp_d;
|
||||
IntrepolFilter(&CorrSurfPtr1[peak + 2*(PITCH_LAG_SPAN2+4)], &T[0][2]);
|
||||
IntrepolFilter(&CorrSurfPtr1[peak + (2*PITCH_LAG_SPAN2+9)], &T[2][2]);
|
||||
T[1][0] = corr;
|
||||
T[0][1] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)];
|
||||
T[2][1] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)];
|
||||
T[1][2] = CorrSurfPtr1[peak + (2*PITCH_LAG_SPAN2+9)];
|
||||
}
|
||||
}
|
||||
|
||||
/* 2D parabolic interpolation gives more accurate lags and peak value */
|
||||
Intrpol2D(T, &lags1[k], &lags2[k], &peak_vals[k]);
|
||||
}
|
||||
|
||||
/* determine the highest peak, after applying a bias towards short lags */
|
||||
corr_max = 0.0;
|
||||
for (k = 0; k < peaks_ind; k++) {
|
||||
corr = peak_vals[k] * pow(PITCH_PEAK_DECAY, log(lags1[k] + lags2[k]));
|
||||
if (corr > corr_max) {
|
||||
corr_max = corr;
|
||||
peak = k;
|
||||
}
|
||||
}
|
||||
|
||||
lags1[peak] *= 2.0;
|
||||
lags2[peak] *= 2.0;
|
||||
|
||||
if (lags1[peak] < (double) PITCH_MIN_LAG) lags1[peak] = (double) PITCH_MIN_LAG;
|
||||
if (lags2[peak] < (double) PITCH_MIN_LAG) lags2[peak] = (double) PITCH_MIN_LAG;
|
||||
if (lags1[peak] > (double) PITCH_MAX_LAG) lags1[peak] = (double) PITCH_MAX_LAG;
|
||||
if (lags2[peak] > (double) PITCH_MAX_LAG) lags2[peak] = (double) PITCH_MAX_LAG;
|
||||
|
||||
/* store lags of highest peak in output array */
|
||||
lags[0] = lags1[peak];
|
||||
lags[1] = lags1[peak];
|
||||
lags[2] = lags2[peak];
|
||||
lags[3] = lags2[peak];
|
||||
}
|
||||
else
|
||||
{
|
||||
row = max_ind / (PITCH_LAG_SPAN2+4);
|
||||
lags1[0] = (double) ((max_ind - row * (PITCH_LAG_SPAN2+4)) + PITCH_MIN_LAG/2 - 4);
|
||||
lags2[0] = (double) (lags1[0] + PITCH_BW - row);
|
||||
|
||||
if (lags1[0] < (double) PITCH_MIN_LAG) lags1[0] = (double) PITCH_MIN_LAG;
|
||||
if (lags2[0] < (double) PITCH_MIN_LAG) lags2[0] = (double) PITCH_MIN_LAG;
|
||||
if (lags1[0] > (double) PITCH_MAX_LAG) lags1[0] = (double) PITCH_MAX_LAG;
|
||||
if (lags2[0] > (double) PITCH_MAX_LAG) lags2[0] = (double) PITCH_MAX_LAG;
|
||||
|
||||
/* store lags of highest peak in output array */
|
||||
lags[0] = lags1[0];
|
||||
lags[1] = lags1[0];
|
||||
lags[2] = lags2[0];
|
||||
lags[3] = lags2[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* create weighting matrix by orthogonalizing a basis of polynomials of increasing order
|
||||
* t = (0:4)';
|
||||
* A = [t.^0, t.^1, t.^2, t.^3, t.^4];
|
||||
* [Q, dummy] = qr(A);
|
||||
* P.Weight = Q * diag([0, .1, .5, 1, 1]) * Q'; */
|
||||
static const double kWeight[5][5] = {
|
||||
{ 0.29714285714286, -0.30857142857143, -0.05714285714286, 0.05142857142857, 0.01714285714286},
|
||||
{-0.30857142857143, 0.67428571428571, -0.27142857142857, -0.14571428571429, 0.05142857142857},
|
||||
{-0.05714285714286, -0.27142857142857, 0.65714285714286, -0.27142857142857, -0.05714285714286},
|
||||
{ 0.05142857142857, -0.14571428571429, -0.27142857142857, 0.67428571428571, -0.30857142857143},
|
||||
{ 0.01714285714286, 0.05142857142857, -0.05714285714286, -0.30857142857143, 0.29714285714286}
|
||||
};
|
||||
|
||||
|
||||
void WebRtcIsac_PitchAnalysis(const double *in, /* PITCH_FRAME_LEN samples */
|
||||
double *out, /* PITCH_FRAME_LEN+QLOOKAHEAD samples */
|
||||
PitchAnalysisStruct *State,
|
||||
double *lags,
|
||||
double *gains)
|
||||
{
|
||||
double HPin[PITCH_FRAME_LEN];
|
||||
double Weighted[PITCH_FRAME_LEN];
|
||||
double Whitened[PITCH_FRAME_LEN + QLOOKAHEAD];
|
||||
double inbuf[PITCH_FRAME_LEN + QLOOKAHEAD];
|
||||
double out_G[PITCH_FRAME_LEN + QLOOKAHEAD]; // could be removed by using out instead
|
||||
double out_dG[4][PITCH_FRAME_LEN + QLOOKAHEAD];
|
||||
double old_lag, old_gain;
|
||||
double nrg_wht, tmp;
|
||||
double Wnrg, Wfluct, Wgain;
|
||||
double H[4][4];
|
||||
double grad[4];
|
||||
double dG[4];
|
||||
int k, m, n, iter;
|
||||
|
||||
/* high pass filtering using second order pole-zero filter */
|
||||
WebRtcIsac_Highpass(in, HPin, State->hp_state, PITCH_FRAME_LEN);
|
||||
|
||||
/* copy from state into buffer */
|
||||
memcpy(Whitened, State->whitened_buf, sizeof(double) * QLOOKAHEAD);
|
||||
|
||||
/* compute weighted and whitened signals */
|
||||
WebRtcIsac_WeightingFilter(HPin, &Weighted[0], &Whitened[QLOOKAHEAD], &(State->Wghtstr));
|
||||
|
||||
/* copy from buffer into state */
|
||||
memcpy(State->whitened_buf, Whitened+PITCH_FRAME_LEN, sizeof(double) * QLOOKAHEAD);
|
||||
|
||||
old_lag = State->PFstr_wght.oldlagp[0];
|
||||
old_gain = State->PFstr_wght.oldgainp[0];
|
||||
|
||||
/* inital pitch estimate */
|
||||
WebRtcIsac_InitializePitch(Weighted, old_lag, old_gain, State, lags);
|
||||
|
||||
|
||||
/* Iterative optimization of lags - to be done */
|
||||
|
||||
/* compute energy of whitened signal */
|
||||
nrg_wht = 0.0;
|
||||
for (k = 0; k < PITCH_FRAME_LEN + QLOOKAHEAD; k++)
|
||||
nrg_wht += Whitened[k] * Whitened[k];
|
||||
|
||||
|
||||
/* Iterative optimization of gains */
|
||||
|
||||
/* set weights for energy, gain fluctiation, and spectral gain penalty functions */
|
||||
Wnrg = 1.0 / nrg_wht;
|
||||
Wgain = 0.005;
|
||||
Wfluct = 3.0;
|
||||
|
||||
/* set initial gains */
|
||||
for (k = 0; k < 4; k++)
|
||||
gains[k] = PITCH_MAX_GAIN_06;
|
||||
|
||||
/* two iterations should be enough */
|
||||
for (iter = 0; iter < 2; iter++) {
|
||||
/* compute Jacobian of pre-filter output towards gains */
|
||||
WebRtcIsac_PitchfilterPre_gains(Whitened, out_G, out_dG, &(State->PFstr_wght), lags, gains);
|
||||
|
||||
/* gradient and approximate Hessian (lower triangle) for minimizing the filter's output power */
|
||||
for (k = 0; k < 4; k++) {
|
||||
tmp = 0.0;
|
||||
for (n = 0; n < PITCH_FRAME_LEN + QLOOKAHEAD; n++)
|
||||
tmp += out_G[n] * out_dG[k][n];
|
||||
grad[k] = tmp * Wnrg;
|
||||
}
|
||||
for (k = 0; k < 4; k++) {
|
||||
for (m = 0; m <= k; m++) {
|
||||
tmp = 0.0;
|
||||
for (n = 0; n < PITCH_FRAME_LEN + QLOOKAHEAD; n++)
|
||||
tmp += out_dG[m][n] * out_dG[k][n];
|
||||
H[k][m] = tmp * Wnrg;
|
||||
}
|
||||
}
|
||||
|
||||
/* add gradient and Hessian (lower triangle) for dampening fast gain changes */
|
||||
for (k = 0; k < 4; k++) {
|
||||
tmp = kWeight[k+1][0] * old_gain;
|
||||
for (m = 0; m < 4; m++)
|
||||
tmp += kWeight[k+1][m+1] * gains[m];
|
||||
grad[k] += tmp * Wfluct;
|
||||
}
|
||||
for (k = 0; k < 4; k++) {
|
||||
for (m = 0; m <= k; m++) {
|
||||
H[k][m] += kWeight[k+1][m+1] * Wfluct;
|
||||
}
|
||||
}
|
||||
|
||||
/* add gradient and Hessian for dampening gain */
|
||||
for (k = 0; k < 3; k++) {
|
||||
tmp = 1.0 / (1 - gains[k]);
|
||||
grad[k] += tmp * tmp * Wgain;
|
||||
H[k][k] += 2.0 * tmp * (tmp * tmp * Wgain);
|
||||
}
|
||||
tmp = 1.0 / (1 - gains[3]);
|
||||
grad[3] += 1.33 * (tmp * tmp * Wgain);
|
||||
H[3][3] += 2.66 * tmp * (tmp * tmp * Wgain);
|
||||
|
||||
|
||||
/* compute Cholesky factorization of Hessian
|
||||
* by overwritting the upper triangle; scale factors on diagonal
|
||||
* (for non pc-platforms store the inverse of the diagonals seperately to minimize divisions) */
|
||||
H[0][1] = H[1][0] / H[0][0];
|
||||
H[0][2] = H[2][0] / H[0][0];
|
||||
H[0][3] = H[3][0] / H[0][0];
|
||||
H[1][1] -= H[0][0] * H[0][1] * H[0][1];
|
||||
H[1][2] = (H[2][1] - H[0][1] * H[2][0]) / H[1][1];
|
||||
H[1][3] = (H[3][1] - H[0][1] * H[3][0]) / H[1][1];
|
||||
H[2][2] -= H[0][0] * H[0][2] * H[0][2] + H[1][1] * H[1][2] * H[1][2];
|
||||
H[2][3] = (H[3][2] - H[0][2] * H[3][0] - H[1][2] * H[1][1] * H[1][3]) / H[2][2];
|
||||
H[3][3] -= H[0][0] * H[0][3] * H[0][3] + H[1][1] * H[1][3] * H[1][3] + H[2][2] * H[2][3] * H[2][3];
|
||||
|
||||
/* Compute update as delta_gains = -inv(H) * grad */
|
||||
/* copy and negate */
|
||||
for (k = 0; k < 4; k++)
|
||||
dG[k] = -grad[k];
|
||||
/* back substitution */
|
||||
dG[1] -= dG[0] * H[0][1];
|
||||
dG[2] -= dG[0] * H[0][2] + dG[1] * H[1][2];
|
||||
dG[3] -= dG[0] * H[0][3] + dG[1] * H[1][3] + dG[2] * H[2][3];
|
||||
/* scale */
|
||||
for (k = 0; k < 4; k++)
|
||||
dG[k] /= H[k][k];
|
||||
/* back substitution */
|
||||
dG[2] -= dG[3] * H[2][3];
|
||||
dG[1] -= dG[3] * H[1][3] + dG[2] * H[1][2];
|
||||
dG[0] -= dG[3] * H[0][3] + dG[2] * H[0][2] + dG[1] * H[0][1];
|
||||
|
||||
/* update gains and check range */
|
||||
for (k = 0; k < 4; k++) {
|
||||
gains[k] += dG[k];
|
||||
if (gains[k] > PITCH_MAX_GAIN)
|
||||
gains[k] = PITCH_MAX_GAIN;
|
||||
else if (gains[k] < 0.0)
|
||||
gains[k] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* update state for next frame */
|
||||
WebRtcIsac_PitchfilterPre(Whitened, out, &(State->PFstr_wght), lags, gains);
|
||||
|
||||
/* concatenate previous input's end and current input */
|
||||
memcpy(inbuf, State->inbuf, sizeof(double) * QLOOKAHEAD);
|
||||
memcpy(inbuf+QLOOKAHEAD, in, sizeof(double) * PITCH_FRAME_LEN);
|
||||
|
||||
/* lookahead pitch filtering for masking analysis */
|
||||
WebRtcIsac_PitchfilterPre_la(inbuf, out, &(State->PFstr), lags, gains);
|
||||
|
||||
/* store last part of input */
|
||||
for (k = 0; k < QLOOKAHEAD; k++)
|
||||
State->inbuf[k] = inbuf[k + PITCH_FRAME_LEN];
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_estimator.h
|
||||
*
|
||||
* Pitch functions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_ESTIMATOR_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_ESTIMATOR_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
|
||||
void WebRtcIsac_PitchAnalysis(const double *in, /* PITCH_FRAME_LEN samples */
|
||||
double *out, /* PITCH_FRAME_LEN+QLOOKAHEAD samples */
|
||||
PitchAnalysisStruct *State,
|
||||
double *lags,
|
||||
double *gains);
|
||||
|
||||
void WebRtcIsac_InitializePitch(const double *in,
|
||||
const double old_lag,
|
||||
const double old_gain,
|
||||
PitchAnalysisStruct *State,
|
||||
double *lags);
|
||||
|
||||
void WebRtcIsac_PitchfilterPre(double *indat,
|
||||
double *outdat,
|
||||
PitchFiltstr *pfp,
|
||||
double *lags,
|
||||
double *gains);
|
||||
|
||||
void WebRtcIsac_PitchfilterPost(double *indat,
|
||||
double *outdat,
|
||||
PitchFiltstr *pfp,
|
||||
double *lags,
|
||||
double *gains);
|
||||
|
||||
void WebRtcIsac_PitchfilterPre_la(double *indat,
|
||||
double *outdat,
|
||||
PitchFiltstr *pfp,
|
||||
double *lags,
|
||||
double *gains);
|
||||
|
||||
void WebRtcIsac_PitchfilterPre_gains(double *indat,
|
||||
double *outdat,
|
||||
double out_dG[][PITCH_FRAME_LEN + QLOOKAHEAD],
|
||||
PitchFiltstr *pfp,
|
||||
double *lags,
|
||||
double *gains);
|
||||
|
||||
void WebRtcIsac_WeightingFilter(const double *in, double *weiout, double *whiout, WeightFiltstr *wfdata);
|
||||
|
||||
void WebRtcIsac_Highpass(const double *in, double *out, double *state, int N);
|
||||
|
||||
void WebRtcIsac_DecimateAllpass(const double *in,
|
||||
double *state_in, /* array of size: 2*ALLPASSSECTIONS+1 */
|
||||
int N, /* number of input samples */
|
||||
double *out); /* array of size N/2 */
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_ESTIMATOR_H_ */
|
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "pitch_estimator.h"
|
||||
#include "os_specific_inline.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
|
||||
static const double kDampFilter[PITCH_DAMPORDER] = {-0.07, 0.25, 0.64, 0.25, -0.07};
|
||||
|
||||
/* interpolation coefficients; generated by design_pitch_filter.m */
|
||||
static const double kIntrpCoef[PITCH_FRACS][PITCH_FRACORDER] = {
|
||||
{-0.02239172458614, 0.06653315052934, -0.16515880017569, 0.60701333734125, 0.64671399919202, -0.20249000396417, 0.09926548334755, -0.04765933793109, 0.01754159521746},
|
||||
{-0.01985640750434, 0.05816126837866, -0.13991265473714, 0.44560418147643, 0.79117042386876, -0.20266133815188, 0.09585268418555, -0.04533310458084, 0.01654127246314},
|
||||
{-0.01463300534216, 0.04229888475060, -0.09897034715253, 0.28284326017787, 0.90385267956632, -0.16976950138649, 0.07704272393639, -0.03584218578311, 0.01295781500709},
|
||||
{-0.00764851320885, 0.02184035544377, -0.04985561057281, 0.13083306574393, 0.97545011664662, -0.10177807997561, 0.04400901776474, -0.02010737175166, 0.00719783432422},
|
||||
{-0.00000000000000, 0.00000000000000, -0.00000000000001, 0.00000000000001, 0.99999999999999, 0.00000000000001, -0.00000000000001, 0.00000000000000, -0.00000000000000},
|
||||
{ 0.00719783432422, -0.02010737175166, 0.04400901776474, -0.10177807997562, 0.97545011664663, 0.13083306574393, -0.04985561057280, 0.02184035544377, -0.00764851320885},
|
||||
{ 0.01295781500710, -0.03584218578312, 0.07704272393640, -0.16976950138650, 0.90385267956634, 0.28284326017785, -0.09897034715252, 0.04229888475059, -0.01463300534216},
|
||||
{ 0.01654127246315, -0.04533310458085, 0.09585268418557, -0.20266133815190, 0.79117042386878, 0.44560418147640, -0.13991265473712, 0.05816126837865, -0.01985640750433}
|
||||
};
|
||||
|
||||
|
||||
void WebRtcIsac_PitchfilterPre(double *indat,
|
||||
double *outdat,
|
||||
PitchFiltstr *pfp,
|
||||
double *lags,
|
||||
double *gains)
|
||||
{
|
||||
|
||||
double ubuf[PITCH_INTBUFFSIZE];
|
||||
const double *fracoeff = NULL;
|
||||
double curgain, curlag, gaindelta, lagdelta;
|
||||
double sum, inystate[PITCH_DAMPORDER];
|
||||
double ftmp, oldlag, oldgain;
|
||||
int k, n, m, pos, ind, pos2, Li, frc;
|
||||
|
||||
Li = 0;
|
||||
/* Set up buffer and states */
|
||||
memcpy(ubuf, pfp->ubuf, sizeof(double) * PITCH_BUFFSIZE);
|
||||
memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER);
|
||||
|
||||
oldlag = *pfp->oldlagp;
|
||||
oldgain = *pfp->oldgainp;
|
||||
|
||||
/* No interpolation if pitch lag step is big */
|
||||
if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) {
|
||||
oldlag = lags[0];
|
||||
oldgain = gains[0];
|
||||
}
|
||||
|
||||
ind=0;
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++) {
|
||||
|
||||
/* Calculate interpolation steps */
|
||||
lagdelta=(lags[k]-oldlag) / PITCH_GRAN_PER_SUBFRAME;
|
||||
curlag=oldlag ;
|
||||
gaindelta=(gains[k]-oldgain) / PITCH_GRAN_PER_SUBFRAME;
|
||||
curgain=oldgain ;
|
||||
oldlag=lags[k];
|
||||
oldgain=gains[k];
|
||||
|
||||
for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
|
||||
if ((ind % PITCH_UPDATE) == 0) { /* Update parameters */
|
||||
curgain += gaindelta;
|
||||
curlag += lagdelta;
|
||||
Li = WebRtcIsac_lrint(curlag+PITCH_FILTDELAY + 0.5);
|
||||
ftmp = Li - (curlag+PITCH_FILTDELAY);
|
||||
frc = WebRtcIsac_lrint(PITCH_FRACS * ftmp - 0.5);
|
||||
fracoeff = kIntrpCoef[frc];
|
||||
}
|
||||
|
||||
/* shift low pass filter state */
|
||||
for (m=PITCH_DAMPORDER-1;m>0;m--)
|
||||
inystate[m] = inystate[m-1];
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos2 = pos - Li;
|
||||
sum=0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++)
|
||||
sum += ubuf[pos2+m] * fracoeff[m];
|
||||
inystate[0] = curgain * sum; /* Multiply with gain */
|
||||
|
||||
/* Low pass filter */
|
||||
sum=0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
sum += inystate[m] * kDampFilter[m];
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
outdat[ind] = indat[ind] - sum;
|
||||
ubuf[pos] = indat[ind] + outdat[ind];
|
||||
ind++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Export buffer and states */
|
||||
memcpy(pfp->ubuf, ubuf+PITCH_FRAME_LEN, sizeof(double) * PITCH_BUFFSIZE);
|
||||
memcpy(pfp->ystate, inystate, sizeof(double) * PITCH_DAMPORDER);
|
||||
|
||||
*pfp->oldlagp = oldlag;
|
||||
*pfp->oldgainp = oldgain;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_PitchfilterPre_la(double *indat,
|
||||
double *outdat,
|
||||
PitchFiltstr *pfp,
|
||||
double *lags,
|
||||
double *gains)
|
||||
{
|
||||
double ubuf[PITCH_INTBUFFSIZE+QLOOKAHEAD];
|
||||
const double *fracoeff = NULL;
|
||||
double curgain, curlag, gaindelta, lagdelta;
|
||||
double sum, inystate[PITCH_DAMPORDER];
|
||||
double ftmp;
|
||||
double oldlag, oldgain;
|
||||
int k, n, m, pos, ind, pos2, Li, frc;
|
||||
|
||||
Li = 0;
|
||||
/* Set up buffer and states */
|
||||
memcpy(ubuf, pfp->ubuf, sizeof(double) * PITCH_BUFFSIZE);
|
||||
memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER);
|
||||
|
||||
oldlag = *pfp->oldlagp;
|
||||
oldgain = *pfp->oldgainp;
|
||||
|
||||
/* No interpolation if pitch lag step is big */
|
||||
if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) {
|
||||
oldlag = lags[0];
|
||||
oldgain = gains[0];
|
||||
}
|
||||
|
||||
|
||||
ind=0;
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++) {
|
||||
|
||||
/* Calculate interpolation steps */
|
||||
lagdelta=(lags[k]-oldlag) / PITCH_GRAN_PER_SUBFRAME;
|
||||
curlag=oldlag ;
|
||||
gaindelta=(gains[k]-oldgain) / PITCH_GRAN_PER_SUBFRAME;
|
||||
curgain=oldgain ;
|
||||
oldlag=lags[k];
|
||||
oldgain=gains[k];
|
||||
|
||||
for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
|
||||
if ((ind % PITCH_UPDATE) == 0) { /* Update parameters */
|
||||
curgain += gaindelta;
|
||||
curlag += lagdelta;
|
||||
Li = WebRtcIsac_lrint(curlag+PITCH_FILTDELAY + 0.5);
|
||||
ftmp = Li - (curlag+PITCH_FILTDELAY);
|
||||
frc = WebRtcIsac_lrint(PITCH_FRACS * ftmp - 0.5);
|
||||
fracoeff = kIntrpCoef[frc];
|
||||
}
|
||||
|
||||
/* shift low pass filter state */
|
||||
for (m=PITCH_DAMPORDER-1;m>0;m--)
|
||||
inystate[m] = inystate[m-1];
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos2 = pos - Li;
|
||||
sum=0.0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++)
|
||||
sum += ubuf[pos2+m] * fracoeff[m];
|
||||
inystate[0] = curgain * sum; /* Multiply with gain */
|
||||
|
||||
/* Low pass filter */
|
||||
sum=0.0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
sum += inystate[m] * kDampFilter[m];
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
outdat[ind] = indat[ind] - sum;
|
||||
ubuf[pos] = indat[ind] + outdat[ind];
|
||||
ind++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Export buffer and states */
|
||||
memcpy(pfp->ubuf, ubuf+PITCH_FRAME_LEN, sizeof(double) * PITCH_BUFFSIZE);
|
||||
memcpy(pfp->ystate, inystate, sizeof(double) * PITCH_DAMPORDER);
|
||||
|
||||
*pfp->oldlagp = oldlag;
|
||||
*pfp->oldgainp = oldgain;
|
||||
|
||||
|
||||
/* Filter look-ahead segment */
|
||||
for (n=0;n<QLOOKAHEAD;n++) {
|
||||
/* shift low pass filter state */
|
||||
for (m=PITCH_DAMPORDER-1;m>0;m--)
|
||||
inystate[m] = inystate[m-1];
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos2 = pos - Li;
|
||||
sum=0.0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++)
|
||||
sum += ubuf[pos2+m] * fracoeff[m];
|
||||
inystate[0] = curgain * sum; /* Multiply with gain */
|
||||
|
||||
/* Low pass filter */
|
||||
sum=0.0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
sum += inystate[m] * kDampFilter[m];
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
outdat[ind] = indat[ind] - sum;
|
||||
ubuf[pos] = indat[ind] + outdat[ind];
|
||||
ind++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_PitchfilterPre_gains(double *indat,
|
||||
double *outdat,
|
||||
double out_dG[][PITCH_FRAME_LEN + QLOOKAHEAD],
|
||||
PitchFiltstr *pfp,
|
||||
double *lags,
|
||||
double *gains)
|
||||
{
|
||||
double ubuf[PITCH_INTBUFFSIZE+QLOOKAHEAD];
|
||||
double inystate_dG[4][PITCH_DAMPORDER];
|
||||
double gain_mult[4];
|
||||
const double *fracoeff = NULL;
|
||||
double curgain, curlag, gaindelta, lagdelta;
|
||||
double sum, sum2, inystate[PITCH_DAMPORDER];
|
||||
double ftmp, oldlag, oldgain;
|
||||
int k, n, m, m_tmp, j, pos, ind, pos2, Li, frc;
|
||||
|
||||
Li = 0;
|
||||
|
||||
/* Set up buffer and states */
|
||||
memcpy(ubuf, pfp->ubuf, sizeof(double) * PITCH_BUFFSIZE);
|
||||
memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER);
|
||||
|
||||
/* clear some buffers */
|
||||
for (k = 0; k < 4; k++) {
|
||||
gain_mult[k] = 0.0;
|
||||
for (n = 0; n < PITCH_DAMPORDER; n++)
|
||||
inystate_dG[k][n] = 0.0;
|
||||
}
|
||||
|
||||
oldlag = *pfp->oldlagp;
|
||||
oldgain = *pfp->oldgainp;
|
||||
|
||||
/* No interpolation if pitch lag step is big */
|
||||
if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) {
|
||||
oldlag = lags[0];
|
||||
oldgain = gains[0];
|
||||
gain_mult[0] = 1.0;
|
||||
}
|
||||
|
||||
|
||||
ind=0;
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++) {
|
||||
|
||||
/* Calculate interpolation steps */
|
||||
lagdelta=(lags[k]-oldlag) / PITCH_GRAN_PER_SUBFRAME;
|
||||
curlag=oldlag ;
|
||||
gaindelta=(gains[k]-oldgain) / PITCH_GRAN_PER_SUBFRAME;
|
||||
curgain=oldgain ;
|
||||
oldlag=lags[k];
|
||||
oldgain=gains[k];
|
||||
|
||||
for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
|
||||
if ((ind % PITCH_UPDATE) == 0) { /* Update parameters */
|
||||
curgain += gaindelta;
|
||||
curlag += lagdelta;
|
||||
Li = WebRtcIsac_lrint(curlag+PITCH_FILTDELAY + 0.5);
|
||||
ftmp = Li - (curlag+PITCH_FILTDELAY);
|
||||
frc = WebRtcIsac_lrint(PITCH_FRACS * ftmp - 0.5);
|
||||
fracoeff = kIntrpCoef[frc];
|
||||
gain_mult[k] += 0.2;
|
||||
if (gain_mult[k] > 1.0) gain_mult[k] = 1.0;
|
||||
if (k > 0) gain_mult[k-1] -= 0.2;
|
||||
}
|
||||
|
||||
/* shift low pass filter states */
|
||||
for (m=PITCH_DAMPORDER-1;m>0;m--) {
|
||||
inystate[m] = inystate[m-1];
|
||||
for (j = 0; j < 4; j++)
|
||||
inystate_dG[j][m] = inystate_dG[j][m-1];
|
||||
}
|
||||
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos2 = pos - Li;
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
sum=0.0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++)
|
||||
sum += ubuf[pos2+m] * fracoeff[m];
|
||||
inystate[0] = curgain * sum; /* Multiply with gain */
|
||||
m_tmp = (Li-ind > 0) ? Li-ind : 0;
|
||||
for (j = 0; j < k+1; j++) {
|
||||
/* filter */
|
||||
sum2 = 0.0;
|
||||
for (m = PITCH_FRACORDER-1; m >= m_tmp; m--)
|
||||
sum2 += out_dG[j][ind-Li + m] * fracoeff[m];
|
||||
inystate_dG[j][0] = gain_mult[j] * sum + curgain * sum2;
|
||||
}
|
||||
|
||||
/* Low pass filter */
|
||||
sum=0.0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
sum += inystate[m] * kDampFilter[m];
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
outdat[ind] = indat[ind] - sum;
|
||||
ubuf[pos] = indat[ind] + outdat[ind];
|
||||
|
||||
for (j = 0; j < k+1; j++) {
|
||||
sum = 0.0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
sum -= inystate_dG[j][m] * kDampFilter[m];
|
||||
out_dG[j][ind] = sum;
|
||||
}
|
||||
for (j = k+1; j < 4; j++)
|
||||
out_dG[j][ind] = 0.0;
|
||||
|
||||
|
||||
ind++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Filter look-ahead segment */
|
||||
for (n=0;n<QLOOKAHEAD;n++) {
|
||||
/* shift low pass filter states */
|
||||
for (m=PITCH_DAMPORDER-1;m>0;m--) {
|
||||
inystate[m] = inystate[m-1];
|
||||
for (j = 0; j < 4; j++)
|
||||
inystate_dG[j][m] = inystate_dG[j][m-1];
|
||||
}
|
||||
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos2 = pos - Li;
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
sum=0.0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++)
|
||||
sum += ubuf[pos2+m] * fracoeff[m];
|
||||
inystate[0] = curgain * sum; /* Multiply with gain */
|
||||
m_tmp = (Li-ind > 0) ? Li-ind : 0;
|
||||
for (j = 0; (j<k+1)&&(j<4); j++) {
|
||||
/* filter */
|
||||
sum2 = 0.0;
|
||||
for (m = PITCH_FRACORDER-1; m >= m_tmp; m--)
|
||||
sum2 += out_dG[j][ind-Li + m] * fracoeff[m];
|
||||
inystate_dG[j][0] = gain_mult[j] * sum + curgain * sum2;
|
||||
}
|
||||
|
||||
/* Low pass filter */
|
||||
sum=0.0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
sum += inystate[m] * kDampFilter[m];
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
outdat[ind] = indat[ind] - sum;
|
||||
ubuf[pos] = indat[ind] + outdat[ind];
|
||||
|
||||
for (j = 0; (j<k+1)&&(j<4); j++) {
|
||||
sum = 0.0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
sum -= inystate_dG[j][m] * kDampFilter[m];
|
||||
out_dG[j][ind] = sum;
|
||||
}
|
||||
|
||||
ind++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_PitchfilterPost(double *indat,
|
||||
double *outdat,
|
||||
PitchFiltstr *pfp,
|
||||
double *lags,
|
||||
double *gains)
|
||||
{
|
||||
|
||||
double ubuf[PITCH_INTBUFFSIZE];
|
||||
const double *fracoeff = NULL;
|
||||
double curgain, curlag, gaindelta, lagdelta;
|
||||
double sum, inystate[PITCH_DAMPORDER];
|
||||
double ftmp, oldlag, oldgain;
|
||||
int k, n, m, pos, ind, pos2, Li, frc;
|
||||
|
||||
Li = 0;
|
||||
|
||||
/* Set up buffer and states */
|
||||
memcpy(ubuf, pfp->ubuf, sizeof(double) * PITCH_BUFFSIZE);
|
||||
memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER);
|
||||
|
||||
oldlag = *pfp->oldlagp;
|
||||
oldgain = *pfp->oldgainp;
|
||||
|
||||
/* make output more periodic */
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++)
|
||||
gains[k] *= 1.3;
|
||||
|
||||
/* No interpolation if pitch lag step is big */
|
||||
if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) {
|
||||
oldlag = lags[0];
|
||||
oldgain = gains[0];
|
||||
}
|
||||
|
||||
|
||||
ind=0;
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++) {
|
||||
|
||||
/* Calculate interpolation steps */
|
||||
lagdelta=(lags[k]-oldlag) / PITCH_GRAN_PER_SUBFRAME;
|
||||
curlag=oldlag ;
|
||||
gaindelta=(gains[k]-oldgain) / PITCH_GRAN_PER_SUBFRAME;
|
||||
curgain=oldgain ;
|
||||
oldlag=lags[k];
|
||||
oldgain=gains[k];
|
||||
|
||||
for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
|
||||
if ((ind % PITCH_UPDATE) == 0) { /* Update parameters */
|
||||
curgain += gaindelta;
|
||||
curlag += lagdelta;
|
||||
Li = WebRtcIsac_lrint(curlag+PITCH_FILTDELAY + 0.5);
|
||||
ftmp = Li - (curlag+PITCH_FILTDELAY);
|
||||
frc = WebRtcIsac_lrint(PITCH_FRACS * ftmp - 0.5);
|
||||
fracoeff = kIntrpCoef[frc];
|
||||
}
|
||||
|
||||
/* shift low pass filter state */
|
||||
for (m=PITCH_DAMPORDER-1;m>0;m--)
|
||||
inystate[m] = inystate[m-1];
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos2 = pos - Li;
|
||||
sum=0.0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++)
|
||||
sum += ubuf[pos2+m] * fracoeff[m];
|
||||
inystate[0] = curgain * sum; /* Multiply with gain */
|
||||
|
||||
/* Low pass filter */
|
||||
sum=0.0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
sum += inystate[m] * kDampFilter[m];
|
||||
|
||||
/* Add to input and update buffer */
|
||||
outdat[ind] = indat[ind] + sum;
|
||||
ubuf[pos] = indat[ind] + outdat[ind];
|
||||
ind++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Export buffer and states */
|
||||
memcpy(pfp->ubuf, ubuf+PITCH_FRAME_LEN, sizeof(double) * PITCH_BUFFSIZE);
|
||||
memcpy(pfp->ystate, inystate, sizeof(double) * PITCH_DAMPORDER);
|
||||
|
||||
*pfp->oldlagp = oldlag;
|
||||
*pfp->oldgainp = oldgain;
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "pitch_gain_tables.h"
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
/* header file for coding tables for the pitch filter side-info in the entropy coder */
|
||||
/********************* Pitch Filter Gain Coefficient Tables ************************/
|
||||
/* cdf for quantized pitch filter gains */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchGainCdf[255] = {
|
||||
0, 2, 4, 6, 64, 901, 903, 905, 16954, 16956,
|
||||
16961, 17360, 17362, 17364, 17366, 17368, 17370, 17372, 17374, 17411,
|
||||
17514, 17516, 17583, 18790, 18796, 18802, 20760, 20777, 20782, 21722,
|
||||
21724, 21728, 21738, 21740, 21742, 21744, 21746, 21748, 22224, 22227,
|
||||
22230, 23214, 23229, 23239, 25086, 25108, 25120, 26088, 26094, 26098,
|
||||
26175, 26177, 26179, 26181, 26183, 26185, 26484, 26507, 26522, 27705,
|
||||
27731, 27750, 29767, 29799, 29817, 30866, 30883, 30885, 31025, 31029,
|
||||
31031, 31033, 31035, 31037, 31114, 31126, 31134, 32687, 32722, 32767,
|
||||
35718, 35742, 35757, 36943, 36952, 36954, 37115, 37128, 37130, 37132,
|
||||
37134, 37136, 37143, 37145, 37152, 38843, 38863, 38897, 47458, 47467,
|
||||
47474, 49040, 49061, 49063, 49145, 49157, 49159, 49161, 49163, 49165,
|
||||
49167, 49169, 49171, 49757, 49770, 49782, 61333, 61344, 61346, 62860,
|
||||
62883, 62885, 62887, 62889, 62891, 62893, 62895, 62897, 62899, 62901,
|
||||
62903, 62905, 62907, 62909, 65496, 65498, 65500, 65521, 65523, 65525,
|
||||
65527, 65529, 65531, 65533, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535};
|
||||
|
||||
/* index limits and ranges */
|
||||
const WebRtc_Word16 WebRtcIsac_kIndexLowerLimitGain[3] = {
|
||||
-7, -2, -1};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsac_kIndexUpperLimitGain[3] = {
|
||||
0, 3, 1};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kIndexMultsGain[2] = {
|
||||
18, 3};
|
||||
|
||||
/* size of cdf table */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQCdfTableSizeGain[1] = {
|
||||
256};
|
||||
|
||||
///////////////////////////FIXED POINT
|
||||
/* mean values of pitch filter gains in FIXED point */
|
||||
const WebRtc_Word16 WebRtcIsac_kQMeanGain1Q12[144] = {
|
||||
843, 1092, 1336, 1222, 1405, 1656, 1500, 1815, 1843, 1838, 1839, 1843, 1843, 1843, 1843, 1843,
|
||||
1843, 1843, 814, 846, 1092, 1013, 1174, 1383, 1391, 1511, 1584, 1734, 1753, 1843, 1843, 1843,
|
||||
1843, 1843, 1843, 1843, 524, 689, 777, 845, 947, 1069, 1090, 1263, 1380, 1447, 1559, 1676,
|
||||
1645, 1749, 1843, 1843, 1843, 1843, 81, 477, 563, 611, 706, 806, 849, 1012, 1192, 1128,
|
||||
1330, 1489, 1425, 1576, 1826, 1741, 1843, 1843, 0, 290, 305, 356, 488, 575, 602, 741,
|
||||
890, 835, 1079, 1196, 1182, 1376, 1519, 1506, 1680, 1843, 0, 47, 97, 69, 289, 381,
|
||||
385, 474, 617, 664, 803, 1079, 935, 1160, 1269, 1265, 1506, 1741, 0, 0, 0, 0,
|
||||
112, 120, 190, 283, 442, 343, 526, 809, 684, 935, 1134, 1020, 1265, 1506, 0, 0,
|
||||
0, 0, 0, 0, 0, 111, 256, 87, 373, 597, 430, 684, 935, 770, 1020, 1265};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsac_kQMeanGain2Q12[144] = {
|
||||
1760, 1525, 1285, 1747, 1671, 1393, 1843, 1826, 1555, 1843, 1784, 1606, 1843, 1843, 1711, 1843,
|
||||
1843, 1814, 1389, 1275, 1040, 1564, 1414, 1252, 1610, 1495, 1343, 1753, 1592, 1405, 1804, 1720,
|
||||
1475, 1843, 1814, 1581, 1208, 1061, 856, 1349, 1148, 994, 1390, 1253, 1111, 1495, 1343, 1178,
|
||||
1770, 1465, 1234, 1814, 1581, 1342, 1040, 793, 713, 1053, 895, 737, 1128, 1003, 861, 1277,
|
||||
1094, 981, 1475, 1192, 1019, 1581, 1342, 1098, 855, 570, 483, 833, 648, 540, 948, 744,
|
||||
572, 1009, 844, 636, 1234, 934, 685, 1342, 1217, 984, 537, 318, 124, 603, 423, 350,
|
||||
687, 479, 322, 791, 581, 430, 987, 671, 488, 1098, 849, 597, 283, 27, 0, 397,
|
||||
222, 38, 513, 271, 124, 624, 325, 157, 737, 484, 233, 849, 597, 343, 27, 0,
|
||||
0, 141, 0, 0, 256, 69, 0, 370, 87, 0, 484, 229, 0, 597, 343, 87};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsac_kQMeanGain3Q12[144] = {
|
||||
1843, 1843, 1711, 1843, 1818, 1606, 1843, 1827, 1511, 1814, 1639, 1393, 1760, 1525, 1285, 1656,
|
||||
1419, 1176, 1835, 1718, 1475, 1841, 1650, 1387, 1648, 1498, 1287, 1600, 1411, 1176, 1522, 1299,
|
||||
1040, 1419, 1176, 928, 1773, 1461, 1128, 1532, 1355, 1202, 1429, 1260, 1115, 1398, 1151, 1025,
|
||||
1172, 1080, 790, 1176, 928, 677, 1475, 1147, 1019, 1276, 1096, 922, 1214, 1010, 901, 1057,
|
||||
893, 800, 1040, 796, 734, 928, 677, 424, 1137, 897, 753, 1120, 830, 710, 875, 751,
|
||||
601, 795, 642, 583, 790, 544, 475, 677, 474, 140, 987, 750, 482, 697, 573, 450,
|
||||
691, 487, 303, 661, 394, 332, 537, 303, 220, 424, 168, 0, 737, 484, 229, 624,
|
||||
348, 153, 441, 261, 136, 397, 166, 51, 283, 27, 0, 168, 0, 0, 484, 229,
|
||||
0, 370, 57, 0, 256, 43, 0, 141, 0, 0, 27, 0, 0, 0, 0, 0};
|
||||
|
||||
|
||||
const WebRtc_Word16 WebRtcIsac_kQMeanGain4Q12[144] = {
|
||||
1843, 1843, 1843, 1843, 1841, 1843, 1500, 1821, 1843, 1222, 1434, 1656, 843, 1092, 1336, 504,
|
||||
757, 1007, 1843, 1843, 1843, 1838, 1791, 1843, 1265, 1505, 1599, 965, 1219, 1425, 730, 821,
|
||||
1092, 249, 504, 757, 1783, 1819, 1843, 1351, 1567, 1727, 1096, 1268, 1409, 805, 961, 1131,
|
||||
444, 670, 843, 0, 249, 504, 1425, 1655, 1743, 1096, 1324, 1448, 822, 1019, 1199, 490,
|
||||
704, 867, 81, 450, 555, 0, 0, 249, 1247, 1428, 1530, 881, 1073, 1283, 610, 759,
|
||||
939, 278, 464, 645, 0, 200, 270, 0, 0, 0, 935, 1163, 1410, 528, 790, 1068,
|
||||
377, 499, 717, 173, 240, 274, 0, 43, 62, 0, 0, 0, 684, 935, 1182, 343,
|
||||
551, 735, 161, 262, 423, 0, 55, 27, 0, 0, 0, 0, 0, 0, 430, 684,
|
||||
935, 87, 377, 597, 0, 46, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_gain_tables.h
|
||||
*
|
||||
* This file contains tables for the pitch filter side-info in the entropy coder.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
/* header file for coding tables for the pitch filter side-info in the entropy coder */
|
||||
/********************* Pitch Filter Gain Coefficient Tables ************************/
|
||||
/* cdf for quantized pitch filter gains */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchGainCdf[255];
|
||||
|
||||
/* index limits and ranges */
|
||||
extern const WebRtc_Word16 WebRtcIsac_kIndexLowerLimitGain[3];
|
||||
|
||||
extern const WebRtc_Word16 WebRtcIsac_kIndexUpperLimitGain[3];
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kIndexMultsGain[2];
|
||||
|
||||
/* mean values of pitch filter gains */
|
||||
//(Y)
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQMeanGain1Q12[144];
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQMeanGain2Q12[144];
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQMeanGain3Q12[144];
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQMeanGain4Q12[144];
|
||||
//(Y)
|
||||
|
||||
/* size of cdf table */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQCdfTableSizeGain[1];
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_ */
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "pitch_lag_tables.h"
|
||||
#include "settings.h"
|
||||
|
||||
/* header file for coding tables for the pitch filter side-info in the entropy coder */
|
||||
/********************* Pitch Filter Gain Coefficient Tables ************************/
|
||||
|
||||
/* tables for use with small pitch gain */
|
||||
|
||||
/* cdf for quantized pitch filter lags */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Lo[127] = {
|
||||
0, 134, 336, 549, 778, 998, 1264, 1512, 1777, 2070,
|
||||
2423, 2794, 3051, 3361, 3708, 3979, 4315, 4610, 4933, 5269,
|
||||
5575, 5896, 6155, 6480, 6816, 7129, 7477, 7764, 8061, 8358,
|
||||
8718, 9020, 9390, 9783, 10177, 10543, 10885, 11342, 11795, 12213,
|
||||
12680, 13096, 13524, 13919, 14436, 14903, 15349, 15795, 16267, 16734,
|
||||
17266, 17697, 18130, 18632, 19080, 19447, 19884, 20315, 20735, 21288,
|
||||
21764, 22264, 22723, 23193, 23680, 24111, 24557, 25022, 25537, 26082,
|
||||
26543, 27090, 27620, 28139, 28652, 29149, 29634, 30175, 30692, 31273,
|
||||
31866, 32506, 33059, 33650, 34296, 34955, 35629, 36295, 36967, 37726,
|
||||
38559, 39458, 40364, 41293, 42256, 43215, 44231, 45253, 46274, 47359,
|
||||
48482, 49678, 50810, 51853, 53016, 54148, 55235, 56263, 57282, 58363,
|
||||
59288, 60179, 61076, 61806, 62474, 63129, 63656, 64160, 64533, 64856,
|
||||
65152, 65535, 65535, 65535, 65535, 65535, 65535};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Lo[20] = {
|
||||
0, 429, 3558, 5861, 8558, 11639, 15210, 19502, 24773, 31983,
|
||||
42602, 48567, 52601, 55676, 58160, 60172, 61889, 63235, 65383, 65535};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Lo[2] = {
|
||||
0, 65535};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Lo[10] = {
|
||||
0, 2966, 6368, 11182, 19431, 37793, 48532, 55353, 60626, 65535};
|
||||
|
||||
const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrLo[4] = {WebRtcIsac_kQPitchLagCdf1Lo, WebRtcIsac_kQPitchLagCdf2Lo, WebRtcIsac_kQPitchLagCdf3Lo, WebRtcIsac_kQPitchLagCdf4Lo};
|
||||
|
||||
/* size of first cdf table */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeLo[1] = {128};
|
||||
|
||||
/* index limits and ranges */
|
||||
const WebRtc_Word16 WebRtcIsac_kQIndexLowerLimitLagLo[4] = {
|
||||
-140, -9, 0, -4};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsac_kQIndexUpperLimitLagLo[4] = {
|
||||
-20, 9, 0, 4};
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagLo[3] = {
|
||||
10, 1, 5};
|
||||
|
||||
/* mean values of pitch filter lags */
|
||||
const double WebRtcIsac_kQMeanLag2Lo[19] = {
|
||||
-17.21385070, -15.82678944, -14.07123081, -12.03003877, -10.01311864, -8.00794627, -5.91162987, -3.89231876, -1.90220980, -0.01879275,
|
||||
1.89144232, 3.88123171, 5.92146992, 7.96435361, 9.98923648, 11.98266347, 13.96101002, 15.74855713, 17.10976611};
|
||||
|
||||
const double WebRtcIsac_kQMeanLag3Lo[1] = {
|
||||
0.00000000};
|
||||
|
||||
const double WebRtcIsac_kQMeanLag4Lo[9] = {
|
||||
-7.76246496, -5.92083980, -3.94095226, -1.89502305, 0.03724681, 1.93054221, 3.96443467, 5.91726366, 7.78434291};
|
||||
|
||||
const double WebRtcIsac_kQPitchLagStepsizeLo = 2.000000;
|
||||
|
||||
|
||||
/* tables for use with medium pitch gain */
|
||||
|
||||
/* cdf for quantized pitch filter lags */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Mid[255] = {
|
||||
0, 28, 61, 88, 121, 149, 233, 331, 475, 559,
|
||||
624, 661, 689, 712, 745, 791, 815, 843, 866, 922,
|
||||
959, 1024, 1061, 1117, 1178, 1238, 1280, 1350, 1453, 1513,
|
||||
1564, 1625, 1671, 1741, 1788, 1904, 2072, 2421, 2626, 2770,
|
||||
2840, 2900, 2942, 3012, 3068, 3115, 3147, 3194, 3254, 3319,
|
||||
3366, 3520, 3678, 3780, 3850, 3911, 3957, 4032, 4106, 4185,
|
||||
4292, 4474, 4683, 4842, 5019, 5191, 5321, 5428, 5540, 5675,
|
||||
5763, 5847, 5959, 6127, 6304, 6564, 6839, 7090, 7263, 7421,
|
||||
7556, 7728, 7872, 7984, 8142, 8361, 8580, 8743, 8938, 9227,
|
||||
9409, 9539, 9674, 9795, 9930, 10060, 10177, 10382, 10614, 10861,
|
||||
11038, 11271, 11415, 11629, 11792, 12044, 12193, 12416, 12574, 12821,
|
||||
13007, 13235, 13445, 13654, 13901, 14134, 14488, 15000, 15703, 16285,
|
||||
16504, 16797, 17086, 17328, 17579, 17807, 17998, 18268, 18538, 18836,
|
||||
19087, 19274, 19474, 19716, 19935, 20270, 20833, 21303, 21532, 21741,
|
||||
21978, 22207, 22523, 22770, 23054, 23613, 23943, 24204, 24399, 24651,
|
||||
24832, 25074, 25270, 25549, 25759, 26015, 26150, 26424, 26713, 27048,
|
||||
27342, 27504, 27681, 27854, 28021, 28207, 28412, 28664, 28859, 29064,
|
||||
29278, 29548, 29748, 30107, 30377, 30656, 30856, 31164, 31452, 31755,
|
||||
32011, 32328, 32626, 32919, 33319, 33789, 34329, 34925, 35396, 35973,
|
||||
36443, 36964, 37551, 38156, 38724, 39357, 40023, 40908, 41587, 42602,
|
||||
43924, 45037, 45810, 46597, 47421, 48291, 49092, 50051, 51448, 52719,
|
||||
53440, 54241, 54944, 55977, 56676, 57299, 57872, 58389, 59059, 59688,
|
||||
60237, 60782, 61094, 61573, 61890, 62290, 62658, 63030, 63217, 63454,
|
||||
63622, 63882, 64003, 64273, 64427, 64529, 64581, 64697, 64758, 64902,
|
||||
65414, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Mid[36] = {
|
||||
0, 71, 335, 581, 836, 1039, 1323, 1795, 2258, 2608,
|
||||
3005, 3591, 4243, 5344, 7163, 10583, 16848, 28078, 49448, 57007,
|
||||
60357, 61850, 62837, 63437, 63872, 64188, 64377, 64614, 64774, 64949,
|
||||
65039, 65115, 65223, 65360, 65474, 65535};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Mid[2] = {
|
||||
0, 65535};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Mid[20] = {
|
||||
0, 28, 246, 459, 667, 1045, 1523, 2337, 4337, 11347,
|
||||
44231, 56709, 60781, 62243, 63161, 63969, 64608, 65062, 65502, 65535};
|
||||
|
||||
const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrMid[4] = {WebRtcIsac_kQPitchLagCdf1Mid, WebRtcIsac_kQPitchLagCdf2Mid, WebRtcIsac_kQPitchLagCdf3Mid, WebRtcIsac_kQPitchLagCdf4Mid};
|
||||
|
||||
/* size of first cdf table */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeMid[1] = {256};
|
||||
|
||||
/* index limits and ranges */
|
||||
const WebRtc_Word16 WebRtcIsac_kQIndexLowerLimitLagMid[4] = {
|
||||
-280, -17, 0, -9};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsac_kQIndexUpperLimitLagMid[4] = {
|
||||
-40, 17, 0, 9};
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagMid[3] = {
|
||||
18, 1, 10};
|
||||
|
||||
/* mean values of pitch filter lags */
|
||||
const double WebRtcIsac_kQMeanLag2Mid[35] = {
|
||||
-16.89183900, -15.86949778, -15.05476653, -14.00664348, -13.02793036, -12.07324237, -11.00542532, -10.11250602, -8.90792971, -8.02474753,
|
||||
-7.00426767, -5.94055287, -4.98251338, -3.91053158, -2.98820425, -1.93524245, -0.92978085, -0.01722509, 0.91317387, 1.92973955,
|
||||
2.96908851, 3.93728974, 4.96308471, 5.92244151, 7.08673497, 8.00993708, 9.04656316, 9.98538742, 10.97851694, 11.94772884,
|
||||
13.02426166, 14.00039951, 15.01347042, 15.80758023, 16.94086895};
|
||||
|
||||
const double WebRtcIsac_kQMeanLag3Mid[1] = {
|
||||
0.00000000};
|
||||
|
||||
const double WebRtcIsac_kQMeanLag4Mid[19] = {
|
||||
-8.60409403, -7.89198395, -7.03450280, -5.86260421, -4.93822322, -3.93078706, -2.91302322, -1.91824007, -0.87003282, 0.02822649,
|
||||
0.89951758, 1.87495484, 2.91802604, 3.96874074, 5.06571703, 5.93618227, 7.00520185, 7.88497726, 8.64160364};
|
||||
|
||||
const double WebRtcIsac_kQPitchLagStepsizeMid = 1.000000;
|
||||
|
||||
|
||||
/* tables for use with large pitch gain */
|
||||
|
||||
/* cdf for quantized pitch filter lags */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Hi[511] = {
|
||||
0, 7, 18, 33, 69, 105, 156, 228, 315, 612,
|
||||
680, 691, 709, 724, 735, 738, 742, 746, 749, 753,
|
||||
756, 760, 764, 774, 782, 785, 789, 796, 800, 803,
|
||||
807, 814, 818, 822, 829, 832, 847, 854, 858, 869,
|
||||
876, 883, 898, 908, 934, 977, 1010, 1050, 1060, 1064,
|
||||
1075, 1078, 1086, 1089, 1093, 1104, 1111, 1122, 1133, 1136,
|
||||
1151, 1162, 1183, 1209, 1252, 1281, 1339, 1364, 1386, 1401,
|
||||
1411, 1415, 1426, 1430, 1433, 1440, 1448, 1455, 1462, 1477,
|
||||
1487, 1495, 1502, 1506, 1509, 1516, 1524, 1531, 1535, 1542,
|
||||
1553, 1556, 1578, 1589, 1611, 1625, 1639, 1643, 1654, 1665,
|
||||
1672, 1687, 1694, 1705, 1708, 1719, 1730, 1744, 1752, 1759,
|
||||
1791, 1795, 1820, 1867, 1886, 1915, 1936, 1943, 1965, 1987,
|
||||
2041, 2099, 2161, 2175, 2200, 2211, 2226, 2233, 2244, 2251,
|
||||
2266, 2280, 2287, 2298, 2309, 2316, 2331, 2342, 2356, 2378,
|
||||
2403, 2418, 2447, 2497, 2544, 2602, 2863, 2895, 2903, 2935,
|
||||
2950, 2971, 3004, 3011, 3018, 3029, 3040, 3062, 3087, 3127,
|
||||
3152, 3170, 3199, 3243, 3293, 3322, 3340, 3377, 3402, 3427,
|
||||
3474, 3518, 3543, 3579, 3601, 3637, 3659, 3706, 3731, 3760,
|
||||
3818, 3847, 3869, 3901, 3920, 3952, 4068, 4169, 4220, 4271,
|
||||
4524, 4571, 4604, 4632, 4672, 4730, 4777, 4806, 4857, 4904,
|
||||
4951, 5002, 5031, 5060, 5107, 5150, 5212, 5266, 5331, 5382,
|
||||
5432, 5490, 5544, 5610, 5700, 5762, 5812, 5874, 5972, 6022,
|
||||
6091, 6163, 6232, 6305, 6402, 6540, 6685, 6880, 7090, 7271,
|
||||
7379, 7452, 7542, 7625, 7687, 7770, 7843, 7911, 7966, 8024,
|
||||
8096, 8190, 8252, 8320, 8411, 8501, 8585, 8639, 8751, 8842,
|
||||
8918, 8986, 9066, 9127, 9203, 9269, 9345, 9406, 9464, 9536,
|
||||
9612, 9667, 9735, 9844, 9931, 10036, 10119, 10199, 10260, 10358,
|
||||
10441, 10514, 10666, 10734, 10872, 10951, 11053, 11125, 11223, 11324,
|
||||
11516, 11664, 11737, 11816, 11892, 12008, 12120, 12200, 12280, 12392,
|
||||
12490, 12576, 12685, 12812, 12917, 13003, 13108, 13210, 13300, 13384,
|
||||
13470, 13579, 13673, 13771, 13879, 13999, 14136, 14201, 14368, 14614,
|
||||
14759, 14867, 14958, 15030, 15121, 15189, 15280, 15385, 15461, 15555,
|
||||
15653, 15768, 15884, 15971, 16069, 16145, 16210, 16279, 16380, 16463,
|
||||
16539, 16615, 16688, 16818, 16919, 17017, 18041, 18338, 18523, 18649,
|
||||
18790, 18917, 19047, 19167, 19315, 19460, 19601, 19731, 19858, 20068,
|
||||
20173, 20318, 20466, 20625, 20741, 20911, 21045, 21201, 21396, 21588,
|
||||
21816, 22022, 22305, 22547, 22786, 23072, 23322, 23600, 23879, 24168,
|
||||
24433, 24769, 25120, 25511, 25895, 26289, 26792, 27219, 27683, 28077,
|
||||
28566, 29094, 29546, 29977, 30491, 30991, 31573, 32105, 32594, 33173,
|
||||
33788, 34497, 35181, 35833, 36488, 37255, 37921, 38645, 39275, 39894,
|
||||
40505, 41167, 41790, 42431, 43096, 43723, 44385, 45134, 45858, 46607,
|
||||
47349, 48091, 48768, 49405, 49955, 50555, 51167, 51985, 52611, 53078,
|
||||
53494, 53965, 54435, 54996, 55601, 56125, 56563, 56838, 57244, 57566,
|
||||
57967, 58297, 58771, 59093, 59419, 59647, 59886, 60143, 60461, 60693,
|
||||
60917, 61170, 61416, 61634, 61891, 62122, 62310, 62455, 62632, 62839,
|
||||
63103, 63436, 63639, 63805, 63906, 64015, 64192, 64355, 64475, 64558,
|
||||
64663, 64742, 64811, 64865, 64916, 64956, 64981, 65025, 65068, 65115,
|
||||
65195, 65314, 65419, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
||||
65535};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Hi[68] = {
|
||||
0, 7, 11, 22, 37, 52, 56, 59, 81, 85,
|
||||
89, 96, 115, 130, 137, 152, 170, 181, 193, 200,
|
||||
207, 233, 237, 259, 289, 318, 363, 433, 592, 992,
|
||||
1607, 3062, 6149, 12206, 25522, 48368, 58223, 61918, 63640, 64584,
|
||||
64943, 65098, 65206, 65268, 65294, 65335, 65350, 65372, 65387, 65402,
|
||||
65413, 65420, 65428, 65435, 65439, 65450, 65454, 65468, 65472, 65476,
|
||||
65483, 65491, 65498, 65505, 65516, 65520, 65528, 65535};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Hi[2] = {
|
||||
0, 65535};
|
||||
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Hi[35] = {
|
||||
0, 7, 19, 30, 41, 48, 63, 74, 82, 96,
|
||||
122, 152, 215, 330, 701, 2611, 10931, 48106, 61177, 64341,
|
||||
65112, 65238, 65309, 65338, 65364, 65379, 65401, 65427, 65453, 65465,
|
||||
65476, 65490, 65509, 65528, 65535};
|
||||
|
||||
const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrHi[4] = {WebRtcIsac_kQPitchLagCdf1Hi, WebRtcIsac_kQPitchLagCdf2Hi, WebRtcIsac_kQPitchLagCdf3Hi, WebRtcIsac_kQPitchLagCdf4Hi};
|
||||
|
||||
/* size of first cdf table */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeHi[1] = {512};
|
||||
|
||||
/* index limits and ranges */
|
||||
const WebRtc_Word16 WebRtcIsac_kQindexLowerLimitLagHi[4] = {
|
||||
-552, -34, 0, -16};
|
||||
|
||||
const WebRtc_Word16 WebRtcIsac_kQindexUpperLimitLagHi[4] = {
|
||||
-80, 32, 0, 17};
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagHi[3] = {
|
||||
34, 1, 18};
|
||||
|
||||
/* mean values of pitch filter lags */
|
||||
const double WebRtcIsac_kQMeanLag2Hi[67] = {
|
||||
-17.07263295, -16.50000000, -15.83966081, -15.55613708, -14.96948007, -14.50000000, -14.00000000, -13.48377986, -13.00000000, -12.50000000,
|
||||
-11.93199636, -11.44530414, -11.04197641, -10.39910301, -10.15202337, -9.51322461, -8.93357741, -8.46456632, -8.10270672, -7.53751847,
|
||||
-6.98686404, -6.50000000, -6.08463150, -5.46872991, -5.00864717, -4.50163760, -4.01382410, -3.43856708, -2.96898001, -2.46554810,
|
||||
-1.96861004, -1.47106701, -0.97197237, -0.46561654, -0.00531409, 0.45767857, 0.96777907, 1.47507903, 1.97740425, 2.46695420,
|
||||
3.00695774, 3.47167185, 4.02712538, 4.49280007, 5.01087640, 5.48191963, 6.04916550, 6.51511058, 6.97297819, 7.46565499,
|
||||
8.01489405, 8.39912001, 8.91819757, 9.50000000, 10.11654065, 10.50000000, 11.03712583, 11.50000000, 12.00000000, 12.38964346,
|
||||
12.89466127, 13.43657881, 13.96013840, 14.46279912, 15.00000000, 15.39412269, 15.96662441};
|
||||
|
||||
const double WebRtcIsac_kQMeanLag3Hi[1] = {
|
||||
0.00000000};
|
||||
|
||||
const double WebRtcIsac_kQMeanLag4Hi[34] = {
|
||||
-7.98331221, -7.47988769, -7.03626557, -6.52708003, -6.06982173, -5.51856292, -5.05827033, -4.45909878, -3.99125864, -3.45308135,
|
||||
-3.02328139, -2.47297273, -1.94341995, -1.44699056, -0.93612243, -0.43012406, 0.01120357, 0.44054812, 0.93199883, 1.45669587,
|
||||
1.97218322, 2.50187419, 2.98748690, 3.49343202, 4.01660147, 4.50984306, 5.01402683, 5.58936797, 5.91787793, 6.59998900,
|
||||
6.85034315, 7.53503316, 7.87711194, 8.53631648};
|
||||
|
||||
const double WebRtcIsac_kQPitchLagStepsizeHi = 0.500000;
|
||||
|
||||
/* transform matrix */
|
||||
const double WebRtcIsac_kTransform[4][4] = {
|
||||
{-0.50000000, -0.50000000, -0.50000000, -0.50000000},
|
||||
{ 0.67082039, 0.22360680, -0.22360680, -0.67082039},
|
||||
{ 0.50000000, -0.50000000, -0.50000000, 0.50000000},
|
||||
{ 0.22360680, -0.67082039, 0.67082039, -0.22360680}};
|
||||
|
||||
/* transpose transform matrix */
|
||||
const double WebRtcIsac_kTransformTranspose[4][4] = {
|
||||
{-0.50000000, 0.67082039, 0.50000000, 0.22360680},
|
||||
{-0.50000000, 0.22360680, -0.50000000, -0.67082039},
|
||||
{-0.50000000, -0.22360680, -0.50000000, 0.67082039},
|
||||
{-0.50000000, -0.67082039, 0.50000000, -0.22360680}};
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_lag_tables.h
|
||||
*
|
||||
* This file contains tables for the pitch filter side-info in the entropy coder.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
/* header file for coding tables for the pitch filter side-info in the entropy coder */
|
||||
/********************* Pitch Filter Lag Coefficient Tables ************************/
|
||||
|
||||
/* tables for use with small pitch gain */
|
||||
|
||||
/* cdfs for quantized pitch lags */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Lo[127];
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Lo[20];
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Lo[2];
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Lo[10];
|
||||
|
||||
extern const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrLo[4];
|
||||
|
||||
/* size of first cdf table */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeLo[1];
|
||||
|
||||
/* index limits and ranges */
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQIndexLowerLimitLagLo[4];
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQIndexUpperLimitLagLo[4];
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagLo[3];
|
||||
|
||||
/* mean values of pitch filter lags */
|
||||
extern const double WebRtcIsac_kQMeanLag2Lo[19];
|
||||
extern const double WebRtcIsac_kQMeanLag3Lo[1];
|
||||
extern const double WebRtcIsac_kQMeanLag4Lo[9];
|
||||
|
||||
extern const double WebRtcIsac_kQPitchLagStepsizeLo;
|
||||
|
||||
|
||||
/* tables for use with medium pitch gain */
|
||||
|
||||
/* cdfs for quantized pitch lags */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Mid[255];
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Mid[36];
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Mid[2];
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Mid[20];
|
||||
|
||||
extern const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrMid[4];
|
||||
|
||||
/* size of first cdf table */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeMid[1];
|
||||
|
||||
/* index limits and ranges */
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQIndexLowerLimitLagMid[4];
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQIndexUpperLimitLagMid[4];
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagMid[3];
|
||||
|
||||
/* mean values of pitch filter lags */
|
||||
extern const double WebRtcIsac_kQMeanLag2Mid[35];
|
||||
extern const double WebRtcIsac_kQMeanLag3Mid[1];
|
||||
extern const double WebRtcIsac_kQMeanLag4Mid[19];
|
||||
|
||||
extern const double WebRtcIsac_kQPitchLagStepsizeMid;
|
||||
|
||||
|
||||
/* tables for use with large pitch gain */
|
||||
|
||||
/* cdfs for quantized pitch lags */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf1Hi[511];
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf2Hi[68];
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf3Hi[2];
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdf4Hi[35];
|
||||
|
||||
extern const WebRtc_UWord16 *WebRtcIsac_kQPitchLagCdfPtrHi[4];
|
||||
|
||||
/* size of first cdf table */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQPitchLagCdfSizeHi[1];
|
||||
|
||||
/* index limits and ranges */
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQindexLowerLimitLagHi[4];
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQindexUpperLimitLagHi[4];
|
||||
|
||||
/* initial index for arithmetic decoder */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQInitIndexLagHi[3];
|
||||
|
||||
/* mean values of pitch filter lags */
|
||||
extern const double WebRtcIsac_kQMeanLag2Hi[67];
|
||||
extern const double WebRtcIsac_kQMeanLag3Hi[1];
|
||||
extern const double WebRtcIsac_kQMeanLag4Hi[34];
|
||||
|
||||
extern const double WebRtcIsac_kQPitchLagStepsizeHi;
|
||||
|
||||
/* transform matrix */
|
||||
extern const double WebRtcIsac_kTransform[4][4];
|
||||
|
||||
/* transpose transform matrix */
|
||||
extern const double WebRtcIsac_kTransformTranspose[4][4];
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_ */
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* settings.h
|
||||
*
|
||||
* Declaration of #defines used in the iSAC codec
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SETTINGS_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SETTINGS_H_
|
||||
|
||||
/* sampling frequency (Hz) */
|
||||
#define FS 16000
|
||||
|
||||
/* number of samples per frame (either 320 (20ms), 480 (30ms) or 960 (60ms)) */
|
||||
#define INITIAL_FRAMESAMPLES 960
|
||||
|
||||
|
||||
#define MAXFFTSIZE 2048
|
||||
#define NFACTOR 11
|
||||
|
||||
|
||||
|
||||
/* do not modify the following; this will have to be modified if we have a 20ms framesize option */
|
||||
/*************************************************************************************************/
|
||||
/* miliseconds */
|
||||
#define FRAMESIZE 30
|
||||
/* number of samples per frame processed in the encoder, 480 */
|
||||
#define FRAMESAMPLES 480 /* ((FRAMESIZE*FS)/1000) */
|
||||
#define FRAMESAMPLES_HALF 240
|
||||
#define FRAMESAMPLES_QUARTER 120
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* max number of samples per frame (= 60 ms frame) */
|
||||
#define MAX_FRAMESAMPLES 960
|
||||
#define MAX_SWBFRAMESAMPLES (MAX_FRAMESAMPLES * 2)
|
||||
/* number of samples per 10ms frame */
|
||||
#define FRAMESAMPLES_10ms ((10*FS)/1000)
|
||||
#define SWBFRAMESAMPLES_10ms (FRAMESAMPLES_10ms * 2)
|
||||
/* number of samples in 30 ms frame */
|
||||
#define FRAMESAMPLES_30ms 480
|
||||
/* number of subframes */
|
||||
#define SUBFRAMES 6
|
||||
/* length of a subframe */
|
||||
#define UPDATE 80
|
||||
/* length of half a subframe (low/high band) */
|
||||
#define HALF_SUBFRAMELEN (UPDATE/2)
|
||||
/* samples of look ahead (in a half-band, so actually half the samples of look ahead @ FS) */
|
||||
#define QLOOKAHEAD 24 /* 3 ms */
|
||||
/* order of AR model in spectral entropy coder */
|
||||
#define AR_ORDER 6
|
||||
/* order of LP model in spectral entropy coder */
|
||||
#define LP_ORDER 0
|
||||
|
||||
/* window length (masking analysis) */
|
||||
#define WINLEN 256
|
||||
/* order of low-band pole filter used to approximate masking curve */
|
||||
#define ORDERLO 12
|
||||
/* order of hi-band pole filter used to approximate masking curve */
|
||||
#define ORDERHI 6
|
||||
|
||||
#define UB_LPC_ORDER 4
|
||||
#define UB_LPC_VEC_PER_FRAME 2
|
||||
#define UB16_LPC_VEC_PER_FRAME 4
|
||||
#define UB_ACTIVE_SUBFRAMES 2
|
||||
#define UB_MAX_LPC_ORDER 6
|
||||
#define UB_INTERPOL_SEGMENTS 1
|
||||
#define UB16_INTERPOL_SEGMENTS 3
|
||||
#define LB_TOTAL_DELAY_SAMPLES 48
|
||||
enum ISACBandwidth {isac8kHz = 8, isac12kHz = 12, isac16kHz = 16};
|
||||
enum ISACBand{isacLowerBand = 0, isacUpperBand = 1};
|
||||
#define UB_LPC_GAIN_DIM SUBFRAMES
|
||||
#define FB_STATE_SIZE_WORD32 6
|
||||
|
||||
|
||||
/* order for post_filter_bank */
|
||||
#define POSTQORDER 3
|
||||
/* order for pre-filterbank */
|
||||
#define QORDER 3
|
||||
/* another order */
|
||||
#define QORDER_ALL (POSTQORDER+QORDER-1)
|
||||
/* for decimator */
|
||||
#define ALLPASSSECTIONS 2
|
||||
|
||||
|
||||
/* array size for byte stream in number of bytes. */
|
||||
#define STREAM_SIZE_MAX 600 /* The old maximum size still needed for the decoding */
|
||||
#define STREAM_SIZE_MAX_30 200 /* 200 bytes = 53.4 kbit/s @ 30 ms.framelength */
|
||||
#define STREAM_SIZE_MAX_60 400 /* 400 bytes = 53.4 kbit/s @ 60 ms.framelength */
|
||||
|
||||
/* storage size for bit counts */
|
||||
#define BIT_COUNTER_SIZE 30
|
||||
/* maximum order of any AR model or filter */
|
||||
#define MAX_AR_MODEL_ORDER 12//50
|
||||
|
||||
|
||||
/* For pitch analysis */
|
||||
#define PITCH_FRAME_LEN (FRAMESAMPLES_HALF) /* 30 ms */
|
||||
#define PITCH_MAX_LAG 140 /* 57 Hz */
|
||||
#define PITCH_MIN_LAG 20 /* 400 Hz */
|
||||
#define PITCH_MAX_GAIN 0.45
|
||||
#define PITCH_MAX_GAIN_06 0.27 /* PITCH_MAX_GAIN*0.6 */
|
||||
#define PITCH_MAX_GAIN_Q12 1843
|
||||
#define PITCH_LAG_SPAN2 (PITCH_MAX_LAG/2-PITCH_MIN_LAG/2+5)
|
||||
#define PITCH_CORR_LEN2 60 /* 15 ms */
|
||||
#define PITCH_CORR_STEP2 (PITCH_FRAME_LEN/4)
|
||||
#define PITCH_BW 11 /* half the band width of correlation surface */
|
||||
#define PITCH_SUBFRAMES 4
|
||||
#define PITCH_GRAN_PER_SUBFRAME 5
|
||||
#define PITCH_SUBFRAME_LEN (PITCH_FRAME_LEN/PITCH_SUBFRAMES)
|
||||
#define PITCH_UPDATE (PITCH_SUBFRAME_LEN/PITCH_GRAN_PER_SUBFRAME)
|
||||
/* maximum number of peaks to be examined in correlation surface */
|
||||
#define PITCH_MAX_NUM_PEAKS 10
|
||||
#define PITCH_PEAK_DECAY 0.85
|
||||
/* For weighting filter */
|
||||
#define PITCH_WLPCORDER 6
|
||||
#define PITCH_WLPCWINLEN PITCH_FRAME_LEN
|
||||
#define PITCH_WLPCASYM 0.3 /* asymmetry parameter */
|
||||
#define PITCH_WLPCBUFLEN PITCH_WLPCWINLEN
|
||||
/* For pitch filter */
|
||||
#define PITCH_BUFFSIZE (PITCH_MAX_LAG + 50) /* Extra 50 for fraction and LP filters */
|
||||
#define PITCH_INTBUFFSIZE (PITCH_FRAME_LEN+PITCH_BUFFSIZE)
|
||||
/* Max rel. step for interpolation */
|
||||
#define PITCH_UPSTEP 1.5
|
||||
/* Max rel. step for interpolation */
|
||||
#define PITCH_DOWNSTEP 0.67
|
||||
#define PITCH_FRACS 8
|
||||
#define PITCH_FRACORDER 9
|
||||
#define PITCH_DAMPORDER 5
|
||||
#define PITCH_FILTDELAY 1.5f
|
||||
/* stepsize for quantization of the pitch Gain */
|
||||
#define PITCH_GAIN_STEPSIZE 0.125
|
||||
|
||||
|
||||
|
||||
/* Order of high pass filter */
|
||||
#define HPORDER 2
|
||||
|
||||
/* some mathematical constants */
|
||||
#define LOG2EXP 1.44269504088896 /* log2(exp) */
|
||||
#define PI 3.14159265358979
|
||||
|
||||
/* Maximum number of iterations allowed to limit payload size */
|
||||
#define MAX_PAYLOAD_LIMIT_ITERATION 5
|
||||
|
||||
/* Redundant Coding */
|
||||
#define RCU_BOTTLENECK_BPS 16000
|
||||
#define RCU_TRANSCODING_SCALE 0.40f
|
||||
#define RCU_TRANSCODING_SCALE_INVERSE 2.5f
|
||||
|
||||
#define RCU_TRANSCODING_SCALE_UB 0.50f
|
||||
#define RCU_TRANSCODING_SCALE_UB_INVERSE 2.0f
|
||||
|
||||
|
||||
/* Define Error codes */
|
||||
/* 6000 General */
|
||||
#define ISAC_MEMORY_ALLOCATION_FAILED 6010
|
||||
#define ISAC_MODE_MISMATCH 6020
|
||||
#define ISAC_DISALLOWED_BOTTLENECK 6030
|
||||
#define ISAC_DISALLOWED_FRAME_LENGTH 6040
|
||||
#define ISAC_UNSUPPORTED_SAMPLING_FREQUENCY 6050
|
||||
|
||||
/* 6200 Bandwidth estimator */
|
||||
#define ISAC_RANGE_ERROR_BW_ESTIMATOR 6240
|
||||
/* 6400 Encoder */
|
||||
#define ISAC_ENCODER_NOT_INITIATED 6410
|
||||
#define ISAC_DISALLOWED_CODING_MODE 6420
|
||||
#define ISAC_DISALLOWED_FRAME_MODE_ENCODER 6430
|
||||
#define ISAC_DISALLOWED_BITSTREAM_LENGTH 6440
|
||||
#define ISAC_PAYLOAD_LARGER_THAN_LIMIT 6450
|
||||
#define ISAC_DISALLOWED_ENCODER_BANDWIDTH 6460
|
||||
/* 6600 Decoder */
|
||||
#define ISAC_DECODER_NOT_INITIATED 6610
|
||||
#define ISAC_EMPTY_PACKET 6620
|
||||
#define ISAC_DISALLOWED_FRAME_MODE_DECODER 6630
|
||||
#define ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH 6640
|
||||
#define ISAC_RANGE_ERROR_DECODE_BANDWIDTH 6650
|
||||
#define ISAC_RANGE_ERROR_DECODE_PITCH_GAIN 6660
|
||||
#define ISAC_RANGE_ERROR_DECODE_PITCH_LAG 6670
|
||||
#define ISAC_RANGE_ERROR_DECODE_LPC 6680
|
||||
#define ISAC_RANGE_ERROR_DECODE_SPECTRUM 6690
|
||||
#define ISAC_LENGTH_MISMATCH 6730
|
||||
#define ISAC_RANGE_ERROR_DECODE_BANDWITH 6740
|
||||
#define ISAC_DISALLOWED_BANDWIDTH_MODE_DECODER 6750
|
||||
/* 6800 Call setup formats */
|
||||
#define ISAC_INCOMPATIBLE_FORMATS 6810
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SETTINGS_H_ */
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "spectrum_ar_model_tables.h"
|
||||
#include "settings.h"
|
||||
|
||||
/********************* AR Coefficient Tables ************************/
|
||||
/* cdf for quantized reflection coefficient 1 */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQArRc1Cdf[12] = {
|
||||
0, 2, 4, 129, 7707, 57485, 65495, 65527, 65529, 65531,
|
||||
65533, 65535};
|
||||
|
||||
/* cdf for quantized reflection coefficient 2 */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQArRc2Cdf[12] = {
|
||||
0, 2, 4, 7, 531, 25298, 64525, 65526, 65529, 65531,
|
||||
65533, 65535};
|
||||
|
||||
/* cdf for quantized reflection coefficient 3 */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQArRc3Cdf[12] = {
|
||||
0, 2, 4, 6, 620, 22898, 64843, 65527, 65529, 65531,
|
||||
65533, 65535};
|
||||
|
||||
/* cdf for quantized reflection coefficient 4 */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQArRc4Cdf[12] = {
|
||||
0, 2, 4, 6, 35, 10034, 60733, 65506, 65529, 65531,
|
||||
65533, 65535};
|
||||
|
||||
/* cdf for quantized reflection coefficient 5 */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQArRc5Cdf[12] = {
|
||||
0, 2, 4, 6, 36, 7567, 56727, 65385, 65529, 65531,
|
||||
65533, 65535};
|
||||
|
||||
/* cdf for quantized reflection coefficient 6 */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQArRc6Cdf[12] = {
|
||||
0, 2, 4, 6, 14, 6579, 57360, 65409, 65529, 65531,
|
||||
65533, 65535};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 1 */
|
||||
const WebRtc_Word16 WebRtcIsac_kQArRc1Levels[11] = {
|
||||
-32104, -29007, -23202, -15496, -9279, -2577, 5934, 17535, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 2 */
|
||||
const WebRtc_Word16 WebRtcIsac_kQArRc2Levels[11] = {
|
||||
-32104, -29503, -23494, -15261, -7309, -1399, 6158, 16381, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 3 */
|
||||
const WebRtc_Word16 WebRtcIsac_kQArRc3Levels[11] = {
|
||||
-32104, -29503, -23157, -15186, -7347, -1359, 5829, 17535, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 4 */
|
||||
const WebRtc_Word16 WebRtcIsac_kQArRc4Levels[11] = {
|
||||
-32104, -29503, -24512, -15362, -6665, -342, 6596, 14585, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 5 */
|
||||
const WebRtc_Word16 WebRtcIsac_kQArRc5Levels[11] = {
|
||||
-32104, -29503, -24512, -15005, -6564, -106, 7123, 14920, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* representation levels for quantized reflection coefficient 6 */
|
||||
const WebRtc_Word16 WebRtcIsac_kQArRc6Levels[11] = {
|
||||
-32104, -29503, -24512, -15096, -6656, -37, 7036, 14847, 24512, 29503, 32104
|
||||
};
|
||||
|
||||
/* quantization boundary levels for reflection coefficients */
|
||||
const WebRtc_Word16 WebRtcIsac_kQArBoundaryLevels[12] = {
|
||||
-32768, -31441, -27566, -21458, -13612, -4663, 4663, 13612, 21458, 27566, 31441, 32767
|
||||
};
|
||||
|
||||
/* initial index for AR reflection coefficient quantizer and cdf table search */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQArRcInitIndex[6] = {
|
||||
5, 5, 5, 5, 5, 5};
|
||||
|
||||
/* pointers to AR cdf tables */
|
||||
const WebRtc_UWord16 *WebRtcIsac_kQArRcCdfPtr[AR_ORDER] = {
|
||||
WebRtcIsac_kQArRc1Cdf, WebRtcIsac_kQArRc2Cdf, WebRtcIsac_kQArRc3Cdf,
|
||||
WebRtcIsac_kQArRc4Cdf, WebRtcIsac_kQArRc5Cdf, WebRtcIsac_kQArRc6Cdf
|
||||
};
|
||||
|
||||
/* pointers to AR representation levels tables */
|
||||
const WebRtc_Word16 *WebRtcIsac_kQArRcLevelsPtr[AR_ORDER] = {
|
||||
WebRtcIsac_kQArRc1Levels, WebRtcIsac_kQArRc2Levels, WebRtcIsac_kQArRc3Levels,
|
||||
WebRtcIsac_kQArRc4Levels, WebRtcIsac_kQArRc5Levels, WebRtcIsac_kQArRc6Levels
|
||||
};
|
||||
|
||||
|
||||
/******************** GAIN Coefficient Tables ***********************/
|
||||
/* cdf for Gain coefficient */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQGainCdf[19] = {
|
||||
0, 2, 4, 6, 8, 10, 12, 14, 16, 1172,
|
||||
11119, 29411, 51699, 64445, 65527, 65529, 65531, 65533, 65535};
|
||||
|
||||
/* representation levels for quantized squared Gain coefficient */
|
||||
const WebRtc_Word32 WebRtcIsac_kQGain2Levels[18] = {
|
||||
// 17, 28, 46, 76, 128, 215, 364, 709, 1268, 1960, 3405, 6078, 11286, 17827, 51918, 134498, 487432, 2048000};
|
||||
128, 128, 128, 128, 128, 215, 364, 709, 1268, 1960, 3405, 6078, 11286, 17827, 51918, 134498, 487432, 2048000};
|
||||
/* quantization boundary levels for squared Gain coefficient */
|
||||
const WebRtc_Word32 WebRtcIsac_kQGain2BoundaryLevels[19] = {
|
||||
0, 21, 35, 59, 99, 166, 280, 475, 815, 1414, 2495, 4505, 8397, 16405, 34431, 81359, 240497, 921600, 0x7FFFFFFF};
|
||||
|
||||
/* pointers to Gain cdf table */
|
||||
const WebRtc_UWord16 *WebRtcIsac_kQGainCdf_ptr[1] = {WebRtcIsac_kQGainCdf};
|
||||
|
||||
/* Gain initial index for gain quantizer and cdf table search */
|
||||
const WebRtc_UWord16 WebRtcIsac_kQGainInitIndex[1] = {11};
|
||||
|
||||
/************************* Cosine Tables ****************************/
|
||||
/* Cosine table */
|
||||
const WebRtc_Word16 WebRtcIsac_kCos[6][60] = {
|
||||
{512, 512, 511, 510, 508, 507, 505, 502, 499, 496, 493, 489, 485, 480, 476, 470, 465, 459, 453, 447,
|
||||
440, 433, 426, 418, 410, 402, 394, 385, 376, 367, 357, 348, 338, 327, 317, 306, 295, 284, 273, 262,
|
||||
250, 238, 226, 214, 202, 190, 177, 165, 152, 139, 126, 113, 100, 87, 73, 60, 47, 33, 20, 7},
|
||||
{512, 510, 508, 503, 498, 491, 483, 473, 462, 450, 437, 422, 406, 389, 371, 352, 333, 312, 290, 268,
|
||||
244, 220, 196, 171, 145, 120, 93, 67, 40, 13, -13, -40, -67, -93, -120, -145, -171, -196, -220, -244,
|
||||
-268, -290, -312, -333, -352, -371, -389, -406, -422, -437, -450, -462, -473, -483, -491, -498, -503, -508, -510, -512},
|
||||
{512, 508, 502, 493, 480, 465, 447, 426, 402, 376, 348, 317, 284, 250, 214, 177, 139, 100, 60, 20,
|
||||
-20, -60, -100, -139, -177, -214, -250, -284, -317, -348, -376, -402, -426, -447, -465, -480, -493, -502, -508, -512,
|
||||
-512, -508, -502, -493, -480, -465, -447, -426, -402, -376, -348, -317, -284, -250, -214, -177, -139, -100, -60, -20},
|
||||
{511, 506, 495, 478, 456, 429, 398, 362, 322, 279, 232, 183, 133, 80, 27, -27, -80, -133, -183, -232,
|
||||
-279, -322, -362, -398, -429, -456, -478, -495, -506, -511, -511, -506, -495, -478, -456, -429, -398, -362, -322, -279,
|
||||
-232, -183, -133, -80, -27, 27, 80, 133, 183, 232, 279, 322, 362, 398, 429, 456, 478, 495, 506, 511},
|
||||
{511, 502, 485, 459, 426, 385, 338, 284, 226, 165, 100, 33, -33, -100, -165, -226, -284, -338, -385, -426,
|
||||
-459, -485, -502, -511, -511, -502, -485, -459, -426, -385, -338, -284, -226, -165, -100, -33, 33, 100, 165, 226,
|
||||
284, 338, 385, 426, 459, 485, 502, 511, 511, 502, 485, 459, 426, 385, 338, 284, 226, 165, 100, 33},
|
||||
{510, 498, 473, 437, 389, 333, 268, 196, 120, 40, -40, -120, -196, -268, -333, -389, -437, -473, -498, -510,
|
||||
-510, -498, -473, -437, -389, -333, -268, -196, -120, -40, 40, 120, 196, 268, 333, 389, 437, 473, 498, 510,
|
||||
510, 498, 473, 437, 389, 333, 268, 196, 120, 40, -40, -120, -196, -268, -333, -389, -437, -473, -498, -510}
|
||||
};
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* spectrum_ar_model_tables.h
|
||||
*
|
||||
* This file contains definitions of tables with AR coefficients,
|
||||
* Gain coefficients and cosine tables.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
/********************* AR Coefficient Tables ************************/
|
||||
/* cdf for quantized reflection coefficient 1 */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQArRc1Cdf[12];
|
||||
|
||||
/* cdf for quantized reflection coefficient 2 */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQArRc2Cdf[12];
|
||||
|
||||
/* cdf for quantized reflection coefficient 3 */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQArRc3Cdf[12];
|
||||
|
||||
/* cdf for quantized reflection coefficient 4 */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQArRc4Cdf[12];
|
||||
|
||||
/* cdf for quantized reflection coefficient 5 */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQArRc5Cdf[12];
|
||||
|
||||
/* cdf for quantized reflection coefficient 6 */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQArRc6Cdf[12];
|
||||
|
||||
/* quantization boundary levels for reflection coefficients */
|
||||
extern const WebRtc_Word16 WebRtcIsac_kQArBoundaryLevels[12];
|
||||
|
||||
/* initial indices for AR reflection coefficient quantizer and cdf table search */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQArRcInitIndex[AR_ORDER];
|
||||
|
||||
/* pointers to AR cdf tables */
|
||||
extern const WebRtc_UWord16 *WebRtcIsac_kQArRcCdfPtr[AR_ORDER];
|
||||
|
||||
/* pointers to AR representation levels tables */
|
||||
extern const WebRtc_Word16 *WebRtcIsac_kQArRcLevelsPtr[AR_ORDER];
|
||||
|
||||
|
||||
/******************** GAIN Coefficient Tables ***********************/
|
||||
/* cdf for Gain coefficient */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQGainCdf[19];
|
||||
|
||||
/* representation levels for quantized Gain coefficient */
|
||||
extern const WebRtc_Word32 WebRtcIsac_kQGain2Levels[18];
|
||||
|
||||
/* squared quantization boundary levels for Gain coefficient */
|
||||
extern const WebRtc_Word32 WebRtcIsac_kQGain2BoundaryLevels[19];
|
||||
|
||||
/* pointer to Gain cdf table */
|
||||
extern const WebRtc_UWord16 *WebRtcIsac_kQGainCdf_ptr[1];
|
||||
|
||||
/* Gain initial index for gain quantizer and cdf table search */
|
||||
extern const WebRtc_UWord16 WebRtcIsac_kQGainInitIndex[1];
|
||||
|
||||
/************************* Cosine Tables ****************************/
|
||||
/* Cosine table */
|
||||
extern const WebRtc_Word16 WebRtcIsac_kCos[6][60];
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_ */
|
|
@ -0,0 +1,478 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* structs.h
|
||||
*
|
||||
* This header file contains all the structs used in the ISAC codec
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_
|
||||
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "settings.h"
|
||||
#include "isac.h"
|
||||
|
||||
typedef struct Bitstreamstruct {
|
||||
|
||||
WebRtc_UWord8 stream[STREAM_SIZE_MAX];
|
||||
WebRtc_UWord32 W_upper;
|
||||
WebRtc_UWord32 streamval;
|
||||
WebRtc_UWord32 stream_index;
|
||||
|
||||
} Bitstr;
|
||||
|
||||
typedef struct {
|
||||
|
||||
double DataBufferLo[WINLEN];
|
||||
double DataBufferHi[WINLEN];
|
||||
|
||||
double CorrBufLo[ORDERLO+1];
|
||||
double CorrBufHi[ORDERHI+1];
|
||||
|
||||
float PreStateLoF[ORDERLO+1];
|
||||
float PreStateLoG[ORDERLO+1];
|
||||
float PreStateHiF[ORDERHI+1];
|
||||
float PreStateHiG[ORDERHI+1];
|
||||
float PostStateLoF[ORDERLO+1];
|
||||
float PostStateLoG[ORDERLO+1];
|
||||
float PostStateHiF[ORDERHI+1];
|
||||
float PostStateHiG[ORDERHI+1];
|
||||
|
||||
double OldEnergy;
|
||||
|
||||
} MaskFiltstr;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
//state vectors for each of the two analysis filters
|
||||
double INSTAT1[2*(QORDER-1)];
|
||||
double INSTAT2[2*(QORDER-1)];
|
||||
double INSTATLA1[2*(QORDER-1)];
|
||||
double INSTATLA2[2*(QORDER-1)];
|
||||
double INLABUF1[QLOOKAHEAD];
|
||||
double INLABUF2[QLOOKAHEAD];
|
||||
|
||||
float INSTAT1_float[2*(QORDER-1)];
|
||||
float INSTAT2_float[2*(QORDER-1)];
|
||||
float INSTATLA1_float[2*(QORDER-1)];
|
||||
float INSTATLA2_float[2*(QORDER-1)];
|
||||
float INLABUF1_float[QLOOKAHEAD];
|
||||
float INLABUF2_float[QLOOKAHEAD];
|
||||
|
||||
/* High pass filter */
|
||||
double HPstates[HPORDER];
|
||||
float HPstates_float[HPORDER];
|
||||
|
||||
} PreFiltBankstr;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
//state vectors for each of the two analysis filters
|
||||
double STATE_0_LOWER[2*POSTQORDER];
|
||||
double STATE_0_UPPER[2*POSTQORDER];
|
||||
|
||||
/* High pass filter */
|
||||
double HPstates1[HPORDER];
|
||||
double HPstates2[HPORDER];
|
||||
|
||||
float STATE_0_LOWER_float[2*POSTQORDER];
|
||||
float STATE_0_UPPER_float[2*POSTQORDER];
|
||||
|
||||
float HPstates1_float[HPORDER];
|
||||
float HPstates2_float[HPORDER];
|
||||
|
||||
} PostFiltBankstr;
|
||||
|
||||
typedef struct {
|
||||
|
||||
//data buffer for pitch filter
|
||||
double ubuf[PITCH_BUFFSIZE];
|
||||
|
||||
//low pass state vector
|
||||
double ystate[PITCH_DAMPORDER];
|
||||
|
||||
//old lag and gain
|
||||
double oldlagp[1];
|
||||
double oldgainp[1];
|
||||
|
||||
} PitchFiltstr;
|
||||
|
||||
typedef struct {
|
||||
|
||||
//data buffer
|
||||
double buffer[PITCH_WLPCBUFLEN];
|
||||
|
||||
//state vectors
|
||||
double istate[PITCH_WLPCORDER];
|
||||
double weostate[PITCH_WLPCORDER];
|
||||
double whostate[PITCH_WLPCORDER];
|
||||
|
||||
//LPC window -> should be a global array because constant
|
||||
double window[PITCH_WLPCWINLEN];
|
||||
|
||||
} WeightFiltstr;
|
||||
|
||||
typedef struct {
|
||||
|
||||
//for inital estimator
|
||||
double dec_buffer[PITCH_CORR_LEN2 + PITCH_CORR_STEP2 +
|
||||
PITCH_MAX_LAG/2 - PITCH_FRAME_LEN/2+2];
|
||||
double decimator_state[2*ALLPASSSECTIONS+1];
|
||||
double hp_state[2];
|
||||
|
||||
double whitened_buf[QLOOKAHEAD];
|
||||
|
||||
double inbuf[QLOOKAHEAD];
|
||||
|
||||
PitchFiltstr PFstr_wght;
|
||||
PitchFiltstr PFstr;
|
||||
WeightFiltstr Wghtstr;
|
||||
|
||||
} PitchAnalysisStruct;
|
||||
|
||||
|
||||
|
||||
/* Have instance of struct together with other iSAC structs */
|
||||
typedef struct {
|
||||
|
||||
/* Previous frame length (in ms) */
|
||||
WebRtc_Word32 prev_frame_length;
|
||||
|
||||
/* Previous RTP timestamp from received
|
||||
packet (in samples relative beginning) */
|
||||
WebRtc_Word32 prev_rec_rtp_number;
|
||||
|
||||
/* Send timestamp for previous packet (in ms using timeGetTime()) */
|
||||
WebRtc_UWord32 prev_rec_send_ts;
|
||||
|
||||
/* Arrival time for previous packet (in ms using timeGetTime()) */
|
||||
WebRtc_UWord32 prev_rec_arr_ts;
|
||||
|
||||
/* rate of previous packet, derived from RTP timestamps (in bits/s) */
|
||||
float prev_rec_rtp_rate;
|
||||
|
||||
/* Time sinse the last update of the BN estimate (in ms) */
|
||||
WebRtc_UWord32 last_update_ts;
|
||||
|
||||
/* Time sinse the last reduction (in ms) */
|
||||
WebRtc_UWord32 last_reduction_ts;
|
||||
|
||||
/* How many times the estimate was update in the beginning */
|
||||
WebRtc_Word32 count_tot_updates_rec;
|
||||
|
||||
/* The estimated bottle neck rate from there to here (in bits/s) */
|
||||
WebRtc_Word32 rec_bw;
|
||||
float rec_bw_inv;
|
||||
float rec_bw_avg;
|
||||
float rec_bw_avg_Q;
|
||||
|
||||
/* The estimated mean absolute jitter value,
|
||||
as seen on this side (in ms) */
|
||||
float rec_jitter;
|
||||
float rec_jitter_short_term;
|
||||
float rec_jitter_short_term_abs;
|
||||
float rec_max_delay;
|
||||
float rec_max_delay_avg_Q;
|
||||
|
||||
/* (assumed) bitrate for headers (bps) */
|
||||
float rec_header_rate;
|
||||
|
||||
/* The estimated bottle neck rate from here to there (in bits/s) */
|
||||
float send_bw_avg;
|
||||
|
||||
/* The estimated mean absolute jitter value, as seen on
|
||||
the other siee (in ms) */
|
||||
float send_max_delay_avg;
|
||||
|
||||
// number of packets received since last update
|
||||
int num_pkts_rec;
|
||||
|
||||
int num_consec_rec_pkts_over_30k;
|
||||
|
||||
// flag for marking that a high speed network has been
|
||||
// detected downstream
|
||||
int hsn_detect_rec;
|
||||
|
||||
int num_consec_snt_pkts_over_30k;
|
||||
|
||||
// flag for marking that a high speed network has
|
||||
// been detected upstream
|
||||
int hsn_detect_snd;
|
||||
|
||||
WebRtc_UWord32 start_wait_period;
|
||||
|
||||
int in_wait_period;
|
||||
|
||||
int change_to_WB;
|
||||
|
||||
WebRtc_UWord32 senderTimestamp;
|
||||
WebRtc_UWord32 receiverTimestamp;
|
||||
//enum IsacSamplingRate incomingStreamSampFreq;
|
||||
WebRtc_UWord16 numConsecLatePkts;
|
||||
float consecLatency;
|
||||
WebRtc_Word16 inWaitLatePkts;
|
||||
} BwEstimatorstr;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
/* boolean, flags if previous packet exceeded B.N. */
|
||||
int PrevExceed;
|
||||
/* ms */
|
||||
int ExceedAgo;
|
||||
/* packets left to send in current burst */
|
||||
int BurstCounter;
|
||||
/* packets */
|
||||
int InitCounter;
|
||||
/* ms remaining in buffer when next packet will be sent */
|
||||
double StillBuffered;
|
||||
|
||||
} RateModel;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
unsigned int SpaceAlloced;
|
||||
unsigned int MaxPermAlloced;
|
||||
double Tmp0[MAXFFTSIZE];
|
||||
double Tmp1[MAXFFTSIZE];
|
||||
double Tmp2[MAXFFTSIZE];
|
||||
double Tmp3[MAXFFTSIZE];
|
||||
int Perm[MAXFFTSIZE];
|
||||
int factor [NFACTOR];
|
||||
|
||||
} FFTstr;
|
||||
|
||||
|
||||
/* The following strutc is used to store data from encoding, to make it
|
||||
fast and easy to construct a new bitstream with a different Bandwidth
|
||||
estimate. All values (except framelength and minBytes) is double size to
|
||||
handle 60 ms of data.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
/* Used to keep track of if it is first or second part of 60 msec packet */
|
||||
int startIdx;
|
||||
|
||||
/* Frame length in samples */
|
||||
WebRtc_Word16 framelength;
|
||||
|
||||
/* Pitch Gain */
|
||||
int pitchGain_index[2];
|
||||
|
||||
/* Pitch Lag */
|
||||
double meanGain[2];
|
||||
int pitchIndex[PITCH_SUBFRAMES*2];
|
||||
|
||||
/* LPC */
|
||||
int LPCmodel[2];
|
||||
int LPCindex_s[108*2]; /* KLT_ORDER_SHAPE = 108 */
|
||||
int LPCindex_g[12*2]; /* KLT_ORDER_GAIN = 12 */
|
||||
double LPCcoeffs_lo[(ORDERLO+1)*SUBFRAMES*2];
|
||||
double LPCcoeffs_hi[(ORDERHI+1)*SUBFRAMES*2];
|
||||
|
||||
/* Encode Spec */
|
||||
WebRtc_Word16 fre[FRAMESAMPLES];
|
||||
WebRtc_Word16 fim[FRAMESAMPLES];
|
||||
WebRtc_Word16 AvgPitchGain[2];
|
||||
|
||||
/* Used in adaptive mode only */
|
||||
int minBytes;
|
||||
|
||||
} ISAC_SaveEncData_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
int indexLPCShape[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
|
||||
double lpcGain[SUBFRAMES<<1];
|
||||
int lpcGainIndex[SUBFRAMES<<1];
|
||||
|
||||
Bitstr bitStreamObj;
|
||||
|
||||
WebRtc_Word16 realFFT[FRAMESAMPLES_HALF];
|
||||
WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF];
|
||||
} ISACUBSaveEncDataStruct;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
Bitstr bitstr_obj;
|
||||
MaskFiltstr maskfiltstr_obj;
|
||||
PreFiltBankstr prefiltbankstr_obj;
|
||||
PitchFiltstr pitchfiltstr_obj;
|
||||
PitchAnalysisStruct pitchanalysisstr_obj;
|
||||
FFTstr fftstr_obj;
|
||||
ISAC_SaveEncData_t SaveEnc_obj;
|
||||
|
||||
int buffer_index;
|
||||
WebRtc_Word16 current_framesamples;
|
||||
|
||||
float data_buffer_float[FRAMESAMPLES_30ms];
|
||||
|
||||
int frame_nb;
|
||||
double bottleneck;
|
||||
WebRtc_Word16 new_framelength;
|
||||
double s2nr;
|
||||
|
||||
/* Maximum allowed number of bits for a 30 msec packet */
|
||||
WebRtc_Word16 payloadLimitBytes30;
|
||||
/* Maximum allowed number of bits for a 30 msec packet */
|
||||
WebRtc_Word16 payloadLimitBytes60;
|
||||
/* Maximum allowed number of bits for both 30 and 60 msec packet */
|
||||
WebRtc_Word16 maxPayloadBytes;
|
||||
/* Maximum allowed rate in bytes per 30 msec packet */
|
||||
WebRtc_Word16 maxRateInBytes;
|
||||
|
||||
/*---
|
||||
If set to 1 iSAC will not addapt the frame-size, if used in
|
||||
channel-adaptive mode. The initial value will be used for all rates.
|
||||
---*/
|
||||
WebRtc_Word16 enforceFrameSize;
|
||||
|
||||
/*-----
|
||||
This records the BWE index the encoder injected into the bit-stream.
|
||||
It will be used in RCU. The same BWE index of main paylaod will be in
|
||||
the redundant payload. We can not retrive it from BWE because it is
|
||||
a recursive procedure (WebRtcIsac_GetDownlinkBwJitIndexImpl) and has to be
|
||||
called only once per each encode.
|
||||
-----*/
|
||||
WebRtc_Word16 lastBWIdx;
|
||||
} ISACLBEncStruct;
|
||||
|
||||
typedef struct {
|
||||
|
||||
Bitstr bitstr_obj;
|
||||
MaskFiltstr maskfiltstr_obj;
|
||||
PreFiltBankstr prefiltbankstr_obj;
|
||||
FFTstr fftstr_obj;
|
||||
ISACUBSaveEncDataStruct SaveEnc_obj;
|
||||
|
||||
int buffer_index;
|
||||
float data_buffer_float[MAX_FRAMESAMPLES +
|
||||
LB_TOTAL_DELAY_SAMPLES];
|
||||
double bottleneck;
|
||||
/* Maximum allowed number of bits for a 30 msec packet */
|
||||
//WebRtc_Word16 payloadLimitBytes30;
|
||||
/* Maximum allowed number of bits for both 30 and 60 msec packet */
|
||||
//WebRtc_Word16 maxPayloadBytes;
|
||||
WebRtc_Word16 maxPayloadSizeBytes;
|
||||
|
||||
double lastLPCVec[UB_LPC_ORDER];
|
||||
WebRtc_Word16 numBytesUsed;
|
||||
WebRtc_Word16 lastJitterInfo;
|
||||
} ISACUBEncStruct;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
Bitstr bitstr_obj;
|
||||
MaskFiltstr maskfiltstr_obj;
|
||||
PostFiltBankstr postfiltbankstr_obj;
|
||||
PitchFiltstr pitchfiltstr_obj;
|
||||
FFTstr fftstr_obj;
|
||||
|
||||
} ISACLBDecStruct;
|
||||
|
||||
typedef struct {
|
||||
|
||||
Bitstr bitstr_obj;
|
||||
MaskFiltstr maskfiltstr_obj;
|
||||
PostFiltBankstr postfiltbankstr_obj;
|
||||
FFTstr fftstr_obj;
|
||||
|
||||
} ISACUBDecStruct;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
ISACLBEncStruct ISACencLB_obj;
|
||||
ISACLBDecStruct ISACdecLB_obj;
|
||||
} ISACLBStruct;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
ISACUBEncStruct ISACencUB_obj;
|
||||
ISACUBDecStruct ISACdecUB_obj;
|
||||
} ISACUBStruct;
|
||||
|
||||
/*
|
||||
This struct is used to take a snapshot of the entropy coder and LPC gains
|
||||
right before encoding LPC gains. This allows us to go back to that state
|
||||
if we like to limit the payload size.
|
||||
*/
|
||||
typedef struct {
|
||||
/* 6 lower-band & 6 upper-band */
|
||||
double loFiltGain[SUBFRAMES];
|
||||
double hiFiltGain[SUBFRAMES];
|
||||
/* Upper boundary of interval W */
|
||||
WebRtc_UWord32 W_upper;
|
||||
WebRtc_UWord32 streamval;
|
||||
/* Index to the current position in bytestream */
|
||||
WebRtc_UWord32 stream_index;
|
||||
WebRtc_UWord8 stream[3];
|
||||
} transcode_obj;
|
||||
|
||||
|
||||
typedef struct {
|
||||
// lower-band codec instance
|
||||
ISACLBStruct instLB;
|
||||
// upper-band codec instance
|
||||
ISACUBStruct instUB;
|
||||
|
||||
// Bandwidth Estimator and model for the rate.
|
||||
BwEstimatorstr bwestimator_obj;
|
||||
RateModel rate_data_obj;
|
||||
double MaxDelay;
|
||||
|
||||
/* 0 = adaptive; 1 = instantaneous */
|
||||
WebRtc_Word16 codingMode;
|
||||
|
||||
// overall bottleneck of the codec
|
||||
WebRtc_Word32 bottleneck;
|
||||
|
||||
// QMF Filter state
|
||||
WebRtc_Word32 analysisFBState1[FB_STATE_SIZE_WORD32];
|
||||
WebRtc_Word32 analysisFBState2[FB_STATE_SIZE_WORD32];
|
||||
WebRtc_Word32 synthesisFBState1[FB_STATE_SIZE_WORD32];
|
||||
WebRtc_Word32 synthesisFBState2[FB_STATE_SIZE_WORD32];
|
||||
|
||||
// Error Code
|
||||
WebRtc_Word16 errorCode;
|
||||
|
||||
// bandwidth of the encoded audio 8, 12 or 16 kHz
|
||||
enum ISACBandwidth bandwidthKHz;
|
||||
// Sampling rate of audio, encoder and decode, 8 or 16 kHz
|
||||
enum IsacSamplingRate encoderSamplingRateKHz;
|
||||
enum IsacSamplingRate decoderSamplingRateKHz;
|
||||
// Flag to keep track of initializations, lower & upper-band
|
||||
// encoder and decoder.
|
||||
WebRtc_Word16 initFlag;
|
||||
|
||||
// Flag to to indicate signal bandwidth switch
|
||||
WebRtc_Word16 resetFlag_8kHz;
|
||||
|
||||
// Maximum allowed rate, measured in Bytes per 30 ms.
|
||||
WebRtc_Word16 maxRateBytesPer30Ms;
|
||||
// Maximum allowed payload-size, measured in Bytes.
|
||||
WebRtc_Word16 maxPayloadSizeBytes;
|
||||
} ISACMainStruct;
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_ */
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
#include "fft.h"
|
||||
#include "codec.h"
|
||||
#include "os_specific_inline.h"
|
||||
#include <math.h>
|
||||
|
||||
static double costab1[FRAMESAMPLES_HALF];
|
||||
static double sintab1[FRAMESAMPLES_HALF];
|
||||
static double costab2[FRAMESAMPLES_QUARTER];
|
||||
static double sintab2[FRAMESAMPLES_QUARTER];
|
||||
|
||||
void WebRtcIsac_InitTransform()
|
||||
{
|
||||
int k;
|
||||
double fact, phase;
|
||||
|
||||
fact = PI / (FRAMESAMPLES_HALF);
|
||||
phase = 0.0;
|
||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||
costab1[k] = cos(phase);
|
||||
sintab1[k] = sin(phase);
|
||||
phase += fact;
|
||||
}
|
||||
|
||||
fact = PI * ((double) (FRAMESAMPLES_HALF - 1)) / ((double) FRAMESAMPLES_HALF);
|
||||
phase = 0.5 * fact;
|
||||
for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
|
||||
costab2[k] = cos(phase);
|
||||
sintab2[k] = sin(phase);
|
||||
phase += fact;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_Time2Spec(double *inre1,
|
||||
double *inre2,
|
||||
WebRtc_Word16 *outreQ7,
|
||||
WebRtc_Word16 *outimQ7,
|
||||
FFTstr *fftstr_obj)
|
||||
{
|
||||
|
||||
int k;
|
||||
int dims[1];
|
||||
double tmp1r, tmp1i, xr, xi, yr, yi, fact;
|
||||
double tmpre[FRAMESAMPLES_HALF], tmpim[FRAMESAMPLES_HALF];
|
||||
|
||||
|
||||
dims[0] = FRAMESAMPLES_HALF;
|
||||
|
||||
|
||||
/* Multiply with complex exponentials and combine into one complex vector */
|
||||
fact = 0.5 / sqrt(FRAMESAMPLES_HALF);
|
||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||
tmp1r = costab1[k];
|
||||
tmp1i = sintab1[k];
|
||||
tmpre[k] = (inre1[k] * tmp1r + inre2[k] * tmp1i) * fact;
|
||||
tmpim[k] = (inre2[k] * tmp1r - inre1[k] * tmp1i) * fact;
|
||||
}
|
||||
|
||||
|
||||
/* Get DFT */
|
||||
WebRtcIsac_Fftns(1, dims, tmpre, tmpim, -1, 1.0, fftstr_obj);
|
||||
|
||||
/* Use symmetry to separate into two complex vectors and center frames in time around zero */
|
||||
for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
|
||||
xr = tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k];
|
||||
yi = -tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k];
|
||||
xi = tmpim[k] - tmpim[FRAMESAMPLES_HALF - 1 - k];
|
||||
yr = tmpim[k] + tmpim[FRAMESAMPLES_HALF - 1 - k];
|
||||
|
||||
tmp1r = costab2[k];
|
||||
tmp1i = sintab2[k];
|
||||
outreQ7[k] = (WebRtc_Word16)WebRtcIsac_lrint((xr * tmp1r - xi * tmp1i) * 128.0);
|
||||
outimQ7[k] = (WebRtc_Word16)WebRtcIsac_lrint((xr * tmp1i + xi * tmp1r) * 128.0);
|
||||
outreQ7[FRAMESAMPLES_HALF - 1 - k] = (WebRtc_Word16)WebRtcIsac_lrint((-yr * tmp1i - yi * tmp1r) * 128.0);
|
||||
outimQ7[FRAMESAMPLES_HALF - 1 - k] = (WebRtc_Word16)WebRtcIsac_lrint((-yr * tmp1r + yi * tmp1i) * 128.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_Spec2time(double *inre, double *inim, double *outre1, double *outre2, FFTstr *fftstr_obj)
|
||||
{
|
||||
|
||||
int k;
|
||||
double tmp1r, tmp1i, xr, xi, yr, yi, fact;
|
||||
|
||||
int dims;
|
||||
|
||||
dims = FRAMESAMPLES_HALF;
|
||||
|
||||
for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
|
||||
/* Move zero in time to beginning of frames */
|
||||
tmp1r = costab2[k];
|
||||
tmp1i = sintab2[k];
|
||||
xr = inre[k] * tmp1r + inim[k] * tmp1i;
|
||||
xi = inim[k] * tmp1r - inre[k] * tmp1i;
|
||||
yr = -inim[FRAMESAMPLES_HALF - 1 - k] * tmp1r - inre[FRAMESAMPLES_HALF - 1 - k] * tmp1i;
|
||||
yi = -inre[FRAMESAMPLES_HALF - 1 - k] * tmp1r + inim[FRAMESAMPLES_HALF - 1 - k] * tmp1i;
|
||||
|
||||
/* Combine into one vector, z = x + j * y */
|
||||
outre1[k] = xr - yi;
|
||||
outre1[FRAMESAMPLES_HALF - 1 - k] = xr + yi;
|
||||
outre2[k] = xi + yr;
|
||||
outre2[FRAMESAMPLES_HALF - 1 - k] = -xi + yr;
|
||||
}
|
||||
|
||||
|
||||
/* Get IDFT */
|
||||
WebRtcIsac_Fftns(1, &dims, outre1, outre2, 1, FRAMESAMPLES_HALF, fftstr_obj);
|
||||
|
||||
|
||||
/* Demodulate and separate */
|
||||
fact = sqrt(FRAMESAMPLES_HALF);
|
||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||
tmp1r = costab1[k];
|
||||
tmp1i = sintab1[k];
|
||||
xr = (outre1[k] * tmp1r - outre2[k] * tmp1i) * fact;
|
||||
outre2[k] = (outre2[k] * tmp1r + outre1[k] * tmp1i) * fact;
|
||||
outre1[k] = xr;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_AutoCorrToReflCoef().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRtc_Word16 *K)
|
||||
{
|
||||
int i, n;
|
||||
WebRtc_Word16 tmp;
|
||||
G_CONST WebRtc_Word32 *rptr;
|
||||
WebRtc_Word32 L_num, L_den;
|
||||
WebRtc_Word16 *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER],
|
||||
P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER];
|
||||
|
||||
// Initialize loop and pointers.
|
||||
acfptr = ACF;
|
||||
rptr = R;
|
||||
pptr = P;
|
||||
p1ptr = &P[1];
|
||||
w1ptr = &W[1];
|
||||
wptr = w1ptr;
|
||||
|
||||
// First loop; n=0. Determine shifting.
|
||||
tmp = WebRtcSpl_NormW32(*R);
|
||||
*acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);
|
||||
*pptr++ = *acfptr++;
|
||||
|
||||
// Initialize ACF, P and W.
|
||||
for (i = 1; i <= use_order; i++)
|
||||
{
|
||||
*acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);
|
||||
*wptr++ = *acfptr;
|
||||
*pptr++ = *acfptr++;
|
||||
}
|
||||
|
||||
// Compute reflection coefficients.
|
||||
for (n = 1; n <= use_order; n++, K++)
|
||||
{
|
||||
tmp = WEBRTC_SPL_ABS_W16(*p1ptr);
|
||||
if (*P < tmp)
|
||||
{
|
||||
for (i = n; i <= use_order; i++)
|
||||
*K++ = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Division: WebRtcSpl_div(tmp, *P)
|
||||
*K = 0;
|
||||
if (tmp != 0)
|
||||
{
|
||||
L_num = tmp;
|
||||
L_den = *P;
|
||||
i = 15;
|
||||
while (i--)
|
||||
{
|
||||
(*K) <<= 1;
|
||||
L_num <<= 1;
|
||||
if (L_num >= L_den)
|
||||
{
|
||||
L_num -= L_den;
|
||||
(*K)++;
|
||||
}
|
||||
}
|
||||
if (*p1ptr > 0)
|
||||
*K = -*K;
|
||||
}
|
||||
|
||||
// Last iteration; don't do Schur recursion.
|
||||
if (n == use_order)
|
||||
return;
|
||||
|
||||
// Schur recursion.
|
||||
pptr = P;
|
||||
wptr = w1ptr;
|
||||
tmp = (WebRtc_Word16)(((WebRtc_Word32)*p1ptr * (WebRtc_Word32)*K + 16384) >> 15);
|
||||
*pptr = WEBRTC_SPL_ADD_SAT_W16( *pptr, tmp );
|
||||
pptr++;
|
||||
for (i = 1; i <= use_order - n; i++)
|
||||
{
|
||||
tmp = (WebRtc_Word16)(((WebRtc_Word32)*wptr * (WebRtc_Word32)*K + 16384) >> 15);
|
||||
*pptr = WEBRTC_SPL_ADD_SAT_W16( *(pptr+1), tmp );
|
||||
pptr++;
|
||||
tmp = (WebRtc_Word16)(((WebRtc_Word32)*pptr * (WebRtc_Word32)*K + 16384) >> 15);
|
||||
*wptr = WEBRTC_SPL_ADD_SAT_W16( *wptr, tmp );
|
||||
wptr++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_AutoCorrelation().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* in_vector,
|
||||
int in_vector_length,
|
||||
int order,
|
||||
WebRtc_Word32* result,
|
||||
int* scale)
|
||||
{
|
||||
WebRtc_Word32 sum;
|
||||
int i, j;
|
||||
WebRtc_Word16 smax; // Sample max
|
||||
G_CONST WebRtc_Word16* xptr1;
|
||||
G_CONST WebRtc_Word16* xptr2;
|
||||
WebRtc_Word32* resultptr;
|
||||
int scaling = 0;
|
||||
|
||||
#ifdef _ARM_OPT_
|
||||
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
|
||||
WebRtc_Word16 loops4;
|
||||
#endif
|
||||
|
||||
if (order < 0)
|
||||
order = in_vector_length;
|
||||
|
||||
// Find the max. sample
|
||||
smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length);
|
||||
|
||||
// In order to avoid overflow when computing the sum we should scale the samples so that
|
||||
// (in_vector_length * smax * smax) will not overflow.
|
||||
|
||||
if (smax == 0)
|
||||
{
|
||||
scaling = 0;
|
||||
} else
|
||||
{
|
||||
int nbits = WebRtcSpl_GetSizeInBits(in_vector_length); // # of bits in the sum loop
|
||||
int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); // # of bits to normalize smax
|
||||
|
||||
if (t > nbits)
|
||||
{
|
||||
scaling = 0;
|
||||
} else
|
||||
{
|
||||
scaling = nbits - t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resultptr = result;
|
||||
|
||||
// Perform the actual correlation calculation
|
||||
for (i = 0; i < order + 1; i++)
|
||||
{
|
||||
int loops = (in_vector_length - i);
|
||||
sum = 0;
|
||||
xptr1 = in_vector;
|
||||
xptr2 = &in_vector[i];
|
||||
#ifndef _ARM_OPT_
|
||||
for (j = loops; j > 0; j--)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1++, *xptr2++, scaling);
|
||||
}
|
||||
#else
|
||||
loops4 = (loops >> 2) << 2;
|
||||
|
||||
if (scaling == 0)
|
||||
{
|
||||
for (j = 0; j < loops4; j = j + 4)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
}
|
||||
|
||||
for (j = loops4; j < loops; j++)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < loops4; j = j + 4)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
}
|
||||
|
||||
for (j = loops4; j < loops; j++)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
*resultptr++ = sum;
|
||||
}
|
||||
|
||||
*scale = scaling;
|
||||
|
||||
return order + 1;
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
/* Tables for data buffer indexes that are bit reversed and thus need to be
|
||||
* swapped. Note that, index_7[{0, 2, 4, ...}] are for the left side of the swap
|
||||
* operations, while index_7[{1, 3, 5, ...}] are for the right side of the
|
||||
* operation. Same for index_8.
|
||||
*/
|
||||
|
||||
/* Indexes for the case of stages == 7. */
|
||||
static const int16_t index_7[112] = {
|
||||
1, 64, 2, 32, 3, 96, 4, 16, 5, 80, 6, 48, 7, 112, 9, 72, 10, 40, 11, 104,
|
||||
12, 24, 13, 88, 14, 56, 15, 120, 17, 68, 18, 36, 19, 100, 21, 84, 22, 52,
|
||||
23, 116, 25, 76, 26, 44, 27, 108, 29, 92, 30, 60, 31, 124, 33, 66, 35, 98,
|
||||
37, 82, 38, 50, 39, 114, 41, 74, 43, 106, 45, 90, 46, 58, 47, 122, 49, 70,
|
||||
51, 102, 53, 86, 55, 118, 57, 78, 59, 110, 61, 94, 63, 126, 67, 97, 69,
|
||||
81, 71, 113, 75, 105, 77, 89, 79, 121, 83, 101, 87, 117, 91, 109, 95, 125,
|
||||
103, 115, 111, 123
|
||||
};
|
||||
|
||||
/* Indexes for the case of stages == 8. */
|
||||
static const int16_t index_8[240] = {
|
||||
1, 128, 2, 64, 3, 192, 4, 32, 5, 160, 6, 96, 7, 224, 8, 16, 9, 144, 10, 80,
|
||||
11, 208, 12, 48, 13, 176, 14, 112, 15, 240, 17, 136, 18, 72, 19, 200, 20,
|
||||
40, 21, 168, 22, 104, 23, 232, 25, 152, 26, 88, 27, 216, 28, 56, 29, 184,
|
||||
30, 120, 31, 248, 33, 132, 34, 68, 35, 196, 37, 164, 38, 100, 39, 228, 41,
|
||||
148, 42, 84, 43, 212, 44, 52, 45, 180, 46, 116, 47, 244, 49, 140, 50, 76,
|
||||
51, 204, 53, 172, 54, 108, 55, 236, 57, 156, 58, 92, 59, 220, 61, 188, 62,
|
||||
124, 63, 252, 65, 130, 67, 194, 69, 162, 70, 98, 71, 226, 73, 146, 74, 82,
|
||||
75, 210, 77, 178, 78, 114, 79, 242, 81, 138, 83, 202, 85, 170, 86, 106, 87,
|
||||
234, 89, 154, 91, 218, 93, 186, 94, 122, 95, 250, 97, 134, 99, 198, 101,
|
||||
166, 103, 230, 105, 150, 107, 214, 109, 182, 110, 118, 111, 246, 113, 142,
|
||||
115, 206, 117, 174, 119, 238, 121, 158, 123, 222, 125, 190, 127, 254, 131,
|
||||
193, 133, 161, 135, 225, 137, 145, 139, 209, 141, 177, 143, 241, 147, 201,
|
||||
149, 169, 151, 233, 155, 217, 157, 185, 159, 249, 163, 197, 167, 229, 171,
|
||||
213, 173, 181, 175, 245, 179, 205, 183, 237, 187, 221, 191, 253, 199, 227,
|
||||
203, 211, 207, 243, 215, 235, 223, 251, 239, 247
|
||||
};
|
||||
|
||||
void WebRtcSpl_ComplexBitReverse(int16_t* __restrict complex_data, int stages) {
|
||||
/* For any specific value of stages, we know exactly the indexes that are
|
||||
* bit reversed. Currently (Feb. 2012) in WebRTC the only possible values of
|
||||
* stages are 7 and 8, so we use tables to save unnecessary iterations and
|
||||
* calculations for these two cases.
|
||||
*/
|
||||
if (stages == 7 || stages == 8) {
|
||||
int m = 0;
|
||||
int length = 112;
|
||||
const int16_t* index = index_7;
|
||||
|
||||
if (stages == 8) {
|
||||
length = 240;
|
||||
index = index_8;
|
||||
}
|
||||
|
||||
/* Decimation in time. Swap the elements with bit-reversed indexes. */
|
||||
for (m = 0; m < length; m += 2) {
|
||||
/* We declare a int32_t* type pointer, to load both the 16-bit real
|
||||
* and imaginary elements from complex_data in one instruction, reducing
|
||||
* complexity.
|
||||
*/
|
||||
int32_t* complex_data_ptr = (int32_t*)complex_data;
|
||||
int32_t temp = 0;
|
||||
|
||||
temp = complex_data_ptr[index[m]]; /* Real and imaginary */
|
||||
complex_data_ptr[index[m]] = complex_data_ptr[index[m + 1]];
|
||||
complex_data_ptr[index[m + 1]] = temp;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int m = 0, mr = 0, l = 0;
|
||||
int n = 1 << stages;
|
||||
int nn = n - 1;
|
||||
|
||||
/* Decimation in time - re-order data */
|
||||
for (m = 1; m <= nn; ++m) {
|
||||
int32_t* complex_data_ptr = (int32_t*)complex_data;
|
||||
int32_t temp = 0;
|
||||
|
||||
/* Find out indexes that are bit-reversed. */
|
||||
l = n;
|
||||
do {
|
||||
l >>= 1;
|
||||
} while (l > nn - mr);
|
||||
mr = (mr & (l - 1)) + l;
|
||||
|
||||
if (mr <= m) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Swap the elements with bit-reversed indexes.
|
||||
* This is similar to the loop in the stages == 7 or 8 cases.
|
||||
*/
|
||||
temp = complex_data_ptr[m]; /* Real and imaginary */
|
||||
complex_data_ptr[m] = complex_data_ptr[mr];
|
||||
complex_data_ptr[mr] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,425 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_ComplexFFT().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
#define CFFTSFT 14
|
||||
#define CFFTRND 1
|
||||
#define CFFTRND2 16384
|
||||
|
||||
#define CIFFTSFT 14
|
||||
#define CIFFTRND 1
|
||||
|
||||
static const WebRtc_Word16 kSinTable1024[] = {
|
||||
0, 201, 402, 603, 804, 1005, 1206, 1406,
|
||||
1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011,
|
||||
3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608,
|
||||
4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195,
|
||||
6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766,
|
||||
7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319,
|
||||
9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849,
|
||||
11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353,
|
||||
12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827,
|
||||
14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268,
|
||||
15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672,
|
||||
16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036,
|
||||
18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357,
|
||||
19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631,
|
||||
20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855,
|
||||
22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027,
|
||||
23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143,
|
||||
24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201,
|
||||
25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198,
|
||||
26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132,
|
||||
27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001,
|
||||
28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802,
|
||||
28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534,
|
||||
29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195,
|
||||
30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783,
|
||||
30851, 30918, 30984, 31049,
|
||||
31113, 31175, 31236, 31297,
|
||||
31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735,
|
||||
31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097,
|
||||
32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382,
|
||||
32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588,
|
||||
32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717,
|
||||
32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766,
|
||||
32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736,
|
||||
32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628,
|
||||
32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441,
|
||||
32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176,
|
||||
32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833,
|
||||
31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413,
|
||||
31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918,
|
||||
30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349,
|
||||
30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706,
|
||||
29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992,
|
||||
28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208,
|
||||
28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355,
|
||||
27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437,
|
||||
26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456,
|
||||
25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413,
|
||||
24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311,
|
||||
23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153,
|
||||
22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942,
|
||||
20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680,
|
||||
19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371,
|
||||
18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017,
|
||||
16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623,
|
||||
15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191,
|
||||
14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724,
|
||||
12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227,
|
||||
11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703,
|
||||
9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156,
|
||||
7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589,
|
||||
6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006,
|
||||
4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411,
|
||||
3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808,
|
||||
1607, 1406, 1206, 1005, 804, 603, 402, 201,
|
||||
0, -201, -402, -603, -804, -1005, -1206, -1406,
|
||||
-1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011,
|
||||
-3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608,
|
||||
-4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195,
|
||||
-6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766,
|
||||
-7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319,
|
||||
-9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849,
|
||||
-11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353,
|
||||
-12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827,
|
||||
-14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268,
|
||||
-15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672,
|
||||
-16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036,
|
||||
-18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357,
|
||||
-19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631,
|
||||
-20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855,
|
||||
-22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027,
|
||||
-23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143,
|
||||
-24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201,
|
||||
-25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198,
|
||||
-26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132,
|
||||
-27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001,
|
||||
-28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802,
|
||||
-28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534,
|
||||
-29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195,
|
||||
-30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783,
|
||||
-30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297,
|
||||
-31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735,
|
||||
-31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097,
|
||||
-32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382,
|
||||
-32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588,
|
||||
-32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717,
|
||||
-32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766,
|
||||
-32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736,
|
||||
-32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628,
|
||||
-32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441,
|
||||
-32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176,
|
||||
-32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833,
|
||||
-31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413,
|
||||
-31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918,
|
||||
-30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349,
|
||||
-30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706,
|
||||
-29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992,
|
||||
-28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208,
|
||||
-28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355,
|
||||
-27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437,
|
||||
-26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456,
|
||||
-25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413,
|
||||
-24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311,
|
||||
-23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153,
|
||||
-22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942,
|
||||
-20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680,
|
||||
-19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371,
|
||||
-18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017,
|
||||
-16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623,
|
||||
-15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191,
|
||||
-14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724,
|
||||
-12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227,
|
||||
-11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703,
|
||||
-9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156,
|
||||
-7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589,
|
||||
-6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006,
|
||||
-4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411,
|
||||
-3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808,
|
||||
-1607, -1406, -1206, -1005, -804, -603, -402, -201
|
||||
};
|
||||
|
||||
int WebRtcSpl_ComplexFFT(WebRtc_Word16 frfi[], int stages, int mode)
|
||||
{
|
||||
int i, j, l, k, istep, n, m;
|
||||
WebRtc_Word16 wr, wi;
|
||||
WebRtc_Word32 tr32, ti32, qr32, qi32;
|
||||
|
||||
/* The 1024-value is a constant given from the size of kSinTable1024[],
|
||||
* and should not be changed depending on the input parameter 'stages'
|
||||
*/
|
||||
n = 1 << stages;
|
||||
if (n > 1024)
|
||||
return -1;
|
||||
|
||||
l = 1;
|
||||
k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change
|
||||
depending on the input parameter 'stages' */
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
// mode==0: Low-complexity and Low-accuracy mode
|
||||
while (l < n)
|
||||
{
|
||||
istep = l << 1;
|
||||
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = kSinTable1024[j + 256];
|
||||
wi = -kSinTable1024[j];
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
|
||||
- WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1])), 15);
|
||||
|
||||
ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
|
||||
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j])), 15);
|
||||
|
||||
qr32 = (WebRtc_Word32)frfi[2 * i];
|
||||
qi32 = (WebRtc_Word32)frfi[2 * i + 1];
|
||||
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, 1);
|
||||
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, 1);
|
||||
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, 1);
|
||||
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, 1);
|
||||
}
|
||||
}
|
||||
|
||||
--k;
|
||||
l = istep;
|
||||
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
// mode==1: High-complexity and High-accuracy mode
|
||||
while (l < n)
|
||||
{
|
||||
istep = l << 1;
|
||||
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = kSinTable1024[j + 256];
|
||||
wi = -kSinTable1024[j];
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7A
|
||||
WebRtc_Word32 wri;
|
||||
WebRtc_Word32 frfi_r;
|
||||
__asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
|
||||
"r"((WebRtc_Word32)wr), "r"((WebRtc_Word32)wi));
|
||||
#endif
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7A
|
||||
__asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(frfi_r) :
|
||||
"r"((WebRtc_Word32)frfi[2*j]), "r"((WebRtc_Word32)frfi[2*j +1]));
|
||||
__asm__("smlsd %0, %1, %2, %3" : "=r"(tr32) :
|
||||
"r"(wri), "r"(frfi_r), "r"(CFFTRND));
|
||||
__asm__("smladx %0, %1, %2, %3" : "=r"(ti32) :
|
||||
"r"(wri), "r"(frfi_r), "r"(CFFTRND));
|
||||
|
||||
#else
|
||||
tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
|
||||
- WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CFFTRND;
|
||||
|
||||
ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
|
||||
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND;
|
||||
#endif
|
||||
|
||||
tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CFFTSFT);
|
||||
ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CFFTSFT);
|
||||
|
||||
qr32 = ((WebRtc_Word32)frfi[2 * i]) << CFFTSFT;
|
||||
qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CFFTSFT;
|
||||
|
||||
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qr32 - tr32 + CFFTRND2), 1 + CFFTSFT);
|
||||
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qi32 - ti32 + CFFTRND2), 1 + CFFTSFT);
|
||||
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qr32 + tr32 + CFFTRND2), 1 + CFFTSFT);
|
||||
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qi32 + ti32 + CFFTRND2), 1 + CFFTSFT);
|
||||
}
|
||||
}
|
||||
|
||||
--k;
|
||||
l = istep;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtcSpl_ComplexIFFT(WebRtc_Word16 frfi[], int stages, int mode)
|
||||
{
|
||||
int i, j, l, k, istep, n, m, scale, shift;
|
||||
WebRtc_Word16 wr, wi;
|
||||
WebRtc_Word32 tr32, ti32, qr32, qi32;
|
||||
WebRtc_Word32 tmp32, round2;
|
||||
|
||||
/* The 1024-value is a constant given from the size of kSinTable1024[],
|
||||
* and should not be changed depending on the input parameter 'stages'
|
||||
*/
|
||||
n = 1 << stages;
|
||||
if (n > 1024)
|
||||
return -1;
|
||||
|
||||
scale = 0;
|
||||
|
||||
l = 1;
|
||||
k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change
|
||||
depending on the input parameter 'stages' */
|
||||
|
||||
while (l < n)
|
||||
{
|
||||
// variable scaling, depending upon data
|
||||
shift = 0;
|
||||
round2 = 8192;
|
||||
|
||||
tmp32 = (WebRtc_Word32)WebRtcSpl_MaxAbsValueW16(frfi, 2 * n);
|
||||
if (tmp32 > 13573)
|
||||
{
|
||||
shift++;
|
||||
scale++;
|
||||
round2 <<= 1;
|
||||
}
|
||||
if (tmp32 > 27146)
|
||||
{
|
||||
shift++;
|
||||
scale++;
|
||||
round2 <<= 1;
|
||||
}
|
||||
|
||||
istep = l << 1;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
// mode==0: Low-complexity and Low-accuracy mode
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = kSinTable1024[j + 256];
|
||||
wi = kSinTable1024[j];
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0)
|
||||
- WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0)), 15);
|
||||
|
||||
ti32 = WEBRTC_SPL_RSHIFT_W32(
|
||||
(WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0)
|
||||
+ WEBRTC_SPL_MUL_16_16_RSFT(wi,frfi[2*j],0)), 15);
|
||||
|
||||
qr32 = (WebRtc_Word32)frfi[2 * i];
|
||||
qi32 = (WebRtc_Word32)frfi[2 * i + 1];
|
||||
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, shift);
|
||||
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, shift);
|
||||
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, shift);
|
||||
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, shift);
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
// mode==1: High-complexity and High-accuracy mode
|
||||
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = kSinTable1024[j + 256];
|
||||
wi = kSinTable1024[j];
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7A
|
||||
WebRtc_Word32 wri;
|
||||
WebRtc_Word32 frfi_r;
|
||||
__asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
|
||||
"r"((WebRtc_Word32)wr), "r"((WebRtc_Word32)wi));
|
||||
#endif
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7A
|
||||
__asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(frfi_r) :
|
||||
"r"((WebRtc_Word32)frfi[2*j]), "r"((WebRtc_Word32)frfi[2*j +1]));
|
||||
__asm__("smlsd %0, %1, %2, %3" : "=r"(tr32) :
|
||||
"r"(wri), "r"(frfi_r), "r"(CIFFTRND));
|
||||
__asm__("smladx %0, %1, %2, %3" : "=r"(ti32) :
|
||||
"r"(wri), "r"(frfi_r), "r"(CIFFTRND));
|
||||
#else
|
||||
|
||||
tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
|
||||
- WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CIFFTRND;
|
||||
|
||||
ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
|
||||
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CIFFTRND;
|
||||
#endif
|
||||
tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CIFFTSFT);
|
||||
ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CIFFTSFT);
|
||||
|
||||
qr32 = ((WebRtc_Word32)frfi[2 * i]) << CIFFTSFT;
|
||||
qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CIFFTSFT;
|
||||
|
||||
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 - tr32+round2),
|
||||
shift+CIFFTSFT);
|
||||
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qi32 - ti32 + round2), shift + CIFFTSFT);
|
||||
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 + tr32 + round2),
|
||||
shift + CIFFTSFT);
|
||||
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qi32 + ti32 + round2), shift + CIFFTSFT);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
--k;
|
||||
l = istep;
|
||||
}
|
||||
return scale;
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the implementation of functions
|
||||
* WebRtcSpl_MemSetW16()
|
||||
* WebRtcSpl_MemSetW32()
|
||||
* WebRtcSpl_MemCpyReversedOrder()
|
||||
* WebRtcSpl_CopyFromEndW16()
|
||||
* WebRtcSpl_ZerosArrayW16()
|
||||
* WebRtcSpl_ZerosArrayW32()
|
||||
* WebRtcSpl_OnesArrayW16()
|
||||
* WebRtcSpl_OnesArrayW32()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
|
||||
void WebRtcSpl_MemSetW16(WebRtc_Word16 *ptr, WebRtc_Word16 set_value, int length)
|
||||
{
|
||||
int j;
|
||||
WebRtc_Word16 *arrptr = ptr;
|
||||
|
||||
for (j = length; j > 0; j--)
|
||||
{
|
||||
*arrptr++ = set_value;
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_MemSetW32(WebRtc_Word32 *ptr, WebRtc_Word32 set_value, int length)
|
||||
{
|
||||
int j;
|
||||
WebRtc_Word32 *arrptr = ptr;
|
||||
|
||||
for (j = length; j > 0; j--)
|
||||
{
|
||||
*arrptr++ = set_value;
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* dest, WebRtc_Word16* source, int length)
|
||||
{
|
||||
int j;
|
||||
WebRtc_Word16* destPtr = dest;
|
||||
WebRtc_Word16* sourcePtr = source;
|
||||
|
||||
for (j = 0; j < length; j++)
|
||||
{
|
||||
*destPtr-- = *sourcePtr++;
|
||||
}
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16 *vector_in,
|
||||
WebRtc_Word16 length,
|
||||
WebRtc_Word16 samples,
|
||||
WebRtc_Word16 *vector_out)
|
||||
{
|
||||
// Copy the last <samples> of the input vector to vector_out
|
||||
WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[length - samples], samples);
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_ZerosArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtcSpl_MemSetW16(vector, 0, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_ZerosArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtcSpl_MemSetW32(vector, 0, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_OnesArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word16 i;
|
||||
WebRtc_Word16 *tmpvec = vector;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
*tmpvec++ = 1;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_OnesArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word16 i;
|
||||
WebRtc_Word32 *tmpvec = vector;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
*tmpvec++ = 1;
|
||||
}
|
||||
return length;
|
||||
}
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_CrossCorrelation().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
/* TODO(kma): Clean up the code in this file, and break it up for
|
||||
* various platforms (Xscale, ARM/Neon etc.).
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_correlation, WebRtc_Word16* seq1,
|
||||
WebRtc_Word16* seq2, WebRtc_Word16 dim_seq,
|
||||
WebRtc_Word16 dim_cross_correlation,
|
||||
WebRtc_Word16 right_shifts,
|
||||
WebRtc_Word16 step_seq2)
|
||||
{
|
||||
int i, j;
|
||||
WebRtc_Word16* seq1Ptr;
|
||||
WebRtc_Word16* seq2Ptr;
|
||||
WebRtc_Word32* CrossCorrPtr;
|
||||
|
||||
#ifdef _XSCALE_OPT_
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma message("NOTE: _XSCALE_OPT_ optimizations are used (overrides _ARM_OPT_ and requires /QRxscale compiler flag)")
|
||||
#endif
|
||||
|
||||
__int64 macc40;
|
||||
|
||||
int iseq1[250];
|
||||
int iseq2[250];
|
||||
int iseq3[250];
|
||||
int * iseq1Ptr;
|
||||
int * iseq2Ptr;
|
||||
int * iseq3Ptr;
|
||||
int len, i_len;
|
||||
|
||||
seq1Ptr = seq1;
|
||||
iseq1Ptr = iseq1;
|
||||
for(i = 0; i < ((dim_seq + 1) >> 1); i++)
|
||||
{
|
||||
*iseq1Ptr = (unsigned short)*seq1Ptr++;
|
||||
*iseq1Ptr++ |= (WebRtc_Word32)*seq1Ptr++ << 16;
|
||||
|
||||
}
|
||||
|
||||
if(dim_seq%2)
|
||||
{
|
||||
*(iseq1Ptr-1) &= 0x0000ffff;
|
||||
}
|
||||
*iseq1Ptr = 0;
|
||||
iseq1Ptr++;
|
||||
*iseq1Ptr = 0;
|
||||
iseq1Ptr++;
|
||||
*iseq1Ptr = 0;
|
||||
|
||||
if(step_seq2 < 0)
|
||||
{
|
||||
seq2Ptr = seq2 - dim_cross_correlation + 1;
|
||||
CrossCorrPtr = &cross_correlation[dim_cross_correlation - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
seq2Ptr = seq2;
|
||||
CrossCorrPtr = cross_correlation;
|
||||
}
|
||||
|
||||
len = dim_seq + dim_cross_correlation - 1;
|
||||
i_len = (len + 1) >> 1;
|
||||
iseq2Ptr = iseq2;
|
||||
|
||||
iseq3Ptr = iseq3;
|
||||
for(i = 0; i < i_len; i++)
|
||||
{
|
||||
*iseq2Ptr = (unsigned short)*seq2Ptr++;
|
||||
*iseq3Ptr = (unsigned short)*seq2Ptr;
|
||||
*iseq2Ptr++ |= (WebRtc_Word32)*seq2Ptr++ << 16;
|
||||
*iseq3Ptr++ |= (WebRtc_Word32)*seq2Ptr << 16;
|
||||
}
|
||||
|
||||
if(len % 2)
|
||||
{
|
||||
iseq2[i_len - 1] &= 0x0000ffff;
|
||||
iseq3[i_len - 1] = 0;
|
||||
}
|
||||
else
|
||||
iseq3[i_len - 1] &= 0x0000ffff;
|
||||
|
||||
iseq2[i_len] = 0;
|
||||
iseq3[i_len] = 0;
|
||||
iseq2[i_len + 1] = 0;
|
||||
iseq3[i_len + 1] = 0;
|
||||
iseq2[i_len + 2] = 0;
|
||||
iseq3[i_len + 2] = 0;
|
||||
|
||||
// Set pointer to start value
|
||||
iseq2Ptr = iseq2;
|
||||
iseq3Ptr = iseq3;
|
||||
|
||||
i_len = (dim_seq + 7) >> 3;
|
||||
for (i = 0; i < dim_cross_correlation; i++)
|
||||
{
|
||||
|
||||
iseq1Ptr = iseq1;
|
||||
|
||||
macc40 = 0;
|
||||
|
||||
_WriteCoProcessor(macc40, 0);
|
||||
|
||||
if((i & 1))
|
||||
{
|
||||
iseq3Ptr = iseq3 + (i >> 1);
|
||||
for (j = i_len; j > 0; j--)
|
||||
{
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iseq2Ptr = iseq2 + (i >> 1);
|
||||
for (j = i_len; j > 0; j--)
|
||||
{
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
macc40 = _ReadCoProcessor(0);
|
||||
*CrossCorrPtr = (WebRtc_Word32)(macc40 >> right_shifts);
|
||||
CrossCorrPtr += step_seq2;
|
||||
}
|
||||
#else // #ifdef _XSCALE_OPT_
|
||||
#ifdef _ARM_OPT_
|
||||
WebRtc_Word16 dim_seq8 = (dim_seq >> 3) << 3;
|
||||
#endif
|
||||
|
||||
CrossCorrPtr = cross_correlation;
|
||||
|
||||
for (i = 0; i < dim_cross_correlation; i++)
|
||||
{
|
||||
// Set the pointer to the static vector, set the pointer to the sliding vector
|
||||
// and initialize cross_correlation
|
||||
seq1Ptr = seq1;
|
||||
seq2Ptr = seq2 + (step_seq2 * i);
|
||||
(*CrossCorrPtr) = 0;
|
||||
|
||||
#ifndef _ARM_OPT_
|
||||
#ifdef _WIN32
|
||||
#pragma message("NOTE: default implementation is used")
|
||||
#endif
|
||||
// Perform the cross correlation
|
||||
for (j = 0; j < dim_seq; j++)
|
||||
{
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
}
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
|
||||
#endif
|
||||
if (right_shifts == 0)
|
||||
{
|
||||
// Perform the optimized cross correlation
|
||||
for (j = 0; j < dim_seq8; j = j + 8)
|
||||
{
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
}
|
||||
|
||||
for (j = dim_seq8; j < dim_seq; j++)
|
||||
{
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
}
|
||||
}
|
||||
else // right_shifts != 0
|
||||
|
||||
{
|
||||
// Perform the optimized cross correlation
|
||||
for (j = 0; j < dim_seq8; j = j + 8)
|
||||
{
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
}
|
||||
|
||||
for (j = dim_seq8; j < dim_seq; j++)
|
||||
{
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
CrossCorrPtr++;
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains implementations of the divisions
|
||||
* WebRtcSpl_DivU32U16()
|
||||
* WebRtcSpl_DivW32W16()
|
||||
* WebRtcSpl_DivW32W16ResW16()
|
||||
* WebRtcSpl_DivResultInQ31()
|
||||
* WebRtcSpl_DivW32HiLow()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den)
|
||||
{
|
||||
// Guard against division with 0
|
||||
if (den != 0)
|
||||
{
|
||||
return (WebRtc_UWord32)(num / den);
|
||||
} else
|
||||
{
|
||||
return (WebRtc_UWord32)0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den)
|
||||
{
|
||||
// Guard against division with 0
|
||||
if (den != 0)
|
||||
{
|
||||
return (WebRtc_Word32)(num / den);
|
||||
} else
|
||||
{
|
||||
return (WebRtc_Word32)0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den)
|
||||
{
|
||||
// Guard against division with 0
|
||||
if (den != 0)
|
||||
{
|
||||
return (WebRtc_Word16)(num / den);
|
||||
} else
|
||||
{
|
||||
return (WebRtc_Word16)0x7FFF;
|
||||
}
|
||||
}
|
||||
|
||||
WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den)
|
||||
{
|
||||
WebRtc_Word32 L_num = num;
|
||||
WebRtc_Word32 L_den = den;
|
||||
WebRtc_Word32 div = 0;
|
||||
int k = 31;
|
||||
int change_sign = 0;
|
||||
|
||||
if (num == 0)
|
||||
return 0;
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
change_sign++;
|
||||
L_num = -num;
|
||||
}
|
||||
if (den < 0)
|
||||
{
|
||||
change_sign++;
|
||||
L_den = -den;
|
||||
}
|
||||
while (k--)
|
||||
{
|
||||
div <<= 1;
|
||||
L_num <<= 1;
|
||||
if (L_num >= L_den)
|
||||
{
|
||||
L_num -= L_den;
|
||||
div++;
|
||||
}
|
||||
}
|
||||
if (change_sign == 1)
|
||||
{
|
||||
div = -div;
|
||||
}
|
||||
return div;
|
||||
}
|
||||
|
||||
WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi,
|
||||
WebRtc_Word16 den_low)
|
||||
{
|
||||
WebRtc_Word16 approx, tmp_hi, tmp_low, num_hi, num_low;
|
||||
WebRtc_Word32 tmpW32;
|
||||
|
||||
approx = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)0x1FFFFFFF, den_hi);
|
||||
// result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
|
||||
|
||||
// tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
|
||||
tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1)
|
||||
+ ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1);
|
||||
// tmpW32 = den * approx
|
||||
|
||||
tmpW32 = (WebRtc_Word32)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
|
||||
|
||||
// Store tmpW32 in hi and low format
|
||||
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
|
||||
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
|
||||
|
||||
// tmpW32 = 1/den in Q29
|
||||
tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx)
|
||||
>> 15)) << 1);
|
||||
|
||||
// 1/den in hi and low format
|
||||
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
|
||||
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
|
||||
|
||||
// Store num in hi and low format
|
||||
num_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(num, 16);
|
||||
num_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((num
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)num_hi, 16)), 1);
|
||||
|
||||
// num * (1/den) by 32 bit multiplication (result in Q28)
|
||||
|
||||
tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low)
|
||||
>> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15));
|
||||
|
||||
// Put result in Q31 (convert from Q28)
|
||||
tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
|
||||
|
||||
return tmpW32;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue