Built SDL2_image and _mixer static

This commit is contained in:
2022-09-30 15:49:16 -04:00
parent e2605bf6c1
commit 1dec4347e0
4473 changed files with 1964551 additions and 9 deletions

View File

@ -0,0 +1,175 @@
/*Copyright (c) 2003-2004, Mark Borgerding
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.*/
#ifndef KISS_FFT_GUTS_H
#define KISS_FFT_GUTS_H
#define MIN(a,b) ((a)<(b) ? (a):(b))
#define MAX(a,b) ((a)>(b) ? (a):(b))
/* kiss_fft.h
defines kiss_fft_scalar as either short or a float type
and defines
typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
#include "kiss_fft.h"
/*
Explanation of macros dealing with complex math:
C_MUL(m,a,b) : m = a*b
C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
C_SUB( res, a,b) : res = a - b
C_SUBFROM( res , a) : res -= a
C_ADDTO( res , a) : res += a
* */
#ifdef FIXED_POINT
#include "arch.h"
#define SAMP_MAX 2147483647
#define TWID_MAX 32767
#define TRIG_UPSCALE 1
#define SAMP_MIN -SAMP_MAX
# define S_MUL(a,b) MULT16_32_Q15(b, a)
# define C_MUL(m,a,b) \
do{ (m).r = SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
(m).i = ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)
# define C_MULC(m,a,b) \
do{ (m).r = ADD32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
(m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)
# define C_MUL4(m,a,b) \
do{ (m).r = SHR32(SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)),2); \
(m).i = SHR32(ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)),2); }while(0)
# define C_MULBYSCALAR( c, s ) \
do{ (c).r = S_MUL( (c).r , s ) ;\
(c).i = S_MUL( (c).i , s ) ; }while(0)
# define DIVSCALAR(x,k) \
(x) = S_MUL( x, (TWID_MAX-((k)>>1))/(k)+1 )
# define C_FIXDIV(c,div) \
do { DIVSCALAR( (c).r , div); \
DIVSCALAR( (c).i , div); }while (0)
#define C_ADD( res, a,b)\
do {(res).r=ADD32((a).r,(b).r); (res).i=ADD32((a).i,(b).i); \
}while(0)
#define C_SUB( res, a,b)\
do {(res).r=SUB32((a).r,(b).r); (res).i=SUB32((a).i,(b).i); \
}while(0)
#define C_ADDTO( res , a)\
do {(res).r = ADD32((res).r, (a).r); (res).i = ADD32((res).i,(a).i);\
}while(0)
#define C_SUBFROM( res , a)\
do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \
}while(0)
#else /* not FIXED_POINT*/
# define S_MUL(a,b) ( (a)*(b) )
#define C_MUL(m,a,b) \
do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
(m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
#define C_MULC(m,a,b) \
do{ (m).r = (a).r*(b).r + (a).i*(b).i;\
(m).i = (a).i*(b).r - (a).r*(b).i; }while(0)
#define C_MUL4(m,a,b) C_MUL(m,a,b)
# define C_FIXDIV(c,div) /* NOOP */
# define C_MULBYSCALAR( c, s ) \
do{ (c).r *= (s);\
(c).i *= (s); }while(0)
#endif
#ifndef CHECK_OVERFLOW_OP
# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
#endif
#ifndef C_ADD
#define C_ADD( res, a,b)\
do { \
CHECK_OVERFLOW_OP((a).r,+,(b).r)\
CHECK_OVERFLOW_OP((a).i,+,(b).i)\
(res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
}while(0)
#define C_SUB( res, a,b)\
do { \
CHECK_OVERFLOW_OP((a).r,-,(b).r)\
CHECK_OVERFLOW_OP((a).i,-,(b).i)\
(res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
}while(0)
#define C_ADDTO( res , a)\
do { \
CHECK_OVERFLOW_OP((res).r,+,(a).r)\
CHECK_OVERFLOW_OP((res).i,+,(a).i)\
(res).r += (a).r; (res).i += (a).i;\
}while(0)
#define C_SUBFROM( res , a)\
do {\
CHECK_OVERFLOW_OP((res).r,-,(a).r)\
CHECK_OVERFLOW_OP((res).i,-,(a).i)\
(res).r -= (a).r; (res).i -= (a).i; \
}while(0)
#endif /* C_ADD defined */
#ifdef FIXED_POINT
/*# define KISS_FFT_COS(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase))))
# define KISS_FFT_SIN(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))*/
# define KISS_FFT_COS(phase) floor(.5+TWID_MAX*cos (phase))
# define KISS_FFT_SIN(phase) floor(.5+TWID_MAX*sin (phase))
# define HALF_OF(x) ((x)>>1)
#elif defined(USE_SIMD)
# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
# define HALF_OF(x) ((x)*_mm_set1_ps(.5f))
#else
# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
# define HALF_OF(x) ((x)*.5f)
#endif
#define kf_cexp(x,phase) \
do{ \
(x)->r = KISS_FFT_COS(phase);\
(x)->i = KISS_FFT_SIN(phase);\
}while(0)
#define kf_cexp2(x,phase) \
do{ \
(x)->r = TRIG_UPSCALE*celt_cos_norm((phase));\
(x)->i = TRIG_UPSCALE*celt_cos_norm((phase)-32768);\
}while(0)
#endif /* KISS_FFT_GUTS_H */

View File

@ -0,0 +1,209 @@
/* Copyright (c) 2003-2008 Jean-Marc Valin
Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/**
@file arch.h
@brief Various architecture definitions for CELT
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARCH_H
#define ARCH_H
#include "opus_types.h"
# if !defined(__GNUC_PREREQ)
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
# define __GNUC_PREREQ(_maj,_min) \
((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
# else
# define __GNUC_PREREQ(_maj,_min) 0
# endif
# endif
#define CELT_SIG_SCALE 32768.f
#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__);
#ifdef ENABLE_ASSERTIONS
#include <stdio.h>
#include <stdlib.h>
#ifdef __GNUC__
__attribute__((noreturn))
#endif
static inline void _celt_fatal(const char *str, const char *file, int line)
{
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
abort();
}
#define celt_assert(cond) {if (!(cond)) {celt_fatal("assertion failed: " #cond);}}
#define celt_assert2(cond, message) {if (!(cond)) {celt_fatal("assertion failed: " #cond "\n" message);}}
#else
#define celt_assert(cond)
#define celt_assert2(cond, message)
#endif
#define IMUL32(a,b) ((a)*(b))
#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */
#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 16-bit value. */
#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */
#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 32-bit value. */
#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
#define IMIN(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum int value. */
#define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */
#define UADD32(a,b) ((a)+(b))
#define USUB32(a,b) ((a)-(b))
#define PRINT_MIPS(file)
#ifdef FIXED_POINT
typedef opus_int16 opus_val16;
typedef opus_int32 opus_val32;
typedef opus_val32 celt_sig;
typedef opus_val16 celt_norm;
typedef opus_val32 celt_ener;
#define Q15ONE 32767
#define SIG_SHIFT 12
#define NORM_SCALING 16384
#define DB_SHIFT 10
#define EPSILON 1
#define VERY_LARGE16 ((opus_val16)32767)
#define Q15_ONE ((opus_val16)32767)
#define SCALEIN(a) (a)
#define SCALEOUT(a) (a)
#ifdef FIXED_DEBUG
#include "fixed_debug.h"
#else
#include "fixed_generic.h"
#ifdef ARM5E_ASM
#include "fixed_arm5e.h"
#elif defined (ARM4_ASM)
#include "fixed_arm4.h"
#elif defined (BFIN_ASM)
#include "fixed_bfin.h"
#elif defined (TI_C5X_ASM)
#include "fixed_c5x.h"
#elif defined (TI_C6X_ASM)
#include "fixed_c6x.h"
#endif
#endif
#else /* FIXED_POINT */
typedef float opus_val16;
typedef float opus_val32;
typedef float celt_sig;
typedef float celt_norm;
typedef float celt_ener;
#define Q15ONE 1.0f
#define NORM_SCALING 1.f
#define EPSILON 1e-15f
#define VERY_LARGE16 1e15f
#define Q15_ONE ((opus_val16)1.f)
#define QCONST16(x,bits) (x)
#define QCONST32(x,bits) (x)
#define NEG16(x) (-(x))
#define NEG32(x) (-(x))
#define EXTRACT16(x) (x)
#define EXTEND32(x) (x)
#define SHR16(a,shift) (a)
#define SHL16(a,shift) (a)
#define SHR32(a,shift) (a)
#define SHL32(a,shift) (a)
#define PSHR32(a,shift) (a)
#define VSHR32(a,shift) (a)
#define PSHR(a,shift) (a)
#define SHR(a,shift) (a)
#define SHL(a,shift) (a)
#define SATURATE(x,a) (x)
#define ROUND16(a,shift) (a)
#define HALF16(x) (.5f*(x))
#define HALF32(x) (.5f*(x))
#define ADD16(a,b) ((a)+(b))
#define SUB16(a,b) ((a)-(b))
#define ADD32(a,b) ((a)+(b))
#define SUB32(a,b) ((a)-(b))
#define MULT16_16_16(a,b) ((a)*(b))
#define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b))
#define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b))
#define MULT16_32_Q15(a,b) ((a)*(b))
#define MULT16_32_Q16(a,b) ((a)*(b))
#define MULT32_32_Q31(a,b) ((a)*(b))
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
#define MULT16_16_Q11_32(a,b) ((a)*(b))
#define MULT16_16_Q13(a,b) ((a)*(b))
#define MULT16_16_Q14(a,b) ((a)*(b))
#define MULT16_16_Q15(a,b) ((a)*(b))
#define MULT16_16_P15(a,b) ((a)*(b))
#define MULT16_16_P13(a,b) ((a)*(b))
#define MULT16_16_P14(a,b) ((a)*(b))
#define MULT16_32_P16(a,b) ((a)*(b))
#define DIV32_16(a,b) (((opus_val32)(a))/(opus_val16)(b))
#define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b))
#define SCALEIN(a) ((a)*CELT_SIG_SCALE)
#define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE))
#endif /* !FIXED_POINT */
#ifndef GLOBAL_STACK_SIZE
#ifdef FIXED_POINT
#define GLOBAL_STACK_SIZE 100000
#else
#define GLOBAL_STACK_SIZE 100000
#endif
#endif
#endif /* ARCH_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Copyright (c) 2008-2009 Gregory Maxwell
Written by Jean-Marc Valin and Gregory Maxwell */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BANDS_H
#define BANDS_H
#include "arch.h"
#include "modes.h"
#include "entenc.h"
#include "entdec.h"
#include "rate.h"
/** Compute the amplitude (sqrt energy) in each of the bands
* @param m Mode data
* @param X Spectrum
* @param bands Square root of the energy for each band (returned)
*/
void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M);
/*void compute_noise_energies(const CELTMode *m, const celt_sig *X, const opus_val16 *tonality, celt_ener *bandE);*/
/** Normalise each band of X such that the energy in each band is
equal to 1
* @param m Mode data
* @param X Spectrum (returned normalised)
* @param bands Square root of the energy for each band
*/
void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M);
/** Denormalise each band of X to restore full amplitude
* @param m Mode data
* @param X Spectrum (returned de-normalised)
* @param bands Square root of the energy for each band
*/
void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, celt_sig * OPUS_RESTRICT freq, const celt_ener *bandE, int end, int C, int M);
#define SPREAD_NONE (0)
#define SPREAD_LIGHT (1)
#define SPREAD_NORMAL (2)
#define SPREAD_AGGRESSIVE (3)
int spreading_decision(const CELTMode *m, celt_norm *X, int *average,
int last_decision, int *hf_average, int *tapset_decision, int update_hf,
int end, int C, int M);
#ifdef MEASURE_NORM_MSE
void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C);
#endif
void haar1(celt_norm *X, int N0, int stride);
/** Quantisation/encoding of the residual spectrum
* @param m Mode data
* @param X Residual (normalised)
* @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
* @param enc Entropy encoder
*/
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
celt_norm * X, celt_norm * Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
int time_domain, int fold, int dual_stereo, int intensity, int *tf_res,
opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed);
void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size,
int start, int end, opus_val16 *logE, opus_val16 *prev1logE,
opus_val16 *prev2logE, int *pulses, opus_uint32 seed);
opus_uint32 celt_lcg_rand(opus_uint32 seed);
#endif /* BANDS_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,117 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Copyright (c) 2008 Gregory Maxwell
Written by Jean-Marc Valin and Gregory Maxwell */
/**
@file celt.h
@brief Contains all the functions for encoding and decoding audio
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CELT_H
#define CELT_H
#include "opus_types.h"
#include "opus_defines.h"
#include "opus_custom.h"
#include "entenc.h"
#include "entdec.h"
#include "arch.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CELTEncoder OpusCustomEncoder
#define CELTDecoder OpusCustomDecoder
#define CELTMode OpusCustomMode
#define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
/* Encoder/decoder Requests */
#define CELT_SET_PREDICTION_REQUEST 10002
/** Controls the use of interframe prediction.
0=Independent frames
1=Short term interframe prediction allowed
2=Long term prediction allowed
*/
#define CELT_SET_PREDICTION(x) CELT_SET_PREDICTION_REQUEST, __opus_check_int(x)
#define CELT_SET_INPUT_CLIPPING_REQUEST 10004
#define CELT_SET_INPUT_CLIPPING(x) CELT_SET_INPUT_CLIPPING_REQUEST, __opus_check_int(x)
#define CELT_GET_AND_CLEAR_ERROR_REQUEST 10007
#define CELT_GET_AND_CLEAR_ERROR(x) CELT_GET_AND_CLEAR_ERROR_REQUEST, __opus_check_int_ptr(x)
#define CELT_SET_CHANNELS_REQUEST 10008
#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, __opus_check_int(x)
/* Internal */
#define CELT_SET_START_BAND_REQUEST 10010
#define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, __opus_check_int(x)
#define CELT_SET_END_BAND_REQUEST 10012
#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, __opus_check_int(x)
#define CELT_GET_MODE_REQUEST 10015
/** Get the CELTMode used by an encoder or decoder */
#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, _celt_check_mode_ptr_ptr(x)
#define CELT_SET_SIGNALLING_REQUEST 10016
#define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x)
/* Encoder stuff */
int celt_encoder_get_size(int channels);
int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc);
int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels);
/* Decoder stuff */
int celt_decoder_get_size(int channels);
int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels);
int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec);
#define celt_encoder_ctl opus_custom_encoder_ctl
#define celt_decoder_ctl opus_custom_decoder_ctl
#ifdef __cplusplus
}
#endif
#endif /* CELT_H */

View File

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{245603E3-F580-41A5-9632-B25FE3372CBF}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>celt</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<CustomBuildBeforeTargets>
</CustomBuildBeforeTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../win32;../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PreBuildEvent>
<Command>"$(ProjectDir)..\win32\genversion.bat" "$(ProjectDir)..\win32\version.h" OPUS_VERSION</Command>
<Message>Generating version.h</Message>
</PreBuildEvent>
<CustomBuildStep>
<Command>
</Command>
</CustomBuildStep>
<CustomBuildStep>
<Outputs>
</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../win32;../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PreBuildEvent>
<Command>"$(ProjectDir)..\win32\genversion.bat" "$(ProjectDir)..\win32\version.h" OPUS_VERSION</Command>
<Message>Generating version.h</Message>
</PreBuildEvent>
<CustomBuildStep>
<Command>
</Command>
</CustomBuildStep>
<CustomBuildStep>
<Outputs>
</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../win32;../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PreBuildEvent>
<Command>"$(ProjectDir)..\win32\genversion.bat" "$(ProjectDir)..\win32\version.h" OPUS_VERSION</Command>
<Message>Generating version.h</Message>
</PreBuildEvent>
<CustomBuildStep>
<Command>
</Command>
</CustomBuildStep>
<CustomBuildStep>
<Outputs>
</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../win32;../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PreBuildEvent>
<Command>"$(ProjectDir)..\win32\genversion.bat" "$(ProjectDir)..\win32\version.h" OPUS_VERSION</Command>
<Message>Generating version.h</Message>
</PreBuildEvent>
<CustomBuildStep>
<Command>
</Command>
</CustomBuildStep>
<CustomBuildStep>
<Outputs>
</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\win32\config.h" />
<ClInclude Include="arch.h" />
<ClInclude Include="bands.h" />
<ClInclude Include="celt.h" />
<ClInclude Include="cwrs.h" />
<ClInclude Include="ecintrin.h" />
<ClInclude Include="entcode.h" />
<ClInclude Include="entdec.h" />
<ClInclude Include="entenc.h" />
<ClInclude Include="fixed_debug.h" />
<ClInclude Include="fixed_generic.h" />
<ClInclude Include="float_cast.h" />
<ClInclude Include="kiss_fft.h" />
<ClInclude Include="laplace.h" />
<ClInclude Include="mathops.h" />
<ClInclude Include="mdct.h" />
<ClInclude Include="modes.h" />
<ClInclude Include="os_support.h" />
<ClInclude Include="pitch.h" />
<ClInclude Include="celt_lpc.h" />
<ClInclude Include="quant_bands.h" />
<ClInclude Include="rate.h" />
<ClInclude Include="stack_alloc.h" />
<ClInclude Include="vq.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="bands.c" />
<ClCompile Include="celt.c" />
<ClCompile Include="cwrs.c" />
<ClCompile Include="entcode.c" />
<ClCompile Include="entdec.c" />
<ClCompile Include="entenc.c" />
<ClCompile Include="kiss_fft.c" />
<ClCompile Include="laplace.c" />
<ClCompile Include="mathops.c" />
<ClCompile Include="mdct.c" />
<ClCompile Include="modes.c" />
<ClCompile Include="pitch.c" />
<ClCompile Include="celt_lpc.c" />
<ClCompile Include="quant_bands.c" />
<ClCompile Include="rate.c" />
<ClCompile Include="vq.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="arch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="bands.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="celt.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cwrs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ecintrin.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="entcode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="entdec.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="entenc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="fixed_debug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="fixed_generic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="float_cast.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="kiss_fft.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="laplace.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mathops.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mdct.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="modes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="os_support.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pitch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="celt_lpc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="quant_bands.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="rate.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stack_alloc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="vq.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\win32\config.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="bands.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="celt.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cwrs.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="entcode.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="entdec.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="entenc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="kiss_fft.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="laplace.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mdct.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="modes.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pitch.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="celt_lpc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="quant_bands.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="rate.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="vq.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mathops.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,188 @@
/* Copyright (c) 2009-2010 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "celt_lpc.h"
#include "stack_alloc.h"
#include "mathops.h"
void _celt_lpc(
opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */
const opus_val32 *ac, /* in: [0...p] autocorrelation values */
int p
)
{
int i, j;
opus_val32 r;
opus_val32 error = ac[0];
#ifdef FIXED_POINT
opus_val32 lpc[LPC_ORDER];
#else
float *lpc = _lpc;
#endif
for (i = 0; i < p; i++)
lpc[i] = 0;
if (ac[0] != 0)
{
for (i = 0; i < p; i++) {
/* Sum up this iteration's reflection coefficient */
opus_val32 rr = 0;
for (j = 0; j < i; j++)
rr += MULT32_32_Q31(lpc[j],ac[i - j]);
rr += SHR32(ac[i + 1],3);
r = -frac_div32(SHL32(rr,3), error);
/* Update LPC coefficients and total error */
lpc[i] = SHR32(r,3);
for (j = 0; j < (i+1)>>1; j++)
{
opus_val32 tmp1, tmp2;
tmp1 = lpc[j];
tmp2 = lpc[i-1-j];
lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2);
lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
}
error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
/* Bail out once we get 30 dB gain */
#ifdef FIXED_POINT
if (error<SHR32(ac[0],10))
break;
#else
if (error<.001f*ac[0])
break;
#endif
}
}
#ifdef FIXED_POINT
for (i=0;i<p;i++)
_lpc[i] = ROUND16(lpc[i],16);
#endif
}
void celt_fir(const opus_val16 *x,
const opus_val16 *num,
opus_val16 *y,
int N,
int ord,
opus_val16 *mem)
{
int i,j;
for (i=0;i<N;i++)
{
opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
for (j=0;j<ord;j++)
{
sum += MULT16_16(num[j],mem[j]);
}
for (j=ord-1;j>=1;j--)
{
mem[j]=mem[j-1];
}
mem[0] = x[i];
y[i] = ROUND16(sum, SIG_SHIFT);
}
}
void celt_iir(const opus_val32 *x,
const opus_val16 *den,
opus_val32 *y,
int N,
int ord,
opus_val16 *mem)
{
int i,j;
for (i=0;i<N;i++)
{
opus_val32 sum = x[i];
for (j=0;j<ord;j++)
{
sum -= MULT16_16(den[j],mem[j]);
}
for (j=ord-1;j>=1;j--)
{
mem[j]=mem[j-1];
}
mem[0] = ROUND16(sum,SIG_SHIFT);
y[i] = sum;
}
}
void _celt_autocorr(
const opus_val16 *x, /* in: [0...n-1] samples x */
opus_val32 *ac, /* out: [0...lag-1] ac values */
const opus_val16 *window,
int overlap,
int lag,
int n
)
{
opus_val32 d;
int i;
VARDECL(opus_val16, xx);
SAVE_STACK;
ALLOC(xx, n, opus_val16);
celt_assert(n>0);
celt_assert(overlap>=0);
for (i=0;i<n;i++)
xx[i] = x[i];
for (i=0;i<overlap;i++)
{
xx[i] = MULT16_16_Q15(x[i],window[i]);
xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
}
#ifdef FIXED_POINT
{
opus_val32 ac0=0;
int shift;
for(i=0;i<n;i++)
ac0 += SHR32(MULT16_16(xx[i],xx[i]),9);
ac0 += 1+n;
shift = celt_ilog2(ac0)-30+10;
shift = (shift+1)/2;
for(i=0;i<n;i++)
xx[i] = VSHR32(xx[i], shift);
}
#endif
while (lag>=0)
{
for (i = lag, d = 0; i < n; i++)
d += xx[i] * xx[i-lag];
ac[lag] = d;
/*printf ("%f ", ac[lag]);*/
lag--;
}
/*printf ("\n");*/
ac[0] += 10;
RESTORE_STACK;
}

View File

@ -0,0 +1,53 @@
/* Copyright (c) 2009-2010 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PLC_H
#define PLC_H
#include "arch.h"
#define LPC_ORDER 24
void _celt_lpc(opus_val16 *_lpc, const opus_val32 *ac, int p);
void celt_fir(const opus_val16 *x,
const opus_val16 *num,
opus_val16 *y,
int N,
int ord,
opus_val16 *mem);
void celt_iir(const opus_val32 *x,
const opus_val16 *den,
opus_val32 *y,
int N,
int ord,
opus_val16 *mem);
void _celt_autocorr(const opus_val16 *x, opus_val32 *ac, const opus_val16 *window, int overlap, int lag, int n);
#endif /* PLC_H */

View File

@ -0,0 +1,647 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Copyright (c) 2007-2009 Timothy B. Terriberry
Written by Timothy B. Terriberry and Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_support.h"
#include "cwrs.h"
#include "mathops.h"
#include "arch.h"
#ifdef CUSTOM_MODES
/*Guaranteed to return a conservatively large estimate of the binary logarithm
with frac bits of fractional precision.
Tested for all possible 32-bit inputs with frac=4, where the maximum
overestimation is 0.06254243 bits.*/
int log2_frac(opus_uint32 val, int frac)
{
int l;
l=EC_ILOG(val);
if(val&(val-1)){
/*This is (val>>l-16), but guaranteed to round up, even if adding a bias
before the shift would cause overflow (e.g., for 0xFFFFxxxx).
Doesn't work for val=0, but that case fails the test above.*/
if(l>16)val=((val-1)>>(l-16))+1;
else val<<=16-l;
l=(l-1)<<frac;
/*Note that we always need one iteration, since the rounding up above means
that we might need to adjust the integer part of the logarithm.*/
do{
int b;
b=(int)(val>>16);
l+=b<<frac;
val=(val+b)>>b;
val=(val*val+0x7FFF)>>15;
}
while(frac-->0);
/*If val is not exactly 0x8000, then we have to round up the remainder.*/
return l+(val>0x8000);
}
/*Exact powers of two require no rounding.*/
else return (l-1)<<frac;
}
#endif
#ifndef SMALL_FOOTPRINT
#define MASK32 (0xFFFFFFFF)
/*INV_TABLE[i] holds the multiplicative inverse of (2*i+1) mod 2**32.*/
static const opus_uint32 INV_TABLE[53]={
0x00000001,0xAAAAAAAB,0xCCCCCCCD,0xB6DB6DB7,
0x38E38E39,0xBA2E8BA3,0xC4EC4EC5,0xEEEEEEEF,
0xF0F0F0F1,0x286BCA1B,0x3CF3CF3D,0xE9BD37A7,
0xC28F5C29,0x684BDA13,0x4F72C235,0xBDEF7BDF,
0x3E0F83E1,0x8AF8AF8B,0x914C1BAD,0x96F96F97,
0xC18F9C19,0x2FA0BE83,0xA4FA4FA5,0x677D46CF,
0x1A1F58D1,0xFAFAFAFB,0x8C13521D,0x586FB587,
0xB823EE09,0xA08AD8F3,0xC10C9715,0xBEFBEFBF,
0xC0FC0FC1,0x07A44C6B,0xA33F128D,0xE327A977,
0xC7E3F1F9,0x962FC963,0x3F2B3885,0x613716AF,
0x781948B1,0x2B2E43DB,0xFCFCFCFD,0x6FD0EB67,
0xFA3F47E9,0xD2FD2FD3,0x3F4FD3F5,0xD4E25B9F,
0x5F02A3A1,0xBF5A814B,0x7C32B16D,0xD3431B57,
0xD8FD8FD9,
};
/*Computes (_a*_b-_c)/(2*_d+1) when the quotient is known to be exact.
_a, _b, _c, and _d may be arbitrary so long as the arbitrary precision result
fits in 32 bits, but currently the table for multiplicative inverses is only
valid for _d<=52.*/
static inline opus_uint32 imusdiv32odd(opus_uint32 _a,opus_uint32 _b,
opus_uint32 _c,int _d){
celt_assert(_d<=52);
return (_a*_b-_c)*INV_TABLE[_d]&MASK32;
}
/*Computes (_a*_b-_c)/_d when the quotient is known to be exact.
_d does not actually have to be even, but imusdiv32odd will be faster when
it's odd, so you should use that instead.
_a and _d are assumed to be small (e.g., _a*_d fits in 32 bits; currently the
table for multiplicative inverses is only valid for _d<=54).
_b and _c may be arbitrary so long as the arbitrary precision reuslt fits in
32 bits.*/
static inline opus_uint32 imusdiv32even(opus_uint32 _a,opus_uint32 _b,
opus_uint32 _c,int _d){
opus_uint32 inv;
int mask;
int shift;
int one;
celt_assert(_d>0);
celt_assert(_d<=54);
shift=EC_ILOG(_d^(_d-1));
inv=INV_TABLE[(_d-1)>>shift];
shift--;
one=1<<shift;
mask=one-1;
return (_a*(_b>>shift)-(_c>>shift)+
((_a*(_b&mask)+one-(_c&mask))>>shift)-1)*inv&MASK32;
}
#endif /* SMALL_FOOTPRINT */
/*Although derived separately, the pulse vector coding scheme is equivalent to
a Pyramid Vector Quantizer \cite{Fis86}.
Some additional notes about an early version appear at
http://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering
and the definitions of some terms have evolved since that was written.
The conversion from a pulse vector to an integer index (encoding) and back
(decoding) is governed by two related functions, V(N,K) and U(N,K).
V(N,K) = the number of combinations, with replacement, of N items, taken K
at a time, when a sign bit is added to each item taken at least once (i.e.,
the number of N-dimensional unit pulse vectors with K pulses).
One way to compute this is via
V(N,K) = K>0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1,
where choose() is the binomial function.
A table of values for N<10 and K<10 looks like:
V[10][10] = {
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{1, 4, 8, 12, 16, 20, 24, 28, 32, 36},
{1, 6, 18, 38, 66, 102, 146, 198, 258, 326},
{1, 8, 32, 88, 192, 360, 608, 952, 1408, 1992},
{1, 10, 50, 170, 450, 1002, 1970, 3530, 5890, 9290},
{1, 12, 72, 292, 912, 2364, 5336, 10836, 20256, 35436},
{1, 14, 98, 462, 1666, 4942, 12642, 28814, 59906, 115598},
{1, 16, 128, 688, 2816, 9424, 27008, 68464, 157184, 332688},
{1, 18, 162, 978, 4482, 16722, 53154, 148626, 374274, 864146}
};
U(N,K) = the number of such combinations wherein N-1 objects are taken at
most K-1 at a time.
This is given by
U(N,K) = sum(k=0...K-1,V(N-1,k))
= K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0.
The latter expression also makes clear that U(N,K) is half the number of such
combinations wherein the first object is taken at least once.
Although it may not be clear from either of these definitions, U(N,K) is the
natural function to work with when enumerating the pulse vector codebooks,
not V(N,K).
U(N,K) is not well-defined for N=0, but with the extension
U(0,K) = K>0 ? 0 : 1,
the function becomes symmetric: U(N,K) = U(K,N), with a similar table:
U[10][10] = {
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 1, 3, 5, 7, 9, 11, 13, 15, 17},
{0, 1, 5, 13, 25, 41, 61, 85, 113, 145},
{0, 1, 7, 25, 63, 129, 231, 377, 575, 833},
{0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649},
{0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073},
{0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081},
{0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545},
{0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729}
};
With this extension, V(N,K) may be written in terms of U(N,K):
V(N,K) = U(N,K) + U(N,K+1)
for all N>=0, K>=0.
Thus U(N,K+1) represents the number of combinations where the first element
is positive or zero, and U(N,K) represents the number of combinations where
it is negative.
With a large enough table of U(N,K) values, we could write O(N) encoding
and O(min(N*log(K),N+K)) decoding routines, but such a table would be
prohibitively large for small embedded devices (K may be as large as 32767
for small N, and N may be as large as 200).
Both functions obey the same recurrence relation:
V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1),
U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1),
for all N>0, K>0, with different initial conditions at N=0 or K=0.
This allows us to construct a row of one of the tables above given the
previous row or the next row.
Thus we can derive O(NK) encoding and decoding routines with O(K) memory
using only addition and subtraction.
When encoding, we build up from the U(2,K) row and work our way forwards.
When decoding, we need to start at the U(N,K) row and work our way backwards,
which requires a means of computing U(N,K).
U(N,K) may be computed from two previous values with the same N:
U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2)
for all N>1, and since U(N,K) is symmetric, a similar relation holds for two
previous values with the same K:
U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K)
for all K>1.
This allows us to construct an arbitrary row of the U(N,K) table by starting
with the first two values, which are constants.
This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K)
multiplications.
Similar relations can be derived for V(N,K), but are not used here.
For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree
polynomial for fixed N.
The first few are
U(1,K) = 1,
U(2,K) = 2*K-1,
U(3,K) = (2*K-2)*K+1,
U(4,K) = (((4*K-6)*K+8)*K-3)/3,
U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3,
and
V(1,K) = 2,
V(2,K) = 4*K,
V(3,K) = 4*K*K+2,
V(4,K) = 8*(K*K+2)*K/3,
V(5,K) = ((4*K*K+20)*K*K+6)/3,
for all K>0.
This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for
small N (and indeed decoding is also O(N) for N<3).
@ARTICLE{Fis86,
author="Thomas R. Fischer",
title="A Pyramid Vector Quantizer",
journal="IEEE Transactions on Information Theory",
volume="IT-32",
number=4,
pages="568--583",
month=Jul,
year=1986
}*/
#ifndef SMALL_FOOTPRINT
/*Compute U(2,_k).
Note that this may be called with _k=32768 (maxK[2]+1).*/
static inline unsigned ucwrs2(unsigned _k){
celt_assert(_k>0);
return _k+(_k-1);
}
/*Compute V(2,_k).*/
static inline opus_uint32 ncwrs2(int _k){
celt_assert(_k>0);
return 4*(opus_uint32)_k;
}
/*Compute U(3,_k).
Note that this may be called with _k=32768 (maxK[3]+1).*/
static inline opus_uint32 ucwrs3(unsigned _k){
celt_assert(_k>0);
return (2*(opus_uint32)_k-2)*_k+1;
}
/*Compute V(3,_k).*/
static inline opus_uint32 ncwrs3(int _k){
celt_assert(_k>0);
return 2*(2*(unsigned)_k*(opus_uint32)_k+1);
}
/*Compute U(4,_k).*/
static inline opus_uint32 ucwrs4(int _k){
celt_assert(_k>0);
return imusdiv32odd(2*_k,(2*_k-3)*(opus_uint32)_k+4,3,1);
}
/*Compute V(4,_k).*/
static inline opus_uint32 ncwrs4(int _k){
celt_assert(_k>0);
return ((_k*(opus_uint32)_k+2)*_k)/3<<3;
}
#endif /* SMALL_FOOTPRINT */
/*Computes the next row/column of any recurrence that obeys the relation
u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1].
_ui0 is the base case for the new row/column.*/
static inline void unext(opus_uint32 *_ui,unsigned _len,opus_uint32 _ui0){
opus_uint32 ui1;
unsigned j;
/*This do-while will overrun the array if we don't have storage for at least
2 values.*/
j=1; do {
ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0);
_ui[j-1]=_ui0;
_ui0=ui1;
} while (++j<_len);
_ui[j-1]=_ui0;
}
/*Computes the previous row/column of any recurrence that obeys the relation
u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1].
_ui0 is the base case for the new row/column.*/
static inline void uprev(opus_uint32 *_ui,unsigned _n,opus_uint32 _ui0){
opus_uint32 ui1;
unsigned j;
/*This do-while will overrun the array if we don't have storage for at least
2 values.*/
j=1; do {
ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0);
_ui[j-1]=_ui0;
_ui0=ui1;
} while (++j<_n);
_ui[j-1]=_ui0;
}
/*Compute V(_n,_k), as well as U(_n,0..._k+1).
_u: On exit, _u[i] contains U(_n,i) for i in [0..._k+1].*/
static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){
opus_uint32 um2;
unsigned len;
unsigned k;
len=_k+2;
/*We require storage at least 3 values (e.g., _k>0).*/
celt_assert(len>=3);
_u[0]=0;
_u[1]=um2=1;
#ifndef SMALL_FOOTPRINT
/*_k>52 doesn't work in the false branch due to the limits of INV_TABLE,
but _k isn't tested here because k<=52 for n=7*/
if(_n<=6)
#endif
{
/*If _n==0, _u[0] should be 1 and the rest should be 0.*/
/*If _n==1, _u[i] should be 1 for i>1.*/
celt_assert(_n>=2);
/*If _k==0, the following do-while loop will overflow the buffer.*/
celt_assert(_k>0);
k=2;
do _u[k]=(k<<1)-1;
while(++k<len);
for(k=2;k<_n;k++)unext(_u+1,_k+1,1);
}
#ifndef SMALL_FOOTPRINT
else{
opus_uint32 um1;
opus_uint32 n2m1;
_u[2]=n2m1=um1=(_n<<1)-1;
for(k=3;k<len;k++){
/*U(N,K) = ((2*N-1)*U(N,K-1)-U(N,K-2))/(K-1) + U(N,K-2)*/
_u[k]=um2=imusdiv32even(n2m1,um1,um2,k-1)+um2;
if(++k>=len)break;
_u[k]=um1=imusdiv32odd(n2m1,um2,um1,(k-1)>>1)+um1;
}
}
#endif /* SMALL_FOOTPRINT */
return _u[_k]+_u[_k+1];
}
#ifndef SMALL_FOOTPRINT
/*Returns the _i'th combination of _k elements (at most 32767) chosen from a
set of size 1 with associated sign bits.
_y: Returns the vector of pulses.*/
static inline void cwrsi1(int _k,opus_uint32 _i,int *_y){
int s;
s=-(int)_i;
_y[0]=(_k+s)^s;
}
/*Returns the _i'th combination of _k elements (at most 32767) chosen from a
set of size 2 with associated sign bits.
_y: Returns the vector of pulses.*/
static inline void cwrsi2(int _k,opus_uint32 _i,int *_y){
opus_uint32 p;
int s;
int yj;
p=ucwrs2(_k+1U);
s=-(_i>=p);
_i-=p&s;
yj=_k;
_k=(_i+1)>>1;
p=_k?ucwrs2(_k):0;
_i-=p;
yj-=_k;
_y[0]=(yj+s)^s;
cwrsi1(_k,_i,_y+1);
}
/*Returns the _i'th combination of _k elements (at most 32767) chosen from a
set of size 3 with associated sign bits.
_y: Returns the vector of pulses.*/
static void cwrsi3(int _k,opus_uint32 _i,int *_y){
opus_uint32 p;
int s;
int yj;
p=ucwrs3(_k+1U);
s=-(_i>=p);
_i-=p&s;
yj=_k;
/*Finds the maximum _k such that ucwrs3(_k)<=_i (tested for all
_i<2147418113=U(3,32768)).*/
_k=_i>0?(isqrt32(2*_i-1)+1)>>1:0;
p=_k?ucwrs3(_k):0;
_i-=p;
yj-=_k;
_y[0]=(yj+s)^s;
cwrsi2(_k,_i,_y+1);
}
/*Returns the _i'th combination of _k elements (at most 1172) chosen from a set
of size 4 with associated sign bits.
_y: Returns the vector of pulses.*/
static void cwrsi4(int _k,opus_uint32 _i,int *_y){
opus_uint32 p;
int s;
int yj;
int kl;
int kr;
p=ucwrs4(_k+1);
s=-(_i>=p);
_i-=p&s;
yj=_k;
/*We could solve a cubic for k here, but the form of the direct solution does
not lend itself well to exact integer arithmetic.
Instead we do a binary search on U(4,K).*/
kl=0;
kr=_k;
for(;;){
_k=(kl+kr)>>1;
p=_k?ucwrs4(_k):0;
if(p<_i){
if(_k>=kr)break;
kl=_k+1;
}
else if(p>_i)kr=_k-1;
else break;
}
_i-=p;
yj-=_k;
_y[0]=(yj+s)^s;
cwrsi3(_k,_i,_y+1);
}
#endif /* SMALL_FOOTPRINT */
/*Returns the _i'th combination of _k elements chosen from a set of size _n
with associated sign bits.
_y: Returns the vector of pulses.
_u: Must contain entries [0..._k+1] of row _n of U() on input.
Its contents will be destructively modified.*/
static void cwrsi(int _n,int _k,opus_uint32 _i,int *_y,opus_uint32 *_u){
int j;
celt_assert(_n>0);
j=0;
do{
opus_uint32 p;
int s;
int yj;
p=_u[_k+1];
s=-(_i>=p);
_i-=p&s;
yj=_k;
p=_u[_k];
while(p>_i)p=_u[--_k];
_i-=p;
yj-=_k;
_y[j]=(yj+s)^s;
uprev(_u,_k+2,0);
}
while(++j<_n);
}
/*Returns the index of the given combination of K elements chosen from a set
of size 1 with associated sign bits.
_y: The vector of pulses, whose sum of absolute values is K.
_k: Returns K.*/
static inline opus_uint32 icwrs1(const int *_y,int *_k){
*_k=abs(_y[0]);
return _y[0]<0;
}
#ifndef SMALL_FOOTPRINT
/*Returns the index of the given combination of K elements chosen from a set
of size 2 with associated sign bits.
_y: The vector of pulses, whose sum of absolute values is K.
_k: Returns K.*/
static inline opus_uint32 icwrs2(const int *_y,int *_k){
opus_uint32 i;
int k;
i=icwrs1(_y+1,&k);
i+=k?ucwrs2(k):0;
k+=abs(_y[0]);
if(_y[0]<0)i+=ucwrs2(k+1U);
*_k=k;
return i;
}
/*Returns the index of the given combination of K elements chosen from a set
of size 3 with associated sign bits.
_y: The vector of pulses, whose sum of absolute values is K.
_k: Returns K.*/
static inline opus_uint32 icwrs3(const int *_y,int *_k){
opus_uint32 i;
int k;
i=icwrs2(_y+1,&k);
i+=k?ucwrs3(k):0;
k+=abs(_y[0]);
if(_y[0]<0)i+=ucwrs3(k+1U);
*_k=k;
return i;
}
/*Returns the index of the given combination of K elements chosen from a set
of size 4 with associated sign bits.
_y: The vector of pulses, whose sum of absolute values is K.
_k: Returns K.*/
static inline opus_uint32 icwrs4(const int *_y,int *_k){
opus_uint32 i;
int k;
i=icwrs3(_y+1,&k);
i+=k?ucwrs4(k):0;
k+=abs(_y[0]);
if(_y[0]<0)i+=ucwrs4(k+1);
*_k=k;
return i;
}
#endif /* SMALL_FOOTPRINT */
/*Returns the index of the given combination of K elements chosen from a set
of size _n with associated sign bits.
_y: The vector of pulses, whose sum of absolute values must be _k.
_nc: Returns V(_n,_k).*/
static inline opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y,
opus_uint32 *_u){
opus_uint32 i;
int j;
int k;
/*We can't unroll the first two iterations of the loop unless _n>=2.*/
celt_assert(_n>=2);
_u[0]=0;
for(k=1;k<=_k+1;k++)_u[k]=(k<<1)-1;
i=icwrs1(_y+_n-1,&k);
j=_n-2;
i+=_u[k];
k+=abs(_y[j]);
if(_y[j]<0)i+=_u[k+1];
while(j-->0){
unext(_u,_k+2,0);
i+=_u[k];
k+=abs(_y[j]);
if(_y[j]<0)i+=_u[k+1];
}
*_nc=_u[k]+_u[k+1];
return i;
}
#ifdef CUSTOM_MODES
void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){
int k;
/*_maxk==0 => there's nothing to do.*/
celt_assert(_maxk>0);
_bits[0]=0;
if (_n==1)
{
for (k=1;k<=_maxk;k++)
_bits[k] = 1<<_frac;
}
else {
VARDECL(opus_uint32,u);
SAVE_STACK;
ALLOC(u,_maxk+2U,opus_uint32);
ncwrs_urow(_n,_maxk,u);
for(k=1;k<=_maxk;k++)
_bits[k]=log2_frac(u[k]+u[k+1],_frac);
RESTORE_STACK;
}
}
#endif /* CUSTOM_MODES */
#ifdef OPUS_ENABLE_ENCODER
void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){
opus_uint32 i;
celt_assert(_k>0);
#ifndef SMALL_FOOTPRINT
switch(_n){
case 2:{
i=icwrs2(_y,&_k);
ec_enc_uint(_enc,i,ncwrs2(_k));
}break;
case 3:{
i=icwrs3(_y,&_k);
ec_enc_uint(_enc,i,ncwrs3(_k));
}break;
case 4:{
i=icwrs4(_y,&_k);
ec_enc_uint(_enc,i,ncwrs4(_k));
}break;
default:
{
#endif
VARDECL(opus_uint32,u);
opus_uint32 nc;
SAVE_STACK;
ALLOC(u,_k+2U,opus_uint32);
i=icwrs(_n,_k,&nc,_y,u);
ec_enc_uint(_enc,i,nc);
RESTORE_STACK;
#ifndef SMALL_FOOTPRINT
}
break;
}
#endif
}
#endif /* OPUS_ENABLE_ENCODER */
void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec)
{
celt_assert(_k>0);
#ifndef SMALL_FOOTPRINT
switch(_n){
case 2:cwrsi2(_k,ec_dec_uint(_dec,ncwrs2(_k)),_y);break;
case 3:cwrsi3(_k,ec_dec_uint(_dec,ncwrs3(_k)),_y);break;
case 4:cwrsi4(_k,ec_dec_uint(_dec,ncwrs4(_k)),_y);break;
default:
{
#endif
VARDECL(opus_uint32,u);
SAVE_STACK;
ALLOC(u,_k+2U,opus_uint32);
cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u);
RESTORE_STACK;
#ifndef SMALL_FOOTPRINT
}
break;
}
#endif
}

View File

@ -0,0 +1,48 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Copyright (c) 2007-2009 Timothy B. Terriberry
Written by Timothy B. Terriberry and Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CWRS_H
#define CWRS_H
#include "arch.h"
#include "stack_alloc.h"
#include "entenc.h"
#include "entdec.h"
#ifdef CUSTOM_MODES
int log2_frac(opus_uint32 val, int frac);
#endif
void get_required_bits(opus_int16 *bits, int N, int K, int frac);
void encode_pulses(const int *_y, int N, int K, ec_enc *enc);
void decode_pulses(int *_y, int N, int K, ec_dec *dec);
#endif /* CWRS_H */

View File

@ -0,0 +1,87 @@
/* Copyright (c) 2003-2008 Timothy B. Terriberry
Copyright (c) 2008 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*Some common macros for potential platform-specific optimization.*/
#include "opus_types.h"
#include <math.h>
#include <limits.h>
#include "arch.h"
#if !defined(_ecintrin_H)
# define _ecintrin_H (1)
/*Some specific platforms may have optimized intrinsic or inline assembly
versions of these functions which can substantially improve performance.
We define macros for them to allow easy incorporation of these non-ANSI
features.*/
/*Modern gcc (4.x) can compile the naive versions of min and max with cmov if
given an appropriate architecture, but the branchless bit-twiddling versions
are just as fast, and do not require any special target architecture.
Earlier gcc versions (3.x) compiled both code to the same assembly
instructions, because of the way they represented ((_b)>(_a)) internally.*/
# define EC_MINI(_a,_b) ((_a)+(((_b)-(_a))&-((_b)<(_a))))
/*Count leading zeros.
This macro should only be used for implementing ec_ilog(), if it is defined.
All other code should use EC_ILOG() instead.*/
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
# include <intrin.h>
/*In _DEBUG mode this is not an intrinsic by default.*/
# pragma intrinsic(_BitScanReverse)
static __inline int ec_bsr(unsigned long _x){
unsigned long ret;
_BitScanReverse(&ret,_x);
return (int)ret;
}
# define EC_CLZ0 (1)
# define EC_CLZ(_x) (-ec_bsr(_x))
#elif defined(ENABLE_TI_DSPLIB)
# include "dsplib.h"
# define EC_CLZ0 (31)
# define EC_CLZ(_x) (_lnorm(_x))
#elif __GNUC_PREREQ(3,4)
# if INT_MAX>=2147483647
# define EC_CLZ0 ((int)sizeof(unsigned)*CHAR_BIT)
# define EC_CLZ(_x) (__builtin_clz(_x))
# elif LONG_MAX>=2147483647L
# define EC_CLZ0 ((int)sizeof(unsigned long)*CHAR_BIT)
# define EC_CLZ(_x) (__builtin_clzl(_x))
# endif
#endif
#if defined(EC_CLZ)
/*Note that __builtin_clz is not defined when _x==0, according to the gcc
documentation (and that of the BSR instruction that implements it on x86).
The majority of the time we can never pass it zero.
When we need to, it can be special cased.*/
# define EC_ILOG(_x) (EC_CLZ0-EC_CLZ(_x))
#else
int ec_ilog(opus_uint32 _v);
# define EC_ILOG(_x) (ec_ilog(_x))
#endif
#endif

View File

@ -0,0 +1,93 @@
/* Copyright (c) 2001-2011 Timothy B. Terriberry
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "entcode.h"
#include "arch.h"
#if !defined(EC_CLZ)
/*This is a fallback for systems where we don't know how to access
a BSR or CLZ instruction (see ecintrin.h).
If you are optimizing Opus on a new platform and it has a native CLZ or
BZR (e.g. cell, MIPS, x86, etc) then making it available to Opus will be
an easy performance win.*/
int ec_ilog(opus_uint32 _v){
/*On a Pentium M, this branchless version tested as the fastest on
1,000,000,000 random 32-bit integers, edging out a similar version with
branches, and a 256-entry LUT version.*/
int ret;
int m;
ret=!!_v;
m=!!(_v&0xFFFF0000)<<4;
_v>>=m;
ret|=m;
m=!!(_v&0xFF00)<<3;
_v>>=m;
ret|=m;
m=!!(_v&0xF0)<<2;
_v>>=m;
ret|=m;
m=!!(_v&0xC)<<1;
_v>>=m;
ret|=m;
ret+=!!(_v&0x2);
return ret;
}
#endif
opus_uint32 ec_tell_frac(ec_ctx *_this){
opus_uint32 nbits;
opus_uint32 r;
int l;
int i;
/*To handle the non-integral number of bits still left in the encoder/decoder
state, we compute the worst-case number of bits of val that must be
encoded to ensure that the value is inside the range for any possible
subsequent bits.
The computation here is independent of val itself (the decoder does not
even track that value), even though the real number of bits used after
ec_enc_done() may be 1 smaller if rng is a power of two and the
corresponding trailing bits of val are all zeros.
If we did try to track that special case, then coding a value with a
probability of 1/(1<<n) might sometimes appear to use more than n bits.
This may help explain the surprising result that a newly initialized
encoder or decoder claims to have used 1 bit.*/
nbits=_this->nbits_total<<BITRES;
l=EC_ILOG(_this->rng);
r=_this->rng>>(l-16);
for(i=BITRES;i-->0;){
int b;
r=r*r>>15;
b=(int)(r>>16);
l=l<<1|b;
r>>=b;
}
return nbits-l;
}

View File

@ -0,0 +1,116 @@
/* Copyright (c) 2001-2011 Timothy B. Terriberry
Copyright (c) 2008-2009 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "opus_types.h"
#if !defined(_entcode_H)
# define _entcode_H (1)
# include <limits.h>
# include <stddef.h>
# include "ecintrin.h"
/*OPT: ec_window must be at least 32 bits, but if you have fast arithmetic on a
larger type, you can speed up the decoder by using it here.*/
typedef opus_uint32 ec_window;
typedef struct ec_ctx ec_ctx;
typedef struct ec_ctx ec_enc;
typedef struct ec_ctx ec_dec;
# define EC_WINDOW_SIZE ((int)sizeof(ec_window)*CHAR_BIT)
/*The number of bits to use for the range-coded part of unsigned integers.*/
# define EC_UINT_BITS (8)
/*The resolution of fractional-precision bit usage measurements, i.e.,
3 => 1/8th bits.*/
# define BITRES 3
/*The entropy encoder/decoder context.
We use the same structure for both, so that common functions like ec_tell()
can be used on either one.*/
struct ec_ctx{
/*Buffered input/output.*/
unsigned char *buf;
/*The size of the buffer.*/
opus_uint32 storage;
/*The offset at which the last byte containing raw bits was read/written.*/
opus_uint32 end_offs;
/*Bits that will be read from/written at the end.*/
ec_window end_window;
/*Number of valid bits in end_window.*/
int nend_bits;
/*The total number of whole bits read/written.
This does not include partial bits currently in the range coder.*/
int nbits_total;
/*The offset at which the next range coder byte will be read/written.*/
opus_uint32 offs;
/*The number of values in the current range.*/
opus_uint32 rng;
/*In the decoder: the difference between the top of the current range and
the input value, minus one.
In the encoder: the low end of the current range.*/
opus_uint32 val;
/*In the decoder: the saved normalization factor from ec_decode().
In the encoder: the number of oustanding carry propagating symbols.*/
opus_uint32 ext;
/*A buffered input/output symbol, awaiting carry propagation.*/
int rem;
/*Nonzero if an error occurred.*/
int error;
};
static inline opus_uint32 ec_range_bytes(ec_ctx *_this){
return _this->offs;
}
static inline unsigned char *ec_get_buffer(ec_ctx *_this){
return _this->buf;
}
static inline int ec_get_error(ec_ctx *_this){
return _this->error;
}
/*Returns the number of bits "used" by the encoded or decoded symbols so far.
This same number can be computed in either the encoder or the decoder, and is
suitable for making coding decisions.
Return: The number of bits.
This will always be slightly larger than the exact value (e.g., all
rounding error is in the positive direction).*/
static inline int ec_tell(ec_ctx *_this){
return _this->nbits_total-EC_ILOG(_this->rng);
}
/*Returns the number of bits "used" by the encoded or decoded symbols so far.
This same number can be computed in either the encoder or the decoder, and is
suitable for making coding decisions.
Return: The number of bits scaled by 2**BITRES.
This will always be slightly larger than the exact value (e.g., all
rounding error is in the positive direction).*/
opus_uint32 ec_tell_frac(ec_ctx *_this);
#endif

View File

@ -0,0 +1,245 @@
/* Copyright (c) 2001-2011 Timothy B. Terriberry
Copyright (c) 2008-2009 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stddef.h>
#include "os_support.h"
#include "arch.h"
#include "entdec.h"
#include "mfrngcod.h"
/*A range decoder.
This is an entropy decoder based upon \cite{Mar79}, which is itself a
rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}.
It is very similar to arithmetic encoding, except that encoding is done with
digits in any base, instead of with bits, and so it is faster when using
larger bases (i.e.: a byte).
The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$
is the base, longer than the theoretical optimum, but to my knowledge there
is no published justification for this claim.
This only seems true when using near-infinite precision arithmetic so that
the process is carried out with no rounding errors.
An excellent description of implementation details is available at
http://www.arturocampos.com/ac_range.html
A recent work \cite{MNW98} which proposes several changes to arithmetic
encoding for efficiency actually re-discovers many of the principles
behind range encoding, and presents a good theoretical analysis of them.
End of stream is handled by writing out the smallest number of bits that
ensures that the stream will be correctly decoded regardless of the value of
any subsequent bits.
ec_tell() can be used to determine how many bits were needed to decode
all the symbols thus far; other data can be packed in the remaining bits of
the input buffer.
@PHDTHESIS{Pas76,
author="Richard Clark Pasco",
title="Source coding algorithms for fast data compression",
school="Dept. of Electrical Engineering, Stanford University",
address="Stanford, CA",
month=May,
year=1976
}
@INPROCEEDINGS{Mar79,
author="Martin, G.N.N.",
title="Range encoding: an algorithm for removing redundancy from a digitised
message",
booktitle="Video & Data Recording Conference",
year=1979,
address="Southampton",
month=Jul
}
@ARTICLE{MNW98,
author="Alistair Moffat and Radford Neal and Ian H. Witten",
title="Arithmetic Coding Revisited",
journal="{ACM} Transactions on Information Systems",
year=1998,
volume=16,
number=3,
pages="256--294",
month=Jul,
URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
}*/
static int ec_read_byte(ec_dec *_this){
return _this->offs<_this->storage?_this->buf[_this->offs++]:0;
}
static int ec_read_byte_from_end(ec_dec *_this){
return _this->end_offs<_this->storage?
_this->buf[_this->storage-++(_this->end_offs)]:0;
}
/*Normalizes the contents of val and rng so that rng lies entirely in the
high-order symbol.*/
static void ec_dec_normalize(ec_dec *_this){
/*If the range is too small, rescale it and input some bits.*/
while(_this->rng<=EC_CODE_BOT){
int sym;
_this->nbits_total+=EC_SYM_BITS;
_this->rng<<=EC_SYM_BITS;
/*Use up the remaining bits from our last symbol.*/
sym=_this->rem;
/*Read the next value from the input.*/
_this->rem=ec_read_byte(_this);
/*Take the rest of the bits we need from this new symbol.*/
sym=(sym<<EC_SYM_BITS|_this->rem)>>(EC_SYM_BITS-EC_CODE_EXTRA);
/*And subtract them from val, capped to be less than EC_CODE_TOP.*/
_this->val=((_this->val<<EC_SYM_BITS)+(EC_SYM_MAX&~sym))&(EC_CODE_TOP-1);
}
}
void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage){
_this->buf=_buf;
_this->storage=_storage;
_this->end_offs=0;
_this->end_window=0;
_this->nend_bits=0;
/*This is the offset from which ec_tell() will subtract partial bits.
The final value after the ec_dec_normalize() call will be the same as in
the encoder, but we have to compensate for the bits that are added there.*/
_this->nbits_total=EC_CODE_BITS+1
-((EC_CODE_BITS-EC_CODE_EXTRA)/EC_SYM_BITS)*EC_SYM_BITS;
_this->offs=0;
_this->rng=1U<<EC_CODE_EXTRA;
_this->rem=ec_read_byte(_this);
_this->val=_this->rng-1-(_this->rem>>(EC_SYM_BITS-EC_CODE_EXTRA));
_this->error=0;
/*Normalize the interval.*/
ec_dec_normalize(_this);
}
unsigned ec_decode(ec_dec *_this,unsigned _ft){
unsigned s;
_this->ext=_this->rng/_ft;
s=(unsigned)(_this->val/_this->ext);
return _ft-EC_MINI(s+1,_ft);
}
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){
unsigned s;
_this->ext=_this->rng>>_bits;
s=(unsigned)(_this->val/_this->ext);
return (1U<<_bits)-EC_MINI(s+1U,1U<<_bits);
}
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
opus_uint32 s;
s=IMUL32(_this->ext,_ft-_fh);
_this->val-=s;
_this->rng=_fl>0?IMUL32(_this->ext,_fh-_fl):_this->rng-s;
ec_dec_normalize(_this);
}
/*The probability of having a "one" is 1/(1<<_logp).*/
int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){
opus_uint32 r;
opus_uint32 d;
opus_uint32 s;
int ret;
r=_this->rng;
d=_this->val;
s=r>>_logp;
ret=d<s;
if(!ret)_this->val=d-s;
_this->rng=ret?s:r-s;
ec_dec_normalize(_this);
return ret;
}
int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){
opus_uint32 r;
opus_uint32 d;
opus_uint32 s;
opus_uint32 t;
int ret;
s=_this->rng;
d=_this->val;
r=s>>_ftb;
ret=-1;
do{
t=s;
s=IMUL32(r,_icdf[++ret]);
}
while(d<s);
_this->val=d-s;
_this->rng=t-s;
ec_dec_normalize(_this);
return ret;
}
opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft){
unsigned ft;
unsigned s;
int ftb;
/*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
celt_assert(_ft>1);
_ft--;
ftb=EC_ILOG(_ft);
if(ftb>EC_UINT_BITS){
opus_uint32 t;
ftb-=EC_UINT_BITS;
ft=(unsigned)(_ft>>ftb)+1;
s=ec_decode(_this,ft);
ec_dec_update(_this,s,s+1,ft);
t=(opus_uint32)s<<ftb|ec_dec_bits(_this,ftb);
if(t<=_ft)return t;
_this->error=1;
return _ft;
}
else{
_ft++;
s=ec_decode(_this,(unsigned)_ft);
ec_dec_update(_this,s,s+1,(unsigned)_ft);
return s;
}
}
opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _bits){
ec_window window;
int available;
opus_uint32 ret;
window=_this->end_window;
available=_this->nend_bits;
if((unsigned)available<_bits){
do{
window|=(ec_window)ec_read_byte_from_end(_this)<<available;
available+=EC_SYM_BITS;
}
while(available<=EC_WINDOW_SIZE-EC_SYM_BITS);
}
ret=(opus_uint32)window&(((opus_uint32)1<<_bits)-1U);
window>>=_bits;
available-=_bits;
_this->end_window=window;
_this->nend_bits=available;
_this->nbits_total+=_bits;
return ret;
}

View File

@ -0,0 +1,100 @@
/* Copyright (c) 2001-2011 Timothy B. Terriberry
Copyright (c) 2008-2009 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(_entdec_H)
# define _entdec_H (1)
# include <limits.h>
# include "entcode.h"
/*Initializes the decoder.
_buf: The input buffer to use.
Return: 0 on success, or a negative value on error.*/
void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage);
/*Calculates the cumulative frequency for the next symbol.
This can then be fed into the probability model to determine what that
symbol is, and the additional frequency information required to advance to
the next symbol.
This function cannot be called more than once without a corresponding call to
ec_dec_update(), or decoding will not proceed correctly.
_ft: The total frequency of the symbols in the alphabet the next symbol was
encoded with.
Return: A cumulative frequency representing the encoded symbol.
If the cumulative frequency of all the symbols before the one that
was encoded was fl, and the cumulative frequency of all the symbols
up to and including the one encoded is fh, then the returned value
will fall in the range [fl,fh).*/
unsigned ec_decode(ec_dec *_this,unsigned _ft);
/*Equivalent to ec_decode() with _ft==1<<_bits.*/
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits);
/*Advance the decoder past the next symbol using the frequency information the
symbol was encoded with.
Exactly one call to ec_decode() must have been made so that all necessary
intermediate calculations are performed.
_fl: The cumulative frequency of all symbols that come before the symbol
decoded.
_fh: The cumulative frequency of all symbols up to and including the symbol
decoded.
Together with _fl, this defines the range [_fl,_fh) in which the value
returned above must fall.
_ft: The total frequency of the symbols in the alphabet the symbol decoded
was encoded in.
This must be the same as passed to the preceding call to ec_decode().*/
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft);
/* Decode a bit that has a 1/(1<<_logp) probability of being a one */
int ec_dec_bit_logp(ec_dec *_this,unsigned _logp);
/*Decodes a symbol given an "inverse" CDF table.
No call to ec_dec_update() is necessary after this call.
_icdf: The "inverse" CDF, such that symbol s falls in the range
[s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb.
The values must be monotonically non-increasing, and the last value
must be 0.
_ftb: The number of bits of precision in the cumulative distribution.
Return: The decoded symbol s.*/
int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb);
/*Extracts a raw unsigned integer with a non-power-of-2 range from the stream.
The bits must have been encoded with ec_enc_uint().
No call to ec_dec_update() is necessary after this call.
_ft: The number of integers that can be decoded (one more than the max).
This must be at least one, and no more than 2**32-1.
Return: The decoded bits.*/
opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft);
/*Extracts a sequence of raw bits from the stream.
The bits must have been encoded with ec_enc_bits().
No call to ec_dec_update() is necessary after this call.
_ftb: The number of bits to extract.
This must be between 0 and 25, inclusive.
Return: The decoded bits.*/
opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb);
#endif

View File

@ -0,0 +1,294 @@
/* Copyright (c) 2001-2011 Timothy B. Terriberry
Copyright (c) 2008-2009 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(HAVE_CONFIG_H)
# include "config.h"
#endif
#include "os_support.h"
#include "arch.h"
#include "entenc.h"
#include "mfrngcod.h"
/*A range encoder.
See entdec.c and the references for implementation details \cite{Mar79,MNW98}.
@INPROCEEDINGS{Mar79,
author="Martin, G.N.N.",
title="Range encoding: an algorithm for removing redundancy from a digitised
message",
booktitle="Video \& Data Recording Conference",
year=1979,
address="Southampton",
month=Jul
}
@ARTICLE{MNW98,
author="Alistair Moffat and Radford Neal and Ian H. Witten",
title="Arithmetic Coding Revisited",
journal="{ACM} Transactions on Information Systems",
year=1998,
volume=16,
number=3,
pages="256--294",
month=Jul,
URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
}*/
static int ec_write_byte(ec_enc *_this,unsigned _value){
if(_this->offs+_this->end_offs>=_this->storage)return -1;
_this->buf[_this->offs++]=(unsigned char)_value;
return 0;
}
static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){
if(_this->offs+_this->end_offs>=_this->storage)return -1;
_this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value;
return 0;
}
/*Outputs a symbol, with a carry bit.
If there is a potential to propagate a carry over several symbols, they are
buffered until it can be determined whether or not an actual carry will
occur.
If the counter for the buffered symbols overflows, then the stream becomes
undecodable.
This gives a theoretical limit of a few billion symbols in a single packet on
32-bit systems.
The alternative is to truncate the range in order to force a carry, but
requires similar carry tracking in the decoder, needlessly slowing it down.*/
static void ec_enc_carry_out(ec_enc *_this,int _c){
if(_c!=EC_SYM_MAX){
/*No further carry propagation possible, flush buffer.*/
int carry;
carry=_c>>EC_SYM_BITS;
/*Don't output a byte on the first write.
This compare should be taken care of by branch-prediction thereafter.*/
if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry);
if(_this->ext>0){
unsigned sym;
sym=(EC_SYM_MAX+carry)&EC_SYM_MAX;
do _this->error|=ec_write_byte(_this,sym);
while(--(_this->ext)>0);
}
_this->rem=_c&EC_SYM_MAX;
}
else _this->ext++;
}
static void ec_enc_normalize(ec_enc *_this){
/*If the range is too small, output some bits and rescale it.*/
while(_this->rng<=EC_CODE_BOT){
ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT));
/*Move the next-to-high-order symbol into the high-order position.*/
_this->val=(_this->val<<EC_SYM_BITS)&(EC_CODE_TOP-1);
_this->rng<<=EC_SYM_BITS;
_this->nbits_total+=EC_SYM_BITS;
}
}
void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){
_this->buf=_buf;
_this->end_offs=0;
_this->end_window=0;
_this->nend_bits=0;
/*This is the offset from which ec_tell() will subtract partial bits.*/
_this->nbits_total=EC_CODE_BITS+1;
_this->offs=0;
_this->rng=EC_CODE_TOP;
_this->rem=-1;
_this->val=0;
_this->ext=0;
_this->storage=_size;
_this->error=0;
}
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
opus_uint32 r;
r=_this->rng/_ft;
if(_fl>0){
_this->val+=_this->rng-IMUL32(r,(_ft-_fl));
_this->rng=IMUL32(r,(_fh-_fl));
}
else _this->rng-=IMUL32(r,(_ft-_fh));
ec_enc_normalize(_this);
}
void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){
opus_uint32 r;
r=_this->rng>>_bits;
if(_fl>0){
_this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl));
_this->rng=IMUL32(r,(_fh-_fl));
}
else _this->rng-=IMUL32(r,((1U<<_bits)-_fh));
ec_enc_normalize(_this);
}
/*The probability of having a "one" is 1/(1<<_logp).*/
void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
opus_uint32 r;
opus_uint32 s;
opus_uint32 l;
r=_this->rng;
l=_this->val;
s=r>>_logp;
r-=s;
if(_val)_this->val=l+r;
_this->rng=_val?s:r;
ec_enc_normalize(_this);
}
void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){
opus_uint32 r;
r=_this->rng>>_ftb;
if(_s>0){
_this->val+=_this->rng-IMUL32(r,_icdf[_s-1]);
_this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
}
else _this->rng-=IMUL32(r,_icdf[_s]);
ec_enc_normalize(_this);
}
void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){
unsigned ft;
unsigned fl;
int ftb;
/*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
celt_assert(_ft>1);
_ft--;
ftb=EC_ILOG(_ft);
if(ftb>EC_UINT_BITS){
ftb-=EC_UINT_BITS;
ft=(_ft>>ftb)+1;
fl=(unsigned)(_fl>>ftb);
ec_encode(_this,fl,fl+1,ft);
ec_enc_bits(_this,_fl&(((opus_uint32)1<<ftb)-1U),ftb);
}
else ec_encode(_this,_fl,_fl+1,_ft+1);
}
void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _bits){
ec_window window;
int used;
window=_this->end_window;
used=_this->nend_bits;
celt_assert(_bits>0);
if(used+_bits>EC_WINDOW_SIZE){
do{
_this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
window>>=EC_SYM_BITS;
used-=EC_SYM_BITS;
}
while(used>=EC_SYM_BITS);
}
window|=(ec_window)_fl<<used;
used+=_bits;
_this->end_window=window;
_this->nend_bits=used;
_this->nbits_total+=_bits;
}
void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){
int shift;
unsigned mask;
celt_assert(_nbits<=EC_SYM_BITS);
shift=EC_SYM_BITS-_nbits;
mask=((1<<_nbits)-1)<<shift;
if(_this->offs>0){
/*The first byte has been finalized.*/
_this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<<shift);
}
else if(_this->rem>=0){
/*The first byte is still awaiting carry propagation.*/
_this->rem=(_this->rem&~mask)|_val<<shift;
}
else if(_this->rng<=(EC_CODE_TOP>>_nbits)){
/*The renormalization loop has never been run.*/
_this->val=(_this->val&~((opus_uint32)mask<<EC_CODE_SHIFT))|
(opus_uint32)_val<<(EC_CODE_SHIFT+shift);
}
/*The encoder hasn't even encoded _nbits of data yet.*/
else _this->error=-1;
}
void ec_enc_shrink(ec_enc *_this,opus_uint32 _size){
celt_assert(_this->offs+_this->end_offs<=_size);
OPUS_MOVE(_this->buf+_size-_this->end_offs,
_this->buf+_this->storage-_this->end_offs,_this->end_offs);
_this->storage=_size;
}
void ec_enc_done(ec_enc *_this){
ec_window window;
int used;
opus_uint32 msk;
opus_uint32 end;
int l;
/*We output the minimum number of bits that ensures that the symbols encoded
thus far will be decoded correctly regardless of the bits that follow.*/
l=EC_CODE_BITS-EC_ILOG(_this->rng);
msk=(EC_CODE_TOP-1)>>l;
end=(_this->val+msk)&~msk;
if((end|msk)>=_this->val+_this->rng){
l++;
msk>>=1;
end=(_this->val+msk)&~msk;
}
while(l>0){
ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT));
end=(end<<EC_SYM_BITS)&(EC_CODE_TOP-1);
l-=EC_SYM_BITS;
}
/*If we have a buffered byte flush it into the output buffer.*/
if(_this->rem>=0||_this->ext>0)ec_enc_carry_out(_this,0);
/*If we have buffered extra bits, flush them as well.*/
window=_this->end_window;
used=_this->nend_bits;
while(used>=EC_SYM_BITS){
_this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
window>>=EC_SYM_BITS;
used-=EC_SYM_BITS;
}
/*Clear any excess space and add any remaining extra bits to the last byte.*/
if(!_this->error){
OPUS_CLEAR(_this->buf+_this->offs,
_this->storage-_this->offs-_this->end_offs);
if(used>0){
/*If there's no range coder data at all, give up.*/
if(_this->end_offs>=_this->storage)_this->error=-1;
else{
l=-l;
/*If we've busted, don't add too many extra bits to the last byte; it
would corrupt the range coder data, and that's more important.*/
if(_this->offs+_this->end_offs>=_this->storage&&l<used){
window&=(1<<l)-1;
_this->error=-1;
}
_this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window;
}
}
}
}

View File

@ -0,0 +1,110 @@
/* Copyright (c) 2001-2011 Timothy B. Terriberry
Copyright (c) 2008-2009 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(_entenc_H)
# define _entenc_H (1)
# include <stddef.h>
# include "entcode.h"
/*Initializes the encoder.
_buf: The buffer to store output bytes in.
_size: The size of the buffer, in chars.*/
void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size);
/*Encodes a symbol given its frequency information.
The frequency information must be discernable by the decoder, assuming it
has read only the previous symbols from the stream.
It is allowable to change the frequency information, or even the entire
source alphabet, so long as the decoder can tell from the context of the
previously encoded information that it is supposed to do so as well.
_fl: The cumulative frequency of all symbols that come before the one to be
encoded.
_fh: The cumulative frequency of all symbols up to and including the one to
be encoded.
Together with _fl, this defines the range [_fl,_fh) in which the
decoded value will fall.
_ft: The sum of the frequencies of all the symbols*/
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft);
/*Equivalent to ec_encode() with _ft==1<<_bits.*/
void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits);
/* Encode a bit that has a 1/(1<<_logp) probability of being a one */
void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp);
/*Encodes a symbol given an "inverse" CDF table.
_s: The index of the symbol to encode.
_icdf: The "inverse" CDF, such that symbol _s falls in the range
[_s>0?ft-_icdf[_s-1]:0,ft-_icdf[_s]), where ft=1<<_ftb.
The values must be monotonically non-increasing, and the last value
must be 0.
_ftb: The number of bits of precision in the cumulative distribution.*/
void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb);
/*Encodes a raw unsigned integer in the stream.
_fl: The integer to encode.
_ft: The number of integers that can be encoded (one more than the max).
This must be at least one, and no more than 2**32-1.*/
void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft);
/*Encodes a sequence of raw bits in the stream.
_fl: The bits to encode.
_ftb: The number of bits to encode.
This must be between 1 and 25, inclusive.*/
void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _ftb);
/*Overwrites a few bits at the very start of an existing stream, after they
have already been encoded.
This makes it possible to have a few flags up front, where it is easy for
decoders to access them without parsing the whole stream, even if their
values are not determined until late in the encoding process, without having
to buffer all the intermediate symbols in the encoder.
In order for this to work, at least _nbits bits must have already been
encoded using probabilities that are an exact power of two.
The encoder can verify the number of encoded bits is sufficient, but cannot
check this latter condition.
_val: The bits to encode (in the least _nbits significant bits).
They will be decoded in order from most-significant to least.
_nbits: The number of bits to overwrite.
This must be no more than 8.*/
void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits);
/*Compacts the data to fit in the target size.
This moves up the raw bits at the end of the current buffer so they are at
the end of the new buffer size.
The caller must ensure that the amount of data that's already been written
will fit in the new size.
_size: The number of bytes in the new buffer.
This must be large enough to contain the bits already written, and
must be no larger than the existing size.*/
void ec_enc_shrink(ec_enc *_this,opus_uint32 _size);
/*Indicates that there are no more symbols to encode.
All reamining output bytes are flushed to the output buffer.
ec_enc_init() must be called before the encoder can be used again.*/
void ec_enc_done(ec_enc *_this);
#endif

View File

@ -0,0 +1,763 @@
/* Copyright (C) 2003-2008 Jean-Marc Valin
Copyright (C) 2007-2012 Xiph.Org Foundation */
/**
@file fixed_debug.h
@brief Fixed-point operations with debugging
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_DEBUG_H
#define FIXED_DEBUG_H
#include <stdio.h>
#ifdef CELT_C
#include "opus_defines.h"
OPUS_EXPORT opus_int64 celt_mips=0;
#else
extern opus_int64 celt_mips;
#endif
#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL32(MULT16_16(SHR32((a),16),SHR((b),16)),1), SHR32(MULT16_16SU(SHR32((a),16),((b)&0x0000ffff)),15)), SHR32(MULT16_16SU(SHR32((b),16),((a)&0x0000ffff)),15))
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16))
#define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16)
#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
#define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1))
#define SHR(a,b) SHR32(a,b)
#define PSHR(a,b) PSHR32(a,b)
static inline short NEG16(int x)
{
int res;
if (!VERIFY_SHORT(x))
{
fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = -x;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips++;
return res;
}
static inline int NEG32(opus_int64 x)
{
opus_int64 res;
if (!VERIFY_INT(x))
{
fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = -x;
if (!VERIFY_INT(res))
{
fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=2;
return res;
}
#define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)
static inline short EXTRACT16_(int x, char *file, int line)
{
int res;
if (!VERIFY_SHORT(x))
{
fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = x;
celt_mips++;
return res;
}
#define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)
static inline int EXTEND32_(int x, char *file, int line)
{
int res;
if (!VERIFY_SHORT(x))
{
fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = x;
celt_mips++;
return res;
}
#define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)
static inline short SHR16_(int a, int shift, char *file, int line)
{
int res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
{
fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a>>shift;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips++;
return res;
}
#define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)
static inline short SHL16_(int a, int shift, char *file, int line)
{
int res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
{
fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a<<shift;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips++;
return res;
}
static inline int SHR32(opus_int64 a, int shift)
{
opus_int64 res;
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
{
fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a>>shift;
if (!VERIFY_INT(res))
{
fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=2;
return res;
}
#define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__)
static inline int SHL32_(opus_int64 a, int shift, char *file, int line)
{
opus_int64 res;
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
{
fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", a, shift, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a<<shift;
if (!VERIFY_INT(res))
{
fprintf (stderr, "SHL32: output is not int: %lld<<%d = %lld in %s: line %d\n", a, shift, res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=2;
return res;
}
#define PSHR32(a,shift) (celt_mips--,SHR32(ADD32((a),(((opus_val32)(1)<<((shift))>>1))),shift))
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
#define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
#define HALF16(x) (SHR16(x,1))
#define HALF32(x) (SHR32(x,1))
//#define SHR(a,shift) ((a) >> (shift))
//#define SHL(a,shift) ((a) << (shift))
#define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
static inline short ADD16_(int a, int b, char *file, int line)
{
int res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a+b;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips++;
return res;
}
#define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)
static inline short SUB16_(int a, int b, char *file, int line)
{
int res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a-b;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips++;
return res;
}
#define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)
static inline int ADD32_(opus_int64 a, opus_int64 b, char *file, int line)
{
opus_int64 res;
if (!VERIFY_INT(a) || !VERIFY_INT(b))
{
fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a+b;
if (!VERIFY_INT(res))
{
fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=2;
return res;
}
#define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)
static inline int SUB32_(opus_int64 a, opus_int64 b, char *file, int line)
{
opus_int64 res;
if (!VERIFY_INT(a) || !VERIFY_INT(b))
{
fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a-b;
if (!VERIFY_INT(res))
{
fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=2;
return res;
}
#undef UADD32
#define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)
static inline unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line)
{
opus_uint64 res;
if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
{
fprintf (stderr, "UADD32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a+b;
if (!VERIFY_UINT(res))
{
fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=2;
return res;
}
#undef USUB32
#define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)
static inline unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line)
{
opus_uint64 res;
if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
{
fprintf (stderr, "USUB32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
if (a<b)
{
fprintf (stderr, "USUB32: inputs underflow: %llu < %llu in %s: line %d\n", a, b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a-b;
if (!VERIFY_UINT(res))
{
fprintf (stderr, "USUB32: output is not uint32: %llu - %llu = %llu in %s: line %d\n", a, b, res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=2;
return res;
}
/* result fits in 16 bits */
static inline short MULT16_16_16(int a, int b)
{
int res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a*b;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips++;
return res;
}
#define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
static inline int MULT16_16_(int a, int b, char *file, int line)
{
opus_int64 res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = ((opus_int64)a)*b;
if (!VERIFY_INT(res))
{
fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips++;
return res;
}
#define MAC16_16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
#define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__)
static inline int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line)
{
opus_int64 res;
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
{
fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
if (ABS32(b)>=((opus_val32)(1)<<(15+Q)))
{
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = (((opus_int64)a)*(opus_int64)b) >> Q;
if (!VERIFY_INT(res))
{
fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
if (Q==15)
celt_mips+=3;
else
celt_mips+=4;
return res;
}
#define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__)
static inline int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line)
{
opus_int64 res;
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
{
fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d in %s: line %d\n\n", Q, (int)a, (int)b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
if (ABS32(b)>=((opus_int64)(1)<<(15+Q)))
{
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n\n", Q, (int)a, (int)b,file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<<Q)>>1))>> Q;
if (!VERIFY_INT(res))
{
fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d in %s: line %d\n\n", Q, (int)a, (int)b,(int)res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
if (Q==15)
celt_mips+=4;
else
celt_mips+=5;
return res;
}
#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
#define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
static inline int SATURATE(int a, int b)
{
if (a>b)
a=b;
if (a<-b)
a = -b;
celt_mips+=3;
return a;
}
static inline int MULT16_16_Q11_32(int a, int b)
{
opus_int64 res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = ((opus_int64)a)*b;
res >>= 11;
if (!VERIFY_INT(res))
{
fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=3;
return res;
}
static inline short MULT16_16_Q13(int a, int b)
{
opus_int64 res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = ((opus_int64)a)*b;
res >>= 13;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=3;
return res;
}
static inline short MULT16_16_Q14(int a, int b)
{
opus_int64 res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = ((opus_int64)a)*b;
res >>= 14;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=3;
return res;
}
#define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
static inline short MULT16_16_Q15_(int a, int b, char *file, int line)
{
opus_int64 res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = ((opus_int64)a)*b;
res >>= 15;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=1;
return res;
}
static inline short MULT16_16_P13(int a, int b)
{
opus_int64 res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = ((opus_int64)a)*b;
res += 4096;
if (!VERIFY_INT(res))
{
fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res >>= 13;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=4;
return res;
}
static inline short MULT16_16_P14(int a, int b)
{
opus_int64 res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = ((opus_int64)a)*b;
res += 8192;
if (!VERIFY_INT(res))
{
fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res >>= 14;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=4;
return res;
}
static inline short MULT16_16_P15(int a, int b)
{
opus_int64 res;
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = ((opus_int64)a)*b;
res += 16384;
if (!VERIFY_INT(res))
{
fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res >>= 15;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=2;
return res;
}
#define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
static inline int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
{
opus_int64 res;
if (b==0)
{
fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
return 0;
}
if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
{
fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a/b;
if (!VERIFY_SHORT(res))
{
fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
if (res>32767)
res = 32767;
if (res<-32768)
res = -32768;
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=35;
return res;
}
#define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
static inline int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)
{
opus_int64 res;
if (b==0)
{
fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
return 0;
}
if (!VERIFY_INT(a) || !VERIFY_INT(b))
{
fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
res = a/b;
if (!VERIFY_INT(res))
{
fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
#ifdef FIXED_DEBUG_ASSERT
celt_assert(0);
#endif
}
celt_mips+=70;
return res;
}
#undef PRINT_MIPS
#define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0);
#endif

View File

@ -0,0 +1,129 @@
/* Copyright (C) 2007-2009 Xiph.Org Foundation
Copyright (C) 2003-2008 Jean-Marc Valin
Copyright (C) 2007-2008 CSIRO */
/**
@file fixed_generic.h
@brief Generic fixed-point operations
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_GENERIC_H
#define FIXED_GENERIC_H
/** Multiply a 16-bit signed value by a 16-bit unsigned value. The result is a 32-bit signed value */
#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */
#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16((a),((b)&0x0000ffff)),16))
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))
/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */
#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15))
/** Compile-time conversion of float constant to 16-bit value */
#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
/** Compile-time conversion of float constant to 32-bit value */
#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
/** Negate a 16-bit value */
#define NEG16(x) (-(x))
/** Negate a 32-bit value */
#define NEG32(x) (-(x))
/** Change a 32-bit value into a 16-bit value. The value is assumed to fit in 16-bit, otherwise the result is undefined */
#define EXTRACT16(x) ((opus_val16)(x))
/** Change a 16-bit value into a 32-bit value */
#define EXTEND32(x) ((opus_val32)(x))
/** Arithmetic shift-right of a 16-bit value */
#define SHR16(a,shift) ((a) >> (shift))
/** Arithmetic shift-left of a 16-bit value */
#define SHL16(a,shift) ((opus_int16)((opus_uint16)(a)<<(shift)))
/** Arithmetic shift-right of a 32-bit value */
#define SHR32(a,shift) ((a) >> (shift))
/** Arithmetic shift-left of a 32-bit value */
#define SHL32(a,shift) ((opus_int32)((opus_uint32)(a)<<(shift)))
/** 32-bit arithmetic shift right with rounding-to-nearest instead of rounding down */
#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))
/** 32-bit arithmetic shift right where the argument can be negative */
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
/** "RAW" macros, should not be used outside of this header file */
#define SHR(a,shift) ((a) >> (shift))
#define SHL(a,shift) SHL32(a,shift)
#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */
#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))
/** Divide by two */
#define HALF16(x) (SHR16(x,1))
#define HALF32(x) (SHR32(x,1))
/** Add two 16-bit values */
#define ADD16(a,b) ((opus_val16)((opus_val16)(a)+(opus_val16)(b)))
/** Subtract two 16-bit values */
#define SUB16(a,b) ((opus_val16)(a)-(opus_val16)(b))
/** Add two 32-bit values */
#define ADD32(a,b) ((opus_val32)(a)+(opus_val32)(b))
/** Subtract two 32-bit values */
#define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b))
/** 16x16 multiplication where the result fits in 16 bits */
#define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b))))
/* (opus_val32)(opus_val16) gives TI compiler a hint that it's 16x16->32 multiply */
/** 16x16 multiplication where the result fits in 32 bits */
#define MULT16_16(a,b) (((opus_val32)(opus_val16)(a))*((opus_val32)(opus_val16)(b)))
/** 16x16 multiply-add where the result fits in 32 bits */
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
/** 16x32 multiply-add, followed by a 15-bit shift right. Results fits in 32 bits */
#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
/** Divide a 32-bit value by a 16-bit value. Result fits in 16 bits */
#define DIV32_16(a,b) ((opus_val16)(((opus_val32)(a))/((opus_val16)(b))))
/** Divide a 32-bit value by a 32-bit value. Result fits in 32 bits */
#define DIV32(a,b) (((opus_val32)(a))/((opus_val32)(b)))
#endif

View File

@ -0,0 +1,147 @@
/* Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com> */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Version 1.1 */
#ifndef FLOAT_CAST_H
#define FLOAT_CAST_H
#include "arch.h"
/*============================================================================
** On Intel Pentium processors (especially PIII and probably P4), converting
** from float to int is very slow. To meet the C specs, the code produced by
** most C compilers targeting Pentium needs to change the FPU rounding mode
** before the float to int conversion is performed.
**
** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
** is this flushing of the pipeline which is so slow.
**
** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
** llrint and llrintf which fix this problem as a side effect.
**
** On Unix-like systems, the configure process should have detected the
** presence of these functions. If they weren't found we have to replace them
** here with a standard C cast.
*/
/*
** The C99 prototypes for lrint and lrintf are as follows:
**
** long int lrintf (float x) ;
** long int lrint (double x) ;
*/
/* The presence of the required functions are detected during the configure
** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
** the config.h file.
*/
#if (defined(__GNUC__) && defined(_WIN64))
#include <xmmintrin.h>
static __inline long int float2int(float value)
{
return _mm_cvtss_si32(_mm_load_ss(&value));
}
#elif (HAVE_LRINTF)
/* These defines enable functionality introduced with the 1999 ISO C
** standard. They must be defined before the inclusion of math.h to
** engage them. If optimisation is enabled, these functions will be
** inlined. With optimisation switched off, you have to link in the
** maths library using -lm.
*/
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC9X 1
#define __USE_ISOC99 1
#include <math.h>
#define float2int(x) lrintf(x)
#elif (defined(HAVE_LRINT))
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC9X 1
#define __USE_ISOC99 1
#include <math.h>
#define float2int(x) lrint(x)
#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN64) || defined (_WIN64))
#include <xmmintrin.h>
__inline long int float2int(float value)
{
return _mm_cvtss_si32(_mm_load_ss(&value));
}
#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN32) || defined (_WIN32))
#include <math.h>
/* Win32 doesn't seem to have these functions.
** Therefore implement inline versions of these functions here.
*/
__inline long int
float2int (float flt)
{ int intgr;
_asm
{ fld flt
fistp intgr
} ;
return intgr ;
}
#else
#if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L)
/* supported by gcc in C99 mode, but not by all other compilers */
#warning "Don't have the functions lrint() and lrintf ()."
#warning "Replacing these functions with a standard C cast."
#endif /* __STDC_VERSION__ >= 199901L */
#include <math.h>
#define float2int(flt) ((int)(floor(.5+flt)))
#endif
#ifndef DISABLE_FLOAT_API
static inline opus_int16 FLOAT2INT16(float x)
{
x = x*CELT_SIG_SCALE;
x = MAX32(x, -32768);
x = MIN32(x, 32767);
return (opus_int16)float2int(x);
}
#endif /* DISABLE_FLOAT_API */
#endif /* FLOAT_CAST_H */

View File

@ -0,0 +1,722 @@
/*Copyright (c) 2003-2004, Mark Borgerding
Lots of modifications by Jean-Marc Valin
Copyright (c) 2005-2007, Xiph.Org Foundation
Copyright (c) 2008, Xiph.Org Foundation, CSIRO
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.*/
/* This code is originally from Mark Borgerding's KISS-FFT but has been
heavily modified to better suit Opus */
#ifndef SKIP_CONFIG_H
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
#endif
#include "_kiss_fft_guts.h"
#include "arch.h"
#include "os_support.h"
#include "mathops.h"
#include "stack_alloc.h"
#include "os_support.h"
/* The guts header contains all the multiplication and addition macros that are defined for
complex numbers. It also delares the kf_ internal functions.
*/
static void kf_bfly2(
kiss_fft_cpx * Fout,
const size_t fstride,
const kiss_fft_state *st,
int m,
int N,
int mm
)
{
kiss_fft_cpx * Fout2;
const kiss_twiddle_cpx * tw1;
int i,j;
kiss_fft_cpx * Fout_beg = Fout;
for (i=0;i<N;i++)
{
Fout = Fout_beg + i*mm;
Fout2 = Fout + m;
tw1 = st->twiddles;
for(j=0;j<m;j++)
{
kiss_fft_cpx t;
Fout->r = SHR32(Fout->r, 1);Fout->i = SHR32(Fout->i, 1);
Fout2->r = SHR32(Fout2->r, 1);Fout2->i = SHR32(Fout2->i, 1);
C_MUL (t, *Fout2 , *tw1);
tw1 += fstride;
C_SUB( *Fout2 , *Fout , t );
C_ADDTO( *Fout , t );
++Fout2;
++Fout;
}
}
}
static void ki_bfly2(
kiss_fft_cpx * Fout,
const size_t fstride,
const kiss_fft_state *st,
int m,
int N,
int mm
)
{
kiss_fft_cpx * Fout2;
const kiss_twiddle_cpx * tw1;
kiss_fft_cpx t;
int i,j;
kiss_fft_cpx * Fout_beg = Fout;
for (i=0;i<N;i++)
{
Fout = Fout_beg + i*mm;
Fout2 = Fout + m;
tw1 = st->twiddles;
for(j=0;j<m;j++)
{
C_MULC (t, *Fout2 , *tw1);
tw1 += fstride;
C_SUB( *Fout2 , *Fout , t );
C_ADDTO( *Fout , t );
++Fout2;
++Fout;
}
}
}
static void kf_bfly4(
kiss_fft_cpx * Fout,
const size_t fstride,
const kiss_fft_state *st,
int m,
int N,
int mm
)
{
const kiss_twiddle_cpx *tw1,*tw2,*tw3;
kiss_fft_cpx scratch[6];
const size_t m2=2*m;
const size_t m3=3*m;
int i, j;
kiss_fft_cpx * Fout_beg = Fout;
for (i=0;i<N;i++)
{
Fout = Fout_beg + i*mm;
tw3 = tw2 = tw1 = st->twiddles;
for (j=0;j<m;j++)
{
C_MUL4(scratch[0],Fout[m] , *tw1 );
C_MUL4(scratch[1],Fout[m2] , *tw2 );
C_MUL4(scratch[2],Fout[m3] , *tw3 );
Fout->r = PSHR32(Fout->r, 2);
Fout->i = PSHR32(Fout->i, 2);
C_SUB( scratch[5] , *Fout, scratch[1] );
C_ADDTO(*Fout, scratch[1]);
C_ADD( scratch[3] , scratch[0] , scratch[2] );
C_SUB( scratch[4] , scratch[0] , scratch[2] );
Fout[m2].r = PSHR32(Fout[m2].r, 2);
Fout[m2].i = PSHR32(Fout[m2].i, 2);
C_SUB( Fout[m2], *Fout, scratch[3] );
tw1 += fstride;
tw2 += fstride*2;
tw3 += fstride*3;
C_ADDTO( *Fout , scratch[3] );
Fout[m].r = scratch[5].r + scratch[4].i;
Fout[m].i = scratch[5].i - scratch[4].r;
Fout[m3].r = scratch[5].r - scratch[4].i;
Fout[m3].i = scratch[5].i + scratch[4].r;
++Fout;
}
}
}
static void ki_bfly4(
kiss_fft_cpx * Fout,
const size_t fstride,
const kiss_fft_state *st,
int m,
int N,
int mm
)
{
const kiss_twiddle_cpx *tw1,*tw2,*tw3;
kiss_fft_cpx scratch[6];
const size_t m2=2*m;
const size_t m3=3*m;
int i, j;
kiss_fft_cpx * Fout_beg = Fout;
for (i=0;i<N;i++)
{
Fout = Fout_beg + i*mm;
tw3 = tw2 = tw1 = st->twiddles;
for (j=0;j<m;j++)
{
C_MULC(scratch[0],Fout[m] , *tw1 );
C_MULC(scratch[1],Fout[m2] , *tw2 );
C_MULC(scratch[2],Fout[m3] , *tw3 );
C_SUB( scratch[5] , *Fout, scratch[1] );
C_ADDTO(*Fout, scratch[1]);
C_ADD( scratch[3] , scratch[0] , scratch[2] );
C_SUB( scratch[4] , scratch[0] , scratch[2] );
C_SUB( Fout[m2], *Fout, scratch[3] );
tw1 += fstride;
tw2 += fstride*2;
tw3 += fstride*3;
C_ADDTO( *Fout , scratch[3] );
Fout[m].r = scratch[5].r - scratch[4].i;
Fout[m].i = scratch[5].i + scratch[4].r;
Fout[m3].r = scratch[5].r + scratch[4].i;
Fout[m3].i = scratch[5].i - scratch[4].r;
++Fout;
}
}
}
#ifndef RADIX_TWO_ONLY
static void kf_bfly3(
kiss_fft_cpx * Fout,
const size_t fstride,
const kiss_fft_state *st,
int m,
int N,
int mm
)
{
int i;
size_t k;
const size_t m2 = 2*m;
const kiss_twiddle_cpx *tw1,*tw2;
kiss_fft_cpx scratch[5];
kiss_twiddle_cpx epi3;
kiss_fft_cpx * Fout_beg = Fout;
epi3 = st->twiddles[fstride*m];
for (i=0;i<N;i++)
{
Fout = Fout_beg + i*mm;
tw1=tw2=st->twiddles;
k=m;
do {
C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
C_MUL(scratch[1],Fout[m] , *tw1);
C_MUL(scratch[2],Fout[m2] , *tw2);
C_ADD(scratch[3],scratch[1],scratch[2]);
C_SUB(scratch[0],scratch[1],scratch[2]);
tw1 += fstride;
tw2 += fstride*2;
Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
C_MULBYSCALAR( scratch[0] , epi3.i );
C_ADDTO(*Fout,scratch[3]);
Fout[m2].r = Fout[m].r + scratch[0].i;
Fout[m2].i = Fout[m].i - scratch[0].r;
Fout[m].r -= scratch[0].i;
Fout[m].i += scratch[0].r;
++Fout;
} while(--k);
}
}
static void ki_bfly3(
kiss_fft_cpx * Fout,
const size_t fstride,
const kiss_fft_state *st,
int m,
int N,
int mm
)
{
int i, k;
const size_t m2 = 2*m;
const kiss_twiddle_cpx *tw1,*tw2;
kiss_fft_cpx scratch[5];
kiss_twiddle_cpx epi3;
kiss_fft_cpx * Fout_beg = Fout;
epi3 = st->twiddles[fstride*m];
for (i=0;i<N;i++)
{
Fout = Fout_beg + i*mm;
tw1=tw2=st->twiddles;
k=m;
do{
C_MULC(scratch[1],Fout[m] , *tw1);
C_MULC(scratch[2],Fout[m2] , *tw2);
C_ADD(scratch[3],scratch[1],scratch[2]);
C_SUB(scratch[0],scratch[1],scratch[2]);
tw1 += fstride;
tw2 += fstride*2;
Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
C_MULBYSCALAR( scratch[0] , -epi3.i );
C_ADDTO(*Fout,scratch[3]);
Fout[m2].r = Fout[m].r + scratch[0].i;
Fout[m2].i = Fout[m].i - scratch[0].r;
Fout[m].r -= scratch[0].i;
Fout[m].i += scratch[0].r;
++Fout;
}while(--k);
}
}
static void kf_bfly5(
kiss_fft_cpx * Fout,
const size_t fstride,
const kiss_fft_state *st,
int m,
int N,
int mm
)
{
kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
int i, u;
kiss_fft_cpx scratch[13];
const kiss_twiddle_cpx * twiddles = st->twiddles;
const kiss_twiddle_cpx *tw;
kiss_twiddle_cpx ya,yb;
kiss_fft_cpx * Fout_beg = Fout;
ya = twiddles[fstride*m];
yb = twiddles[fstride*2*m];
tw=st->twiddles;
for (i=0;i<N;i++)
{
Fout = Fout_beg + i*mm;
Fout0=Fout;
Fout1=Fout0+m;
Fout2=Fout0+2*m;
Fout3=Fout0+3*m;
Fout4=Fout0+4*m;
for ( u=0; u<m; ++u ) {
C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
scratch[0] = *Fout0;
C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
C_ADD( scratch[7],scratch[1],scratch[4]);
C_SUB( scratch[10],scratch[1],scratch[4]);
C_ADD( scratch[8],scratch[2],scratch[3]);
C_SUB( scratch[9],scratch[2],scratch[3]);
Fout0->r += scratch[7].r + scratch[8].r;
Fout0->i += scratch[7].i + scratch[8].i;
scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
C_SUB(*Fout1,scratch[5],scratch[6]);
C_ADD(*Fout4,scratch[5],scratch[6]);
scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
C_ADD(*Fout2,scratch[11],scratch[12]);
C_SUB(*Fout3,scratch[11],scratch[12]);
++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
}
}
}
static void ki_bfly5(
kiss_fft_cpx * Fout,
const size_t fstride,
const kiss_fft_state *st,
int m,
int N,
int mm
)
{
kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
int i, u;
kiss_fft_cpx scratch[13];
const kiss_twiddle_cpx * twiddles = st->twiddles;
const kiss_twiddle_cpx *tw;
kiss_twiddle_cpx ya,yb;
kiss_fft_cpx * Fout_beg = Fout;
ya = twiddles[fstride*m];
yb = twiddles[fstride*2*m];
tw=st->twiddles;
for (i=0;i<N;i++)
{
Fout = Fout_beg + i*mm;
Fout0=Fout;
Fout1=Fout0+m;
Fout2=Fout0+2*m;
Fout3=Fout0+3*m;
Fout4=Fout0+4*m;
for ( u=0; u<m; ++u ) {
scratch[0] = *Fout0;
C_MULC(scratch[1] ,*Fout1, tw[u*fstride]);
C_MULC(scratch[2] ,*Fout2, tw[2*u*fstride]);
C_MULC(scratch[3] ,*Fout3, tw[3*u*fstride]);
C_MULC(scratch[4] ,*Fout4, tw[4*u*fstride]);
C_ADD( scratch[7],scratch[1],scratch[4]);
C_SUB( scratch[10],scratch[1],scratch[4]);
C_ADD( scratch[8],scratch[2],scratch[3]);
C_SUB( scratch[9],scratch[2],scratch[3]);
Fout0->r += scratch[7].r + scratch[8].r;
Fout0->i += scratch[7].i + scratch[8].i;
scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
scratch[6].r = -S_MUL(scratch[10].i,ya.i) - S_MUL(scratch[9].i,yb.i);
scratch[6].i = S_MUL(scratch[10].r,ya.i) + S_MUL(scratch[9].r,yb.i);
C_SUB(*Fout1,scratch[5],scratch[6]);
C_ADD(*Fout4,scratch[5],scratch[6]);
scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
scratch[12].r = S_MUL(scratch[10].i,yb.i) - S_MUL(scratch[9].i,ya.i);
scratch[12].i = -S_MUL(scratch[10].r,yb.i) + S_MUL(scratch[9].r,ya.i);
C_ADD(*Fout2,scratch[11],scratch[12]);
C_SUB(*Fout3,scratch[11],scratch[12]);
++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
}
}
}
#endif
#ifdef CUSTOM_MODES
static
void compute_bitrev_table(
int Fout,
opus_int16 *f,
const size_t fstride,
int in_stride,
opus_int16 * factors,
const kiss_fft_state *st
)
{
const int p=*factors++; /* the radix */
const int m=*factors++; /* stage's fft length/p */
/*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
if (m==1)
{
int j;
for (j=0;j<p;j++)
{
*f = Fout+j;
f += fstride*in_stride;
}
} else {
int j;
for (j=0;j<p;j++)
{
compute_bitrev_table( Fout , f, fstride*p, in_stride, factors,st);
f += fstride*in_stride;
Fout += m;
}
}
}
/* facbuf is populated by p1,m1,p2,m2, ...
where
p[i] * m[i] = m[i-1]
m0 = n */
static
int kf_factor(int n,opus_int16 * facbuf)
{
int p=4;
/*factor out powers of 4, powers of 2, then any remaining primes */
do {
while (n % p) {
switch (p) {
case 4: p = 2; break;
case 2: p = 3; break;
default: p += 2; break;
}
if (p>32000 || (opus_int32)p*(opus_int32)p > n)
p = n; /* no more factors, skip to end */
}
n /= p;
#ifdef RADIX_TWO_ONLY
if (p!=2 && p != 4)
#else
if (p>5)
#endif
{
return 0;
}
*facbuf++ = p;
*facbuf++ = n;
} while (n > 1);
return 1;
}
static void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft)
{
int i;
#ifdef FIXED_POINT
for (i=0;i<nfft;++i) {
opus_val32 phase = -i;
kf_cexp2(twiddles+i, DIV32(SHL32(phase,17),nfft));
}
#else
for (i=0;i<nfft;++i) {
const double pi=3.14159265358979323846264338327;
double phase = ( -2*pi /nfft ) * i;
kf_cexp(twiddles+i, phase );
}
#endif
}
/*
*
* Allocates all necessary storage space for the fft and ifft.
* The return value is a contiguous block of memory. As such,
* It can be freed with free().
* */
kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base)
{
kiss_fft_state *st=NULL;
size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/
if ( lenmem==NULL ) {
st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded );
}else{
if (mem != NULL && *lenmem >= memneeded)
st = (kiss_fft_state*)mem;
*lenmem = memneeded;
}
if (st) {
opus_int16 *bitrev;
kiss_twiddle_cpx *twiddles;
st->nfft=nfft;
#ifndef FIXED_POINT
st->scale = 1.f/nfft;
#endif
if (base != NULL)
{
st->twiddles = base->twiddles;
st->shift = 0;
while (nfft<<st->shift != base->nfft && st->shift < 32)
st->shift++;
if (st->shift>=32)
goto fail;
} else {
st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft);
compute_twiddles(twiddles, nfft);
st->shift = -1;
}
if (!kf_factor(nfft,st->factors))
{
goto fail;
}
/* bitrev */
st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft);
if (st->bitrev==NULL)
goto fail;
compute_bitrev_table(0, bitrev, 1,1, st->factors,st);
}
return st;
fail:
opus_fft_free(st);
return NULL;
}
kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem )
{
return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL);
}
void opus_fft_free(const kiss_fft_state *cfg)
{
if (cfg)
{
opus_free((opus_int16*)cfg->bitrev);
if (cfg->shift < 0)
opus_free((kiss_twiddle_cpx*)cfg->twiddles);
opus_free((kiss_fft_state*)cfg);
}
}
#endif /* CUSTOM_MODES */
void opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
{
int m2, m;
int p;
int L;
int fstride[MAXFACTORS];
int i;
int shift;
/* st->shift can be -1 */
shift = st->shift>0 ? st->shift : 0;
celt_assert2 (fin != fout, "In-place FFT not supported");
/* Bit-reverse the input */
for (i=0;i<st->nfft;i++)
{
fout[st->bitrev[i]] = fin[i];
#ifndef FIXED_POINT
fout[st->bitrev[i]].r *= st->scale;
fout[st->bitrev[i]].i *= st->scale;
#endif
}
fstride[0] = 1;
L=0;
do {
p = st->factors[2*L];
m = st->factors[2*L+1];
fstride[L+1] = fstride[L]*p;
L++;
} while(m!=1);
m = st->factors[2*L-1];
for (i=L-1;i>=0;i--)
{
if (i!=0)
m2 = st->factors[2*i-1];
else
m2 = 1;
switch (st->factors[2*i])
{
case 2:
kf_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2);
break;
case 4:
kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2);
break;
#ifndef RADIX_TWO_ONLY
case 3:
kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2);
break;
case 5:
kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2);
break;
#endif
}
m = m2;
}
}
void opus_ifft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
{
int m2, m;
int p;
int L;
int fstride[MAXFACTORS];
int i;
int shift;
/* st->shift can be -1 */
shift = st->shift>0 ? st->shift : 0;
celt_assert2 (fin != fout, "In-place FFT not supported");
/* Bit-reverse the input */
for (i=0;i<st->nfft;i++)
fout[st->bitrev[i]] = fin[i];
fstride[0] = 1;
L=0;
do {
p = st->factors[2*L];
m = st->factors[2*L+1];
fstride[L+1] = fstride[L]*p;
L++;
} while(m!=1);
m = st->factors[2*L-1];
for (i=L-1;i>=0;i--)
{
if (i!=0)
m2 = st->factors[2*i-1];
else
m2 = 1;
switch (st->factors[2*i])
{
case 2:
ki_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2);
break;
case 4:
ki_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2);
break;
#ifndef RADIX_TWO_ONLY
case 3:
ki_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2);
break;
case 5:
ki_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2);
break;
#endif
}
m = m2;
}
}

View File

@ -0,0 +1,139 @@
/*Copyright (c) 2003-2004, Mark Borgerding
Lots of modifications by Jean-Marc Valin
Copyright (c) 2005-2007, Xiph.Org Foundation
Copyright (c) 2008, Xiph.Org Foundation, CSIRO
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.*/
#ifndef KISS_FFT_H
#define KISS_FFT_H
#include <stdlib.h>
#include <math.h>
#include "arch.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef USE_SIMD
# include <xmmintrin.h>
# define kiss_fft_scalar __m128
#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes)
#else
#define KISS_FFT_MALLOC opus_alloc
#endif
#ifdef FIXED_POINT
#include "arch.h"
# define kiss_fft_scalar opus_int32
# define kiss_twiddle_scalar opus_int16
#else
# ifndef kiss_fft_scalar
/* default is float */
# define kiss_fft_scalar float
# define kiss_twiddle_scalar float
# define KF_SUFFIX _celt_single
# endif
#endif
typedef struct {
kiss_fft_scalar r;
kiss_fft_scalar i;
}kiss_fft_cpx;
typedef struct {
kiss_twiddle_scalar r;
kiss_twiddle_scalar i;
}kiss_twiddle_cpx;
#define MAXFACTORS 8
/* e.g. an fft of length 128 has 4 factors
as far as kissfft is concerned
4*4*4*2
*/
typedef struct kiss_fft_state{
int nfft;
#ifndef FIXED_POINT
kiss_fft_scalar scale;
#endif
int shift;
opus_int16 factors[2*MAXFACTORS];
const opus_int16 *bitrev;
const kiss_twiddle_cpx *twiddles;
} kiss_fft_state;
/*typedef struct kiss_fft_state* kiss_fft_cfg;*/
/**
* opus_fft_alloc
*
* Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
*
* typical usage: kiss_fft_cfg mycfg=opus_fft_alloc(1024,0,NULL,NULL);
*
* The return value from fft_alloc is a cfg buffer used internally
* by the fft routine or NULL.
*
* If lenmem is NULL, then opus_fft_alloc will allocate a cfg buffer using malloc.
* The returned value should be free()d when done to avoid memory leaks.
*
* The state can be placed in a user supplied buffer 'mem':
* If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
* then the function places the cfg in mem and the size used in *lenmem
* and returns mem.
*
* If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
* then the function returns NULL and places the minimum cfg
* buffer size in *lenmem.
* */
kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base);
kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem);
/**
* opus_fft(cfg,in_out_buf)
*
* Perform an FFT on a complex input buffer.
* for a forward FFT,
* fin should be f[0] , f[1] , ... ,f[nfft-1]
* fout will be F[0] , F[1] , ... ,F[nfft-1]
* Note that each element is complex and can be accessed like
f[k].r and f[k].i
* */
void opus_fft(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
void opus_ifft(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
void opus_fft_free(const kiss_fft_state *cfg);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,136 @@
/* Copyright (c) 2007 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "laplace.h"
#include "mathops.h"
/* The minimum probability of an energy delta (out of 32768). */
#define LAPLACE_LOG_MINP (0)
#define LAPLACE_MINP (1<<LAPLACE_LOG_MINP)
/* The minimum number of guaranteed representable energy deltas (in one
direction). */
#define LAPLACE_NMIN (16)
/* When called, decay is positive and at most 11456. */
static unsigned ec_laplace_get_freq1(unsigned fs0, int decay)
{
unsigned ft;
ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0;
return ft*(opus_int32)(16384-decay)>>15;
}
#ifdef OPUS_ENABLE_ENCODER
void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay)
{
unsigned fl;
int val = *value;
fl = 0;
if (val)
{
int s;
int i;
s = -(val<0);
val = (val+s)^s;
fl = fs;
fs = ec_laplace_get_freq1(fs, decay);
/* Search the decaying part of the PDF.*/
for (i=1; fs > 0 && i < val; i++)
{
fs *= 2;
fl += fs+2*LAPLACE_MINP;
fs = (fs*(opus_int32)decay)>>15;
}
/* Everything beyond that has probability LAPLACE_MINP. */
if (!fs)
{
int di;
int ndi_max;
ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP;
ndi_max = (ndi_max-s)>>1;
di = IMIN(val - i, ndi_max - 1);
fl += (2*di+1+s)*LAPLACE_MINP;
fs = IMIN(LAPLACE_MINP, 32768-fl);
*value = (i+di+s)^s;
}
else
{
fs += LAPLACE_MINP;
fl += fs&~s;
}
celt_assert(fl+fs<=32768);
celt_assert(fs>0);
}
ec_encode_bin(enc, fl, fl+fs, 15);
}
#endif /* OPUS_ENABLE_ENCODER */
int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay)
{
int val=0;
unsigned fl;
unsigned fm;
fm = ec_decode_bin(dec, 15);
fl = 0;
if (fm >= fs)
{
val++;
fl = fs;
fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP;
/* Search the decaying part of the PDF.*/
while(fs > LAPLACE_MINP && fm >= fl+2*fs)
{
fs *= 2;
fl += fs;
fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15;
fs += LAPLACE_MINP;
val++;
}
/* Everything beyond that has probability LAPLACE_MINP. */
if (fs <= LAPLACE_MINP)
{
int di;
di = (fm-fl)>>(LAPLACE_LOG_MINP+1);
val += di;
fl += 2*di*LAPLACE_MINP;
}
if (fm < fl+fs)
val = -val;
else
fl += fs;
}
celt_assert(fl<32768);
celt_assert(fs>0);
celt_assert(fl<=fm);
celt_assert(fm<IMIN(fl+fs,32768));
ec_dec_update(dec, fl, IMIN(fl+fs,32768), 32768);
return val;
}

View File

@ -0,0 +1,48 @@
/* Copyright (c) 2007 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "entenc.h"
#include "entdec.h"
/** Encode a value that is assumed to be the realisation of a
Laplace-distributed random process
@param enc Entropy encoder state
@param value Value to encode
@param fs Probability of 0, multiplied by 32768
@param decay Probability of the value +/- 1, multiplied by 16384
*/
void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay);
/** Decode a value that is assumed to be the realisation of a
Laplace-distributed random process
@param dec Entropy decoder state
@param fs Probability of 0, multiplied by 32768
@param decay Probability of the value +/- 1, multiplied by 16384
@return Value decoded
*/
int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay);

View File

@ -0,0 +1,206 @@
/* Copyright (c) 2002-2008 Jean-Marc Valin
Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/**
@file mathops.h
@brief Various math functions
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "mathops.h"
/*Compute floor(sqrt(_val)) with exact arithmetic.
This has been tested on all possible 32-bit inputs.*/
unsigned isqrt32(opus_uint32 _val){
unsigned b;
unsigned g;
int bshift;
/*Uses the second method from
http://www.azillionmonkeys.com/qed/sqroot.html
The main idea is to search for the largest binary digit b such that
(g+b)*(g+b) <= _val, and add it to the solution g.*/
g=0;
bshift=(EC_ILOG(_val)-1)>>1;
b=1U<<bshift;
do{
opus_uint32 t;
t=(((opus_uint32)g<<1)+b)<<bshift;
if(t<=_val){
g+=b;
_val-=t;
}
b>>=1;
bshift--;
}
while(bshift>=0);
return g;
}
#ifdef FIXED_POINT
opus_val32 frac_div32(opus_val32 a, opus_val32 b)
{
opus_val16 rcp;
opus_val32 result, rem;
int shift = celt_ilog2(b)-29;
a = VSHR32(a,shift);
b = VSHR32(b,shift);
/* 16-bit reciprocal */
rcp = ROUND16(celt_rcp(ROUND16(b,16)),3);
result = MULT16_32_Q15(rcp, a);
rem = PSHR32(a,2)-MULT32_32_Q31(result, b);
result = ADD32(result, SHL32(MULT16_32_Q15(rcp, rem),2));
if (result >= 536870912) /* 2^29 */
return 2147483647; /* 2^31 - 1 */
else if (result <= -536870912) /* -2^29 */
return -2147483647; /* -2^31 */
else
return SHL32(result, 2);
}
/** Reciprocal sqrt approximation in the range [0.25,1) (Q16 in, Q14 out) */
opus_val16 celt_rsqrt_norm(opus_val32 x)
{
opus_val16 n;
opus_val16 r;
opus_val16 r2;
opus_val16 y;
/* Range of n is [-16384,32767] ([-0.5,1) in Q15). */
n = x-32768;
/* Get a rough initial guess for the root.
The optimal minimax quadratic approximation (using relative error) is
r = 1.437799046117536+n*(-0.823394375837328+n*0.4096419668459485).
Coefficients here, and the final result r, are Q14.*/
r = ADD16(23557, MULT16_16_Q15(n, ADD16(-13490, MULT16_16_Q15(n, 6713))));
/* We want y = x*r*r-1 in Q15, but x is 32-bit Q16 and r is Q14.
We can compute the result from n and r using Q15 multiplies with some
adjustment, carefully done to avoid overflow.
Range of y is [-1564,1594]. */
r2 = MULT16_16_Q15(r, r);
y = SHL16(SUB16(ADD16(MULT16_16_Q15(r2, n), r2), 16384), 1);
/* Apply a 2nd-order Householder iteration: r += r*y*(y*0.375-0.5).
This yields the Q14 reciprocal square root of the Q16 x, with a maximum
relative error of 1.04956E-4, a (relative) RMSE of 2.80979E-5, and a
peak absolute error of 2.26591/16384. */
return ADD16(r, MULT16_16_Q15(r, MULT16_16_Q15(y,
SUB16(MULT16_16_Q15(y, 12288), 16384))));
}
/** Sqrt approximation (QX input, QX/2 output) */
opus_val32 celt_sqrt(opus_val32 x)
{
int k;
opus_val16 n;
opus_val32 rt;
static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664};
if (x==0)
return 0;
k = (celt_ilog2(x)>>1)-7;
x = VSHR32(x, 2*k);
n = x-32768;
rt = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2],
MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, (C[4])))))))));
rt = VSHR32(rt,7-k);
return rt;
}
#define L1 32767
#define L2 -7651
#define L3 8277
#define L4 -626
static inline opus_val16 _celt_cos_pi_2(opus_val16 x)
{
opus_val16 x2;
x2 = MULT16_16_P15(x,x);
return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2
))))))));
}
#undef L1
#undef L2
#undef L3
#undef L4
opus_val16 celt_cos_norm(opus_val32 x)
{
x = x&0x0001ffff;
if (x>SHL32(EXTEND32(1), 16))
x = SUB32(SHL32(EXTEND32(1), 17),x);
if (x&0x00007fff)
{
if (x<SHL32(EXTEND32(1), 15))
{
return _celt_cos_pi_2(EXTRACT16(x));
} else {
return NEG32(_celt_cos_pi_2(EXTRACT16(65536-x)));
}
} else {
if (x&0x0000ffff)
return 0;
else if (x&0x0001ffff)
return -32767;
else
return 32767;
}
}
/** Reciprocal approximation (Q15 input, Q16 output) */
opus_val32 celt_rcp(opus_val32 x)
{
int i;
opus_val16 n;
opus_val16 r;
celt_assert2(x>0, "celt_rcp() only defined for positive values");
i = celt_ilog2(x);
/* n is Q15 with range [0,1). */
n = VSHR32(x,i-15)-32768;
/* Start with a linear approximation:
r = 1.8823529411764706-0.9411764705882353*n.
The coefficients and the result are Q14 in the range [15420,30840].*/
r = ADD16(30840, MULT16_16_Q15(-15420, n));
/* Perform two Newton iterations:
r -= r*((r*n)-1.Q15)
= r*((r*n)+(r-1.Q15)). */
r = SUB16(r, MULT16_16_Q15(r,
ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768))));
/* We subtract an extra 1 in the second iteration to avoid overflow; it also
neatly compensates for truncation error in the rest of the process. */
r = SUB16(r, ADD16(1, MULT16_16_Q15(r,
ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768)))));
/* r is now the Q15 solution to 2/(n+1), with a maximum relative error
of 7.05346E-5, a (relative) RMSE of 2.14418E-5, and a peak absolute
error of 1.24665/32768. */
return VSHR32(EXTEND32(r),i-16);
}
#endif

View File

@ -0,0 +1,241 @@
/* Copyright (c) 2002-2008 Jean-Marc Valin
Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/**
@file mathops.h
@brief Various math functions
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MATHOPS_H
#define MATHOPS_H
#include "arch.h"
#include "entcode.h"
#include "os_support.h"
/* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */
#define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15)
unsigned isqrt32(opus_uint32 _val);
#ifndef FIXED_POINT
#define PI 3.141592653f
#define celt_sqrt(x) ((float)sqrt(x))
#define celt_rsqrt(x) (1.f/celt_sqrt(x))
#define celt_rsqrt_norm(x) (celt_rsqrt(x))
#define celt_cos_norm(x) ((float)cos((.5f*PI)*(x)))
#define celt_rcp(x) (1.f/(x))
#define celt_div(a,b) ((a)/(b))
#define frac_div32(a,b) ((float)(a)/(b))
#ifdef FLOAT_APPROX
/* Note: This assumes radix-2 floating point with the exponent at bits 23..30 and an offset of 127
denorm, +/- inf and NaN are *not* handled */
/** Base-2 log approximation (log2(x)). */
static inline float celt_log2(float x)
{
int integer;
float frac;
union {
float f;
opus_uint32 i;
} in;
in.f = x;
integer = (in.i>>23)-127;
in.i -= integer<<23;
frac = in.f - 1.5f;
frac = -0.41445418f + frac*(0.95909232f
+ frac*(-0.33951290f + frac*0.16541097f));
return 1+integer+frac;
}
/** Base-2 exponential approximation (2^x). */
static inline float celt_exp2(float x)
{
int integer;
float frac;
union {
float f;
opus_uint32 i;
} res;
integer = floor(x);
if (integer < -50)
return 0;
frac = x-integer;
/* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */
res.f = 0.99992522f + frac * (0.69583354f
+ frac * (0.22606716f + 0.078024523f*frac));
res.i = (res.i + (integer<<23)) & 0x7fffffff;
return res.f;
}
#else
#define celt_log2(x) ((float)(1.442695040888963387*log(x)))
#define celt_exp2(x) ((float)exp(0.6931471805599453094*(x)))
#endif
#endif
#ifdef FIXED_POINT
#include "os_support.h"
#ifndef OVERRIDE_CELT_ILOG2
/** Integer log in base2. Undefined for zero and negative numbers */
static inline opus_int16 celt_ilog2(opus_int32 x)
{
celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers");
return EC_ILOG(x)-1;
}
#endif
#ifndef OVERRIDE_CELT_MAXABS16
static inline opus_val32 celt_maxabs16(const opus_val16 *x, int len)
{
int i;
opus_val16 maxval = 0;
opus_val16 minval = 0;
for (i=0;i<len;i++)
{
maxval = MAX16(maxval, x[i]);
minval = MIN16(minval, x[i]);
}
return MAX32(EXTEND32(maxval),-EXTEND32(minval));
}
#endif
#ifndef OVERRIDE_CELT_MAXABS32
static inline opus_val32 celt_maxabs32(opus_val32 *x, int len)
{
int i;
opus_val32 maxval = 0;
for (i=0;i<len;i++)
maxval = MAX32(maxval, ABS32(x[i]));
return maxval;
}
#endif
/** Integer log in base2. Defined for zero, but not for negative numbers */
static inline opus_int16 celt_zlog2(opus_val32 x)
{
return x <= 0 ? 0 : celt_ilog2(x);
}
opus_val16 celt_rsqrt_norm(opus_val32 x);
opus_val32 celt_sqrt(opus_val32 x);
opus_val16 celt_cos_norm(opus_val32 x);
static inline opus_val16 celt_log2(opus_val32 x)
{
int i;
opus_val16 n, frac;
/* -0.41509302963303146, 0.9609890551383969, -0.31836011537636605,
0.15530808010959576, -0.08556153059057618 */
static const opus_val16 C[5] = {-6801+(1<<(13-DB_SHIFT)), 15746, -5217, 2545, -1401};
if (x==0)
return -32767;
i = celt_ilog2(x);
n = VSHR32(x,i-15)-32768-16384;
frac = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, C[4]))))))));
return SHL16(i-13,DB_SHIFT)+SHR16(frac,14-DB_SHIFT);
}
/*
K0 = 1
K1 = log(2)
K2 = 3-4*log(2)
K3 = 3*log(2) - 2
*/
#define D0 16383
#define D1 22804
#define D2 14819
#define D3 10204
/** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */
static inline opus_val32 celt_exp2(opus_val16 x)
{
int integer;
opus_val16 frac;
integer = SHR16(x,10);
if (integer>14)
return 0x7f000000;
else if (integer < -15)
return 0;
frac = SHL16(x-SHL16(integer,10),4);
frac = ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac))))));
return VSHR32(EXTEND32(frac), -integer-2);
}
opus_val32 celt_rcp(opus_val32 x);
#define celt_div(a,b) MULT32_32_Q31((opus_val32)(a),celt_rcp(b))
opus_val32 frac_div32(opus_val32 a, opus_val32 b);
#define M1 32767
#define M2 -21
#define M3 -11943
#define M4 4936
/* Atan approximation using a 4th order polynomial. Input is in Q15 format
and normalized by pi/4. Output is in Q15 format */
static inline opus_val16 celt_atan01(opus_val16 x)
{
return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
}
#undef M1
#undef M2
#undef M3
#undef M4
/* atan2() approximation valid for positive input values */
static inline opus_val16 celt_atan2p(opus_val16 y, opus_val16 x)
{
if (y < x)
{
opus_val32 arg;
arg = celt_div(SHL32(EXTEND32(y),15),x);
if (arg >= 32767)
arg = 32767;
return SHR16(celt_atan01(EXTRACT16(arg)),1);
} else {
opus_val32 arg;
arg = celt_div(SHL32(EXTEND32(x),15),y);
if (arg >= 32767)
arg = 32767;
return 25736-SHR16(celt_atan01(EXTRACT16(arg)),1);
}
}
#endif /* FIXED_POINT */
#endif /* MATHOPS_H */

View File

@ -0,0 +1,332 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2008 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* This is a simple MDCT implementation that uses a N/4 complex FFT
to do most of the work. It should be relatively straightforward to
plug in pretty much and FFT here.
This replaces the Vorbis FFT (and uses the exact same API), which
was a bit too messy and that was ending up duplicating code
(might as well use the same FFT everywhere).
The algorithm is similar to (and inspired from) Fabrice Bellard's
MDCT implementation in FFMPEG, but has differences in signs, ordering
and scaling in many places.
*/
#ifndef SKIP_CONFIG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif
#include "mdct.h"
#include "kiss_fft.h"
#include "_kiss_fft_guts.h"
#include <math.h>
#include "os_support.h"
#include "mathops.h"
#include "stack_alloc.h"
#ifdef CUSTOM_MODES
int clt_mdct_init(mdct_lookup *l,int N, int maxshift)
{
int i;
int N4;
kiss_twiddle_scalar *trig;
#if defined(FIXED_POINT)
int N2=N>>1;
#endif
l->n = N;
N4 = N>>2;
l->maxshift = maxshift;
for (i=0;i<=maxshift;i++)
{
if (i==0)
l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0);
else
l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0]);
#ifndef ENABLE_TI_DSPLIB55
if (l->kfft[i]==NULL)
return 0;
#endif
}
l->trig = trig = (kiss_twiddle_scalar*)opus_alloc((N4+1)*sizeof(kiss_twiddle_scalar));
if (l->trig==NULL)
return 0;
/* We have enough points that sine isn't necessary */
#if defined(FIXED_POINT)
for (i=0;i<=N4;i++)
trig[i] = TRIG_UPSCALE*celt_cos_norm(DIV32(ADD32(SHL32(EXTEND32(i),17),N2),N));
#else
for (i=0;i<=N4;i++)
trig[i] = (kiss_twiddle_scalar)cos(2*PI*i/N);
#endif
return 1;
}
void clt_mdct_clear(mdct_lookup *l)
{
int i;
for (i=0;i<=l->maxshift;i++)
opus_fft_free(l->kfft[i]);
opus_free((kiss_twiddle_scalar*)l->trig);
}
#endif /* CUSTOM_MODES */
/* Forward MDCT trashes the input array */
void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 *window, int overlap, int shift, int stride)
{
int i;
int N, N2, N4;
kiss_twiddle_scalar sine;
VARDECL(kiss_fft_scalar, f);
SAVE_STACK;
N = l->n;
N >>= shift;
N2 = N>>1;
N4 = N>>2;
ALLOC(f, N2, kiss_fft_scalar);
/* sin(x) ~= x here */
#ifdef FIXED_POINT
sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N;
#else
sine = (kiss_twiddle_scalar)2*PI*(.125f)/N;
#endif
/* Consider the input to be composed of four blocks: [a, b, c, d] */
/* Window, shuffle, fold */
{
/* Temp pointers to make it really clear to the compiler what we're doing */
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
kiss_fft_scalar * OPUS_RESTRICT yp = f;
const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
for(i=0;i<(overlap>>2);i++)
{
/* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
*yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);
*yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]);
xp1+=2;
xp2-=2;
wp1+=2;
wp2-=2;
}
wp1 = window;
wp2 = window+overlap-1;
for(;i<N4-(overlap>>2);i++)
{
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
*yp++ = *xp2;
*yp++ = *xp1;
xp1+=2;
xp2-=2;
}
for(;i<N4;i++)
{
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
*yp++ = -MULT16_32_Q15(*wp1, xp1[-N2]) + MULT16_32_Q15(*wp2, *xp2);
*yp++ = MULT16_32_Q15(*wp2, *xp1) + MULT16_32_Q15(*wp1, xp2[N2]);
xp1+=2;
xp2-=2;
wp1+=2;
wp2-=2;
}
}
/* Pre-rotation */
{
kiss_fft_scalar * OPUS_RESTRICT yp = f;
const kiss_twiddle_scalar *t = &l->trig[0];
for(i=0;i<N4;i++)
{
kiss_fft_scalar re, im, yr, yi;
re = yp[0];
im = yp[1];
yr = -S_MUL(re,t[i<<shift]) - S_MUL(im,t[(N4-i)<<shift]);
yi = -S_MUL(im,t[i<<shift]) + S_MUL(re,t[(N4-i)<<shift]);
/* works because the cos is nearly one */
*yp++ = yr + S_MUL(yi,sine);
*yp++ = yi - S_MUL(yr,sine);
}
}
/* N/4 complex FFT, down-scales by 4/N */
opus_fft(l->kfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)in);
/* Post-rotate */
{
/* Temp pointers to make it really clear to the compiler what we're doing */
const kiss_fft_scalar * OPUS_RESTRICT fp = in;
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
const kiss_twiddle_scalar *t = &l->trig[0];
/* Temp pointers to make it really clear to the compiler what we're doing */
for(i=0;i<N4;i++)
{
kiss_fft_scalar yr, yi;
yr = S_MUL(fp[1],t[(N4-i)<<shift]) + S_MUL(fp[0],t[i<<shift]);
yi = S_MUL(fp[0],t[(N4-i)<<shift]) - S_MUL(fp[1],t[i<<shift]);
/* works because the cos is nearly one */
*yp1 = yr - S_MUL(yi,sine);
*yp2 = yi + S_MUL(yr,sine);;
fp += 2;
yp1 += 2*stride;
yp2 -= 2*stride;
}
}
RESTORE_STACK;
}
void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride)
{
int i;
int N, N2, N4;
kiss_twiddle_scalar sine;
VARDECL(kiss_fft_scalar, f);
VARDECL(kiss_fft_scalar, f2);
SAVE_STACK;
N = l->n;
N >>= shift;
N2 = N>>1;
N4 = N>>2;
ALLOC(f, N2, kiss_fft_scalar);
ALLOC(f2, N2, kiss_fft_scalar);
/* sin(x) ~= x here */
#ifdef FIXED_POINT
sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N;
#else
sine = (kiss_twiddle_scalar)2*PI*(.125f)/N;
#endif
/* Pre-rotate */
{
/* Temp pointers to make it really clear to the compiler what we're doing */
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
kiss_fft_scalar * OPUS_RESTRICT yp = f2;
const kiss_twiddle_scalar *t = &l->trig[0];
for(i=0;i<N4;i++)
{
kiss_fft_scalar yr, yi;
yr = -S_MUL(*xp2, t[i<<shift]) + S_MUL(*xp1,t[(N4-i)<<shift]);
yi = -S_MUL(*xp2, t[(N4-i)<<shift]) - S_MUL(*xp1,t[i<<shift]);
/* works because the cos is nearly one */
*yp++ = yr - S_MUL(yi,sine);
*yp++ = yi + S_MUL(yr,sine);
xp1+=2*stride;
xp2-=2*stride;
}
}
/* Inverse N/4 complex FFT. This one should *not* downscale even in fixed-point */
opus_ifft(l->kfft[shift], (kiss_fft_cpx *)f2, (kiss_fft_cpx *)f);
/* Post-rotate */
{
kiss_fft_scalar * OPUS_RESTRICT fp = f;
const kiss_twiddle_scalar *t = &l->trig[0];
for(i=0;i<N4;i++)
{
kiss_fft_scalar re, im, yr, yi;
re = fp[0];
im = fp[1];
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
yr = S_MUL(re,t[i<<shift]) - S_MUL(im,t[(N4-i)<<shift]);
yi = S_MUL(im,t[i<<shift]) + S_MUL(re,t[(N4-i)<<shift]);
/* works because the cos is nearly one */
*fp++ = yr - S_MUL(yi,sine);
*fp++ = yi + S_MUL(yr,sine);
}
}
/* De-shuffle the components for the middle of the window only */
{
const kiss_fft_scalar * OPUS_RESTRICT fp1 = f;
const kiss_fft_scalar * OPUS_RESTRICT fp2 = f+N2-1;
kiss_fft_scalar * OPUS_RESTRICT yp = f2;
for(i = 0; i < N4; i++)
{
*yp++ =-*fp1;
*yp++ = *fp2;
fp1 += 2;
fp2 -= 2;
}
}
out -= (N2-overlap)>>1;
/* Mirror on both sides for TDAC */
{
kiss_fft_scalar * OPUS_RESTRICT fp1 = f2+N4-1;
kiss_fft_scalar * OPUS_RESTRICT xp1 = out+N2-1;
kiss_fft_scalar * OPUS_RESTRICT yp1 = out+N4-overlap/2;
const opus_val16 * OPUS_RESTRICT wp1 = window;
const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
for(i = 0; i< N4-overlap/2; i++)
{
*xp1 = *fp1;
xp1--;
fp1--;
}
for(; i < N4; i++)
{
kiss_fft_scalar x1;
x1 = *fp1--;
*yp1++ +=-MULT16_32_Q15(*wp1, x1);
*xp1-- += MULT16_32_Q15(*wp2, x1);
wp1++;
wp2--;
}
}
{
kiss_fft_scalar * OPUS_RESTRICT fp2 = f2+N4;
kiss_fft_scalar * OPUS_RESTRICT xp2 = out+N2;
kiss_fft_scalar * OPUS_RESTRICT yp2 = out+N-1-(N4-overlap/2);
const opus_val16 * OPUS_RESTRICT wp1 = window;
const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
for(i = 0; i< N4-overlap/2; i++)
{
*xp2 = *fp2;
xp2++;
fp2++;
}
for(; i < N4; i++)
{
kiss_fft_scalar x2;
x2 = *fp2++;
*yp2-- = MULT16_32_Q15(*wp1, x2);
*xp2++ = MULT16_32_Q15(*wp2, x2);
wp1++;
wp2--;
}
}
RESTORE_STACK;
}

View File

@ -0,0 +1,70 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2008 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* This is a simple MDCT implementation that uses a N/4 complex FFT
to do most of the work. It should be relatively straightforward to
plug in pretty much and FFT here.
This replaces the Vorbis FFT (and uses the exact same API), which
was a bit too messy and that was ending up duplicating code
(might as well use the same FFT everywhere).
The algorithm is similar to (and inspired from) Fabrice Bellard's
MDCT implementation in FFMPEG, but has differences in signs, ordering
and scaling in many places.
*/
#ifndef MDCT_H
#define MDCT_H
#include "opus_defines.h"
#include "kiss_fft.h"
#include "arch.h"
typedef struct {
int n;
int maxshift;
const kiss_fft_state *kfft[4];
const kiss_twiddle_scalar * OPUS_RESTRICT trig;
} mdct_lookup;
int clt_mdct_init(mdct_lookup *l,int N, int maxshift);
void clt_mdct_clear(mdct_lookup *l);
/** Compute a forward MDCT and scale by 4/N, trashes the input array */
void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 *window, int overlap, int shift, int stride);
/** Compute a backward MDCT (no scaling) and performs weighted overlap-add
(scales implicitly by 1/2) */
void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride);
#endif

View File

@ -0,0 +1,48 @@
/* Copyright (c) 2001-2008 Timothy B. Terriberry
Copyright (c) 2008-2009 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(_mfrngcode_H)
# define _mfrngcode_H (1)
# include "entcode.h"
/*Constants used by the entropy encoder/decoder.*/
/*The number of bits to output at a time.*/
# define EC_SYM_BITS (8)
/*The total number of bits in each of the state registers.*/
# define EC_CODE_BITS (32)
/*The maximum symbol value.*/
# define EC_SYM_MAX ((1U<<EC_SYM_BITS)-1)
/*Bits to shift by to move a symbol into the high-order position.*/
# define EC_CODE_SHIFT (EC_CODE_BITS-EC_SYM_BITS-1)
/*Carry bit of the high-order range symbol.*/
# define EC_CODE_TOP (((opus_uint32)1U)<<(EC_CODE_BITS-1))
/*Low-order bit of the high-order range symbol.*/
# define EC_CODE_BOT (EC_CODE_TOP>>EC_SYM_BITS)
/*The number of bits available for the last, partial symbol in the code field.*/
# define EC_CODE_EXTRA ((EC_CODE_BITS-2)%EC_SYM_BITS+1)
#endif

View File

@ -0,0 +1,430 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Copyright (c) 2008 Gregory Maxwell
Written by Jean-Marc Valin and Gregory Maxwell */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "celt.h"
#include "modes.h"
#include "rate.h"
#include "os_support.h"
#include "stack_alloc.h"
#include "quant_bands.h"
static const opus_int16 eband5ms[] = {
/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
};
/* Alternate tuning (partially derived from Vorbis) */
#define BITALLOC_SIZE 11
/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
static const unsigned char band_allocation[] = {
/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0,
110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0,
118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0,
126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0,
134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1,
144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1,
152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1,
162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1,
172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20,
200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104,
};
#ifndef CUSTOM_MODES_ONLY
#ifdef FIXED_POINT
#include "static_modes_fixed.h"
#else
#include "static_modes_float.h"
#endif
#endif /* CUSTOM_MODES_ONLY */
#ifndef M_PI
#define M_PI 3.141592653
#endif
#ifdef CUSTOM_MODES
/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
#define BARK_BANDS 25
static const opus_int16 bark_freq[BARK_BANDS+1] = {
0, 100, 200, 300, 400,
510, 630, 770, 920, 1080,
1270, 1480, 1720, 2000, 2320,
2700, 3150, 3700, 4400, 5300,
6400, 7700, 9500, 12000, 15500,
20000};
static opus_int16 *compute_ebands(opus_int32 Fs, int frame_size, int res, int *nbEBands)
{
opus_int16 *eBands;
int i, j, lin, low, high, nBark, offset=0;
/* All modes that have 2.5 ms short blocks use the same definition */
if (Fs == 400*(opus_int32)frame_size)
{
*nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+1));
for (i=0;i<*nbEBands+1;i++)
eBands[i] = eband5ms[i];
return eBands;
}
/* Find the number of critical bands supported by our sampling rate */
for (nBark=1;nBark<BARK_BANDS;nBark++)
if (bark_freq[nBark+1]*2 >= Fs)
break;
/* Find where the linear part ends (i.e. where the spacing is more than min_width */
for (lin=0;lin<nBark;lin++)
if (bark_freq[lin+1]-bark_freq[lin] >= res)
break;
low = (bark_freq[lin]+res/2)/res;
high = nBark-lin;
*nbEBands = low+high;
eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+2));
if (eBands==NULL)
return NULL;
/* Linear spacing (min_width) */
for (i=0;i<low;i++)
eBands[i] = i;
if (low>0)
offset = eBands[low-1]*res - bark_freq[lin-1];
/* Spacing follows critical bands */
for (i=0;i<high;i++)
{
int target = bark_freq[lin+i];
/* Round to an even value */
eBands[i+low] = (target+offset/2+res)/(2*res)*2;
offset = eBands[i+low]*res - target;
}
/* Enforce the minimum spacing at the boundary */
for (i=0;i<*nbEBands;i++)
if (eBands[i] < i)
eBands[i] = i;
/* Round to an even value */
eBands[*nbEBands] = (bark_freq[nBark]+res)/(2*res)*2;
if (eBands[*nbEBands] > frame_size)
eBands[*nbEBands] = frame_size;
for (i=1;i<*nbEBands-1;i++)
{
if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
{
eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
}
}
/* Remove any empty bands. */
for (i=j=0;i<*nbEBands;i++)
if(eBands[i+1]>eBands[j])
eBands[++j]=eBands[i+1];
*nbEBands=j;
for (i=1;i<*nbEBands;i++)
{
/* Every band must be smaller than the last band. */
celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]);
/* Each band must be no larger than twice the size of the previous one. */
celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1]));
}
return eBands;
}
static void compute_allocation_table(CELTMode *mode)
{
int i, j;
unsigned char *allocVectors;
int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
mode->nbAllocVectors = BITALLOC_SIZE;
allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
if (allocVectors==NULL)
return;
/* Check for standard mode */
if (mode->Fs == 400*(opus_int32)mode->shortMdctSize)
{
for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
allocVectors[i] = band_allocation[i];
mode->allocVectors = allocVectors;
return;
}
/* If not the standard mode, interpolate */
/* Compute per-codec-band allocation from per-critical-band matrix */
for (i=0;i<BITALLOC_SIZE;i++)
{
for (j=0;j<mode->nbEBands;j++)
{
int k;
for (k=0;k<maxBands;k++)
{
if (400*(opus_int32)eband5ms[k] > mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize)
break;
}
if (k>maxBands-1)
allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1];
else {
opus_int32 a0, a1;
a1 = mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize - 400*(opus_int32)eband5ms[k-1];
a0 = 400*(opus_int32)eband5ms[k] - mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize;
allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1]
+ a1*band_allocation[i*maxBands+k])/(a0+a1);
}
}
}
/*printf ("\n");
for (i=0;i<BITALLOC_SIZE;i++)
{
for (j=0;j<mode->nbEBands;j++)
printf ("%d ", allocVectors[i*mode->nbEBands+j]);
printf ("\n");
}
exit(0);*/
mode->allocVectors = allocVectors;
}
#endif /* CUSTOM_MODES */
CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
{
int i;
#ifdef CUSTOM_MODES
CELTMode *mode=NULL;
int res;
opus_val16 *window;
opus_int16 *logN;
int LM;
ALLOC_STACK;
#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
if (global_stack==NULL)
goto failure;
#endif
#endif
#ifndef CUSTOM_MODES_ONLY
for (i=0;i<TOTAL_MODES;i++)
{
int j;
for (j=0;j<4;j++)
{
if (Fs == static_mode_list[i]->Fs &&
(frame_size<<j) == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
{
if (error)
*error = OPUS_OK;
return (CELTMode*)static_mode_list[i];
}
}
}
#endif /* CUSTOM_MODES_ONLY */
#ifndef CUSTOM_MODES
if (error)
*error = OPUS_BAD_ARG;
return NULL;
#else
/* The good thing here is that permutation of the arguments will automatically be invalid */
if (Fs < 8000 || Fs > 96000)
{
if (error)
*error = OPUS_BAD_ARG;
return NULL;
}
if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
{
if (error)
*error = OPUS_BAD_ARG;
return NULL;
}
/* Frames of less than 1ms are not supported. */
if ((opus_int32)frame_size*1000 < Fs)
{
if (error)
*error = OPUS_BAD_ARG;
return NULL;
}
if ((opus_int32)frame_size*75 >= Fs && (frame_size%16)==0)
{
LM = 3;
} else if ((opus_int32)frame_size*150 >= Fs && (frame_size%8)==0)
{
LM = 2;
} else if ((opus_int32)frame_size*300 >= Fs && (frame_size%4)==0)
{
LM = 1;
} else
{
LM = 0;
}
/* Shorts longer than 3.3ms are not supported. */
if ((opus_int32)(frame_size>>LM)*300 > Fs)
{
if (error)
*error = OPUS_BAD_ARG;
return NULL;
}
mode = opus_alloc(sizeof(CELTMode));
if (mode==NULL)
goto failure;
mode->Fs = Fs;
/* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
approximate that. */
if(Fs < 12000) /* 8 kHz */
{
mode->preemph[0] = QCONST16(0.3500061035f, 15);
mode->preemph[1] = -QCONST16(0.1799926758f, 15);
mode->preemph[2] = QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */
mode->preemph[3] = QCONST16(3.6765136719f, 13);
} else if(Fs < 24000) /* 16 kHz */
{
mode->preemph[0] = QCONST16(0.6000061035f, 15);
mode->preemph[1] = -QCONST16(0.1799926758f, 15);
mode->preemph[2] = QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */
mode->preemph[3] = QCONST16(2.2598876953f, 13);
} else if(Fs < 40000) /* 32 kHz */
{
mode->preemph[0] = QCONST16(0.7799987793f, 15);
mode->preemph[1] = -QCONST16(0.1000061035f, 15);
mode->preemph[2] = QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */
mode->preemph[3] = QCONST16(1.3333740234f, 13);
} else /* 48 kHz */
{
mode->preemph[0] = QCONST16(0.8500061035f, 15);
mode->preemph[1] = QCONST16(0.0f, 15);
mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
mode->preemph[3] = QCONST16(1.f, 13);
}
mode->maxLM = LM;
mode->nbShortMdcts = 1<<LM;
mode->shortMdctSize = frame_size/mode->nbShortMdcts;
res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
if (mode->eBands==NULL)
goto failure;
mode->effEBands = mode->nbEBands;
while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
mode->effEBands--;
/* Overlap must be divisible by 4 */
mode->overlap = ((mode->shortMdctSize>>2)<<2);
compute_allocation_table(mode);
if (mode->allocVectors==NULL)
goto failure;
window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16));
if (window==NULL)
goto failure;
#ifndef FIXED_POINT
for (i=0;i<mode->overlap;i++)
window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
#else
for (i=0;i<mode->overlap;i++)
window[i] = MIN32(32767,floor(.5+32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap))));
#endif
mode->window = window;
logN = (opus_int16*)opus_alloc(mode->nbEBands*sizeof(opus_int16));
if (logN==NULL)
goto failure;
for (i=0;i<mode->nbEBands;i++)
logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
mode->logN = logN;
compute_pulse_cache(mode, mode->maxLM);
if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts,
mode->maxLM) == 0)
goto failure;
if (error)
*error = OPUS_OK;
return mode;
failure:
if (error)
*error = OPUS_ALLOC_FAIL;
if (mode!=NULL)
opus_custom_mode_destroy(mode);
return NULL;
#endif /* !CUSTOM_MODES */
}
#ifdef CUSTOM_MODES
void opus_custom_mode_destroy(CELTMode *mode)
{
if (mode == NULL)
return;
#ifndef CUSTOM_MODES_ONLY
{
int i;
for (i=0;i<TOTAL_MODES;i++)
{
if (mode == static_mode_list[i])
{
return;
}
}
}
#endif /* CUSTOM_MODES_ONLY */
opus_free((opus_int16*)mode->eBands);
opus_free((opus_int16*)mode->allocVectors);
opus_free((opus_val16*)mode->window);
opus_free((opus_int16*)mode->logN);
opus_free((opus_int16*)mode->cache.index);
opus_free((unsigned char*)mode->cache.bits);
opus_free((unsigned char*)mode->cache.caps);
clt_mdct_clear(&mode->mdct);
opus_free((CELTMode *)mode);
}
#endif

View File

@ -0,0 +1,83 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Copyright (c) 2008 Gregory Maxwell
Written by Jean-Marc Valin and Gregory Maxwell */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MODES_H
#define MODES_H
#include "opus_types.h"
#include "celt.h"
#include "arch.h"
#include "mdct.h"
#include "entenc.h"
#include "entdec.h"
#define MAX_PERIOD 1024
#ifndef OVERLAP
#define OVERLAP(mode) ((mode)->overlap)
#endif
#ifndef FRAMESIZE
#define FRAMESIZE(mode) ((mode)->mdctSize)
#endif
typedef struct {
int size;
const opus_int16 *index;
const unsigned char *bits;
const unsigned char *caps;
} PulseCache;
/** Mode definition (opaque)
@brief Mode definition
*/
struct OpusCustomMode {
opus_int32 Fs;
int overlap;
int nbEBands;
int effEBands;
opus_val16 preemph[4];
const opus_int16 *eBands; /**< Definition for each "pseudo-critical band" */
int maxLM;
int nbShortMdcts;
int shortMdctSize;
int nbAllocVectors; /**< Number of lines in the matrix below */
const unsigned char *allocVectors; /**< Number of bits in each band for several rates */
const opus_int16 *logN;
const opus_val16 *window;
mdct_lookup mdct;
PulseCache cache;
};
#endif

View File

@ -0,0 +1,210 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "opus_custom.h"
#include "arch.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX_PACKET 1275
int main(int argc, char *argv[])
{
int err;
char *inFile, *outFile;
FILE *fin, *fout;
OpusCustomMode *mode=NULL;
OpusCustomEncoder *enc;
OpusCustomDecoder *dec;
int len;
opus_int32 frame_size, channels, rate;
int bytes_per_packet;
unsigned char data[MAX_PACKET];
int complexity;
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
int i;
double rmsd = 0;
#endif
int count = 0;
opus_int32 skip;
opus_int16 *in, *out;
if (argc != 9 && argc != 8 && argc != 7)
{
fprintf (stderr, "Usage: test_opus_custom <rate> <channels> <frame size> "
" <bytes per packet> [<complexity> [packet loss rate]] "
"<input> <output>\n");
return 1;
}
rate = (opus_int32)atol(argv[1]);
channels = atoi(argv[2]);
frame_size = atoi(argv[3]);
mode = opus_custom_mode_create(rate, frame_size, NULL);
if (mode == NULL)
{
fprintf(stderr, "failed to create a mode\n");
return 1;
}
bytes_per_packet = atoi(argv[4]);
if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET)
{
fprintf (stderr, "bytes per packet must be between 0 and %d\n",
MAX_PACKET);
return 1;
}
inFile = argv[argc-2];
fin = fopen(inFile, "rb");
if (!fin)
{
fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
return 1;
}
outFile = argv[argc-1];
fout = fopen(outFile, "wb+");
if (!fout)
{
fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
fclose(fin);
return 1;
}
enc = opus_custom_encoder_create(mode, channels, &err);
if (err != 0)
{
fprintf(stderr, "Failed to create the encoder: %s\n", opus_strerror(err));
fclose(fin);
fclose(fout);
return 1;
}
dec = opus_custom_decoder_create(mode, channels, &err);
if (err != 0)
{
fprintf(stderr, "Failed to create the decoder: %s\n", opus_strerror(err));
fclose(fin);
fclose(fout);
return 1;
}
opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD(&skip));
if (argc>7)
{
complexity=atoi(argv[5]);
opus_custom_encoder_ctl(enc,OPUS_SET_COMPLEXITY(complexity));
}
in = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16));
out = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16));
while (!feof(fin))
{
int ret;
err = fread(in, sizeof(short), frame_size*channels, fin);
if (feof(fin))
break;
len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet);
if (len <= 0)
fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len));
/* This is for simulating bit errors */
#if 0
int errors = 0;
int eid = 0;
/* This simulates random bit error */
for (i=0;i<len*8;i++)
{
if (rand()%atoi(argv[8])==0)
{
if (i<64)
{
errors++;
eid = i;
}
data[i/8] ^= 1<<(7-(i%8));
}
}
if (errors == 1)
data[eid/8] ^= 1<<(7-(eid%8));
else if (errors%2 == 1)
data[rand()%8] ^= 1<<rand()%8;
#endif
#if 1 /* Set to zero to use the encoder's output instead */
/* This is to simulate packet loss */
if (argc==9 && rand()%1000<atoi(argv[argc-3]))
/*if (errors && (errors%2==0))*/
ret = opus_custom_decode(dec, NULL, len, out, frame_size);
else
ret = opus_custom_decode(dec, data, len, out, frame_size);
if (ret < 0)
fprintf(stderr, "opus_custom_decode() failed: %s\n", opus_strerror(ret));
#else
for (i=0;i<ret*channels;i++)
out[i] = in[i];
#endif
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
for (i=0;i<ret*channels;i++)
{
rmsd += (in[i]-out[i])*1.0*(in[i]-out[i]);
/*out[i] -= in[i];*/
}
#endif
count++;
fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout);
skip = 0;
}
PRINT_MIPS(stderr);
opus_custom_encoder_destroy(enc);
opus_custom_decoder_destroy(dec);
fclose(fin);
fclose(fout);
opus_custom_mode_destroy(mode);
free(in);
free(out);
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
if (rmsd > 0)
{
rmsd = sqrt(rmsd/(1.0*frame_size*channels*count));
fprintf (stderr, "Error: encoder doesn't match decoder\n");
fprintf (stderr, "RMS mismatch is %f\n", rmsd);
return 1;
} else {
fprintf (stderr, "Encoder matches decoder!!\n");
}
#endif
return 0;
}

View File

@ -0,0 +1,89 @@
/* Copyright (C) 2007 Jean-Marc Valin
File: os_support.h
This is the (tiny) OS abstraction layer. Aside from math.h, this is the
only place where system headers are allowed.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OS_SUPPORT_H
#define OS_SUPPORT_H
#ifdef CUSTOM_SUPPORT
# include "custom_support.h"
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */
#ifndef OVERRIDE_OPUS_ALLOC
static inline void *opus_alloc (size_t size)
{
return malloc(size);
}
#endif
/** Same as celt_alloc(), except that the area is only needed inside a CELT call (might cause problem with wideband though) */
#ifndef OVERRIDE_OPUS_ALLOC_SCRATCH
static inline void *opus_alloc_scratch (size_t size)
{
/* Scratch space doesn't need to be cleared */
return opus_alloc(size);
}
#endif
/** Opus wrapper for free(). To do your own dynamic allocation, all you need to do is replace this function and opus_alloc */
#ifndef OVERRIDE_OPUS_FREE
static inline void opus_free (void *ptr)
{
free(ptr);
}
#endif
/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking */
#ifndef OVERRIDE_OPUS_COPY
#define OPUS_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
#endif
/** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term
provides compile-time type checking */
#ifndef OVERRIDE_OPUS_MOVE
#define OPUS_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
#endif
/** Set n elements of dst to zero, starting at address s */
#ifndef OVERRIDE_OPUS_CLEAR
#define OPUS_CLEAR(dst, n) (memset((dst), 0, (n)*sizeof(*(dst))))
#endif
/*#ifdef __GNUC__
#pragma GCC poison printf sprintf
#pragma GCC poison malloc free realloc calloc
#endif*/
#endif /* OS_SUPPORT_H */

View File

@ -0,0 +1,410 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/**
@file pitch.c
@brief Pitch analysis
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pitch.h"
#include "os_support.h"
#include "modes.h"
#include "stack_alloc.h"
#include "mathops.h"
#include "celt_lpc.h"
static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len,
int max_pitch, int *best_pitch
#ifdef FIXED_POINT
, int yshift, opus_val32 maxcorr
#endif
)
{
int i, j;
opus_val32 Syy=1;
opus_val16 best_num[2];
opus_val32 best_den[2];
#ifdef FIXED_POINT
int xshift;
xshift = celt_ilog2(maxcorr)-14;
#endif
best_num[0] = -1;
best_num[1] = -1;
best_den[0] = 0;
best_den[1] = 0;
best_pitch[0] = 0;
best_pitch[1] = 1;
for (j=0;j<len;j++)
Syy = ADD32(Syy, SHR32(MULT16_16(y[j],y[j]), yshift));
for (i=0;i<max_pitch;i++)
{
if (xcorr[i]>0)
{
opus_val16 num;
opus_val32 xcorr16;
xcorr16 = EXTRACT16(VSHR32(xcorr[i], xshift));
#ifndef FIXED_POINT
/* Considering the range of xcorr16, this should avoid both underflows
and overflows (inf) when squaring xcorr16 */
xcorr16 *= 1e-12f;
#endif
num = MULT16_16_Q15(xcorr16,xcorr16);
if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy))
{
if (MULT16_32_Q15(num,best_den[0]) > MULT16_32_Q15(best_num[0],Syy))
{
best_num[1] = best_num[0];
best_den[1] = best_den[0];
best_pitch[1] = best_pitch[0];
best_num[0] = num;
best_den[0] = Syy;
best_pitch[0] = i;
} else {
best_num[1] = num;
best_den[1] = Syy;
best_pitch[1] = i;
}
}
}
Syy += SHR32(MULT16_16(y[i+len],y[i+len]),yshift) - SHR32(MULT16_16(y[i],y[i]),yshift);
Syy = MAX32(1, Syy);
}
}
void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,
int len, int C)
{
int i;
opus_val32 ac[5];
opus_val16 tmp=Q15ONE;
opus_val16 lpc[4], mem[4]={0,0,0,0};
#ifdef FIXED_POINT
int shift;
opus_val32 maxabs = celt_maxabs32(x[0], len);
if (C==2)
{
opus_val32 maxabs_1 = celt_maxabs32(x[1], len);
maxabs = MAX32(maxabs, maxabs_1);
}
if (maxabs<1)
maxabs=1;
shift = celt_ilog2(maxabs)-10;
if (shift<0)
shift=0;
if (C==2)
shift++;
#endif
for (i=1;i<len>>1;i++)
x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift);
x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift);
if (C==2)
{
for (i=1;i<len>>1;i++)
x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift);
x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift);
}
_celt_autocorr(x_lp, ac, NULL, 0,
4, len>>1);
/* Noise floor -40 dB */
#ifdef FIXED_POINT
ac[0] += SHR32(ac[0],13);
#else
ac[0] *= 1.0001f;
#endif
/* Lag windowing */
for (i=1;i<=4;i++)
{
/*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
#ifdef FIXED_POINT
ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
#else
ac[i] -= ac[i]*(.008f*i)*(.008f*i);
#endif
}
_celt_lpc(lpc, ac, 4);
for (i=0;i<4;i++)
{
tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp);
lpc[i] = MULT16_16_Q15(lpc[i], tmp);
}
celt_fir(x_lp, lpc, x_lp, len>>1, 4, mem);
mem[0]=0;
lpc[0]=QCONST16(.8f,12);
celt_fir(x_lp, lpc, x_lp, len>>1, 1, mem);
}
void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,
int len, int max_pitch, int *pitch)
{
int i, j;
int lag;
int best_pitch[2]={0,0};
VARDECL(opus_val16, x_lp4);
VARDECL(opus_val16, y_lp4);
VARDECL(opus_val32, xcorr);
#ifdef FIXED_POINT
opus_val32 maxcorr=1;
opus_val32 xmax, ymax;
int shift=0;
#endif
int offset;
SAVE_STACK;
celt_assert(len>0);
celt_assert(max_pitch>0);
lag = len+max_pitch;
ALLOC(x_lp4, len>>2, opus_val16);
ALLOC(y_lp4, lag>>2, opus_val16);
ALLOC(xcorr, max_pitch>>1, opus_val32);
/* Downsample by 2 again */
for (j=0;j<len>>2;j++)
x_lp4[j] = x_lp[2*j];
for (j=0;j<lag>>2;j++)
y_lp4[j] = y[2*j];
#ifdef FIXED_POINT
xmax = celt_maxabs16(x_lp4, len>>2);
ymax = celt_maxabs16(y_lp4, lag>>2);
shift = celt_ilog2(MAX32(1, MAX32(xmax, ymax)))-11;
if (shift>0)
{
for (j=0;j<len>>2;j++)
x_lp4[j] = SHR16(x_lp4[j], shift);
for (j=0;j<lag>>2;j++)
y_lp4[j] = SHR16(y_lp4[j], shift);
/* Use double the shift for a MAC */
shift *= 2;
} else {
shift = 0;
}
#endif
/* Coarse search with 4x decimation */
for (i=0;i<max_pitch>>2;i++)
{
opus_val32 sum = 0;
for (j=0;j<len>>2;j++)
sum = MAC16_16(sum, x_lp4[j],y_lp4[i+j]);
xcorr[i] = MAX32(-1, sum);
#ifdef FIXED_POINT
maxcorr = MAX32(maxcorr, sum);
#endif
}
find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch
#ifdef FIXED_POINT
, 0, maxcorr
#endif
);
/* Finer search with 2x decimation */
#ifdef FIXED_POINT
maxcorr=1;
#endif
for (i=0;i<max_pitch>>1;i++)
{
opus_val32 sum=0;
xcorr[i] = 0;
if (abs(i-2*best_pitch[0])>2 && abs(i-2*best_pitch[1])>2)
continue;
for (j=0;j<len>>1;j++)
sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift);
xcorr[i] = MAX32(-1, sum);
#ifdef FIXED_POINT
maxcorr = MAX32(maxcorr, sum);
#endif
}
find_best_pitch(xcorr, y, len>>1, max_pitch>>1, best_pitch
#ifdef FIXED_POINT
, shift+1, maxcorr
#endif
);
/* Refine by pseudo-interpolation */
if (best_pitch[0]>0 && best_pitch[0]<(max_pitch>>1)-1)
{
opus_val32 a, b, c;
a = xcorr[best_pitch[0]-1];
b = xcorr[best_pitch[0]];
c = xcorr[best_pitch[0]+1];
if ((c-a) > MULT16_32_Q15(QCONST16(.7f,15),b-a))
offset = 1;
else if ((a-c) > MULT16_32_Q15(QCONST16(.7f,15),b-c))
offset = -1;
else
offset = 0;
} else {
offset = 0;
}
*pitch = 2*best_pitch[0]-offset;
RESTORE_STACK;
}
static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2};
opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
int N, int *T0_, int prev_period, opus_val16 prev_gain)
{
int k, i, T, T0;
opus_val16 g, g0;
opus_val16 pg;
opus_val32 xy,xx,yy;
opus_val32 xcorr[3];
opus_val32 best_xy, best_yy;
int offset;
int minperiod0;
minperiod0 = minperiod;
maxperiod /= 2;
minperiod /= 2;
*T0_ /= 2;
prev_period /= 2;
N /= 2;
x += maxperiod;
if (*T0_>=maxperiod)
*T0_=maxperiod-1;
T = T0 = *T0_;
xx=xy=yy=0;
for (i=0;i<N;i++)
{
xy = MAC16_16(xy, x[i], x[i-T0]);
xx = MAC16_16(xx, x[i], x[i]);
yy = MAC16_16(yy, x[i-T0],x[i-T0]);
}
best_xy = xy;
best_yy = yy;
#ifdef FIXED_POINT
{
opus_val32 x2y2;
int sh, t;
x2y2 = 1+HALF32(MULT32_32_Q31(xx,yy));
sh = celt_ilog2(x2y2)>>1;
t = VSHR32(x2y2, 2*(sh-7));
g = g0 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
}
#else
g = g0 = xy/celt_sqrt(1+xx*yy);
#endif
/* Look for any pitch at T/k */
for (k=2;k<=15;k++)
{
int T1, T1b;
opus_val16 g1;
opus_val16 cont=0;
T1 = (2*T0+k)/(2*k);
if (T1 < minperiod)
break;
/* Look for another strong correlation at T1b */
if (k==2)
{
if (T1+T0>maxperiod)
T1b = T0;
else
T1b = T0+T1;
} else
{
T1b = (2*second_check[k]*T0+k)/(2*k);
}
xy=yy=0;
for (i=0;i<N;i++)
{
xy = MAC16_16(xy, x[i], x[i-T1]);
yy = MAC16_16(yy, x[i-T1], x[i-T1]);
xy = MAC16_16(xy, x[i], x[i-T1b]);
yy = MAC16_16(yy, x[i-T1b], x[i-T1b]);
}
#ifdef FIXED_POINT
{
opus_val32 x2y2;
int sh, t;
x2y2 = 1+MULT32_32_Q31(xx,yy);
sh = celt_ilog2(x2y2)>>1;
t = VSHR32(x2y2, 2*(sh-7));
g1 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
}
#else
g1 = xy/celt_sqrt(1+2.f*xx*1.f*yy);
#endif
if (abs(T1-prev_period)<=1)
cont = prev_gain;
else if (abs(T1-prev_period)<=2 && 5*k*k < T0)
cont = HALF32(prev_gain);
else
cont = 0;
if (g1 > QCONST16(.3f,15) + MULT16_16_Q15(QCONST16(.4f,15),g0)-cont)
{
best_xy = xy;
best_yy = yy;
T = T1;
g = g1;
}
}
best_xy = MAX32(0, best_xy);
if (best_yy <= best_xy)
pg = Q15ONE;
else
pg = SHR32(frac_div32(best_xy,best_yy+1),16);
for (k=0;k<3;k++)
{
int T1 = T+k-1;
xy = 0;
for (i=0;i<N;i++)
xy = MAC16_16(xy, x[i], x[i-T1]);
xcorr[k] = xy;
}
if ((xcorr[2]-xcorr[0]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[0]))
offset = 1;
else if ((xcorr[0]-xcorr[2]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[2]))
offset = -1;
else
offset = 0;
if (pg > g)
pg = g;
*T0_ = 2*T+offset;
if (*T0_<minperiod0)
*T0_=minperiod0;
return pg;
}

View File

@ -0,0 +1,48 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/**
@file pitch.h
@brief Pitch analysis
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PITCH_H
#define PITCH_H
#include "modes.h"
void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,
int len, int C);
void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,
int len, int max_pitch, int *pitch);
opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
int N, int *T0, int prev_period, opus_val16 prev_gain);
#endif

View File

@ -0,0 +1,572 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "quant_bands.h"
#include "laplace.h"
#include <math.h>
#include "os_support.h"
#include "arch.h"
#include "mathops.h"
#include "stack_alloc.h"
#include "rate.h"
#ifdef FIXED_POINT
/* Mean energy in each band quantized in Q6 */
static const signed char eMeans[25] = {
103,100, 92, 85, 81,
77, 72, 70, 78, 75,
73, 71, 78, 74, 69,
72, 70, 74, 76, 71,
60, 60, 60, 60, 60
};
#else
/* Mean energy in each band quantized in Q6 and converted back to float */
static const opus_val16 eMeans[25] = {
6.437500f, 6.250000f, 5.750000f, 5.312500f, 5.062500f,
4.812500f, 4.500000f, 4.375000f, 4.875000f, 4.687500f,
4.562500f, 4.437500f, 4.875000f, 4.625000f, 4.312500f,
4.500000f, 4.375000f, 4.625000f, 4.750000f, 4.437500f,
3.750000f, 3.750000f, 3.750000f, 3.750000f, 3.750000f
};
#endif
/* prediction coefficients: 0.9, 0.8, 0.65, 0.5 */
#ifdef FIXED_POINT
static const opus_val16 pred_coef[4] = {29440, 26112, 21248, 16384};
static const opus_val16 beta_coef[4] = {30147, 22282, 12124, 6554};
static const opus_val16 beta_intra = 4915;
#else
static const opus_val16 pred_coef[4] = {29440/32768., 26112/32768., 21248/32768., 16384/32768.};
static const opus_val16 beta_coef[4] = {30147/32768., 22282/32768., 12124/32768., 6554/32768.};
static const opus_val16 beta_intra = 4915/32768.;
#endif
/*Parameters of the Laplace-like probability models used for the coarse energy.
There is one pair of parameters for each frame size, prediction type
(inter/intra), and band number.
The first number of each pair is the probability of 0, and the second is the
decay rate, both in Q8 precision.*/
static const unsigned char e_prob_model[4][2][42] = {
/*120 sample frames.*/
{
/*Inter*/
{
72, 127, 65, 129, 66, 128, 65, 128, 64, 128, 62, 128, 64, 128,
64, 128, 92, 78, 92, 79, 92, 78, 90, 79, 116, 41, 115, 40,
114, 40, 132, 26, 132, 26, 145, 17, 161, 12, 176, 10, 177, 11
},
/*Intra*/
{
24, 179, 48, 138, 54, 135, 54, 132, 53, 134, 56, 133, 55, 132,
55, 132, 61, 114, 70, 96, 74, 88, 75, 88, 87, 74, 89, 66,
91, 67, 100, 59, 108, 50, 120, 40, 122, 37, 97, 43, 78, 50
}
},
/*240 sample frames.*/
{
/*Inter*/
{
83, 78, 84, 81, 88, 75, 86, 74, 87, 71, 90, 73, 93, 74,
93, 74, 109, 40, 114, 36, 117, 34, 117, 34, 143, 17, 145, 18,
146, 19, 162, 12, 165, 10, 178, 7, 189, 6, 190, 8, 177, 9
},
/*Intra*/
{
23, 178, 54, 115, 63, 102, 66, 98, 69, 99, 74, 89, 71, 91,
73, 91, 78, 89, 86, 80, 92, 66, 93, 64, 102, 59, 103, 60,
104, 60, 117, 52, 123, 44, 138, 35, 133, 31, 97, 38, 77, 45
}
},
/*480 sample frames.*/
{
/*Inter*/
{
61, 90, 93, 60, 105, 42, 107, 41, 110, 45, 116, 38, 113, 38,
112, 38, 124, 26, 132, 27, 136, 19, 140, 20, 155, 14, 159, 16,
158, 18, 170, 13, 177, 10, 187, 8, 192, 6, 175, 9, 159, 10
},
/*Intra*/
{
21, 178, 59, 110, 71, 86, 75, 85, 84, 83, 91, 66, 88, 73,
87, 72, 92, 75, 98, 72, 105, 58, 107, 54, 115, 52, 114, 55,
112, 56, 129, 51, 132, 40, 150, 33, 140, 29, 98, 35, 77, 42
}
},
/*960 sample frames.*/
{
/*Inter*/
{
42, 121, 96, 66, 108, 43, 111, 40, 117, 44, 123, 32, 120, 36,
119, 33, 127, 33, 134, 34, 139, 21, 147, 23, 152, 20, 158, 25,
154, 26, 166, 21, 173, 16, 184, 13, 184, 10, 150, 13, 139, 15
},
/*Intra*/
{
22, 178, 63, 114, 74, 82, 84, 83, 92, 82, 103, 62, 96, 72,
96, 67, 101, 73, 107, 72, 113, 55, 118, 52, 125, 52, 118, 52,
117, 55, 135, 49, 137, 39, 157, 32, 145, 29, 97, 33, 77, 40
}
}
};
static const unsigned char small_energy_icdf[3]={2,1,0};
#ifdef OPUS_ENABLE_ENCODER
static opus_val32 loss_distortion(const opus_val16 *eBands, opus_val16 *oldEBands, int start, int end, int len, int C)
{
int c, i;
opus_val32 dist = 0;
c=0; do {
for (i=start;i<end;i++)
{
opus_val16 d = SUB16(SHR16(eBands[i+c*len], 3), SHR16(oldEBands[i+c*len], 3));
dist = MAC16_16(dist, d,d);
}
} while (++c<C);
return MIN32(200,SHR32(dist,2*DB_SHIFT-6));
}
static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
const opus_val16 *eBands, opus_val16 *oldEBands,
opus_int32 budget, opus_int32 tell,
const unsigned char *prob_model, opus_val16 *error, ec_enc *enc,
int C, int LM, int intra, opus_val16 max_decay)
{
int i, c;
int badness = 0;
opus_val32 prev[2] = {0,0};
opus_val16 coef;
opus_val16 beta;
if (tell+3 <= budget)
ec_enc_bit_logp(enc, intra, 3);
if (intra)
{
coef = 0;
beta = beta_intra;
} else {
beta = beta_coef[LM];
coef = pred_coef[LM];
}
/* Encode at a fixed coarse resolution */
for (i=start;i<end;i++)
{
c=0;
do {
int bits_left;
int qi, qi0;
opus_val32 q;
opus_val16 x;
opus_val32 f, tmp;
opus_val16 oldE;
opus_val16 decay_bound;
x = eBands[i+c*m->nbEBands];
oldE = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);
#ifdef FIXED_POINT
f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c];
/* Rounding to nearest integer here is really important! */
qi = (f+QCONST32(.5f,DB_SHIFT+7))>>(DB_SHIFT+7);
decay_bound = EXTRACT16(MAX32(-QCONST16(28.f,DB_SHIFT),
SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay)));
#else
f = x-coef*oldE-prev[c];
/* Rounding to nearest integer here is really important! */
qi = (int)floor(.5f+f);
decay_bound = MAX16(-QCONST16(28.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]) - max_decay;
#endif
/* Prevent the energy from going down too quickly (e.g. for bands
that have just one bin) */
if (qi < 0 && x < decay_bound)
{
qi += (int)SHR16(SUB16(decay_bound,x), DB_SHIFT);
if (qi > 0)
qi = 0;
}
qi0 = qi;
/* If we don't have enough bits to encode all the energy, just assume
something safe. */
tell = ec_tell(enc);
bits_left = budget-tell-3*C*(end-i);
if (i!=start && bits_left < 30)
{
if (bits_left < 24)
qi = IMIN(1, qi);
if (bits_left < 16)
qi = IMAX(-1, qi);
}
if (budget-tell >= 15)
{
int pi;
pi = 2*IMIN(i,20);
ec_laplace_encode(enc, &qi,
prob_model[pi]<<7, prob_model[pi+1]<<6);
}
else if(budget-tell >= 2)
{
qi = IMAX(-1, IMIN(qi, 1));
ec_enc_icdf(enc, 2*qi^-(qi<0), small_energy_icdf, 2);
}
else if(budget-tell >= 1)
{
qi = IMIN(0, qi);
ec_enc_bit_logp(enc, -qi, 1);
}
else
qi = -1;
error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT);
badness += abs(qi0-qi);
q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);
tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(q,7);
#ifdef FIXED_POINT
tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);
#endif
oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);
prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
} while (++c < C);
}
return badness;
}
void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,
opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes,
int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate)
{
int intra;
opus_val16 max_decay;
VARDECL(opus_val16, oldEBands_intra);
VARDECL(opus_val16, error_intra);
ec_enc enc_start_state;
opus_uint32 tell;
int badness1=0;
opus_int32 intra_bias;
opus_val32 new_distortion;
SAVE_STACK;
intra = force_intra || (!two_pass && *delayedIntra>2*C*(end-start) && nbAvailableBytes > (end-start)*C);
intra_bias = (opus_int32)((budget**delayedIntra*loss_rate)/(C*512));
new_distortion = loss_distortion(eBands, oldEBands, start, effEnd, m->nbEBands, C);
tell = ec_tell(enc);
if (tell+3 > budget)
two_pass = intra = 0;
/* Encode the global flags using a simple probability model
(first symbols in the stream) */
max_decay = QCONST16(16.f,DB_SHIFT);
if (end-start>10)
{
#ifdef FIXED_POINT
max_decay = MIN32(max_decay, SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3));
#else
max_decay = MIN32(max_decay, .125f*nbAvailableBytes);
#endif
}
enc_start_state = *enc;
ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16);
ALLOC(error_intra, C*m->nbEBands, opus_val16);
OPUS_COPY(oldEBands_intra, oldEBands, C*m->nbEBands);
if (two_pass || intra)
{
badness1 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands_intra, budget,
tell, e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay);
}
if (!intra)
{
unsigned char *intra_buf;
ec_enc enc_intra_state;
opus_int32 tell_intra;
opus_uint32 nstart_bytes;
opus_uint32 nintra_bytes;
int badness2;
VARDECL(unsigned char, intra_bits);
tell_intra = ec_tell_frac(enc);
enc_intra_state = *enc;
nstart_bytes = ec_range_bytes(&enc_start_state);
nintra_bytes = ec_range_bytes(&enc_intra_state);
intra_buf = ec_get_buffer(&enc_intra_state) + nstart_bytes;
ALLOC(intra_bits, nintra_bytes-nstart_bytes, unsigned char);
/* Copy bits from intra bit-stream */
OPUS_COPY(intra_bits, intra_buf, nintra_bytes - nstart_bytes);
*enc = enc_start_state;
badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget,
tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay);
if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ((opus_int32)ec_tell_frac(enc))+intra_bias > tell_intra)))
{
*enc = enc_intra_state;
/* Copy intra bits to bit-stream */
OPUS_COPY(intra_buf, intra_bits, nintra_bytes - nstart_bytes);
OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands);
OPUS_COPY(error, error_intra, C*m->nbEBands);
intra = 1;
}
} else {
OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands);
OPUS_COPY(error, error_intra, C*m->nbEBands);
}
if (intra)
*delayedIntra = new_distortion;
else
*delayedIntra = ADD32(MULT16_32_Q15(MULT16_16_Q15(pred_coef[LM], pred_coef[LM]),*delayedIntra),
new_distortion);
RESTORE_STACK;
}
void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C)
{
int i, c;
/* Encode finer resolution */
for (i=start;i<end;i++)
{
opus_int16 frac = 1<<fine_quant[i];
if (fine_quant[i] <= 0)
continue;
c=0;
do {
int q2;
opus_val16 offset;
#ifdef FIXED_POINT
/* Has to be without rounding */
q2 = (error[i+c*m->nbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]);
#else
q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac);
#endif
if (q2 > frac-1)
q2 = frac-1;
if (q2<0)
q2 = 0;
ec_enc_bits(enc, q2, fine_quant[i]);
#ifdef FIXED_POINT
offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
#else
offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
#endif
oldEBands[i+c*m->nbEBands] += offset;
error[i+c*m->nbEBands] -= offset;
/*printf ("%f ", error[i] - offset);*/
} while (++c < C);
}
}
void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C)
{
int i, prio, c;
/* Use up the remaining bits */
for (prio=0;prio<2;prio++)
{
for (i=start;i<end && bits_left>=C ;i++)
{
if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio)
continue;
c=0;
do {
int q2;
opus_val16 offset;
q2 = error[i+c*m->nbEBands]<0 ? 0 : 1;
ec_enc_bits(enc, q2, 1);
#ifdef FIXED_POINT
offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1);
#else
offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
#endif
oldEBands[i+c*m->nbEBands] += offset;
bits_left--;
} while (++c < C);
}
}
}
#endif /* OPUS_ENABLE_ENCODER */
void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM)
{
const unsigned char *prob_model = e_prob_model[LM][intra];
int i, c;
opus_val32 prev[2] = {0, 0};
opus_val16 coef;
opus_val16 beta;
opus_int32 budget;
opus_int32 tell;
if (intra)
{
coef = 0;
beta = beta_intra;
} else {
beta = beta_coef[LM];
coef = pred_coef[LM];
}
budget = dec->storage*8;
/* Decode at a fixed coarse resolution */
for (i=start;i<end;i++)
{
c=0;
do {
int qi;
opus_val32 q;
opus_val32 tmp;
/* It would be better to express this invariant as a
test on C at function entry, but that isn't enough
to make the static analyzer happy. */
celt_assert(c<2);
tell = ec_tell(dec);
if(budget-tell>=15)
{
int pi;
pi = 2*IMIN(i,20);
qi = ec_laplace_decode(dec,
prob_model[pi]<<7, prob_model[pi+1]<<6);
}
else if(budget-tell>=2)
{
qi = ec_dec_icdf(dec, small_energy_icdf, 2);
qi = (qi>>1)^-(qi&1);
}
else if(budget-tell>=1)
{
qi = -ec_dec_bit_logp(dec, 1);
}
else
qi = -1;
q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);
oldEBands[i+c*m->nbEBands] = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);
tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(q,7);
#ifdef FIXED_POINT
tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);
#endif
oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);
prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
} while (++c < C);
}
}
void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C)
{
int i, c;
/* Decode finer resolution */
for (i=start;i<end;i++)
{
if (fine_quant[i] <= 0)
continue;
c=0;
do {
int q2;
opus_val16 offset;
q2 = ec_dec_bits(dec, fine_quant[i]);
#ifdef FIXED_POINT
offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
#else
offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
#endif
oldEBands[i+c*m->nbEBands] += offset;
} while (++c < C);
}
}
void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C)
{
int i, prio, c;
/* Use up the remaining bits */
for (prio=0;prio<2;prio++)
{
for (i=start;i<end && bits_left>=C ;i++)
{
if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio)
continue;
c=0;
do {
int q2;
opus_val16 offset;
q2 = ec_dec_bits(dec, 1);
#ifdef FIXED_POINT
offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1);
#else
offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
#endif
oldEBands[i+c*m->nbEBands] += offset;
bits_left--;
} while (++c < C);
}
}
}
void log2Amp(const CELTMode *m, int start, int end,
celt_ener *eBands, const opus_val16 *oldEBands, int C)
{
int c, i;
c=0;
do {
for (i=0;i<start;i++)
eBands[i+c*m->nbEBands] = 0;
for (;i<end;i++)
{
opus_val16 lg = ADD16(oldEBands[i+c*m->nbEBands],
SHL16((opus_val16)eMeans[i],6));
eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4);
}
for (;i<m->nbEBands;i++)
eBands[i+c*m->nbEBands] = 0;
} while (++c < C);
}
void amp2Log2(const CELTMode *m, int effEnd, int end,
celt_ener *bandE, opus_val16 *bandLogE, int C)
{
int c, i;
c=0;
do {
for (i=0;i<effEnd;i++)
bandLogE[i+c*m->nbEBands] =
celt_log2(SHL32(bandE[i+c*m->nbEBands],2))
- SHL16((opus_val16)eMeans[i],6);
for (i=effEnd;i<end;i++)
bandLogE[c*m->nbEBands+i] = -QCONST16(14.f,DB_SHIFT);
} while (++c < C);
}

View File

@ -0,0 +1,60 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef QUANT_BANDS
#define QUANT_BANDS
#include "arch.h"
#include "modes.h"
#include "entenc.h"
#include "entdec.h"
#include "mathops.h"
void amp2Log2(const CELTMode *m, int effEnd, int end,
celt_ener *bandE, opus_val16 *bandLogE, int C);
void log2Amp(const CELTMode *m, int start, int end,
celt_ener *eBands, const opus_val16 *oldEBands, int C);
void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,
opus_val16 *error, ec_enc *enc, int C, int LM,
int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra,
int two_pass, int loss_rate);
void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C);
void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C);
void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM);
void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C);
void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C);
#endif /* QUANT_BANDS */

View File

@ -0,0 +1,645 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include "modes.h"
#include "cwrs.h"
#include "arch.h"
#include "os_support.h"
#include "entcode.h"
#include "rate.h"
static const unsigned char LOG2_FRAC_TABLE[24]={
0,
8,13,
16,19,21,23,
24,26,27,28,29,30,31,32,
32,33,34,34,35,36,36,37,37
};
#ifdef CUSTOM_MODES
/*Determines if V(N,K) fits in a 32-bit unsigned integer.
N and K are themselves limited to 15 bits.*/
static int fits_in32(int _n, int _k)
{
static const opus_int16 maxN[15] = {
32767, 32767, 32767, 1476, 283, 109, 60, 40,
29, 24, 20, 18, 16, 14, 13};
static const opus_int16 maxK[15] = {
32767, 32767, 32767, 32767, 1172, 238, 95, 53,
36, 27, 22, 18, 16, 15, 13};
if (_n>=14)
{
if (_k>=14)
return 0;
else
return _n <= maxN[_k];
} else {
return _k <= maxK[_n];
}
}
void compute_pulse_cache(CELTMode *m, int LM)
{
int C;
int i;
int j;
int curr=0;
int nbEntries=0;
int entryN[100], entryK[100], entryI[100];
const opus_int16 *eBands = m->eBands;
PulseCache *cache = &m->cache;
opus_int16 *cindex;
unsigned char *bits;
unsigned char *cap;
cindex = (opus_int16 *)opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2));
cache->index = cindex;
/* Scan for all unique band sizes */
for (i=0;i<=LM+1;i++)
{
for (j=0;j<m->nbEBands;j++)
{
int k;
int N = (eBands[j+1]-eBands[j])<<i>>1;
cindex[i*m->nbEBands+j] = -1;
/* Find other bands that have the same size */
for (k=0;k<=i;k++)
{
int n;
for (n=0;n<m->nbEBands && (k!=i || n<j);n++)
{
if (N == (eBands[n+1]-eBands[n])<<k>>1)
{
cindex[i*m->nbEBands+j] = cindex[k*m->nbEBands+n];
break;
}
}
}
if (cache->index[i*m->nbEBands+j] == -1 && N!=0)
{
int K;
entryN[nbEntries] = N;
K = 0;
while (fits_in32(N,get_pulses(K+1)) && K<MAX_PSEUDO)
K++;
entryK[nbEntries] = K;
cindex[i*m->nbEBands+j] = curr;
entryI[nbEntries] = curr;
curr += K+1;
nbEntries++;
}
}
}
bits = (unsigned char *)opus_alloc(sizeof(unsigned char)*curr);
cache->bits = bits;
cache->size = curr;
/* Compute the cache for all unique sizes */
for (i=0;i<nbEntries;i++)
{
unsigned char *ptr = bits+entryI[i];
opus_int16 tmp[MAX_PULSES+1];
get_required_bits(tmp, entryN[i], get_pulses(entryK[i]), BITRES);
for (j=1;j<=entryK[i];j++)
ptr[j] = tmp[get_pulses(j)]-1;
ptr[0] = entryK[i];
}
/* Compute the maximum rate for each band at which we'll reliably use as
many bits as we ask for. */
cache->caps = cap = (unsigned char *)opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands);
for (i=0;i<=LM;i++)
{
for (C=1;C<=2;C++)
{
for (j=0;j<m->nbEBands;j++)
{
int N0;
int max_bits;
N0 = m->eBands[j+1]-m->eBands[j];
/* N=1 bands only have a sign bit and fine bits. */
if (N0<<i == 1)
max_bits = C*(1+MAX_FINE_BITS)<<BITRES;
else
{
const unsigned char *pcache;
opus_int32 num;
opus_int32 den;
int LM0;
int N;
int offset;
int ndof;
int qb;
int k;
LM0 = 0;
/* Even-sized bands bigger than N=2 can be split one more time.
As of commit 44203907 all bands >1 are even, including custom modes.*/
if (N0 > 2)
{
N0>>=1;
LM0--;
}
/* N0=1 bands can't be split down to N<2. */
else if (N0 <= 1)
{
LM0=IMIN(i,1);
N0<<=LM0;
}
/* Compute the cost for the lowest-level PVQ of a fully split
band. */
pcache = bits + cindex[(LM0+1)*m->nbEBands+j];
max_bits = pcache[pcache[0]]+1;
/* Add in the cost of coding regular splits. */
N = N0;
for(k=0;k<i-LM0;k++){
max_bits <<= 1;
/* Offset the number of qtheta bits by log2(N)/2
+ QTHETA_OFFSET compared to their "fair share" of
total/N */
offset = ((m->logN[j]+((LM0+k)<<BITRES))>>1)-QTHETA_OFFSET;
/* The number of qtheta bits we'll allocate if the remainder
is to be max_bits.
The average measured cost for theta is 0.89701 times qb,
approximated here as 459/512. */
num=459*(opus_int32)((2*N-1)*offset+max_bits);
den=((opus_int32)(2*N-1)<<9)-459;
qb = IMIN((num+(den>>1))/den, 57);
celt_assert(qb >= 0);
max_bits += qb;
N <<= 1;
}
/* Add in the cost of a stereo split, if necessary. */
if (C==2)
{
max_bits <<= 1;
offset = ((m->logN[j]+(i<<BITRES))>>1)-(N==2?QTHETA_OFFSET_TWOPHASE:QTHETA_OFFSET);
ndof = 2*N-1-(N==2);
/* The average measured cost for theta with the step PDF is
0.95164 times qb, approximated here as 487/512. */
num = (N==2?512:487)*(opus_int32)(max_bits+ndof*offset);
den = ((opus_int32)ndof<<9)-(N==2?512:487);
qb = IMIN((num+(den>>1))/den, (N==2?64:61));
celt_assert(qb >= 0);
max_bits += qb;
}
/* Add the fine bits we'll use. */
/* Compensate for the extra DoF in stereo */
ndof = C*N + ((C==2 && N>2) ? 1 : 0);
/* Offset the number of fine bits by log2(N)/2 + FINE_OFFSET
compared to their "fair share" of total/N */
offset = ((m->logN[j] + (i<<BITRES))>>1)-FINE_OFFSET;
/* N=2 is the only point that doesn't match the curve */
if (N==2)
offset += 1<<BITRES>>2;
/* The number of fine bits we'll allocate if the remainder is
to be max_bits. */
num = max_bits+ndof*offset;
den = (ndof-1)<<BITRES;
qb = IMIN((num+(den>>1))/den, MAX_FINE_BITS);
celt_assert(qb >= 0);
max_bits += C*qb<<BITRES;
}
max_bits = (4*max_bits/(C*((m->eBands[j+1]-m->eBands[j])<<i)))-64;
celt_assert(max_bits >= 0);
celt_assert(max_bits < 256);
*cap++ = (unsigned char)max_bits;
}
}
}
}
#endif /* CUSTOM_MODES */
#define ALLOC_STEPS 6
static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start,
const int *bits1, const int *bits2, const int *thresh, const int *cap, opus_int32 total, opus_int32 *_balance,
int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits,
int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev)
{
opus_int32 psum;
int lo, hi;
int i, j;
int logM;
int stereo;
int codedBands=-1;
int alloc_floor;
opus_int32 left, percoeff;
int done;
opus_int32 balance;
SAVE_STACK;
alloc_floor = C<<BITRES;
stereo = C>1;
logM = LM<<BITRES;
lo = 0;
hi = 1<<ALLOC_STEPS;
for (i=0;i<ALLOC_STEPS;i++)
{
int mid = (lo+hi)>>1;
psum = 0;
done = 0;
for (j=end;j-->start;)
{
int tmp = bits1[j] + (mid*(opus_int32)bits2[j]>>ALLOC_STEPS);
if (tmp >= thresh[j] || done)
{
done = 1;
/* Don't allocate more than we can actually use */
psum += IMIN(tmp, cap[j]);
} else {
if (tmp >= alloc_floor)
psum += alloc_floor;
}
}
if (psum > total)
hi = mid;
else
lo = mid;
}
psum = 0;
/*printf ("interp bisection gave %d\n", lo);*/
done = 0;
for (j=end;j-->start;)
{
int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS);
if (tmp < thresh[j] && !done)
{
if (tmp >= alloc_floor)
tmp = alloc_floor;
else
tmp = 0;
} else
done = 1;
/* Don't allocate more than we can actually use */
tmp = IMIN(tmp, cap[j]);
bits[j] = tmp;
psum += tmp;
}
/* Decide which bands to skip, working backwards from the end. */
for (codedBands=end;;codedBands--)
{
int band_width;
int band_bits;
int rem;
j = codedBands-1;
/* Never skip the first band, nor a band that has been boosted by
dynalloc.
In the first case, we'd be coding a bit to signal we're going to waste
all the other bits.
In the second case, we'd be coding a bit to redistribute all the bits
we just signaled should be cocentrated in this band. */
if (j<=skip_start)
{
/* Give the bit we reserved to end skipping back. */
total += skip_rsv;
break;
}
/*Figure out how many left-over bits we would be adding to this band.
This can include bits we've stolen back from higher, skipped bands.*/
left = total-psum;
percoeff = left/(m->eBands[codedBands]-m->eBands[start]);
left -= (m->eBands[codedBands]-m->eBands[start])*percoeff;
rem = IMAX(left-(m->eBands[j]-m->eBands[start]),0);
band_width = m->eBands[codedBands]-m->eBands[j];
band_bits = (int)(bits[j] + percoeff*band_width + rem);
/*Only code a skip decision if we're above the threshold for this band.
Otherwise it is force-skipped.
This ensures that we have enough bits to code the skip flag.*/
if (band_bits >= IMAX(thresh[j], alloc_floor+(1<<BITRES)))
{
#ifdef OPUS_ENABLE_ENCODER
if (encode)
{
/*This if() block is the only part of the allocation function that
is not a mandatory part of the bitstream: any bands we choose to
skip here must be explicitly signaled.*/
/*Choose a threshold with some hysteresis to keep bands from
fluctuating in and out.*/
#ifdef FUZZING
if ((rand()&0x1) == 0)
#else
if (codedBands<=start+2 || band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
#endif
{
ec_enc_bit_logp(ec, 1, 1);
break;
}
ec_enc_bit_logp(ec, 0, 1);
} else
#endif /* OPUS_ENABLE_ENCODER */
if (ec_dec_bit_logp(ec, 1)) {
break;
}
/*We used a bit to skip this band.*/
psum += 1<<BITRES;
band_bits -= 1<<BITRES;
}
/*Reclaim the bits originally allocated to this band.*/
psum -= bits[j]+intensity_rsv;
if (intensity_rsv > 0)
intensity_rsv = LOG2_FRAC_TABLE[j-start];
psum += intensity_rsv;
if (band_bits >= alloc_floor)
{
/*If we have enough for a fine energy bit per channel, use it.*/
psum += alloc_floor;
bits[j] = alloc_floor;
} else {
/*Otherwise this band gets nothing at all.*/
bits[j] = 0;
}
}
celt_assert(codedBands > start);
/* Code the intensity and dual stereo parameters. */
if (intensity_rsv > 0)
{
#ifdef OPUS_ENABLE_ENCODER
if (encode)
{
*intensity = IMIN(*intensity, codedBands);
ec_enc_uint(ec, *intensity-start, codedBands+1-start);
}
else
#endif
*intensity = start+ec_dec_uint(ec, codedBands+1-start);
}
else
*intensity = 0;
if (*intensity <= start)
{
total += dual_stereo_rsv;
dual_stereo_rsv = 0;
}
if (dual_stereo_rsv > 0)
{
#ifdef OPUS_ENABLE_ENCODER
if (encode)
ec_enc_bit_logp(ec, *dual_stereo, 1);
else
#endif
*dual_stereo = ec_dec_bit_logp(ec, 1);
}
else
*dual_stereo = 0;
/* Allocate the remaining bits */
left = total-psum;
percoeff = left/(m->eBands[codedBands]-m->eBands[start]);
left -= (m->eBands[codedBands]-m->eBands[start])*percoeff;
for (j=start;j<codedBands;j++)
bits[j] += ((int)percoeff*(m->eBands[j+1]-m->eBands[j]));
for (j=start;j<codedBands;j++)
{
int tmp = (int)IMIN(left, m->eBands[j+1]-m->eBands[j]);
bits[j] += tmp;
left -= tmp;
}
/*for (j=0;j<end;j++)printf("%d ", bits[j]);printf("\n");*/
balance = 0;
for (j=start;j<codedBands;j++)
{
int N0, N, den;
int offset;
int NClogN;
opus_int32 excess, bit;
celt_assert(bits[j] >= 0);
N0 = m->eBands[j+1]-m->eBands[j];
N=N0<<LM;
bit = (opus_int32)bits[j]+balance;
if (N>1)
{
excess = MAX32(bit-cap[j],0);
bits[j] = bit-excess;
/* Compensate for the extra DoF in stereo */
den=(C*N+ ((C==2 && N>2 && !*dual_stereo && j<*intensity) ? 1 : 0));
NClogN = den*(m->logN[j] + logM);
/* Offset for the number of fine bits by log2(N)/2 + FINE_OFFSET
compared to their "fair share" of total/N */
offset = (NClogN>>1)-den*FINE_OFFSET;
/* N=2 is the only point that doesn't match the curve */
if (N==2)
offset += den<<BITRES>>2;
/* Changing the offset for allocating the second and third
fine energy bit */
if (bits[j] + offset < den*2<<BITRES)
offset += NClogN>>2;
else if (bits[j] + offset < den*3<<BITRES)
offset += NClogN>>3;
/* Divide with rounding */
ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1))) / (den<<BITRES));
/* Make sure not to bust */
if (C*ebits[j] > (bits[j]>>BITRES))
ebits[j] = bits[j] >> stereo >> BITRES;
/* More than that is useless because that's about as far as PVQ can go */
ebits[j] = IMIN(ebits[j], MAX_FINE_BITS);
/* If we rounded down or capped this band, make it a candidate for the
final fine energy pass */
fine_priority[j] = ebits[j]*(den<<BITRES) >= bits[j]+offset;
/* Remove the allocated fine bits; the rest are assigned to PVQ */
bits[j] -= C*ebits[j]<<BITRES;
} else {
/* For N=1, all bits go to fine energy except for a single sign bit */
excess = MAX32(0,bit-(C<<BITRES));
bits[j] = bit-excess;
ebits[j] = 0;
fine_priority[j] = 1;
}
/* Fine energy can't take advantage of the re-balancing in
quant_all_bands().
Instead, do the re-balancing here.*/
if(excess > 0)
{
int extra_fine;
int extra_bits;
extra_fine = IMIN(excess>>(stereo+BITRES),MAX_FINE_BITS-ebits[j]);
ebits[j] += extra_fine;
extra_bits = extra_fine*C<<BITRES;
fine_priority[j] = extra_bits >= excess-balance;
excess -= extra_bits;
}
balance = excess;
celt_assert(bits[j] >= 0);
celt_assert(ebits[j] >= 0);
}
/* Save any remaining bits over the cap for the rebalancing in
quant_all_bands(). */
*_balance = balance;
/* The skipped bands use all their bits for fine energy. */
for (;j<end;j++)
{
ebits[j] = bits[j] >> stereo >> BITRES;
celt_assert(C*ebits[j]<<BITRES == bits[j]);
bits[j] = 0;
fine_priority[j] = ebits[j]<1;
}
RESTORE_STACK;
return codedBands;
}
int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev)
{
int lo, hi, len, j;
int codedBands;
int skip_start;
int skip_rsv;
int intensity_rsv;
int dual_stereo_rsv;
VARDECL(int, bits1);
VARDECL(int, bits2);
VARDECL(int, thresh);
VARDECL(int, trim_offset);
SAVE_STACK;
total = IMAX(total, 0);
len = m->nbEBands;
skip_start = start;
/* Reserve a bit to signal the end of manually skipped bands. */
skip_rsv = total >= 1<<BITRES ? 1<<BITRES : 0;
total -= skip_rsv;
/* Reserve bits for the intensity and dual stereo parameters. */
intensity_rsv = dual_stereo_rsv = 0;
if (C==2)
{
intensity_rsv = LOG2_FRAC_TABLE[end-start];
if (intensity_rsv>total)
intensity_rsv = 0;
else
{
total -= intensity_rsv;
dual_stereo_rsv = total>=1<<BITRES ? 1<<BITRES : 0;
total -= dual_stereo_rsv;
}
}
ALLOC(bits1, len, int);
ALLOC(bits2, len, int);
ALLOC(thresh, len, int);
ALLOC(trim_offset, len, int);
for (j=start;j<end;j++)
{
/* Below this threshold, we're sure not to allocate any PVQ bits */
thresh[j] = IMAX((C)<<BITRES, (3*(m->eBands[j+1]-m->eBands[j])<<LM<<BITRES)>>4);
/* Tilt of the allocation curve */
trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(end-j-1)
*(1<<(LM+BITRES))>>6;
/* Giving less resolution to single-coefficient bands because they get
more benefit from having one coarse value per coefficient*/
if ((m->eBands[j+1]-m->eBands[j])<<LM==1)
trim_offset[j] -= C<<BITRES;
}
lo = 1;
hi = m->nbAllocVectors - 1;
do
{
int done = 0;
int psum = 0;
int mid = (lo+hi) >> 1;
for (j=end;j-->start;)
{
int bitsj;
int N = m->eBands[j+1]-m->eBands[j];
bitsj = C*N*m->allocVectors[mid*len+j]<<LM>>2;
if (bitsj > 0)
bitsj = IMAX(0, bitsj + trim_offset[j]);
bitsj += offsets[j];
if (bitsj >= thresh[j] || done)
{
done = 1;
/* Don't allocate more than we can actually use */
psum += IMIN(bitsj, cap[j]);
} else {
if (bitsj >= C<<BITRES)
psum += C<<BITRES;
}
}
if (psum > total)
hi = mid - 1;
else
lo = mid + 1;
/*printf ("lo = %d, hi = %d\n", lo, hi);*/
}
while (lo <= hi);
hi = lo--;
/*printf ("interp between %d and %d\n", lo, hi);*/
for (j=start;j<end;j++)
{
int bits1j, bits2j;
int N = m->eBands[j+1]-m->eBands[j];
bits1j = C*N*m->allocVectors[lo*len+j]<<LM>>2;
bits2j = hi>=m->nbAllocVectors ?
cap[j] : C*N*m->allocVectors[hi*len+j]<<LM>>2;
if (bits1j > 0)
bits1j = IMAX(0, bits1j + trim_offset[j]);
if (bits2j > 0)
bits2j = IMAX(0, bits2j + trim_offset[j]);
if (lo > 0)
bits1j += offsets[j];
bits2j += offsets[j];
if (offsets[j]>0)
skip_start = j;
bits2j = IMAX(0,bits2j-bits1j);
bits1[j] = bits1j;
bits2[j] = bits2j;
}
codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, cap,
total, balance, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv,
pulses, ebits, fine_priority, C, LM, ec, encode, prev);
RESTORE_STACK;
return codedBands;
}

View File

@ -0,0 +1,101 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RATE_H
#define RATE_H
#define MAX_PSEUDO 40
#define LOG_MAX_PSEUDO 6
#define MAX_PULSES 128
#define MAX_FINE_BITS 8
#define FINE_OFFSET 21
#define QTHETA_OFFSET 4
#define QTHETA_OFFSET_TWOPHASE 16
#include "cwrs.h"
#include "modes.h"
void compute_pulse_cache(CELTMode *m, int LM);
static inline int get_pulses(int i)
{
return i<8 ? i : (8 + (i&7)) << ((i>>3)-1);
}
static inline int bits2pulses(const CELTMode *m, int band, int LM, int bits)
{
int i;
int lo, hi;
const unsigned char *cache;
LM++;
cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band];
lo = 0;
hi = cache[0];
bits--;
for (i=0;i<LOG_MAX_PSEUDO;i++)
{
int mid = (lo+hi+1)>>1;
/* OPT: Make sure this is implemented with a conditional move */
if ((int)cache[mid] >= bits)
hi = mid;
else
lo = mid;
}
if (bits- (lo == 0 ? -1 : (int)cache[lo]) <= (int)cache[hi]-bits)
return lo;
else
return hi;
}
static inline int pulses2bits(const CELTMode *m, int band, int LM, int pulses)
{
const unsigned char *cache;
LM++;
cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band];
return pulses == 0 ? 0 : cache[pulses]+1;
}
/** Compute the pulse allocation, i.e. how many pulses will go in each
* band.
@param m mode
@param offsets Requested increase or decrease in the number of bits for
each band
@param total Number of bands
@param pulses Number of pulses per band (returned)
@return Total number of bits allocated
*/
int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev);
#endif

View File

@ -0,0 +1,149 @@
/* Copyright (C) 2002-2003 Jean-Marc Valin
Copyright (C) 2007-2009 Xiph.Org Foundation */
/**
@file stack_alloc.h
@brief Temporary memory allocation on stack
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STACK_ALLOC_H
#define STACK_ALLOC_H
#if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA) && !defined (NONTHREADSAFE_PSEUDOSTACK))
#error "Opus requires one of VAR_ARRAYS, USE_ALLOCA, or NONTHREADSAFE_PSEUDOSTACK be defined to select the temporary allocation mode."
#endif
#ifdef USE_ALLOCA
# ifdef WIN32
# include <malloc.h>
# else
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# else
# include <stdlib.h>
# endif
# endif
#endif
/**
* @def ALIGN(stack, size)
*
* Aligns the stack to a 'size' boundary
*
* @param stack Stack
* @param size New size boundary
*/
/**
* @def PUSH(stack, size, type)
*
* Allocates 'size' elements of type 'type' on the stack
*
* @param stack Stack
* @param size Number of elements
* @param type Type of element
*/
/**
* @def VARDECL(var)
*
* Declare variable on stack
*
* @param var Variable to declare
*/
/**
* @def ALLOC(var, size, type)
*
* Allocate 'size' elements of 'type' on stack
*
* @param var Name of variable to allocate
* @param size Number of elements
* @param type Type of element
*/
#if defined(VAR_ARRAYS)
#define VARDECL(type, var)
#define ALLOC(var, size, type) type var[size]
#define SAVE_STACK
#define RESTORE_STACK
#define ALLOC_STACK
#elif defined(USE_ALLOCA)
#define VARDECL(type, var) type *var
# ifdef WIN32
# define ALLOC(var, size, type) var = ((type*)_alloca(sizeof(type)*(size)))
# else
# define ALLOC(var, size, type) var = ((type*)alloca(sizeof(type)*(size)))
# endif
#define SAVE_STACK
#define RESTORE_STACK
#define ALLOC_STACK
#else
#ifdef CELT_C
char *global_stack=0;
#else
extern char *global_stack;
#endif /* CELT_C */
#ifdef ENABLE_VALGRIND
#include <valgrind/memcheck.h>
#ifdef CELT_C
char *global_stack_top=0;
#else
extern char *global_stack_top;
#endif /* CELT_C */
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
#define PUSH(stack, size, type) (VALGRIND_MAKE_MEM_NOACCESS(stack, global_stack_top-stack),ALIGN((stack),sizeof(type)/sizeof(char)),VALGRIND_MAKE_MEM_UNDEFINED(stack, ((size)*sizeof(type)/sizeof(char))),(stack)+=(2*(size)*sizeof(type)/sizeof(char)),(type*)((stack)-(2*(size)*sizeof(type)/sizeof(char))))
#define RESTORE_STACK ((global_stack = _saved_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack))
#define ALLOC_STACK char *_saved_stack; ((global_stack = (global_stack==0) ? ((global_stack_top=opus_alloc_scratch(GLOBAL_STACK_SIZE*2)+(GLOBAL_STACK_SIZE*2))-(GLOBAL_STACK_SIZE*2)) : global_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack)); _saved_stack = global_stack;
#else
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)/sizeof(char)),(stack)+=(size)*(sizeof(type)/sizeof(char)),(type*)((stack)-(size)*(sizeof(type)/sizeof(char))))
#define RESTORE_STACK (global_stack = _saved_stack)
#define ALLOC_STACK char *_saved_stack; (global_stack = (global_stack==0) ? opus_alloc_scratch(GLOBAL_STACK_SIZE) : global_stack); _saved_stack = global_stack;
#endif /* ENABLE_VALGRIND */
#include "os_support.h"
#define VARDECL(type, var) type *var
#define ALLOC(var, size, type) var = PUSH(global_stack, size, type)
#define SAVE_STACK char *_saved_stack = global_stack;
#endif /* VAR_ARRAYS */
#endif /* STACK_ALLOC_H */

View File

@ -0,0 +1,595 @@
/* The contents of this file was automatically generated by dump_modes.c
with arguments: 48000 960
It contains static definitions for some pre-defined modes. */
#include "modes.h"
#include "rate.h"
#ifndef DEF_WINDOW120
#define DEF_WINDOW120
static const opus_val16 window120[120] = {
2, 20, 55, 108, 178,
266, 372, 494, 635, 792,
966, 1157, 1365, 1590, 1831,
2089, 2362, 2651, 2956, 3276,
3611, 3961, 4325, 4703, 5094,
5499, 5916, 6346, 6788, 7241,
7705, 8179, 8663, 9156, 9657,
10167, 10684, 11207, 11736, 12271,
12810, 13353, 13899, 14447, 14997,
15547, 16098, 16648, 17197, 17744,
18287, 18827, 19363, 19893, 20418,
20936, 21447, 21950, 22445, 22931,
23407, 23874, 24330, 24774, 25208,
25629, 26039, 26435, 26819, 27190,
27548, 27893, 28224, 28541, 28845,
29135, 29411, 29674, 29924, 30160,
30384, 30594, 30792, 30977, 31151,
31313, 31463, 31602, 31731, 31849,
31958, 32057, 32148, 32229, 32303,
32370, 32429, 32481, 32528, 32568,
32604, 32634, 32661, 32683, 32701,
32717, 32729, 32740, 32748, 32754,
32758, 32762, 32764, 32766, 32767,
32767, 32767, 32767, 32767, 32767,
};
#endif
#ifndef DEF_LOGN400
#define DEF_LOGN400
static const opus_int16 logN400[21] = {
0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, };
#endif
#ifndef DEF_PULSE_CACHE50
#define DEF_PULSE_CACHE50
static const opus_int16 cache_index50[105] = {
-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41,
82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41,
41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41,
41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305,
318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240,
305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240,
240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387,
};
static const unsigned char cache_bits50[392] = {
40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28,
31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50,
51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65,
66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61,
64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92,
94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123,
124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94,
97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139,
142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35,
28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149,
153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225,
229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157,
166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63,
86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250,
25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180,
185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89,
110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41,
74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138,
163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214,
228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49,
90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47,
87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57,
106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187,
224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127,
182, 234, };
static const unsigned char cache_caps50[168] = {
224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185,
178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240,
240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160,
160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172,
138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207,
204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185,
185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39,
207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201,
188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193,
193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204,
204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175,
140, 66, 40, };
#endif
#ifndef FFT_TWIDDLES48000_960
#define FFT_TWIDDLES48000_960
static const kiss_twiddle_cpx fft_twiddles48000_960[480] = {
{32767, 0}, {32766, -429},
{32757, -858}, {32743, -1287},
{32724, -1715}, {32698, -2143},
{32667, -2570}, {32631, -2998},
{32588, -3425}, {32541, -3851},
{32488, -4277}, {32429, -4701},
{32364, -5125}, {32295, -5548},
{32219, -5971}, {32138, -6393},
{32051, -6813}, {31960, -7231},
{31863, -7650}, {31760, -8067},
{31652, -8481}, {31539, -8895},
{31419, -9306}, {31294, -9716},
{31165, -10126}, {31030, -10532},
{30889, -10937}, {30743, -11340},
{30592, -11741}, {30436, -12141},
{30274, -12540}, {30107, -12935},
{29936, -13328}, {29758, -13718},
{29577, -14107}, {29390, -14493},
{29197, -14875}, {29000, -15257},
{28797, -15635}, {28590, -16010},
{28379, -16384}, {28162, -16753},
{27940, -17119}, {27714, -17484},
{27482, -17845}, {27246, -18205},
{27006, -18560}, {26760, -18911},
{26510, -19260}, {26257, -19606},
{25997, -19947}, {25734, -20286},
{25466, -20621}, {25194, -20952},
{24918, -21281}, {24637, -21605},
{24353, -21926}, {24063, -22242},
{23770, -22555}, {23473, -22865},
{23171, -23171}, {22866, -23472},
{22557, -23769}, {22244, -24063},
{21927, -24352}, {21606, -24636},
{21282, -24917}, {20954, -25194},
{20622, -25465}, {20288, -25733},
{19949, -25997}, {19607, -26255},
{19261, -26509}, {18914, -26760},
{18561, -27004}, {18205, -27246},
{17846, -27481}, {17485, -27713},
{17122, -27940}, {16755, -28162},
{16385, -28378}, {16012, -28590},
{15636, -28797}, {15258, -28999},
{14878, -29197}, {14494, -29389},
{14108, -29576}, {13720, -29757},
{13329, -29934}, {12937, -30107},
{12540, -30274}, {12142, -30435},
{11744, -30592}, {11342, -30743},
{10939, -30889}, {10534, -31030},
{10127, -31164}, {9718, -31294},
{9307, -31418}, {8895, -31537},
{8482, -31652}, {8067, -31759},
{7650, -31862}, {7233, -31960},
{6815, -32051}, {6393, -32138},
{5973, -32219}, {5549, -32294},
{5127, -32364}, {4703, -32429},
{4278, -32487}, {3852, -32541},
{3426, -32588}, {2999, -32630},
{2572, -32667}, {2144, -32698},
{1716, -32724}, {1287, -32742},
{860, -32757}, {430, -32766},
{0, -32767}, {-429, -32766},
{-858, -32757}, {-1287, -32743},
{-1715, -32724}, {-2143, -32698},
{-2570, -32667}, {-2998, -32631},
{-3425, -32588}, {-3851, -32541},
{-4277, -32488}, {-4701, -32429},
{-5125, -32364}, {-5548, -32295},
{-5971, -32219}, {-6393, -32138},
{-6813, -32051}, {-7231, -31960},
{-7650, -31863}, {-8067, -31760},
{-8481, -31652}, {-8895, -31539},
{-9306, -31419}, {-9716, -31294},
{-10126, -31165}, {-10532, -31030},
{-10937, -30889}, {-11340, -30743},
{-11741, -30592}, {-12141, -30436},
{-12540, -30274}, {-12935, -30107},
{-13328, -29936}, {-13718, -29758},
{-14107, -29577}, {-14493, -29390},
{-14875, -29197}, {-15257, -29000},
{-15635, -28797}, {-16010, -28590},
{-16384, -28379}, {-16753, -28162},
{-17119, -27940}, {-17484, -27714},
{-17845, -27482}, {-18205, -27246},
{-18560, -27006}, {-18911, -26760},
{-19260, -26510}, {-19606, -26257},
{-19947, -25997}, {-20286, -25734},
{-20621, -25466}, {-20952, -25194},
{-21281, -24918}, {-21605, -24637},
{-21926, -24353}, {-22242, -24063},
{-22555, -23770}, {-22865, -23473},
{-23171, -23171}, {-23472, -22866},
{-23769, -22557}, {-24063, -22244},
{-24352, -21927}, {-24636, -21606},
{-24917, -21282}, {-25194, -20954},
{-25465, -20622}, {-25733, -20288},
{-25997, -19949}, {-26255, -19607},
{-26509, -19261}, {-26760, -18914},
{-27004, -18561}, {-27246, -18205},
{-27481, -17846}, {-27713, -17485},
{-27940, -17122}, {-28162, -16755},
{-28378, -16385}, {-28590, -16012},
{-28797, -15636}, {-28999, -15258},
{-29197, -14878}, {-29389, -14494},
{-29576, -14108}, {-29757, -13720},
{-29934, -13329}, {-30107, -12937},
{-30274, -12540}, {-30435, -12142},
{-30592, -11744}, {-30743, -11342},
{-30889, -10939}, {-31030, -10534},
{-31164, -10127}, {-31294, -9718},
{-31418, -9307}, {-31537, -8895},
{-31652, -8482}, {-31759, -8067},
{-31862, -7650}, {-31960, -7233},
{-32051, -6815}, {-32138, -6393},
{-32219, -5973}, {-32294, -5549},
{-32364, -5127}, {-32429, -4703},
{-32487, -4278}, {-32541, -3852},
{-32588, -3426}, {-32630, -2999},
{-32667, -2572}, {-32698, -2144},
{-32724, -1716}, {-32742, -1287},
{-32757, -860}, {-32766, -430},
{-32767, 0}, {-32766, 429},
{-32757, 858}, {-32743, 1287},
{-32724, 1715}, {-32698, 2143},
{-32667, 2570}, {-32631, 2998},
{-32588, 3425}, {-32541, 3851},
{-32488, 4277}, {-32429, 4701},
{-32364, 5125}, {-32295, 5548},
{-32219, 5971}, {-32138, 6393},
{-32051, 6813}, {-31960, 7231},
{-31863, 7650}, {-31760, 8067},
{-31652, 8481}, {-31539, 8895},
{-31419, 9306}, {-31294, 9716},
{-31165, 10126}, {-31030, 10532},
{-30889, 10937}, {-30743, 11340},
{-30592, 11741}, {-30436, 12141},
{-30274, 12540}, {-30107, 12935},
{-29936, 13328}, {-29758, 13718},
{-29577, 14107}, {-29390, 14493},
{-29197, 14875}, {-29000, 15257},
{-28797, 15635}, {-28590, 16010},
{-28379, 16384}, {-28162, 16753},
{-27940, 17119}, {-27714, 17484},
{-27482, 17845}, {-27246, 18205},
{-27006, 18560}, {-26760, 18911},
{-26510, 19260}, {-26257, 19606},
{-25997, 19947}, {-25734, 20286},
{-25466, 20621}, {-25194, 20952},
{-24918, 21281}, {-24637, 21605},
{-24353, 21926}, {-24063, 22242},
{-23770, 22555}, {-23473, 22865},
{-23171, 23171}, {-22866, 23472},
{-22557, 23769}, {-22244, 24063},
{-21927, 24352}, {-21606, 24636},
{-21282, 24917}, {-20954, 25194},
{-20622, 25465}, {-20288, 25733},
{-19949, 25997}, {-19607, 26255},
{-19261, 26509}, {-18914, 26760},
{-18561, 27004}, {-18205, 27246},
{-17846, 27481}, {-17485, 27713},
{-17122, 27940}, {-16755, 28162},
{-16385, 28378}, {-16012, 28590},
{-15636, 28797}, {-15258, 28999},
{-14878, 29197}, {-14494, 29389},
{-14108, 29576}, {-13720, 29757},
{-13329, 29934}, {-12937, 30107},
{-12540, 30274}, {-12142, 30435},
{-11744, 30592}, {-11342, 30743},
{-10939, 30889}, {-10534, 31030},
{-10127, 31164}, {-9718, 31294},
{-9307, 31418}, {-8895, 31537},
{-8482, 31652}, {-8067, 31759},
{-7650, 31862}, {-7233, 31960},
{-6815, 32051}, {-6393, 32138},
{-5973, 32219}, {-5549, 32294},
{-5127, 32364}, {-4703, 32429},
{-4278, 32487}, {-3852, 32541},
{-3426, 32588}, {-2999, 32630},
{-2572, 32667}, {-2144, 32698},
{-1716, 32724}, {-1287, 32742},
{-860, 32757}, {-430, 32766},
{0, 32767}, {429, 32766},
{858, 32757}, {1287, 32743},
{1715, 32724}, {2143, 32698},
{2570, 32667}, {2998, 32631},
{3425, 32588}, {3851, 32541},
{4277, 32488}, {4701, 32429},
{5125, 32364}, {5548, 32295},
{5971, 32219}, {6393, 32138},
{6813, 32051}, {7231, 31960},
{7650, 31863}, {8067, 31760},
{8481, 31652}, {8895, 31539},
{9306, 31419}, {9716, 31294},
{10126, 31165}, {10532, 31030},
{10937, 30889}, {11340, 30743},
{11741, 30592}, {12141, 30436},
{12540, 30274}, {12935, 30107},
{13328, 29936}, {13718, 29758},
{14107, 29577}, {14493, 29390},
{14875, 29197}, {15257, 29000},
{15635, 28797}, {16010, 28590},
{16384, 28379}, {16753, 28162},
{17119, 27940}, {17484, 27714},
{17845, 27482}, {18205, 27246},
{18560, 27006}, {18911, 26760},
{19260, 26510}, {19606, 26257},
{19947, 25997}, {20286, 25734},
{20621, 25466}, {20952, 25194},
{21281, 24918}, {21605, 24637},
{21926, 24353}, {22242, 24063},
{22555, 23770}, {22865, 23473},
{23171, 23171}, {23472, 22866},
{23769, 22557}, {24063, 22244},
{24352, 21927}, {24636, 21606},
{24917, 21282}, {25194, 20954},
{25465, 20622}, {25733, 20288},
{25997, 19949}, {26255, 19607},
{26509, 19261}, {26760, 18914},
{27004, 18561}, {27246, 18205},
{27481, 17846}, {27713, 17485},
{27940, 17122}, {28162, 16755},
{28378, 16385}, {28590, 16012},
{28797, 15636}, {28999, 15258},
{29197, 14878}, {29389, 14494},
{29576, 14108}, {29757, 13720},
{29934, 13329}, {30107, 12937},
{30274, 12540}, {30435, 12142},
{30592, 11744}, {30743, 11342},
{30889, 10939}, {31030, 10534},
{31164, 10127}, {31294, 9718},
{31418, 9307}, {31537, 8895},
{31652, 8482}, {31759, 8067},
{31862, 7650}, {31960, 7233},
{32051, 6815}, {32138, 6393},
{32219, 5973}, {32294, 5549},
{32364, 5127}, {32429, 4703},
{32487, 4278}, {32541, 3852},
{32588, 3426}, {32630, 2999},
{32667, 2572}, {32698, 2144},
{32724, 1716}, {32742, 1287},
{32757, 860}, {32766, 430},
};
#ifndef FFT_BITREV480
#define FFT_BITREV480
static const opus_int16 fft_bitrev480[480] = {
0, 120, 240, 360, 30, 150, 270, 390, 60, 180, 300, 420, 90, 210, 330,
450, 15, 135, 255, 375, 45, 165, 285, 405, 75, 195, 315, 435, 105, 225,
345, 465, 5, 125, 245, 365, 35, 155, 275, 395, 65, 185, 305, 425, 95,
215, 335, 455, 20, 140, 260, 380, 50, 170, 290, 410, 80, 200, 320, 440,
110, 230, 350, 470, 10, 130, 250, 370, 40, 160, 280, 400, 70, 190, 310,
430, 100, 220, 340, 460, 25, 145, 265, 385, 55, 175, 295, 415, 85, 205,
325, 445, 115, 235, 355, 475, 1, 121, 241, 361, 31, 151, 271, 391, 61,
181, 301, 421, 91, 211, 331, 451, 16, 136, 256, 376, 46, 166, 286, 406,
76, 196, 316, 436, 106, 226, 346, 466, 6, 126, 246, 366, 36, 156, 276,
396, 66, 186, 306, 426, 96, 216, 336, 456, 21, 141, 261, 381, 51, 171,
291, 411, 81, 201, 321, 441, 111, 231, 351, 471, 11, 131, 251, 371, 41,
161, 281, 401, 71, 191, 311, 431, 101, 221, 341, 461, 26, 146, 266, 386,
56, 176, 296, 416, 86, 206, 326, 446, 116, 236, 356, 476, 2, 122, 242,
362, 32, 152, 272, 392, 62, 182, 302, 422, 92, 212, 332, 452, 17, 137,
257, 377, 47, 167, 287, 407, 77, 197, 317, 437, 107, 227, 347, 467, 7,
127, 247, 367, 37, 157, 277, 397, 67, 187, 307, 427, 97, 217, 337, 457,
22, 142, 262, 382, 52, 172, 292, 412, 82, 202, 322, 442, 112, 232, 352,
472, 12, 132, 252, 372, 42, 162, 282, 402, 72, 192, 312, 432, 102, 222,
342, 462, 27, 147, 267, 387, 57, 177, 297, 417, 87, 207, 327, 447, 117,
237, 357, 477, 3, 123, 243, 363, 33, 153, 273, 393, 63, 183, 303, 423,
93, 213, 333, 453, 18, 138, 258, 378, 48, 168, 288, 408, 78, 198, 318,
438, 108, 228, 348, 468, 8, 128, 248, 368, 38, 158, 278, 398, 68, 188,
308, 428, 98, 218, 338, 458, 23, 143, 263, 383, 53, 173, 293, 413, 83,
203, 323, 443, 113, 233, 353, 473, 13, 133, 253, 373, 43, 163, 283, 403,
73, 193, 313, 433, 103, 223, 343, 463, 28, 148, 268, 388, 58, 178, 298,
418, 88, 208, 328, 448, 118, 238, 358, 478, 4, 124, 244, 364, 34, 154,
274, 394, 64, 184, 304, 424, 94, 214, 334, 454, 19, 139, 259, 379, 49,
169, 289, 409, 79, 199, 319, 439, 109, 229, 349, 469, 9, 129, 249, 369,
39, 159, 279, 399, 69, 189, 309, 429, 99, 219, 339, 459, 24, 144, 264,
384, 54, 174, 294, 414, 84, 204, 324, 444, 114, 234, 354, 474, 14, 134,
254, 374, 44, 164, 284, 404, 74, 194, 314, 434, 104, 224, 344, 464, 29,
149, 269, 389, 59, 179, 299, 419, 89, 209, 329, 449, 119, 239, 359, 479,
};
#endif
#ifndef FFT_BITREV240
#define FFT_BITREV240
static const opus_int16 fft_bitrev240[240] = {
0, 60, 120, 180, 15, 75, 135, 195, 30, 90, 150, 210, 45, 105, 165,
225, 5, 65, 125, 185, 20, 80, 140, 200, 35, 95, 155, 215, 50, 110,
170, 230, 10, 70, 130, 190, 25, 85, 145, 205, 40, 100, 160, 220, 55,
115, 175, 235, 1, 61, 121, 181, 16, 76, 136, 196, 31, 91, 151, 211,
46, 106, 166, 226, 6, 66, 126, 186, 21, 81, 141, 201, 36, 96, 156,
216, 51, 111, 171, 231, 11, 71, 131, 191, 26, 86, 146, 206, 41, 101,
161, 221, 56, 116, 176, 236, 2, 62, 122, 182, 17, 77, 137, 197, 32,
92, 152, 212, 47, 107, 167, 227, 7, 67, 127, 187, 22, 82, 142, 202,
37, 97, 157, 217, 52, 112, 172, 232, 12, 72, 132, 192, 27, 87, 147,
207, 42, 102, 162, 222, 57, 117, 177, 237, 3, 63, 123, 183, 18, 78,
138, 198, 33, 93, 153, 213, 48, 108, 168, 228, 8, 68, 128, 188, 23,
83, 143, 203, 38, 98, 158, 218, 53, 113, 173, 233, 13, 73, 133, 193,
28, 88, 148, 208, 43, 103, 163, 223, 58, 118, 178, 238, 4, 64, 124,
184, 19, 79, 139, 199, 34, 94, 154, 214, 49, 109, 169, 229, 9, 69,
129, 189, 24, 84, 144, 204, 39, 99, 159, 219, 54, 114, 174, 234, 14,
74, 134, 194, 29, 89, 149, 209, 44, 104, 164, 224, 59, 119, 179, 239,
};
#endif
#ifndef FFT_BITREV120
#define FFT_BITREV120
static const opus_int16 fft_bitrev120[120] = {
0, 30, 60, 90, 15, 45, 75, 105, 5, 35, 65, 95, 20, 50, 80,
110, 10, 40, 70, 100, 25, 55, 85, 115, 1, 31, 61, 91, 16, 46,
76, 106, 6, 36, 66, 96, 21, 51, 81, 111, 11, 41, 71, 101, 26,
56, 86, 116, 2, 32, 62, 92, 17, 47, 77, 107, 7, 37, 67, 97,
22, 52, 82, 112, 12, 42, 72, 102, 27, 57, 87, 117, 3, 33, 63,
93, 18, 48, 78, 108, 8, 38, 68, 98, 23, 53, 83, 113, 13, 43,
73, 103, 28, 58, 88, 118, 4, 34, 64, 94, 19, 49, 79, 109, 9,
39, 69, 99, 24, 54, 84, 114, 14, 44, 74, 104, 29, 59, 89, 119,
};
#endif
#ifndef FFT_BITREV60
#define FFT_BITREV60
static const opus_int16 fft_bitrev60[60] = {
0, 15, 30, 45, 5, 20, 35, 50, 10, 25, 40, 55, 1, 16, 31,
46, 6, 21, 36, 51, 11, 26, 41, 56, 2, 17, 32, 47, 7, 22,
37, 52, 12, 27, 42, 57, 3, 18, 33, 48, 8, 23, 38, 53, 13,
28, 43, 58, 4, 19, 34, 49, 9, 24, 39, 54, 14, 29, 44, 59,
};
#endif
#ifndef FFT_STATE48000_960_0
#define FFT_STATE48000_960_0
static const kiss_fft_state fft_state48000_960_0 = {
480, /* nfft */
-1, /* shift */
{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev480, /* bitrev */
fft_twiddles48000_960, /* bitrev */
};
#endif
#ifndef FFT_STATE48000_960_1
#define FFT_STATE48000_960_1
static const kiss_fft_state fft_state48000_960_1 = {
240, /* nfft */
1, /* shift */
{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev240, /* bitrev */
fft_twiddles48000_960, /* bitrev */
};
#endif
#ifndef FFT_STATE48000_960_2
#define FFT_STATE48000_960_2
static const kiss_fft_state fft_state48000_960_2 = {
120, /* nfft */
2, /* shift */
{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev120, /* bitrev */
fft_twiddles48000_960, /* bitrev */
};
#endif
#ifndef FFT_STATE48000_960_3
#define FFT_STATE48000_960_3
static const kiss_fft_state fft_state48000_960_3 = {
60, /* nfft */
3, /* shift */
{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev60, /* bitrev */
fft_twiddles48000_960, /* bitrev */
};
#endif
#endif
#ifndef MDCT_TWIDDLES960
#define MDCT_TWIDDLES960
static const opus_val16 mdct_twiddles960[481] = {
32767, 32767, 32767, 32767, 32766,
32763, 32762, 32759, 32757, 32753,
32751, 32747, 32743, 32738, 32733,
32729, 32724, 32717, 32711, 32705,
32698, 32690, 32683, 32676, 32667,
32658, 32650, 32640, 32631, 32620,
32610, 32599, 32588, 32577, 32566,
32554, 32541, 32528, 32515, 32502,
32487, 32474, 32459, 32444, 32429,
32413, 32397, 32381, 32364, 32348,
32331, 32313, 32294, 32277, 32257,
32239, 32219, 32200, 32180, 32159,
32138, 32118, 32096, 32074, 32051,
32029, 32006, 31984, 31960, 31936,
31912, 31888, 31863, 31837, 31812,
31786, 31760, 31734, 31707, 31679,
31652, 31624, 31596, 31567, 31539,
31508, 31479, 31450, 31419, 31388,
31357, 31326, 31294, 31262, 31230,
31198, 31164, 31131, 31097, 31063,
31030, 30994, 30959, 30924, 30889,
30853, 30816, 30779, 30743, 30705,
30668, 30629, 30592, 30553, 30515,
30475, 30435, 30396, 30356, 30315,
30274, 30233, 30191, 30149, 30107,
30065, 30022, 29979, 29936, 29891,
29847, 29803, 29758, 29713, 29668,
29622, 29577, 29529, 29483, 29436,
29390, 29341, 29293, 29246, 29197,
29148, 29098, 29050, 29000, 28949,
28899, 28848, 28797, 28746, 28694,
28642, 28590, 28537, 28485, 28432,
28378, 28324, 28271, 28217, 28162,
28106, 28051, 27995, 27940, 27884,
27827, 27770, 27713, 27657, 27598,
27540, 27481, 27423, 27365, 27305,
27246, 27187, 27126, 27066, 27006,
26945, 26883, 26822, 26760, 26698,
26636, 26574, 26510, 26448, 26383,
26320, 26257, 26191, 26127, 26062,
25997, 25931, 25866, 25800, 25734,
25667, 25601, 25533, 25466, 25398,
25330, 25262, 25194, 25125, 25056,
24987, 24917, 24848, 24778, 24707,
24636, 24566, 24495, 24424, 24352,
24280, 24208, 24135, 24063, 23990,
23917, 23842, 23769, 23695, 23622,
23546, 23472, 23398, 23322, 23246,
23171, 23095, 23018, 22942, 22866,
22788, 22711, 22634, 22557, 22478,
22400, 22322, 22244, 22165, 22085,
22006, 21927, 21846, 21766, 21687,
21606, 21524, 21443, 21363, 21282,
21199, 21118, 21035, 20954, 20870,
20788, 20705, 20621, 20538, 20455,
20371, 20286, 20202, 20118, 20034,
19947, 19863, 19777, 19692, 19606,
19520, 19434, 19347, 19260, 19174,
19088, 18999, 18911, 18825, 18737,
18648, 18560, 18472, 18384, 18294,
18205, 18116, 18025, 17936, 17846,
17757, 17666, 17576, 17485, 17395,
17303, 17212, 17122, 17030, 16937,
16846, 16755, 16662, 16569, 16477,
16385, 16291, 16198, 16105, 16012,
15917, 15824, 15730, 15636, 15541,
15447, 15352, 15257, 15162, 15067,
14973, 14875, 14781, 14685, 14589,
14493, 14396, 14300, 14204, 14107,
14010, 13914, 13815, 13718, 13621,
13524, 13425, 13328, 13230, 13133,
13033, 12935, 12836, 12738, 12638,
12540, 12441, 12341, 12241, 12142,
12044, 11943, 11843, 11744, 11643,
11542, 11442, 11342, 11241, 11139,
11039, 10939, 10836, 10736, 10635,
10534, 10431, 10330, 10228, 10127,
10024, 9921, 9820, 9718, 9614,
9512, 9410, 9306, 9204, 9101,
8998, 8895, 8791, 8689, 8585,
8481, 8377, 8274, 8171, 8067,
7962, 7858, 7753, 7650, 7545,
7441, 7336, 7231, 7129, 7023,
6917, 6813, 6709, 6604, 6498,
6393, 6288, 6182, 6077, 5973,
5867, 5760, 5656, 5549, 5445,
5339, 5232, 5127, 5022, 4914,
4809, 4703, 4596, 4490, 4384,
4278, 4171, 4065, 3958, 3852,
3745, 3640, 3532, 3426, 3318,
3212, 3106, 2998, 2891, 2786,
2679, 2570, 2465, 2358, 2251,
2143, 2037, 1929, 1823, 1715,
1609, 1501, 1393, 1287, 1180,
1073, 964, 858, 751, 644,
535, 429, 322, 214, 107,
0, };
#endif
static const CELTMode mode48000_960_120 = {
48000, /* Fs */
120, /* overlap */
21, /* nbEBands */
21, /* effEBands */
{27853, 0, 4096, 8192, }, /* preemph */
eband5ms, /* eBands */
3, /* maxLM */
8, /* nbShortMdcts */
120, /* shortMdctSize */
11, /* nbAllocVectors */
band_allocation, /* allocVectors */
logN400, /* logN */
window120, /* window */
{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */
{392, cache_index50, cache_bits50, cache_caps50}, /* cache */
};
/* List of all the available modes */
#define TOTAL_MODES 1
static const CELTMode * const static_mode_list[TOTAL_MODES] = {
&mode48000_960_120,
};

View File

@ -0,0 +1,599 @@
/* The contents of this file was automatically generated by dump_modes.c
with arguments: 48000 960
It contains static definitions for some pre-defined modes. */
#include "modes.h"
#include "rate.h"
#ifndef DEF_WINDOW120
#define DEF_WINDOW120
static const opus_val16 window120[120] = {
6.7286966e-05f, 0.00060551348f, 0.0016815970f, 0.0032947962f, 0.0054439943f,
0.0081276923f, 0.011344001f, 0.015090633f, 0.019364886f, 0.024163635f,
0.029483315f, 0.035319905f, 0.041668911f, 0.048525347f, 0.055883718f,
0.063737999f, 0.072081616f, 0.080907428f, 0.090207705f, 0.099974111f,
0.11019769f, 0.12086883f, 0.13197729f, 0.14351214f, 0.15546177f,
0.16781389f, 0.18055550f, 0.19367290f, 0.20715171f, 0.22097682f,
0.23513243f, 0.24960208f, 0.26436860f, 0.27941419f, 0.29472040f,
0.31026818f, 0.32603788f, 0.34200931f, 0.35816177f, 0.37447407f,
0.39092462f, 0.40749142f, 0.42415215f, 0.44088423f, 0.45766484f,
0.47447104f, 0.49127978f, 0.50806798f, 0.52481261f, 0.54149077f,
0.55807973f, 0.57455701f, 0.59090049f, 0.60708841f, 0.62309951f,
0.63891306f, 0.65450896f, 0.66986776f, 0.68497077f, 0.69980010f,
0.71433873f, 0.72857055f, 0.74248043f, 0.75605424f, 0.76927895f,
0.78214257f, 0.79463430f, 0.80674445f, 0.81846456f, 0.82978733f,
0.84070669f, 0.85121779f, 0.86131698f, 0.87100183f, 0.88027111f,
0.88912479f, 0.89756398f, 0.90559094f, 0.91320904f, 0.92042270f,
0.92723738f, 0.93365955f, 0.93969656f, 0.94535671f, 0.95064907f,
0.95558353f, 0.96017067f, 0.96442171f, 0.96834849f, 0.97196334f,
0.97527906f, 0.97830883f, 0.98106616f, 0.98356480f, 0.98581869f,
0.98784191f, 0.98964856f, 0.99125274f, 0.99266849f, 0.99390969f,
0.99499004f, 0.99592297f, 0.99672162f, 0.99739874f, 0.99796667f,
0.99843728f, 0.99882195f, 0.99913147f, 0.99937606f, 0.99956527f,
0.99970802f, 0.99981248f, 0.99988613f, 0.99993565f, 0.99996697f,
0.99998518f, 0.99999457f, 0.99999859f, 0.99999982f, 1.0000000f,
};
#endif
#ifndef DEF_LOGN400
#define DEF_LOGN400
static const opus_int16 logN400[21] = {
0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, };
#endif
#ifndef DEF_PULSE_CACHE50
#define DEF_PULSE_CACHE50
static const opus_int16 cache_index50[105] = {
-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41,
82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41,
41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41,
41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305,
318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240,
305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240,
240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387,
};
static const unsigned char cache_bits50[392] = {
40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28,
31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50,
51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65,
66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61,
64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92,
94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123,
124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94,
97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139,
142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35,
28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149,
153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225,
229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157,
166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63,
86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250,
25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180,
185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89,
110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41,
74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138,
163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214,
228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49,
90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47,
87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57,
106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187,
224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127,
182, 234, };
static const unsigned char cache_caps50[168] = {
224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185,
178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240,
240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160,
160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172,
138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207,
204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185,
185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39,
207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201,
188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193,
193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204,
204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175,
140, 66, 40, };
#endif
#ifndef FFT_TWIDDLES48000_960
#define FFT_TWIDDLES48000_960
static const kiss_twiddle_cpx fft_twiddles48000_960[480] = {
{1.0000000f, -0.0000000f}, {0.99991433f, -0.013089596f},
{0.99965732f, -0.026176948f}, {0.99922904f, -0.039259816f},
{0.99862953f, -0.052335956f}, {0.99785892f, -0.065403129f},
{0.99691733f, -0.078459096f}, {0.99580493f, -0.091501619f},
{0.99452190f, -0.10452846f}, {0.99306846f, -0.11753740f},
{0.99144486f, -0.13052619f}, {0.98965139f, -0.14349262f},
{0.98768834f, -0.15643447f}, {0.98555606f, -0.16934950f},
{0.98325491f, -0.18223553f}, {0.98078528f, -0.19509032f},
{0.97814760f, -0.20791169f}, {0.97534232f, -0.22069744f},
{0.97236992f, -0.23344536f}, {0.96923091f, -0.24615329f},
{0.96592583f, -0.25881905f}, {0.96245524f, -0.27144045f},
{0.95881973f, -0.28401534f}, {0.95501994f, -0.29654157f},
{0.95105652f, -0.30901699f}, {0.94693013f, -0.32143947f},
{0.94264149f, -0.33380686f}, {0.93819134f, -0.34611706f},
{0.93358043f, -0.35836795f}, {0.92880955f, -0.37055744f},
{0.92387953f, -0.38268343f}, {0.91879121f, -0.39474386f},
{0.91354546f, -0.40673664f}, {0.90814317f, -0.41865974f},
{0.90258528f, -0.43051110f}, {0.89687274f, -0.44228869f},
{0.89100652f, -0.45399050f}, {0.88498764f, -0.46561452f},
{0.87881711f, -0.47715876f}, {0.87249601f, -0.48862124f},
{0.86602540f, -0.50000000f}, {0.85940641f, -0.51129309f},
{0.85264016f, -0.52249856f}, {0.84572782f, -0.53361452f},
{0.83867057f, -0.54463904f}, {0.83146961f, -0.55557023f},
{0.82412619f, -0.56640624f}, {0.81664156f, -0.57714519f},
{0.80901699f, -0.58778525f}, {0.80125381f, -0.59832460f},
{0.79335334f, -0.60876143f}, {0.78531693f, -0.61909395f},
{0.77714596f, -0.62932039f}, {0.76884183f, -0.63943900f},
{0.76040597f, -0.64944805f}, {0.75183981f, -0.65934582f},
{0.74314483f, -0.66913061f}, {0.73432251f, -0.67880075f},
{0.72537437f, -0.68835458f}, {0.71630194f, -0.69779046f},
{0.70710678f, -0.70710678f}, {0.69779046f, -0.71630194f},
{0.68835458f, -0.72537437f}, {0.67880075f, -0.73432251f},
{0.66913061f, -0.74314483f}, {0.65934582f, -0.75183981f},
{0.64944805f, -0.76040597f}, {0.63943900f, -0.76884183f},
{0.62932039f, -0.77714596f}, {0.61909395f, -0.78531693f},
{0.60876143f, -0.79335334f}, {0.59832460f, -0.80125381f},
{0.58778525f, -0.80901699f}, {0.57714519f, -0.81664156f},
{0.56640624f, -0.82412619f}, {0.55557023f, -0.83146961f},
{0.54463904f, -0.83867057f}, {0.53361452f, -0.84572782f},
{0.52249856f, -0.85264016f}, {0.51129309f, -0.85940641f},
{0.50000000f, -0.86602540f}, {0.48862124f, -0.87249601f},
{0.47715876f, -0.87881711f}, {0.46561452f, -0.88498764f},
{0.45399050f, -0.89100652f}, {0.44228869f, -0.89687274f},
{0.43051110f, -0.90258528f}, {0.41865974f, -0.90814317f},
{0.40673664f, -0.91354546f}, {0.39474386f, -0.91879121f},
{0.38268343f, -0.92387953f}, {0.37055744f, -0.92880955f},
{0.35836795f, -0.93358043f}, {0.34611706f, -0.93819134f},
{0.33380686f, -0.94264149f}, {0.32143947f, -0.94693013f},
{0.30901699f, -0.95105652f}, {0.29654157f, -0.95501994f},
{0.28401534f, -0.95881973f}, {0.27144045f, -0.96245524f},
{0.25881905f, -0.96592583f}, {0.24615329f, -0.96923091f},
{0.23344536f, -0.97236992f}, {0.22069744f, -0.97534232f},
{0.20791169f, -0.97814760f}, {0.19509032f, -0.98078528f},
{0.18223553f, -0.98325491f}, {0.16934950f, -0.98555606f},
{0.15643447f, -0.98768834f}, {0.14349262f, -0.98965139f},
{0.13052619f, -0.99144486f}, {0.11753740f, -0.99306846f},
{0.10452846f, -0.99452190f}, {0.091501619f, -0.99580493f},
{0.078459096f, -0.99691733f}, {0.065403129f, -0.99785892f},
{0.052335956f, -0.99862953f}, {0.039259816f, -0.99922904f},
{0.026176948f, -0.99965732f}, {0.013089596f, -0.99991433f},
{6.1230318e-17f, -1.0000000f}, {-0.013089596f, -0.99991433f},
{-0.026176948f, -0.99965732f}, {-0.039259816f, -0.99922904f},
{-0.052335956f, -0.99862953f}, {-0.065403129f, -0.99785892f},
{-0.078459096f, -0.99691733f}, {-0.091501619f, -0.99580493f},
{-0.10452846f, -0.99452190f}, {-0.11753740f, -0.99306846f},
{-0.13052619f, -0.99144486f}, {-0.14349262f, -0.98965139f},
{-0.15643447f, -0.98768834f}, {-0.16934950f, -0.98555606f},
{-0.18223553f, -0.98325491f}, {-0.19509032f, -0.98078528f},
{-0.20791169f, -0.97814760f}, {-0.22069744f, -0.97534232f},
{-0.23344536f, -0.97236992f}, {-0.24615329f, -0.96923091f},
{-0.25881905f, -0.96592583f}, {-0.27144045f, -0.96245524f},
{-0.28401534f, -0.95881973f}, {-0.29654157f, -0.95501994f},
{-0.30901699f, -0.95105652f}, {-0.32143947f, -0.94693013f},
{-0.33380686f, -0.94264149f}, {-0.34611706f, -0.93819134f},
{-0.35836795f, -0.93358043f}, {-0.37055744f, -0.92880955f},
{-0.38268343f, -0.92387953f}, {-0.39474386f, -0.91879121f},
{-0.40673664f, -0.91354546f}, {-0.41865974f, -0.90814317f},
{-0.43051110f, -0.90258528f}, {-0.44228869f, -0.89687274f},
{-0.45399050f, -0.89100652f}, {-0.46561452f, -0.88498764f},
{-0.47715876f, -0.87881711f}, {-0.48862124f, -0.87249601f},
{-0.50000000f, -0.86602540f}, {-0.51129309f, -0.85940641f},
{-0.52249856f, -0.85264016f}, {-0.53361452f, -0.84572782f},
{-0.54463904f, -0.83867057f}, {-0.55557023f, -0.83146961f},
{-0.56640624f, -0.82412619f}, {-0.57714519f, -0.81664156f},
{-0.58778525f, -0.80901699f}, {-0.59832460f, -0.80125381f},
{-0.60876143f, -0.79335334f}, {-0.61909395f, -0.78531693f},
{-0.62932039f, -0.77714596f}, {-0.63943900f, -0.76884183f},
{-0.64944805f, -0.76040597f}, {-0.65934582f, -0.75183981f},
{-0.66913061f, -0.74314483f}, {-0.67880075f, -0.73432251f},
{-0.68835458f, -0.72537437f}, {-0.69779046f, -0.71630194f},
{-0.70710678f, -0.70710678f}, {-0.71630194f, -0.69779046f},
{-0.72537437f, -0.68835458f}, {-0.73432251f, -0.67880075f},
{-0.74314483f, -0.66913061f}, {-0.75183981f, -0.65934582f},
{-0.76040597f, -0.64944805f}, {-0.76884183f, -0.63943900f},
{-0.77714596f, -0.62932039f}, {-0.78531693f, -0.61909395f},
{-0.79335334f, -0.60876143f}, {-0.80125381f, -0.59832460f},
{-0.80901699f, -0.58778525f}, {-0.81664156f, -0.57714519f},
{-0.82412619f, -0.56640624f}, {-0.83146961f, -0.55557023f},
{-0.83867057f, -0.54463904f}, {-0.84572782f, -0.53361452f},
{-0.85264016f, -0.52249856f}, {-0.85940641f, -0.51129309f},
{-0.86602540f, -0.50000000f}, {-0.87249601f, -0.48862124f},
{-0.87881711f, -0.47715876f}, {-0.88498764f, -0.46561452f},
{-0.89100652f, -0.45399050f}, {-0.89687274f, -0.44228869f},
{-0.90258528f, -0.43051110f}, {-0.90814317f, -0.41865974f},
{-0.91354546f, -0.40673664f}, {-0.91879121f, -0.39474386f},
{-0.92387953f, -0.38268343f}, {-0.92880955f, -0.37055744f},
{-0.93358043f, -0.35836795f}, {-0.93819134f, -0.34611706f},
{-0.94264149f, -0.33380686f}, {-0.94693013f, -0.32143947f},
{-0.95105652f, -0.30901699f}, {-0.95501994f, -0.29654157f},
{-0.95881973f, -0.28401534f}, {-0.96245524f, -0.27144045f},
{-0.96592583f, -0.25881905f}, {-0.96923091f, -0.24615329f},
{-0.97236992f, -0.23344536f}, {-0.97534232f, -0.22069744f},
{-0.97814760f, -0.20791169f}, {-0.98078528f, -0.19509032f},
{-0.98325491f, -0.18223553f}, {-0.98555606f, -0.16934950f},
{-0.98768834f, -0.15643447f}, {-0.98965139f, -0.14349262f},
{-0.99144486f, -0.13052619f}, {-0.99306846f, -0.11753740f},
{-0.99452190f, -0.10452846f}, {-0.99580493f, -0.091501619f},
{-0.99691733f, -0.078459096f}, {-0.99785892f, -0.065403129f},
{-0.99862953f, -0.052335956f}, {-0.99922904f, -0.039259816f},
{-0.99965732f, -0.026176948f}, {-0.99991433f, -0.013089596f},
{-1.0000000f, -1.2246064e-16f}, {-0.99991433f, 0.013089596f},
{-0.99965732f, 0.026176948f}, {-0.99922904f, 0.039259816f},
{-0.99862953f, 0.052335956f}, {-0.99785892f, 0.065403129f},
{-0.99691733f, 0.078459096f}, {-0.99580493f, 0.091501619f},
{-0.99452190f, 0.10452846f}, {-0.99306846f, 0.11753740f},
{-0.99144486f, 0.13052619f}, {-0.98965139f, 0.14349262f},
{-0.98768834f, 0.15643447f}, {-0.98555606f, 0.16934950f},
{-0.98325491f, 0.18223553f}, {-0.98078528f, 0.19509032f},
{-0.97814760f, 0.20791169f}, {-0.97534232f, 0.22069744f},
{-0.97236992f, 0.23344536f}, {-0.96923091f, 0.24615329f},
{-0.96592583f, 0.25881905f}, {-0.96245524f, 0.27144045f},
{-0.95881973f, 0.28401534f}, {-0.95501994f, 0.29654157f},
{-0.95105652f, 0.30901699f}, {-0.94693013f, 0.32143947f},
{-0.94264149f, 0.33380686f}, {-0.93819134f, 0.34611706f},
{-0.93358043f, 0.35836795f}, {-0.92880955f, 0.37055744f},
{-0.92387953f, 0.38268343f}, {-0.91879121f, 0.39474386f},
{-0.91354546f, 0.40673664f}, {-0.90814317f, 0.41865974f},
{-0.90258528f, 0.43051110f}, {-0.89687274f, 0.44228869f},
{-0.89100652f, 0.45399050f}, {-0.88498764f, 0.46561452f},
{-0.87881711f, 0.47715876f}, {-0.87249601f, 0.48862124f},
{-0.86602540f, 0.50000000f}, {-0.85940641f, 0.51129309f},
{-0.85264016f, 0.52249856f}, {-0.84572782f, 0.53361452f},
{-0.83867057f, 0.54463904f}, {-0.83146961f, 0.55557023f},
{-0.82412619f, 0.56640624f}, {-0.81664156f, 0.57714519f},
{-0.80901699f, 0.58778525f}, {-0.80125381f, 0.59832460f},
{-0.79335334f, 0.60876143f}, {-0.78531693f, 0.61909395f},
{-0.77714596f, 0.62932039f}, {-0.76884183f, 0.63943900f},
{-0.76040597f, 0.64944805f}, {-0.75183981f, 0.65934582f},
{-0.74314483f, 0.66913061f}, {-0.73432251f, 0.67880075f},
{-0.72537437f, 0.68835458f}, {-0.71630194f, 0.69779046f},
{-0.70710678f, 0.70710678f}, {-0.69779046f, 0.71630194f},
{-0.68835458f, 0.72537437f}, {-0.67880075f, 0.73432251f},
{-0.66913061f, 0.74314483f}, {-0.65934582f, 0.75183981f},
{-0.64944805f, 0.76040597f}, {-0.63943900f, 0.76884183f},
{-0.62932039f, 0.77714596f}, {-0.61909395f, 0.78531693f},
{-0.60876143f, 0.79335334f}, {-0.59832460f, 0.80125381f},
{-0.58778525f, 0.80901699f}, {-0.57714519f, 0.81664156f},
{-0.56640624f, 0.82412619f}, {-0.55557023f, 0.83146961f},
{-0.54463904f, 0.83867057f}, {-0.53361452f, 0.84572782f},
{-0.52249856f, 0.85264016f}, {-0.51129309f, 0.85940641f},
{-0.50000000f, 0.86602540f}, {-0.48862124f, 0.87249601f},
{-0.47715876f, 0.87881711f}, {-0.46561452f, 0.88498764f},
{-0.45399050f, 0.89100652f}, {-0.44228869f, 0.89687274f},
{-0.43051110f, 0.90258528f}, {-0.41865974f, 0.90814317f},
{-0.40673664f, 0.91354546f}, {-0.39474386f, 0.91879121f},
{-0.38268343f, 0.92387953f}, {-0.37055744f, 0.92880955f},
{-0.35836795f, 0.93358043f}, {-0.34611706f, 0.93819134f},
{-0.33380686f, 0.94264149f}, {-0.32143947f, 0.94693013f},
{-0.30901699f, 0.95105652f}, {-0.29654157f, 0.95501994f},
{-0.28401534f, 0.95881973f}, {-0.27144045f, 0.96245524f},
{-0.25881905f, 0.96592583f}, {-0.24615329f, 0.96923091f},
{-0.23344536f, 0.97236992f}, {-0.22069744f, 0.97534232f},
{-0.20791169f, 0.97814760f}, {-0.19509032f, 0.98078528f},
{-0.18223553f, 0.98325491f}, {-0.16934950f, 0.98555606f},
{-0.15643447f, 0.98768834f}, {-0.14349262f, 0.98965139f},
{-0.13052619f, 0.99144486f}, {-0.11753740f, 0.99306846f},
{-0.10452846f, 0.99452190f}, {-0.091501619f, 0.99580493f},
{-0.078459096f, 0.99691733f}, {-0.065403129f, 0.99785892f},
{-0.052335956f, 0.99862953f}, {-0.039259816f, 0.99922904f},
{-0.026176948f, 0.99965732f}, {-0.013089596f, 0.99991433f},
{-1.8369095e-16f, 1.0000000f}, {0.013089596f, 0.99991433f},
{0.026176948f, 0.99965732f}, {0.039259816f, 0.99922904f},
{0.052335956f, 0.99862953f}, {0.065403129f, 0.99785892f},
{0.078459096f, 0.99691733f}, {0.091501619f, 0.99580493f},
{0.10452846f, 0.99452190f}, {0.11753740f, 0.99306846f},
{0.13052619f, 0.99144486f}, {0.14349262f, 0.98965139f},
{0.15643447f, 0.98768834f}, {0.16934950f, 0.98555606f},
{0.18223553f, 0.98325491f}, {0.19509032f, 0.98078528f},
{0.20791169f, 0.97814760f}, {0.22069744f, 0.97534232f},
{0.23344536f, 0.97236992f}, {0.24615329f, 0.96923091f},
{0.25881905f, 0.96592583f}, {0.27144045f, 0.96245524f},
{0.28401534f, 0.95881973f}, {0.29654157f, 0.95501994f},
{0.30901699f, 0.95105652f}, {0.32143947f, 0.94693013f},
{0.33380686f, 0.94264149f}, {0.34611706f, 0.93819134f},
{0.35836795f, 0.93358043f}, {0.37055744f, 0.92880955f},
{0.38268343f, 0.92387953f}, {0.39474386f, 0.91879121f},
{0.40673664f, 0.91354546f}, {0.41865974f, 0.90814317f},
{0.43051110f, 0.90258528f}, {0.44228869f, 0.89687274f},
{0.45399050f, 0.89100652f}, {0.46561452f, 0.88498764f},
{0.47715876f, 0.87881711f}, {0.48862124f, 0.87249601f},
{0.50000000f, 0.86602540f}, {0.51129309f, 0.85940641f},
{0.52249856f, 0.85264016f}, {0.53361452f, 0.84572782f},
{0.54463904f, 0.83867057f}, {0.55557023f, 0.83146961f},
{0.56640624f, 0.82412619f}, {0.57714519f, 0.81664156f},
{0.58778525f, 0.80901699f}, {0.59832460f, 0.80125381f},
{0.60876143f, 0.79335334f}, {0.61909395f, 0.78531693f},
{0.62932039f, 0.77714596f}, {0.63943900f, 0.76884183f},
{0.64944805f, 0.76040597f}, {0.65934582f, 0.75183981f},
{0.66913061f, 0.74314483f}, {0.67880075f, 0.73432251f},
{0.68835458f, 0.72537437f}, {0.69779046f, 0.71630194f},
{0.70710678f, 0.70710678f}, {0.71630194f, 0.69779046f},
{0.72537437f, 0.68835458f}, {0.73432251f, 0.67880075f},
{0.74314483f, 0.66913061f}, {0.75183981f, 0.65934582f},
{0.76040597f, 0.64944805f}, {0.76884183f, 0.63943900f},
{0.77714596f, 0.62932039f}, {0.78531693f, 0.61909395f},
{0.79335334f, 0.60876143f}, {0.80125381f, 0.59832460f},
{0.80901699f, 0.58778525f}, {0.81664156f, 0.57714519f},
{0.82412619f, 0.56640624f}, {0.83146961f, 0.55557023f},
{0.83867057f, 0.54463904f}, {0.84572782f, 0.53361452f},
{0.85264016f, 0.52249856f}, {0.85940641f, 0.51129309f},
{0.86602540f, 0.50000000f}, {0.87249601f, 0.48862124f},
{0.87881711f, 0.47715876f}, {0.88498764f, 0.46561452f},
{0.89100652f, 0.45399050f}, {0.89687274f, 0.44228869f},
{0.90258528f, 0.43051110f}, {0.90814317f, 0.41865974f},
{0.91354546f, 0.40673664f}, {0.91879121f, 0.39474386f},
{0.92387953f, 0.38268343f}, {0.92880955f, 0.37055744f},
{0.93358043f, 0.35836795f}, {0.93819134f, 0.34611706f},
{0.94264149f, 0.33380686f}, {0.94693013f, 0.32143947f},
{0.95105652f, 0.30901699f}, {0.95501994f, 0.29654157f},
{0.95881973f, 0.28401534f}, {0.96245524f, 0.27144045f},
{0.96592583f, 0.25881905f}, {0.96923091f, 0.24615329f},
{0.97236992f, 0.23344536f}, {0.97534232f, 0.22069744f},
{0.97814760f, 0.20791169f}, {0.98078528f, 0.19509032f},
{0.98325491f, 0.18223553f}, {0.98555606f, 0.16934950f},
{0.98768834f, 0.15643447f}, {0.98965139f, 0.14349262f},
{0.99144486f, 0.13052619f}, {0.99306846f, 0.11753740f},
{0.99452190f, 0.10452846f}, {0.99580493f, 0.091501619f},
{0.99691733f, 0.078459096f}, {0.99785892f, 0.065403129f},
{0.99862953f, 0.052335956f}, {0.99922904f, 0.039259816f},
{0.99965732f, 0.026176948f}, {0.99991433f, 0.013089596f},
};
#ifndef FFT_BITREV480
#define FFT_BITREV480
static const opus_int16 fft_bitrev480[480] = {
0, 120, 240, 360, 30, 150, 270, 390, 60, 180, 300, 420, 90, 210, 330,
450, 15, 135, 255, 375, 45, 165, 285, 405, 75, 195, 315, 435, 105, 225,
345, 465, 5, 125, 245, 365, 35, 155, 275, 395, 65, 185, 305, 425, 95,
215, 335, 455, 20, 140, 260, 380, 50, 170, 290, 410, 80, 200, 320, 440,
110, 230, 350, 470, 10, 130, 250, 370, 40, 160, 280, 400, 70, 190, 310,
430, 100, 220, 340, 460, 25, 145, 265, 385, 55, 175, 295, 415, 85, 205,
325, 445, 115, 235, 355, 475, 1, 121, 241, 361, 31, 151, 271, 391, 61,
181, 301, 421, 91, 211, 331, 451, 16, 136, 256, 376, 46, 166, 286, 406,
76, 196, 316, 436, 106, 226, 346, 466, 6, 126, 246, 366, 36, 156, 276,
396, 66, 186, 306, 426, 96, 216, 336, 456, 21, 141, 261, 381, 51, 171,
291, 411, 81, 201, 321, 441, 111, 231, 351, 471, 11, 131, 251, 371, 41,
161, 281, 401, 71, 191, 311, 431, 101, 221, 341, 461, 26, 146, 266, 386,
56, 176, 296, 416, 86, 206, 326, 446, 116, 236, 356, 476, 2, 122, 242,
362, 32, 152, 272, 392, 62, 182, 302, 422, 92, 212, 332, 452, 17, 137,
257, 377, 47, 167, 287, 407, 77, 197, 317, 437, 107, 227, 347, 467, 7,
127, 247, 367, 37, 157, 277, 397, 67, 187, 307, 427, 97, 217, 337, 457,
22, 142, 262, 382, 52, 172, 292, 412, 82, 202, 322, 442, 112, 232, 352,
472, 12, 132, 252, 372, 42, 162, 282, 402, 72, 192, 312, 432, 102, 222,
342, 462, 27, 147, 267, 387, 57, 177, 297, 417, 87, 207, 327, 447, 117,
237, 357, 477, 3, 123, 243, 363, 33, 153, 273, 393, 63, 183, 303, 423,
93, 213, 333, 453, 18, 138, 258, 378, 48, 168, 288, 408, 78, 198, 318,
438, 108, 228, 348, 468, 8, 128, 248, 368, 38, 158, 278, 398, 68, 188,
308, 428, 98, 218, 338, 458, 23, 143, 263, 383, 53, 173, 293, 413, 83,
203, 323, 443, 113, 233, 353, 473, 13, 133, 253, 373, 43, 163, 283, 403,
73, 193, 313, 433, 103, 223, 343, 463, 28, 148, 268, 388, 58, 178, 298,
418, 88, 208, 328, 448, 118, 238, 358, 478, 4, 124, 244, 364, 34, 154,
274, 394, 64, 184, 304, 424, 94, 214, 334, 454, 19, 139, 259, 379, 49,
169, 289, 409, 79, 199, 319, 439, 109, 229, 349, 469, 9, 129, 249, 369,
39, 159, 279, 399, 69, 189, 309, 429, 99, 219, 339, 459, 24, 144, 264,
384, 54, 174, 294, 414, 84, 204, 324, 444, 114, 234, 354, 474, 14, 134,
254, 374, 44, 164, 284, 404, 74, 194, 314, 434, 104, 224, 344, 464, 29,
149, 269, 389, 59, 179, 299, 419, 89, 209, 329, 449, 119, 239, 359, 479,
};
#endif
#ifndef FFT_BITREV240
#define FFT_BITREV240
static const opus_int16 fft_bitrev240[240] = {
0, 60, 120, 180, 15, 75, 135, 195, 30, 90, 150, 210, 45, 105, 165,
225, 5, 65, 125, 185, 20, 80, 140, 200, 35, 95, 155, 215, 50, 110,
170, 230, 10, 70, 130, 190, 25, 85, 145, 205, 40, 100, 160, 220, 55,
115, 175, 235, 1, 61, 121, 181, 16, 76, 136, 196, 31, 91, 151, 211,
46, 106, 166, 226, 6, 66, 126, 186, 21, 81, 141, 201, 36, 96, 156,
216, 51, 111, 171, 231, 11, 71, 131, 191, 26, 86, 146, 206, 41, 101,
161, 221, 56, 116, 176, 236, 2, 62, 122, 182, 17, 77, 137, 197, 32,
92, 152, 212, 47, 107, 167, 227, 7, 67, 127, 187, 22, 82, 142, 202,
37, 97, 157, 217, 52, 112, 172, 232, 12, 72, 132, 192, 27, 87, 147,
207, 42, 102, 162, 222, 57, 117, 177, 237, 3, 63, 123, 183, 18, 78,
138, 198, 33, 93, 153, 213, 48, 108, 168, 228, 8, 68, 128, 188, 23,
83, 143, 203, 38, 98, 158, 218, 53, 113, 173, 233, 13, 73, 133, 193,
28, 88, 148, 208, 43, 103, 163, 223, 58, 118, 178, 238, 4, 64, 124,
184, 19, 79, 139, 199, 34, 94, 154, 214, 49, 109, 169, 229, 9, 69,
129, 189, 24, 84, 144, 204, 39, 99, 159, 219, 54, 114, 174, 234, 14,
74, 134, 194, 29, 89, 149, 209, 44, 104, 164, 224, 59, 119, 179, 239,
};
#endif
#ifndef FFT_BITREV120
#define FFT_BITREV120
static const opus_int16 fft_bitrev120[120] = {
0, 30, 60, 90, 15, 45, 75, 105, 5, 35, 65, 95, 20, 50, 80,
110, 10, 40, 70, 100, 25, 55, 85, 115, 1, 31, 61, 91, 16, 46,
76, 106, 6, 36, 66, 96, 21, 51, 81, 111, 11, 41, 71, 101, 26,
56, 86, 116, 2, 32, 62, 92, 17, 47, 77, 107, 7, 37, 67, 97,
22, 52, 82, 112, 12, 42, 72, 102, 27, 57, 87, 117, 3, 33, 63,
93, 18, 48, 78, 108, 8, 38, 68, 98, 23, 53, 83, 113, 13, 43,
73, 103, 28, 58, 88, 118, 4, 34, 64, 94, 19, 49, 79, 109, 9,
39, 69, 99, 24, 54, 84, 114, 14, 44, 74, 104, 29, 59, 89, 119,
};
#endif
#ifndef FFT_BITREV60
#define FFT_BITREV60
static const opus_int16 fft_bitrev60[60] = {
0, 15, 30, 45, 5, 20, 35, 50, 10, 25, 40, 55, 1, 16, 31,
46, 6, 21, 36, 51, 11, 26, 41, 56, 2, 17, 32, 47, 7, 22,
37, 52, 12, 27, 42, 57, 3, 18, 33, 48, 8, 23, 38, 53, 13,
28, 43, 58, 4, 19, 34, 49, 9, 24, 39, 54, 14, 29, 44, 59,
};
#endif
#ifndef FFT_STATE48000_960_0
#define FFT_STATE48000_960_0
static const kiss_fft_state fft_state48000_960_0 = {
480, /* nfft */
0.002083333f, /* scale */
-1, /* shift */
{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev480, /* bitrev */
fft_twiddles48000_960, /* bitrev */
};
#endif
#ifndef FFT_STATE48000_960_1
#define FFT_STATE48000_960_1
static const kiss_fft_state fft_state48000_960_1 = {
240, /* nfft */
0.004166667f, /* scale */
1, /* shift */
{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev240, /* bitrev */
fft_twiddles48000_960, /* bitrev */
};
#endif
#ifndef FFT_STATE48000_960_2
#define FFT_STATE48000_960_2
static const kiss_fft_state fft_state48000_960_2 = {
120, /* nfft */
0.008333333f, /* scale */
2, /* shift */
{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev120, /* bitrev */
fft_twiddles48000_960, /* bitrev */
};
#endif
#ifndef FFT_STATE48000_960_3
#define FFT_STATE48000_960_3
static const kiss_fft_state fft_state48000_960_3 = {
60, /* nfft */
0.016666667f, /* scale */
3, /* shift */
{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev60, /* bitrev */
fft_twiddles48000_960, /* bitrev */
};
#endif
#endif
#ifndef MDCT_TWIDDLES960
#define MDCT_TWIDDLES960
static const opus_val16 mdct_twiddles960[481] = {
1.0000000f, 0.99999465f, 0.99997858f, 0.99995181f, 0.99991433f,
0.99986614f, 0.99980724f, 0.99973764f, 0.99965732f, 0.99956631f,
0.99946459f, 0.99935216f, 0.99922904f, 0.99909521f, 0.99895068f,
0.99879546f, 0.99862953f, 0.99845292f, 0.99826561f, 0.99806761f,
0.99785892f, 0.99763955f, 0.99740949f, 0.99716875f, 0.99691733f,
0.99665524f, 0.99638247f, 0.99609903f, 0.99580493f, 0.99550016f,
0.99518473f, 0.99485864f, 0.99452190f, 0.99417450f, 0.99381646f,
0.99344778f, 0.99306846f, 0.99267850f, 0.99227791f, 0.99186670f,
0.99144486f, 0.99101241f, 0.99056934f, 0.99011566f, 0.98965139f,
0.98917651f, 0.98869104f, 0.98819498f, 0.98768834f, 0.98717112f,
0.98664333f, 0.98610497f, 0.98555606f, 0.98499659f, 0.98442657f,
0.98384600f, 0.98325491f, 0.98265328f, 0.98204113f, 0.98141846f,
0.98078528f, 0.98014159f, 0.97948742f, 0.97882275f, 0.97814760f,
0.97746197f, 0.97676588f, 0.97605933f, 0.97534232f, 0.97461487f,
0.97387698f, 0.97312866f, 0.97236992f, 0.97160077f, 0.97082121f,
0.97003125f, 0.96923091f, 0.96842019f, 0.96759909f, 0.96676764f,
0.96592582f, 0.96507367f, 0.96421118f, 0.96333837f, 0.96245523f,
0.96156180f, 0.96065806f, 0.95974403f, 0.95881973f, 0.95788517f,
0.95694034f, 0.95598526f, 0.95501995f, 0.95404440f, 0.95305864f,
0.95206267f, 0.95105651f, 0.95004016f, 0.94901364f, 0.94797697f,
0.94693013f, 0.94587315f, 0.94480604f, 0.94372882f, 0.94264149f,
0.94154406f, 0.94043656f, 0.93931897f, 0.93819133f, 0.93705365f,
0.93590592f, 0.93474818f, 0.93358042f, 0.93240268f, 0.93121493f,
0.93001722f, 0.92880955f, 0.92759193f, 0.92636438f, 0.92512690f,
0.92387953f, 0.92262225f, 0.92135509f, 0.92007809f, 0.91879121f,
0.91749449f, 0.91618795f, 0.91487161f, 0.91354545f, 0.91220952f,
0.91086382f, 0.90950836f, 0.90814316f, 0.90676824f, 0.90538363f,
0.90398929f, 0.90258528f, 0.90117161f, 0.89974828f, 0.89831532f,
0.89687273f, 0.89542055f, 0.89395877f, 0.89248742f, 0.89100652f,
0.88951606f, 0.88801610f, 0.88650661f, 0.88498764f, 0.88345918f,
0.88192125f, 0.88037390f, 0.87881711f, 0.87725090f, 0.87567531f,
0.87409035f, 0.87249599f, 0.87089232f, 0.86927933f, 0.86765699f,
0.86602540f, 0.86438453f, 0.86273437f, 0.86107503f, 0.85940641f,
0.85772862f, 0.85604161f, 0.85434547f, 0.85264014f, 0.85092572f,
0.84920218f, 0.84746955f, 0.84572781f, 0.84397704f, 0.84221721f,
0.84044838f, 0.83867056f, 0.83688375f, 0.83508799f, 0.83328325f,
0.83146961f, 0.82964704f, 0.82781562f, 0.82597530f, 0.82412620f,
0.82226820f, 0.82040144f, 0.81852589f, 0.81664154f, 0.81474847f,
0.81284665f, 0.81093620f, 0.80901698f, 0.80708914f, 0.80515262f,
0.80320752f, 0.80125378f, 0.79929149f, 0.79732067f, 0.79534125f,
0.79335335f, 0.79135691f, 0.78935204f, 0.78733867f, 0.78531691f,
0.78328674f, 0.78124818f, 0.77920122f, 0.77714595f, 0.77508232f,
0.77301043f, 0.77093026f, 0.76884183f, 0.76674517f, 0.76464026f,
0.76252720f, 0.76040593f, 0.75827656f, 0.75613907f, 0.75399349f,
0.75183978f, 0.74967807f, 0.74750833f, 0.74533054f, 0.74314481f,
0.74095112f, 0.73874950f, 0.73653993f, 0.73432251f, 0.73209718f,
0.72986405f, 0.72762307f, 0.72537438f, 0.72311787f, 0.72085359f,
0.71858162f, 0.71630192f, 0.71401459f, 0.71171956f, 0.70941701f,
0.70710677f, 0.70478900f, 0.70246363f, 0.70013079f, 0.69779041f,
0.69544260f, 0.69308738f, 0.69072466f, 0.68835458f, 0.68597709f,
0.68359229f, 0.68120013f, 0.67880072f, 0.67639404f, 0.67398011f,
0.67155892f, 0.66913059f, 0.66669509f, 0.66425240f, 0.66180265f,
0.65934581f, 0.65688191f, 0.65441092f, 0.65193298f, 0.64944801f,
0.64695613f, 0.64445727f, 0.64195160f, 0.63943902f, 0.63691954f,
0.63439328f, 0.63186019f, 0.62932037f, 0.62677377f, 0.62422055f,
0.62166055f, 0.61909394f, 0.61652065f, 0.61394081f, 0.61135435f,
0.60876139f, 0.60616195f, 0.60355593f, 0.60094349f, 0.59832457f,
0.59569929f, 0.59306758f, 0.59042957f, 0.58778523f, 0.58513460f,
0.58247766f, 0.57981452f, 0.57714518f, 0.57446961f, 0.57178793f,
0.56910013f, 0.56640624f, 0.56370623f, 0.56100023f, 0.55828818f,
0.55557020f, 0.55284627f, 0.55011641f, 0.54738067f, 0.54463901f,
0.54189157f, 0.53913828f, 0.53637921f, 0.53361450f, 0.53084398f,
0.52806787f, 0.52528601f, 0.52249852f, 0.51970543f, 0.51690688f,
0.51410279f, 0.51129310f, 0.50847793f, 0.50565732f, 0.50283139f,
0.49999997f, 0.49716321f, 0.49432122f, 0.49147383f, 0.48862118f,
0.48576340f, 0.48290042f, 0.48003216f, 0.47715876f, 0.47428025f,
0.47139677f, 0.46850813f, 0.46561448f, 0.46271584f, 0.45981235f,
0.45690383f, 0.45399042f, 0.45107214f, 0.44814915f, 0.44522124f,
0.44228868f, 0.43935137f, 0.43640926f, 0.43346247f, 0.43051104f,
0.42755511f, 0.42459449f, 0.42162932f, 0.41865964f, 0.41568558f,
0.41270697f, 0.40972393f, 0.40673661f, 0.40374494f, 0.40074884f,
0.39774844f, 0.39474390f, 0.39173501f, 0.38872193f, 0.38570469f,
0.38268343f, 0.37965796f, 0.37662842f, 0.37359496f, 0.37055739f,
0.36751585f, 0.36447038f, 0.36142122f, 0.35836797f, 0.35531089f,
0.35225000f, 0.34918544f, 0.34611704f, 0.34304493f, 0.33996926f,
0.33688983f, 0.33380680f, 0.33072019f, 0.32763015f, 0.32453650f,
0.32143936f, 0.31833890f, 0.31523503f, 0.31212767f, 0.30901696f,
0.30590306f, 0.30278577f, 0.29966524f, 0.29654150f, 0.29341470f,
0.29028464f, 0.28715147f, 0.28401522f, 0.28087605f, 0.27773376f,
0.27458861f, 0.27144052f, 0.26828940f, 0.26513541f, 0.26197859f,
0.25881907f, 0.25565666f, 0.25249152f, 0.24932367f, 0.24615327f,
0.24298012f, 0.23980436f, 0.23662604f, 0.23344530f, 0.23026206f,
0.22707623f, 0.22388809f, 0.22069744f, 0.21750443f, 0.21430908f,
0.21111156f, 0.20791165f, 0.20470953f, 0.20150520f, 0.19829884f,
0.19509024f, 0.19187955f, 0.18866692f, 0.18545227f, 0.18223552f,
0.17901681f, 0.17579631f, 0.17257380f, 0.16934945f, 0.16612328f,
0.16289546f, 0.15966577f, 0.15643437f, 0.15320141f, 0.14996669f,
0.14673037f, 0.14349260f, 0.14025329f, 0.13701235f, 0.13376995f,
0.13052612f, 0.12728101f, 0.12403442f, 0.12078650f, 0.11753740f,
0.11428693f, 0.11103523f, 0.10778234f, 0.10452842f, 0.10127326f,
0.098017137f, 0.094759842f, 0.091501652f, 0.088242363f, 0.084982129f,
0.081721103f, 0.078459084f, 0.075196224f, 0.071932560f, 0.068668243f,
0.065403073f, 0.062137201f, 0.058870665f, 0.055603617f, 0.052335974f,
0.049067651f, 0.045798921f, 0.042529582f, 0.039259788f, 0.035989573f,
0.032719092f, 0.029448142f, 0.026176876f, 0.022905329f, 0.019633657f,
0.016361655f, 0.013089478f, 0.0098171604f, 0.0065449764f, 0.0032724839f,
-4.3711390e-08f, };
#endif
static const CELTMode mode48000_960_120 = {
48000, /* Fs */
120, /* overlap */
21, /* nbEBands */
21, /* effEBands */
{0.85000610f, 0.0000000f, 1.0000000f, 1.0000000f, }, /* preemph */
eband5ms, /* eBands */
3, /* maxLM */
8, /* nbShortMdcts */
120, /* shortMdctSize */
11, /* nbAllocVectors */
band_allocation, /* allocVectors */
logN400, /* logN */
window120, /* window */
{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */
{392, cache_index50, cache_bits50, cache_caps50}, /* cache */
};
/* List of all the available modes */
#define TOTAL_MODES 1
static const CELTMode * const static_mode_list[TOTAL_MODES] = {
&mode48000_960_120,
};

View File

@ -0,0 +1,223 @@
/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
Gregory Maxwell
Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#ifndef CUSTOM_MODES
#define CUSTOM_MODES
#else
#define TEST_CUSTOM_MODES
#endif
#define CELT_C
#include "stack_alloc.h"
#include "entenc.c"
#include "entdec.c"
#include "entcode.c"
#include "cwrs.c"
#include "mathops.c"
#include "rate.h"
#define NMAX (240)
#define KMAX (128)
#ifdef TEST_CUSTOM_MODES
#define NDIMS (46)
static const int pn[NDIMS]={
2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 18, 20, 22,
24, 26, 28, 30, 32, 36, 40, 44, 48,
52, 56, 60, 64, 72, 80, 88, 96, 104,
112, 120, 128, 144, 160, 176, 192, 208, 224,
240
};
static const int pkmax[NDIMS]={
128, 128, 128, 128, 88, 52, 36, 26, 22,
18, 16, 15, 13, 12, 12, 11, 10, 9,
9, 8, 8, 7, 7, 7, 7, 6, 6,
6, 6, 6, 5, 5, 5, 5, 5, 5,
4, 4, 4, 4, 4, 4, 4, 4, 4,
4
};
#else /* TEST_CUSTOM_MODES */
#define NDIMS (22)
static const int pn[NDIMS]={
2, 3, 4, 6, 8, 9, 11, 12, 16,
18, 22, 24, 32, 36, 44, 48, 64, 72,
88, 96, 144, 176
};
static const int pkmax[NDIMS]={
128, 128, 128, 88, 36, 26, 18, 16, 12,
11, 9, 9, 7, 7, 6, 6, 5, 5,
5, 5, 4, 4
};
#endif
int main(void){
int t;
int n;
ALLOC_STACK;
for(t=0;t<NDIMS;t++){
int pseudo;
n=pn[t];
for(pseudo=1;pseudo<41;pseudo++)
{
int k;
opus_uint32 uu[KMAX+2U];
opus_uint32 inc;
opus_uint32 nc;
opus_uint32 i;
k=get_pulses(pseudo);
if (k>pkmax[t])break;
printf("Testing CWRS with N=%i, K=%i...\n",n,k);
nc=ncwrs_urow(n,k,uu);
inc=nc/20000;
if(inc<1)inc=1;
for(i=0;i<nc;i+=inc){
opus_uint32 u[KMAX+2U];
int y[NMAX];
int sy;
int yy[5];
opus_uint32 v;
opus_uint32 ii;
int kk;
int j;
memcpy(u,uu,(k+2U)*sizeof(*u));
cwrsi(n,k,i,y,u);
sy=0;
for(j=0;j<n;j++)sy+=ABS(y[j]);
if(sy!=k){
fprintf(stderr,"N=%d Pulse count mismatch in cwrsi (%d!=%d).\n",
n,sy,k);
return 99;
}
/*printf("%6u of %u:",i,nc);
for(j=0;j<n;j++)printf(" %+3i",y[j]);
printf(" ->");*/
ii=icwrs(n,k,&v,y,u);
if(ii!=i){
fprintf(stderr,"Combination-index mismatch (%lu!=%lu).\n",
(long)ii,(long)i);
return 1;
}
if(v!=nc){
fprintf(stderr,"Combination count mismatch (%lu!=%lu).\n",
(long)v,(long)nc);
return 2;
}
#ifndef SMALL_FOOTPRINT
if(n==2){
cwrsi2(k,i,yy);
for(j=0;j<2;j++)if(yy[j]!=y[j]){
fprintf(stderr,"N=2 pulse vector mismatch ({%i,%i}!={%i,%i}).\n",
yy[0],yy[1],y[0],y[1]);
return 3;
}
ii=icwrs2(yy,&kk);
if(ii!=i){
fprintf(stderr,"N=2 combination-index mismatch (%lu!=%lu).\n",
(long)ii,(long)i);
return 4;
}
if(kk!=k){
fprintf(stderr,"N=2 pulse count mismatch (%i,%i).\n",kk,k);
return 5;
}
v=ncwrs2(k);
if(v!=nc){
fprintf(stderr,"N=2 combination count mismatch (%lu,%lu).\n",
(long)v,(long)nc);
return 6;
}
}
else if(n==3){
cwrsi3(k,i,yy);
for(j=0;j<3;j++)if(yy[j]!=y[j]){
fprintf(stderr,"N=3 pulse vector mismatch "
"({%i,%i,%i}!={%i,%i,%i}).\n",yy[0],yy[1],yy[2],y[0],y[1],y[2]);
return 7;
}
ii=icwrs3(yy,&kk);
if(ii!=i){
fprintf(stderr,"N=3 combination-index mismatch (%lu!=%lu).\n",
(long)ii,(long)i);
return 8;
}
if(kk!=k){
fprintf(stderr,"N=3 pulse count mismatch (%i!=%i).\n",kk,k);
return 9;
}
v=ncwrs3(k);
if(v!=nc){
fprintf(stderr,"N=3 combination count mismatch (%lu!=%lu).\n",
(long)v,(long)nc);
return 10;
}
}
else if(n==4){
cwrsi4(k,i,yy);
for(j=0;j<4;j++)if(yy[j]!=y[j]){
fprintf(stderr,"N=4 pulse vector mismatch "
"({%i,%i,%i,%i}!={%i,%i,%i,%i}.\n",
yy[0],yy[1],yy[2],yy[3],y[0],y[1],y[2],y[3]);
return 11;
}
ii=icwrs4(yy,&kk);
if(ii!=i){
fprintf(stderr,"N=4 combination-index mismatch (%lu!=%lu).\n",
(long)ii,(long)i);
return 12;
}
if(kk!=k){
fprintf(stderr,"N=4 pulse count mismatch (%i!=%i).\n",kk,k);
return 13;
}
v=ncwrs4(k);
if(v!=nc){
fprintf(stderr,"N=4 combination count mismatch (%lu!=%lu).\n",
(long)v,(long)nc);
return 14;
}
}
#endif /* SMALL_FOOTPRINT */
/*printf(" %6u\n",i);*/
}
/*printf("\n");*/
}
}
return 0;
}

View File

@ -0,0 +1,164 @@
/* Copyright (c) 2008 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define SKIP_CONFIG_H
#ifndef CUSTOM_MODES
#define CUSTOM_MODES
#endif
#include <stdio.h>
#define CELT_C
#include "stack_alloc.h"
#include "kiss_fft.h"
#include "kiss_fft.c"
#include "mathops.c"
#include "entcode.c"
#ifndef M_PI
#define M_PI 3.141592653
#endif
int ret = 0;
void check(kiss_fft_cpx * in,kiss_fft_cpx * out,int nfft,int isinverse)
{
int bin,k;
double errpow=0,sigpow=0, snr;
for (bin=0;bin<nfft;++bin) {
double ansr = 0;
double ansi = 0;
double difr;
double difi;
for (k=0;k<nfft;++k) {
double phase = -2*M_PI*bin*k/nfft;
double re = cos(phase);
double im = sin(phase);
if (isinverse)
im = -im;
if (!isinverse)
{
re /= nfft;
im /= nfft;
}
ansr += in[k].r * re - in[k].i * im;
ansi += in[k].r * im + in[k].i * re;
}
/*printf ("%d %d ", (int)ansr, (int)ansi);*/
difr = ansr - out[bin].r;
difi = ansi - out[bin].i;
errpow += difr*difr + difi*difi;
sigpow += ansr*ansr+ansi*ansi;
}
snr = 10*log10(sigpow/errpow);
printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
if (snr<60) {
printf( "** poor snr: %f ** \n", snr);
ret = 1;
}
}
void test1d(int nfft,int isinverse)
{
size_t buflen = sizeof(kiss_fft_cpx)*nfft;
kiss_fft_cpx * in = (kiss_fft_cpx*)malloc(buflen);
kiss_fft_cpx * out= (kiss_fft_cpx*)malloc(buflen);
kiss_fft_state *cfg = opus_fft_alloc(nfft,0,0);
int k;
for (k=0;k<nfft;++k) {
in[k].r = (rand() % 32767) - 16384;
in[k].i = (rand() % 32767) - 16384;
}
for (k=0;k<nfft;++k) {
in[k].r *= 32768;
in[k].i *= 32768;
}
if (isinverse)
{
for (k=0;k<nfft;++k) {
in[k].r /= nfft;
in[k].i /= nfft;
}
}
/*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
if (isinverse)
opus_ifft(cfg,in,out);
else
opus_fft(cfg,in,out);
/*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
check(in,out,nfft,isinverse);
free(in);
free(out);
free(cfg);
}
int main(int argc,char ** argv)
{
ALLOC_STACK;
if (argc>1) {
int k;
for (k=1;k<argc;++k) {
test1d(atoi(argv[k]),0);
test1d(atoi(argv[k]),1);
}
}else{
test1d(32,0);
test1d(32,1);
test1d(128,0);
test1d(128,1);
test1d(256,0);
test1d(256,1);
#ifndef RADIX_TWO_ONLY
test1d(36,0);
test1d(36,1);
test1d(50,0);
test1d(50,1);
test1d(120,0);
test1d(120,1);
#endif
}
return ret;
}

View File

@ -0,0 +1,382 @@
/* Copyright (c) 2007-2011 Xiph.Org Foundation, Mozilla Corporation,
Gregory Maxwell
Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include "entcode.h"
#include "entenc.h"
#include "entdec.h"
#include <string.h>
#include "entenc.c"
#include "entdec.c"
#include "entcode.c"
#ifndef M_LOG2E
# define M_LOG2E 1.4426950408889634074
#endif
#define DATA_SIZE 10000000
#define DATA_SIZE2 10000
int main(int _argc,char **_argv){
ec_enc enc;
ec_dec dec;
long nbits;
long nbits2;
double entropy;
int ft;
int ftb;
int sz;
int i;
int ret;
unsigned int sym;
unsigned int seed;
unsigned char *ptr;
const char *env_seed;
ret=0;
entropy=0;
if (_argc > 2) {
fprintf(stderr, "Usage: %s [<seed>]\n", _argv[0]);
return 1;
}
env_seed = getenv("SEED");
if (_argc > 1)
seed = atoi(_argv[1]);
else if (env_seed)
seed = atoi(env_seed);
else
seed = time(NULL);
/*Testing encoding of raw bit values.*/
ptr = (unsigned char *)malloc(DATA_SIZE);
ec_enc_init(&enc,ptr, DATA_SIZE);
for(ft=2;ft<1024;ft++){
for(i=0;i<ft;i++){
entropy+=log(ft)*M_LOG2E;
ec_enc_uint(&enc,i,ft);
}
}
/*Testing encoding of raw bit values.*/
for(ftb=1;ftb<16;ftb++){
for(i=0;i<(1<<ftb);i++){
entropy+=ftb;
nbits=ec_tell(&enc);
ec_enc_bits(&enc,i,ftb);
nbits2=ec_tell(&enc);
if(nbits2-nbits!=ftb){
fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
nbits2-nbits,ftb);
ret=-1;
}
}
}
nbits=ec_tell_frac(&enc);
ec_enc_done(&enc);
fprintf(stderr,
"Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
entropy,ldexp(nbits,-3),100*(nbits-ldexp(entropy,3))/nbits);
fprintf(stderr,"Packed to %li bytes.\n",(long)ec_range_bytes(&enc));
ec_dec_init(&dec,ptr,DATA_SIZE);
for(ft=2;ft<1024;ft++){
for(i=0;i<ft;i++){
sym=ec_dec_uint(&dec,ft);
if(sym!=(unsigned)i){
fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
ret=-1;
}
}
}
for(ftb=1;ftb<16;ftb++){
for(i=0;i<(1<<ftb);i++){
sym=ec_dec_bits(&dec,ftb);
if(sym!=(unsigned)i){
fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
ret=-1;
}
}
}
nbits2=ec_tell_frac(&dec);
if(nbits!=nbits2){
fprintf(stderr,
"Reported number of bits used was %0.2lf, should be %0.2lf.\n",
ldexp(nbits2,-3),ldexp(nbits,-3));
ret=-1;
}
/*Testing an encoder bust prefers range coder data over raw bits.
This isn't a general guarantee, will only work for data that is buffered in
the encoder state and not yet stored in the user buffer, and should never
get used in practice.
It's mostly here for code coverage completeness.*/
/*Start with a 16-bit buffer.*/
ec_enc_init(&enc,ptr,2);
/*Write 7 raw bits.*/
ec_enc_bits(&enc,0x55,7);
/*Write 12.3 bits of range coder data.*/
ec_enc_uint(&enc,1,2);
ec_enc_uint(&enc,1,3);
ec_enc_uint(&enc,1,4);
ec_enc_uint(&enc,1,5);
ec_enc_uint(&enc,2,6);
ec_enc_uint(&enc,6,7);
ec_enc_done(&enc);
ec_dec_init(&dec,ptr,2);
if(!enc.error
/*The raw bits should have been overwritten by the range coder data.*/
||ec_dec_bits(&dec,7)!=0x05
/*And all the range coder data should have been encoded correctly.*/
||ec_dec_uint(&dec,2)!=1
||ec_dec_uint(&dec,3)!=1
||ec_dec_uint(&dec,4)!=1
||ec_dec_uint(&dec,5)!=1
||ec_dec_uint(&dec,6)!=2
||ec_dec_uint(&dec,7)!=6){
fprintf(stderr,"Encoder bust overwrote range coder data with raw bits.\n");
ret=-1;
}
srand(seed);
fprintf(stderr,"Testing random streams... Random seed: %u (%.4X)\n", seed, rand() % 65536);
for(i=0;i<409600;i++){
unsigned *data;
unsigned *tell;
unsigned tell_bits;
int j;
int zeros;
ft=rand()/((RAND_MAX>>(rand()%11U))+1U)+10;
sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
data=(unsigned *)malloc(sz*sizeof(*data));
tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
ec_enc_init(&enc,ptr,DATA_SIZE2);
zeros = rand()%13==0;
tell[0]=ec_tell_frac(&enc);
for(j=0;j<sz;j++){
if (zeros)
data[j]=0;
else
data[j]=rand()%ft;
ec_enc_uint(&enc,data[j],ft);
tell[j+1]=ec_tell_frac(&enc);
}
if (rand()%2==0)
while(ec_tell(&enc)%8 != 0)
ec_enc_uint(&enc, rand()%2, 2);
tell_bits = ec_tell(&enc);
ec_enc_done(&enc);
if(tell_bits!=(unsigned)ec_tell(&enc)){
fprintf(stderr,"ec_tell() changed after ec_enc_done(): %i instead of %i (Random seed: %u)\n",
ec_tell(&enc),tell_bits,seed);
ret=-1;
}
if ((tell_bits+7)/8 < ec_range_bytes(&enc))
{
fprintf (stderr, "ec_tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
ec_range_bytes(&enc), (tell_bits+7)/8,seed);
ret=-1;
}
ec_dec_init(&dec,ptr,DATA_SIZE2);
if(ec_tell_frac(&dec)!=tell[0]){
fprintf(stderr,
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
0,ec_tell_frac(&dec),tell[0],seed);
}
for(j=0;j<sz;j++){
sym=ec_dec_uint(&dec,ft);
if(sym!=data[j]){
fprintf(stderr,
"Decoded %i instead of %i with ft of %i at position %i of %i (Random seed: %u).\n",
sym,data[j],ft,j,sz,seed);
ret=-1;
}
if(ec_tell_frac(&dec)!=tell[j+1]){
fprintf(stderr,
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
j+1,ec_tell_frac(&dec),tell[j+1],seed);
}
}
free(tell);
free(data);
}
/*Test compatibility between multiple different encode/decode routines.*/
for(i=0;i<409600;i++){
unsigned *logp1;
unsigned *data;
unsigned *tell;
unsigned *enc_method;
int j;
sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
logp1=(unsigned *)malloc(sz*sizeof(*logp1));
data=(unsigned *)malloc(sz*sizeof(*data));
tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));
ec_enc_init(&enc,ptr,DATA_SIZE2);
tell[0]=ec_tell_frac(&enc);
for(j=0;j<sz;j++){
data[j]=rand()/((RAND_MAX>>1)+1);
logp1[j]=(rand()%15)+1;
enc_method[j]=rand()/((RAND_MAX>>2)+1);
switch(enc_method[j]){
case 0:{
ec_encode(&enc,data[j]?(1<<logp1[j])-1:0,
(1<<logp1[j])-(data[j]?0:1),1<<logp1[j]);
}break;
case 1:{
ec_encode_bin(&enc,data[j]?(1<<logp1[j])-1:0,
(1<<logp1[j])-(data[j]?0:1),logp1[j]);
}break;
case 2:{
ec_enc_bit_logp(&enc,data[j],logp1[j]);
}break;
case 3:{
unsigned char icdf[2];
icdf[0]=1;
icdf[1]=0;
ec_enc_icdf(&enc,data[j],icdf,logp1[j]);
}break;
}
tell[j+1]=ec_tell_frac(&enc);
}
ec_enc_done(&enc);
if((ec_tell(&enc)+7U)/8U<ec_range_bytes(&enc)){
fprintf(stderr,"tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
ec_range_bytes(&enc),(ec_tell(&enc)+7)/8,seed);
ret=-1;
}
ec_dec_init(&dec,ptr,DATA_SIZE2);
if(ec_tell_frac(&dec)!=tell[0]){
fprintf(stderr,
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
0,ec_tell_frac(&dec),tell[0],seed);
}
for(j=0;j<sz;j++){
int fs;
int dec_method;
dec_method=rand()/((RAND_MAX>>2)+1);
switch(dec_method){
case 0:{
fs=ec_decode(&dec,1<<logp1[j]);
sym=fs>=(1<<logp1[j])-1;
ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
(1<<logp1[j])-(sym?0:1),1<<logp1[j]);
}break;
case 1:{
fs=ec_decode_bin(&dec,logp1[j]);
sym=fs>=(1<<logp1[j])-1;
ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
(1<<logp1[j])-(sym?0:1),1<<logp1[j]);
}break;
case 2:{
sym=ec_dec_bit_logp(&dec,logp1[j]);
}break;
case 3:{
unsigned char icdf[2];
icdf[0]=1;
icdf[1]=0;
sym=ec_dec_icdf(&dec,icdf,logp1[j]);
}break;
}
if(sym!=data[j]){
fprintf(stderr,
"Decoded %i instead of %i with logp1 of %i at position %i of %i (Random seed: %u).\n",
sym,data[j],logp1[j],j,sz,seed);
fprintf(stderr,"Encoding method: %i, decoding method: %i\n",
enc_method[j],dec_method);
ret=-1;
}
if(ec_tell_frac(&dec)!=tell[j+1]){
fprintf(stderr,
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
j+1,ec_tell_frac(&dec),tell[j+1],seed);
}
}
free(enc_method);
free(tell);
free(data);
free(logp1);
}
ec_enc_init(&enc,ptr,DATA_SIZE2);
ec_enc_bit_logp(&enc,0,1);
ec_enc_bit_logp(&enc,0,1);
ec_enc_bit_logp(&enc,0,1);
ec_enc_bit_logp(&enc,0,1);
ec_enc_bit_logp(&enc,0,2);
ec_enc_patch_initial_bits(&enc,3,2);
if(enc.error){
fprintf(stderr,"patch_initial_bits failed");
ret=-1;
}
ec_enc_patch_initial_bits(&enc,0,5);
if(!enc.error){
fprintf(stderr,"patch_initial_bits didn't fail when it should have");
ret=-1;
}
ec_enc_done(&enc);
if(ec_range_bytes(&enc)!=1||ptr[0]!=192){
fprintf(stderr,"Got %d when expecting 192 for patch_initial_bits",ptr[0]);
ret=-1;
}
ec_enc_init(&enc,ptr,DATA_SIZE2);
ec_enc_bit_logp(&enc,0,1);
ec_enc_bit_logp(&enc,0,1);
ec_enc_bit_logp(&enc,1,6);
ec_enc_bit_logp(&enc,0,2);
ec_enc_patch_initial_bits(&enc,0,2);
if(enc.error){
fprintf(stderr,"patch_initial_bits failed");
ret=-1;
}
ec_enc_done(&enc);
if(ec_range_bytes(&enc)!=2||ptr[0]!=63){
fprintf(stderr,"Got %d when expecting 63 for patch_initial_bits",ptr[0]);
ret=-1;
}
ec_enc_init(&enc,ptr,2);
ec_enc_bit_logp(&enc,0,2);
for(i=0;i<48;i++){
ec_enc_bits(&enc,0,1);
}
ec_enc_done(&enc);
if(!enc.error){
fprintf(stderr,"Raw bits overfill didn't fail when it should have");
ret=-1;
}
ec_enc_init(&enc,ptr,2);
for(i=0;i<17;i++){
ec_enc_bits(&enc,0,1);
}
ec_enc_done(&enc);
if(!enc.error){
fprintf(stderr,"17 raw bits encoded in two bytes");
ret=-1;
}
free(ptr);
return ret;
}

View File

@ -0,0 +1,92 @@
/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation
Written by Jean-Marc Valin and Timothy B. Terriberry */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include "laplace.h"
#define CELT_C
#include "stack_alloc.h"
#include "entenc.c"
#include "entdec.c"
#include "entcode.c"
#include "laplace.c"
#define DATA_SIZE 40000
int ec_laplace_get_start_freq(int decay)
{
opus_uint32 ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN+1);
int fs = (ft*(16384-decay))/(16384+decay);
return fs+LAPLACE_MINP;
}
int main(void)
{
int i;
int ret = 0;
ec_enc enc;
ec_dec dec;
unsigned char *ptr;
int val[10000], decay[10000];
ALLOC_STACK;
ptr = (unsigned char *)malloc(DATA_SIZE);
ec_enc_init(&enc,ptr,DATA_SIZE);
val[0] = 3; decay[0] = 6000;
val[1] = 0; decay[1] = 5800;
val[2] = -1; decay[2] = 5600;
for (i=3;i<10000;i++)
{
val[i] = rand()%15-7;
decay[i] = rand()%11000+5000;
}
for (i=0;i<10000;i++)
ec_laplace_encode(&enc, &val[i],
ec_laplace_get_start_freq(decay[i]), decay[i]);
ec_enc_done(&enc);
ec_dec_init(&dec,ec_get_buffer(&enc),ec_range_bytes(&enc));
for (i=0;i<10000;i++)
{
int d = ec_laplace_decode(&dec,
ec_laplace_get_start_freq(decay[i]), decay[i]);
if (d != val[i])
{
fprintf (stderr, "Got %d instead of %d\n", d, val[i]);
ret = 1;
}
}
return ret;
}

View File

@ -0,0 +1,273 @@
/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
Gregory Maxwell
Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef CUSTOM_MODES
#define CUSTOM_MODES
#endif
#define CELT_C
#include "mathops.c"
#include "entenc.c"
#include "entdec.c"
#include "entcode.c"
#include "bands.c"
#include "vq.c"
#include "cwrs.c"
#include <stdio.h>
#include <math.h>
#ifdef FIXED_POINT
#define WORD "%d"
#else
#define WORD "%f"
#endif
int ret = 0;
void testdiv(void)
{
opus_int32 i;
for (i=1;i<=327670;i++)
{
double prod;
opus_val32 val;
val = celt_rcp(i);
#ifdef FIXED_POINT
prod = (1./32768./65526.)*val*i;
#else
prod = val*i;
#endif
if (fabs(prod-1) > .00025)
{
fprintf (stderr, "div failed: 1/%d="WORD" (product = %f)\n", i, val, prod);
ret = 1;
}
}
}
void testsqrt(void)
{
opus_int32 i;
for (i=1;i<=1000000000;i++)
{
double ratio;
opus_val16 val;
val = celt_sqrt(i);
ratio = val/sqrt(i);
if (fabs(ratio - 1) > .0005 && fabs(val-sqrt(i)) > 2)
{
fprintf (stderr, "sqrt failed: sqrt(%d)="WORD" (ratio = %f)\n", i, val, ratio);
ret = 1;
}
i+= i>>10;
}
}
void testbitexactcos(void)
{
int i;
opus_int32 min_d,max_d,last,chk;
chk=max_d=0;
last=min_d=32767;
for(i=64;i<=16320;i++)
{
opus_int32 d;
opus_int32 q=bitexact_cos(i);
chk ^= q*i;
d = last - q;
if (d>max_d)max_d=d;
if (d<min_d)min_d=d;
last = q;
}
if ((chk!=89408644)||(max_d!=5)||(min_d!=0)||(bitexact_cos(64)!=32767)||
(bitexact_cos(16320)!=200)||(bitexact_cos(8192)!=23171))
{
fprintf (stderr, "bitexact_cos failed\n");
ret = 1;
}
}
void testbitexactlog2tan(void)
{
int i,fail;
opus_int32 min_d,max_d,last,chk;
fail=chk=max_d=0;
last=min_d=15059;
for(i=64;i<8193;i++)
{
opus_int32 d;
opus_int32 mid=bitexact_cos(i);
opus_int32 side=bitexact_cos(16384-i);
opus_int32 q=bitexact_log2tan(mid,side);
chk ^= q*i;
d = last - q;
if (q!=-1*bitexact_log2tan(side,mid))
fail = 1;
if (d>max_d)max_d=d;
if (d<min_d)min_d=d;
last = q;
}
if ((chk!=15821257)||(max_d!=61)||(min_d!=-2)||fail||
(bitexact_log2tan(32767,200)!=15059)||(bitexact_log2tan(30274,12540)!=2611)||
(bitexact_log2tan(23171,23171)!=0))
{
fprintf (stderr, "bitexact_log2tan failed\n");
ret = 1;
}
}
#ifndef FIXED_POINT
void testlog2(void)
{
float x;
for (x=0.001;x<1677700.0;x+=(x/8.0))
{
float error = fabs((1.442695040888963387*log(x))-celt_log2(x));
if (error>0.0009)
{
fprintf (stderr, "celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\n", x,error);
ret = 1;
}
}
}
void testexp2(void)
{
float x;
for (x=-11.0;x<24.0;x+=0.0007)
{
float error = fabs(x-(1.442695040888963387*log(celt_exp2(x))));
if (error>0.0002)
{
fprintf (stderr, "celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\n", x,error);
ret = 1;
}
}
}
void testexp2log2(void)
{
float x;
for (x=-11.0;x<24.0;x+=0.0007)
{
float error = fabs(x-(celt_log2(celt_exp2(x))));
if (error>0.001)
{
fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_log2(celt_exp2(x))))>0.001 (x = %f, error = %f)\n", x,error);
ret = 1;
}
}
}
#else
void testlog2(void)
{
opus_val32 x;
for (x=8;x<1073741824;x+=(x>>3))
{
float error = fabs((1.442695040888963387*log(x/16384.0))-celt_log2(x)/1024.0);
if (error>0.003)
{
fprintf (stderr, "celt_log2 failed: x = %ld, error = %f\n", (long)x,error);
ret = 1;
}
}
}
void testexp2(void)
{
opus_val16 x;
for (x=-32768;x<15360;x++)
{
float error1 = fabs(x/1024.0-(1.442695040888963387*log(celt_exp2(x)/65536.0)));
float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0);
if (error1>0.0002&&error2>0.00004)
{
fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2);
ret = 1;
}
}
}
void testexp2log2(void)
{
opus_val32 x;
for (x=8;x<65536;x+=(x>>3))
{
float error = fabs(x-0.25*celt_exp2(celt_log2(x)))/16384;
if (error>0.004)
{
fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_exp2(celt_log2(x))))>0.001 (x = %ld, error = %f)\n", (long)x,error);
ret = 1;
}
}
}
void testilog2(void)
{
opus_val32 x;
for (x=1;x<=268435455;x+=127)
{
opus_val32 lg;
opus_val32 y;
lg = celt_ilog2(x);
if (lg<0 || lg>=31)
{
printf("celt_ilog2 failed: 0<=celt_ilog2(x)<31 (x = %d, celt_ilog2(x) = %d)\n",x,lg);
ret = 1;
}
y = 1<<lg;
if (x<y || (x>>1)>=y)
{
printf("celt_ilog2 failed: 2**celt_ilog2(x)<=x<2**(celt_ilog2(x)+1) (x = %d, 2**celt_ilog2(x) = %d)\n",x,y);
ret = 1;
}
}
}
#endif
int main(void)
{
testbitexactcos();
testbitexactlog2tan();
testdiv();
testsqrt();
testlog2();
testexp2();
testexp2log2();
#ifdef FIXED_POINT
testilog2();
#endif
return ret;
}

View File

@ -0,0 +1,195 @@
/* Copyright (c) 2008-2011 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define SKIP_CONFIG_H
#ifndef CUSTOM_MODES
#define CUSTOM_MODES
#endif
#include <stdio.h>
#define CELT_C
#include "mdct.h"
#include "stack_alloc.h"
#include "kiss_fft.c"
#include "mdct.c"
#include "mathops.c"
#include "entcode.c"
#ifndef M_PI
#define M_PI 3.141592653
#endif
int ret = 0;
void check(kiss_fft_scalar * in,kiss_fft_scalar * out,int nfft,int isinverse)
{
int bin,k;
double errpow=0,sigpow=0;
double snr;
for (bin=0;bin<nfft/2;++bin) {
double ansr = 0;
double difr;
for (k=0;k<nfft;++k) {
double phase = 2*M_PI*(k+.5+.25*nfft)*(bin+.5)/nfft;
double re = cos(phase);
re /= nfft/4;
ansr += in[k] * re;
}
/*printf ("%f %f\n", ansr, out[bin]);*/
difr = ansr - out[bin];
errpow += difr*difr;
sigpow += ansr*ansr;
}
snr = 10*log10(sigpow/errpow);
printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
if (snr<60) {
printf( "** poor snr: %f **\n", snr);
ret = 1;
}
}
void check_inv(kiss_fft_scalar * in,kiss_fft_scalar * out,int nfft,int isinverse)
{
int bin,k;
double errpow=0,sigpow=0;
double snr;
for (bin=0;bin<nfft;++bin) {
double ansr = 0;
double difr;
for (k=0;k<nfft/2;++k) {
double phase = 2*M_PI*(bin+.5+.25*nfft)*(k+.5)/nfft;
double re = cos(phase);
/*re *= 2;*/
ansr += in[k] * re;
}
/*printf ("%f %f\n", ansr, out[bin]);*/
difr = ansr - out[bin];
errpow += difr*difr;
sigpow += ansr*ansr;
}
snr = 10*log10(sigpow/errpow);
printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
if (snr<60) {
printf( "** poor snr: %f **\n", snr);
ret = 1;
}
}
void test1d(int nfft,int isinverse)
{
mdct_lookup cfg;
size_t buflen = sizeof(kiss_fft_scalar)*nfft;
kiss_fft_scalar * in = (kiss_fft_scalar*)malloc(buflen);
kiss_fft_scalar * in_copy = (kiss_fft_scalar*)malloc(buflen);
kiss_fft_scalar * out= (kiss_fft_scalar*)malloc(buflen);
opus_val16 * window= (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);
int k;
clt_mdct_init(&cfg, nfft, 0);
for (k=0;k<nfft;++k) {
in[k] = (rand() % 32768) - 16384;
}
for (k=0;k<nfft/2;++k) {
window[k] = Q15ONE;
}
for (k=0;k<nfft;++k) {
in[k] *= 32768;
}
if (isinverse)
{
for (k=0;k<nfft;++k) {
in[k] /= nfft;
}
}
for (k=0;k<nfft;++k)
in_copy[k] = in[k];
/*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
if (isinverse)
{
for (k=0;k<nfft;++k)
out[k] = 0;
clt_mdct_backward(&cfg,in,out, window, nfft/2, 0, 1);
check_inv(in,out,nfft,isinverse);
} else {
clt_mdct_forward(&cfg,in,out,window, nfft/2, 0, 1);
check(in_copy,out,nfft,isinverse);
}
/*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
free(in);
free(out);
clt_mdct_clear(&cfg);
}
int main(int argc,char ** argv)
{
ALLOC_STACK;
if (argc>1) {
int k;
for (k=1;k<argc;++k) {
test1d(atoi(argv[k]),0);
test1d(atoi(argv[k]),1);
}
}else{
test1d(32,0);
test1d(32,1);
test1d(256,0);
test1d(256,1);
test1d(512,0);
test1d(512,1);
#ifndef RADIX_TWO_ONLY
test1d(40,0);
test1d(40,1);
test1d(120,0);
test1d(120,1);
test1d(240,0);
test1d(240,1);
test1d(480,0);
test1d(480,1);
#endif
}
return ret;
}

View File

@ -0,0 +1,90 @@
/* Copyright (c) 2008-2011 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef CUSTOM_MODES
#define CUSTOM_MODES
#endif
#define CELT_C
#include <stdio.h>
#include <stdlib.h>
#include "vq.c"
#include "cwrs.c"
#include "entcode.c"
#include "entenc.c"
#include "entdec.c"
#include "mathops.c"
#include "bands.h"
#include <math.h>
#define MAX_SIZE 100
int ret=0;
void test_rotation(int N, int K)
{
int i;
double err = 0, ener = 0, snr, snr0;
opus_val16 x0[MAX_SIZE];
opus_val16 x1[MAX_SIZE];
for (i=0;i<N;i++)
x1[i] = x0[i] = rand()%32767-16384;
exp_rotation(x1, N, 1, 1, K, SPREAD_NORMAL);
for (i=0;i<N;i++)
{
err += (x0[i]-(double)x1[i])*(x0[i]-(double)x1[i]);
ener += x0[i]*(double)x0[i];
}
snr0 = 20*log10(ener/err);
err = ener = 0;
exp_rotation(x1, N, -1, 1, K, SPREAD_NORMAL);
for (i=0;i<N;i++)
{
err += (x0[i]-(double)x1[i])*(x0[i]-(double)x1[i]);
ener += x0[i]*(double)x0[i];
}
snr = 20*log10(ener/err);
printf ("SNR for size %d (%d pulses) is %f (was %f without inverse)\n", N, K, snr, snr0);
if (snr < 60 || snr0 > 20)
{
fprintf(stderr, "FAIL!\n");
ret = 1;
}
}
int main(void)
{
ALLOC_STACK;
test_rotation(15, 3);
test_rotation(23, 5);
test_rotation(50, 3);
test_rotation(80, 1);
return ret;
}

View File

@ -0,0 +1,50 @@
/* Copyright (c) 2008-2011 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "opus_types.h"
#include <stdio.h>
int main(void)
{
opus_int16 i = 1;
i <<= 14;
if (i>>14 != 1)
{
fprintf(stderr, "opus_int16 isn't 16 bits\n");
return 1;
}
if (sizeof(opus_int16)*2 != sizeof(opus_int32))
{
fprintf(stderr, "16*2 != 32\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,417 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "mathops.h"
#include "cwrs.h"
#include "vq.h"
#include "arch.h"
#include "os_support.h"
#include "bands.h"
#include "rate.h"
static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)
{
int i;
celt_norm *Xptr;
Xptr = X;
for (i=0;i<len-stride;i++)
{
celt_norm x1, x2;
x1 = Xptr[0];
x2 = Xptr[stride];
Xptr[stride] = EXTRACT16(SHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15));
*Xptr++ = EXTRACT16(SHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15));
}
Xptr = &X[len-2*stride-1];
for (i=len-2*stride-1;i>=0;i--)
{
celt_norm x1, x2;
x1 = Xptr[0];
x2 = Xptr[stride];
Xptr[stride] = EXTRACT16(SHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15));
*Xptr-- = EXTRACT16(SHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15));
}
}
static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread)
{
static const int SPREAD_FACTOR[3]={15,10,5};
int i;
opus_val16 c, s;
opus_val16 gain, theta;
int stride2=0;
int factor;
if (2*K>=len || spread==SPREAD_NONE)
return;
factor = SPREAD_FACTOR[spread-1];
gain = celt_div((opus_val32)MULT16_16(Q15_ONE,len),(opus_val32)(len+factor*K));
theta = HALF16(MULT16_16_Q15(gain,gain));
c = celt_cos_norm(EXTEND32(theta));
s = celt_cos_norm(EXTEND32(SUB16(Q15ONE,theta))); /* sin(theta) */
if (len>=8*stride)
{
stride2 = 1;
/* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding.
It's basically incrementing long as (stride2+0.5)^2 < len/stride. */
while ((stride2*stride2+stride2)*stride + (stride>>2) < len)
stride2++;
}
/*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for
extract_collapse_mask().*/
len /= stride;
for (i=0;i<stride;i++)
{
if (dir < 0)
{
if (stride2)
exp_rotation1(X+i*len, len, stride2, s, c);
exp_rotation1(X+i*len, len, 1, c, s);
} else {
exp_rotation1(X+i*len, len, 1, c, -s);
if (stride2)
exp_rotation1(X+i*len, len, stride2, s, -c);
}
}
}
/** Takes the pitch vector and the decoded residual vector, computes the gain
that will give ||p+g*y||=1 and mixes the residual with the pitch. */
static void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT X,
int N, opus_val32 Ryy, opus_val16 gain)
{
int i;
#ifdef FIXED_POINT
int k;
#endif
opus_val32 t;
opus_val16 g;
#ifdef FIXED_POINT
k = celt_ilog2(Ryy)>>1;
#endif
t = VSHR32(Ryy, 2*(k-7));
g = MULT16_16_P15(celt_rsqrt_norm(t),gain);
i=0;
do
X[i] = EXTRACT16(PSHR32(MULT16_16(g, iy[i]), k+1));
while (++i < N);
}
static unsigned extract_collapse_mask(int *iy, int N, int B)
{
unsigned collapse_mask;
int N0;
int i;
if (B<=1)
return 1;
/*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for
exp_rotation().*/
N0 = N/B;
collapse_mask = 0;
i=0; do {
int j;
j=0; do {
collapse_mask |= (iy[i*N0+j]!=0)<<i;
} while (++j<N0);
} while (++i<B);
return collapse_mask;
}
#ifdef OPUS_ENABLE_ENCODER
unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
#ifdef RESYNTH
, opus_val16 gain
#endif
)
{
VARDECL(celt_norm, y);
VARDECL(int, iy);
VARDECL(opus_val16, signx);
int i, j;
opus_val16 s;
int pulsesLeft;
opus_val32 sum;
opus_val32 xy;
opus_val16 yy;
unsigned collapse_mask;
SAVE_STACK;
celt_assert2(K>0, "alg_quant() needs at least one pulse");
celt_assert2(N>1, "alg_quant() needs at least two dimensions");
ALLOC(y, N, celt_norm);
ALLOC(iy, N, int);
ALLOC(signx, N, opus_val16);
exp_rotation(X, N, 1, B, K, spread);
/* Get rid of the sign */
sum = 0;
j=0; do {
if (X[j]>0)
signx[j]=1;
else {
signx[j]=-1;
X[j]=-X[j];
}
iy[j] = 0;
y[j] = 0;
} while (++j<N);
xy = yy = 0;
pulsesLeft = K;
/* Do a pre-search by projecting on the pyramid */
if (K > (N>>1))
{
opus_val16 rcp;
j=0; do {
sum += X[j];
} while (++j<N);
/* If X is too small, just replace it with a pulse at 0 */
#ifdef FIXED_POINT
if (sum <= K)
#else
/* Prevents infinities and NaNs from causing too many pulses
to be allocated. 64 is an approximation of infinity here. */
if (!(sum > EPSILON && sum < 64))
#endif
{
X[0] = QCONST16(1.f,14);
j=1; do
X[j]=0;
while (++j<N);
sum = QCONST16(1.f,14);
}
rcp = EXTRACT16(MULT16_32_Q16(K-1, celt_rcp(sum)));
j=0; do {
#ifdef FIXED_POINT
/* It's really important to round *towards zero* here */
iy[j] = MULT16_16_Q15(X[j],rcp);
#else
iy[j] = (int)floor(rcp*X[j]);
#endif
y[j] = (celt_norm)iy[j];
yy = MAC16_16(yy, y[j],y[j]);
xy = MAC16_16(xy, X[j],y[j]);
y[j] *= 2;
pulsesLeft -= iy[j];
} while (++j<N);
}
celt_assert2(pulsesLeft>=1, "Allocated too many pulses in the quick pass");
/* This should never happen, but just in case it does (e.g. on silence)
we fill the first bin with pulses. */
#ifdef FIXED_POINT_DEBUG
celt_assert2(pulsesLeft<=N+3, "Not enough pulses in the quick pass");
#endif
if (pulsesLeft > N+3)
{
opus_val16 tmp = (opus_val16)pulsesLeft;
yy = MAC16_16(yy, tmp, tmp);
yy = MAC16_16(yy, tmp, y[0]);
iy[0] += pulsesLeft;
pulsesLeft=0;
}
s = 1;
for (i=0;i<pulsesLeft;i++)
{
int best_id;
opus_val32 best_num = -VERY_LARGE16;
opus_val16 best_den = 0;
#ifdef FIXED_POINT
int rshift;
#endif
#ifdef FIXED_POINT
rshift = 1+celt_ilog2(K-pulsesLeft+i+1);
#endif
best_id = 0;
/* The squared magnitude term gets added anyway, so we might as well
add it outside the loop */
yy = ADD32(yy, 1);
j=0;
do {
opus_val16 Rxy, Ryy;
/* Temporary sums of the new pulse(s) */
Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[j])),rshift));
/* We're multiplying y[j] by two so we don't have to do it here */
Ryy = ADD16(yy, y[j]);
/* Approximate score: we maximise Rxy/sqrt(Ryy) (we're guaranteed that
Rxy is positive because the sign is pre-computed) */
Rxy = MULT16_16_Q15(Rxy,Rxy);
/* The idea is to check for num/den >= best_num/best_den, but that way
we can do it without any division */
/* OPT: Make sure to use conditional moves here */
if (MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num))
{
best_den = Ryy;
best_num = Rxy;
best_id = j;
}
} while (++j<N);
/* Updating the sums of the new pulse(s) */
xy = ADD32(xy, EXTEND32(X[best_id]));
/* We're multiplying y[j] by two so we don't have to do it here */
yy = ADD16(yy, y[best_id]);
/* Only now that we've made the final choice, update y/iy */
/* Multiplying y[j] by 2 so we don't have to do it everywhere else */
y[best_id] += 2*s;
iy[best_id]++;
}
/* Put the original sign back */
j=0;
do {
X[j] = MULT16_16(signx[j],X[j]);
if (signx[j] < 0)
iy[j] = -iy[j];
} while (++j<N);
encode_pulses(iy, N, K, enc);
#ifdef RESYNTH
normalise_residual(iy, X, N, yy, gain);
exp_rotation(X, N, -1, B, K, spread);
#endif
collapse_mask = extract_collapse_mask(iy, N, B);
RESTORE_STACK;
return collapse_mask;
}
#endif /* OPUS_ENABLE_ENCODER */
/** Decode pulse vector and combine the result with the pitch vector to produce
the final normalised signal in the current band. */
unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,
ec_dec *dec, opus_val16 gain)
{
int i;
opus_val32 Ryy;
unsigned collapse_mask;
VARDECL(int, iy);
SAVE_STACK;
celt_assert2(K>0, "alg_unquant() needs at least one pulse");
celt_assert2(N>1, "alg_unquant() needs at least two dimensions");
ALLOC(iy, N, int);
decode_pulses(iy, N, K, dec);
Ryy = 0;
i=0;
do {
Ryy = MAC16_16(Ryy, iy[i], iy[i]);
} while (++i < N);
normalise_residual(iy, X, N, Ryy, gain);
exp_rotation(X, N, -1, B, K, spread);
collapse_mask = extract_collapse_mask(iy, N, B);
RESTORE_STACK;
return collapse_mask;
}
void renormalise_vector(celt_norm *X, int N, opus_val16 gain)
{
int i;
#ifdef FIXED_POINT
int k;
#endif
opus_val32 E = EPSILON;
opus_val16 g;
opus_val32 t;
celt_norm *xptr = X;
for (i=0;i<N;i++)
{
E = MAC16_16(E, *xptr, *xptr);
xptr++;
}
#ifdef FIXED_POINT
k = celt_ilog2(E)>>1;
#endif
t = VSHR32(E, 2*(k-7));
g = MULT16_16_P15(celt_rsqrt_norm(t),gain);
xptr = X;
for (i=0;i<N;i++)
{
*xptr = EXTRACT16(PSHR32(MULT16_16(g, *xptr), k+1));
xptr++;
}
/*return celt_sqrt(E);*/
}
int stereo_itheta(celt_norm *X, celt_norm *Y, int stereo, int N)
{
int i;
int itheta;
opus_val16 mid, side;
opus_val32 Emid, Eside;
Emid = Eside = EPSILON;
if (stereo)
{
for (i=0;i<N;i++)
{
celt_norm m, s;
m = ADD16(SHR16(X[i],1),SHR16(Y[i],1));
s = SUB16(SHR16(X[i],1),SHR16(Y[i],1));
Emid = MAC16_16(Emid, m, m);
Eside = MAC16_16(Eside, s, s);
}
} else {
for (i=0;i<N;i++)
{
celt_norm m, s;
m = X[i];
s = Y[i];
Emid = MAC16_16(Emid, m, m);
Eside = MAC16_16(Eside, s, s);
}
}
mid = celt_sqrt(Emid);
side = celt_sqrt(Eside);
#ifdef FIXED_POINT
/* 0.63662 = 2/pi */
itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid));
#else
itheta = (int)floor(.5f+16384*0.63662f*atan2(side,mid));
#endif
return itheta;
}

View File

@ -0,0 +1,73 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/**
@file vq.h
@brief Vector quantisation of the residual
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef VQ_H
#define VQ_H
#include "entenc.h"
#include "entdec.h"
#include "modes.h"
/** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of
* the pitch and a combination of pulses such that its norm is still equal
* to 1. This is the function that will typically require the most CPU.
* @param x Residual signal to quantise/encode (returns quantised version)
* @param W Perceptual weight to use when optimising (currently unused)
* @param N Number of samples to encode
* @param K Number of pulses to use
* @param p Pitch vector (it is assumed that p+x is a unit vector)
* @param enc Entropy encoder state
* @ret A mask indicating which blocks in the band received pulses
*/
unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B,
ec_enc *enc
#ifdef RESYNTH
, opus_val16 gain
#endif
);
/** Algebraic pulse decoder
* @param x Decoded normalised spectrum (returned)
* @param N Number of samples to decode
* @param K Number of pulses to use
* @param p Pitch vector (automatically added to x)
* @param dec Entropy decoder state
* @ret A mask indicating which blocks in the band received pulses
*/
unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,
ec_dec *dec, opus_val16 gain);
void renormalise_vector(celt_norm *X, int N, opus_val16 gain);
int stereo_itheta(celt_norm *X, celt_norm *Y, int stereo, int N);
#endif /* VQ_H */