Remove speex support, it is obsoleted by opus
As mentioned by upstream, Xiph.Org [0]: > The Speex codec has been obsoleted by Opus. It will continue to be > available, but since Opus is better than Speex in all aspects, > users are encouraged to switch. [0] http://www.speex.org/
This commit is contained in:
parent
6c0be2c017
commit
d3d0507c05
110 changed files with 1 additions and 28804 deletions
|
@ -126,7 +126,6 @@ opts.Add('squish','Squish BC Texture Compression in editor (yes/no)','yes')
|
|||
opts.Add('theora','Theora Video (yes/no)','yes')
|
||||
opts.Add('theoralib','Theora Video (yes/no)','no')
|
||||
opts.Add('freetype','Freetype support in editor','builtin')
|
||||
opts.Add('speex','Speex Audio (yes/no)','yes')
|
||||
opts.Add('xml','XML Save/Load support (yes/no)','yes')
|
||||
opts.Add('png','PNG Image loader support (yes/no)','yes')
|
||||
opts.Add('jpg','JPG Image loader support (yes/no)','yes')
|
||||
|
@ -362,9 +361,6 @@ if selected_platform in platform_list:
|
|||
if (env['webp']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DWEBP_ENABLED']);
|
||||
|
||||
if (env['speex']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DSPEEX_ENABLED']);
|
||||
|
||||
if (env['tools']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DTOOLS_ENABLED'])
|
||||
if (env['disable_3d']=='yes'):
|
||||
|
|
|
@ -5459,18 +5459,6 @@
|
|||
<constants>
|
||||
</constants>
|
||||
</class>
|
||||
<class name="AudioStreamSpeex" inherits="AudioStream" category="Core">
|
||||
<brief_description>
|
||||
Speex audio stream driver.
|
||||
</brief_description>
|
||||
<description>
|
||||
Speex audio stream driver. Speex is very useful for compressed speech. It allows loading a very large amount of speech in memory at little IO/latency cost.
|
||||
</description>
|
||||
<methods>
|
||||
</methods>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
||||
<class name="BackBufferCopy" inherits="Node2D" category="Core">
|
||||
<brief_description>
|
||||
Copies a region of the screen (or the whole screen) to a buffer so it can be accessed with the texscreen() shader instruction.
|
||||
|
|
4
drivers/SCsub
vendored
4
drivers/SCsub
vendored
|
@ -43,7 +43,7 @@ SConscript("rtaudio/SCsub");
|
|||
SConscript("nedmalloc/SCsub");
|
||||
SConscript("nrex/SCsub");
|
||||
SConscript("chibi/SCsub");
|
||||
if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theoralib"]=="yes" or env["opus"]=="yes"):
|
||||
if (env["vorbis"]=="yes" or env["theoralib"]=="yes" or env["opus"]=="yes"):
|
||||
SConscript("ogg/SCsub");
|
||||
if (env["vorbis"]=="yes"):
|
||||
SConscript("vorbis/SCsub");
|
||||
|
@ -54,8 +54,6 @@ if (env["tools"]=="yes"):
|
|||
|
||||
if (env["theoralib"]=="yes"):
|
||||
SConscript("theora/SCsub");
|
||||
if (env['speex']=='yes'):
|
||||
SConscript("speex/SCsub");
|
||||
if (env['musepack']=='yes'):
|
||||
SConscript("mpc/SCsub");
|
||||
if (env["squish"]=="yes" and env["tools"]=="yes"):
|
||||
|
|
18
drivers/register_driver_types.cpp
vendored
18
drivers/register_driver_types.cpp
vendored
|
@ -64,10 +64,6 @@
|
|||
#include "opus/audio_stream_opus.h"
|
||||
#endif
|
||||
|
||||
#ifdef SPEEX_ENABLED
|
||||
#include "speex/audio_stream_speex.h"
|
||||
#endif
|
||||
|
||||
#ifdef THEORA_ENABLED
|
||||
#include "theora/video_stream_theora.h"
|
||||
#endif
|
||||
|
@ -118,10 +114,6 @@ static ResourceFormatLoaderAudioStreamOGGVorbis *vorbis_stream_loader=NULL;
|
|||
static ResourceFormatLoaderAudioStreamOpus *opus_stream_loader=NULL;
|
||||
#endif
|
||||
|
||||
#ifdef SPEEX_ENABLED
|
||||
static ResourceFormatLoaderAudioStreamSpeex *speex_stream_loader=NULL;
|
||||
#endif
|
||||
|
||||
#ifdef THEORA_ENABLED
|
||||
static ResourceFormatLoaderVideoStreamTheora* theora_stream_loader = NULL;
|
||||
#endif
|
||||
|
@ -236,12 +228,6 @@ void register_driver_types() {
|
|||
Geometry::_decompose_func=b2d_decompose;
|
||||
#endif
|
||||
|
||||
#ifdef SPEEX_ENABLED
|
||||
speex_stream_loader=memnew( ResourceFormatLoaderAudioStreamSpeex );
|
||||
ResourceLoader::add_resource_format_loader(speex_stream_loader);
|
||||
ObjectTypeDB::register_type<AudioStreamSpeex>();
|
||||
#endif
|
||||
|
||||
#ifdef MUSEPACK_ENABLED
|
||||
|
||||
mpc_stream_loader=memnew( ResourceFormatLoaderAudioStreamMPC );
|
||||
|
@ -292,10 +278,6 @@ void unregister_driver_types() {
|
|||
memdelete( opus_stream_loader );
|
||||
#endif
|
||||
|
||||
#ifdef SPEEX_ENABLED
|
||||
memdelete( speex_stream_loader );
|
||||
#endif
|
||||
|
||||
#ifdef THEORA_ENABLED
|
||||
memdelete (theora_stream_loader);
|
||||
#endif
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
Import('env')
|
||||
|
||||
|
||||
|
||||
|
||||
speex_sources = [\
|
||||
"speex/bits.c",\
|
||||
"speex/buffer.c",\
|
||||
"speex/cb_search.c",\
|
||||
"speex/exc_10_16_table.c",\
|
||||
"speex/exc_10_32_table.c",\
|
||||
"speex/exc_20_32_table.c",\
|
||||
"speex/exc_5_256_table.c",\
|
||||
"speex/exc_5_64_table.c",\
|
||||
"speex/exc_8_128_table.c",\
|
||||
"speex/fftwrap.c",\
|
||||
"speex/filterbank.c",\
|
||||
"speex/filters.c",\
|
||||
"speex/gain_table.c",\
|
||||
"speex/gain_table_lbr.c",\
|
||||
"speex/hexc_10_32_table.c",\
|
||||
"speex/hexc_table.c",\
|
||||
"speex/high_lsp_tables.c",\
|
||||
"speex/jitter.c",\
|
||||
"speex/kiss_fft.c",\
|
||||
"speex/kiss_fftr.c",\
|
||||
"speex/lpc.c",\
|
||||
"speex/lsp.c",\
|
||||
"speex/lsp_tables_nb.c",\
|
||||
"speex/ltp.c",\
|
||||
"speex/mdf.c",\
|
||||
"speex/modes.c",\
|
||||
"speex/modes_wb.c",\
|
||||
"speex/nb_celp.c",\
|
||||
"speex/preprocess.c",\
|
||||
"speex/quant_lsp.c",\
|
||||
"speex/resample.c",\
|
||||
"speex/sb_celp.c",\
|
||||
"speex/scal.c",\
|
||||
"speex/smallft.c",\
|
||||
"speex/speex.c",\
|
||||
"speex/speex_callbacks.c",\
|
||||
"speex/speex_header.c",\
|
||||
"speex/stereo.c",\
|
||||
"speex/vbr.c",\
|
||||
"speex/vq.c",\
|
||||
"speex/window.c",\
|
||||
"speex/audio_stream_speex.cpp",
|
||||
]
|
||||
|
||||
env.drivers_sources+=speex_sources
|
||||
|
||||
#env.add_source_files(env.drivers_sources, speex_sources)
|
||||
|
||||
Export('env')
|
|
@ -1,160 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
* Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#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"
|
||||
#include "math_approx.h"
|
||||
|
||||
#define MAXFACTORS 32
|
||||
/* e.g. an fft of length 128 has 4 factors
|
||||
as far as kissfft is concerned
|
||||
4*4*4*2
|
||||
*/
|
||||
|
||||
struct kiss_fft_state{
|
||||
int nfft;
|
||||
int inverse;
|
||||
int factors[2*MAXFACTORS];
|
||||
kiss_fft_cpx twiddles[1];
|
||||
};
|
||||
|
||||
/*
|
||||
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 FRACBITS 15
|
||||
# define SAMPPROD spx_int32_t
|
||||
#define SAMP_MAX 32767
|
||||
|
||||
#define SAMP_MIN -SAMP_MAX
|
||||
|
||||
#if defined(CHECK_OVERFLOW)
|
||||
# define CHECK_OVERFLOW_OP(a,op,b) \
|
||||
if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
|
||||
fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); }
|
||||
#endif
|
||||
|
||||
|
||||
# define smul(a,b) ( (SAMPPROD)(a)*(b) )
|
||||
# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
|
||||
|
||||
# define S_MUL(a,b) sround( smul(a,b) )
|
||||
|
||||
# define C_MUL(m,a,b) \
|
||||
do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
|
||||
(m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
|
||||
|
||||
# define C_MUL4(m,a,b) \
|
||||
do{ (m).r = PSHR32( smul((a).r,(b).r) - smul((a).i,(b).i),17 ); \
|
||||
(m).i = PSHR32( smul((a).r,(b).i) + smul((a).i,(b).r),17 ); }while(0)
|
||||
|
||||
# define DIVSCALAR(x,k) \
|
||||
(x) = sround( smul( x, SAMP_MAX/k ) )
|
||||
|
||||
# define C_FIXDIV(c,div) \
|
||||
do { DIVSCALAR( (c).r , div); \
|
||||
DIVSCALAR( (c).i , div); }while (0)
|
||||
|
||||
# define C_MULBYSCALAR( c, s ) \
|
||||
do{ (c).r = sround( smul( (c).r , s ) ) ;\
|
||||
(c).i = sround( smul( (c).i , s ) ) ; }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_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
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
# define KISS_FFT_COS(phase) floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase))))
|
||||
# define KISS_FFT_SIN(phase) floor(MIN(32767,MAX(-32767,.5+32768 * 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(.5))
|
||||
#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)*.5)
|
||||
#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 = spx_cos_norm((phase));\
|
||||
(x)->i = spx_cos_norm((phase)-32768);\
|
||||
}while(0)
|
||||
|
||||
|
||||
/* a debugging function */
|
||||
#define pcpx(c)\
|
||||
fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
|
|
@ -1,249 +0,0 @@
|
|||
/* Copyright (C) 2003 Jean-Marc Valin */
|
||||
/**
|
||||
@file arch.h
|
||||
@brief Various architecture definitions Speex
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCH_H
|
||||
#define ARCH_H
|
||||
|
||||
#ifndef SPEEX_VERSION
|
||||
#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */
|
||||
#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */
|
||||
#define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */
|
||||
#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */
|
||||
#define SPEEX_VERSION "speex-1.2beta3" /**< Speex version string. */
|
||||
#endif
|
||||
|
||||
#include "os_support.h"
|
||||
/* A couple test to catch stupid option combinations */
|
||||
|
||||
//custom engine code
|
||||
#ifndef FIXED_POINT
|
||||
#define FLOATING_POINT
|
||||
#endif
|
||||
#define USE_SMALLFT
|
||||
#define EXPORT
|
||||
//end of custom engine code
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
#ifdef FLOATING_POINT
|
||||
#error You cannot compile as floating point and fixed point at the same time
|
||||
#endif
|
||||
#ifdef _USE_SSE
|
||||
#error SSE is only for floating-point
|
||||
#endif
|
||||
#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))
|
||||
#error Make up your mind. What CPU do you have?
|
||||
#endif
|
||||
#ifdef VORBIS_PSYCHO
|
||||
#error Vorbis-psy model currently not implemented in fixed-point
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifndef FLOATING_POINT
|
||||
#error You now need to define either FIXED_POINT or FLOATING_POINT
|
||||
#endif
|
||||
#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
|
||||
#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?
|
||||
#endif
|
||||
#ifdef FIXED_POINT_DEBUG
|
||||
#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?"
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef OUTSIDE_SPEEX
|
||||
#include "speex/speex_types.h"
|
||||
#endif
|
||||
|
||||
#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)) /**< Maximum 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)) /**< Maximum 32-bit value. */
|
||||
#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
typedef spx_int16_t spx_word16_t;
|
||||
typedef spx_int32_t spx_word32_t;
|
||||
typedef spx_word32_t spx_mem_t;
|
||||
typedef spx_word16_t spx_coef_t;
|
||||
typedef spx_word16_t spx_lsp_t;
|
||||
typedef spx_word32_t spx_sig_t;
|
||||
|
||||
#define Q15ONE 32767
|
||||
|
||||
#define LPC_SCALING 8192
|
||||
#define SIG_SCALING 16384
|
||||
#define LSP_SCALING 8192.
|
||||
#define GAMMA_SCALING 32768.
|
||||
#define GAIN_SCALING 64
|
||||
#define GAIN_SCALING_1 0.015625
|
||||
|
||||
#define LPC_SHIFT 13
|
||||
#define LSP_SHIFT 13
|
||||
#define SIG_SHIFT 14
|
||||
#define GAIN_SHIFT 6
|
||||
|
||||
#define VERY_SMALL 0
|
||||
#define VERY_LARGE32 ((spx_word32_t)2147483647)
|
||||
#define VERY_LARGE16 ((spx_word16_t)32767)
|
||||
#define Q15_ONE ((spx_word16_t)32767)
|
||||
|
||||
|
||||
#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"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
|
||||
typedef float spx_mem_t;
|
||||
typedef float spx_coef_t;
|
||||
typedef float spx_lsp_t;
|
||||
typedef float spx_sig_t;
|
||||
typedef float spx_word16_t;
|
||||
typedef float spx_word32_t;
|
||||
|
||||
#define Q15ONE 1.0f
|
||||
#define LPC_SCALING 1.f
|
||||
#define SIG_SCALING 1.f
|
||||
#define LSP_SCALING 1.f
|
||||
#define GAMMA_SCALING 1.f
|
||||
#define GAIN_SCALING 1.f
|
||||
#define GAIN_SCALING_1 1.f
|
||||
|
||||
|
||||
#define VERY_SMALL 1e-15f
|
||||
#define VERY_LARGE32 1e15f
|
||||
#define VERY_LARGE16 1e15f
|
||||
#define Q15_ONE ((spx_word16_t)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 PSHR16(a,shift) (a)
|
||||
#define PSHR32(a,shift) (a)
|
||||
#define VSHR32(a,shift) (a)
|
||||
#define SATURATE16(x,a) (x)
|
||||
#define SATURATE32(x,a) (x)
|
||||
|
||||
#define PSHR(a,shift) (a)
|
||||
#define SHR(a,shift) (a)
|
||||
#define SHL(a,shift) (a)
|
||||
#define SATURATE(x,a) (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) ((spx_word32_t)(a)*(spx_word32_t)(b))
|
||||
#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b))
|
||||
|
||||
#define MULT16_32_Q11(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q13(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q14(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q15(a,b) ((a)*(b))
|
||||
#define MULT16_32_P15(a,b) ((a)*(b))
|
||||
|
||||
#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b))
|
||||
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
|
||||
|
||||
#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b))
|
||||
#define MAC16_16_Q13(c,a,b) ((c)+(a)*(b))
|
||||
#define MAC16_16_P13(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 DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
|
||||
#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
|
||||
#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
|
||||
#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
|
||||
|
||||
/* 2 on TI C5x DSP */
|
||||
#define BYTES_PER_CHAR 2
|
||||
#define BITS_PER_CHAR 16
|
||||
#define LOG2_BITS_PER_CHAR 4
|
||||
|
||||
#else
|
||||
|
||||
#define BYTES_PER_CHAR 1
|
||||
#define BITS_PER_CHAR 8
|
||||
#define LOG2_BITS_PER_CHAR 3
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
extern long long spx_mips;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -1,581 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* audio_stream_speex.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "audio_stream_speex.h"
|
||||
|
||||
#include "os_support.h"
|
||||
#include "os/os.h"
|
||||
#define READ_CHUNK 1024
|
||||
|
||||
static _FORCE_INLINE_ uint16_t le_short(uint16_t s)
|
||||
{
|
||||
uint16_t ret=s;
|
||||
#if 0 //def BIG_ENDIAN_ENABLED
|
||||
ret = s>>8;
|
||||
ret += s<<8;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int AudioStreamPlaybackSpeex::mix(int16_t* p_buffer,int p_frames) {
|
||||
|
||||
|
||||
|
||||
//printf("update, loops %i, read ofs %i\n", (int)loops, read_ofs);
|
||||
//printf("playing %i, paused %i\n", (int)playing, (int)paused);
|
||||
|
||||
if (!active || !playing || !data.size())
|
||||
return 0;
|
||||
|
||||
/*
|
||||
if (read_ofs >= data.size()) {
|
||||
if (loops) {
|
||||
reload();
|
||||
++loop_count;
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
int todo = p_frames;
|
||||
if (todo < page_size) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
int eos = 0;
|
||||
|
||||
while (todo > page_size) {
|
||||
|
||||
int ret=0;
|
||||
while ((todo>page_size && packets_available && !eos) || (ret = ogg_sync_pageout(&oy, &og))==1) {
|
||||
|
||||
if (!packets_available) {
|
||||
/*Add page to the bitstream*/
|
||||
ogg_stream_pagein(&os, &og);
|
||||
page_granule = ogg_page_granulepos(&og);
|
||||
page_nb_packets = ogg_page_packets(&og);
|
||||
packet_no=0;
|
||||
if (page_granule>0 && frame_size)
|
||||
{
|
||||
skip_samples = page_nb_packets*frame_size*nframes - (page_granule-last_granule);
|
||||
if (ogg_page_eos(&og))
|
||||
skip_samples = -skip_samples;
|
||||
/*else if (!ogg_page_bos(&og))
|
||||
skip_samples = 0;*/
|
||||
} else
|
||||
{
|
||||
skip_samples = 0;
|
||||
}
|
||||
|
||||
|
||||
last_granule = page_granule;
|
||||
packets_available=true;
|
||||
}
|
||||
/*Extract all available packets*/
|
||||
while (todo > page_size && !eos) {
|
||||
|
||||
if (ogg_stream_packetout(&os, &op)!=1) {
|
||||
packets_available=false;
|
||||
break;
|
||||
}
|
||||
|
||||
packet_no++;
|
||||
|
||||
|
||||
/*End of stream condition*/
|
||||
if (op.e_o_s)
|
||||
eos=1;
|
||||
|
||||
/*Copy Ogg packet to Speex bitstream*/
|
||||
speex_bits_read_from(&bits, (char*)op.packet, op.bytes);
|
||||
|
||||
|
||||
for (int j=0;j!=nframes;j++)
|
||||
{
|
||||
|
||||
int16_t* out = p_buffer;
|
||||
|
||||
int ret;
|
||||
/*Decode frame*/
|
||||
ret = speex_decode_int(st, &bits, out);
|
||||
|
||||
/*for (i=0;i<frame_size*channels;i++)
|
||||
printf ("%d\n", (int)output[i]);*/
|
||||
|
||||
if (ret==-1) {
|
||||
printf("decode returned -1\n");
|
||||
break;
|
||||
};
|
||||
if (ret==-2)
|
||||
{
|
||||
OS::get_singleton()->printerr( "Decoding error: corrupted stream?\n");
|
||||
break;
|
||||
}
|
||||
if (speex_bits_remaining(&bits)<0)
|
||||
{
|
||||
OS::get_singleton()->printerr( "Decoding overflow: corrupted stream?\n");
|
||||
break;
|
||||
}
|
||||
//if (channels==2)
|
||||
// speex_decode_stereo_int(output, frame_size, &stereo);
|
||||
|
||||
|
||||
/*Convert to short and save to output file*/
|
||||
for (int i=0;i<frame_size*stream_channels;i++) {
|
||||
out[i]=le_short(out[i]);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
|
||||
int new_frame_size = frame_size;
|
||||
|
||||
/*printf ("packet %d %d\n", packet_no, skip_samples);*/
|
||||
if (packet_no == 1 && j==0 && skip_samples > 0)
|
||||
{
|
||||
/*printf ("chopping first packet\n");*/
|
||||
new_frame_size -= skip_samples;
|
||||
}
|
||||
if (packet_no == page_nb_packets && skip_samples < 0)
|
||||
{
|
||||
int packet_length = nframes*frame_size+skip_samples;
|
||||
new_frame_size = packet_length - j*frame_size;
|
||||
if (new_frame_size<0)
|
||||
new_frame_size = 0;
|
||||
if (new_frame_size>frame_size)
|
||||
new_frame_size = frame_size;
|
||||
/*printf ("chopping end: %d %d %d\n", new_frame_size, packet_length, packet_no);*/
|
||||
}
|
||||
|
||||
|
||||
p_buffer+=new_frame_size*stream_channels;
|
||||
todo-=new_frame_size;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
//todo = get_todo();
|
||||
|
||||
//todo is still greater than page size, can write more
|
||||
if (todo > page_size || eos) {
|
||||
if (read_ofs < data.size()) {
|
||||
|
||||
//char *buf;
|
||||
int nb_read = MIN(data.size() - read_ofs, READ_CHUNK);
|
||||
|
||||
/*Get the ogg buffer for writing*/
|
||||
char* ogg_dst = ogg_sync_buffer(&oy, nb_read);
|
||||
/*Read bitstream from input file*/
|
||||
copymem(ogg_dst, &data[read_ofs], nb_read);
|
||||
read_ofs += nb_read;
|
||||
ogg_sync_wrote(&oy, nb_read);
|
||||
} else {
|
||||
if (loops) {
|
||||
reload();
|
||||
++loop_count;
|
||||
//break;
|
||||
} else {
|
||||
playing=false;
|
||||
unload();
|
||||
break;
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
return p_frames-todo;
|
||||
};
|
||||
|
||||
|
||||
void AudioStreamPlaybackSpeex::unload() {
|
||||
|
||||
|
||||
|
||||
if (!active) return;
|
||||
|
||||
speex_bits_destroy(&bits);
|
||||
if (st)
|
||||
speex_decoder_destroy(st);
|
||||
|
||||
ogg_sync_clear(&oy);
|
||||
active = false;
|
||||
//data.resize(0);
|
||||
st = NULL;
|
||||
|
||||
frame_size = 0;
|
||||
page_size = 0;
|
||||
loop_count = 0;
|
||||
}
|
||||
|
||||
void *AudioStreamPlaybackSpeex::process_header(ogg_packet *op, int *frame_size, int *rate, int *nframes, int *channels, int *extra_headers) {
|
||||
|
||||
SpeexHeader *header;
|
||||
int modeID;
|
||||
|
||||
header = speex_packet_to_header((char*)op->packet, op->bytes);
|
||||
if (!header)
|
||||
{
|
||||
OS::get_singleton()->printerr( "Cannot read header\n");
|
||||
return NULL;
|
||||
}
|
||||
if (header->mode >= SPEEX_NB_MODES)
|
||||
{
|
||||
OS::get_singleton()->printerr( "Mode number %d does not (yet/any longer) exist in this version\n",
|
||||
header->mode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
modeID = header->mode;
|
||||
|
||||
const SpeexMode *mode = speex_lib_get_mode (modeID);
|
||||
|
||||
if (header->speex_version_id > 1)
|
||||
{
|
||||
OS::get_singleton()->printerr( "This file was encoded with Speex bit-stream version %d, which I don't know how to decode\n", header->speex_version_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mode->bitstream_version < header->mode_bitstream_version)
|
||||
{
|
||||
OS::get_singleton()->printerr( "The file was encoded with a newer version of Speex. You need to upgrade in order to play it.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (mode->bitstream_version > header->mode_bitstream_version)
|
||||
{
|
||||
OS::get_singleton()->printerr( "The file was encoded with an older version of Speex. You would need to downgrade the version in order to play it.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* state = speex_decoder_init(mode);
|
||||
if (!state)
|
||||
{
|
||||
OS::get_singleton()->printerr( "Decoder initialization failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
//speex_decoder_ctl(state, SPEEX_SET_ENH, &enh_enabled);
|
||||
speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, frame_size);
|
||||
|
||||
if (!*rate)
|
||||
*rate = header->rate;
|
||||
|
||||
speex_decoder_ctl(state, SPEEX_SET_SAMPLING_RATE, rate);
|
||||
|
||||
*nframes = header->frames_per_packet;
|
||||
|
||||
*channels = header->nb_channels;
|
||||
|
||||
if (*channels!=1) {
|
||||
OS::get_singleton()->printerr("Only MONO speex streams supported\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*extra_headers = header->extra_headers;
|
||||
|
||||
speex_free(header);
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AudioStreamPlaybackSpeex::reload() {
|
||||
|
||||
|
||||
|
||||
if (active)
|
||||
unload();
|
||||
|
||||
if (!data.size())
|
||||
return;
|
||||
|
||||
ogg_sync_init(&oy);
|
||||
speex_bits_init(&bits);
|
||||
|
||||
read_ofs = 0;
|
||||
// char *buf;
|
||||
|
||||
int packet_count = 0;
|
||||
int extra_headers = 0;
|
||||
int stream_init = 0;
|
||||
|
||||
page_granule=0;
|
||||
last_granule=0;
|
||||
skip_samples=0;
|
||||
page_nb_packets=0;
|
||||
packets_available=false;
|
||||
packet_no=0;
|
||||
|
||||
int eos = 0;
|
||||
|
||||
do {
|
||||
|
||||
/*Get the ogg buffer for writing*/
|
||||
int nb_read = MIN(data.size() - read_ofs, READ_CHUNK);
|
||||
char* ogg_dst = ogg_sync_buffer(&oy, nb_read);
|
||||
/*Read bitstream from input file*/
|
||||
copymem(ogg_dst, &data[read_ofs], nb_read);
|
||||
read_ofs += nb_read;
|
||||
ogg_sync_wrote(&oy, nb_read);
|
||||
|
||||
/*Loop for all complete pages we got (most likely only one)*/
|
||||
while (ogg_sync_pageout(&oy, &og)==1) {
|
||||
|
||||
if (stream_init == 0) {
|
||||
ogg_stream_init(&os, ogg_page_serialno(&og));
|
||||
stream_init = 1;
|
||||
}
|
||||
/*Add page to the bitstream*/
|
||||
ogg_stream_pagein(&os, &og);
|
||||
page_granule = ogg_page_granulepos(&og);
|
||||
page_nb_packets = ogg_page_packets(&og);
|
||||
if (page_granule>0 && frame_size)
|
||||
{
|
||||
skip_samples = page_nb_packets*frame_size*nframes - (page_granule-last_granule);
|
||||
if (ogg_page_eos(&og))
|
||||
skip_samples = -skip_samples;
|
||||
/*else if (!ogg_page_bos(&og))
|
||||
skip_samples = 0;*/
|
||||
} else
|
||||
{
|
||||
skip_samples = 0;
|
||||
}
|
||||
|
||||
|
||||
last_granule = page_granule;
|
||||
/*Extract all available packets*/
|
||||
while (!eos && ogg_stream_packetout(&os, &op)==1)
|
||||
{
|
||||
/*If first packet, process as Speex header*/
|
||||
if (packet_count==0)
|
||||
{
|
||||
int rate = 0;
|
||||
int channels;
|
||||
st = process_header(&op, &frame_size, &rate, &nframes, &channels, &extra_headers);
|
||||
if (!nframes)
|
||||
nframes=1;
|
||||
if (!st) {
|
||||
unload();
|
||||
return;
|
||||
};
|
||||
|
||||
page_size = nframes * frame_size;
|
||||
stream_srate=rate;
|
||||
stream_channels=channels;
|
||||
stream_minbuff_size=page_size;
|
||||
|
||||
|
||||
} else if (packet_count==1)
|
||||
{
|
||||
} else if (packet_count<=1+extra_headers)
|
||||
{
|
||||
/* Ignore extra headers */
|
||||
};
|
||||
};
|
||||
++packet_count;
|
||||
};
|
||||
|
||||
} while (packet_count <= extra_headers);
|
||||
|
||||
active=true;
|
||||
|
||||
}
|
||||
|
||||
void AudioStreamPlaybackSpeex::_bind_methods() {
|
||||
|
||||
//ObjectTypeDB::bind_method(_MD("set_file","file"),&AudioStreamPlaybackSpeex::set_file);
|
||||
// ObjectTypeDB::bind_method(_MD("get_file"),&AudioStreamPlaybackSpeex::get_file);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_set_bundled"),&AudioStreamPlaybackSpeex::_set_bundled);
|
||||
ObjectTypeDB::bind_method(_MD("_get_bundled"),&AudioStreamPlaybackSpeex::_get_bundled);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::DICTIONARY,"_bundled",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_BUNDLE),_SCS("_set_bundled"),_SCS("_get_bundled"));
|
||||
//ADD_PROPERTY( PropertyInfo(Variant::STRING,"file",PROPERTY_HINT_FILE,"*.spx"),_SCS("set_file"),_SCS("get_file"));
|
||||
};
|
||||
|
||||
void AudioStreamPlaybackSpeex::_set_bundled(const Dictionary& dict) {
|
||||
|
||||
ERR_FAIL_COND( !dict.has("filename"));
|
||||
ERR_FAIL_COND( !dict.has("data"));
|
||||
|
||||
filename = dict["filename"];
|
||||
data = dict["data"];
|
||||
};
|
||||
|
||||
Dictionary AudioStreamPlaybackSpeex::_get_bundled() const {
|
||||
|
||||
Dictionary d;
|
||||
d["filename"] = filename;
|
||||
d["data"] = data;
|
||||
return d;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void AudioStreamPlaybackSpeex::set_data(const Vector<uint8_t>& p_data) {
|
||||
|
||||
data=p_data;
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
void AudioStreamPlaybackSpeex::play(float p_from_pos) {
|
||||
|
||||
|
||||
|
||||
reload();
|
||||
if (!active)
|
||||
return;
|
||||
playing = true;
|
||||
|
||||
}
|
||||
void AudioStreamPlaybackSpeex::stop(){
|
||||
|
||||
|
||||
unload();
|
||||
playing = false;
|
||||
|
||||
}
|
||||
bool AudioStreamPlaybackSpeex::is_playing() const{
|
||||
|
||||
return playing;
|
||||
}
|
||||
|
||||
|
||||
void AudioStreamPlaybackSpeex::set_loop(bool p_enable){
|
||||
|
||||
loops = p_enable;
|
||||
}
|
||||
bool AudioStreamPlaybackSpeex::has_loop() const{
|
||||
|
||||
return loops;
|
||||
}
|
||||
|
||||
float AudioStreamPlaybackSpeex::get_length() const{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
String AudioStreamPlaybackSpeex::get_stream_name() const{
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
int AudioStreamPlaybackSpeex::get_loop_count() const{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
float AudioStreamPlaybackSpeex::get_pos() const{
|
||||
|
||||
return 0;
|
||||
}
|
||||
void AudioStreamPlaybackSpeex::seek_pos(float p_time){
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
AudioStreamPlaybackSpeex::AudioStreamPlaybackSpeex() {
|
||||
|
||||
active=false;
|
||||
st = NULL;
|
||||
stream_channels=1;
|
||||
stream_srate=1;
|
||||
stream_minbuff_size=1;
|
||||
playing=false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
AudioStreamPlaybackSpeex::~AudioStreamPlaybackSpeex() {
|
||||
|
||||
unload();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
void AudioStreamSpeex::set_file(const String& p_file) {
|
||||
|
||||
if (this->file == p_file)
|
||||
return;
|
||||
|
||||
this->file=p_file;
|
||||
|
||||
if (p_file == "") {
|
||||
data.resize(0);
|
||||
return;
|
||||
};
|
||||
|
||||
Error err;
|
||||
FileAccess* file = FileAccess::open(p_file, FileAccess::READ,&err);
|
||||
if (err != OK) {
|
||||
data.resize(0);
|
||||
};
|
||||
ERR_FAIL_COND(err != OK);
|
||||
|
||||
this->file = p_file;
|
||||
data.resize(file->get_len());
|
||||
int read = file->get_buffer(&data[0], data.size());
|
||||
memdelete(file);
|
||||
|
||||
}
|
||||
|
||||
RES ResourceFormatLoaderAudioStreamSpeex::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
AudioStreamSpeex *stream = memnew(AudioStreamSpeex);
|
||||
stream->set_file(p_path);
|
||||
return Ref<AudioStreamSpeex>(stream);
|
||||
}
|
||||
|
||||
void ResourceFormatLoaderAudioStreamSpeex::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("spx");
|
||||
}
|
||||
bool ResourceFormatLoaderAudioStreamSpeex::handles_type(const String& p_type) const {
|
||||
|
||||
return (p_type=="AudioStream" || p_type=="AudioStreamSpeex");
|
||||
}
|
||||
|
||||
String ResourceFormatLoaderAudioStreamSpeex::get_resource_type(const String &p_path) const {
|
||||
|
||||
if (p_path.extension().to_lower()=="spx")
|
||||
return "AudioStreamSpeex";
|
||||
return "";
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* audio_stream_speex.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef AUDIO_STREAM_SPEEX_H
|
||||
#define AUDIO_STREAM_SPEEX_H
|
||||
|
||||
#include "scene/resources/audio_stream.h"
|
||||
#include "speex/speex.h"
|
||||
#include "os/file_access.h"
|
||||
#include "io/resource_loader.h"
|
||||
#include "os/thread_safe.h"
|
||||
|
||||
#include <speex/speex.h>
|
||||
#include <speex/speex_header.h>
|
||||
#include <speex/speex_stereo.h>
|
||||
#include <speex/speex_callbacks.h>
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
class AudioStreamPlaybackSpeex : public AudioStreamPlayback {
|
||||
|
||||
OBJ_TYPE(AudioStreamPlaybackSpeex, AudioStreamPlayback);
|
||||
|
||||
|
||||
void *st;
|
||||
SpeexBits bits;
|
||||
Vector<uint8_t> data;
|
||||
int read_ofs;
|
||||
bool active;
|
||||
String filename;
|
||||
int loop_count;
|
||||
bool loops;
|
||||
int page_size;
|
||||
bool playing;
|
||||
bool packets_available;
|
||||
|
||||
void unload();
|
||||
void reload();
|
||||
|
||||
ogg_sync_state oy;
|
||||
ogg_page og;
|
||||
ogg_packet op;
|
||||
ogg_stream_state os;
|
||||
int nframes;
|
||||
int frame_size;
|
||||
int packet_no;
|
||||
|
||||
ogg_int64_t page_granule, last_granule;
|
||||
int skip_samples, page_nb_packets;
|
||||
int stream_channels;
|
||||
int stream_srate;
|
||||
int stream_minbuff_size;
|
||||
|
||||
void* process_header(ogg_packet *op, int *frame_size, int *rate, int *nframes, int *channels, int *extra_headers);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
protected:
|
||||
|
||||
//virtual bool _can_mix() const;
|
||||
|
||||
Dictionary _get_bundled() const;
|
||||
void _set_bundled(const Dictionary& dict);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
void set_data(const Vector<uint8_t>& p_data);
|
||||
|
||||
virtual void play(float p_from_pos=0);
|
||||
virtual void stop();
|
||||
virtual bool is_playing() const;
|
||||
|
||||
virtual void set_loop(bool p_enable);
|
||||
virtual bool has_loop() const;
|
||||
|
||||
virtual float get_length() const;
|
||||
|
||||
virtual String get_stream_name() const;
|
||||
|
||||
virtual int get_loop_count() const;
|
||||
|
||||
virtual float get_pos() const;
|
||||
virtual void seek_pos(float p_time);
|
||||
|
||||
virtual int get_channels() const { return stream_channels; }
|
||||
virtual int get_mix_rate() const { return stream_srate; }
|
||||
|
||||
virtual int get_minimum_buffer_size() const { return stream_minbuff_size; }
|
||||
virtual int mix(int16_t* p_bufer,int p_frames);
|
||||
|
||||
virtual void set_loop_restart_time(float p_time) { } //no loop restart, ignore
|
||||
|
||||
AudioStreamPlaybackSpeex();
|
||||
~AudioStreamPlaybackSpeex();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class AudioStreamSpeex : public AudioStream {
|
||||
|
||||
OBJ_TYPE(AudioStreamSpeex,AudioStream);
|
||||
|
||||
Vector<uint8_t> data;
|
||||
String file;
|
||||
public:
|
||||
|
||||
Ref<AudioStreamPlayback> instance_playback() {
|
||||
Ref<AudioStreamPlaybackSpeex> pb = memnew( AudioStreamPlaybackSpeex );
|
||||
pb->set_data(data);
|
||||
return pb;
|
||||
}
|
||||
|
||||
void set_file(const String& p_file);
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ResourceFormatLoaderAudioStreamSpeex : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
||||
};
|
||||
|
||||
#endif // AUDIO_STREAM_SPEEX_H
|
|
@ -1,372 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: speex_bits.c
|
||||
|
||||
Handles bit packing/unpacking
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
/* Maximum size of the bit-stream (for fixed-size allocation) */
|
||||
#ifndef MAX_CHARS_PER_FRAME
|
||||
#define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR)
|
||||
#endif
|
||||
|
||||
EXPORT void speex_bits_init(SpeexBits *bits)
|
||||
{
|
||||
bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);
|
||||
if (!bits->chars)
|
||||
return;
|
||||
|
||||
bits->buf_size = MAX_CHARS_PER_FRAME;
|
||||
|
||||
bits->owner=1;
|
||||
|
||||
speex_bits_reset(bits);
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
|
||||
{
|
||||
bits->chars = (char*)buff;
|
||||
bits->buf_size = buf_size;
|
||||
|
||||
bits->owner=0;
|
||||
|
||||
speex_bits_reset(bits);
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size)
|
||||
{
|
||||
bits->chars = (char*)buff;
|
||||
bits->buf_size = buf_size;
|
||||
|
||||
bits->owner=0;
|
||||
|
||||
bits->nbBits=buf_size<<LOG2_BITS_PER_CHAR;
|
||||
bits->charPtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_destroy(SpeexBits *bits)
|
||||
{
|
||||
if (bits->owner)
|
||||
speex_free(bits->chars);
|
||||
/* Will do something once the allocation is dynamic */
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_reset(SpeexBits *bits)
|
||||
{
|
||||
/* We only need to clear the first byte now */
|
||||
bits->chars[0]=0;
|
||||
bits->nbBits=0;
|
||||
bits->charPtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_rewind(SpeexBits *bits)
|
||||
{
|
||||
bits->charPtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
|
||||
{
|
||||
int i;
|
||||
int nchars = len / BYTES_PER_CHAR;
|
||||
if (nchars > bits->buf_size)
|
||||
{
|
||||
speex_notify("Packet is larger than allocated buffer");
|
||||
if (bits->owner)
|
||||
{
|
||||
char *tmp = (char*)speex_realloc(bits->chars, nchars);
|
||||
if (tmp)
|
||||
{
|
||||
bits->buf_size=nchars;
|
||||
bits->chars=tmp;
|
||||
} else {
|
||||
nchars=bits->buf_size;
|
||||
speex_warning("Could not resize input buffer: truncating input");
|
||||
}
|
||||
} else {
|
||||
speex_warning("Do not own input buffer: truncating oversize input");
|
||||
nchars=bits->buf_size;
|
||||
}
|
||||
}
|
||||
#if (BYTES_PER_CHAR==2)
|
||||
/* Swap bytes to proper endian order (could be done externally) */
|
||||
#define HTOLS(A) ((((A) >> 8)&0xff)|(((A) & 0xff)<<8))
|
||||
#else
|
||||
#define HTOLS(A) (A)
|
||||
#endif
|
||||
for (i=0;i<nchars;i++)
|
||||
bits->chars[i]=HTOLS(chars[i]);
|
||||
|
||||
bits->nbBits=nchars<<LOG2_BITS_PER_CHAR;
|
||||
bits->charPtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
static void speex_bits_flush(SpeexBits *bits)
|
||||
{
|
||||
int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
|
||||
if (bits->charPtr>0)
|
||||
SPEEX_MOVE(bits->chars, &bits->chars[bits->charPtr], nchars-bits->charPtr);
|
||||
bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;
|
||||
bits->charPtr=0;
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
|
||||
{
|
||||
int i,pos;
|
||||
int nchars = nbytes/BYTES_PER_CHAR;
|
||||
|
||||
if (((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)+nchars > bits->buf_size)
|
||||
{
|
||||
/* Packet is larger than allocated buffer */
|
||||
if (bits->owner)
|
||||
{
|
||||
char *tmp = (char*)speex_realloc(bits->chars, (bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1);
|
||||
if (tmp)
|
||||
{
|
||||
bits->buf_size=(bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1;
|
||||
bits->chars=tmp;
|
||||
} else {
|
||||
nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;
|
||||
speex_warning("Could not resize input buffer: truncating oversize input");
|
||||
}
|
||||
} else {
|
||||
speex_warning("Do not own input buffer: truncating oversize input");
|
||||
nchars=bits->buf_size;
|
||||
}
|
||||
}
|
||||
|
||||
speex_bits_flush(bits);
|
||||
pos=bits->nbBits>>LOG2_BITS_PER_CHAR;
|
||||
for (i=0;i<nchars;i++)
|
||||
bits->chars[pos+i]=HTOLS(chars[i]);
|
||||
bits->nbBits+=nchars<<LOG2_BITS_PER_CHAR;
|
||||
}
|
||||
|
||||
EXPORT int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
|
||||
{
|
||||
int i;
|
||||
int max_nchars = max_nbytes/BYTES_PER_CHAR;
|
||||
int charPtr, bitPtr, nbBits;
|
||||
|
||||
/* Insert terminator, but save the data so we can put it back after */
|
||||
bitPtr=bits->bitPtr;
|
||||
charPtr=bits->charPtr;
|
||||
nbBits=bits->nbBits;
|
||||
speex_bits_insert_terminator(bits);
|
||||
bits->bitPtr=bitPtr;
|
||||
bits->charPtr=charPtr;
|
||||
bits->nbBits=nbBits;
|
||||
|
||||
if (max_nchars > ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR))
|
||||
max_nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
|
||||
|
||||
for (i=0;i<max_nchars;i++)
|
||||
chars[i]=HTOLS(bits->chars[i]);
|
||||
return max_nchars*BYTES_PER_CHAR;
|
||||
}
|
||||
|
||||
EXPORT int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)
|
||||
{
|
||||
int max_nchars = max_nbytes/BYTES_PER_CHAR;
|
||||
int i;
|
||||
if (max_nchars > ((bits->nbBits)>>LOG2_BITS_PER_CHAR))
|
||||
max_nchars = ((bits->nbBits)>>LOG2_BITS_PER_CHAR);
|
||||
for (i=0;i<max_nchars;i++)
|
||||
chars[i]=HTOLS(bits->chars[i]);
|
||||
|
||||
if (bits->bitPtr>0)
|
||||
bits->chars[0]=bits->chars[max_nchars];
|
||||
else
|
||||
bits->chars[0]=0;
|
||||
bits->charPtr=0;
|
||||
bits->nbBits &= (BITS_PER_CHAR-1);
|
||||
return max_nchars*BYTES_PER_CHAR;
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
|
||||
{
|
||||
unsigned int d=data;
|
||||
|
||||
if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
|
||||
{
|
||||
speex_notify("Buffer too small to pack bits");
|
||||
if (bits->owner)
|
||||
{
|
||||
int new_nchars = ((bits->buf_size+5)*3)>>1;
|
||||
char *tmp = (char*)speex_realloc(bits->chars, new_nchars);
|
||||
if (tmp)
|
||||
{
|
||||
bits->buf_size=new_nchars;
|
||||
bits->chars=tmp;
|
||||
} else {
|
||||
speex_warning("Could not resize input buffer: not packing");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
speex_warning("Do not own input buffer: not packing");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while(nbBits)
|
||||
{
|
||||
int bit;
|
||||
bit = (d>>(nbBits-1))&1;
|
||||
bits->chars[bits->charPtr] |= bit<<(BITS_PER_CHAR-1-bits->bitPtr);
|
||||
bits->bitPtr++;
|
||||
|
||||
if (bits->bitPtr==BITS_PER_CHAR)
|
||||
{
|
||||
bits->bitPtr=0;
|
||||
bits->charPtr++;
|
||||
bits->chars[bits->charPtr] = 0;
|
||||
}
|
||||
bits->nbBits++;
|
||||
nbBits--;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
|
||||
/* If number is negative */
|
||||
if (d>>(nbBits-1))
|
||||
{
|
||||
d |= (-1)<<nbBits;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
EXPORT unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=0;
|
||||
if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
|
||||
bits->overflow=1;
|
||||
if (bits->overflow)
|
||||
return 0;
|
||||
while(nbBits)
|
||||
{
|
||||
d<<=1;
|
||||
d |= (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
|
||||
bits->bitPtr++;
|
||||
if (bits->bitPtr==BITS_PER_CHAR)
|
||||
{
|
||||
bits->bitPtr=0;
|
||||
bits->charPtr++;
|
||||
}
|
||||
nbBits--;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
EXPORT unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=0;
|
||||
int bitPtr, charPtr;
|
||||
char *chars;
|
||||
|
||||
if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
|
||||
bits->overflow=1;
|
||||
if (bits->overflow)
|
||||
return 0;
|
||||
|
||||
bitPtr=bits->bitPtr;
|
||||
charPtr=bits->charPtr;
|
||||
chars = bits->chars;
|
||||
while(nbBits)
|
||||
{
|
||||
d<<=1;
|
||||
d |= (chars[charPtr]>>(BITS_PER_CHAR-1 - bitPtr))&1;
|
||||
bitPtr++;
|
||||
if (bitPtr==BITS_PER_CHAR)
|
||||
{
|
||||
bitPtr=0;
|
||||
charPtr++;
|
||||
}
|
||||
nbBits--;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
EXPORT int speex_bits_peek(SpeexBits *bits)
|
||||
{
|
||||
if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)
|
||||
bits->overflow=1;
|
||||
if (bits->overflow)
|
||||
return 0;
|
||||
return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_advance(SpeexBits *bits, int n)
|
||||
{
|
||||
if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
|
||||
bits->overflow=1;
|
||||
return;
|
||||
}
|
||||
bits->charPtr += (bits->bitPtr+n) >> LOG2_BITS_PER_CHAR; /* divide by BITS_PER_CHAR */
|
||||
bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1); /* modulo by BITS_PER_CHAR */
|
||||
}
|
||||
|
||||
EXPORT int speex_bits_remaining(SpeexBits *bits)
|
||||
{
|
||||
if (bits->overflow)
|
||||
return -1;
|
||||
else
|
||||
return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);
|
||||
}
|
||||
|
||||
EXPORT int speex_bits_nbytes(SpeexBits *bits)
|
||||
{
|
||||
return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_insert_terminator(SpeexBits *bits)
|
||||
{
|
||||
if (bits->bitPtr)
|
||||
speex_bits_pack(bits, 0, 1);
|
||||
while (bits->bitPtr)
|
||||
speex_bits_pack(bits, 1, 1);
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
/* Copyright (C) 2007 Jean-Marc Valin
|
||||
|
||||
File: buffer.c
|
||||
This is a very simple ring buffer implementation. It is not thread-safe
|
||||
so you need to do your own locking.
|
||||
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
|
||||
#include "os_support.h"
|
||||
#include "arch.h"
|
||||
#include <speex/speex_buffer.h>
|
||||
|
||||
struct SpeexBuffer_ {
|
||||
char *data;
|
||||
int size;
|
||||
int read_ptr;
|
||||
int write_ptr;
|
||||
int available;
|
||||
};
|
||||
|
||||
EXPORT SpeexBuffer *speex_buffer_init(int size)
|
||||
{
|
||||
SpeexBuffer *st = speex_alloc(sizeof(SpeexBuffer));
|
||||
st->data = speex_alloc(size);
|
||||
st->size = size;
|
||||
st->read_ptr = 0;
|
||||
st->write_ptr = 0;
|
||||
st->available = 0;
|
||||
return st;
|
||||
}
|
||||
|
||||
EXPORT void speex_buffer_destroy(SpeexBuffer *st)
|
||||
{
|
||||
speex_free(st->data);
|
||||
speex_free(st);
|
||||
}
|
||||
|
||||
EXPORT int speex_buffer_write(SpeexBuffer *st, void *_data, int len)
|
||||
{
|
||||
int end;
|
||||
int end1;
|
||||
char *data = _data;
|
||||
if (len > st->size)
|
||||
{
|
||||
data += len-st->size;
|
||||
len = st->size;
|
||||
}
|
||||
end = st->write_ptr + len;
|
||||
end1 = end;
|
||||
if (end1 > st->size)
|
||||
end1 = st->size;
|
||||
SPEEX_COPY(st->data + st->write_ptr, data, end1 - st->write_ptr);
|
||||
if (end > st->size)
|
||||
{
|
||||
end -= st->size;
|
||||
SPEEX_COPY(st->data, data+end1 - st->write_ptr, end);
|
||||
}
|
||||
st->available += len;
|
||||
if (st->available > st->size)
|
||||
{
|
||||
st->available = st->size;
|
||||
st->read_ptr = st->write_ptr;
|
||||
}
|
||||
st->write_ptr += len;
|
||||
if (st->write_ptr > st->size)
|
||||
st->write_ptr -= st->size;
|
||||
return len;
|
||||
}
|
||||
|
||||
EXPORT int speex_buffer_writezeros(SpeexBuffer *st, int len)
|
||||
{
|
||||
/* This is almost the same as for speex_buffer_write() but using
|
||||
SPEEX_MEMSET() instead of SPEEX_COPY(). Update accordingly. */
|
||||
int end;
|
||||
int end1;
|
||||
if (len > st->size)
|
||||
{
|
||||
len = st->size;
|
||||
}
|
||||
end = st->write_ptr + len;
|
||||
end1 = end;
|
||||
if (end1 > st->size)
|
||||
end1 = st->size;
|
||||
SPEEX_MEMSET(st->data + st->write_ptr, 0, end1 - st->write_ptr);
|
||||
if (end > st->size)
|
||||
{
|
||||
end -= st->size;
|
||||
SPEEX_MEMSET(st->data, 0, end);
|
||||
}
|
||||
st->available += len;
|
||||
if (st->available > st->size)
|
||||
{
|
||||
st->available = st->size;
|
||||
st->read_ptr = st->write_ptr;
|
||||
}
|
||||
st->write_ptr += len;
|
||||
if (st->write_ptr > st->size)
|
||||
st->write_ptr -= st->size;
|
||||
return len;
|
||||
}
|
||||
|
||||
EXPORT int speex_buffer_read(SpeexBuffer *st, void *_data, int len)
|
||||
{
|
||||
int end, end1;
|
||||
char *data = _data;
|
||||
if (len > st->available)
|
||||
{
|
||||
SPEEX_MEMSET(data+st->available, 0, st->size-st->available);
|
||||
len = st->available;
|
||||
}
|
||||
end = st->read_ptr + len;
|
||||
end1 = end;
|
||||
if (end1 > st->size)
|
||||
end1 = st->size;
|
||||
SPEEX_COPY(data, st->data + st->read_ptr, end1 - st->read_ptr);
|
||||
|
||||
if (end > st->size)
|
||||
{
|
||||
end -= st->size;
|
||||
SPEEX_COPY(data+end1 - st->read_ptr, st->data, end);
|
||||
}
|
||||
st->available -= len;
|
||||
st->read_ptr += len;
|
||||
if (st->read_ptr > st->size)
|
||||
st->read_ptr -= st->size;
|
||||
return len;
|
||||
}
|
||||
|
||||
EXPORT int speex_buffer_get_available(SpeexBuffer *st)
|
||||
{
|
||||
return st->available;
|
||||
}
|
||||
|
||||
EXPORT int speex_buffer_resize(SpeexBuffer *st, int len)
|
||||
{
|
||||
int old_len = st->size;
|
||||
if (len > old_len)
|
||||
{
|
||||
st->data = speex_realloc(st->data, len);
|
||||
/* FIXME: move data/pointers properly for growing the buffer */
|
||||
} else {
|
||||
/* FIXME: move data/pointers properly for shrinking the buffer */
|
||||
st->data = speex_realloc(st->data, len);
|
||||
}
|
||||
return len;
|
||||
}
|
|
@ -1,612 +0,0 @@
|
|||
/* Copyright (C) 2002-2006 Jean-Marc Valin
|
||||
File: cb_search.c
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "cb_search.h"
|
||||
#include "filters.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "vq.h"
|
||||
#include "arch.h"
|
||||
#include "math_approx.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#include "cb_search_sse.h"
|
||||
#elif defined(ARM4_ASM) || defined(ARM5E_ASM)
|
||||
#include "cb_search_arm4.h"
|
||||
#elif defined(BFIN_ASM)
|
||||
#include "cb_search_bfin.h"
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
|
||||
static void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
|
||||
{
|
||||
int i, j, k;
|
||||
VARDECL(spx_word16_t *shape);
|
||||
ALLOC(shape, subvect_size, spx_word16_t);
|
||||
for (i=0;i<shape_cb_size;i++)
|
||||
{
|
||||
spx_word16_t *res;
|
||||
|
||||
res = resp+i*subvect_size;
|
||||
for (k=0;k<subvect_size;k++)
|
||||
shape[k] = (spx_word16_t)shape_cb[i*subvect_size+k];
|
||||
E[i]=0;
|
||||
|
||||
/* Compute codeword response using convolution with impulse response */
|
||||
for(j=0;j<subvect_size;j++)
|
||||
{
|
||||
spx_word32_t resj=0;
|
||||
spx_word16_t res16;
|
||||
for (k=0;k<=j;k++)
|
||||
resj = MAC16_16(resj,shape[k],r[j-k]);
|
||||
#ifdef FIXED_POINT
|
||||
res16 = EXTRACT16(SHR32(resj, 13));
|
||||
#else
|
||||
res16 = 0.03125f*resj;
|
||||
#endif
|
||||
/* Compute codeword energy */
|
||||
E[i]=MAC16_16(E[i],res16,res16);
|
||||
res[j] = res16;
|
||||
/*printf ("%d\n", (int)res[j]);*/
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_TARGET_UPDATE
|
||||
static SPEEX_INLINE void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len)
|
||||
{
|
||||
int n;
|
||||
for (n=0;n<len;n++)
|
||||
t[n] = SUB16(t[n],PSHR32(MULT16_16(g,r[n]),13));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void split_cb_search_shape_sign_N1(
|
||||
spx_word16_t target[], /* target vector */
|
||||
spx_coef_t ak[], /* LPCs for this subframe */
|
||||
spx_coef_t awk1[], /* Weighted LPCs for this subframe */
|
||||
spx_coef_t awk2[], /* Weighted LPCs for this subframe */
|
||||
const void *par, /* Codebook/search parameters*/
|
||||
int p, /* number of LPC coeffs */
|
||||
int nsf, /* number of samples in subframe */
|
||||
spx_sig_t *exc,
|
||||
spx_word16_t *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int update_target
|
||||
)
|
||||
{
|
||||
int i,j,m,q;
|
||||
VARDECL(spx_word16_t *resp);
|
||||
#ifdef _USE_SSE
|
||||
VARDECL(__m128 *resp2);
|
||||
VARDECL(__m128 *E);
|
||||
#else
|
||||
spx_word16_t *resp2;
|
||||
VARDECL(spx_word32_t *E);
|
||||
#endif
|
||||
VARDECL(spx_word16_t *t);
|
||||
VARDECL(spx_sig_t *e);
|
||||
const signed char *shape_cb;
|
||||
int shape_cb_size, subvect_size, nb_subvect;
|
||||
const split_cb_params *params;
|
||||
int best_index;
|
||||
spx_word32_t best_dist;
|
||||
int have_sign;
|
||||
|
||||
params = (const split_cb_params *) par;
|
||||
subvect_size = params->subvect_size;
|
||||
nb_subvect = params->nb_subvect;
|
||||
shape_cb_size = 1<<params->shape_bits;
|
||||
shape_cb = params->shape_cb;
|
||||
have_sign = params->have_sign;
|
||||
ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);
|
||||
#ifdef _USE_SSE
|
||||
ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);
|
||||
ALLOC(E, shape_cb_size>>2, __m128);
|
||||
#else
|
||||
resp2 = resp;
|
||||
ALLOC(E, shape_cb_size, spx_word32_t);
|
||||
#endif
|
||||
ALLOC(t, nsf, spx_word16_t);
|
||||
ALLOC(e, nsf, spx_sig_t);
|
||||
|
||||
/* FIXME: Do we still need to copy the target? */
|
||||
SPEEX_COPY(t, target, nsf);
|
||||
|
||||
compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
|
||||
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
spx_word16_t *x=t+subvect_size*i;
|
||||
/*Find new n-best based on previous n-best j*/
|
||||
if (have_sign)
|
||||
vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
|
||||
else
|
||||
vq_nbest(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
|
||||
|
||||
speex_bits_pack(bits,best_index,params->shape_bits+have_sign);
|
||||
|
||||
{
|
||||
int rind;
|
||||
spx_word16_t *res;
|
||||
spx_word16_t sign=1;
|
||||
rind = best_index;
|
||||
if (rind>=shape_cb_size)
|
||||
{
|
||||
sign=-1;
|
||||
rind-=shape_cb_size;
|
||||
}
|
||||
res = resp+rind*subvect_size;
|
||||
if (sign>0)
|
||||
for (m=0;m<subvect_size;m++)
|
||||
t[subvect_size*i+m] = SUB16(t[subvect_size*i+m], res[m]);
|
||||
else
|
||||
for (m=0;m<subvect_size;m++)
|
||||
t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
if (sign==1)
|
||||
{
|
||||
for (j=0;j<subvect_size;j++)
|
||||
e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
|
||||
} else {
|
||||
for (j=0;j<subvect_size;j++)
|
||||
e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));
|
||||
}
|
||||
#else
|
||||
for (j=0;j<subvect_size;j++)
|
||||
e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
for (m=0;m<subvect_size;m++)
|
||||
{
|
||||
spx_word16_t g;
|
||||
int rind;
|
||||
spx_word16_t sign=1;
|
||||
rind = best_index;
|
||||
if (rind>=shape_cb_size)
|
||||
{
|
||||
sign=-1;
|
||||
rind-=shape_cb_size;
|
||||
}
|
||||
|
||||
q=subvect_size-m;
|
||||
#ifdef FIXED_POINT
|
||||
g=sign*shape_cb[rind*subvect_size+m];
|
||||
#else
|
||||
g=sign*0.03125*shape_cb[rind*subvect_size+m];
|
||||
#endif
|
||||
target_update(t+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));
|
||||
}
|
||||
}
|
||||
|
||||
/* Update excitation */
|
||||
/* FIXME: We could update the excitation directly above */
|
||||
for (j=0;j<nsf;j++)
|
||||
exc[j]=ADD32(exc[j],e[j]);
|
||||
|
||||
/* Update target: only update target if necessary */
|
||||
if (update_target)
|
||||
{
|
||||
VARDECL(spx_word16_t *r2);
|
||||
ALLOC(r2, nsf, spx_word16_t);
|
||||
for (j=0;j<nsf;j++)
|
||||
r2[j] = EXTRACT16(PSHR32(e[j] ,6));
|
||||
syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);
|
||||
for (j=0;j<nsf;j++)
|
||||
target[j]=SUB16(target[j],PSHR16(r2[j],2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void split_cb_search_shape_sign(
|
||||
spx_word16_t target[], /* target vector */
|
||||
spx_coef_t ak[], /* LPCs for this subframe */
|
||||
spx_coef_t awk1[], /* Weighted LPCs for this subframe */
|
||||
spx_coef_t awk2[], /* Weighted LPCs for this subframe */
|
||||
const void *par, /* Codebook/search parameters*/
|
||||
int p, /* number of LPC coeffs */
|
||||
int nsf, /* number of samples in subframe */
|
||||
spx_sig_t *exc,
|
||||
spx_word16_t *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity,
|
||||
int update_target
|
||||
)
|
||||
{
|
||||
int i,j,k,m,n,q;
|
||||
VARDECL(spx_word16_t *resp);
|
||||
#ifdef _USE_SSE
|
||||
VARDECL(__m128 *resp2);
|
||||
VARDECL(__m128 *E);
|
||||
#else
|
||||
spx_word16_t *resp2;
|
||||
VARDECL(spx_word32_t *E);
|
||||
#endif
|
||||
VARDECL(spx_word16_t *t);
|
||||
VARDECL(spx_sig_t *e);
|
||||
VARDECL(spx_word16_t *tmp);
|
||||
VARDECL(spx_word32_t *ndist);
|
||||
VARDECL(spx_word32_t *odist);
|
||||
VARDECL(int *itmp);
|
||||
VARDECL(spx_word16_t **ot2);
|
||||
VARDECL(spx_word16_t **nt2);
|
||||
spx_word16_t **ot, **nt;
|
||||
VARDECL(int **nind);
|
||||
VARDECL(int **oind);
|
||||
VARDECL(int *ind);
|
||||
const signed char *shape_cb;
|
||||
int shape_cb_size, subvect_size, nb_subvect;
|
||||
const split_cb_params *params;
|
||||
int N=2;
|
||||
VARDECL(int *best_index);
|
||||
VARDECL(spx_word32_t *best_dist);
|
||||
VARDECL(int *best_nind);
|
||||
VARDECL(int *best_ntarget);
|
||||
int have_sign;
|
||||
N=complexity;
|
||||
if (N>10)
|
||||
N=10;
|
||||
/* Complexity isn't as important for the codebooks as it is for the pitch */
|
||||
N=(2*N)/3;
|
||||
if (N<1)
|
||||
N=1;
|
||||
if (N==1)
|
||||
{
|
||||
split_cb_search_shape_sign_N1(target,ak,awk1,awk2,par,p,nsf,exc,r,bits,stack,update_target);
|
||||
return;
|
||||
}
|
||||
ALLOC(ot2, N, spx_word16_t*);
|
||||
ALLOC(nt2, N, spx_word16_t*);
|
||||
ALLOC(oind, N, int*);
|
||||
ALLOC(nind, N, int*);
|
||||
|
||||
params = (const split_cb_params *) par;
|
||||
subvect_size = params->subvect_size;
|
||||
nb_subvect = params->nb_subvect;
|
||||
shape_cb_size = 1<<params->shape_bits;
|
||||
shape_cb = params->shape_cb;
|
||||
have_sign = params->have_sign;
|
||||
ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);
|
||||
#ifdef _USE_SSE
|
||||
ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);
|
||||
ALLOC(E, shape_cb_size>>2, __m128);
|
||||
#else
|
||||
resp2 = resp;
|
||||
ALLOC(E, shape_cb_size, spx_word32_t);
|
||||
#endif
|
||||
ALLOC(t, nsf, spx_word16_t);
|
||||
ALLOC(e, nsf, spx_sig_t);
|
||||
ALLOC(ind, nb_subvect, int);
|
||||
|
||||
ALLOC(tmp, 2*N*nsf, spx_word16_t);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
ot2[i]=tmp+2*i*nsf;
|
||||
nt2[i]=tmp+(2*i+1)*nsf;
|
||||
}
|
||||
ot=ot2;
|
||||
nt=nt2;
|
||||
ALLOC(best_index, N, int);
|
||||
ALLOC(best_dist, N, spx_word32_t);
|
||||
ALLOC(best_nind, N, int);
|
||||
ALLOC(best_ntarget, N, int);
|
||||
ALLOC(ndist, N, spx_word32_t);
|
||||
ALLOC(odist, N, spx_word32_t);
|
||||
|
||||
ALLOC(itmp, 2*N*nb_subvect, int);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
nind[i]=itmp+2*i*nb_subvect;
|
||||
oind[i]=itmp+(2*i+1)*nb_subvect;
|
||||
}
|
||||
|
||||
SPEEX_COPY(t, target, nsf);
|
||||
|
||||
for (j=0;j<N;j++)
|
||||
SPEEX_COPY(&ot[j][0], t, nsf);
|
||||
|
||||
/* Pre-compute codewords response and energy */
|
||||
compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
|
||||
|
||||
for (j=0;j<N;j++)
|
||||
odist[j]=0;
|
||||
|
||||
/*For all subvectors*/
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
/*"erase" nbest list*/
|
||||
for (j=0;j<N;j++)
|
||||
ndist[j]=VERY_LARGE32;
|
||||
/* This is not strictly necessary, but it provides an additonal safety
|
||||
to prevent crashes in case something goes wrong in the previous
|
||||
steps (e.g. NaNs) */
|
||||
for (j=0;j<N;j++)
|
||||
best_nind[j] = best_ntarget[j] = 0;
|
||||
/*For all n-bests of previous subvector*/
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
spx_word16_t *x=ot[j]+subvect_size*i;
|
||||
spx_word32_t tener = 0;
|
||||
for (m=0;m<subvect_size;m++)
|
||||
tener = MAC16_16(tener, x[m],x[m]);
|
||||
#ifdef FIXED_POINT
|
||||
tener = SHR32(tener,1);
|
||||
#else
|
||||
tener *= .5;
|
||||
#endif
|
||||
/*Find new n-best based on previous n-best j*/
|
||||
if (have_sign)
|
||||
vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
|
||||
else
|
||||
vq_nbest(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
|
||||
|
||||
/*For all new n-bests*/
|
||||
for (k=0;k<N;k++)
|
||||
{
|
||||
/* Compute total distance (including previous sub-vectors */
|
||||
spx_word32_t err = ADD32(ADD32(odist[j],best_dist[k]),tener);
|
||||
|
||||
/*update n-best list*/
|
||||
if (err<ndist[N-1])
|
||||
{
|
||||
for (m=0;m<N;m++)
|
||||
{
|
||||
if (err < ndist[m])
|
||||
{
|
||||
for (n=N-1;n>m;n--)
|
||||
{
|
||||
ndist[n] = ndist[n-1];
|
||||
best_nind[n] = best_nind[n-1];
|
||||
best_ntarget[n] = best_ntarget[n-1];
|
||||
}
|
||||
/* n is equal to m here, so they're interchangeable */
|
||||
ndist[m] = err;
|
||||
best_nind[n] = best_index[k];
|
||||
best_ntarget[n] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i==0)
|
||||
break;
|
||||
}
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
/*previous target (we don't care what happened before*/
|
||||
for (m=(i+1)*subvect_size;m<nsf;m++)
|
||||
nt[j][m]=ot[best_ntarget[j]][m];
|
||||
|
||||
/* New code: update the rest of the target only if it's worth it */
|
||||
for (m=0;m<subvect_size;m++)
|
||||
{
|
||||
spx_word16_t g;
|
||||
int rind;
|
||||
spx_word16_t sign=1;
|
||||
rind = best_nind[j];
|
||||
if (rind>=shape_cb_size)
|
||||
{
|
||||
sign=-1;
|
||||
rind-=shape_cb_size;
|
||||
}
|
||||
|
||||
q=subvect_size-m;
|
||||
#ifdef FIXED_POINT
|
||||
g=sign*shape_cb[rind*subvect_size+m];
|
||||
#else
|
||||
g=sign*0.03125*shape_cb[rind*subvect_size+m];
|
||||
#endif
|
||||
target_update(nt[j]+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));
|
||||
}
|
||||
|
||||
for (q=0;q<nb_subvect;q++)
|
||||
nind[j][q]=oind[best_ntarget[j]][q];
|
||||
nind[j][i]=best_nind[j];
|
||||
}
|
||||
|
||||
/*update old-new data*/
|
||||
/* just swap pointers instead of a long copy */
|
||||
{
|
||||
spx_word16_t **tmp2;
|
||||
tmp2=ot;
|
||||
ot=nt;
|
||||
nt=tmp2;
|
||||
}
|
||||
for (j=0;j<N;j++)
|
||||
for (m=0;m<nb_subvect;m++)
|
||||
oind[j][m]=nind[j][m];
|
||||
for (j=0;j<N;j++)
|
||||
odist[j]=ndist[j];
|
||||
}
|
||||
|
||||
/*save indices*/
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
ind[i]=nind[0][i];
|
||||
speex_bits_pack(bits,ind[i],params->shape_bits+have_sign);
|
||||
}
|
||||
|
||||
/* Put everything back together */
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
int rind;
|
||||
spx_word16_t sign=1;
|
||||
rind = ind[i];
|
||||
if (rind>=shape_cb_size)
|
||||
{
|
||||
sign=-1;
|
||||
rind-=shape_cb_size;
|
||||
}
|
||||
#ifdef FIXED_POINT
|
||||
if (sign==1)
|
||||
{
|
||||
for (j=0;j<subvect_size;j++)
|
||||
e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
|
||||
} else {
|
||||
for (j=0;j<subvect_size;j++)
|
||||
e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));
|
||||
}
|
||||
#else
|
||||
for (j=0;j<subvect_size;j++)
|
||||
e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
|
||||
#endif
|
||||
}
|
||||
/* Update excitation */
|
||||
for (j=0;j<nsf;j++)
|
||||
exc[j]=ADD32(exc[j],e[j]);
|
||||
|
||||
/* Update target: only update target if necessary */
|
||||
if (update_target)
|
||||
{
|
||||
VARDECL(spx_word16_t *r2);
|
||||
ALLOC(r2, nsf, spx_word16_t);
|
||||
for (j=0;j<nsf;j++)
|
||||
r2[j] = EXTRACT16(PSHR32(e[j] ,6));
|
||||
syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);
|
||||
for (j=0;j<nsf;j++)
|
||||
target[j]=SUB16(target[j],PSHR16(r2[j],2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void split_cb_shape_sign_unquant(
|
||||
spx_sig_t *exc,
|
||||
const void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
spx_int32_t *seed
|
||||
)
|
||||
{
|
||||
int i,j;
|
||||
VARDECL(int *ind);
|
||||
VARDECL(int *signs);
|
||||
const signed char *shape_cb;
|
||||
int shape_cb_size, subvect_size, nb_subvect;
|
||||
const split_cb_params *params;
|
||||
int have_sign;
|
||||
|
||||
params = (const split_cb_params *) par;
|
||||
subvect_size = params->subvect_size;
|
||||
nb_subvect = params->nb_subvect;
|
||||
shape_cb_size = 1<<params->shape_bits;
|
||||
shape_cb = params->shape_cb;
|
||||
have_sign = params->have_sign;
|
||||
|
||||
ALLOC(ind, nb_subvect, int);
|
||||
ALLOC(signs, nb_subvect, int);
|
||||
|
||||
/* Decode codewords and gains */
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
if (have_sign)
|
||||
signs[i] = speex_bits_unpack_unsigned(bits, 1);
|
||||
else
|
||||
signs[i] = 0;
|
||||
ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits);
|
||||
}
|
||||
/* Compute decoded excitation */
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
spx_word16_t s=1;
|
||||
if (signs[i])
|
||||
s=-1;
|
||||
#ifdef FIXED_POINT
|
||||
if (s==1)
|
||||
{
|
||||
for (j=0;j<subvect_size;j++)
|
||||
exc[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5);
|
||||
} else {
|
||||
for (j=0;j<subvect_size;j++)
|
||||
exc[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5));
|
||||
}
|
||||
#else
|
||||
for (j=0;j<subvect_size;j++)
|
||||
exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void noise_codebook_quant(
|
||||
spx_word16_t target[], /* target vector */
|
||||
spx_coef_t ak[], /* LPCs for this subframe */
|
||||
spx_coef_t awk1[], /* Weighted LPCs for this subframe */
|
||||
spx_coef_t awk2[], /* Weighted LPCs for this subframe */
|
||||
const void *par, /* Codebook/search parameters*/
|
||||
int p, /* number of LPC coeffs */
|
||||
int nsf, /* number of samples in subframe */
|
||||
spx_sig_t *exc,
|
||||
spx_word16_t *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity,
|
||||
int update_target
|
||||
)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_word16_t *tmp);
|
||||
ALLOC(tmp, nsf, spx_word16_t);
|
||||
residue_percep_zero16(target, ak, awk1, awk2, tmp, nsf, p, stack);
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]+=SHL32(EXTEND32(tmp[i]),8);
|
||||
SPEEX_MEMSET(target, 0, nsf);
|
||||
}
|
||||
|
||||
|
||||
void noise_codebook_unquant(
|
||||
spx_sig_t *exc,
|
||||
const void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
spx_int32_t *seed
|
||||
)
|
||||
{
|
||||
int i;
|
||||
/* FIXME: This is bad, but I don't think the function ever gets called anyway */
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]=SHL32(EXTEND32(speex_rand(1, seed)),SIG_SHIFT);
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin & David Rowe */
|
||||
/**
|
||||
@file cb_search.h
|
||||
@brief Overlapped codebook search
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CB_SEARCH_H
|
||||
#define CB_SEARCH_H
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "arch.h"
|
||||
|
||||
/** Split codebook parameters. */
|
||||
typedef struct split_cb_params {
|
||||
int subvect_size;
|
||||
int nb_subvect;
|
||||
const signed char *shape_cb;
|
||||
int shape_bits;
|
||||
int have_sign;
|
||||
} split_cb_params;
|
||||
|
||||
|
||||
void split_cb_search_shape_sign(
|
||||
spx_word16_t target[], /* target vector */
|
||||
spx_coef_t ak[], /* LPCs for this subframe */
|
||||
spx_coef_t awk1[], /* Weighted LPCs for this subframe */
|
||||
spx_coef_t awk2[], /* Weighted LPCs for this subframe */
|
||||
const void *par, /* Codebook/search parameters */
|
||||
int p, /* number of LPC coeffs */
|
||||
int nsf, /* number of samples in subframe */
|
||||
spx_sig_t *exc,
|
||||
spx_word16_t *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity,
|
||||
int update_target
|
||||
);
|
||||
|
||||
void split_cb_shape_sign_unquant(
|
||||
spx_sig_t *exc,
|
||||
const void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
spx_int32_t *seed
|
||||
);
|
||||
|
||||
|
||||
void noise_codebook_quant(
|
||||
spx_word16_t target[], /* target vector */
|
||||
spx_coef_t ak[], /* LPCs for this subframe */
|
||||
spx_coef_t awk1[], /* Weighted LPCs for this subframe */
|
||||
spx_coef_t awk2[], /* Weighted LPCs for this subframe */
|
||||
const void *par, /* Codebook/search parameters */
|
||||
int p, /* number of LPC coeffs */
|
||||
int nsf, /* number of samples in subframe */
|
||||
spx_sig_t *exc,
|
||||
spx_word16_t *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity,
|
||||
int update_target
|
||||
);
|
||||
|
||||
|
||||
void noise_codebook_unquant(
|
||||
spx_sig_t *exc,
|
||||
const void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
spx_int32_t *seed
|
||||
);
|
||||
|
||||
#endif
|
|
@ -1,137 +0,0 @@
|
|||
/* Copyright (C) 2004 Jean-Marc Valin */
|
||||
/**
|
||||
@file cb_search_arm4.h
|
||||
@brief Fixed codebook functions (ARM4 version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This optimization is temporaly disabled until it is fixed to account for the fact
|
||||
that "r" is now a 16-bit array */
|
||||
#if 0
|
||||
#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
|
||||
static void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
|
||||
{
|
||||
int i, j, k;
|
||||
//const signed char *shape;
|
||||
for (i=0;i<shape_cb_size;i+=4)
|
||||
{
|
||||
|
||||
//shape = shape_cb;
|
||||
E[0]=0;
|
||||
E[1]=0;
|
||||
E[2]=0;
|
||||
E[3]=0;
|
||||
|
||||
/* Compute codeword response using convolution with impulse response */
|
||||
for(j=0;j<subvect_size;j++)
|
||||
{
|
||||
#if 1
|
||||
spx_word16_t *res;
|
||||
res = resp+j;
|
||||
spx_word32_t resj0,resj1,resj2,resj3;
|
||||
spx_word32_t dead1, dead2, dead3, dead4, dead5, dead6, dead7, dead8;
|
||||
__asm__ __volatile__ (
|
||||
"mov %0, #0 \n\t"
|
||||
"mov %1, #0 \n\t"
|
||||
"mov %2, #0 \n\t"
|
||||
"mov %3, #0 \n\t"
|
||||
".weighted%=: \n\t"
|
||||
"ldrsb %8, [%6] \n\t"
|
||||
"ldr %10, [%5], #-4 \n\t"
|
||||
"mov %9, %6 \n\t"
|
||||
"ldrsb %11, [%9, %7]! \n\t"
|
||||
"mla %0, %10, %8, %0 \n\t"
|
||||
"ldrsb %8, [%9, %7]! \n\t"
|
||||
"mla %1, %10, %11, %1 \n\t"
|
||||
"ldrsb %11, [%9, %7]! \n\t"
|
||||
"mla %2, %10, %8, %2 \n\t"
|
||||
"subs %4, %4, #1 \n\t"
|
||||
"mla %3, %10, %11, %3 \n\t"
|
||||
"add %6, %6, #1 \n\t"
|
||||
"bne .weighted%= \n\t"
|
||||
: "=r" (resj0), "=r" (resj1), "=r" (resj2), "=r" (resj3),
|
||||
"=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
|
||||
"=r" (dead5), "=r" (dead6), "=r" (dead7), "=r" (dead8)
|
||||
: "4" (j+1), "5" (r+j), "6" (shape_cb), "7" (subvect_size)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
spx_word16_t *res;
|
||||
res = resp+j;
|
||||
spx_word32_t resj0=0;
|
||||
spx_word32_t resj1=0;
|
||||
spx_word32_t resj2=0;
|
||||
spx_word32_t resj3=0;
|
||||
for (k=0;k<=j;k++)
|
||||
{
|
||||
const signed char *shape=shape_cb+k;
|
||||
resj0 = MAC16_16(resj0,*shape,r[j-k]);
|
||||
shape += subvect_size;
|
||||
resj1 = MAC16_16(resj1,*shape,r[j-k]);
|
||||
shape += subvect_size;
|
||||
resj2 = MAC16_16(resj2,*shape,r[j-k]);
|
||||
shape += subvect_size;
|
||||
resj3 = MAC16_16(resj3,*shape,r[j-k]);
|
||||
shape += subvect_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
resj0 = SHR(resj0, 11);
|
||||
resj1 = SHR(resj1, 11);
|
||||
resj2 = SHR(resj2, 11);
|
||||
resj3 = SHR(resj3, 11);
|
||||
#else
|
||||
resj0 *= 0.03125;
|
||||
resj1 *= 0.03125;
|
||||
resj2 *= 0.03125;
|
||||
resj3 *= 0.03125;
|
||||
#endif
|
||||
|
||||
/* Compute codeword energy */
|
||||
E[0]=ADD32(E[0],MULT16_16(resj0,resj0));
|
||||
E[1]=ADD32(E[1],MULT16_16(resj1,resj1));
|
||||
E[2]=ADD32(E[2],MULT16_16(resj2,resj2));
|
||||
E[3]=ADD32(E[3],MULT16_16(resj3,resj3));
|
||||
*res = resj0;
|
||||
res += subvect_size;
|
||||
*res = resj1;
|
||||
res += subvect_size;
|
||||
*res = resj2;
|
||||
res += subvect_size;
|
||||
*res = resj3;
|
||||
res += subvect_size;
|
||||
}
|
||||
resp += subvect_size<<2;
|
||||
shape_cb += subvect_size<<2;
|
||||
E+=4;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
|
@ -1,112 +0,0 @@
|
|||
/* Copyright (C) 2005 Analog Devices */
|
||||
/**
|
||||
@author Jean-Marc Valin
|
||||
@file cb_search_bfin.h
|
||||
@brief Fixed codebook functions (Blackfin version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
|
||||
void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<shape_cb_size;i++)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"P0 = %0;\n\t"
|
||||
"LC0 = P0;\n\t"
|
||||
"P1 = %1;\n\t"
|
||||
"P2 = %2;\n\t"
|
||||
"P3 = %3;\n\t"
|
||||
"P0 = 1;\n\t"
|
||||
"L0 = 0;\n\t"
|
||||
"L1 = 0;\n\t"
|
||||
"R2 = 0;\n\t"
|
||||
"A1 = 0;\n\t"
|
||||
"LOOP outter%= LC0;\n\t"
|
||||
"LOOP_BEGIN outter%=;\n\t"
|
||||
"A0 = 0;\n\t"
|
||||
"P4 = P1;\n\t"
|
||||
"I1 = P2;\n\t"
|
||||
"R0 = B[P4++] (X) || R1.L = W[I1--];\n\t"
|
||||
"LOOP inner%= LC1 = P0;\n\t"
|
||||
"LOOP_BEGIN inner%=;\n\t"
|
||||
"A0 += R0.L*R1.L (IS) || R0 = B[P4++] (X) || R1.L = W[I1--];\n\t"
|
||||
"LOOP_END inner%=;\n\t"
|
||||
"R0 = A0;\n\t"
|
||||
"R0 >>>= 13;\n\t"
|
||||
"A1 += R0.L*R0.L (IS);\n\t"
|
||||
"W[P3++] = R0;\n\t"
|
||||
"P0 += 1;\n\t"
|
||||
"P2 += 2;\n\t"
|
||||
"LOOP_END outter%=;\n\t"
|
||||
"P4 = %4;\n\t"
|
||||
"R1 = A1;\n\t"
|
||||
"[P4] = R1;\n\t"
|
||||
:
|
||||
: "m" (subvect_size), "m" (shape_cb), "m" (r), "m" (resp), "m" (E)
|
||||
: "A0", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "I0", "I1", "L0",
|
||||
"L1", "A0", "A1", "memory"
|
||||
#if !(__GNUC__ == 3)
|
||||
, "LC0", "LC1" /* gcc 3.4 doesn't know about LC registers */
|
||||
#endif
|
||||
);
|
||||
shape_cb += subvect_size;
|
||||
resp += subvect_size;
|
||||
E++;
|
||||
}
|
||||
}
|
||||
|
||||
#define OVERRIDE_TARGET_UPDATE
|
||||
static inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len)
|
||||
{
|
||||
if (!len)
|
||||
return;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"I0 = %0;\n\t"
|
||||
"I1 = %1;\n\t"
|
||||
"L0 = 0;\n\t"
|
||||
"L1 = 0;\n\t"
|
||||
"R2 = 4096;\n\t"
|
||||
"LOOP tupdate%= LC0 = %3;\n\t"
|
||||
"LOOP_BEGIN tupdate%=;\n\t"
|
||||
"R0.L = W[I0] || R1.L = W[I1++];\n\t"
|
||||
"R1 = (A1 = R1.L*%2.L) (IS);\n\t"
|
||||
"R1 = R1 + R2;\n\t"
|
||||
"R1 >>>= 13;\n\t"
|
||||
"R0.L = R0.L - R1.L;\n\t"
|
||||
"W[I0++] = R0.L;\n\t"
|
||||
"LOOP_END tupdate%=;\n\t"
|
||||
:
|
||||
: "a" (t), "a" (r), "d" (g), "a" (len)
|
||||
: "R0", "R1", "R2", "A1", "I0", "I1", "L0", "L1"
|
||||
);
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/* Copyright (C) 2004 Jean-Marc Valin */
|
||||
/**
|
||||
@file cb_search_sse.h
|
||||
@brief Fixed codebook functions (SSE version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
static inline void _spx_mm_getr_ps (__m128 U, float *__Z, float *__Y, float *__X, float *__W)
|
||||
{
|
||||
union {
|
||||
float __a[4];
|
||||
__m128 __v;
|
||||
} __u;
|
||||
|
||||
__u.__v = U;
|
||||
|
||||
*__Z = __u.__a[0];
|
||||
*__Y = __u.__a[1];
|
||||
*__X = __u.__a[2];
|
||||
*__W = __u.__a[3];
|
||||
|
||||
}
|
||||
|
||||
#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
|
||||
static void compute_weighted_codebook(const signed char *shape_cb, const spx_sig_t *_r, float *resp, __m128 *resp2, __m128 *E, int shape_cb_size, int subvect_size, char *stack)
|
||||
{
|
||||
int i, j, k;
|
||||
__m128 resj, EE;
|
||||
VARDECL(__m128 *r);
|
||||
VARDECL(__m128 *shape);
|
||||
ALLOC(r, subvect_size, __m128);
|
||||
ALLOC(shape, subvect_size, __m128);
|
||||
for(j=0;j<subvect_size;j++)
|
||||
r[j] = _mm_load_ps1(_r+j);
|
||||
for (i=0;i<shape_cb_size;i+=4)
|
||||
{
|
||||
float *_res = resp+i*subvect_size;
|
||||
const signed char *_shape = shape_cb+i*subvect_size;
|
||||
EE = _mm_setzero_ps();
|
||||
for(j=0;j<subvect_size;j++)
|
||||
{
|
||||
shape[j] = _mm_setr_ps(0.03125*_shape[j], 0.03125*_shape[subvect_size+j], 0.03125*_shape[2*subvect_size+j], 0.03125*_shape[3*subvect_size+j]);
|
||||
}
|
||||
for(j=0;j<subvect_size;j++)
|
||||
{
|
||||
resj = _mm_setzero_ps();
|
||||
for (k=0;k<=j;k++)
|
||||
resj = _mm_add_ps(resj, _mm_mul_ps(shape[k],r[j-k]));
|
||||
_spx_mm_getr_ps(resj, _res+j, _res+subvect_size+j, _res+2*subvect_size+j, _res+3*subvect_size+j);
|
||||
*resp2++ = resj;
|
||||
EE = _mm_add_ps(EE, _mm_mul_ps(resj, resj));
|
||||
}
|
||||
E[i>>2] = EE;
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
/* An inline macro is required for use of the inline keyword as not all C compilers support */
|
||||
/* inline. It is officially C99 and C++ only */
|
||||
|
||||
|
||||
/* Use only fixed point arithmetic */
|
||||
|
||||
//#ifdef _MSC_VER
|
||||
//#define inline _inline
|
||||
//#endif
|
||||
|
||||
#define FIXED_POINT 1
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#endif /* ! CONFIG_H */
|
|
@ -1,72 +0,0 @@
|
|||
% Attempts to diagnose AEC problems from recorded samples
|
||||
%
|
||||
% out = echo_diagnostic(rec_file, play_file, out_file, tail_length)
|
||||
%
|
||||
% Computes the full matrix inversion to cancel echo from the
|
||||
% recording 'rec_file' using the far end signal 'play_file' using
|
||||
% a filter length of 'tail_length'. The output is saved to 'out_file'.
|
||||
function out = echo_diagnostic(rec_file, play_file, out_file, tail_length)
|
||||
|
||||
F=fopen(rec_file,'rb');
|
||||
rec=fread(F,Inf,'short');
|
||||
fclose (F);
|
||||
F=fopen(play_file,'rb');
|
||||
play=fread(F,Inf,'short');
|
||||
fclose (F);
|
||||
|
||||
rec = [rec; zeros(1024,1)];
|
||||
play = [play; zeros(1024,1)];
|
||||
|
||||
N = length(rec);
|
||||
corr = real(ifft(fft(rec).*conj(fft(play))));
|
||||
acorr = real(ifft(fft(play).*conj(fft(play))));
|
||||
|
||||
[a,b] = max(corr);
|
||||
|
||||
if b > N/2
|
||||
b = b-N;
|
||||
end
|
||||
printf ("Far end to near end delay is %d samples\n", b);
|
||||
if (b > .3*tail_length)
|
||||
printf ('This is too much delay, try delaying the far-end signal a bit\n');
|
||||
else if (b < 0)
|
||||
printf ('You have a negative delay, the echo canceller has no chance to cancel anything!\n');
|
||||
else
|
||||
printf ('Delay looks OK.\n');
|
||||
end
|
||||
end
|
||||
end
|
||||
N2 = round(N/2);
|
||||
corr1 = real(ifft(fft(rec(1:N2)).*conj(fft(play(1:N2)))));
|
||||
corr2 = real(ifft(fft(rec(N2+1:end)).*conj(fft(play(N2+1:end)))));
|
||||
|
||||
[a,b1] = max(corr1);
|
||||
if b1 > N2/2
|
||||
b1 = b1-N2;
|
||||
end
|
||||
[a,b2] = max(corr2);
|
||||
if b2 > N2/2
|
||||
b2 = b2-N2;
|
||||
end
|
||||
drift = (b1-b2)/N2;
|
||||
printf ('Drift estimate is %f%% (%d samples)\n', 100*drift, b1-b2);
|
||||
if abs(b1-b2) < 10
|
||||
printf ('A drift of a few (+-10) samples is normal.\n');
|
||||
else
|
||||
if abs(b1-b2) < 30
|
||||
printf ('There may be (not sure) excessive clock drift. Is the capture and playback done on the same soundcard?\n');
|
||||
else
|
||||
printf ('Your clock is drifting! No way the AEC will be able to do anything with that. Most likely, you''re doing capture and playback from two different cards.\n');
|
||||
end
|
||||
end
|
||||
end
|
||||
acorr(1) = .001+1.00001*acorr(1);
|
||||
AtA = toeplitz(acorr(1:tail_length));
|
||||
bb = corr(1:tail_length);
|
||||
h = AtA\bb;
|
||||
|
||||
out = (rec - filter(h, 1, play));
|
||||
|
||||
F=fopen(out_file,'w');
|
||||
fwrite(F,out,'short');
|
||||
fclose (F);
|
|
@ -1,50 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_10_16_table.c
|
||||
Codebook for excitation in narrowband CELP mode (3200 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
const signed char exc_10_16_table[160] = {
|
||||
22,39,14,44,11,35,-2,23,-4,6,
|
||||
46,-28,13,-27,-23,12,4,20,-5,9,
|
||||
37,-18,-23,23,0,9,-6,-20,4,-1,
|
||||
-17,-5,-4,17,0,1,9,-2,1,2,
|
||||
2,-12,8,-25,39,15,9,16,-55,-11,
|
||||
9,11,5,10,-2,-60,8,13,-6,11,
|
||||
-16,27,-47,-12,11,1,16,-7,9,-3,
|
||||
-29,9,-14,25,-19,34,36,12,40,-10,
|
||||
-3,-24,-14,-37,-21,-35,-2,-36,3,-6,
|
||||
67,28,6,-17,-3,-12,-16,-15,-17,-7,
|
||||
-59,-36,-13,1,7,1,2,10,2,11,
|
||||
13,10,8,-2,7,3,5,4,2,2,
|
||||
-3,-8,4,-5,6,7,-42,15,35,-2,
|
||||
-46,38,28,-20,-9,1,7,-3,0,-2,
|
||||
0,0,0,0,0,0,0,0,0,0,
|
||||
-15,-28,52,32,5,-5,-17,-20,-10,-1};
|
|
@ -1,66 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_10_32_table.c
|
||||
Codebook for excitation in narrowband CELP mode (4000 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
const signed char exc_10_32_table[320] = {
|
||||
7,17,17,27,25,22,12,4,-3,0,
|
||||
28,-36,39,-24,-15,3,-9,15,-5,10,
|
||||
31,-28,11,31,-21,9,-11,-11,-2,-7,
|
||||
-25,14,-22,31,4,-14,19,-12,14,-5,
|
||||
4,-7,4,-5,9,0,-2,42,-47,-16,
|
||||
1,8,0,9,23,-57,0,28,-11,6,
|
||||
-31,55,-45,3,-5,4,2,-2,4,-7,
|
||||
-3,6,-2,7,-3,12,5,8,54,-10,
|
||||
8,-7,-8,-24,-25,-27,-14,-5,8,5,
|
||||
44,23,5,-9,-11,-11,-13,-9,-12,-8,
|
||||
-29,-8,-22,6,-15,3,-12,-1,-5,-3,
|
||||
34,-1,29,-16,17,-4,12,2,1,4,
|
||||
-2,-4,2,-1,11,-3,-52,28,30,-9,
|
||||
-32,25,44,-20,-24,4,6,-1,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,
|
||||
-25,-10,22,29,13,-13,-22,-13,-4,0,
|
||||
-4,-16,10,15,-36,-24,28,25,-1,-3,
|
||||
66,-33,-11,-15,6,0,3,4,-2,5,
|
||||
24,-20,-47,29,19,-2,-4,-1,0,-1,
|
||||
-2,3,1,8,-11,5,5,-57,28,28,
|
||||
0,-16,4,-4,12,-6,-1,2,-20,61,
|
||||
-9,24,-22,-42,29,6,17,8,4,2,
|
||||
-65,15,8,10,5,6,5,3,2,-2,
|
||||
-3,5,-9,4,-5,23,13,23,-3,-63,
|
||||
3,-5,-4,-6,0,-3,23,-36,-46,9,
|
||||
5,5,8,4,9,-5,1,-3,10,1,
|
||||
-6,10,-11,24,-47,31,22,-12,14,-10,
|
||||
6,11,-7,-7,7,-31,51,-12,-6,7,
|
||||
6,-17,9,-11,-20,52,-19,3,-6,-6,
|
||||
-8,-5,23,-41,37,1,-21,10,-14,8,
|
||||
7,5,-15,-15,23,39,-26,-33,7,2,
|
||||
-32,-30,-21,-8,4,12,17,15,14,11};
|
|
@ -1,66 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_20_32_table.c
|
||||
Codebook for excitation in narrowband CELP mode (2000 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
const signed char exc_20_32_table[640] = {
|
||||
12,32,25,46,36,33,9,14,-3,6,1,-8,0,-10,-5,-7,-7,-7,-5,-5,
|
||||
31,-27,24,-32,-4,10,-11,21,-3,19,23,-9,22,24,-10,-1,-10,-13,-7,-11,
|
||||
42,-33,31,19,-8,0,-10,-16,1,-21,-17,10,-8,14,8,4,11,-2,5,-2,
|
||||
-33,11,-16,33,11,-4,9,-4,11,2,6,-5,8,-5,11,-4,-6,26,-36,-16,
|
||||
0,4,-2,-8,12,6,-1,34,-46,-22,9,9,21,9,5,-66,-5,26,2,10,
|
||||
13,2,19,9,12,-81,3,13,13,0,-14,22,-35,6,-7,-4,6,-6,10,-6,
|
||||
-31,38,-33,0,-10,-11,5,-12,12,-17,5,0,-6,13,-9,10,8,25,33,2,
|
||||
-12,8,-6,10,-2,21,7,17,43,5,11,-7,-9,-20,-36,-20,-23,-4,-4,-3,
|
||||
27,-9,-9,-49,-39,-38,-11,-9,6,5,23,25,5,3,3,4,1,2,-3,-1,
|
||||
87,39,17,-21,-9,-19,-9,-15,-13,-14,-17,-11,-10,-11,-8,-6,-1,-3,-3,-1,
|
||||
-54,-34,-27,-8,-11,-4,-5,0,0,4,8,6,9,7,9,7,6,5,5,5,
|
||||
48,10,19,-10,12,-1,9,-3,2,5,-3,2,-2,-2,0,-2,-26,6,9,-7,
|
||||
-16,-9,2,7,7,-5,-43,11,22,-11,-9,34,37,-15,-13,-6,1,-1,1,1,
|
||||
-64,56,52,-11,-27,5,4,3,1,2,1,3,-1,-4,-4,-10,-7,-4,-4,2,
|
||||
-1,-7,-7,-12,-10,-15,-9,-5,-5,-11,-16,-13,6,16,4,-13,-16,-10,-4,2,
|
||||
-47,-13,25,47,19,-14,-20,-8,-17,0,-3,-13,1,6,-17,-14,15,1,10,6,
|
||||
-24,0,-10,19,-69,-8,14,49,17,-5,33,-29,3,-4,0,2,-8,5,-6,2,
|
||||
120,-56,-12,-47,23,-9,6,-5,1,2,-5,1,-10,4,-1,-1,4,-1,0,-3,
|
||||
30,-52,-67,30,22,11,-1,-4,3,0,7,2,0,1,-10,-4,-8,-13,5,1,
|
||||
1,-1,5,13,-9,-3,-10,-62,22,48,-4,-6,2,3,5,1,1,4,1,13,
|
||||
3,-20,10,-9,13,-2,-4,9,-20,44,-1,20,-32,-67,19,0,28,11,8,2,
|
||||
-11,15,-19,-53,31,2,34,10,6,-4,-58,8,10,13,14,1,12,2,0,0,
|
||||
-128,37,-8,44,-9,26,-3,18,2,6,11,-1,9,1,5,3,0,1,1,2,
|
||||
12,3,-2,-3,7,25,9,18,-6,-37,3,-8,-16,3,-10,-7,17,-34,-44,11,
|
||||
17,-15,-3,-16,-1,-13,11,-46,-65,-2,8,13,2,4,4,5,15,5,9,6,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
-9,19,-12,12,-28,38,29,-1,12,2,5,23,-10,3,4,-15,21,-4,3,3,
|
||||
6,17,-9,-4,-8,-20,26,5,-10,6,1,-19,18,-15,-12,47,-6,-2,-7,-9,
|
||||
-1,-17,-2,-2,-14,30,-14,2,-7,-4,-1,-12,11,-25,16,-3,-12,11,-7,7,
|
||||
-17,1,19,-28,31,-7,-10,7,-10,3,12,5,-16,6,24,41,-29,-54,0,1,
|
||||
7,-1,5,-6,13,10,-4,-8,8,-9,-27,-53,-38,-1,10,19,17,16,12,12,
|
||||
0,3,-7,-4,13,12,-31,-14,6,-5,3,5,17,43,50,25,10,1,-6,-2};
|
|
@ -1,290 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_5_256_table.c
|
||||
Codebook for excitation in narrowband CELP mode (12800 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
const signed char exc_5_256_table[1280] = {
|
||||
-8,-37,5,-43,5,
|
||||
73,61,39,12,-3,
|
||||
-61,-32,2,42,30,
|
||||
-3,17,-27,9,34,
|
||||
20,-1,-5,2,23,
|
||||
-7,-46,26,53,-47,
|
||||
20,-2,-33,-89,-51,
|
||||
-64,27,11,15,-34,
|
||||
-5,-56,25,-9,-1,
|
||||
-29,1,40,67,-23,
|
||||
-16,16,33,19,7,
|
||||
14,85,22,-10,-10,
|
||||
-12,-7,-1,52,89,
|
||||
29,11,-20,-37,-46,
|
||||
-15,17,-24,-28,24,
|
||||
2,1,0,23,-101,
|
||||
23,14,-1,-23,-18,
|
||||
9,5,-13,38,1,
|
||||
-28,-28,4,27,51,
|
||||
-26,34,-40,35,47,
|
||||
54,38,-54,-26,-6,
|
||||
42,-25,13,-30,-36,
|
||||
18,41,-4,-33,23,
|
||||
-32,-7,-4,51,-3,
|
||||
17,-52,56,-47,36,
|
||||
-2,-21,36,10,8,
|
||||
-33,31,19,9,-5,
|
||||
-40,10,-9,-21,19,
|
||||
18,-78,-18,-5,0,
|
||||
-26,-36,-47,-51,-44,
|
||||
18,40,27,-2,29,
|
||||
49,-26,2,32,-54,
|
||||
30,-73,54,3,-5,
|
||||
36,22,53,10,-1,
|
||||
-84,-53,-29,-5,3,
|
||||
-44,53,-51,4,22,
|
||||
71,-35,-1,33,-5,
|
||||
-27,-7,36,17,-23,
|
||||
-39,16,-9,-55,-15,
|
||||
-20,39,-35,6,-39,
|
||||
-14,18,48,-64,-17,
|
||||
-15,9,39,81,37,
|
||||
-68,37,47,-21,-6,
|
||||
-104,13,6,9,-2,
|
||||
35,8,-23,18,42,
|
||||
45,21,33,-5,-49,
|
||||
9,-6,-43,-56,39,
|
||||
2,-16,-25,87,1,
|
||||
-3,-9,17,-25,-11,
|
||||
-9,-1,10,2,-14,
|
||||
-14,4,-1,-10,28,
|
||||
-23,40,-32,26,-9,
|
||||
26,4,-27,-23,3,
|
||||
42,-60,1,49,-3,
|
||||
27,10,-52,-40,-2,
|
||||
18,45,-23,17,-44,
|
||||
3,-3,17,-46,52,
|
||||
-40,-47,25,75,31,
|
||||
-49,53,30,-30,-32,
|
||||
-36,38,-6,-15,-16,
|
||||
54,-27,-48,3,38,
|
||||
-29,-32,-22,-14,-4,
|
||||
-23,-13,32,-39,9,
|
||||
8,-45,-13,34,-16,
|
||||
49,40,32,31,28,
|
||||
23,23,32,47,59,
|
||||
-68,8,62,44,25,
|
||||
-14,-24,-65,-16,36,
|
||||
67,-25,-38,-21,4,
|
||||
-33,-2,42,5,-63,
|
||||
40,11,26,-42,-23,
|
||||
-61,79,-31,23,-20,
|
||||
10,-32,53,-25,-36,
|
||||
10,-26,-5,3,0,
|
||||
-71,5,-10,-37,1,
|
||||
-24,21,-54,-17,1,
|
||||
-29,-25,-15,-27,32,
|
||||
68,45,-16,-37,-18,
|
||||
-5,1,0,-77,71,
|
||||
-6,3,-20,71,-67,
|
||||
29,-35,10,-30,19,
|
||||
4,16,17,5,0,
|
||||
-14,19,2,28,26,
|
||||
59,3,2,24,39,
|
||||
55,-50,-45,-18,-17,
|
||||
33,-35,14,-1,1,
|
||||
8,87,-35,-29,0,
|
||||
-27,13,-7,23,-13,
|
||||
37,-40,50,-35,14,
|
||||
19,-7,-14,49,54,
|
||||
-5,22,-2,-29,-8,
|
||||
-27,38,13,27,48,
|
||||
12,-41,-21,-15,28,
|
||||
7,-16,-24,-19,-20,
|
||||
11,-20,9,2,13,
|
||||
23,-20,11,27,-27,
|
||||
71,-69,8,2,-6,
|
||||
22,12,16,16,9,
|
||||
-16,-8,-17,1,25,
|
||||
1,40,-37,-33,66,
|
||||
94,53,4,-22,-25,
|
||||
-41,-42,25,35,-16,
|
||||
-15,57,31,-29,-32,
|
||||
21,16,-60,45,15,
|
||||
-1,7,57,-26,-47,
|
||||
-29,11,8,15,19,
|
||||
-105,-8,54,27,10,
|
||||
-17,6,-12,-1,-10,
|
||||
4,0,23,-10,31,
|
||||
13,11,10,12,-64,
|
||||
23,-3,-8,-19,16,
|
||||
52,24,-40,16,10,
|
||||
40,5,9,0,-13,
|
||||
-7,-21,-8,-6,-7,
|
||||
-21,59,16,-53,18,
|
||||
-60,11,-47,14,-18,
|
||||
25,-13,-24,4,-39,
|
||||
16,-28,54,26,-67,
|
||||
30,27,-20,-52,20,
|
||||
-12,55,12,18,-16,
|
||||
39,-14,-6,-26,56,
|
||||
-88,-55,12,25,26,
|
||||
-37,6,75,0,-34,
|
||||
-81,54,-30,1,-7,
|
||||
49,-23,-14,21,10,
|
||||
-62,-58,-57,-47,-34,
|
||||
15,-4,34,-78,31,
|
||||
25,-11,7,50,-10,
|
||||
42,-63,14,-36,-4,
|
||||
57,55,57,53,42,
|
||||
-42,-1,15,40,37,
|
||||
15,25,-11,6,1,
|
||||
31,-2,-6,-1,-7,
|
||||
-64,34,28,30,-1,
|
||||
3,21,0,-88,-12,
|
||||
-56,25,-28,40,8,
|
||||
-28,-14,9,12,2,
|
||||
-6,-17,22,49,-6,
|
||||
-26,14,28,-20,4,
|
||||
-12,50,35,40,13,
|
||||
-38,-58,-29,17,30,
|
||||
22,60,26,-54,-39,
|
||||
-12,58,-28,-63,10,
|
||||
-21,-8,-12,26,-62,
|
||||
6,-10,-11,-22,-6,
|
||||
-7,4,1,18,2,
|
||||
-70,11,14,4,13,
|
||||
19,-24,-34,24,67,
|
||||
17,51,-21,13,23,
|
||||
54,-30,48,1,-13,
|
||||
80,26,-16,-2,13,
|
||||
-4,6,-30,29,-24,
|
||||
73,-58,30,-27,20,
|
||||
-2,-21,41,45,30,
|
||||
-27,-3,-5,-18,-20,
|
||||
-49,-3,-35,10,42,
|
||||
-19,-67,-53,-11,9,
|
||||
13,-15,-33,-51,-30,
|
||||
15,7,25,-30,4,
|
||||
28,-22,-34,54,-29,
|
||||
39,-46,20,16,34,
|
||||
-4,47,75,1,-44,
|
||||
-55,-24,7,-1,9,
|
||||
-42,50,-8,-36,41,
|
||||
68,0,-4,-10,-23,
|
||||
-15,-50,64,36,-9,
|
||||
-27,12,25,-38,-47,
|
||||
-37,32,-49,51,-36,
|
||||
2,-4,69,-26,19,
|
||||
7,45,67,46,13,
|
||||
-63,46,15,-47,4,
|
||||
-41,13,-6,5,-21,
|
||||
37,26,-55,-7,33,
|
||||
-1,-28,10,-17,-64,
|
||||
-14,0,-36,-17,93,
|
||||
-3,-9,-66,44,-21,
|
||||
3,-12,38,-6,-13,
|
||||
-12,19,13,43,-43,
|
||||
-10,-12,6,-5,9,
|
||||
-49,32,-5,2,4,
|
||||
5,15,-16,10,-21,
|
||||
8,-62,-8,64,8,
|
||||
79,-1,-66,-49,-18,
|
||||
5,40,-5,-30,-45,
|
||||
1,-6,21,-32,93,
|
||||
-18,-30,-21,32,21,
|
||||
-18,22,8,5,-41,
|
||||
-54,80,22,-10,-7,
|
||||
-8,-23,-64,66,56,
|
||||
-14,-30,-41,-46,-14,
|
||||
-29,-37,27,-14,42,
|
||||
-2,-9,-29,34,14,
|
||||
33,-14,22,4,10,
|
||||
26,26,28,32,23,
|
||||
-72,-32,3,0,-14,
|
||||
35,-42,-78,-32,6,
|
||||
29,-18,-45,-5,7,
|
||||
-33,-45,-3,-22,-34,
|
||||
8,-8,4,-51,-25,
|
||||
-9,59,-78,21,-5,
|
||||
-25,-48,66,-15,-17,
|
||||
-24,-49,-13,25,-23,
|
||||
-64,-6,40,-24,-19,
|
||||
-11,57,-33,-8,1,
|
||||
10,-52,-54,28,39,
|
||||
49,34,-11,-61,-41,
|
||||
-43,10,15,-15,51,
|
||||
30,15,-51,32,-34,
|
||||
-2,-34,14,18,16,
|
||||
1,1,-3,-3,1,
|
||||
1,-18,6,16,48,
|
||||
12,-5,-42,7,36,
|
||||
48,7,-20,-10,7,
|
||||
12,2,54,39,-38,
|
||||
37,54,4,-11,-8,
|
||||
-46,-10,5,-10,-34,
|
||||
46,-12,29,-37,39,
|
||||
36,-11,24,56,17,
|
||||
14,20,25,0,-25,
|
||||
-28,55,-7,-5,27,
|
||||
3,9,-26,-8,6,
|
||||
-24,-10,-30,-31,-34,
|
||||
18,4,22,21,40,
|
||||
-1,-29,-37,-8,-21,
|
||||
92,-29,11,-3,11,
|
||||
73,23,22,7,4,
|
||||
-44,-9,-11,21,-13,
|
||||
11,9,-78,-1,47,
|
||||
114,-12,-37,-19,-5,
|
||||
-11,-22,19,12,-30,
|
||||
7,38,45,-21,-8,
|
||||
-9,55,-45,56,-21,
|
||||
7,17,46,-57,-87,
|
||||
-6,27,31,31,7,
|
||||
-56,-12,46,21,-5,
|
||||
-12,36,3,3,-21,
|
||||
43,19,12,-7,9,
|
||||
-14,0,-9,-33,-91,
|
||||
7,26,3,-11,64,
|
||||
83,-31,-46,25,2,
|
||||
9,5,2,2,-1,
|
||||
20,-17,10,-5,-27,
|
||||
-8,20,8,-19,16,
|
||||
-21,-13,-31,5,5,
|
||||
42,24,9,34,-20,
|
||||
28,-61,22,11,-39,
|
||||
64,-20,-1,-30,-9,
|
||||
-20,24,-25,-24,-29,
|
||||
22,-60,6,-5,41,
|
||||
-9,-87,14,34,15,
|
||||
-57,52,69,15,-3,
|
||||
-102,58,16,3,6,
|
||||
60,-75,-32,26,7,
|
||||
-57,-27,-32,-24,-21,
|
||||
-29,-16,62,-46,31,
|
||||
30,-27,-15,7,15};
|
|
@ -1,98 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_5_64_table.c
|
||||
Codebook for excitation in narrowband CELP mode (9600 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
const signed char exc_5_64_table[320]={
|
||||
1,5,-15,49,-66,
|
||||
-48,-4,50,-44,7,
|
||||
37,16,-18,25,-26,
|
||||
-26,-15,19,19,-27,
|
||||
-47,28,57,5,-17,
|
||||
-32,-41,68,21,-2,
|
||||
64,56,8,-16,-13,
|
||||
-26,-9,-16,11,6,
|
||||
-39,25,-19,22,-31,
|
||||
20,-45,55,-43,10,
|
||||
-16,47,-40,40,-20,
|
||||
-51,3,-17,-14,-15,
|
||||
-24,53,-20,-46,46,
|
||||
27,-68,32,3,-18,
|
||||
-5,9,-31,16,-9,
|
||||
-10,-1,-23,48,95,
|
||||
47,25,-41,-32,-3,
|
||||
15,-25,-55,36,41,
|
||||
-27,20,5,13,14,
|
||||
-22,5,2,-23,18,
|
||||
46,-15,17,-18,-34,
|
||||
-5,-8,27,-55,73,
|
||||
16,2,-1,-17,40,
|
||||
-78,33,0,2,19,
|
||||
4,53,-16,-15,-16,
|
||||
-28,-3,-13,49,8,
|
||||
-7,-29,27,-13,32,
|
||||
20,32,-61,16,14,
|
||||
41,44,40,24,20,
|
||||
7,4,48,-60,-77,
|
||||
17,-6,-48,65,-15,
|
||||
32,-30,-71,-10,-3,
|
||||
-6,10,-2,-7,-29,
|
||||
-56,67,-30,7,-5,
|
||||
86,-6,-10,0,5,
|
||||
-31,60,34,-38,-3,
|
||||
24,10,-2,30,23,
|
||||
24,-41,12,70,-43,
|
||||
15,-17,6,13,16,
|
||||
-13,8,30,-15,-8,
|
||||
5,23,-34,-98,-4,
|
||||
-13,13,-48,-31,70,
|
||||
12,31,25,24,-24,
|
||||
26,-7,33,-16,8,
|
||||
5,-11,-14,-8,-65,
|
||||
13,10,-2,-9,0,
|
||||
-3,-68,5,35,7,
|
||||
0,-31,-1,-17,-9,
|
||||
-9,16,-37,-18,-1,
|
||||
69,-48,-28,22,-21,
|
||||
-11,5,49,55,23,
|
||||
-86,-36,16,2,13,
|
||||
63,-51,30,-11,13,
|
||||
24,-18,-6,14,-19,
|
||||
1,41,9,-5,27,
|
||||
-36,-44,-34,-37,-21,
|
||||
-26,31,-39,15,43,
|
||||
5,-8,29,20,-8,
|
||||
-20,-52,-28,-1,13,
|
||||
26,-34,-10,-9,27,
|
||||
-8,8,27,-66,4,
|
||||
12,-22,49,10,-77,
|
||||
32,-18,3,-38,12,
|
||||
-3,-1,2,2,0};
|
|
@ -1,162 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_8_128_table.c
|
||||
Codebook for excitation in narrowband CELP mode (7000 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
const signed char exc_8_128_table[1024] = {
|
||||
-14,9,13,-32,2,-10,31,-10,
|
||||
-8,-8,6,-4,-1,10,-64,23,
|
||||
6,20,13,6,8,-22,16,34,
|
||||
7,42,-49,-28,5,26,4,-15,
|
||||
41,34,41,32,33,24,23,14,
|
||||
8,40,34,4,-24,-41,-19,-15,
|
||||
13,-13,33,-54,24,27,-44,33,
|
||||
27,-15,-15,24,-19,14,-36,14,
|
||||
-9,24,-12,-4,37,-5,16,-34,
|
||||
5,10,33,-15,-54,-16,12,25,
|
||||
12,1,2,0,3,-1,-4,-4,
|
||||
11,2,-56,54,27,-20,13,-6,
|
||||
-46,-41,-33,-11,-5,7,12,14,
|
||||
-14,-5,8,20,6,3,4,-8,
|
||||
-5,-42,11,8,-14,25,-2,2,
|
||||
13,11,-22,39,-9,9,5,-45,
|
||||
-9,7,-9,12,-7,34,-17,-102,
|
||||
7,2,-42,18,35,-9,-34,11,
|
||||
-5,-2,3,22,46,-52,-25,-9,
|
||||
-94,8,11,-5,-5,-5,4,-7,
|
||||
-35,-7,54,5,-32,3,24,-9,
|
||||
-22,8,65,37,-1,-12,-23,-6,
|
||||
-9,-28,55,-33,14,-3,2,18,
|
||||
-60,41,-17,8,-16,17,-11,0,
|
||||
-11,29,-28,37,9,-53,33,-14,
|
||||
-9,7,-25,-7,-11,26,-32,-8,
|
||||
24,-21,22,-19,19,-10,29,-14,
|
||||
0,0,0,0,0,0,0,0,
|
||||
-5,-52,10,41,6,-30,-4,16,
|
||||
32,22,-27,-22,32,-3,-28,-3,
|
||||
3,-35,6,17,23,21,8,2,
|
||||
4,-45,-17,14,23,-4,-31,-11,
|
||||
-3,14,1,19,-11,2,61,-8,
|
||||
9,-12,7,-10,12,-3,-24,99,
|
||||
-48,23,50,-37,-5,-23,0,8,
|
||||
-14,35,-64,-5,46,-25,13,-1,
|
||||
-49,-19,-15,9,34,50,25,11,
|
||||
-6,-9,-16,-20,-32,-33,-32,-27,
|
||||
10,-8,12,-15,56,-14,-32,33,
|
||||
3,-9,1,65,-9,-9,-10,-2,
|
||||
-6,-23,9,17,3,-28,13,-32,
|
||||
4,-2,-10,4,-16,76,12,-52,
|
||||
6,13,33,-6,4,-14,-9,-3,
|
||||
1,-15,-16,28,1,-15,11,16,
|
||||
9,4,-21,-37,-40,-6,22,12,
|
||||
-15,-23,-14,-17,-16,-9,-10,-9,
|
||||
13,-39,41,5,-9,16,-38,25,
|
||||
46,-47,4,49,-14,17,-2,6,
|
||||
18,5,-6,-33,-22,44,50,-2,
|
||||
1,3,-6,7,7,-3,-21,38,
|
||||
-18,34,-14,-41,60,-13,6,16,
|
||||
-24,35,19,-13,-36,24,3,-17,
|
||||
-14,-10,36,44,-44,-29,-3,3,
|
||||
-54,-8,12,55,26,4,-2,-5,
|
||||
2,-11,22,-23,2,22,1,-25,
|
||||
-39,66,-49,21,-8,-2,10,-14,
|
||||
-60,25,6,10,27,-25,16,5,
|
||||
-2,-9,26,-13,-20,58,-2,7,
|
||||
52,-9,2,5,-4,-15,23,-1,
|
||||
-38,23,8,27,-6,0,-27,-7,
|
||||
39,-10,-14,26,11,-45,-12,9,
|
||||
-5,34,4,-35,10,43,-22,-11,
|
||||
56,-7,20,1,10,1,-26,9,
|
||||
94,11,-27,-14,-13,1,-11,0,
|
||||
14,-5,-6,-10,-4,-15,-8,-41,
|
||||
21,-5,1,-28,-8,22,-9,33,
|
||||
-23,-4,-4,-12,39,4,-7,3,
|
||||
-60,80,8,-17,2,-6,12,-5,
|
||||
1,9,15,27,31,30,27,23,
|
||||
61,47,26,10,-5,-8,-12,-13,
|
||||
5,-18,25,-15,-4,-15,-11,12,
|
||||
-2,-2,-16,-2,-6,24,12,11,
|
||||
-4,9,1,-9,14,-45,57,12,
|
||||
20,-35,26,11,-64,32,-10,-10,
|
||||
42,-4,-9,-16,32,24,7,10,
|
||||
52,-11,-57,29,0,8,0,-6,
|
||||
17,-17,-56,-40,7,20,18,12,
|
||||
-6,16,5,7,-1,9,1,10,
|
||||
29,12,16,13,-2,23,7,9,
|
||||
-3,-4,-5,18,-64,13,55,-25,
|
||||
9,-9,24,14,-25,15,-11,-40,
|
||||
-30,37,1,-19,22,-5,-31,13,
|
||||
-2,0,7,-4,16,-67,12,66,
|
||||
-36,24,-8,18,-15,-23,19,0,
|
||||
-45,-7,4,3,-13,13,35,5,
|
||||
13,33,10,27,23,0,-7,-11,
|
||||
43,-74,36,-12,2,5,-8,6,
|
||||
-33,11,-16,-14,-5,-7,-3,17,
|
||||
-34,27,-16,11,-9,15,33,-31,
|
||||
8,-16,7,-6,-7,63,-55,-17,
|
||||
11,-1,20,-46,34,-30,6,9,
|
||||
19,28,-9,5,-24,-8,-23,-2,
|
||||
31,-19,-16,-5,-15,-18,0,26,
|
||||
18,37,-5,-15,-2,17,5,-27,
|
||||
21,-33,44,12,-27,-9,17,11,
|
||||
25,-21,-31,-7,13,33,-8,-25,
|
||||
-7,7,-10,4,-6,-9,48,-82,
|
||||
-23,-8,6,11,-23,3,-3,49,
|
||||
-29,25,31,4,14,16,9,-4,
|
||||
-18,10,-26,3,5,-44,-9,9,
|
||||
-47,-55,15,9,28,1,4,-3,
|
||||
46,6,-6,-38,-29,-31,-15,-6,
|
||||
3,0,14,-6,8,-54,-50,33,
|
||||
-5,1,-14,33,-48,26,-4,-5,
|
||||
-3,-5,-3,-5,-28,-22,77,55,
|
||||
-1,2,10,10,-9,-14,-66,-49,
|
||||
11,-36,-6,-20,10,-10,16,12,
|
||||
4,-1,-16,45,-44,-50,31,-2,
|
||||
25,42,23,-32,-22,0,11,20,
|
||||
-40,-35,-40,-36,-32,-26,-21,-13,
|
||||
52,-22,6,-24,-20,17,-5,-8,
|
||||
36,-25,-11,21,-26,6,34,-8,
|
||||
7,20,-3,5,-25,-8,18,-5,
|
||||
-9,-4,1,-9,20,20,39,48,
|
||||
-24,9,5,-65,22,29,4,3,
|
||||
-43,-11,32,-6,9,19,-27,-10,
|
||||
-47,-14,24,10,-7,-36,-7,-1,
|
||||
-4,-5,-5,16,53,25,-26,-29,
|
||||
-4,-12,45,-58,-34,33,-5,2,
|
||||
-1,27,-48,31,-15,22,-5,4,
|
||||
7,7,-25,-3,11,-22,16,-12,
|
||||
8,-3,7,-11,45,14,-73,-19,
|
||||
56,-46,24,-20,28,-12,-2,-1,
|
||||
-36,-3,-33,19,-6,7,2,-15,
|
||||
5,-31,-45,8,35,13,20,0,
|
||||
-9,48,-13,-43,-3,-13,2,-5,
|
||||
72,-68,-27,2,1,-2,-7,5,
|
||||
36,33,-40,-12,-4,-5,23,19};
|
|
@ -1,397 +0,0 @@
|
|||
/* Copyright (C) 2005-2006 Jean-Marc Valin
|
||||
File: fftwrap.c
|
||||
|
||||
Wrapper for various FFTs
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#define MAX_FFT_SIZE 2048
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
static int maximize_range(spx_word16_t *in, spx_word16_t *out, spx_word16_t bound, int len)
|
||||
{
|
||||
int i, shift;
|
||||
spx_word16_t max_val = 0;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
if (in[i]>max_val)
|
||||
max_val = in[i];
|
||||
if (-in[i]>max_val)
|
||||
max_val = -in[i];
|
||||
}
|
||||
shift=0;
|
||||
while (max_val <= (bound>>1) && max_val != 0)
|
||||
{
|
||||
max_val <<= 1;
|
||||
shift++;
|
||||
}
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
out[i] = SHL16(in[i], shift);
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
static void renorm_range(spx_word16_t *in, spx_word16_t *out, int shift, int len)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
out[i] = PSHR16(in[i], shift);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SMALLFT
|
||||
|
||||
#include "smallft.h"
|
||||
#include <math.h>
|
||||
|
||||
void *spx_fft_init(int size)
|
||||
{
|
||||
struct drft_lookup *table;
|
||||
table = speex_alloc(sizeof(struct drft_lookup));
|
||||
spx_drft_init((struct drft_lookup *)table, size);
|
||||
return (void*)table;
|
||||
}
|
||||
|
||||
void spx_fft_destroy(void *table)
|
||||
{
|
||||
spx_drft_clear(table);
|
||||
speex_free(table);
|
||||
}
|
||||
|
||||
void spx_fft(void *table, float *in, float *out)
|
||||
{
|
||||
if (in==out)
|
||||
{
|
||||
int i;
|
||||
float scale = 1./((struct drft_lookup *)table)->n;
|
||||
speex_warning("FFT should not be done in-place");
|
||||
for (i=0;i<((struct drft_lookup *)table)->n;i++)
|
||||
out[i] = scale*in[i];
|
||||
} else {
|
||||
int i;
|
||||
float scale = 1./((struct drft_lookup *)table)->n;
|
||||
for (i=0;i<((struct drft_lookup *)table)->n;i++)
|
||||
out[i] = scale*in[i];
|
||||
}
|
||||
spx_drft_forward((struct drft_lookup *)table, out);
|
||||
}
|
||||
|
||||
void spx_ifft(void *table, float *in, float *out)
|
||||
{
|
||||
if (in==out)
|
||||
{
|
||||
speex_warning("FFT should not be done in-place");
|
||||
} else {
|
||||
int i;
|
||||
for (i=0;i<((struct drft_lookup *)table)->n;i++)
|
||||
out[i] = in[i];
|
||||
}
|
||||
spx_drft_backward((struct drft_lookup *)table, out);
|
||||
}
|
||||
|
||||
#elif defined(USE_INTEL_MKL)
|
||||
#include <mkl.h>
|
||||
|
||||
struct mkl_config {
|
||||
DFTI_DESCRIPTOR_HANDLE desc;
|
||||
int N;
|
||||
};
|
||||
|
||||
void *spx_fft_init(int size)
|
||||
{
|
||||
struct mkl_config *table = (struct mkl_config *) speex_alloc(sizeof(struct mkl_config));
|
||||
table->N = size;
|
||||
DftiCreateDescriptor(&table->desc, DFTI_SINGLE, DFTI_REAL, 1, size);
|
||||
DftiSetValue(table->desc, DFTI_PACKED_FORMAT, DFTI_PACK_FORMAT);
|
||||
DftiSetValue(table->desc, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
|
||||
DftiSetValue(table->desc, DFTI_FORWARD_SCALE, 1.0f / size);
|
||||
DftiCommitDescriptor(table->desc);
|
||||
return table;
|
||||
}
|
||||
|
||||
void spx_fft_destroy(void *table)
|
||||
{
|
||||
struct mkl_config *t = (struct mkl_config *) table;
|
||||
DftiFreeDescriptor(t->desc);
|
||||
speex_free(table);
|
||||
}
|
||||
|
||||
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
struct mkl_config *t = (struct mkl_config *) table;
|
||||
DftiComputeForward(t->desc, in, out);
|
||||
}
|
||||
|
||||
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
struct mkl_config *t = (struct mkl_config *) table;
|
||||
DftiComputeBackward(t->desc, in, out);
|
||||
}
|
||||
|
||||
#elif defined(USE_GPL_FFTW3)
|
||||
|
||||
#include <fftw3.h>
|
||||
|
||||
struct fftw_config {
|
||||
float *in;
|
||||
float *out;
|
||||
fftwf_plan fft;
|
||||
fftwf_plan ifft;
|
||||
int N;
|
||||
};
|
||||
|
||||
void *spx_fft_init(int size)
|
||||
{
|
||||
struct fftw_config *table = (struct fftw_config *) speex_alloc(sizeof(struct fftw_config));
|
||||
table->in = fftwf_malloc(sizeof(float) * (size+2));
|
||||
table->out = fftwf_malloc(sizeof(float) * (size+2));
|
||||
|
||||
table->fft = fftwf_plan_dft_r2c_1d(size, table->in, (fftwf_complex *) table->out, FFTW_PATIENT);
|
||||
table->ifft = fftwf_plan_dft_c2r_1d(size, (fftwf_complex *) table->in, table->out, FFTW_PATIENT);
|
||||
|
||||
table->N = size;
|
||||
return table;
|
||||
}
|
||||
|
||||
void spx_fft_destroy(void *table)
|
||||
{
|
||||
struct fftw_config *t = (struct fftw_config *) table;
|
||||
fftwf_destroy_plan(t->fft);
|
||||
fftwf_destroy_plan(t->ifft);
|
||||
fftwf_free(t->in);
|
||||
fftwf_free(t->out);
|
||||
speex_free(table);
|
||||
}
|
||||
|
||||
|
||||
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
int i;
|
||||
struct fftw_config *t = (struct fftw_config *) table;
|
||||
const int N = t->N;
|
||||
float *iptr = t->in;
|
||||
float *optr = t->out;
|
||||
const float m = 1.0 / N;
|
||||
for(i=0;i<N;++i)
|
||||
iptr[i]=in[i] * m;
|
||||
|
||||
fftwf_execute(t->fft);
|
||||
|
||||
out[0] = optr[0];
|
||||
for(i=1;i<N;++i)
|
||||
out[i] = optr[i+1];
|
||||
}
|
||||
|
||||
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
int i;
|
||||
struct fftw_config *t = (struct fftw_config *) table;
|
||||
const int N = t->N;
|
||||
float *iptr = t->in;
|
||||
float *optr = t->out;
|
||||
|
||||
iptr[0] = in[0];
|
||||
iptr[1] = 0.0f;
|
||||
for(i=1;i<N;++i)
|
||||
iptr[i+1] = in[i];
|
||||
iptr[N+1] = 0.0f;
|
||||
|
||||
fftwf_execute(t->ifft);
|
||||
|
||||
for(i=0;i<N;++i)
|
||||
out[i] = optr[i];
|
||||
}
|
||||
|
||||
#elif defined(USE_KISS_FFT)
|
||||
|
||||
#include "kiss_fftr.h"
|
||||
#include "kiss_fft.h"
|
||||
|
||||
struct kiss_config {
|
||||
kiss_fftr_cfg forward;
|
||||
kiss_fftr_cfg backward;
|
||||
int N;
|
||||
};
|
||||
|
||||
void *spx_fft_init(int size)
|
||||
{
|
||||
struct kiss_config *table;
|
||||
table = (struct kiss_config*)speex_alloc(sizeof(struct kiss_config));
|
||||
table->forward = kiss_fftr_alloc(size,0,NULL,NULL);
|
||||
table->backward = kiss_fftr_alloc(size,1,NULL,NULL);
|
||||
table->N = size;
|
||||
return table;
|
||||
}
|
||||
|
||||
void spx_fft_destroy(void *table)
|
||||
{
|
||||
struct kiss_config *t = (struct kiss_config *)table;
|
||||
kiss_fftr_free(t->forward);
|
||||
kiss_fftr_free(t->backward);
|
||||
speex_free(table);
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
int shift;
|
||||
struct kiss_config *t = (struct kiss_config *)table;
|
||||
shift = maximize_range(in, in, 32000, t->N);
|
||||
kiss_fftr2(t->forward, in, out);
|
||||
renorm_range(in, in, shift, t->N);
|
||||
renorm_range(out, out, shift, t->N);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
int i;
|
||||
float scale;
|
||||
struct kiss_config *t = (struct kiss_config *)table;
|
||||
scale = 1./t->N;
|
||||
kiss_fftr2(t->forward, in, out);
|
||||
for (i=0;i<t->N;i++)
|
||||
out[i] *= scale;
|
||||
}
|
||||
#endif
|
||||
|
||||
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
struct kiss_config *t = (struct kiss_config *)table;
|
||||
kiss_fftri2(t->backward, in, out);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#error No other FFT implemented
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
/*#include "smallft.h"*/
|
||||
|
||||
|
||||
void spx_fft_float(void *table, float *in, float *out)
|
||||
{
|
||||
int i;
|
||||
#ifdef USE_SMALLFT
|
||||
int N = ((struct drft_lookup *)table)->n;
|
||||
#elif defined(USE_KISS_FFT)
|
||||
int N = ((struct kiss_config *)table)->N;
|
||||
#else
|
||||
#endif
|
||||
#ifdef VAR_ARRAYS
|
||||
spx_word16_t _in[N];
|
||||
spx_word16_t _out[N];
|
||||
#else
|
||||
spx_word16_t _in[MAX_FFT_SIZE];
|
||||
spx_word16_t _out[MAX_FFT_SIZE];
|
||||
#endif
|
||||
for (i=0;i<N;i++)
|
||||
_in[i] = (int)floor(.5+in[i]);
|
||||
spx_fft(table, _in, _out);
|
||||
for (i=0;i<N;i++)
|
||||
out[i] = _out[i];
|
||||
#if 0
|
||||
if (!fixed_point)
|
||||
{
|
||||
float scale;
|
||||
struct drft_lookup t;
|
||||
spx_drft_init(&t, ((struct kiss_config *)table)->N);
|
||||
scale = 1./((struct kiss_config *)table)->N;
|
||||
for (i=0;i<((struct kiss_config *)table)->N;i++)
|
||||
out[i] = scale*in[i];
|
||||
spx_drft_forward(&t, out);
|
||||
spx_drft_clear(&t);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void spx_ifft_float(void *table, float *in, float *out)
|
||||
{
|
||||
int i;
|
||||
#ifdef USE_SMALLFT
|
||||
int N = ((struct drft_lookup *)table)->n;
|
||||
#elif defined(USE_KISS_FFT)
|
||||
int N = ((struct kiss_config *)table)->N;
|
||||
#else
|
||||
#endif
|
||||
#ifdef VAR_ARRAYS
|
||||
spx_word16_t _in[N];
|
||||
spx_word16_t _out[N];
|
||||
#else
|
||||
spx_word16_t _in[MAX_FFT_SIZE];
|
||||
spx_word16_t _out[MAX_FFT_SIZE];
|
||||
#endif
|
||||
for (i=0;i<N;i++)
|
||||
_in[i] = (int)floor(.5+in[i]);
|
||||
spx_ifft(table, _in, _out);
|
||||
for (i=0;i<N;i++)
|
||||
out[i] = _out[i];
|
||||
#if 0
|
||||
if (!fixed_point)
|
||||
{
|
||||
int i;
|
||||
struct drft_lookup t;
|
||||
spx_drft_init(&t, ((struct kiss_config *)table)->N);
|
||||
for (i=0;i<((struct kiss_config *)table)->N;i++)
|
||||
out[i] = in[i];
|
||||
spx_drft_backward(&t, out);
|
||||
spx_drft_clear(&t);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void spx_fft_float(void *table, float *in, float *out)
|
||||
{
|
||||
spx_fft(table, in, out);
|
||||
}
|
||||
void spx_ifft_float(void *table, float *in, float *out)
|
||||
{
|
||||
spx_ifft(table, in, out);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||
/* Copyright (C) 2005 Jean-Marc Valin
|
||||
File: fftwrap.h
|
||||
|
||||
Wrapper for various FFTs
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef FFTWRAP_H
|
||||
#define FFTWRAP_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
/** Compute tables for an FFT */
|
||||
void *spx_fft_init(int size);
|
||||
|
||||
/** Destroy tables for an FFT */
|
||||
void spx_fft_destroy(void *table);
|
||||
|
||||
/** Forward (real to half-complex) transform */
|
||||
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out);
|
||||
|
||||
/** Backward (half-complex to real) transform */
|
||||
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out);
|
||||
|
||||
/** Forward (real to half-complex) transform of float data */
|
||||
void spx_fft_float(void *table, float *in, float *out);
|
||||
|
||||
/** Backward (half-complex to real) transform of float data */
|
||||
void spx_ifft_float(void *table, float *in, float *out);
|
||||
|
||||
#endif
|
|
@ -1,227 +0,0 @@
|
|||
/* Copyright (C) 2006 Jean-Marc Valin */
|
||||
/**
|
||||
@file filterbank.c
|
||||
@brief Converting between psd and filterbank
|
||||
*/
|
||||
/*
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "filterbank.h"
|
||||
#include "arch.h"
|
||||
#include <math.h>
|
||||
#include "math_approx.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
#define toBARK(n) (MULT16_16(26829,spx_atan(SHR32(MULT16_16(97,n),2))) + MULT16_16(4588,spx_atan(MULT16_32_Q15(20,MULT16_16(n,n)))) + MULT16_16(3355,n))
|
||||
|
||||
#else
|
||||
#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
|
||||
#endif
|
||||
|
||||
#define toMEL(n) (2595.f*log10(1.f+(n)/700.f))
|
||||
|
||||
FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type)
|
||||
{
|
||||
FilterBank *bank;
|
||||
spx_word32_t df;
|
||||
spx_word32_t max_mel, mel_interval;
|
||||
int i;
|
||||
int id1;
|
||||
int id2;
|
||||
df = DIV32(SHL32(sampling,15),MULT16_16(2,len));
|
||||
max_mel = toBARK(EXTRACT16(sampling/2));
|
||||
mel_interval = PDIV32(max_mel,banks-1);
|
||||
|
||||
bank = (FilterBank*)speex_alloc(sizeof(FilterBank));
|
||||
bank->nb_banks = banks;
|
||||
bank->len = len;
|
||||
bank->bank_left = (int*)speex_alloc(len*sizeof(int));
|
||||
bank->bank_right = (int*)speex_alloc(len*sizeof(int));
|
||||
bank->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
|
||||
bank->filter_right = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
|
||||
/* Think I can safely disable normalisation that for fixed-point (and probably float as well) */
|
||||
#ifndef FIXED_POINT
|
||||
bank->scaling = (float*)speex_alloc(banks*sizeof(float));
|
||||
#endif
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
spx_word16_t curr_freq;
|
||||
spx_word32_t mel;
|
||||
spx_word16_t val;
|
||||
curr_freq = EXTRACT16(MULT16_32_P15(i,df));
|
||||
mel = toBARK(curr_freq);
|
||||
if (mel > max_mel)
|
||||
break;
|
||||
#ifdef FIXED_POINT
|
||||
id1 = DIV32(mel,mel_interval);
|
||||
#else
|
||||
id1 = (int)(floor(mel/mel_interval));
|
||||
#endif
|
||||
if (id1>banks-2)
|
||||
{
|
||||
id1 = banks-2;
|
||||
val = Q15_ONE;
|
||||
} else {
|
||||
val = DIV32_16(mel - id1*mel_interval,EXTRACT16(PSHR32(mel_interval,15)));
|
||||
}
|
||||
id2 = id1+1;
|
||||
bank->bank_left[i] = id1;
|
||||
bank->filter_left[i] = SUB16(Q15_ONE,val);
|
||||
bank->bank_right[i] = id2;
|
||||
bank->filter_right[i] = val;
|
||||
}
|
||||
|
||||
/* Think I can safely disable normalisation for fixed-point (and probably float as well) */
|
||||
#ifndef FIXED_POINT
|
||||
for (i=0;i<bank->nb_banks;i++)
|
||||
bank->scaling[i] = 0;
|
||||
for (i=0;i<bank->len;i++)
|
||||
{
|
||||
int id = bank->bank_left[i];
|
||||
bank->scaling[id] += bank->filter_left[i];
|
||||
id = bank->bank_right[i];
|
||||
bank->scaling[id] += bank->filter_right[i];
|
||||
}
|
||||
for (i=0;i<bank->nb_banks;i++)
|
||||
bank->scaling[i] = Q15_ONE/(bank->scaling[i]);
|
||||
#endif
|
||||
return bank;
|
||||
}
|
||||
|
||||
void filterbank_destroy(FilterBank *bank)
|
||||
{
|
||||
speex_free(bank->bank_left);
|
||||
speex_free(bank->bank_right);
|
||||
speex_free(bank->filter_left);
|
||||
speex_free(bank->filter_right);
|
||||
#ifndef FIXED_POINT
|
||||
speex_free(bank->scaling);
|
||||
#endif
|
||||
speex_free(bank);
|
||||
}
|
||||
|
||||
void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<bank->nb_banks;i++)
|
||||
mel[i] = 0;
|
||||
|
||||
for (i=0;i<bank->len;i++)
|
||||
{
|
||||
int id;
|
||||
id = bank->bank_left[i];
|
||||
mel[id] += MULT16_32_P15(bank->filter_left[i],ps[i]);
|
||||
id = bank->bank_right[i];
|
||||
mel[id] += MULT16_32_P15(bank->filter_right[i],ps[i]);
|
||||
}
|
||||
/* Think I can safely disable normalisation that for fixed-point (and probably float as well) */
|
||||
#ifndef FIXED_POINT
|
||||
/*for (i=0;i<bank->nb_banks;i++)
|
||||
mel[i] = MULT16_32_P15(Q15(bank->scaling[i]),mel[i]);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *ps)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<bank->len;i++)
|
||||
{
|
||||
spx_word32_t tmp;
|
||||
int id1, id2;
|
||||
id1 = bank->bank_left[i];
|
||||
id2 = bank->bank_right[i];
|
||||
tmp = MULT16_16(mel[id1],bank->filter_left[i]);
|
||||
tmp += MULT16_16(mel[id2],bank->filter_right[i]);
|
||||
ps[i] = EXTRACT16(PSHR32(tmp,15));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef FIXED_POINT
|
||||
void filterbank_compute_bank(FilterBank *bank, float *ps, float *mel)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<bank->nb_banks;i++)
|
||||
mel[i] = 0;
|
||||
|
||||
for (i=0;i<bank->len;i++)
|
||||
{
|
||||
int id = bank->bank_left[i];
|
||||
mel[id] += bank->filter_left[i]*ps[i];
|
||||
id = bank->bank_right[i];
|
||||
mel[id] += bank->filter_right[i]*ps[i];
|
||||
}
|
||||
for (i=0;i<bank->nb_banks;i++)
|
||||
mel[i] *= bank->scaling[i];
|
||||
}
|
||||
|
||||
void filterbank_compute_psd(FilterBank *bank, float *mel, float *ps)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<bank->len;i++)
|
||||
{
|
||||
int id = bank->bank_left[i];
|
||||
ps[i] = mel[id]*bank->filter_left[i];
|
||||
id = bank->bank_right[i];
|
||||
ps[i] += mel[id]*bank->filter_right[i];
|
||||
}
|
||||
}
|
||||
|
||||
void filterbank_psy_smooth(FilterBank *bank, float *ps, float *mask)
|
||||
{
|
||||
/* Low freq slope: 14 dB/Bark*/
|
||||
/* High freq slope: 9 dB/Bark*/
|
||||
/* Noise vs tone: 5 dB difference */
|
||||
/* FIXME: Temporary kludge */
|
||||
float bark[100];
|
||||
int i;
|
||||
/* Assumes 1/3 Bark resolution */
|
||||
float decay_low = 0.34145f;
|
||||
float decay_high = 0.50119f;
|
||||
filterbank_compute_bank(bank, ps, bark);
|
||||
for (i=1;i<bank->nb_banks;i++)
|
||||
{
|
||||
/*float decay_high = 13-1.6*log10(bark[i-1]);
|
||||
decay_high = pow(10,(-decay_high/30.f));*/
|
||||
bark[i] = bark[i] + decay_high*bark[i-1];
|
||||
}
|
||||
for (i=bank->nb_banks-2;i>=0;i--)
|
||||
{
|
||||
bark[i] = bark[i] + decay_low*bark[i+1];
|
||||
}
|
||||
filterbank_compute_psd(bank, bark, mask);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,66 +0,0 @@
|
|||
/* Copyright (C) 2006 Jean-Marc Valin */
|
||||
/**
|
||||
@file filterbank.h
|
||||
@brief Converting between psd and filterbank
|
||||
*/
|
||||
/*
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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 FILTERBANK_H
|
||||
#define FILTERBANK_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
typedef struct {
|
||||
int *bank_left;
|
||||
int *bank_right;
|
||||
spx_word16_t *filter_left;
|
||||
spx_word16_t *filter_right;
|
||||
#ifndef FIXED_POINT
|
||||
float *scaling;
|
||||
#endif
|
||||
int nb_banks;
|
||||
int len;
|
||||
} FilterBank;
|
||||
|
||||
|
||||
FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type);
|
||||
|
||||
void filterbank_destroy(FilterBank *bank);
|
||||
|
||||
void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel);
|
||||
|
||||
void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *psd);
|
||||
|
||||
#ifndef FIXED_POINT
|
||||
void filterbank_compute_bank(FilterBank *bank, float *psd, float *mel);
|
||||
void filterbank_compute_psd(FilterBank *bank, float *mel, float *psd);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -1,821 +0,0 @@
|
|||
/* Copyright (C) 2002-2006 Jean-Marc Valin
|
||||
File: filters.c
|
||||
Various analysis/synthesis filters
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "filters.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "arch.h"
|
||||
#include "math_approx.h"
|
||||
#include "ltp.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#include "filters_sse.h"
|
||||
#elif defined (ARM4_ASM) || defined(ARM5E_ASM)
|
||||
#include "filters_arm4.h"
|
||||
#elif defined (BFIN_ASM)
|
||||
#include "filters_bfin.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void bw_lpc(spx_word16_t gamma, const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order)
|
||||
{
|
||||
int i;
|
||||
spx_word16_t tmp=gamma;
|
||||
for (i=0;i<order;i++)
|
||||
{
|
||||
lpc_out[i] = MULT16_16_P15(tmp,lpc_in[i]);
|
||||
tmp = MULT16_16_P15(tmp, gamma);
|
||||
}
|
||||
}
|
||||
|
||||
void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
/* It's important we do the test that way so we can catch NaNs, which are neither greater nor smaller */
|
||||
if (!(vec[i]>=min_val && vec[i] <= max_val))
|
||||
{
|
||||
if (vec[i] < min_val)
|
||||
vec[i] = min_val;
|
||||
else if (vec[i] > max_val)
|
||||
vec[i] = max_val;
|
||||
else /* Has to be NaN */
|
||||
vec[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem)
|
||||
{
|
||||
int i;
|
||||
#ifdef FIXED_POINT
|
||||
const spx_word16_t Pcoef[5][3] = {{16384, -31313, 14991}, {16384, -31569, 15249}, {16384, -31677, 15328}, {16384, -32313, 15947}, {16384, -22446, 6537}};
|
||||
const spx_word16_t Zcoef[5][3] = {{15672, -31344, 15672}, {15802, -31601, 15802}, {15847, -31694, 15847}, {16162, -32322, 16162}, {14418, -28836, 14418}};
|
||||
#else
|
||||
const spx_word16_t Pcoef[5][3] = {{1.00000f, -1.91120f, 0.91498f}, {1.00000f, -1.92683f, 0.93071f}, {1.00000f, -1.93338f, 0.93553f}, {1.00000f, -1.97226f, 0.97332f}, {1.00000f, -1.37000f, 0.39900f}};
|
||||
const spx_word16_t Zcoef[5][3] = {{0.95654f, -1.91309f, 0.95654f}, {0.96446f, -1.92879f, 0.96446f}, {0.96723f, -1.93445f, 0.96723f}, {0.98645f, -1.97277f, 0.98645f}, {0.88000f, -1.76000f, 0.88000f}};
|
||||
#endif
|
||||
const spx_word16_t *den, *num;
|
||||
if (filtID>4)
|
||||
filtID=4;
|
||||
|
||||
den = Pcoef[filtID]; num = Zcoef[filtID];
|
||||
/*return;*/
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
spx_word16_t yi;
|
||||
spx_word32_t vout = ADD32(MULT16_16(num[0], x[i]),mem[0]);
|
||||
yi = EXTRACT16(SATURATE(PSHR32(vout,14),32767));
|
||||
mem[0] = ADD32(MAC16_16(mem[1], num[1],x[i]), SHL32(MULT16_32_Q15(-den[1],vout),1));
|
||||
mem[1] = ADD32(MULT16_16(num[2],x[i]), SHL32(MULT16_32_Q15(-den[2],vout),1));
|
||||
y[i] = yi;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
/* FIXME: These functions are ugly and probably introduce too much error */
|
||||
void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
y[i] = SHL32(MULT16_32_Q14(EXTRACT16(SHR32(x[i],7)),scale),7);
|
||||
}
|
||||
}
|
||||
|
||||
void signal_div(const spx_word16_t *x, spx_word16_t *y, spx_word32_t scale, int len)
|
||||
{
|
||||
int i;
|
||||
if (scale > SHL32(EXTEND32(SIG_SCALING), 8))
|
||||
{
|
||||
spx_word16_t scale_1;
|
||||
scale = PSHR32(scale, SIG_SHIFT);
|
||||
scale_1 = EXTRACT16(PDIV32_16(SHL32(EXTEND32(SIG_SCALING),7),scale));
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
y[i] = MULT16_16_P15(scale_1, x[i]);
|
||||
}
|
||||
} else if (scale > SHR32(EXTEND32(SIG_SCALING), 2)) {
|
||||
spx_word16_t scale_1;
|
||||
scale = PSHR32(scale, SIG_SHIFT-5);
|
||||
scale_1 = DIV32_16(SHL32(EXTEND32(SIG_SCALING),3),scale);
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
y[i] = PSHR32(MULT16_16(scale_1, SHL16(x[i],2)),8);
|
||||
}
|
||||
} else {
|
||||
spx_word16_t scale_1;
|
||||
scale = PSHR32(scale, SIG_SHIFT-7);
|
||||
if (scale < 5)
|
||||
scale = 5;
|
||||
scale_1 = DIV32_16(SHL32(EXTEND32(SIG_SCALING),3),scale);
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
y[i] = PSHR32(MULT16_16(scale_1, SHL16(x[i],2)),6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<len;i++)
|
||||
y[i] = scale*x[i];
|
||||
}
|
||||
|
||||
void signal_div(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
|
||||
{
|
||||
int i;
|
||||
float scale_1 = 1/scale;
|
||||
for (i=0;i<len;i++)
|
||||
y[i] = scale_1*x[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
|
||||
|
||||
spx_word16_t compute_rms(const spx_sig_t *x, int len)
|
||||
{
|
||||
int i;
|
||||
spx_word32_t sum=0;
|
||||
spx_sig_t max_val=1;
|
||||
int sig_shift;
|
||||
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
spx_sig_t tmp = x[i];
|
||||
if (tmp<0)
|
||||
tmp = -tmp;
|
||||
if (tmp > max_val)
|
||||
max_val = tmp;
|
||||
}
|
||||
|
||||
sig_shift=0;
|
||||
while (max_val>16383)
|
||||
{
|
||||
sig_shift++;
|
||||
max_val >>= 1;
|
||||
}
|
||||
|
||||
for (i=0;i<len;i+=4)
|
||||
{
|
||||
spx_word32_t sum2=0;
|
||||
spx_word16_t tmp;
|
||||
tmp = EXTRACT16(SHR32(x[i],sig_shift));
|
||||
sum2 = MAC16_16(sum2,tmp,tmp);
|
||||
tmp = EXTRACT16(SHR32(x[i+1],sig_shift));
|
||||
sum2 = MAC16_16(sum2,tmp,tmp);
|
||||
tmp = EXTRACT16(SHR32(x[i+2],sig_shift));
|
||||
sum2 = MAC16_16(sum2,tmp,tmp);
|
||||
tmp = EXTRACT16(SHR32(x[i+3],sig_shift));
|
||||
sum2 = MAC16_16(sum2,tmp,tmp);
|
||||
sum = ADD32(sum,SHR32(sum2,6));
|
||||
}
|
||||
|
||||
return EXTRACT16(PSHR32(SHL32(EXTEND32(spx_sqrt(DIV32(sum,len))),(sig_shift+3)),SIG_SHIFT));
|
||||
}
|
||||
|
||||
spx_word16_t compute_rms16(const spx_word16_t *x, int len)
|
||||
{
|
||||
int i;
|
||||
spx_word16_t max_val=10;
|
||||
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
spx_sig_t tmp = x[i];
|
||||
if (tmp<0)
|
||||
tmp = -tmp;
|
||||
if (tmp > max_val)
|
||||
max_val = tmp;
|
||||
}
|
||||
if (max_val>16383)
|
||||
{
|
||||
spx_word32_t sum=0;
|
||||
for (i=0;i<len;i+=4)
|
||||
{
|
||||
spx_word32_t sum2=0;
|
||||
sum2 = MAC16_16(sum2,SHR16(x[i],1),SHR16(x[i],1));
|
||||
sum2 = MAC16_16(sum2,SHR16(x[i+1],1),SHR16(x[i+1],1));
|
||||
sum2 = MAC16_16(sum2,SHR16(x[i+2],1),SHR16(x[i+2],1));
|
||||
sum2 = MAC16_16(sum2,SHR16(x[i+3],1),SHR16(x[i+3],1));
|
||||
sum = ADD32(sum,SHR32(sum2,6));
|
||||
}
|
||||
return SHL16(spx_sqrt(DIV32(sum,len)),4);
|
||||
} else {
|
||||
spx_word32_t sum=0;
|
||||
int sig_shift=0;
|
||||
if (max_val < 8192)
|
||||
sig_shift=1;
|
||||
if (max_val < 4096)
|
||||
sig_shift=2;
|
||||
if (max_val < 2048)
|
||||
sig_shift=3;
|
||||
for (i=0;i<len;i+=4)
|
||||
{
|
||||
spx_word32_t sum2=0;
|
||||
sum2 = MAC16_16(sum2,SHL16(x[i],sig_shift),SHL16(x[i],sig_shift));
|
||||
sum2 = MAC16_16(sum2,SHL16(x[i+1],sig_shift),SHL16(x[i+1],sig_shift));
|
||||
sum2 = MAC16_16(sum2,SHL16(x[i+2],sig_shift),SHL16(x[i+2],sig_shift));
|
||||
sum2 = MAC16_16(sum2,SHL16(x[i+3],sig_shift),SHL16(x[i+3],sig_shift));
|
||||
sum = ADD32(sum,SHR32(sum2,6));
|
||||
}
|
||||
return SHL16(spx_sqrt(DIV32(sum,len)),3-sig_shift);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef OVERRIDE_NORMALIZE16
|
||||
int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)
|
||||
{
|
||||
int i;
|
||||
spx_sig_t max_val=1;
|
||||
int sig_shift;
|
||||
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
spx_sig_t tmp = x[i];
|
||||
if (tmp<0)
|
||||
tmp = NEG32(tmp);
|
||||
if (tmp >= max_val)
|
||||
max_val = tmp;
|
||||
}
|
||||
|
||||
sig_shift=0;
|
||||
while (max_val>max_scale)
|
||||
{
|
||||
sig_shift++;
|
||||
max_val >>= 1;
|
||||
}
|
||||
|
||||
for (i=0;i<len;i++)
|
||||
y[i] = EXTRACT16(SHR32(x[i], sig_shift));
|
||||
|
||||
return sig_shift;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
spx_word16_t compute_rms(const spx_sig_t *x, int len)
|
||||
{
|
||||
int i;
|
||||
float sum=0;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
sum += x[i]*x[i];
|
||||
}
|
||||
return sqrt(.1+sum/len);
|
||||
}
|
||||
spx_word16_t compute_rms16(const spx_word16_t *x, int len)
|
||||
{
|
||||
return compute_rms(x, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef OVERRIDE_FILTER_MEM16
|
||||
void filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
int i,j;
|
||||
spx_word16_t xi,yi,nyi;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
xi= x[i];
|
||||
yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));
|
||||
nyi = NEG16(yi);
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = MAC16_16(MAC16_16(mem[j+1], num[j],xi), den[j],nyi);
|
||||
}
|
||||
mem[ord-1] = ADD32(MULT16_16(num[ord-1],xi), MULT16_16(den[ord-1],nyi));
|
||||
y[i] = yi;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_IIR_MEM16
|
||||
void iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
int i,j;
|
||||
spx_word16_t yi,nyi;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));
|
||||
nyi = NEG16(yi);
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = MAC16_16(mem[j+1],den[j],nyi);
|
||||
}
|
||||
mem[ord-1] = MULT16_16(den[ord-1],nyi);
|
||||
y[i] = yi;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_FIR_MEM16
|
||||
void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
int i,j;
|
||||
spx_word16_t xi,yi;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
xi=x[i];
|
||||
yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = MAC16_16(mem[j+1], num[j],xi);
|
||||
}
|
||||
mem[ord-1] = MULT16_16(num[ord-1],xi);
|
||||
y[i] = yi;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_mem_t *mem);
|
||||
ALLOC(mem, ord, spx_mem_t);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
iir_mem16(xx, ak, y, N, ord, mem, stack);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
filter_mem16(y, awk1, awk2, y, N, ord, mem, stack);
|
||||
}
|
||||
void residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_mem_t *mem);
|
||||
ALLOC(mem, ord, spx_mem_t);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
filter_mem16(xx, ak, awk1, y, N, ord, mem, stack);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
fir_mem16(y, awk2, y, N, ord, mem, stack);
|
||||
}
|
||||
|
||||
|
||||
#ifndef OVERRIDE_COMPUTE_IMPULSE_RESPONSE
|
||||
void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
|
||||
{
|
||||
int i,j;
|
||||
spx_word16_t y1, ny1i, ny2i;
|
||||
VARDECL(spx_mem_t *mem1);
|
||||
VARDECL(spx_mem_t *mem2);
|
||||
ALLOC(mem1, ord, spx_mem_t);
|
||||
ALLOC(mem2, ord, spx_mem_t);
|
||||
|
||||
y[0] = LPC_SCALING;
|
||||
for (i=0;i<ord;i++)
|
||||
y[i+1] = awk1[i];
|
||||
i++;
|
||||
for (;i<N;i++)
|
||||
y[i] = VERY_SMALL;
|
||||
for (i=0;i<ord;i++)
|
||||
mem1[i] = mem2[i] = 0;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
y1 = ADD16(y[i], EXTRACT16(PSHR32(mem1[0],LPC_SHIFT)));
|
||||
ny1i = NEG16(y1);
|
||||
y[i] = PSHR32(ADD32(SHL32(EXTEND32(y1),LPC_SHIFT+1),mem2[0]),LPC_SHIFT);
|
||||
ny2i = NEG16(y[i]);
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem1[j] = MAC16_16(mem1[j+1], awk2[j],ny1i);
|
||||
mem2[j] = MAC16_16(mem2[j+1], ak[j],ny2i);
|
||||
}
|
||||
mem1[ord-1] = MULT16_16(awk2[ord-1],ny1i);
|
||||
mem2[ord-1] = MULT16_16(ak[ord-1],ny2i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Decomposes a signal into low-band and high-band using a QMF */
|
||||
void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *y1, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack)
|
||||
{
|
||||
int i,j,k,M2;
|
||||
VARDECL(spx_word16_t *a);
|
||||
VARDECL(spx_word16_t *x);
|
||||
spx_word16_t *x2;
|
||||
|
||||
ALLOC(a, M, spx_word16_t);
|
||||
ALLOC(x, N+M-1, spx_word16_t);
|
||||
x2=x+M-1;
|
||||
M2=M>>1;
|
||||
for (i=0;i<M;i++)
|
||||
a[M-i-1]= aa[i];
|
||||
for (i=0;i<M-1;i++)
|
||||
x[i]=mem[M-i-2];
|
||||
for (i=0;i<N;i++)
|
||||
x[i+M-1]=SHR16(xx[i],1);
|
||||
for (i=0;i<M-1;i++)
|
||||
mem[i]=SHR16(xx[N-i-1],1);
|
||||
for (i=0,k=0;i<N;i+=2,k++)
|
||||
{
|
||||
spx_word32_t y1k=0, y2k=0;
|
||||
for (j=0;j<M2;j++)
|
||||
{
|
||||
y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));
|
||||
y2k=SUB32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));
|
||||
j++;
|
||||
y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));
|
||||
y2k=ADD32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));
|
||||
}
|
||||
y1[k] = EXTRACT16(SATURATE(PSHR32(y1k,15),32767));
|
||||
y2[k] = EXTRACT16(SATURATE(PSHR32(y2k,15),32767));
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-synthesised a signal from the QMF low-band and high-band signals */
|
||||
void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack)
|
||||
/* assumptions:
|
||||
all odd x[i] are zero -- well, actually they are left out of the array now
|
||||
N and M are multiples of 4 */
|
||||
{
|
||||
int i, j;
|
||||
int M2, N2;
|
||||
VARDECL(spx_word16_t *xx1);
|
||||
VARDECL(spx_word16_t *xx2);
|
||||
|
||||
M2 = M>>1;
|
||||
N2 = N>>1;
|
||||
ALLOC(xx1, M2+N2, spx_word16_t);
|
||||
ALLOC(xx2, M2+N2, spx_word16_t);
|
||||
|
||||
for (i = 0; i < N2; i++)
|
||||
xx1[i] = x1[N2-1-i];
|
||||
for (i = 0; i < M2; i++)
|
||||
xx1[N2+i] = mem1[2*i+1];
|
||||
for (i = 0; i < N2; i++)
|
||||
xx2[i] = x2[N2-1-i];
|
||||
for (i = 0; i < M2; i++)
|
||||
xx2[N2+i] = mem2[2*i+1];
|
||||
|
||||
for (i = 0; i < N2; i += 2) {
|
||||
spx_sig_t y0, y1, y2, y3;
|
||||
spx_word16_t x10, x20;
|
||||
|
||||
y0 = y1 = y2 = y3 = 0;
|
||||
x10 = xx1[N2-2-i];
|
||||
x20 = xx2[N2-2-i];
|
||||
|
||||
for (j = 0; j < M2; j += 2) {
|
||||
spx_word16_t x11, x21;
|
||||
spx_word16_t a0, a1;
|
||||
|
||||
a0 = a[2*j];
|
||||
a1 = a[2*j+1];
|
||||
x11 = xx1[N2-1+j-i];
|
||||
x21 = xx2[N2-1+j-i];
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
/* We multiply twice by the same coef to avoid overflows */
|
||||
y0 = MAC16_16(MAC16_16(y0, a0, x11), NEG16(a0), x21);
|
||||
y1 = MAC16_16(MAC16_16(y1, a1, x11), a1, x21);
|
||||
y2 = MAC16_16(MAC16_16(y2, a0, x10), NEG16(a0), x20);
|
||||
y3 = MAC16_16(MAC16_16(y3, a1, x10), a1, x20);
|
||||
#else
|
||||
y0 = ADD32(y0,MULT16_16(a0, x11-x21));
|
||||
y1 = ADD32(y1,MULT16_16(a1, x11+x21));
|
||||
y2 = ADD32(y2,MULT16_16(a0, x10-x20));
|
||||
y3 = ADD32(y3,MULT16_16(a1, x10+x20));
|
||||
#endif
|
||||
a0 = a[2*j+2];
|
||||
a1 = a[2*j+3];
|
||||
x10 = xx1[N2+j-i];
|
||||
x20 = xx2[N2+j-i];
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
/* We multiply twice by the same coef to avoid overflows */
|
||||
y0 = MAC16_16(MAC16_16(y0, a0, x10), NEG16(a0), x20);
|
||||
y1 = MAC16_16(MAC16_16(y1, a1, x10), a1, x20);
|
||||
y2 = MAC16_16(MAC16_16(y2, a0, x11), NEG16(a0), x21);
|
||||
y3 = MAC16_16(MAC16_16(y3, a1, x11), a1, x21);
|
||||
#else
|
||||
y0 = ADD32(y0,MULT16_16(a0, x10-x20));
|
||||
y1 = ADD32(y1,MULT16_16(a1, x10+x20));
|
||||
y2 = ADD32(y2,MULT16_16(a0, x11-x21));
|
||||
y3 = ADD32(y3,MULT16_16(a1, x11+x21));
|
||||
#endif
|
||||
}
|
||||
#ifdef FIXED_POINT
|
||||
y[2*i] = EXTRACT16(SATURATE32(PSHR32(y0,15),32767));
|
||||
y[2*i+1] = EXTRACT16(SATURATE32(PSHR32(y1,15),32767));
|
||||
y[2*i+2] = EXTRACT16(SATURATE32(PSHR32(y2,15),32767));
|
||||
y[2*i+3] = EXTRACT16(SATURATE32(PSHR32(y3,15),32767));
|
||||
#else
|
||||
/* Normalize up explicitly if we're in float */
|
||||
y[2*i] = 2.f*y0;
|
||||
y[2*i+1] = 2.f*y1;
|
||||
y[2*i+2] = 2.f*y2;
|
||||
y[2*i+3] = 2.f*y3;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < M2; i++)
|
||||
mem1[2*i+1] = xx1[i];
|
||||
for (i = 0; i < M2; i++)
|
||||
mem2[2*i+1] = xx2[i];
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#if 0
|
||||
const spx_word16_t shift_filt[3][7] = {{-33, 1043, -4551, 19959, 19959, -4551, 1043},
|
||||
{-98, 1133, -4425, 29179, 8895, -2328, 444},
|
||||
{444, -2328, 8895, 29179, -4425, 1133, -98}};
|
||||
#else
|
||||
const spx_word16_t shift_filt[3][7] = {{-390, 1540, -4993, 20123, 20123, -4993, 1540},
|
||||
{-1064, 2817, -6694, 31589, 6837, -990, -209},
|
||||
{-209, -990, 6837, 31589, -6694, 2817, -1064}};
|
||||
#endif
|
||||
#else
|
||||
#if 0
|
||||
const float shift_filt[3][7] = {{-9.9369e-04, 3.1831e-02, -1.3889e-01, 6.0910e-01, 6.0910e-01, -1.3889e-01, 3.1831e-02},
|
||||
{-0.0029937, 0.0345613, -0.1350474, 0.8904793, 0.2714479, -0.0710304, 0.0135403},
|
||||
{0.0135403, -0.0710304, 0.2714479, 0.8904793, -0.1350474, 0.0345613, -0.0029937}};
|
||||
#else
|
||||
const float shift_filt[3][7] = {{-0.011915f, 0.046995f, -0.152373f, 0.614108f, 0.614108f, -0.152373f, 0.046995f},
|
||||
{-0.0324855f, 0.0859768f, -0.2042986f, 0.9640297f, 0.2086420f, -0.0302054f, -0.0063646f},
|
||||
{-0.0063646f, -0.0302054f, 0.2086420f, 0.9640297f, -0.2042986f, 0.0859768f, -0.0324855f}};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int interp_pitch(
|
||||
spx_word16_t *exc, /*decoded excitation*/
|
||||
spx_word16_t *interp, /*decoded excitation*/
|
||||
int pitch, /*pitch period*/
|
||||
int len
|
||||
)
|
||||
{
|
||||
int i,j,k;
|
||||
spx_word32_t corr[4][7];
|
||||
spx_word32_t maxcorr;
|
||||
int maxi, maxj;
|
||||
for (i=0;i<7;i++)
|
||||
{
|
||||
corr[0][i] = inner_prod(exc, exc-pitch-3+i, len);
|
||||
}
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
for (j=0;j<7;j++)
|
||||
{
|
||||
int i1, i2;
|
||||
spx_word32_t tmp=0;
|
||||
i1 = 3-j;
|
||||
if (i1<0)
|
||||
i1 = 0;
|
||||
i2 = 10-j;
|
||||
if (i2>7)
|
||||
i2 = 7;
|
||||
for (k=i1;k<i2;k++)
|
||||
tmp += MULT16_32_Q15(shift_filt[i][k],corr[0][j+k-3]);
|
||||
corr[i+1][j] = tmp;
|
||||
}
|
||||
}
|
||||
maxi=maxj=0;
|
||||
maxcorr = corr[0][0];
|
||||
for (i=0;i<4;i++)
|
||||
{
|
||||
for (j=0;j<7;j++)
|
||||
{
|
||||
if (corr[i][j] > maxcorr)
|
||||
{
|
||||
maxcorr = corr[i][j];
|
||||
maxi=i;
|
||||
maxj=j;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
spx_word32_t tmp = 0;
|
||||
if (maxi>0)
|
||||
{
|
||||
for (k=0;k<7;k++)
|
||||
{
|
||||
tmp += MULT16_16(exc[i-(pitch-maxj+3)+k-3],shift_filt[maxi-1][k]);
|
||||
}
|
||||
} else {
|
||||
tmp = SHL32(exc[i-(pitch-maxj+3)],15);
|
||||
}
|
||||
interp[i] = PSHR32(tmp,15);
|
||||
}
|
||||
return pitch-maxj+3;
|
||||
}
|
||||
|
||||
void multicomb(
|
||||
spx_word16_t *exc, /*decoded excitation*/
|
||||
spx_word16_t *new_exc, /*enhanced excitation*/
|
||||
spx_coef_t *ak, /*LPC filter coefs*/
|
||||
int p, /*LPC order*/
|
||||
int nsf, /*sub-frame size*/
|
||||
int pitch, /*pitch period*/
|
||||
int max_pitch,
|
||||
spx_word16_t comb_gain, /*gain of comb filter*/
|
||||
char *stack
|
||||
)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_word16_t *iexc);
|
||||
spx_word16_t old_ener, new_ener;
|
||||
int corr_pitch;
|
||||
|
||||
spx_word16_t iexc0_mag, iexc1_mag, exc_mag;
|
||||
spx_word32_t corr0, corr1;
|
||||
spx_word16_t gain0, gain1;
|
||||
spx_word16_t pgain1, pgain2;
|
||||
spx_word16_t c1, c2;
|
||||
spx_word16_t g1, g2;
|
||||
spx_word16_t ngain;
|
||||
spx_word16_t gg1, gg2;
|
||||
#ifdef FIXED_POINT
|
||||
int scaledown=0;
|
||||
#endif
|
||||
#if 0 /* Set to 1 to enable full pitch search */
|
||||
int nol_pitch[6];
|
||||
spx_word16_t nol_pitch_coef[6];
|
||||
spx_word16_t ol_pitch_coef;
|
||||
open_loop_nbest_pitch(exc, 20, 120, nsf,
|
||||
nol_pitch, nol_pitch_coef, 6, stack);
|
||||
corr_pitch=nol_pitch[0];
|
||||
ol_pitch_coef = nol_pitch_coef[0];
|
||||
/*Try to remove pitch multiples*/
|
||||
for (i=1;i<6;i++)
|
||||
{
|
||||
#ifdef FIXED_POINT
|
||||
if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],19661)) &&
|
||||
#else
|
||||
if ((nol_pitch_coef[i]>.6*nol_pitch_coef[0]) &&
|
||||
#endif
|
||||
(ABS(2*nol_pitch[i]-corr_pitch)<=2 || ABS(3*nol_pitch[i]-corr_pitch)<=3 ||
|
||||
ABS(4*nol_pitch[i]-corr_pitch)<=4 || ABS(5*nol_pitch[i]-corr_pitch)<=5))
|
||||
{
|
||||
corr_pitch = nol_pitch[i];
|
||||
}
|
||||
}
|
||||
#else
|
||||
corr_pitch = pitch;
|
||||
#endif
|
||||
|
||||
ALLOC(iexc, 2*nsf, spx_word16_t);
|
||||
|
||||
interp_pitch(exc, iexc, corr_pitch, 80);
|
||||
if (corr_pitch>max_pitch)
|
||||
interp_pitch(exc, iexc+nsf, 2*corr_pitch, 80);
|
||||
else
|
||||
interp_pitch(exc, iexc+nsf, -corr_pitch, 80);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
if (ABS16(exc[i])>16383)
|
||||
{
|
||||
scaledown = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scaledown)
|
||||
{
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i] = SHR16(exc[i],1);
|
||||
for (i=0;i<2*nsf;i++)
|
||||
iexc[i] = SHR16(iexc[i],1);
|
||||
}
|
||||
#endif
|
||||
/*interp_pitch(exc, iexc+2*nsf, 2*corr_pitch, 80);*/
|
||||
|
||||
/*printf ("%d %d %f\n", pitch, corr_pitch, max_corr*ener_1);*/
|
||||
iexc0_mag = spx_sqrt(1000+inner_prod(iexc,iexc,nsf));
|
||||
iexc1_mag = spx_sqrt(1000+inner_prod(iexc+nsf,iexc+nsf,nsf));
|
||||
exc_mag = spx_sqrt(1+inner_prod(exc,exc,nsf));
|
||||
corr0 = inner_prod(iexc,exc,nsf);
|
||||
if (corr0<0)
|
||||
corr0=0;
|
||||
corr1 = inner_prod(iexc+nsf,exc,nsf);
|
||||
if (corr1<0)
|
||||
corr1=0;
|
||||
#ifdef FIXED_POINT
|
||||
/* Doesn't cost much to limit the ratio and it makes the rest easier */
|
||||
if (SHL32(EXTEND32(iexc0_mag),6) < EXTEND32(exc_mag))
|
||||
iexc0_mag = ADD16(1,PSHR16(exc_mag,6));
|
||||
if (SHL32(EXTEND32(iexc1_mag),6) < EXTEND32(exc_mag))
|
||||
iexc1_mag = ADD16(1,PSHR16(exc_mag,6));
|
||||
#endif
|
||||
if (corr0 > MULT16_16(iexc0_mag,exc_mag))
|
||||
pgain1 = QCONST16(1., 14);
|
||||
else
|
||||
pgain1 = PDIV32_16(SHL32(PDIV32(corr0, exc_mag),14),iexc0_mag);
|
||||
if (corr1 > MULT16_16(iexc1_mag,exc_mag))
|
||||
pgain2 = QCONST16(1., 14);
|
||||
else
|
||||
pgain2 = PDIV32_16(SHL32(PDIV32(corr1, exc_mag),14),iexc1_mag);
|
||||
gg1 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc0_mag);
|
||||
gg2 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc1_mag);
|
||||
if (comb_gain>0)
|
||||
{
|
||||
#ifdef FIXED_POINT
|
||||
c1 = (MULT16_16_Q15(QCONST16(.4,15),comb_gain)+QCONST16(.07,15));
|
||||
c2 = QCONST16(.5,15)+MULT16_16_Q14(QCONST16(1.72,14),(c1-QCONST16(.07,15)));
|
||||
#else
|
||||
c1 = .4*comb_gain+.07;
|
||||
c2 = .5+1.72*(c1-.07);
|
||||
#endif
|
||||
} else
|
||||
{
|
||||
c1=c2=0;
|
||||
}
|
||||
#ifdef FIXED_POINT
|
||||
g1 = 32767 - MULT16_16_Q13(MULT16_16_Q15(c2, pgain1),pgain1);
|
||||
g2 = 32767 - MULT16_16_Q13(MULT16_16_Q15(c2, pgain2),pgain2);
|
||||
#else
|
||||
g1 = 1-c2*pgain1*pgain1;
|
||||
g2 = 1-c2*pgain2*pgain2;
|
||||
#endif
|
||||
if (g1<c1)
|
||||
g1 = c1;
|
||||
if (g2<c1)
|
||||
g2 = c1;
|
||||
g1 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g1);
|
||||
g2 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g2);
|
||||
if (corr_pitch>max_pitch)
|
||||
{
|
||||
gain0 = MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q14(g1,gg1));
|
||||
gain1 = MULT16_16_Q15(QCONST16(.3,15),MULT16_16_Q14(g2,gg2));
|
||||
} else {
|
||||
gain0 = MULT16_16_Q15(QCONST16(.6,15),MULT16_16_Q14(g1,gg1));
|
||||
gain1 = MULT16_16_Q15(QCONST16(.6,15),MULT16_16_Q14(g2,gg2));
|
||||
}
|
||||
for (i=0;i<nsf;i++)
|
||||
new_exc[i] = ADD16(exc[i], EXTRACT16(PSHR32(ADD32(MULT16_16(gain0,iexc[i]), MULT16_16(gain1,iexc[i+nsf])),8)));
|
||||
/* FIXME: compute_rms16 is currently not quite accurate enough (but close) */
|
||||
new_ener = compute_rms16(new_exc, nsf);
|
||||
old_ener = compute_rms16(exc, nsf);
|
||||
|
||||
if (old_ener < 1)
|
||||
old_ener = 1;
|
||||
if (new_ener < 1)
|
||||
new_ener = 1;
|
||||
if (old_ener > new_ener)
|
||||
old_ener = new_ener;
|
||||
ngain = PDIV32_16(SHL32(EXTEND32(old_ener),14),new_ener);
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
new_exc[i] = MULT16_16_Q14(ngain, new_exc[i]);
|
||||
#ifdef FIXED_POINT
|
||||
if (scaledown)
|
||||
{
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i] = SHL16(exc[i],1);
|
||||
for (i=0;i<nsf;i++)
|
||||
new_exc[i] = SHL16(SATURATE16(new_exc[i],16383),1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file filters.h
|
||||
@brief Various analysis/synthesis filters
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FILTERS_H
|
||||
#define FILTERS_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
spx_word16_t compute_rms(const spx_sig_t *x, int len);
|
||||
spx_word16_t compute_rms16(const spx_word16_t *x, int len);
|
||||
void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len);
|
||||
void signal_div(const spx_word16_t *x, spx_word16_t *y, spx_word32_t scale, int len);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define HIGHPASS_NARROWBAND 0
|
||||
#define HIGHPASS_WIDEBAND 2
|
||||
#define HIGHPASS_INPUT 0
|
||||
#define HIGHPASS_OUTPUT 1
|
||||
#define HIGHPASS_IRS 4
|
||||
|
||||
void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem);
|
||||
|
||||
|
||||
void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack);
|
||||
void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack);
|
||||
|
||||
void filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);
|
||||
void iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);
|
||||
void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);
|
||||
|
||||
/* Apply bandwidth expansion on LPC coef */
|
||||
void bw_lpc(spx_word16_t , const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order);
|
||||
void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len);
|
||||
|
||||
|
||||
void syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
|
||||
void residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
|
||||
|
||||
void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
|
||||
|
||||
void multicomb(
|
||||
spx_word16_t *exc, /*decoded excitation*/
|
||||
spx_word16_t *new_exc, /*enhanced excitation*/
|
||||
spx_coef_t *ak, /*LPC filter coefs*/
|
||||
int p, /*LPC order*/
|
||||
int nsf, /*sub-frame size*/
|
||||
int pitch, /*pitch period*/
|
||||
int max_pitch, /*pitch gain (3-tap)*/
|
||||
spx_word16_t comb_gain, /*gain of comb filter*/
|
||||
char *stack
|
||||
);
|
||||
|
||||
#endif
|
|
@ -1,96 +0,0 @@
|
|||
/* Copyright (C) 2004 Jean-Marc Valin */
|
||||
/**
|
||||
@file filters_arm4.h
|
||||
@brief Various analysis/synthesis filters (ARM4 version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define OVERRIDE_NORMALIZE16
|
||||
int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)
|
||||
{
|
||||
spx_sig_t max_val=1;
|
||||
int sig_shift;
|
||||
int dead1, dead2, dead3, dead4, dead5, dead6;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"\tmov %1, #1 \n"
|
||||
"\tmov %3, #0 \n"
|
||||
|
||||
".normalize16loop1%=: \n"
|
||||
|
||||
"\tldr %4, [%0], #4 \n"
|
||||
"\tcmps %4, %1 \n"
|
||||
"\tmovgt %1, %4 \n"
|
||||
"\tcmps %4, %3 \n"
|
||||
"\tmovlt %3, %4 \n"
|
||||
|
||||
"\tsubs %2, %2, #1 \n"
|
||||
"\tbne .normalize16loop1%=\n"
|
||||
|
||||
"\trsb %3, %3, #0 \n"
|
||||
"\tcmp %1, %3 \n"
|
||||
"\tmovlt %1, %3 \n"
|
||||
: "=r" (dead1), "=r" (max_val), "=r" (dead3), "=r" (dead4),
|
||||
"=r" (dead5), "=r" (dead6)
|
||||
: "0" (x), "2" (len)
|
||||
: "cc");
|
||||
|
||||
sig_shift=0;
|
||||
while (max_val>max_scale)
|
||||
{
|
||||
sig_shift++;
|
||||
max_val >>= 1;
|
||||
}
|
||||
|
||||
__asm__ __volatile__ (
|
||||
".normalize16loop%=: \n"
|
||||
|
||||
"\tldr %4, [%0], #4 \n"
|
||||
"\tldr %5, [%0], #4 \n"
|
||||
"\tmov %4, %4, asr %3 \n"
|
||||
"\tstrh %4, [%1], #2 \n"
|
||||
"\tldr %4, [%0], #4 \n"
|
||||
"\tmov %5, %5, asr %3 \n"
|
||||
"\tstrh %5, [%1], #2 \n"
|
||||
"\tldr %5, [%0], #4 \n"
|
||||
"\tmov %4, %4, asr %3 \n"
|
||||
"\tstrh %4, [%1], #2 \n"
|
||||
"\tsubs %2, %2, #1 \n"
|
||||
"\tmov %5, %5, asr %3 \n"
|
||||
"\tstrh %5, [%1], #2 \n"
|
||||
|
||||
"\tbgt .normalize16loop%=\n"
|
||||
: "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
|
||||
"=r" (dead5), "=r" (dead6)
|
||||
: "0" (x), "1" (y), "2" (len>>2), "3" (sig_shift)
|
||||
: "cc", "memory");
|
||||
return sig_shift;
|
||||
}
|
||||
|
|
@ -1,515 +0,0 @@
|
|||
/* Copyright (C) 2005 Analog Devices */
|
||||
/**
|
||||
@file filters_bfin.h
|
||||
@brief Various analysis/synthesis filters (Blackfin version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define OVERRIDE_NORMALIZE16
|
||||
int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)
|
||||
{
|
||||
spx_sig_t max_val=1;
|
||||
int sig_shift;
|
||||
__asm__
|
||||
(
|
||||
"%0 = 0;\n\t"
|
||||
"I0 = %1;\n\t"
|
||||
"L0 = 0;\n\t"
|
||||
"R1 = [I0++];\n\t"
|
||||
"LOOP norm_max%= LC0 = %2;\n\t"
|
||||
"LOOP_BEGIN norm_max%=;\n\t"
|
||||
"R2 = ABS R1 || R1 = [I0++];\n\t"
|
||||
"%0 = MAX(%0, R2);\n\t"
|
||||
"LOOP_END norm_max%=;\n\t"
|
||||
: "=&d" (max_val)
|
||||
: "a" (x), "a" (len)
|
||||
: "R1", "R2"
|
||||
);
|
||||
|
||||
sig_shift=0;
|
||||
while (max_val>max_scale)
|
||||
{
|
||||
sig_shift++;
|
||||
max_val >>= 1;
|
||||
}
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"I0 = %0;\n\t"
|
||||
"L0 = 0;\n\t"
|
||||
"P1 = %1;\n\t"
|
||||
"R0 = [I0++];\n\t"
|
||||
"LOOP norm_shift%= LC0 = %3;\n\t"
|
||||
"LOOP_BEGIN norm_shift%=;\n\t"
|
||||
"R1 = ASHIFT R0 by %2.L || R0 = [I0++];\n\t"
|
||||
"W[P1++] = R1;\n\t"
|
||||
"LOOP_END norm_shift%=;\n\t"
|
||||
"R1 = ASHIFT R0 by %2.L;\n\t"
|
||||
"W[P1++] = R1;\n\t"
|
||||
: : "a" (x), "a" (y), "d" (-sig_shift), "a" (len-1)
|
||||
: "I0", "L0", "P1", "R0", "R1", "memory"
|
||||
);
|
||||
return sig_shift;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define OVERRIDE_FILTER_MEM16
|
||||
void filter_mem16(const spx_word16_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *_y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
VARDECL(spx_word32_t *xy2);
|
||||
VARDECL(spx_word32_t *numden_a);
|
||||
spx_word32_t *xy;
|
||||
spx_word16_t *numden;
|
||||
int i;
|
||||
|
||||
ALLOC(xy2, (N+1), spx_word32_t);
|
||||
ALLOC(numden_a, (2*ord+2), spx_word32_t);
|
||||
xy = xy2+1;
|
||||
numden = (spx_word16_t*) numden_a;
|
||||
|
||||
for (i=0;i<ord;i++)
|
||||
{
|
||||
numden[2*i] = num[i];
|
||||
numden[2*i+1] = den[i];
|
||||
}
|
||||
__asm__ __volatile__
|
||||
(
|
||||
/* Register setup */
|
||||
"R0 = %5;\n\t" /*ord */
|
||||
|
||||
"P0 = %3;\n\t"
|
||||
"I0 = P0;\n\t"
|
||||
"B0 = P0;\n\t" /* numden */
|
||||
"L0 = 0;\n\t"
|
||||
|
||||
"P2 = %0;\n\t" /* Fused xy */
|
||||
"I2 = P2;\n\t"
|
||||
"L2 = 0;\n\t"
|
||||
|
||||
"P4 = %6;\n\t" /* mem */
|
||||
"P0 = %1;\n\t" /* _x */
|
||||
"P1 = %2;\n\t" /* _y */
|
||||
|
||||
/* First sample */
|
||||
"R1 = [P4++];\n\t"
|
||||
"R1 <<= 3;\n\t" /* shift mem */
|
||||
"R1.L = R1 (RND);\n\t"
|
||||
"R2 = W[P0++];\n\t" /* load x[0] */
|
||||
"R1.L = R1.L + R2.L;\n\t"
|
||||
"W[P1++] = R1;\n\t" /* store y[0] */
|
||||
"R2 = PACK(R1.L, R2.L);\n\t" /* pack x16 and y16 */
|
||||
"[P2] = R2;\n\t"
|
||||
|
||||
/* Samples 1 to ord-1 (using memory) */
|
||||
"R0 += -1;\n\t"
|
||||
"R3 = 0;\n\t"
|
||||
"LC0 = R0;\n\t"
|
||||
"LOOP filter_start%= LC0;\n\t"
|
||||
"LOOP_BEGIN filter_start%=;\n\t"
|
||||
"R3 += 1;\n\t"
|
||||
"LC1 = R3;\n\t"
|
||||
|
||||
"R1 = [P4++];\n\t"
|
||||
"A1 = R1;\n\t"
|
||||
"A0 = 0;\n\t"
|
||||
"I0 = B0;\n\t"
|
||||
"I2 = P2;\n\t"
|
||||
"P2 += 4;\n\t"
|
||||
"R4 = [I0++] || R5 = [I2--];\n\t"
|
||||
"LOOP filter_start_inner%= LC1;\n\t"
|
||||
"LOOP_BEGIN filter_start_inner%=;\n\t"
|
||||
"A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t"
|
||||
"LOOP_END filter_start_inner%=;\n\t"
|
||||
"A0 += A1;\n\t"
|
||||
"R4 = A0;\n\t"
|
||||
"R4 <<= 3;\n\t" /* shift mem */
|
||||
"R4.L = R4 (RND);\n\t"
|
||||
"R2 = W[P0++];\n\t" /* load x */
|
||||
"R4.L = R4.L + R2.L;\n\t"
|
||||
"W[P1++] = R4;\n\t" /* store y */
|
||||
//"R4 <<= 2;\n\t"
|
||||
//"R2 <<= 2;\n\t"
|
||||
"R2 = PACK(R4.L, R2.L);\n\t" /* pack x16 and y16 */
|
||||
"[P2] = R2;\n\t"
|
||||
|
||||
"LOOP_END filter_start%=;\n\t"
|
||||
|
||||
/* Samples ord to N*/
|
||||
"R0 = %5;\n\t"
|
||||
"R0 <<= 1;\n\t"
|
||||
"I0 = B0;\n\t" /* numden */
|
||||
"R0 <<= 1;\n\t"
|
||||
"L0 = R0;\n\t"
|
||||
|
||||
"R0 = %5;\n\t" /* org */
|
||||
"R2 = %4;\n\t" /* N */
|
||||
"R2 = R2 - R0;\n\t"
|
||||
"R4 = [I0++];\n\t" /* numden */
|
||||
"LC0 = R2;\n\t"
|
||||
"P3 = R0;\n\t"
|
||||
"R0 <<= 2;\n\t"
|
||||
"R0 += 8;\n\t"
|
||||
"I2 = P2;\n\t"
|
||||
"M0 = R0;\n\t"
|
||||
"A1 = A0 = 0;\n\t"
|
||||
"R5 = [I2--];\n\t" /* load xy */
|
||||
"LOOP filter_mid%= LC0;\n\t"
|
||||
"LOOP_BEGIN filter_mid%=;\n\t"
|
||||
"LOOP filter_mid_inner%= LC1=P3;\n\t"
|
||||
"LOOP_BEGIN filter_mid_inner%=;\n\t"
|
||||
"A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t"
|
||||
"LOOP_END filter_mid_inner%=;\n\t"
|
||||
"R0 = (A0 += A1) || I2 += M0;\n\t"
|
||||
"R0 = R0 << 3 || R5 = W[P0++];\n\t" /* load x */
|
||||
"R0.L = R0 (RND);\n\t"
|
||||
"R0.L = R0.L + R5.L;\n\t"
|
||||
"R5 = PACK(R0.L, R5.L) || W[P1++] = R0;\n\t" /* shift y | store y */
|
||||
"A1 = A0 = 0 || [I2--] = R5\n\t"
|
||||
"LOOP_END filter_mid%=;\n\t"
|
||||
"I2 += 4;\n\t"
|
||||
"P2 = I2;\n\t"
|
||||
/* Update memory */
|
||||
"P4 = %6;\n\t"
|
||||
"R0 = %5;\n\t"
|
||||
"LC0 = R0;\n\t"
|
||||
"P0 = B0;\n\t"
|
||||
"A1 = A0 = 0;\n\t"
|
||||
"LOOP mem_update%= LC0;\n\t"
|
||||
"LOOP_BEGIN mem_update%=;\n\t"
|
||||
"I2 = P2;\n\t"
|
||||
"I0 = P0;\n\t"
|
||||
"P0 += 4;\n\t"
|
||||
"R0 = LC0;\n\t"
|
||||
"LC1 = R0;\n\t"
|
||||
"R5 = [I2--] || R4 = [I0++];\n\t"
|
||||
"LOOP mem_accum%= LC1;\n\t"
|
||||
"LOOP_BEGIN mem_accum%=;\n\t"
|
||||
"A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t"
|
||||
"LOOP_END mem_accum%=;\n\t"
|
||||
"R0 = (A0 += A1);\n\t"
|
||||
"A1 = A0 = 0 || [P4++] = R0;\n\t"
|
||||
"LOOP_END mem_update%=;\n\t"
|
||||
"L0 = 0;\n\t"
|
||||
: : "m" (xy), "m" (_x), "m" (_y), "m" (numden), "m" (N), "m" (ord), "m" (mem)
|
||||
: "A0", "A1", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1", "P2", "P3", "P4", "B0", "I0", "I2", "L0", "L2", "M0", "memory"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define OVERRIDE_IIR_MEM16
|
||||
void iir_mem16(const spx_word16_t *_x, const spx_coef_t *den, spx_word16_t *_y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
VARDECL(spx_word16_t *y);
|
||||
spx_word16_t *yy;
|
||||
|
||||
ALLOC(y, (N+2), spx_word16_t);
|
||||
yy = y+2;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
/* Register setup */
|
||||
"R0 = %5;\n\t" /*ord */
|
||||
|
||||
"P1 = %3;\n\t"
|
||||
"I1 = P1;\n\t"
|
||||
"B1 = P1;\n\t"
|
||||
"L1 = 0;\n\t"
|
||||
|
||||
"P3 = %0;\n\t"
|
||||
"I3 = P3;\n\t"
|
||||
"L3 = 0;\n\t"
|
||||
|
||||
"P4 = %6;\n\t"
|
||||
"P0 = %1;\n\t"
|
||||
"P1 = %2;\n\t"
|
||||
|
||||
/* First sample */
|
||||
"R1 = [P4++];\n\t"
|
||||
"R1 = R1 << 3 (S);\n\t"
|
||||
"R1.L = R1 (RND);\n\t"
|
||||
"R2 = W[P0++];\n\t"
|
||||
"R1 = R1 + R2;\n\t"
|
||||
"W[P1++] = R1;\n\t"
|
||||
"W[P3] = R1;\n\t"
|
||||
|
||||
/* Samples 1 to ord-1 (using memory) */
|
||||
"R0 += -1;\n\t"
|
||||
"R3 = 0;\n\t"
|
||||
"LC0 = R0;\n\t"
|
||||
"LOOP filter_start%= LC0;\n\t"
|
||||
"LOOP_BEGIN filter_start%=;\n\t"
|
||||
"R3 += 1;\n\t"
|
||||
"LC1 = R3;\n\t"
|
||||
|
||||
"R1 = [P4++];\n\t"
|
||||
"A1 = R1;\n\t"
|
||||
"I1 = B1;\n\t"
|
||||
"I3 = P3;\n\t"
|
||||
"P3 += 2;\n\t"
|
||||
"LOOP filter_start_inner%= LC1;\n\t"
|
||||
"LOOP_BEGIN filter_start_inner%=;\n\t"
|
||||
"R4.L = W[I1++];\n\t"
|
||||
"R5.L = W[I3--];\n\t"
|
||||
"A1 -= R4.L*R5.L (IS);\n\t"
|
||||
"LOOP_END filter_start_inner%=;\n\t"
|
||||
|
||||
"R1 = A1;\n\t"
|
||||
"R1 <<= 3;\n\t"
|
||||
"R1.L = R1 (RND);\n\t"
|
||||
"R2 = W[P0++];\n\t"
|
||||
"R1 = R1 + R2;\n\t"
|
||||
"W[P1++] = R1;\n\t"
|
||||
"W[P3] = R1;\n\t"
|
||||
"LOOP_END filter_start%=;\n\t"
|
||||
|
||||
/* Samples ord to N*/
|
||||
"R0 = %5;\n\t"
|
||||
"R0 <<= 1;\n\t"
|
||||
"I1 = B1;\n\t"
|
||||
"L1 = R0;\n\t"
|
||||
|
||||
"R0 = %5;\n\t"
|
||||
"R2 = %4;\n\t"
|
||||
"R2 = R2 - R0;\n\t"
|
||||
"R4.L = W[I1++];\n\t"
|
||||
"LC0 = R2;\n\t"
|
||||
"LOOP filter_mid%= LC0;\n\t"
|
||||
"LOOP_BEGIN filter_mid%=;\n\t"
|
||||
"LC1 = R0;\n\t"
|
||||
"A1 = 0;\n\t"
|
||||
"I3 = P3;\n\t"
|
||||
"P3 += 2;\n\t"
|
||||
"R5.L = W[I3--];\n\t"
|
||||
"LOOP filter_mid_inner%= LC1;\n\t"
|
||||
"LOOP_BEGIN filter_mid_inner%=;\n\t"
|
||||
"A1 -= R4.L*R5.L (IS) || R4.L = W[I1++] || R5.L = W[I3--];\n\t"
|
||||
"LOOP_END filter_mid_inner%=;\n\t"
|
||||
"R1 = A1;\n\t"
|
||||
"R1 = R1 << 3 || R2 = W[P0++];\n\t"
|
||||
"R1.L = R1 (RND);\n\t"
|
||||
"R1 = R1 + R2;\n\t"
|
||||
"W[P1++] = R1;\n\t"
|
||||
"W[P3] = R1;\n\t"
|
||||
"LOOP_END filter_mid%=;\n\t"
|
||||
|
||||
/* Update memory */
|
||||
"P4 = %6;\n\t"
|
||||
"R0 = %5;\n\t"
|
||||
"LC0 = R0;\n\t"
|
||||
"P1 = B1;\n\t"
|
||||
"LOOP mem_update%= LC0;\n\t"
|
||||
"LOOP_BEGIN mem_update%=;\n\t"
|
||||
"A0 = 0;\n\t"
|
||||
"I3 = P3;\n\t"
|
||||
"I1 = P1;\n\t"
|
||||
"P1 += 2;\n\t"
|
||||
"R0 = LC0;\n\t"
|
||||
"LC1=R0;\n\t"
|
||||
"R5.L = W[I3--] || R4.L = W[I1++];\n\t"
|
||||
"LOOP mem_accum%= LC1;\n\t"
|
||||
"LOOP_BEGIN mem_accum%=;\n\t"
|
||||
"A0 -= R4.L*R5.L (IS) || R4.L = W[I1++] || R5.L = W[I3--];\n\t"
|
||||
"LOOP_END mem_accum%=;\n\t"
|
||||
"R0 = A0;\n\t"
|
||||
"[P4++] = R0;\n\t"
|
||||
"LOOP_END mem_update%=;\n\t"
|
||||
"L1 = 0;\n\t"
|
||||
: : "m" (yy), "m" (_x), "m" (_y), "m" (den), "m" (N), "m" (ord), "m" (mem)
|
||||
: "A0", "A1", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1", "P2", "P3", "P4", "B1", "I1", "I3", "L1", "L3", "memory"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define OVERRIDE_FIR_MEM16
|
||||
void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
int i;
|
||||
spx_coef_t den2[12];
|
||||
spx_coef_t *den;
|
||||
den = (spx_coef_t*)((((int)den2)+4)&0xfffffffc);
|
||||
for (i=0;i<10;i++)
|
||||
den[i] = 0;
|
||||
filter_mem16(x, num, den, y, N, ord, mem, stack);
|
||||
}
|
||||
|
||||
|
||||
#define OVERRIDE_COMPUTE_IMPULSE_RESPONSE
|
||||
void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_word16_t *ytmp);
|
||||
ALLOC(ytmp, N, spx_word16_t);
|
||||
spx_word16_t *ytmp2 = ytmp;
|
||||
y[0] = LPC_SCALING;
|
||||
for (i=0;i<ord;i++)
|
||||
y[i+1] = awk1[i];
|
||||
i++;
|
||||
for (;i<N;i++)
|
||||
y[i] = 0;
|
||||
|
||||
N-=1;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"I0 = %0;\n\t"
|
||||
"I1 = %1;\n\t"
|
||||
"L0 = 0;\n\t"
|
||||
"L1 = 0;\n\t"
|
||||
"L2 = 0;\n\t"
|
||||
"L3 = 0;\n\t"
|
||||
"R0 = 1;\n\t"
|
||||
"R0 <<= 13;\n\t"
|
||||
"W[I0] = R0.L;\n\t"
|
||||
"R0 <<= 1;\n\t"
|
||||
"W[I1] = R0.L;\n\t"
|
||||
"R0 = %5;\n\t"
|
||||
"LC0 = R0;\n\t"
|
||||
"R2 = 0;\n\t"
|
||||
"LOOP samples%= LC0;\n\t"
|
||||
"LOOP_BEGIN samples%=;\n\t"
|
||||
"R2 += 1;\n\t"
|
||||
"R2 = MIN(R2, %4);\n\t"
|
||||
"I0 = %0;\n\t"
|
||||
"I1 = %1;\n\t"
|
||||
"I2 = %2;\n\t"
|
||||
"I3 = %3;\n\t"
|
||||
"%0 += 2;\n\t"
|
||||
"%1 += 2;\n\t"
|
||||
"A1 = A0 = 0;\n\t"
|
||||
"R0.L = W[I0--] || R1.L = W[I2++];\n\t"
|
||||
"LC1 = R2;\n\t"
|
||||
"LOOP filter%= LC1;\n\t"
|
||||
"LOOP_BEGIN filter%=;\n\t"
|
||||
"A0 -= R0.L*R1.L (IS) || R0.L = W[I1--] || R1.L = W[I3++];\n\t"
|
||||
"A1 -= R0.L*R1.L (IS) || R0.L = W[I0--] || R1.L = W[I2++];\n\t"
|
||||
"LOOP_END filter%=;\n\t"
|
||||
"R0 = A0, R1 = A1;\n\t"
|
||||
"R3 = W[%1] (X);\n\t"
|
||||
"R3 <<= 13;\n\t"
|
||||
"R0 = R0 + R3;\n\t"
|
||||
"R3 = R0 >>> 13;\n\t"
|
||||
"W[%0] = R3.L;\n\t"
|
||||
"R0 <<= 1;\n\t"
|
||||
"R1 = R1 + R0;\n\t"
|
||||
"R1 >>>= 13;\n\t"
|
||||
"W[%1] = R1.L;\n\t"
|
||||
"LOOP_END samples%=;\n\t"
|
||||
: "=a" (ytmp2), "=a" (y)
|
||||
: "a" (awk2), "a" (ak), "d" (ord), "m" (N), "0" (ytmp2), "1" (y)
|
||||
: "A0", "A1", "R0", "R1", "R2", "R3", "I0", "I1", "I2", "I3", "L0", "L1", "L2", "L3", "A0", "A1"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0 /* Equivalent C function for filter_mem2 and compute_impulse_response */
|
||||
#define min(a,b) ((a)<(b) ? (a):(b))
|
||||
|
||||
void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
|
||||
{
|
||||
int i,j;
|
||||
VARDECL(spx_word16_t *ytmp);
|
||||
ALLOC(ytmp, N, spx_word16_t);
|
||||
|
||||
y[0] = LPC_SCALING;
|
||||
for (i=0;i<ord;i++)
|
||||
y[i+1] = awk1[i];
|
||||
i++;
|
||||
for (;i<N;i++)
|
||||
y[i] = 0;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
spx_word32_t yi = SHL32(EXTEND32(y[i]),LPC_SHIFT);
|
||||
spx_word32_t yi2 = 0;
|
||||
for (j=0;j<min(i,ord);j++)
|
||||
{
|
||||
yi = MAC16_16(yi, awk2[j], -ytmp[i-j-1]);
|
||||
yi2 = MAC16_16(yi2, ak[j], -y[i-j-1]);
|
||||
}
|
||||
ytmp[i] = EXTRACT16(SHR32(yi,LPC_SHIFT));
|
||||
yi2 = ADD32(yi2,SHL32(yi,1));
|
||||
y[i] = EXTRACT16(SHR32(yi2,LPC_SHIFT));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *_y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
int i,j;
|
||||
spx_word16_t xi,yi,nyi;
|
||||
spx_word16_t x[N],y[N];
|
||||
spx_word16_t *xx, *yy;
|
||||
xx = x;
|
||||
yy = y;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
x[i] = EXTRACT16(SHR32(_x[i],SIG_SHIFT));
|
||||
}
|
||||
|
||||
for (i=0;i<ord;i++)
|
||||
{
|
||||
spx_word32_t yi = mem[i];
|
||||
for (j=0;j<i;j++)
|
||||
{
|
||||
yi = MAC16_16(yi, num[j], x[i-j-1]);
|
||||
yi = MAC16_16(yi, den[j], -y[i-j-1]);
|
||||
}
|
||||
_y[i] = ADD32(_x[i],SHL32(yi,1));
|
||||
y[i] = EXTRACT16(SHR32(_y[i],SIG_SHIFT));
|
||||
}
|
||||
for (i=ord;i<N;i++)
|
||||
{
|
||||
spx_word32_t yi = 0;
|
||||
for (j=0;j<ord;j++)
|
||||
{
|
||||
yi = MAC16_16(yi, num[j], x[i-j-1]);
|
||||
yi = MAC16_16(yi, den[j], -y[i-j-1]);
|
||||
}
|
||||
_y[i] = ADD32(_x[i],SHL32(yi,1));
|
||||
y[i] = EXTRACT16(SHR32(_y[i],SIG_SHIFT));
|
||||
}
|
||||
|
||||
for (i=0;i<ord;i++)
|
||||
{
|
||||
spx_mem_t m = 0;
|
||||
for (j=0;j<ord-i;j++)
|
||||
{
|
||||
m = MAC16_16(m, x[N-1-j], num[j+i]);
|
||||
m = MAC16_16(m, -y[N-1-j], den[j+i]);
|
||||
}
|
||||
mem[i] = m;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,336 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file filters_sse.h
|
||||
@brief Various analysis/synthesis filters (SSE version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
void filter_mem16_10(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 num[3], den[3], mem[3];
|
||||
|
||||
int i;
|
||||
|
||||
/* Copy numerator, denominator and memory to aligned xmm */
|
||||
for (i=0;i<2;i++)
|
||||
{
|
||||
mem[i] = _mm_loadu_ps(_mem+4*i);
|
||||
num[i] = _mm_loadu_ps(_num+4*i);
|
||||
den[i] = _mm_loadu_ps(_den+4*i);
|
||||
}
|
||||
mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);
|
||||
num[2] = _mm_setr_ps(_num[8], _num[9], 0, 0);
|
||||
den[2] = _mm_setr_ps(_den[8], _den[9], 0, 0);
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
__m128 xx;
|
||||
__m128 yy;
|
||||
/* Compute next filter result */
|
||||
xx = _mm_load_ps1(x+i);
|
||||
yy = _mm_add_ss(xx, mem[0]);
|
||||
_mm_store_ss(y+i, yy);
|
||||
yy = _mm_shuffle_ps(yy, yy, 0);
|
||||
|
||||
/* Update memory */
|
||||
mem[0] = _mm_move_ss(mem[0], mem[1]);
|
||||
mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
|
||||
|
||||
mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
|
||||
mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
|
||||
|
||||
mem[1] = _mm_move_ss(mem[1], mem[2]);
|
||||
mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
|
||||
|
||||
mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
|
||||
mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
|
||||
|
||||
mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);
|
||||
|
||||
mem[2] = _mm_add_ps(mem[2], _mm_mul_ps(xx, num[2]));
|
||||
mem[2] = _mm_sub_ps(mem[2], _mm_mul_ps(yy, den[2]));
|
||||
}
|
||||
/* Put memory back in its place */
|
||||
_mm_storeu_ps(_mem, mem[0]);
|
||||
_mm_storeu_ps(_mem+4, mem[1]);
|
||||
_mm_store_ss(_mem+8, mem[2]);
|
||||
mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);
|
||||
_mm_store_ss(_mem+9, mem[2]);
|
||||
}
|
||||
|
||||
void filter_mem16_8(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 num[2], den[2], mem[2];
|
||||
|
||||
int i;
|
||||
|
||||
/* Copy numerator, denominator and memory to aligned xmm */
|
||||
for (i=0;i<2;i++)
|
||||
{
|
||||
mem[i] = _mm_loadu_ps(_mem+4*i);
|
||||
num[i] = _mm_loadu_ps(_num+4*i);
|
||||
den[i] = _mm_loadu_ps(_den+4*i);
|
||||
}
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
__m128 xx;
|
||||
__m128 yy;
|
||||
/* Compute next filter result */
|
||||
xx = _mm_load_ps1(x+i);
|
||||
yy = _mm_add_ss(xx, mem[0]);
|
||||
_mm_store_ss(y+i, yy);
|
||||
yy = _mm_shuffle_ps(yy, yy, 0);
|
||||
|
||||
/* Update memory */
|
||||
mem[0] = _mm_move_ss(mem[0], mem[1]);
|
||||
mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
|
||||
|
||||
mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
|
||||
mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
|
||||
|
||||
mem[1] = _mm_sub_ss(mem[1], mem[1]);
|
||||
mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
|
||||
|
||||
mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
|
||||
mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
|
||||
}
|
||||
/* Put memory back in its place */
|
||||
_mm_storeu_ps(_mem, mem[0]);
|
||||
_mm_storeu_ps(_mem+4, mem[1]);
|
||||
}
|
||||
|
||||
|
||||
#define OVERRIDE_FILTER_MEM16
|
||||
void filter_mem16(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem, char *stack)
|
||||
{
|
||||
if(ord==10)
|
||||
filter_mem16_10(x, _num, _den, y, N, ord, _mem);
|
||||
else if (ord==8)
|
||||
filter_mem16_8(x, _num, _den, y, N, ord, _mem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void iir_mem16_10(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 den[3], mem[3];
|
||||
|
||||
int i;
|
||||
|
||||
/* Copy numerator, denominator and memory to aligned xmm */
|
||||
for (i=0;i<2;i++)
|
||||
{
|
||||
mem[i] = _mm_loadu_ps(_mem+4*i);
|
||||
den[i] = _mm_loadu_ps(_den+4*i);
|
||||
}
|
||||
mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);
|
||||
den[2] = _mm_setr_ps(_den[8], _den[9], 0, 0);
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
__m128 xx;
|
||||
__m128 yy;
|
||||
/* Compute next filter result */
|
||||
xx = _mm_load_ps1(x+i);
|
||||
yy = _mm_add_ss(xx, mem[0]);
|
||||
_mm_store_ss(y+i, yy);
|
||||
yy = _mm_shuffle_ps(yy, yy, 0);
|
||||
|
||||
/* Update memory */
|
||||
mem[0] = _mm_move_ss(mem[0], mem[1]);
|
||||
mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
|
||||
|
||||
mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
|
||||
|
||||
mem[1] = _mm_move_ss(mem[1], mem[2]);
|
||||
mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
|
||||
|
||||
mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
|
||||
|
||||
mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);
|
||||
|
||||
mem[2] = _mm_sub_ps(mem[2], _mm_mul_ps(yy, den[2]));
|
||||
}
|
||||
/* Put memory back in its place */
|
||||
_mm_storeu_ps(_mem, mem[0]);
|
||||
_mm_storeu_ps(_mem+4, mem[1]);
|
||||
_mm_store_ss(_mem+8, mem[2]);
|
||||
mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);
|
||||
_mm_store_ss(_mem+9, mem[2]);
|
||||
}
|
||||
|
||||
|
||||
void iir_mem16_8(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 den[2], mem[2];
|
||||
|
||||
int i;
|
||||
|
||||
/* Copy numerator, denominator and memory to aligned xmm */
|
||||
for (i=0;i<2;i++)
|
||||
{
|
||||
mem[i] = _mm_loadu_ps(_mem+4*i);
|
||||
den[i] = _mm_loadu_ps(_den+4*i);
|
||||
}
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
__m128 xx;
|
||||
__m128 yy;
|
||||
/* Compute next filter result */
|
||||
xx = _mm_load_ps1(x+i);
|
||||
yy = _mm_add_ss(xx, mem[0]);
|
||||
_mm_store_ss(y+i, yy);
|
||||
yy = _mm_shuffle_ps(yy, yy, 0);
|
||||
|
||||
/* Update memory */
|
||||
mem[0] = _mm_move_ss(mem[0], mem[1]);
|
||||
mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
|
||||
|
||||
mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
|
||||
|
||||
mem[1] = _mm_sub_ss(mem[1], mem[1]);
|
||||
mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
|
||||
|
||||
mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
|
||||
}
|
||||
/* Put memory back in its place */
|
||||
_mm_storeu_ps(_mem, mem[0]);
|
||||
_mm_storeu_ps(_mem+4, mem[1]);
|
||||
}
|
||||
|
||||
#define OVERRIDE_IIR_MEM16
|
||||
void iir_mem16(const float *x, const float *_den, float *y, int N, int ord, float *_mem, char *stack)
|
||||
{
|
||||
if(ord==10)
|
||||
iir_mem16_10(x, _den, y, N, ord, _mem);
|
||||
else if (ord==8)
|
||||
iir_mem16_8(x, _den, y, N, ord, _mem);
|
||||
}
|
||||
|
||||
|
||||
void fir_mem16_10(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 num[3], mem[3];
|
||||
|
||||
int i;
|
||||
|
||||
/* Copy numerator, denominator and memory to aligned xmm */
|
||||
for (i=0;i<2;i++)
|
||||
{
|
||||
mem[i] = _mm_loadu_ps(_mem+4*i);
|
||||
num[i] = _mm_loadu_ps(_num+4*i);
|
||||
}
|
||||
mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);
|
||||
num[2] = _mm_setr_ps(_num[8], _num[9], 0, 0);
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
__m128 xx;
|
||||
__m128 yy;
|
||||
/* Compute next filter result */
|
||||
xx = _mm_load_ps1(x+i);
|
||||
yy = _mm_add_ss(xx, mem[0]);
|
||||
_mm_store_ss(y+i, yy);
|
||||
yy = _mm_shuffle_ps(yy, yy, 0);
|
||||
|
||||
/* Update memory */
|
||||
mem[0] = _mm_move_ss(mem[0], mem[1]);
|
||||
mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
|
||||
|
||||
mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
|
||||
|
||||
mem[1] = _mm_move_ss(mem[1], mem[2]);
|
||||
mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
|
||||
|
||||
mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
|
||||
|
||||
mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);
|
||||
|
||||
mem[2] = _mm_add_ps(mem[2], _mm_mul_ps(xx, num[2]));
|
||||
}
|
||||
/* Put memory back in its place */
|
||||
_mm_storeu_ps(_mem, mem[0]);
|
||||
_mm_storeu_ps(_mem+4, mem[1]);
|
||||
_mm_store_ss(_mem+8, mem[2]);
|
||||
mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);
|
||||
_mm_store_ss(_mem+9, mem[2]);
|
||||
}
|
||||
|
||||
void fir_mem16_8(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 num[2], mem[2];
|
||||
|
||||
int i;
|
||||
|
||||
/* Copy numerator, denominator and memory to aligned xmm */
|
||||
for (i=0;i<2;i++)
|
||||
{
|
||||
mem[i] = _mm_loadu_ps(_mem+4*i);
|
||||
num[i] = _mm_loadu_ps(_num+4*i);
|
||||
}
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
__m128 xx;
|
||||
__m128 yy;
|
||||
/* Compute next filter result */
|
||||
xx = _mm_load_ps1(x+i);
|
||||
yy = _mm_add_ss(xx, mem[0]);
|
||||
_mm_store_ss(y+i, yy);
|
||||
yy = _mm_shuffle_ps(yy, yy, 0);
|
||||
|
||||
/* Update memory */
|
||||
mem[0] = _mm_move_ss(mem[0], mem[1]);
|
||||
mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
|
||||
|
||||
mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
|
||||
|
||||
mem[1] = _mm_sub_ss(mem[1], mem[1]);
|
||||
mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
|
||||
|
||||
mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
|
||||
}
|
||||
/* Put memory back in its place */
|
||||
_mm_storeu_ps(_mem, mem[0]);
|
||||
_mm_storeu_ps(_mem+4, mem[1]);
|
||||
}
|
||||
|
||||
#define OVERRIDE_FIR_MEM16
|
||||
void fir_mem16(const float *x, const float *_num, float *y, int N, int ord, float *_mem, char *stack)
|
||||
{
|
||||
if(ord==10)
|
||||
fir_mem16_10(x, _num, y, N, ord, _mem);
|
||||
else if (ord==8)
|
||||
fir_mem16_8(x, _num, y, N, ord, _mem);
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
/* Copyright (C) 2004 Jean-Marc Valin */
|
||||
/**
|
||||
@file fixed_arm4.h
|
||||
@brief ARM4 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.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FIXED_ARM4_H
|
||||
#define FIXED_ARM4_H
|
||||
|
||||
#undef MULT16_32_Q14
|
||||
static inline spx_word32_t MULT16_32_Q14(spx_word16_t x, spx_word32_t y) {
|
||||
int res;
|
||||
int dummy;
|
||||
asm (
|
||||
"smull %0,%1,%2,%3 \n\t"
|
||||
"mov %0, %0, lsr #14 \n\t"
|
||||
"add %0, %0, %1, lsl #18 \n\t"
|
||||
: "=&r"(res), "=&r" (dummy)
|
||||
: "r"(y),"r"((int)x));
|
||||
return(res);
|
||||
}
|
||||
|
||||
#undef MULT16_32_Q15
|
||||
static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
|
||||
int res;
|
||||
int dummy;
|
||||
asm (
|
||||
"smull %0,%1,%2,%3 \n\t"
|
||||
"mov %0, %0, lsr #15 \n\t"
|
||||
"add %0, %0, %1, lsl #17 \n\t"
|
||||
: "=&r"(res), "=&r" (dummy)
|
||||
: "r"(y),"r"((int)x));
|
||||
return(res);
|
||||
}
|
||||
|
||||
#undef DIV32_16
|
||||
static inline short DIV32_16(int a, int b)
|
||||
{
|
||||
int res=0;
|
||||
int dead1, dead2, dead3, dead4, dead5;
|
||||
__asm__ __volatile__ (
|
||||
"\teor %5, %0, %1\n"
|
||||
"\tmovs %4, %0\n"
|
||||
"\trsbmi %0, %0, #0 \n"
|
||||
"\tmovs %4, %1\n"
|
||||
"\trsbmi %1, %1, #0 \n"
|
||||
"\tmov %4, #1\n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #14 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #14 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #13 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #13 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #12 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #12 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #11 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #11 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #10 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #10 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #9 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #9 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #8 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #8 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #7 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #7 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #6 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #6 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #5 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #5 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #4 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #4 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #3 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #2 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #2 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #1 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4, asl #1 \n"
|
||||
|
||||
"\tsubs %3, %0, %1 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
"\torrpl %2, %2, %4 \n"
|
||||
|
||||
"\tmovs %5, %5, lsr #31 \n"
|
||||
"\trsbne %2, %2, #0 \n"
|
||||
: "=r" (dead1), "=r" (dead2), "=r" (res),
|
||||
"=r" (dead3), "=r" (dead4), "=r" (dead5)
|
||||
: "0" (a), "1" (b), "2" (res)
|
||||
: "cc"
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -1,178 +0,0 @@
|
|||
/* Copyright (C) 2003 Jean-Marc Valin */
|
||||
/**
|
||||
@file fixed_arm5e.h
|
||||
@brief ARM-tuned 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.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FIXED_ARM5E_H
|
||||
#define FIXED_ARM5E_H
|
||||
|
||||
#undef MULT16_16
|
||||
static inline spx_word32_t MULT16_16(spx_word16_t x, spx_word16_t y) {
|
||||
int res;
|
||||
asm ("smulbb %0,%1,%2;\n"
|
||||
: "=&r"(res)
|
||||
: "%r"(x),"r"(y));
|
||||
return(res);
|
||||
}
|
||||
|
||||
#undef MAC16_16
|
||||
static inline spx_word32_t MAC16_16(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
|
||||
int res;
|
||||
asm ("smlabb %0,%1,%2,%3;\n"
|
||||
: "=&r"(res)
|
||||
: "%r"(x),"r"(y),"r"(a));
|
||||
return(res);
|
||||
}
|
||||
|
||||
#undef MULT16_32_Q15
|
||||
static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
|
||||
int res;
|
||||
asm ("smulwb %0,%1,%2;\n"
|
||||
: "=&r"(res)
|
||||
: "%r"(y<<1),"r"(x));
|
||||
return(res);
|
||||
}
|
||||
|
||||
#undef MAC16_32_Q15
|
||||
static inline spx_word32_t MAC16_32_Q15(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
|
||||
int res;
|
||||
asm ("smlawb %0,%1,%2,%3;\n"
|
||||
: "=&r"(res)
|
||||
: "%r"(y<<1),"r"(x),"r"(a));
|
||||
return(res);
|
||||
}
|
||||
|
||||
#undef MULT16_32_Q11
|
||||
static inline spx_word32_t MULT16_32_Q11(spx_word16_t x, spx_word32_t y) {
|
||||
int res;
|
||||
asm ("smulwb %0,%1,%2;\n"
|
||||
: "=&r"(res)
|
||||
: "%r"(y<<5),"r"(x));
|
||||
return(res);
|
||||
}
|
||||
|
||||
#undef MAC16_32_Q11
|
||||
static inline spx_word32_t MAC16_32_Q11(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
|
||||
int res;
|
||||
asm ("smlawb %0,%1,%2,%3;\n"
|
||||
: "=&r"(res)
|
||||
: "%r"(y<<5),"r"(x),"r"(a));
|
||||
return(res);
|
||||
}
|
||||
|
||||
#undef DIV32_16
|
||||
static inline short DIV32_16(int a, int b)
|
||||
{
|
||||
int res=0;
|
||||
int dead1, dead2, dead3, dead4, dead5;
|
||||
__asm__ __volatile__ (
|
||||
"\teor %5, %0, %1\n"
|
||||
"\tmovs %4, %0\n"
|
||||
"\trsbmi %0, %0, #0 \n"
|
||||
"\tmovs %4, %1\n"
|
||||
"\trsbmi %1, %1, #0 \n"
|
||||
"\tmov %4, #1\n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #14 \n"
|
||||
"\torrpl %2, %2, %4, asl #14 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #13 \n"
|
||||
"\torrpl %2, %2, %4, asl #13 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #12 \n"
|
||||
"\torrpl %2, %2, %4, asl #12 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #11 \n"
|
||||
"\torrpl %2, %2, %4, asl #11 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #10 \n"
|
||||
"\torrpl %2, %2, %4, asl #10 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #9 \n"
|
||||
"\torrpl %2, %2, %4, asl #9 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #8 \n"
|
||||
"\torrpl %2, %2, %4, asl #8 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #7 \n"
|
||||
"\torrpl %2, %2, %4, asl #7 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #6 \n"
|
||||
"\torrpl %2, %2, %4, asl #6 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #5 \n"
|
||||
"\torrpl %2, %2, %4, asl #5 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #4 \n"
|
||||
"\torrpl %2, %2, %4, asl #4 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #3 \n"
|
||||
"\torrpl %2, %2, %4, asl #3 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #2 \n"
|
||||
"\torrpl %2, %2, %4, asl #2 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1, asl #1 \n"
|
||||
"\torrpl %2, %2, %4, asl #1 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tsubs %3, %0, %1 \n"
|
||||
"\torrpl %2, %2, %4 \n"
|
||||
"\tmovpl %0, %3 \n"
|
||||
|
||||
"\tmovs %5, %5, lsr #31 \n"
|
||||
"\trsbne %2, %2, #0 \n"
|
||||
: "=r" (dead1), "=r" (dead2), "=r" (res),
|
||||
"=r" (dead3), "=r" (dead4), "=r" (dead5)
|
||||
: "0" (a), "1" (b), "2" (res)
|
||||
: "memory", "cc"
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -1,173 +0,0 @@
|
|||
/* Copyright (C) 2005 Analog Devices
|
||||
Author: Jean-Marc Valin */
|
||||
/**
|
||||
@file fixed_bfin.h
|
||||
@brief Blackfin 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.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FIXED_BFIN_H
|
||||
#define FIXED_BFIN_H
|
||||
|
||||
#undef PDIV32_16
|
||||
static inline spx_word16_t PDIV32_16(spx_word32_t a, spx_word16_t b)
|
||||
{
|
||||
spx_word32_t res, bb;
|
||||
bb = b;
|
||||
a += b>>1;
|
||||
__asm__ (
|
||||
"P0 = 15;\n\t"
|
||||
"R0 = %1;\n\t"
|
||||
"R1 = %2;\n\t"
|
||||
//"R0 = R0 + R1;\n\t"
|
||||
"R0 <<= 1;\n\t"
|
||||
"DIVS (R0, R1);\n\t"
|
||||
"LOOP divide%= LC0 = P0;\n\t"
|
||||
"LOOP_BEGIN divide%=;\n\t"
|
||||
"DIVQ (R0, R1);\n\t"
|
||||
"LOOP_END divide%=;\n\t"
|
||||
"R0 = R0.L;\n\t"
|
||||
"%0 = R0;\n\t"
|
||||
: "=m" (res)
|
||||
: "m" (a), "m" (bb)
|
||||
: "P0", "R0", "R1", "cc");
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef DIV32_16
|
||||
static inline spx_word16_t DIV32_16(spx_word32_t a, spx_word16_t b)
|
||||
{
|
||||
spx_word32_t res, bb;
|
||||
bb = b;
|
||||
/* Make the roundinf consistent with the C version
|
||||
(do we need to do that?)*/
|
||||
if (a<0)
|
||||
a += (b-1);
|
||||
__asm__ (
|
||||
"P0 = 15;\n\t"
|
||||
"R0 = %1;\n\t"
|
||||
"R1 = %2;\n\t"
|
||||
"R0 <<= 1;\n\t"
|
||||
"DIVS (R0, R1);\n\t"
|
||||
"LOOP divide%= LC0 = P0;\n\t"
|
||||
"LOOP_BEGIN divide%=;\n\t"
|
||||
"DIVQ (R0, R1);\n\t"
|
||||
"LOOP_END divide%=;\n\t"
|
||||
"R0 = R0.L;\n\t"
|
||||
"%0 = R0;\n\t"
|
||||
: "=m" (res)
|
||||
: "m" (a), "m" (bb)
|
||||
: "P0", "R0", "R1", "cc");
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef MAX16
|
||||
static inline spx_word16_t MAX16(spx_word16_t a, spx_word16_t b)
|
||||
{
|
||||
spx_word32_t res;
|
||||
__asm__ (
|
||||
"%1 = %1.L (X);\n\t"
|
||||
"%2 = %2.L (X);\n\t"
|
||||
"%0 = MAX(%1,%2);"
|
||||
: "=d" (res)
|
||||
: "%d" (a), "d" (b)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef MULT16_32_Q15
|
||||
static inline spx_word32_t MULT16_32_Q15(spx_word16_t a, spx_word32_t b)
|
||||
{
|
||||
spx_word32_t res;
|
||||
__asm__
|
||||
(
|
||||
"A1 = %2.L*%1.L (M);\n\t"
|
||||
"A1 = A1 >>> 15;\n\t"
|
||||
"%0 = (A1 += %2.L*%1.H) ;\n\t"
|
||||
: "=&W" (res), "=&d" (b)
|
||||
: "d" (a), "1" (b)
|
||||
: "A1"
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef MAC16_32_Q15
|
||||
static inline spx_word32_t MAC16_32_Q15(spx_word32_t c, spx_word16_t a, spx_word32_t b)
|
||||
{
|
||||
spx_word32_t res;
|
||||
__asm__
|
||||
(
|
||||
"A1 = %2.L*%1.L (M);\n\t"
|
||||
"A1 = A1 >>> 15;\n\t"
|
||||
"%0 = (A1 += %2.L*%1.H);\n\t"
|
||||
"%0 = %0 + %4;\n\t"
|
||||
: "=&W" (res), "=&d" (b)
|
||||
: "d" (a), "1" (b), "d" (c)
|
||||
: "A1"
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef MULT16_32_Q14
|
||||
static inline spx_word32_t MULT16_32_Q14(spx_word16_t a, spx_word32_t b)
|
||||
{
|
||||
spx_word32_t res;
|
||||
__asm__
|
||||
(
|
||||
"%2 <<= 1;\n\t"
|
||||
"A1 = %1.L*%2.L (M);\n\t"
|
||||
"A1 = A1 >>> 15;\n\t"
|
||||
"%0 = (A1 += %1.L*%2.H);\n\t"
|
||||
: "=W" (res), "=d" (a), "=d" (b)
|
||||
: "1" (a), "2" (b)
|
||||
: "A1"
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef MAC16_32_Q14
|
||||
static inline spx_word32_t MAC16_32_Q14(spx_word32_t c, spx_word16_t a, spx_word32_t b)
|
||||
{
|
||||
spx_word32_t res;
|
||||
__asm__
|
||||
(
|
||||
"%1 <<= 1;\n\t"
|
||||
"A1 = %2.L*%1.L (M);\n\t"
|
||||
"A1 = A1 >>> 15;\n\t"
|
||||
"%0 = (A1 += %2.L*%1.H);\n\t"
|
||||
"%0 = %0 + %4;\n\t"
|
||||
: "=&W" (res), "=&d" (b)
|
||||
: "d" (a), "1" (b), "d" (c)
|
||||
: "A1"
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,487 +0,0 @@
|
|||
/* Copyright (C) 2003 Jean-Marc Valin */
|
||||
/**
|
||||
@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.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FIXED_DEBUG_H
|
||||
#define FIXED_DEBUG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern long long spx_mips;
|
||||
#define MIPS_INC spx_mips++,
|
||||
|
||||
#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
|
||||
#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
|
||||
|
||||
|
||||
#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
|
||||
#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
|
||||
|
||||
static inline short NEG16(int x)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(x))
|
||||
{
|
||||
fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
|
||||
}
|
||||
res = -x;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
static inline int NEG32(long long x)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_INT(x))
|
||||
{
|
||||
fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
|
||||
}
|
||||
res = -x;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
|
||||
spx_mips++;
|
||||
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);
|
||||
}
|
||||
res = x;
|
||||
spx_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);
|
||||
}
|
||||
res = x;
|
||||
spx_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);
|
||||
}
|
||||
res = a>>shift;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
|
||||
spx_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);
|
||||
}
|
||||
res = a<<shift;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline int SHR32(long long a, int shift)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
|
||||
{
|
||||
fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
|
||||
}
|
||||
res = a>>shift;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
|
||||
}
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
static inline int SHL32(long long a, int shift)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
|
||||
{
|
||||
fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift);
|
||||
}
|
||||
res = a<<shift;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "SHL32: output is not int: %d\n", (int)res);
|
||||
}
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift))
|
||||
#define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift))
|
||||
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
|
||||
|
||||
#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
|
||||
//#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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
spx_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);
|
||||
}
|
||||
res = a-b;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__)
|
||||
static inline int _ADD32(long long a, long long b, char *file, int line)
|
||||
{
|
||||
long long 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);
|
||||
}
|
||||
res = a+b;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
|
||||
}
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline int SUB32(long long a, long long b)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b);
|
||||
}
|
||||
res = a-b;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "SUB32: output is not int: %d\n", (int)res);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define ADD64(a,b) (MIPS_INC(a)+(b))
|
||||
|
||||
/* 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);
|
||||
}
|
||||
res = a*b;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
|
||||
spx_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)
|
||||
{
|
||||
long long 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);
|
||||
}
|
||||
res = ((long long)a)*b;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b))))
|
||||
#define MAC16_16_Q11(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11)))))
|
||||
#define MAC16_16_Q13(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13)))))
|
||||
#define MAC16_16_P13(c,a,b) (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13))))
|
||||
|
||||
|
||||
#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__)
|
||||
static inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line)
|
||||
{
|
||||
long long 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);
|
||||
}
|
||||
if (ABS32(b)>=(EXTEND32(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);
|
||||
res = (((long long)a)*(long long)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);
|
||||
spx_mips+=5;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline int MULT16_32_PX(int a, long long b, int Q)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b);
|
||||
}
|
||||
if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))
|
||||
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b);
|
||||
res = ((((long long)a)*(long long)b) + ((EXTEND32(1)<<Q)>>1))>> Q;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res);
|
||||
spx_mips+=5;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11)
|
||||
#define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b)))
|
||||
#define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12)
|
||||
#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13)
|
||||
#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14)
|
||||
#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
|
||||
#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15)
|
||||
#define MAC16_32_Q15(c,a,b) 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;
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline int MULT16_16_Q11_32(int a, int b)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
|
||||
}
|
||||
res = ((long long)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);
|
||||
spx_mips+=3;
|
||||
return res;
|
||||
}
|
||||
static inline short MULT16_16_Q13(int a, int b)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
|
||||
}
|
||||
res = ((long long)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);
|
||||
spx_mips+=3;
|
||||
return res;
|
||||
}
|
||||
static inline short MULT16_16_Q14(int a, int b)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
|
||||
}
|
||||
res = ((long long)a)*b;
|
||||
res >>= 14;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
|
||||
spx_mips+=3;
|
||||
return res;
|
||||
}
|
||||
static inline short MULT16_16_Q15(int a, int b)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
|
||||
}
|
||||
res = ((long long)a)*b;
|
||||
res >>= 15;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
|
||||
}
|
||||
spx_mips+=3;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline short MULT16_16_P13(int a, int b)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
|
||||
}
|
||||
res = ((long long)a)*b;
|
||||
res += 4096;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
|
||||
res >>= 13;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
|
||||
spx_mips+=4;
|
||||
return res;
|
||||
}
|
||||
static inline short MULT16_16_P14(int a, int b)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
|
||||
}
|
||||
res = ((long long)a)*b;
|
||||
res += 8192;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
|
||||
res >>= 14;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
|
||||
spx_mips+=4;
|
||||
return res;
|
||||
}
|
||||
static inline short MULT16_16_P15(int a, int b)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
|
||||
}
|
||||
res = ((long long)a)*b;
|
||||
res += 16384;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
|
||||
res >>= 15;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
|
||||
spx_mips+=4;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__)
|
||||
|
||||
static inline int _DIV32_16(long long a, long long b, char *file, int line)
|
||||
{
|
||||
long long res;
|
||||
if (b==0)
|
||||
{
|
||||
fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
spx_mips+=20;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__)
|
||||
static inline int _DIV32(long long a, long long b, char *file, int line)
|
||||
{
|
||||
long long res;
|
||||
if (b==0)
|
||||
{
|
||||
fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
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);
|
||||
}
|
||||
res = a/b;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
|
||||
spx_mips+=36;
|
||||
return res;
|
||||
}
|
||||
#define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b)
|
||||
#define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b)
|
||||
|
||||
#endif
|
|
@ -1,106 +0,0 @@
|
|||
/* Copyright (C) 2003 Jean-Marc Valin */
|
||||
/**
|
||||
@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.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FIXED_GENERIC_H
|
||||
#define FIXED_GENERIC_H
|
||||
|
||||
#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
|
||||
#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
|
||||
|
||||
#define NEG16(x) (-(x))
|
||||
#define NEG32(x) (-(x))
|
||||
#define EXTRACT16(x) ((spx_word16_t)(x))
|
||||
#define EXTEND32(x) ((spx_word32_t)(x))
|
||||
#define SHR16(a,shift) ((a) >> (shift))
|
||||
#define SHL16(a,shift) ((a) << (shift))
|
||||
#define SHR32(a,shift) ((a) >> (shift))
|
||||
#define SHL32(a,shift) ((a) << (shift))
|
||||
#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift))
|
||||
#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))
|
||||
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
|
||||
#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
|
||||
#define SHR(a,shift) ((a) >> (shift))
|
||||
#define SHL(a,shift) ((spx_word32_t)(a) << (shift))
|
||||
#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
|
||||
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
|
||||
|
||||
#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b)))
|
||||
#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b))
|
||||
#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b))
|
||||
#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b))
|
||||
|
||||
|
||||
/* result fits in 16 bits */
|
||||
#define MULT16_16_16(a,b) ((((spx_word16_t)(a))*((spx_word16_t)(b))))
|
||||
|
||||
/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */
|
||||
#define MULT16_16(a,b) (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b)))
|
||||
|
||||
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
|
||||
#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
|
||||
#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
|
||||
#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
|
||||
|
||||
#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
|
||||
#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
|
||||
|
||||
#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15))
|
||||
#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
|
||||
#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
|
||||
|
||||
|
||||
#define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11)))
|
||||
#define MAC16_16_Q13(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),13)))
|
||||
#define MAC16_16_P13(c,a,b) (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13)))
|
||||
|
||||
#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))
|
||||
|
||||
#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
|
||||
|
||||
#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b))))
|
||||
#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b))))
|
||||
#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b)))
|
||||
#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b)))
|
||||
|
||||
#endif
|
|
@ -1,160 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: gain_table.c
|
||||
Codebook for 3-tap pitch prediction gain (128 entries)
|
||||
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
const signed char gain_cdbk_nb[512] = {
|
||||
-32, -32, -32, 0,
|
||||
-28, -67, -5, 33,
|
||||
-42, -6, -32, 18,
|
||||
-57, -10, -54, 35,
|
||||
-16, 27, -41, 42,
|
||||
19, -19, -40, 36,
|
||||
-45, 24, -21, 40,
|
||||
-8, -14, -18, 28,
|
||||
1, 14, -58, 53,
|
||||
-18, -88, -39, 39,
|
||||
-38, 21, -18, 37,
|
||||
-19, 20, -43, 38,
|
||||
10, 17, -48, 54,
|
||||
-52, -58, -13, 33,
|
||||
-44, -1, -11, 32,
|
||||
-12, -11, -34, 22,
|
||||
14, 0, -46, 46,
|
||||
-37, -35, -34, 5,
|
||||
-25, 44, -30, 43,
|
||||
6, -4, -63, 49,
|
||||
-31, 43, -41, 43,
|
||||
-23, 30, -43, 41,
|
||||
-43, 26, -14, 44,
|
||||
-33, 1, -13, 27,
|
||||
-13, 18, -37, 37,
|
||||
-46, -73, -45, 34,
|
||||
-36, 24, -25, 34,
|
||||
-36, -11, -20, 19,
|
||||
-25, 12, -18, 33,
|
||||
-36, -69, -59, 34,
|
||||
-45, 6, 8, 46,
|
||||
-22, -14, -24, 18,
|
||||
-1, 13, -44, 44,
|
||||
-39, -48, -26, 15,
|
||||
-32, 31, -37, 34,
|
||||
-33, 15, -46, 31,
|
||||
-24, 30, -36, 37,
|
||||
-41, 31, -23, 41,
|
||||
-50, 22, -4, 50,
|
||||
-22, 2, -21, 28,
|
||||
-17, 30, -34, 40,
|
||||
-7, -60, -28, 29,
|
||||
-38, 42, -28, 42,
|
||||
-44, -11, 21, 43,
|
||||
-16, 8, -44, 34,
|
||||
-39, -55, -43, 21,
|
||||
-11, -35, 26, 41,
|
||||
-9, 0, -34, 29,
|
||||
-8, 121, -81, 113,
|
||||
7, -16, -22, 33,
|
||||
-37, 33, -31, 36,
|
||||
-27, -7, -36, 17,
|
||||
-34, 70, -57, 65,
|
||||
-37, -11, -48, 21,
|
||||
-40, 17, -1, 44,
|
||||
-33, 6, -6, 33,
|
||||
-9, 0, -20, 34,
|
||||
-21, 69, -33, 57,
|
||||
-29, 33, -31, 35,
|
||||
-55, 12, -1, 49,
|
||||
-33, 27, -22, 35,
|
||||
-50, -33, -47, 17,
|
||||
-50, 54, 51, 94,
|
||||
-1, -5, -44, 35,
|
||||
-4, 22, -40, 45,
|
||||
-39, -66, -25, 24,
|
||||
-33, 1, -26, 20,
|
||||
-24, -23, -25, 12,
|
||||
-11, 21, -45, 44,
|
||||
-25, -45, -19, 17,
|
||||
-43, 105, -16, 82,
|
||||
5, -21, 1, 41,
|
||||
-16, 11, -33, 30,
|
||||
-13, -99, -4, 57,
|
||||
-37, 33, -15, 44,
|
||||
-25, 37, -63, 54,
|
||||
-36, 24, -31, 31,
|
||||
-53, -56, -38, 26,
|
||||
-41, -4, 4, 37,
|
||||
-33, 13, -30, 24,
|
||||
49, 52, -94, 114,
|
||||
-5, -30, -15, 23,
|
||||
1, 38, -40, 56,
|
||||
-23, 12, -36, 29,
|
||||
-17, 40, -47, 51,
|
||||
-37, -41, -39, 11,
|
||||
-49, 34, 0, 58,
|
||||
-18, -7, -4, 34,
|
||||
-16, 17, -27, 35,
|
||||
30, 5, -62, 65,
|
||||
4, 48, -68, 76,
|
||||
-43, 11, -11, 38,
|
||||
-18, 19, -15, 41,
|
||||
-23, -62, -39, 23,
|
||||
-42, 10, -2, 41,
|
||||
-21, -13, -13, 25,
|
||||
-9, 13, -47, 42,
|
||||
-23, -62, -24, 24,
|
||||
-44, 60, -21, 58,
|
||||
-18, -3, -52, 32,
|
||||
-22, 22, -36, 34,
|
||||
-75, 57, 16, 90,
|
||||
-19, 3, 10, 45,
|
||||
-29, 23, -38, 32,
|
||||
-5, -62, -51, 38,
|
||||
-51, 40, -18, 53,
|
||||
-42, 13, -24, 32,
|
||||
-34, 14, -20, 30,
|
||||
-56, -75, -26, 37,
|
||||
-26, 32, 15, 59,
|
||||
-26, 17, -29, 29,
|
||||
-7, 28, -52, 53,
|
||||
-12, -30, 5, 30,
|
||||
-5, -48, -5, 35,
|
||||
2, 2, -43, 40,
|
||||
21, 16, 16, 75,
|
||||
-25, -45, -32, 10,
|
||||
-43, 18, -10, 42,
|
||||
9, 0, -1, 52,
|
||||
-1, 7, -30, 36,
|
||||
19, -48, -4, 48,
|
||||
-28, 25, -29, 32,
|
||||
-22, 0, -31, 22,
|
||||
-32, 17, -10, 36,
|
||||
-64, -41, -62, 36,
|
||||
-52, 15, 16, 58,
|
||||
-30, -22, -32, 6,
|
||||
-7, 9, -38, 36};
|
|
@ -1,64 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: gain_table_lbr.c
|
||||
Codebook for 3-tap pitch prediction gain (32 entries)
|
||||
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
const signed char gain_cdbk_lbr[128] = {
|
||||
-32, -32, -32, 0,
|
||||
-31, -58, -16, 22,
|
||||
-41, -24, -43, 14,
|
||||
-56, -22, -55, 29,
|
||||
-13, 33, -41, 47,
|
||||
-4, -39, -9, 29,
|
||||
-41, 15, -12, 38,
|
||||
-8, -15, -12, 31,
|
||||
1, 2, -44, 40,
|
||||
-22, -66, -42, 27,
|
||||
-38, 28, -23, 38,
|
||||
-21, 14, -37, 31,
|
||||
0, 21, -50, 52,
|
||||
-53, -71, -27, 33,
|
||||
-37, -1, -19, 25,
|
||||
-19, -5, -28, 22,
|
||||
6, 65, -44, 74,
|
||||
-33, -48, -33, 9,
|
||||
-40, 57, -14, 58,
|
||||
-17, 4, -45, 32,
|
||||
-31, 38, -33, 36,
|
||||
-23, 28, -40, 39,
|
||||
-43, 29, -12, 46,
|
||||
-34, 13, -23, 28,
|
||||
-16, 15, -27, 34,
|
||||
-14, -82, -15, 43,
|
||||
-31, 25, -32, 29,
|
||||
-21, 5, -5, 38,
|
||||
-47, -63, -51, 33,
|
||||
-46, 12, 3, 47,
|
||||
-28, -17, -29, 11,
|
||||
-10, 14, -40, 38};
|
|
@ -1,66 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: hexc_10_32_table.c
|
||||
Codebook for high-band excitation in SB-CELP mode (4000 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
const signed char hexc_10_32_table[320] = {
|
||||
-3, -2, -1, 0, -4, 5, 35, -40, -9, 13,
|
||||
-44, 5, -27, -1, -7, 6, -11, 7, -8, 7,
|
||||
19, -14, 15, -4, 9, -10, 10, -8, 10, -9,
|
||||
-1, 1, 0, 0, 2, 5, -18, 22, -53, 50,
|
||||
1, -23, 50, -36, 15, 3, -13, 14, -10, 6,
|
||||
1, 5, -3, 4, -2, 5, -32, 25, 5, -2,
|
||||
-1, -4, 1, 11, -29, 26, -6, -15, 30, -18,
|
||||
0, 15, -17, 40, -41, 3, 9, -2, -2, 3,
|
||||
-3, -1, -5, 2, 21, -6, -16, -21, 23, 2,
|
||||
60, 15, 16, -16, -9, 14, 9, -1, 7, -9,
|
||||
0, 1, 1, 0, -1, -6, 17, -28, 54, -45,
|
||||
-1, 1, -1, -6, -6, 2, 11, 26, -29, -2,
|
||||
46, -21, 34, 12, -23, 32, -23, 16, -10, 3,
|
||||
66, 19, -20, 24, 7, 11, -3, 0, -3, -1,
|
||||
-50, -46, 2, -18, -3, 4, -1, -2, 3, -3,
|
||||
-19, 41, -36, 9, 11, -24, 21, -16, 9, -3,
|
||||
-25, -3, 10, 18, -9, -2, -5, -1, -5, 6,
|
||||
-4, -3, 2, -26, 21, -19, 35, -15, 7, -13,
|
||||
17, -19, 39, -43, 48, -31, 16, -9, 7, -2,
|
||||
-5, 3, -4, 9, -19, 27, -55, 63, -35, 10,
|
||||
26, -44, -2, 9, 4, 1, -6, 8, -9, 5,
|
||||
-8, -1, -3, -16, 45, -42, 5, 15, -16, 10,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
-16, 24, -55, 47, -38, 27, -19, 7, -3, 1,
|
||||
16, 27, 20, -19, 18, 5, -7, 1, -5, 2,
|
||||
-6, 8, -22, 0, -3, -3, 8, -1, 7, -8,
|
||||
1, -3, 5, 0, 17, -48, 58, -52, 29, -7,
|
||||
-2, 3, -10, 6, -26, 58, -31, 1, -6, 3,
|
||||
93, -29, 39, 3, 17, 5, 6, -1, -1, -1,
|
||||
27, 13, 10, 19, -7, -34, 12, 10, -4, 9,
|
||||
-76, 9, 8, -28, -2, -11, 2, -1, 3, 1,
|
||||
-83, 38, -39, 4, -16, -6, -2, -5, 5, -2,
|
||||
};
|
|
@ -1,162 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: hexc_table.c
|
||||
Codebook for high-band excitation in SB-CELP mode (8000 bps with sign)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
const signed char hexc_table[1024] = {
|
||||
-24, 21, -20, 5, -5, -7, 14, -10,
|
||||
2, -27, 16, -20, 0, -32, 26, 19,
|
||||
8, -11, -41, 31, 28, -27, -32, 34,
|
||||
42, 34, -17, 22, -10, 13, -29, 18,
|
||||
-12, -26, -24, 11, 22, 5, -5, -5,
|
||||
54, -68, -43, 57, -25, 24, 4, 4,
|
||||
26, -8, -12, -17, 54, 30, -45, 1,
|
||||
10, -15, 18, -41, 11, 68, -67, 37,
|
||||
-16, -24, -16, 38, -22, 6, -29, 30,
|
||||
66, -27, 5, 7, -16, 13, 2, -12,
|
||||
-7, -3, -20, 36, 4, -28, 9, 3,
|
||||
32, 48, 26, 39, 3, 0, 7, -21,
|
||||
-13, 5, -82, -7, 73, -20, 34, -9,
|
||||
-5, 1, -1, 10, -5, -10, -1, 9,
|
||||
1, -9, 10, 0, -14, 11, -1, -2,
|
||||
-1, 11, 20, 96, -81, -22, -12, -9,
|
||||
-58, 9, 24, -30, 26, -35, 27, -12,
|
||||
13, -18, 56, -59, 15, -7, 23, -15,
|
||||
-1, 6, -25, 14, -22, -20, 47, -11,
|
||||
16, 2, 38, -23, -19, -30, -9, 40,
|
||||
-11, 5, 4, -6, 8, 26, -21, -11,
|
||||
127, 4, 1, 6, -9, 2, -7, -2,
|
||||
-3, 7, -5, 10, -19, 7, -106, 91,
|
||||
-3, 9, -4, 21, -8, 26, -80, 8,
|
||||
1, -2, -10, -17, -17, -27, 32, 71,
|
||||
6, -29, 11, -23, 54, -38, 29, -22,
|
||||
39, 87, -31, -12, -20, 3, -2, -2,
|
||||
2, 20, 0, -1, -35, 27, 9, -6,
|
||||
-12, 3, -12, -6, 13, 1, 14, -22,
|
||||
-59, -15, -17, -25, 13, -7, 7, 3,
|
||||
0, 1, -7, 6, -3, 61, -37, -23,
|
||||
-23, -29, 38, -31, 27, 1, -8, 2,
|
||||
-27, 23, -26, 36, -34, 5, 24, -24,
|
||||
-6, 7, 3, -59, 78, -62, 44, -16,
|
||||
1, 6, 0, 17, 8, 45, 0, -110,
|
||||
6, 14, -2, 32, -77, -56, 62, -3,
|
||||
3, -13, 4, -16, 102, -15, -36, -1,
|
||||
9, -113, 6, 23, 0, 9, 9, 5,
|
||||
-8, -1, -14, 5, -12, 121, -53, -27,
|
||||
-8, -9, 22, -13, 3, 2, -3, 1,
|
||||
-2, -71, 95, 38, -19, 15, -16, -5,
|
||||
71, 10, 2, -32, -13, -5, 15, -1,
|
||||
-2, -14, -85, 30, 29, 6, 3, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, -65, -56, -9, 18, 18, 23, -14,
|
||||
-2, 0, 12, -29, 26, -12, 1, 2,
|
||||
-12, -64, 90, -6, 4, 1, 5, -5,
|
||||
-110, -3, -31, 22, -29, 9, 0, 8,
|
||||
-40, -5, 21, -5, -5, 13, 10, -18,
|
||||
40, 1, 35, -20, 30, -28, 11, -6,
|
||||
19, 7, 14, 18, -64, 9, -6, 16,
|
||||
51, 68, 8, 16, 12, -8, 0, -9,
|
||||
20, -22, 25, 7, -4, -13, 41, -35,
|
||||
93, -18, -54, 11, -1, 1, -9, 4,
|
||||
-66, 66, -31, 20, -22, 25, -23, 11,
|
||||
10, 9, 19, 15, 11, -5, -31, -10,
|
||||
-23, -28, -6, -6, -3, -4, 5, 3,
|
||||
-28, 22, -11, -42, 25, -25, -16, 41,
|
||||
34, 47, -6, 2, 42, -19, -22, 5,
|
||||
-39, 32, 6, -35, 22, 17, -30, 8,
|
||||
-26, -11, -11, 3, -12, 33, 33, -37,
|
||||
21, -1, 6, -4, 3, 0, -5, 5,
|
||||
12, -12, 57, 27, -61, -3, 20, -17,
|
||||
2, 0, 4, 0, -2, -33, -58, 81,
|
||||
-23, 39, -10, -5, 2, 6, -7, 5,
|
||||
4, -3, -2, -13, -23, -72, 107, 15,
|
||||
-5, 0, -7, -3, -6, 5, -4, 15,
|
||||
47, 12, -31, 25, -16, 8, 22, -25,
|
||||
-62, -56, -18, 14, 28, 12, 2, -11,
|
||||
74, -66, 41, -20, -7, 16, -20, 16,
|
||||
-8, 0, -16, 4, -19, 92, 12, -59,
|
||||
-14, -39, 49, -25, -16, 23, -27, 19,
|
||||
-3, -33, 19, 85, -29, 6, -7, -10,
|
||||
16, -7, -12, 1, -6, 2, 4, -2,
|
||||
64, 10, -25, 41, -2, -31, 15, 0,
|
||||
110, 50, 69, 35, 28, 19, -10, 2,
|
||||
-43, -49, -56, -15, -16, 10, 3, 12,
|
||||
-1, -8, 1, 26, -12, -1, 7, -11,
|
||||
-27, 41, 25, 1, -11, -18, 22, -7,
|
||||
-1, -47, -8, 23, -3, -17, -7, 18,
|
||||
-125, 59, -5, 3, 18, 1, 2, 3,
|
||||
27, -35, 65, -53, 50, -46, 37, -21,
|
||||
-28, 7, 14, -37, -5, -5, 12, 5,
|
||||
-8, 78, -19, 21, -6, -16, 8, -7,
|
||||
5, 2, 7, 2, 10, -6, 12, -60,
|
||||
44, 11, -36, -32, 31, 0, 2, -2,
|
||||
2, 1, -3, 7, -10, 17, -21, 10,
|
||||
6, -2, 19, -2, 59, -38, -86, 38,
|
||||
8, -41, -30, -45, -33, 7, 15, 28,
|
||||
29, -7, 24, -40, 7, 7, 5, -2,
|
||||
9, 24, -23, -18, 6, -29, 30, 2,
|
||||
28, 49, -11, -46, 10, 43, -13, -9,
|
||||
-1, -3, -7, -7, -17, -6, 97, -33,
|
||||
-21, 3, 5, 1, 12, -43, -8, 28,
|
||||
7, -43, -7, 17, -20, 19, -1, 2,
|
||||
-13, 9, 54, 34, 9, -28, -11, -9,
|
||||
-17, 110, -59, 44, -26, 0, 3, -12,
|
||||
-47, 73, -34, -43, 38, -33, 16, -5,
|
||||
-46, -4, -6, -2, -25, 19, -29, 28,
|
||||
-13, 5, 14, 27, -40, -43, 4, 32,
|
||||
-13, -2, -35, -4, 112, -42, 9, -12,
|
||||
37, -28, 17, 14, -19, 35, -39, 23,
|
||||
3, -14, -1, -57, -5, 94, -9, 3,
|
||||
-39, 5, 30, -10, -32, 42, -13, -14,
|
||||
-97, -63, 30, -9, 1, -7, 12, 5,
|
||||
20, 17, -9, -36, -30, 25, 47, -9,
|
||||
-15, 12, -22, 98, -8, -50, 15, -27,
|
||||
21, -16, -11, 2, 12, -10, 10, -3,
|
||||
33, 36, -96, 0, -17, 31, -9, 9,
|
||||
3, -20, 13, -11, 8, -4, 10, -10,
|
||||
9, 1, 112, -70, -27, 5, -21, 2,
|
||||
-57, -3, -29, 10, 19, -21, 21, -10,
|
||||
-66, -3, 91, -35, 30, -12, 0, -7,
|
||||
59, -28, 26, 2, 14, -18, 1, 1,
|
||||
11, 17, 20, -54, -59, 27, 4, 29,
|
||||
32, 5, 19, 12, -4, 1, 7, -10,
|
||||
5, -2, 10, 0, 23, -5, 28, -104,
|
||||
46, 11, 16, 3, 29, 1, -8, -14,
|
||||
1, 7, -50, 88, -62, 26, 8, -17,
|
||||
-14, 50, 0, 32, -12, -3, -27, 18,
|
||||
-8, -5, 8, 3, -20, -11, 37, -12,
|
||||
9, 33, 46, -101, -1, -4, 1, 6,
|
||||
-1, 28, -42, -15, 16, 5, -1, -2,
|
||||
-55, 85, 38, -9, -4, 11, -2, -9,
|
||||
-6, 3, -20, -10, -77, 89, 24, -3,
|
||||
-104, -57, -26, -31, -20, -6, -9, 14,
|
||||
20, -23, 46, -15, -31, 28, 1, -15,
|
||||
-2, 6, -2, 31, 45, -76, 23, -25,
|
||||
};
|
|
@ -1,163 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: high_lsp_tables.c
|
||||
Codebooks for high-band LSPs in SB-CELP mode
|
||||
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
const signed char high_lsp_cdbk[512]={
|
||||
39,12,-14,-20,-29,-61,-67,-76,
|
||||
-32,-71,-67,68,77,46,34,5,
|
||||
-13,-48,-46,-72,-81,-84,-60,-58,
|
||||
-40,-28,82,93,68,45,29,3,
|
||||
-19,-47,-28,-43,-35,-30,-8,-13,
|
||||
-39,-91,-91,-123,-96,10,10,-6,
|
||||
-18,-55,-60,-91,-56,-36,-27,-16,
|
||||
-48,-75,40,28,-10,-28,35,9,
|
||||
37,19,1,-20,-31,-41,-18,-25,
|
||||
-35,-68,-80,45,27,-1,47,13,
|
||||
0,-29,-35,-57,-50,-79,-73,-38,
|
||||
-19,5,35,14,-10,-23,16,-8,
|
||||
5,-24,-40,-62,-23,-27,-22,-16,
|
||||
-18,-46,-72,-77,43,21,33,1,
|
||||
-80,-70,-70,-64,-56,-52,-39,-33,
|
||||
-31,-38,-19,-19,-15,32,33,-2,
|
||||
7,-15,-15,-24,-23,-33,-41,-56,
|
||||
-24,-57,5,89,64,41,27,5,
|
||||
-9,-47,-60,-97,-97,-124,-20,-9,
|
||||
-44,-73,31,29,-4,64,48,7,
|
||||
-35,-57,0,-3,-26,-47,-3,-6,
|
||||
-40,-76,-79,-48,12,81,55,10,
|
||||
9,-24,-43,-73,-57,-69,16,5,
|
||||
-28,-53,18,29,20,0,-4,-11,
|
||||
6,-13,23,7,-17,-35,-37,-37,
|
||||
-30,-68,-63,6,24,-9,-14,3,
|
||||
21,-13,-27,-57,-49,-80,-24,-41,
|
||||
-5,-16,-5,1,45,25,12,-7,
|
||||
3,-15,-6,-16,-15,-8,6,-13,
|
||||
-42,-81,-80,-87,14,1,-10,-3,
|
||||
-43,-69,-46,-24,-28,-29,36,6,
|
||||
-43,-56,-12,12,54,79,43,9,
|
||||
54,22,2,8,-12,-43,-46,-52,
|
||||
-38,-69,-89,-5,75,38,33,5,
|
||||
-13,-53,-62,-87,-89,-113,-99,-55,
|
||||
-34,-37,62,55,33,16,21,-2,
|
||||
-17,-46,-29,-38,-38,-48,-39,-42,
|
||||
-36,-75,-72,-88,-48,-30,21,2,
|
||||
-15,-57,-64,-98,-84,-76,25,1,
|
||||
-46,-80,-12,18,-7,3,34,6,
|
||||
38,31,23,4,-1,20,14,-15,
|
||||
-43,-78,-91,-24,14,-3,54,16,
|
||||
0,-27,-28,-44,-56,-83,-92,-89,
|
||||
-3,34,56,41,36,22,20,-8,
|
||||
-7,-35,-42,-62,-49,3,12,-10,
|
||||
-50,-87,-96,-66,92,70,38,9,
|
||||
-70,-71,-62,-42,-39,-43,-11,-7,
|
||||
-50,-79,-58,-50,-31,32,31,-6,
|
||||
-4,-25,7,-17,-38,-70,-58,-27,
|
||||
-43,-83,-28,59,36,20,31,2,
|
||||
-27,-71,-80,-109,-98,-75,-33,-32,
|
||||
-31,-2,33,15,-6,43,33,-5,
|
||||
0,-22,-10,-27,-34,-49,-11,-20,
|
||||
-41,-91,-100,-121,-39,57,41,10,
|
||||
-19,-50,-38,-59,-60,-70,-18,-20,
|
||||
-8,-31,-8,-15,1,-14,-26,-25,
|
||||
33,21,32,17,1,-19,-19,-26,
|
||||
-58,-81,-35,-22,45,30,11,-11,
|
||||
3,-26,-48,-87,-67,-83,-58,3,
|
||||
-1,-26,-20,44,10,25,39,5,
|
||||
-9,-35,-27,-38,7,10,4,-9,
|
||||
-42,-85,-102,-127,52,44,28,10,
|
||||
-47,-61,-40,-39,-17,-1,-10,-33,
|
||||
-42,-74,-48,21,-4,70,52,10};
|
||||
|
||||
|
||||
const signed char high_lsp_cdbk2[512]={
|
||||
-36,-62,6,-9,-10,-14,-56,23,
|
||||
1,-26,23,-48,-17,12,8,-7,
|
||||
23,29,-36,-28,-6,-29,-17,-5,
|
||||
40,23,10,10,-46,-13,36,6,
|
||||
4,-30,-29,62,32,-32,-1,22,
|
||||
-14,1,-4,-22,-45,2,54,4,
|
||||
-30,-57,-59,-12,27,-3,-31,8,
|
||||
-9,5,10,-14,32,66,19,9,
|
||||
2,-25,-37,23,-15,18,-38,-31,
|
||||
5,-9,-21,15,0,22,62,30,
|
||||
15,-12,-14,-46,77,21,33,3,
|
||||
34,29,-19,50,2,11,9,-38,
|
||||
-12,-37,62,1,-15,54,32,6,
|
||||
2,-24,20,35,-21,2,19,24,
|
||||
-13,55,4,9,39,-19,30,-1,
|
||||
-21,73,54,33,8,18,3,15,
|
||||
6,-19,-47,6,-3,-48,-50,1,
|
||||
26,20,8,-23,-50,65,-14,-55,
|
||||
-17,-31,-37,-28,53,-1,-17,-53,
|
||||
1,57,11,-8,-25,-30,-37,64,
|
||||
5,-52,-45,15,23,31,15,14,
|
||||
-25,24,33,-2,-44,-56,-18,6,
|
||||
-21,-43,4,-12,17,-37,20,-10,
|
||||
34,15,2,15,55,21,-11,-31,
|
||||
-6,46,25,16,-9,-25,-8,-62,
|
||||
28,17,20,-32,-29,26,30,25,
|
||||
-19,2,-16,-17,26,-51,2,50,
|
||||
42,19,-66,23,29,-2,3,19,
|
||||
-19,-37,32,15,6,30,-34,13,
|
||||
11,-5,40,31,10,-42,4,-9,
|
||||
26,-9,-70,17,-2,-23,20,-22,
|
||||
-55,51,-24,-31,22,-22,15,-13,
|
||||
3,-10,-28,-16,56,4,-63,11,
|
||||
-18,-15,-18,-38,-35,16,-7,34,
|
||||
-1,-21,-49,-47,9,-37,7,8,
|
||||
69,55,20,6,-33,-45,-10,-9,
|
||||
6,-9,12,71,15,-3,-42,-7,
|
||||
-24,32,-35,-2,-42,-17,-5,0,
|
||||
-2,-33,-54,13,-12,-34,47,23,
|
||||
19,55,7,-8,74,31,14,16,
|
||||
-23,-26,19,12,-18,-49,-28,-31,
|
||||
-20,2,-14,-20,-47,78,40,13,
|
||||
-23,-11,21,-6,18,1,47,5,
|
||||
38,35,32,46,22,8,13,16,
|
||||
-14,18,51,19,40,39,11,-26,
|
||||
-1,-17,47,2,-53,-15,31,-22,
|
||||
38,21,-15,-16,5,-33,53,15,
|
||||
-38,86,11,-3,-24,49,13,-4,
|
||||
-11,-18,28,20,-12,-27,-26,35,
|
||||
-25,-35,-3,-20,-61,30,10,-55,
|
||||
-12,-22,-52,-54,-14,19,-32,-12,
|
||||
45,15,-8,-48,-9,11,-32,8,
|
||||
-16,-34,-13,51,18,38,-2,-32,
|
||||
-17,22,-2,-18,-28,-70,59,27,
|
||||
-28,-19,-10,-20,-9,-9,-8,-21,
|
||||
21,-8,35,-2,45,-3,-9,12,
|
||||
0,30,7,-39,43,27,-38,-91,
|
||||
30,26,19,-55,-4,63,14,-17,
|
||||
13,9,13,2,7,4,6,61,
|
||||
72,-1,-17,29,-1,-22,-17,8,
|
||||
-28,-37,63,44,41,3,2,14,
|
||||
9,-6,75,-8,-7,-12,-15,-12,
|
||||
13,9,-4,30,-22,-65,15,0,
|
||||
-45,4,-4,1,5,22,11,23};
|
|
@ -1,843 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: speex_jitter.h
|
||||
|
||||
Adaptive jitter buffer for Speex
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
TODO:
|
||||
- Add short-term estimate
|
||||
- Defensive programming
|
||||
+ warn when last returned < last desired (begative buffering)
|
||||
+ warn if update_delay not called between get() and tick() or is called twice in a row
|
||||
- Linked list structure for holding the packets instead of the current fixed-size array
|
||||
+ return memory to a pool
|
||||
+ allow pre-allocation of the pool
|
||||
+ optional max number of elements
|
||||
- Statistics
|
||||
+ drift
|
||||
+ loss
|
||||
+ late
|
||||
+ jitter
|
||||
+ buffering delay
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
|
||||
#include "arch.h"
|
||||
#include <speex/speex.h>
|
||||
#include <speex/speex_bits.h>
|
||||
#include <speex/speex_jitter.h>
|
||||
#include "os_support.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */
|
||||
|
||||
#define TSUB(a,b) ((spx_int32_t)((a)-(b)))
|
||||
|
||||
#define GT32(a,b) (((spx_int32_t)((a)-(b)))>0)
|
||||
#define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0)
|
||||
#define LT32(a,b) (((spx_int32_t)((a)-(b)))<0)
|
||||
#define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0)
|
||||
|
||||
#define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step))
|
||||
|
||||
#define MAX_TIMINGS 40
|
||||
#define MAX_BUFFERS 3
|
||||
#define TOP_DELAY 40
|
||||
|
||||
/** Buffer that keeps the time of arrival of the latest packets */
|
||||
struct TimingBuffer {
|
||||
int filled; /**< Number of entries occupied in "timing" and "counts"*/
|
||||
int curr_count; /**< Number of packet timings we got (including those we discarded) */
|
||||
spx_int32_t timing[MAX_TIMINGS]; /**< Sorted list of all timings ("latest" packets first) */
|
||||
spx_int16_t counts[MAX_TIMINGS]; /**< Order the packets were put in (will be used for short-term estimate) */
|
||||
};
|
||||
|
||||
static void tb_init(struct TimingBuffer *tb)
|
||||
{
|
||||
tb->filled = 0;
|
||||
tb->curr_count = 0;
|
||||
}
|
||||
|
||||
/* Add the timing of a new packet to the TimingBuffer */
|
||||
static void tb_add(struct TimingBuffer *tb, spx_int16_t timing)
|
||||
{
|
||||
int pos;
|
||||
/* Discard packet that won't make it into the list because they're too early */
|
||||
if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1])
|
||||
{
|
||||
tb->curr_count++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find where the timing info goes in the sorted list */
|
||||
pos = 0;
|
||||
/* FIXME: Do bisection instead of linear search */
|
||||
while (pos<tb->filled && timing >= tb->timing[pos])
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
|
||||
speex_assert(pos <= tb->filled && pos < MAX_TIMINGS);
|
||||
|
||||
/* Shift everything so we can perform the insertion */
|
||||
if (pos < tb->filled)
|
||||
{
|
||||
int move_size = tb->filled-pos;
|
||||
if (tb->filled == MAX_TIMINGS)
|
||||
move_size -= 1;
|
||||
SPEEX_MOVE(&tb->timing[pos+1], &tb->timing[pos], move_size);
|
||||
SPEEX_MOVE(&tb->counts[pos+1], &tb->counts[pos], move_size);
|
||||
}
|
||||
/* Insert */
|
||||
tb->timing[pos] = timing;
|
||||
tb->counts[pos] = tb->curr_count;
|
||||
|
||||
tb->curr_count++;
|
||||
if (tb->filled<MAX_TIMINGS)
|
||||
tb->filled++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Jitter buffer structure */
|
||||
struct JitterBuffer_ {
|
||||
spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */
|
||||
spx_uint32_t last_returned_timestamp; /**< Useful for getting the next packet with the same timestamp (for fragmented media) */
|
||||
spx_uint32_t next_stop; /**< Estimated time the next get() will be called */
|
||||
|
||||
spx_int32_t buffered; /**< Amount of data we think is still buffered by the application (timestamp units)*/
|
||||
|
||||
JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */
|
||||
spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */
|
||||
|
||||
void (*destroy) (void *); /**< Callback for destroying a packet */
|
||||
|
||||
spx_int32_t delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */
|
||||
spx_int32_t concealment_size; /**< Size of the packet loss concealment "units" */
|
||||
int reset_state; /**< True if state was just reset */
|
||||
int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */
|
||||
int late_cutoff; /**< How late must a packet be for it not to be considered at all */
|
||||
int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */
|
||||
int auto_adjust; /**< Whether to automatically adjust the delay at any time */
|
||||
|
||||
struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */
|
||||
struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */
|
||||
int window_size; /**< Total window over which the late frames are counted */
|
||||
int subwindow_size; /**< Sub-window size for faster computation */
|
||||
int max_late_rate; /**< Absolute maximum amount of late packets tolerable (in percent) */
|
||||
int latency_tradeoff; /**< Latency equivalent of losing one percent of packets */
|
||||
int auto_tradeoff; /**< Latency equivalent of losing one percent of packets (automatic default) */
|
||||
|
||||
int lost_count; /**< Number of consecutive lost packets */
|
||||
};
|
||||
|
||||
/** Based on available data, this computes the optimal delay for the jitter buffer.
|
||||
The optimised function is in timestamp units and is:
|
||||
cost = delay + late_factor*[number of frames that would be late if we used that delay]
|
||||
@param tb Array of buffers
|
||||
@param late_factor Equivalent cost of a late frame (in timestamp units)
|
||||
*/
|
||||
static spx_int16_t compute_opt_delay(JitterBuffer *jitter)
|
||||
{
|
||||
int i;
|
||||
spx_int16_t opt=0;
|
||||
spx_int32_t best_cost=0x7fffffff;
|
||||
int late = 0;
|
||||
int pos[MAX_BUFFERS];
|
||||
int tot_count;
|
||||
float late_factor;
|
||||
int penalty_taken = 0;
|
||||
int best = 0;
|
||||
int worst = 0;
|
||||
spx_int32_t deltaT;
|
||||
struct TimingBuffer *tb;
|
||||
|
||||
tb = jitter->_tb;
|
||||
|
||||
/* Number of packet timings we have received (including those we didn't keep) */
|
||||
tot_count = 0;
|
||||
for (i=0;i<MAX_BUFFERS;i++)
|
||||
tot_count += tb[i].curr_count;
|
||||
if (tot_count==0)
|
||||
return 0;
|
||||
|
||||
/* Compute cost for one lost packet */
|
||||
if (jitter->latency_tradeoff != 0)
|
||||
late_factor = jitter->latency_tradeoff * 100.0f / tot_count;
|
||||
else
|
||||
late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count;
|
||||
|
||||
/*fprintf(stderr, "late_factor = %f\n", late_factor);*/
|
||||
for (i=0;i<MAX_BUFFERS;i++)
|
||||
pos[i] = 0;
|
||||
|
||||
/* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late
|
||||
for the current settings) */
|
||||
for (i=0;i<TOP_DELAY;i++)
|
||||
{
|
||||
int j;
|
||||
int next=-1;
|
||||
int latest = 32767;
|
||||
/* Pick latest amoung all sub-windows */
|
||||
for (j=0;j<MAX_BUFFERS;j++)
|
||||
{
|
||||
if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest)
|
||||
{
|
||||
next = j;
|
||||
latest = tb[j].timing[pos[j]];
|
||||
}
|
||||
}
|
||||
if (next != -1)
|
||||
{
|
||||
spx_int32_t cost;
|
||||
|
||||
if (i==0)
|
||||
worst = latest;
|
||||
best = latest;
|
||||
latest = ROUND_DOWN(latest, jitter->delay_step);
|
||||
pos[next]++;
|
||||
|
||||
/* Actual cost function that tells us how bad using this delay would be */
|
||||
cost = -latest + late_factor*late;
|
||||
/*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/
|
||||
if (cost < best_cost)
|
||||
{
|
||||
best_cost = cost;
|
||||
opt = latest;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
/* For the next timing we will consider, there will be one more late packet to count */
|
||||
late++;
|
||||
/* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */
|
||||
if (latest >= 0 && !penalty_taken)
|
||||
{
|
||||
penalty_taken = 1;
|
||||
late+=4;
|
||||
}
|
||||
}
|
||||
|
||||
deltaT = best-worst;
|
||||
/* This is a default "automatic latency tradeoff" when none is provided */
|
||||
jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY;
|
||||
/*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/
|
||||
|
||||
/* FIXME: Compute a short-term estimate too and combine with the long-term one */
|
||||
|
||||
/* Prevents reducing the buffer size when we haven't really had much data */
|
||||
if (tot_count < TOP_DELAY && opt > 0)
|
||||
return 0;
|
||||
return opt;
|
||||
}
|
||||
|
||||
|
||||
/** Initialise jitter buffer */
|
||||
EXPORT JitterBuffer *jitter_buffer_init(int step_size)
|
||||
{
|
||||
JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer));
|
||||
if (jitter)
|
||||
{
|
||||
int i;
|
||||
spx_int32_t tmp;
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
jitter->packets[i].data=NULL;
|
||||
jitter->delay_step = step_size;
|
||||
jitter->concealment_size = step_size;
|
||||
/*FIXME: Should this be 0 or 1?*/
|
||||
jitter->buffer_margin = 0;
|
||||
jitter->late_cutoff = 50;
|
||||
jitter->destroy = NULL;
|
||||
jitter->latency_tradeoff = 0;
|
||||
jitter->auto_adjust = 1;
|
||||
tmp = 4;
|
||||
jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
|
||||
jitter_buffer_reset(jitter);
|
||||
}
|
||||
return jitter;
|
||||
}
|
||||
|
||||
/** Reset jitter buffer */
|
||||
EXPORT void jitter_buffer_reset(JitterBuffer *jitter)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->packets[i].data)
|
||||
{
|
||||
if (jitter->destroy)
|
||||
jitter->destroy(jitter->packets[i].data);
|
||||
else
|
||||
speex_free(jitter->packets[i].data);
|
||||
jitter->packets[i].data = NULL;
|
||||
}
|
||||
}
|
||||
/* Timestamp is actually undefined at this point */
|
||||
jitter->pointer_timestamp = 0;
|
||||
jitter->next_stop = 0;
|
||||
jitter->reset_state = 1;
|
||||
jitter->lost_count = 0;
|
||||
jitter->buffered = 0;
|
||||
jitter->auto_tradeoff = 32000;
|
||||
|
||||
for (i=0;i<MAX_BUFFERS;i++)
|
||||
{
|
||||
tb_init(&jitter->_tb[i]);
|
||||
jitter->timeBuffers[i] = &jitter->_tb[i];
|
||||
}
|
||||
/*fprintf (stderr, "reset\n");*/
|
||||
}
|
||||
|
||||
/** Destroy jitter buffer */
|
||||
EXPORT void jitter_buffer_destroy(JitterBuffer *jitter)
|
||||
{
|
||||
jitter_buffer_reset(jitter);
|
||||
speex_free(jitter);
|
||||
}
|
||||
|
||||
/** Take the following timing into consideration for future calculations */
|
||||
static void update_timings(JitterBuffer *jitter, spx_int32_t timing)
|
||||
{
|
||||
if (timing < -32767)
|
||||
timing = -32767;
|
||||
if (timing > 32767)
|
||||
timing = 32767;
|
||||
/* If the current sub-window is full, perform a rotation and discard oldest sub-widow */
|
||||
if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size)
|
||||
{
|
||||
int i;
|
||||
/*fprintf(stderr, "Rotate buffer\n");*/
|
||||
struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1];
|
||||
for (i=MAX_BUFFERS-1;i>=1;i--)
|
||||
jitter->timeBuffers[i] = jitter->timeBuffers[i-1];
|
||||
jitter->timeBuffers[0] = tmp;
|
||||
tb_init(jitter->timeBuffers[0]);
|
||||
}
|
||||
tb_add(jitter->timeBuffers[0], timing);
|
||||
}
|
||||
|
||||
/** Compensate all timings when we do an adjustment of the buffering */
|
||||
static void shift_timings(JitterBuffer *jitter, spx_int16_t amount)
|
||||
{
|
||||
int i, j;
|
||||
for (i=0;i<MAX_BUFFERS;i++)
|
||||
{
|
||||
for (j=0;j<jitter->timeBuffers[i]->filled;j++)
|
||||
jitter->timeBuffers[i]->timing[j] += amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Put one packet into the jitter buffer */
|
||||
EXPORT void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
|
||||
{
|
||||
int i,j;
|
||||
int late;
|
||||
/*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/
|
||||
|
||||
/* Cleanup buffer (remove old packets that weren't played) */
|
||||
if (!jitter->reset_state)
|
||||
{
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
/* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */
|
||||
if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp))
|
||||
{
|
||||
/*fprintf (stderr, "cleaned (not played)\n");*/
|
||||
if (jitter->destroy)
|
||||
jitter->destroy(jitter->packets[i].data);
|
||||
else
|
||||
speex_free(jitter->packets[i].data);
|
||||
jitter->packets[i].data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/
|
||||
/* Check if packet is late (could still be useful though) */
|
||||
if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop))
|
||||
{
|
||||
update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin);
|
||||
late = 1;
|
||||
} else {
|
||||
late = 0;
|
||||
}
|
||||
|
||||
/* For some reason, the consumer has failed the last 20 fetches. Make sure this packet is
|
||||
* used to resync. */
|
||||
if (jitter->lost_count>20)
|
||||
{
|
||||
jitter_buffer_reset(jitter);
|
||||
}
|
||||
|
||||
/* Only insert the packet if it's not hopelessly late (i.e. totally useless) */
|
||||
if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp))
|
||||
{
|
||||
|
||||
/*Find an empty slot in the buffer*/
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->packets[i].data==NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/*No place left in the buffer, need to make room for it by discarding the oldest packet */
|
||||
if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
|
||||
{
|
||||
int earliest=jitter->packets[0].timestamp;
|
||||
i=0;
|
||||
for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
|
||||
{
|
||||
if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest))
|
||||
{
|
||||
earliest = jitter->packets[j].timestamp;
|
||||
i=j;
|
||||
}
|
||||
}
|
||||
if (jitter->destroy)
|
||||
jitter->destroy(jitter->packets[i].data);
|
||||
else
|
||||
speex_free(jitter->packets[i].data);
|
||||
jitter->packets[i].data=NULL;
|
||||
/*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/
|
||||
}
|
||||
|
||||
/* Copy packet in buffer */
|
||||
if (jitter->destroy)
|
||||
{
|
||||
jitter->packets[i].data = packet->data;
|
||||
} else {
|
||||
jitter->packets[i].data=(char*)speex_alloc(packet->len);
|
||||
for (j=0;j<packet->len;j++)
|
||||
jitter->packets[i].data[j]=packet->data[j];
|
||||
}
|
||||
jitter->packets[i].timestamp=packet->timestamp;
|
||||
jitter->packets[i].span=packet->span;
|
||||
jitter->packets[i].len=packet->len;
|
||||
jitter->packets[i].sequence=packet->sequence;
|
||||
jitter->packets[i].user_data=packet->user_data;
|
||||
if (jitter->reset_state || late)
|
||||
jitter->arrival[i] = 0;
|
||||
else
|
||||
jitter->arrival[i] = jitter->next_stop;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/** Get one packet from the jitter buffer */
|
||||
EXPORT int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset)
|
||||
{
|
||||
int i;
|
||||
unsigned int j;
|
||||
int incomplete = 0;
|
||||
spx_int16_t opt;
|
||||
|
||||
if (start_offset != NULL)
|
||||
*start_offset = 0;
|
||||
|
||||
/* Syncing on the first call */
|
||||
if (jitter->reset_state)
|
||||
{
|
||||
int found = 0;
|
||||
/* Find the oldest packet */
|
||||
spx_uint32_t oldest=0;
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->packets[i].data && (!found || LT32(jitter->packets[i].timestamp,oldest)))
|
||||
{
|
||||
oldest = jitter->packets[i].timestamp;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
jitter->reset_state=0;
|
||||
jitter->pointer_timestamp = oldest;
|
||||
jitter->next_stop = oldest;
|
||||
} else {
|
||||
packet->timestamp = 0;
|
||||
packet->span = jitter->interp_requested;
|
||||
return JITTER_BUFFER_MISSING;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jitter->last_returned_timestamp = jitter->pointer_timestamp;
|
||||
|
||||
if (jitter->interp_requested != 0)
|
||||
{
|
||||
packet->timestamp = jitter->pointer_timestamp;
|
||||
packet->span = jitter->interp_requested;
|
||||
|
||||
/* Increment the pointer because it got decremented in the delay update */
|
||||
jitter->pointer_timestamp += jitter->interp_requested;
|
||||
packet->len = 0;
|
||||
/*fprintf (stderr, "Deferred interpolate\n");*/
|
||||
|
||||
jitter->interp_requested = 0;
|
||||
|
||||
jitter->buffered = packet->span - desired_span;
|
||||
|
||||
return JITTER_BUFFER_INSERTION;
|
||||
}
|
||||
|
||||
/* Searching for the packet that fits best */
|
||||
|
||||
/* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->pointer_timestamp && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span))
|
||||
break;
|
||||
}
|
||||
|
||||
/* If no match, try for an "older" packet that still spans (fully) the current chunk */
|
||||
if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
|
||||
{
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If still no match, try for an "older" packet that spans part of the current chunk */
|
||||
if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
|
||||
{
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GT32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If still no match, try for earliest packet possible */
|
||||
if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
|
||||
{
|
||||
int found = 0;
|
||||
spx_uint32_t best_time=0;
|
||||
int best_span=0;
|
||||
int besti=0;
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
/* check if packet starts within current chunk */
|
||||
if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp))
|
||||
{
|
||||
if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span)))
|
||||
{
|
||||
best_time = jitter->packets[i].timestamp;
|
||||
best_span = jitter->packets[i].span;
|
||||
besti = i;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
i=besti;
|
||||
incomplete = 1;
|
||||
/*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/
|
||||
}
|
||||
}
|
||||
|
||||
/* If we find something */
|
||||
if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
|
||||
{
|
||||
spx_int32_t offset;
|
||||
|
||||
/* We (obviously) haven't lost this packet */
|
||||
jitter->lost_count = 0;
|
||||
|
||||
/* In this case, 0 isn't as a valid timestamp */
|
||||
if (jitter->arrival[i] != 0)
|
||||
{
|
||||
update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin);
|
||||
}
|
||||
|
||||
|
||||
/* Copy packet */
|
||||
if (jitter->destroy)
|
||||
{
|
||||
packet->data = jitter->packets[i].data;
|
||||
packet->len = jitter->packets[i].len;
|
||||
} else {
|
||||
if (jitter->packets[i].len > packet->len)
|
||||
{
|
||||
speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len);
|
||||
} else {
|
||||
packet->len = jitter->packets[i].len;
|
||||
}
|
||||
for (j=0;j<packet->len;j++)
|
||||
packet->data[j] = jitter->packets[i].data[j];
|
||||
/* Remove packet */
|
||||
speex_free(jitter->packets[i].data);
|
||||
}
|
||||
jitter->packets[i].data = NULL;
|
||||
/* Set timestamp and span (if requested) */
|
||||
offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp;
|
||||
if (start_offset != NULL)
|
||||
*start_offset = offset;
|
||||
else if (offset != 0)
|
||||
speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset);
|
||||
|
||||
packet->timestamp = jitter->packets[i].timestamp;
|
||||
jitter->last_returned_timestamp = packet->timestamp;
|
||||
|
||||
packet->span = jitter->packets[i].span;
|
||||
packet->sequence = jitter->packets[i].sequence;
|
||||
packet->user_data = jitter->packets[i].user_data;
|
||||
/* Point to the end of the current packet */
|
||||
jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span;
|
||||
|
||||
jitter->buffered = packet->span - desired_span;
|
||||
|
||||
if (start_offset != NULL)
|
||||
jitter->buffered += *start_offset;
|
||||
|
||||
return JITTER_BUFFER_OK;
|
||||
}
|
||||
|
||||
|
||||
/* If we haven't found anything worth returning */
|
||||
|
||||
/*fprintf (stderr, "not found\n");*/
|
||||
jitter->lost_count++;
|
||||
/*fprintf (stderr, "m");*/
|
||||
/*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/
|
||||
|
||||
opt = compute_opt_delay(jitter);
|
||||
|
||||
/* Should we force an increase in the buffer or just do normal interpolation? */
|
||||
if (opt < 0)
|
||||
{
|
||||
/* Need to increase buffering */
|
||||
|
||||
/* Shift histogram to compensate */
|
||||
shift_timings(jitter, -opt);
|
||||
|
||||
packet->timestamp = jitter->pointer_timestamp;
|
||||
packet->span = -opt;
|
||||
/* Don't move the pointer_timestamp forward */
|
||||
packet->len = 0;
|
||||
|
||||
jitter->buffered = packet->span - desired_span;
|
||||
return JITTER_BUFFER_INSERTION;
|
||||
/*jitter->pointer_timestamp -= jitter->delay_step;*/
|
||||
/*fprintf (stderr, "Forced to interpolate\n");*/
|
||||
} else {
|
||||
/* Normal packet loss */
|
||||
packet->timestamp = jitter->pointer_timestamp;
|
||||
|
||||
desired_span = ROUND_DOWN(desired_span, jitter->concealment_size);
|
||||
packet->span = desired_span;
|
||||
jitter->pointer_timestamp += desired_span;
|
||||
packet->len = 0;
|
||||
|
||||
jitter->buffered = packet->span - desired_span;
|
||||
return JITTER_BUFFER_MISSING;
|
||||
/*fprintf (stderr, "Normal loss\n");*/
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
EXPORT int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet)
|
||||
{
|
||||
int i, j;
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp)
|
||||
break;
|
||||
}
|
||||
if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
|
||||
{
|
||||
/* Copy packet */
|
||||
packet->len = jitter->packets[i].len;
|
||||
if (jitter->destroy)
|
||||
{
|
||||
packet->data = jitter->packets[i].data;
|
||||
} else {
|
||||
for (j=0;j<packet->len;j++)
|
||||
packet->data[j] = jitter->packets[i].data[j];
|
||||
/* Remove packet */
|
||||
speex_free(jitter->packets[i].data);
|
||||
}
|
||||
jitter->packets[i].data = NULL;
|
||||
packet->timestamp = jitter->packets[i].timestamp;
|
||||
packet->span = jitter->packets[i].span;
|
||||
packet->sequence = jitter->packets[i].sequence;
|
||||
packet->user_data = jitter->packets[i].user_data;
|
||||
return JITTER_BUFFER_OK;
|
||||
} else {
|
||||
packet->data = NULL;
|
||||
packet->len = 0;
|
||||
packet->span = 0;
|
||||
return JITTER_BUFFER_MISSING;
|
||||
}
|
||||
}
|
||||
|
||||
/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
|
||||
static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
|
||||
{
|
||||
spx_int16_t opt = compute_opt_delay(jitter);
|
||||
/*fprintf(stderr, "opt adjustment is %d ", opt);*/
|
||||
|
||||
if (opt < 0)
|
||||
{
|
||||
shift_timings(jitter, -opt);
|
||||
|
||||
jitter->pointer_timestamp += opt;
|
||||
jitter->interp_requested = -opt;
|
||||
/*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/
|
||||
} else if (opt > 0)
|
||||
{
|
||||
shift_timings(jitter, -opt);
|
||||
jitter->pointer_timestamp += opt;
|
||||
/*fprintf (stderr, "Decision to drop %d samples\n", opt);*/
|
||||
}
|
||||
|
||||
return opt;
|
||||
}
|
||||
|
||||
/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
|
||||
EXPORT int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
|
||||
{
|
||||
/* If the programmer calls jitter_buffer_update_delay() directly,
|
||||
automatically disable auto-adjustment */
|
||||
jitter->auto_adjust = 0;
|
||||
|
||||
return _jitter_buffer_update_delay(jitter, packet, start_offset);
|
||||
}
|
||||
|
||||
/** Get pointer timestamp of jitter buffer */
|
||||
EXPORT int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
|
||||
{
|
||||
return jitter->pointer_timestamp;
|
||||
}
|
||||
|
||||
EXPORT void jitter_buffer_tick(JitterBuffer *jitter)
|
||||
{
|
||||
/* Automatically-adjust the buffering delay if requested */
|
||||
if (jitter->auto_adjust)
|
||||
_jitter_buffer_update_delay(jitter, NULL, NULL);
|
||||
|
||||
if (jitter->buffered >= 0)
|
||||
{
|
||||
jitter->next_stop = jitter->pointer_timestamp - jitter->buffered;
|
||||
} else {
|
||||
jitter->next_stop = jitter->pointer_timestamp;
|
||||
speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered);
|
||||
}
|
||||
jitter->buffered = 0;
|
||||
}
|
||||
|
||||
EXPORT void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem)
|
||||
{
|
||||
/* Automatically-adjust the buffering delay if requested */
|
||||
if (jitter->auto_adjust)
|
||||
_jitter_buffer_update_delay(jitter, NULL, NULL);
|
||||
|
||||
if (jitter->buffered < 0)
|
||||
speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered);
|
||||
jitter->next_stop = jitter->pointer_timestamp - rem;
|
||||
}
|
||||
|
||||
|
||||
/* Used like the ioctl function to control the jitter buffer parameters */
|
||||
EXPORT int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr)
|
||||
{
|
||||
int count, i;
|
||||
switch(request)
|
||||
{
|
||||
case JITTER_BUFFER_SET_MARGIN:
|
||||
jitter->buffer_margin = *(spx_int32_t*)ptr;
|
||||
break;
|
||||
case JITTER_BUFFER_GET_MARGIN:
|
||||
*(spx_int32_t*)ptr = jitter->buffer_margin;
|
||||
break;
|
||||
case JITTER_BUFFER_GET_AVALIABLE_COUNT:
|
||||
count = 0;
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
*(spx_int32_t*)ptr = count;
|
||||
break;
|
||||
case JITTER_BUFFER_SET_DESTROY_CALLBACK:
|
||||
jitter->destroy = (void (*) (void *))ptr;
|
||||
break;
|
||||
case JITTER_BUFFER_GET_DESTROY_CALLBACK:
|
||||
*(void (**) (void *))ptr = jitter->destroy;
|
||||
break;
|
||||
case JITTER_BUFFER_SET_DELAY_STEP:
|
||||
jitter->delay_step = *(spx_int32_t*)ptr;
|
||||
break;
|
||||
case JITTER_BUFFER_GET_DELAY_STEP:
|
||||
*(spx_int32_t*)ptr = jitter->delay_step;
|
||||
break;
|
||||
case JITTER_BUFFER_SET_CONCEALMENT_SIZE:
|
||||
jitter->concealment_size = *(spx_int32_t*)ptr;
|
||||
break;
|
||||
case JITTER_BUFFER_GET_CONCEALMENT_SIZE:
|
||||
*(spx_int32_t*)ptr = jitter->concealment_size;
|
||||
break;
|
||||
case JITTER_BUFFER_SET_MAX_LATE_RATE:
|
||||
jitter->max_late_rate = *(spx_int32_t*)ptr;
|
||||
jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate;
|
||||
jitter->subwindow_size = jitter->window_size/MAX_BUFFERS;
|
||||
break;
|
||||
case JITTER_BUFFER_GET_MAX_LATE_RATE:
|
||||
*(spx_int32_t*)ptr = jitter->max_late_rate;
|
||||
break;
|
||||
case JITTER_BUFFER_SET_LATE_COST:
|
||||
jitter->latency_tradeoff = *(spx_int32_t*)ptr;
|
||||
break;
|
||||
case JITTER_BUFFER_GET_LATE_COST:
|
||||
*(spx_int32_t*)ptr = jitter->latency_tradeoff;
|
||||
break;
|
||||
default:
|
||||
speex_warning_int("Unknown jitter_buffer_ctl request: ", request);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,523 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2003-2004, Mark Borgerding
|
||||
Copyright (c) 2005-2007, Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "_kiss_fft_guts.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
/* The guts header contains all the multiplication and addition macros that are defined for
|
||||
fixed or floating point complex numbers. It also delares the kf_ internal functions.
|
||||
*/
|
||||
|
||||
static void kf_bfly2(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
int m,
|
||||
int N,
|
||||
int mm
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx * Fout2;
|
||||
kiss_fft_cpx * tw1;
|
||||
kiss_fft_cpx t;
|
||||
if (!st->inverse) {
|
||||
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++)
|
||||
{
|
||||
/* Almost the same as the code path below, except that we divide the input by two
|
||||
(while keeping the best accuracy possible) */
|
||||
spx_word32_t tr, ti;
|
||||
tr = SHR32(SUB32(MULT16_16(Fout2->r , tw1->r),MULT16_16(Fout2->i , tw1->i)), 1);
|
||||
ti = SHR32(ADD32(MULT16_16(Fout2->i , tw1->r),MULT16_16(Fout2->r , tw1->i)), 1);
|
||||
tw1 += fstride;
|
||||
Fout2->r = PSHR32(SUB32(SHL32(EXTEND32(Fout->r), 14), tr), 15);
|
||||
Fout2->i = PSHR32(SUB32(SHL32(EXTEND32(Fout->i), 14), ti), 15);
|
||||
Fout->r = PSHR32(ADD32(SHL32(EXTEND32(Fout->r), 14), tr), 15);
|
||||
Fout->i = PSHR32(ADD32(SHL32(EXTEND32(Fout->i), 14), ti), 15);
|
||||
++Fout2;
|
||||
++Fout;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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_MUL (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_cfg st,
|
||||
int m,
|
||||
int N,
|
||||
int mm
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx *tw1,*tw2,*tw3;
|
||||
kiss_fft_cpx scratch[6];
|
||||
const size_t m2=2*m;
|
||||
const size_t m3=3*m;
|
||||
int i, j;
|
||||
|
||||
if (st->inverse)
|
||||
{
|
||||
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_MUL(scratch[0],Fout[m] , *tw1 );
|
||||
C_MUL(scratch[1],Fout[m2] , *tw2 );
|
||||
C_MUL(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;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
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 = PSHR16(Fout->r, 2);
|
||||
Fout->i = PSHR16(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 = PSHR16(Fout[m2].r, 2);
|
||||
Fout[m2].i = PSHR16(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 kf_bfly3(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
size_t m
|
||||
)
|
||||
{
|
||||
size_t k=m;
|
||||
const size_t m2 = 2*m;
|
||||
kiss_fft_cpx *tw1,*tw2;
|
||||
kiss_fft_cpx scratch[5];
|
||||
kiss_fft_cpx epi3;
|
||||
epi3 = st->twiddles[fstride*m];
|
||||
|
||||
tw1=tw2=st->twiddles;
|
||||
|
||||
do{
|
||||
if (!st->inverse) {
|
||||
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 kf_bfly5(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
int m
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
|
||||
int u;
|
||||
kiss_fft_cpx scratch[13];
|
||||
kiss_fft_cpx * twiddles = st->twiddles;
|
||||
kiss_fft_cpx *tw;
|
||||
kiss_fft_cpx ya,yb;
|
||||
ya = twiddles[fstride*m];
|
||||
yb = twiddles[fstride*2*m];
|
||||
|
||||
Fout0=Fout;
|
||||
Fout1=Fout0+m;
|
||||
Fout2=Fout0+2*m;
|
||||
Fout3=Fout0+3*m;
|
||||
Fout4=Fout0+4*m;
|
||||
|
||||
tw=st->twiddles;
|
||||
for ( u=0; u<m; ++u ) {
|
||||
if (!st->inverse) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* perform the butterfly for one stage of a mixed radix FFT */
|
||||
static void kf_bfly_generic(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
int m,
|
||||
int p
|
||||
)
|
||||
{
|
||||
int u,k,q1,q;
|
||||
kiss_fft_cpx * twiddles = st->twiddles;
|
||||
kiss_fft_cpx t;
|
||||
kiss_fft_cpx scratchbuf[17];
|
||||
int Norig = st->nfft;
|
||||
|
||||
/*CHECKBUF(scratchbuf,nscratchbuf,p);*/
|
||||
if (p>17)
|
||||
speex_fatal("KissFFT: max radix supported is 17");
|
||||
|
||||
for ( u=0; u<m; ++u ) {
|
||||
k=u;
|
||||
for ( q1=0 ; q1<p ; ++q1 ) {
|
||||
scratchbuf[q1] = Fout[ k ];
|
||||
if (!st->inverse) {
|
||||
C_FIXDIV(scratchbuf[q1],p);
|
||||
}
|
||||
k += m;
|
||||
}
|
||||
|
||||
k=u;
|
||||
for ( q1=0 ; q1<p ; ++q1 ) {
|
||||
int twidx=0;
|
||||
Fout[ k ] = scratchbuf[0];
|
||||
for (q=1;q<p;++q ) {
|
||||
twidx += fstride * k;
|
||||
if (twidx>=Norig) twidx-=Norig;
|
||||
C_MUL(t,scratchbuf[q] , twiddles[twidx] );
|
||||
C_ADDTO( Fout[ k ] ,t);
|
||||
}
|
||||
k += m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void kf_shuffle(
|
||||
kiss_fft_cpx * Fout,
|
||||
const kiss_fft_cpx * f,
|
||||
const size_t fstride,
|
||||
int in_stride,
|
||||
int * factors,
|
||||
const kiss_fft_cfg 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++)
|
||||
{
|
||||
Fout[j] = *f;
|
||||
f += fstride*in_stride;
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
for (j=0;j<p;j++)
|
||||
{
|
||||
kf_shuffle( Fout , f, fstride*p, in_stride, factors,st);
|
||||
f += fstride*in_stride;
|
||||
Fout += m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void kf_work(
|
||||
kiss_fft_cpx * Fout,
|
||||
const kiss_fft_cpx * f,
|
||||
const size_t fstride,
|
||||
int in_stride,
|
||||
int * factors,
|
||||
const kiss_fft_cfg st,
|
||||
int N,
|
||||
int s2,
|
||||
int m2
|
||||
)
|
||||
{
|
||||
int i;
|
||||
kiss_fft_cpx * Fout_beg=Fout;
|
||||
const int p=*factors++; /* the radix */
|
||||
const int m=*factors++; /* stage's fft length/p */
|
||||
#if 0
|
||||
/*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++)
|
||||
{
|
||||
Fout[j] = *f;
|
||||
f += fstride*in_stride;
|
||||
}*/
|
||||
} else {
|
||||
int j;
|
||||
for (j=0;j<p;j++)
|
||||
{
|
||||
kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m);
|
||||
f += fstride*in_stride;
|
||||
Fout += m;
|
||||
}
|
||||
}
|
||||
|
||||
Fout=Fout_beg;
|
||||
|
||||
switch (p) {
|
||||
case 2: kf_bfly2(Fout,fstride,st,m); break;
|
||||
case 3: kf_bfly3(Fout,fstride,st,m); break;
|
||||
case 4: kf_bfly4(Fout,fstride,st,m); break;
|
||||
case 5: kf_bfly5(Fout,fstride,st,m); break;
|
||||
default: kf_bfly_generic(Fout,fstride,st,m,p); break;
|
||||
}
|
||||
#else
|
||||
/*printf ("fft %d %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N, m2);*/
|
||||
if (m==1)
|
||||
{
|
||||
/*for (i=0;i<N;i++)
|
||||
{
|
||||
int j;
|
||||
Fout = Fout_beg+i*m2;
|
||||
const kiss_fft_cpx * f2 = f+i*s2;
|
||||
for (j=0;j<p;j++)
|
||||
{
|
||||
*Fout++ = *f2;
|
||||
f2 += fstride*in_stride;
|
||||
}
|
||||
}*/
|
||||
}else{
|
||||
kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
switch (p) {
|
||||
case 2: kf_bfly2(Fout,fstride,st,m, N, m2); break;
|
||||
case 3: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly3(Fout,fstride,st,m);} break;
|
||||
case 4: kf_bfly4(Fout,fstride,st,m, N, m2); break;
|
||||
case 5: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly5(Fout,fstride,st,m);} break;
|
||||
default: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly_generic(Fout,fstride,st,m,p);} break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* facbuf is populated by p1,m1,p2,m2, ...
|
||||
where
|
||||
p[i] * m[i] = m[i-1]
|
||||
m0 = n */
|
||||
static
|
||||
void kf_factor(int n,int * 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 || (spx_int32_t)p*(spx_int32_t)p > n)
|
||||
p = n; /* no more factors, skip to end */
|
||||
}
|
||||
n /= p;
|
||||
*facbuf++ = p;
|
||||
*facbuf++ = n;
|
||||
} while (n > 1);
|
||||
}
|
||||
/*
|
||||
*
|
||||
* User-callable function to allocate all necessary storage space for the fft.
|
||||
*
|
||||
* The return value is a contiguous block of memory, allocated with malloc. As such,
|
||||
* It can be freed with free(), rather than a kiss_fft-specific function.
|
||||
* */
|
||||
kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
|
||||
{
|
||||
kiss_fft_cfg st=NULL;
|
||||
size_t memneeded = sizeof(struct kiss_fft_state)
|
||||
+ sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
|
||||
|
||||
if ( lenmem==NULL ) {
|
||||
st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
|
||||
}else{
|
||||
if (mem != NULL && *lenmem >= memneeded)
|
||||
st = (kiss_fft_cfg)mem;
|
||||
*lenmem = memneeded;
|
||||
}
|
||||
if (st) {
|
||||
int i;
|
||||
st->nfft=nfft;
|
||||
st->inverse = inverse_fft;
|
||||
#ifdef FIXED_POINT
|
||||
for (i=0;i<nfft;++i) {
|
||||
spx_word32_t phase = i;
|
||||
if (!st->inverse)
|
||||
phase = -phase;
|
||||
kf_cexp2(st->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;
|
||||
if (st->inverse)
|
||||
phase *= -1;
|
||||
kf_cexp(st->twiddles+i, phase );
|
||||
}
|
||||
#endif
|
||||
kf_factor(nfft,st->factors);
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
|
||||
{
|
||||
if (fin == fout)
|
||||
{
|
||||
speex_fatal("In-place FFT not supported");
|
||||
/*CHECKBUF(tmpbuf,ntmpbuf,st->nfft);
|
||||
kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
|
||||
SPEEX_MOVE(fout,tmpbuf,st->nfft);*/
|
||||
} else {
|
||||
kf_shuffle( fout, fin, 1,in_stride, st->factors,st);
|
||||
kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
|
||||
{
|
||||
kiss_fft_stride(cfg,fin,fout,1);
|
||||
}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
#ifndef KISS_FFT_H
|
||||
#define KISS_FFT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "arch.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
ATTENTION!
|
||||
If you would like a :
|
||||
-- a utility that will handle the caching of fft objects
|
||||
-- real-only (no imaginary time component ) FFT
|
||||
-- a multi-dimensional FFT
|
||||
-- a command-line utility to perform ffts
|
||||
-- a command-line utility to perform fast-convolution filtering
|
||||
|
||||
Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
|
||||
in the tools/ directory.
|
||||
*/
|
||||
|
||||
#ifdef USE_SIMD
|
||||
# include <xmmintrin.h>
|
||||
# define kiss_fft_scalar __m128
|
||||
#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes)
|
||||
#else
|
||||
#define KISS_FFT_MALLOC speex_alloc
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#include "arch.h"
|
||||
# define kiss_fft_scalar spx_int16_t
|
||||
#else
|
||||
# ifndef kiss_fft_scalar
|
||||
/* default is float */
|
||||
# define kiss_fft_scalar float
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
kiss_fft_scalar r;
|
||||
kiss_fft_scalar i;
|
||||
}kiss_fft_cpx;
|
||||
|
||||
typedef struct kiss_fft_state* kiss_fft_cfg;
|
||||
|
||||
/*
|
||||
* kiss_fft_alloc
|
||||
*
|
||||
* Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
|
||||
*
|
||||
* typical usage: kiss_fft_cfg mycfg=kiss_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 kiss_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_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
|
||||
|
||||
/*
|
||||
* kiss_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 kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
|
||||
|
||||
/*
|
||||
A more generic version of the above function. It reads its input from every Nth sample.
|
||||
* */
|
||||
void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
|
||||
|
||||
/* If kiss_fft_alloc allocated a buffer, it is one contiguous
|
||||
buffer and can be simply free()d when no longer needed*/
|
||||
#define kiss_fft_free speex_free
|
||||
|
||||
/*
|
||||
Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up
|
||||
your compiler output to call this before you exit.
|
||||
*/
|
||||
void kiss_fft_cleanup(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,297 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
* Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "os_support.h"
|
||||
#include "kiss_fftr.h"
|
||||
#include "_kiss_fft_guts.h"
|
||||
|
||||
struct kiss_fftr_state{
|
||||
kiss_fft_cfg substate;
|
||||
kiss_fft_cpx * tmpbuf;
|
||||
kiss_fft_cpx * super_twiddles;
|
||||
#ifdef USE_SIMD
|
||||
long pad;
|
||||
#endif
|
||||
};
|
||||
|
||||
kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
|
||||
{
|
||||
int i;
|
||||
kiss_fftr_cfg st = NULL;
|
||||
size_t subsize, memneeded;
|
||||
|
||||
if (nfft & 1) {
|
||||
speex_warning("Real FFT optimization must be even.\n");
|
||||
return NULL;
|
||||
}
|
||||
nfft >>= 1;
|
||||
|
||||
kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);
|
||||
memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 2);
|
||||
|
||||
if (lenmem == NULL) {
|
||||
st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);
|
||||
} else {
|
||||
if (*lenmem >= memneeded)
|
||||
st = (kiss_fftr_cfg) mem;
|
||||
*lenmem = memneeded;
|
||||
}
|
||||
if (!st)
|
||||
return NULL;
|
||||
|
||||
st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
|
||||
st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
|
||||
st->super_twiddles = st->tmpbuf + nfft;
|
||||
kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
for (i=0;i<nfft;++i) {
|
||||
spx_word32_t phase = i+(nfft>>1);
|
||||
if (!inverse_fft)
|
||||
phase = -phase;
|
||||
kf_cexp2(st->super_twiddles+i, DIV32(SHL32(phase,16),nfft));
|
||||
}
|
||||
#else
|
||||
for (i=0;i<nfft;++i) {
|
||||
const double pi=3.14159265358979323846264338327;
|
||||
double phase = pi*(((double)i) /nfft + .5);
|
||||
if (!inverse_fft)
|
||||
phase = -phase;
|
||||
kf_cexp(st->super_twiddles+i, phase );
|
||||
}
|
||||
#endif
|
||||
return st;
|
||||
}
|
||||
|
||||
void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
|
||||
{
|
||||
/* input buffer timedata is stored row-wise */
|
||||
int k,ncfft;
|
||||
kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
|
||||
|
||||
if ( st->substate->inverse) {
|
||||
speex_fatal("kiss fft usage error: improper alloc\n");
|
||||
}
|
||||
|
||||
ncfft = st->substate->nfft;
|
||||
|
||||
/*perform the parallel fft of two real signals packed in real,imag*/
|
||||
kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
|
||||
/* The real part of the DC element of the frequency spectrum in st->tmpbuf
|
||||
* contains the sum of the even-numbered elements of the input time sequence
|
||||
* The imag part is the sum of the odd-numbered elements
|
||||
*
|
||||
* The sum of tdc.r and tdc.i is the sum of the input time sequence.
|
||||
* yielding DC of input time sequence
|
||||
* The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
|
||||
* yielding Nyquist bin of input time sequence
|
||||
*/
|
||||
|
||||
tdc.r = st->tmpbuf[0].r;
|
||||
tdc.i = st->tmpbuf[0].i;
|
||||
C_FIXDIV(tdc,2);
|
||||
CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
|
||||
CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
|
||||
freqdata[0].r = tdc.r + tdc.i;
|
||||
freqdata[ncfft].r = tdc.r - tdc.i;
|
||||
#ifdef USE_SIMD
|
||||
freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
|
||||
#else
|
||||
freqdata[ncfft].i = freqdata[0].i = 0;
|
||||
#endif
|
||||
|
||||
for ( k=1;k <= ncfft/2 ; ++k ) {
|
||||
fpk = st->tmpbuf[k];
|
||||
fpnk.r = st->tmpbuf[ncfft-k].r;
|
||||
fpnk.i = - st->tmpbuf[ncfft-k].i;
|
||||
C_FIXDIV(fpk,2);
|
||||
C_FIXDIV(fpnk,2);
|
||||
|
||||
C_ADD( f1k, fpk , fpnk );
|
||||
C_SUB( f2k, fpk , fpnk );
|
||||
C_MUL( tw , f2k , st->super_twiddles[k]);
|
||||
|
||||
freqdata[k].r = HALF_OF(f1k.r + tw.r);
|
||||
freqdata[k].i = HALF_OF(f1k.i + tw.i);
|
||||
freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r);
|
||||
freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i);
|
||||
}
|
||||
}
|
||||
|
||||
void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata, kiss_fft_scalar *timedata)
|
||||
{
|
||||
/* input buffer timedata is stored row-wise */
|
||||
int k, ncfft;
|
||||
|
||||
if (st->substate->inverse == 0) {
|
||||
speex_fatal("kiss fft usage error: improper alloc\n");
|
||||
}
|
||||
|
||||
ncfft = st->substate->nfft;
|
||||
|
||||
st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;
|
||||
st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;
|
||||
/*C_FIXDIV(st->tmpbuf[0],2);*/
|
||||
|
||||
for (k = 1; k <= ncfft / 2; ++k) {
|
||||
kiss_fft_cpx fk, fnkc, fek, fok, tmp;
|
||||
fk = freqdata[k];
|
||||
fnkc.r = freqdata[ncfft - k].r;
|
||||
fnkc.i = -freqdata[ncfft - k].i;
|
||||
/*C_FIXDIV( fk , 2 );
|
||||
C_FIXDIV( fnkc , 2 );*/
|
||||
|
||||
C_ADD (fek, fk, fnkc);
|
||||
C_SUB (tmp, fk, fnkc);
|
||||
C_MUL (fok, tmp, st->super_twiddles[k]);
|
||||
C_ADD (st->tmpbuf[k], fek, fok);
|
||||
C_SUB (st->tmpbuf[ncfft - k], fek, fok);
|
||||
#ifdef USE_SIMD
|
||||
st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
|
||||
#else
|
||||
st->tmpbuf[ncfft - k].i *= -1;
|
||||
#endif
|
||||
}
|
||||
kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
|
||||
}
|
||||
|
||||
void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata)
|
||||
{
|
||||
/* input buffer timedata is stored row-wise */
|
||||
int k,ncfft;
|
||||
kiss_fft_cpx f2k,tdc;
|
||||
spx_word32_t f1kr, f1ki, twr, twi;
|
||||
|
||||
if ( st->substate->inverse) {
|
||||
speex_fatal("kiss fft usage error: improper alloc\n");
|
||||
}
|
||||
|
||||
ncfft = st->substate->nfft;
|
||||
|
||||
/*perform the parallel fft of two real signals packed in real,imag*/
|
||||
kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
|
||||
/* The real part of the DC element of the frequency spectrum in st->tmpbuf
|
||||
* contains the sum of the even-numbered elements of the input time sequence
|
||||
* The imag part is the sum of the odd-numbered elements
|
||||
*
|
||||
* The sum of tdc.r and tdc.i is the sum of the input time sequence.
|
||||
* yielding DC of input time sequence
|
||||
* The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
|
||||
* yielding Nyquist bin of input time sequence
|
||||
*/
|
||||
|
||||
tdc.r = st->tmpbuf[0].r;
|
||||
tdc.i = st->tmpbuf[0].i;
|
||||
C_FIXDIV(tdc,2);
|
||||
CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
|
||||
CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
|
||||
freqdata[0] = tdc.r + tdc.i;
|
||||
freqdata[2*ncfft-1] = tdc.r - tdc.i;
|
||||
|
||||
for ( k=1;k <= ncfft/2 ; ++k )
|
||||
{
|
||||
/*fpk = st->tmpbuf[k];
|
||||
fpnk.r = st->tmpbuf[ncfft-k].r;
|
||||
fpnk.i = - st->tmpbuf[ncfft-k].i;
|
||||
C_FIXDIV(fpk,2);
|
||||
C_FIXDIV(fpnk,2);
|
||||
|
||||
C_ADD( f1k, fpk , fpnk );
|
||||
C_SUB( f2k, fpk , fpnk );
|
||||
|
||||
C_MUL( tw , f2k , st->super_twiddles[k]);
|
||||
|
||||
freqdata[2*k-1] = HALF_OF(f1k.r + tw.r);
|
||||
freqdata[2*k] = HALF_OF(f1k.i + tw.i);
|
||||
freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r);
|
||||
freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i);
|
||||
*/
|
||||
|
||||
/*f1k.r = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);
|
||||
f1k.i = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);
|
||||
f2k.r = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);
|
||||
f2k.i = SHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);
|
||||
|
||||
C_MUL( tw , f2k , st->super_twiddles[k]);
|
||||
|
||||
freqdata[2*k-1] = HALF_OF(f1k.r + tw.r);
|
||||
freqdata[2*k] = HALF_OF(f1k.i + tw.i);
|
||||
freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r);
|
||||
freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i);
|
||||
*/
|
||||
f2k.r = SHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);
|
||||
f2k.i = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);
|
||||
|
||||
f1kr = SHL32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),13);
|
||||
f1ki = SHL32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),13);
|
||||
|
||||
twr = SHR32(SUB32(MULT16_16(f2k.r,st->super_twiddles[k].r),MULT16_16(f2k.i,st->super_twiddles[k].i)), 1);
|
||||
twi = SHR32(ADD32(MULT16_16(f2k.i,st->super_twiddles[k].r),MULT16_16(f2k.r,st->super_twiddles[k].i)), 1);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
freqdata[2*k-1] = PSHR32(f1kr + twr, 15);
|
||||
freqdata[2*k] = PSHR32(f1ki + twi, 15);
|
||||
freqdata[2*(ncfft-k)-1] = PSHR32(f1kr - twr, 15);
|
||||
freqdata[2*(ncfft-k)] = PSHR32(twi - f1ki, 15);
|
||||
#else
|
||||
freqdata[2*k-1] = .5f*(f1kr + twr);
|
||||
freqdata[2*k] = .5f*(f1ki + twi);
|
||||
freqdata[2*(ncfft-k)-1] = .5f*(f1kr - twr);
|
||||
freqdata[2*(ncfft-k)] = .5f*(twi - f1ki);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scalar *timedata)
|
||||
{
|
||||
/* input buffer timedata is stored row-wise */
|
||||
int k, ncfft;
|
||||
|
||||
if (st->substate->inverse == 0) {
|
||||
speex_fatal ("kiss fft usage error: improper alloc\n");
|
||||
}
|
||||
|
||||
ncfft = st->substate->nfft;
|
||||
|
||||
st->tmpbuf[0].r = freqdata[0] + freqdata[2*ncfft-1];
|
||||
st->tmpbuf[0].i = freqdata[0] - freqdata[2*ncfft-1];
|
||||
/*C_FIXDIV(st->tmpbuf[0],2);*/
|
||||
|
||||
for (k = 1; k <= ncfft / 2; ++k) {
|
||||
kiss_fft_cpx fk, fnkc, fek, fok, tmp;
|
||||
fk.r = freqdata[2*k-1];
|
||||
fk.i = freqdata[2*k];
|
||||
fnkc.r = freqdata[2*(ncfft - k)-1];
|
||||
fnkc.i = -freqdata[2*(ncfft - k)];
|
||||
/*C_FIXDIV( fk , 2 );
|
||||
C_FIXDIV( fnkc , 2 );*/
|
||||
|
||||
C_ADD (fek, fk, fnkc);
|
||||
C_SUB (tmp, fk, fnkc);
|
||||
C_MUL (fok, tmp, st->super_twiddles[k]);
|
||||
C_ADD (st->tmpbuf[k], fek, fok);
|
||||
C_SUB (st->tmpbuf[ncfft - k], fek, fok);
|
||||
#ifdef USE_SIMD
|
||||
st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
|
||||
#else
|
||||
st->tmpbuf[ncfft - k].i *= -1;
|
||||
#endif
|
||||
}
|
||||
kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
#ifndef KISS_FTR_H
|
||||
#define KISS_FTR_H
|
||||
|
||||
#include "kiss_fft.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
typedef struct kiss_fftr_state *kiss_fftr_cfg;
|
||||
|
||||
|
||||
kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
|
||||
/*
|
||||
nfft must be even
|
||||
|
||||
If you don't care to allocate space, use mem = lenmem = NULL
|
||||
*/
|
||||
|
||||
|
||||
void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
|
||||
/*
|
||||
input timedata has nfft scalar points
|
||||
output freqdata has nfft/2+1 complex points
|
||||
*/
|
||||
|
||||
void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata);
|
||||
|
||||
void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
|
||||
|
||||
void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata, kiss_fft_scalar *timedata);
|
||||
|
||||
/*
|
||||
input freqdata has nfft/2+1 complex points
|
||||
output timedata has nfft scalar points
|
||||
*/
|
||||
|
||||
#define kiss_fftr_free speex_free
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -1,201 +0,0 @@
|
|||
/*
|
||||
Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
|
||||
Technische Universitaet Berlin
|
||||
|
||||
Any use of this software is permitted provided that this notice is not
|
||||
removed and that neither the authors nor the Technische Universitaet Berlin
|
||||
are deemed to have made any representations as to the suitability of this
|
||||
software for any purpose nor are held responsible for any defects of
|
||||
this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
|
||||
As a matter of courtesy, the authors request to be informed about uses
|
||||
this software has found, about bugs in this software, and about any
|
||||
improvements that may be of general interest.
|
||||
|
||||
Berlin, 28.11.1994
|
||||
Jutta Degener
|
||||
Carsten Bormann
|
||||
|
||||
|
||||
Code modified by Jean-Marc Valin
|
||||
|
||||
Speex License:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "lpc.h"
|
||||
|
||||
#ifdef BFIN_ASM
|
||||
#include "lpc_bfin.h"
|
||||
#endif
|
||||
|
||||
/* LPC analysis
|
||||
*
|
||||
* The next two functions calculate linear prediction coefficients
|
||||
* and/or the related reflection coefficients from the first P_MAX+1
|
||||
* values of the autocorrelation function.
|
||||
*/
|
||||
|
||||
/* Invented by N. Levinson in 1947, modified by J. Durbin in 1959.
|
||||
*/
|
||||
|
||||
/* returns minimum mean square error */
|
||||
spx_word32_t _spx_lpc(
|
||||
spx_coef_t *lpc, /* out: [0...p-1] LPC coefficients */
|
||||
const spx_word16_t *ac, /* in: [0...p] autocorrelation values */
|
||||
int p
|
||||
)
|
||||
{
|
||||
int i, j;
|
||||
spx_word16_t r;
|
||||
spx_word16_t error = ac[0];
|
||||
|
||||
if (ac[0] == 0)
|
||||
{
|
||||
for (i = 0; i < p; i++)
|
||||
lpc[i] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < p; i++) {
|
||||
|
||||
/* Sum up this iteration's reflection coefficient */
|
||||
spx_word32_t rr = NEG32(SHL32(EXTEND32(ac[i + 1]),13));
|
||||
for (j = 0; j < i; j++)
|
||||
rr = SUB32(rr,MULT16_16(lpc[j],ac[i - j]));
|
||||
#ifdef FIXED_POINT
|
||||
r = DIV32_16(rr+PSHR32(error,1),ADD16(error,8));
|
||||
#else
|
||||
r = rr/(error+.003*ac[0]);
|
||||
#endif
|
||||
/* Update LPC coefficients and total error */
|
||||
lpc[i] = r;
|
||||
for (j = 0; j < i>>1; j++)
|
||||
{
|
||||
spx_word16_t tmp = lpc[j];
|
||||
lpc[j] = MAC16_16_P13(lpc[j],r,lpc[i-1-j]);
|
||||
lpc[i-1-j] = MAC16_16_P13(lpc[i-1-j],r,tmp);
|
||||
}
|
||||
if (i & 1)
|
||||
lpc[j] = MAC16_16_P13(lpc[j],lpc[j],r);
|
||||
|
||||
error = SUB16(error,MULT16_16_Q13(r,MULT16_16_Q13(error,r)));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
/* Compute the autocorrelation
|
||||
* ,--,
|
||||
* ac(i) = > x(n) * x(n-i) for all n
|
||||
* `--'
|
||||
* for lags between 0 and lag-1, and x == 0 outside 0...n-1
|
||||
*/
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_AUTOCORR
|
||||
void _spx_autocorr(
|
||||
const spx_word16_t *x, /* in: [0...n-1] samples x */
|
||||
spx_word16_t *ac, /* out: [0...lag-1] ac values */
|
||||
int lag,
|
||||
int n
|
||||
)
|
||||
{
|
||||
spx_word32_t d;
|
||||
int i, j;
|
||||
spx_word32_t ac0=1;
|
||||
int shift, ac_shift;
|
||||
|
||||
for (j=0;j<n;j++)
|
||||
ac0 = ADD32(ac0,SHR32(MULT16_16(x[j],x[j]),8));
|
||||
ac0 = ADD32(ac0,n);
|
||||
shift = 8;
|
||||
while (shift && ac0<0x40000000)
|
||||
{
|
||||
shift--;
|
||||
ac0 <<= 1;
|
||||
}
|
||||
ac_shift = 18;
|
||||
while (ac_shift && ac0<0x40000000)
|
||||
{
|
||||
ac_shift--;
|
||||
ac0 <<= 1;
|
||||
}
|
||||
|
||||
|
||||
for (i=0;i<lag;i++)
|
||||
{
|
||||
d=0;
|
||||
for (j=i;j<n;j++)
|
||||
{
|
||||
d = ADD32(d,SHR32(MULT16_16(x[j],x[j-i]), shift));
|
||||
}
|
||||
|
||||
ac[i] = SHR32(d, ac_shift);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
|
||||
/* Compute the autocorrelation
|
||||
* ,--,
|
||||
* ac(i) = > x(n) * x(n-i) for all n
|
||||
* `--'
|
||||
* for lags between 0 and lag-1, and x == 0 outside 0...n-1
|
||||
*/
|
||||
void _spx_autocorr(
|
||||
const spx_word16_t *x, /* in: [0...n-1] samples x */
|
||||
float *ac, /* out: [0...lag-1] ac values */
|
||||
int lag,
|
||||
int n
|
||||
)
|
||||
{
|
||||
float d;
|
||||
int i;
|
||||
while (lag--)
|
||||
{
|
||||
for (i = lag, d = 0; i < n; i++)
|
||||
d += x[i] * x[i-lag];
|
||||
ac[lag] = d;
|
||||
}
|
||||
ac[0] += 10;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file lpc.h
|
||||
@brief Functions for LPC (Linear Prediction Coefficients) 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.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LPC_H
|
||||
#define LPC_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
void _spx_autocorr(
|
||||
const spx_word16_t * x, /* in: [0...n-1] samples x */
|
||||
spx_word16_t *ac, /* out: [0...lag-1] ac values */
|
||||
int lag, int n);
|
||||
|
||||
spx_word32_t /* returns minimum mean square error */
|
||||
_spx_lpc(
|
||||
spx_coef_t * lpc, /* [0...p-1] LPC coefficients */
|
||||
const spx_word16_t * ac, /* in: [0...p] autocorrelation values */
|
||||
int p
|
||||
);
|
||||
|
||||
|
||||
#endif
|
|
@ -1,131 +0,0 @@
|
|||
/* Copyright (C) 2005 Analog Devices */
|
||||
/**
|
||||
@file lpc_bfin.h
|
||||
@author Jean-Marc Valin
|
||||
@brief Functions for LPC (Linear Prediction Coefficients) analysis (Blackfin version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define OVERRIDE_SPEEX_AUTOCORR
|
||||
void _spx_autocorr(
|
||||
const spx_word16_t *x, /* in: [0...n-1] samples x */
|
||||
spx_word16_t *ac, /* out: [0...lag-1] ac values */
|
||||
int lag,
|
||||
int n
|
||||
)
|
||||
{
|
||||
spx_word32_t d;
|
||||
const spx_word16_t *xs;
|
||||
int i, j;
|
||||
spx_word32_t ac0=1;
|
||||
spx_word32_t ac32[11], *ac32top;
|
||||
int shift, ac_shift;
|
||||
ac32top = ac32+lag-1;
|
||||
int lag_1, N_lag;
|
||||
int nshift;
|
||||
lag_1 = lag-1;
|
||||
N_lag = n-lag_1;
|
||||
for (j=0;j<n;j++)
|
||||
ac0 = ADD32(ac0,SHR32(MULT16_16(x[j],x[j]),8));
|
||||
ac0 = ADD32(ac0,n);
|
||||
shift = 8;
|
||||
while (shift && ac0<0x40000000)
|
||||
{
|
||||
shift--;
|
||||
ac0 <<= 1;
|
||||
}
|
||||
ac_shift = 18;
|
||||
while (ac_shift && ac0<0x40000000)
|
||||
{
|
||||
ac_shift--;
|
||||
ac0 <<= 1;
|
||||
}
|
||||
|
||||
xs = x+lag-1;
|
||||
nshift = -shift;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"P2 = %0;\n\t"
|
||||
"I0 = P2;\n\t" /* x in I0 */
|
||||
"B0 = P2;\n\t" /* x in B0 */
|
||||
"R0 = %3;\n\t" /* len in R0 */
|
||||
"P3 = %3;\n\t" /* len in R0 */
|
||||
"P4 = %4;\n\t" /* nb_pitch in R0 */
|
||||
"R1 = R0 << 1;\n\t" /* number of bytes in x */
|
||||
"L0 = R1;\n\t"
|
||||
"P0 = %1;\n\t"
|
||||
"P1 = %2;\n\t"
|
||||
"B1 = P1;\n\t"
|
||||
"R4 = %5;\n\t"
|
||||
"L1 = 0;\n\t" /*Disable looping on I1*/
|
||||
|
||||
"r0 = [I0++];\n\t"
|
||||
"R2 = 0;R3=0;"
|
||||
"LOOP pitch%= LC0 = P4 >> 1;\n\t"
|
||||
"LOOP_BEGIN pitch%=;\n\t"
|
||||
"I1 = P0;\n\t"
|
||||
"A1 = A0 = 0;\n\t"
|
||||
"R1 = [I1++];\n\t"
|
||||
"LOOP inner_prod%= LC1 = P3 >> 1;\n\t"
|
||||
"LOOP_BEGIN inner_prod%=;\n\t"
|
||||
"A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\n\t"
|
||||
"A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R1.H = W[I1++] || R0 = [I0++];\n\t"
|
||||
"LOOP_END inner_prod%=;\n\t"
|
||||
"A0 = ASHIFT A0 by R4.L;\n\t"
|
||||
"A1 = ASHIFT A1 by R4.L;\n\t"
|
||||
|
||||
"R2 = A0, R3 = A1;\n\t"
|
||||
"[P1--] = R2;\n\t"
|
||||
"[P1--] = R3;\n\t"
|
||||
"P0 += 4;\n\t"
|
||||
"LOOP_END pitch%=;\n\t"
|
||||
: : "m" (xs), "m" (x), "m" (ac32top), "m" (N_lag), "m" (lag_1), "m" (nshift)
|
||||
: "A0", "A1", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "R3", "R4", "I0", "I1", "L0", "L1", "B0", "B1", "memory"
|
||||
);
|
||||
d=0;
|
||||
for (j=0;j<n;j++)
|
||||
{
|
||||
d = ADD32(d,SHR32(MULT16_16(x[j],x[j]), shift));
|
||||
}
|
||||
ac32[0] = d;
|
||||
|
||||
for (i=0;i<lag;i++)
|
||||
{
|
||||
d=0;
|
||||
for (j=i;j<lag_1;j++)
|
||||
{
|
||||
d = ADD32(d,SHR32(MULT16_16(x[j],x[j-i]), shift));
|
||||
}
|
||||
if (i)
|
||||
ac32[i] += d;
|
||||
ac[i] = SHR32(ac32[i], ac_shift);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,656 +0,0 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
Original copyright
|
||||
FILE........: lsp.c
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/2/93
|
||||
|
||||
Heavily modified by Jean-Marc Valin (c) 2002-2006 (fixed-point,
|
||||
optimizations, additional functions, ...)
|
||||
|
||||
This file contains functions for converting Linear Prediction
|
||||
Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the
|
||||
LSP coefficients are not in radians format but in the x domain of the
|
||||
unit circle.
|
||||
|
||||
Speex License:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
Introduction to Line Spectrum Pairs (LSPs)
|
||||
------------------------------------------
|
||||
|
||||
LSPs are used to encode the LPC filter coefficients {ak} for
|
||||
transmission over the channel. LSPs have several properties (like
|
||||
less sensitivity to quantisation noise) that make them superior to
|
||||
direct quantisation of {ak}.
|
||||
|
||||
A(z) is a polynomial of order lpcrdr with {ak} as the coefficients.
|
||||
|
||||
A(z) is transformed to P(z) and Q(z) (using a substitution and some
|
||||
algebra), to obtain something like:
|
||||
|
||||
A(z) = 0.5[P(z)(z+z^-1) + Q(z)(z-z^-1)] (1)
|
||||
|
||||
As you can imagine A(z) has complex zeros all over the z-plane. P(z)
|
||||
and Q(z) have the very neat property of only having zeros _on_ the
|
||||
unit circle. So to find them we take a test point z=exp(jw) and
|
||||
evaluate P (exp(jw)) and Q(exp(jw)) using a grid of points between 0
|
||||
and pi.
|
||||
|
||||
The zeros (roots) of P(z) also happen to alternate, which is why we
|
||||
swap coefficients as we find roots. So the process of finding the
|
||||
LSP frequencies is basically finding the roots of 5th order
|
||||
polynomials.
|
||||
|
||||
The root so P(z) and Q(z) occur in symmetrical pairs at +/-w, hence
|
||||
the name Line Spectrum Pairs (LSPs).
|
||||
|
||||
To convert back to ak we just evaluate (1), "clocking" an impulse
|
||||
thru it lpcrdr times gives us the impulse response of A(z) which is
|
||||
{ak}.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include "lsp.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "math_approx.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 /* pi */
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
#define FREQ_SCALE 16384
|
||||
|
||||
/*#define ANGLE2X(a) (32768*cos(((a)/8192.)))*/
|
||||
#define ANGLE2X(a) (SHL16(spx_cos(a),2))
|
||||
|
||||
/*#define X2ANGLE(x) (acos(.00006103515625*(x))*LSP_SCALING)*/
|
||||
#define X2ANGLE(x) (spx_acos(x))
|
||||
|
||||
#ifdef BFIN_ASM
|
||||
#include "lsp_bfin.h"
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/*#define C1 0.99940307
|
||||
#define C2 -0.49558072
|
||||
#define C3 0.03679168*/
|
||||
|
||||
#define FREQ_SCALE 1.
|
||||
#define ANGLE2X(a) (spx_cos(a))
|
||||
#define X2ANGLE(x) (acos(x))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FUNCTION....: cheb_poly_eva()
|
||||
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/2/93
|
||||
|
||||
This function evaluates a series of Chebyshev polynomials
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
#ifndef OVERRIDE_CHEB_POLY_EVA
|
||||
static inline spx_word32_t cheb_poly_eva(
|
||||
spx_word16_t *coef, /* P or Q coefs in Q13 format */
|
||||
spx_word16_t x, /* cos of freq (-1.0 to 1.0) in Q14 format */
|
||||
int m, /* LPC order/2 */
|
||||
char *stack
|
||||
)
|
||||
{
|
||||
int i;
|
||||
spx_word16_t b0, b1;
|
||||
spx_word32_t sum;
|
||||
|
||||
/*Prevents overflows*/
|
||||
if (x>16383)
|
||||
x = 16383;
|
||||
if (x<-16383)
|
||||
x = -16383;
|
||||
|
||||
/* Initialise values */
|
||||
b1=16384;
|
||||
b0=x;
|
||||
|
||||
/* Evaluate Chebyshev series formulation usin g iterative approach */
|
||||
sum = ADD32(EXTEND32(coef[m]), EXTEND32(MULT16_16_P14(coef[m-1],x)));
|
||||
for(i=2;i<=m;i++)
|
||||
{
|
||||
spx_word16_t tmp=b0;
|
||||
b0 = SUB16(MULT16_16_Q13(x,b0), b1);
|
||||
b1 = tmp;
|
||||
sum = ADD32(sum, EXTEND32(MULT16_16_P14(coef[m-i],b0)));
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
static float cheb_poly_eva(spx_word32_t *coef, spx_word16_t x, int m, char *stack)
|
||||
{
|
||||
int k;
|
||||
float b0, b1, tmp;
|
||||
|
||||
/* Initial conditions */
|
||||
b0=0; /* b_(m+1) */
|
||||
b1=0; /* b_(m+2) */
|
||||
|
||||
x*=2;
|
||||
|
||||
/* Calculate the b_(k) */
|
||||
for(k=m;k>0;k--)
|
||||
{
|
||||
tmp=b0; /* tmp holds the previous value of b0 */
|
||||
b0=x*b0-b1+coef[m-k]; /* b0 holds its new value based on b0 and b1 */
|
||||
b1=tmp; /* b1 holds the previous value of b0 */
|
||||
}
|
||||
|
||||
return(-b1+.5*x*b0+coef[m]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FUNCTION....: lpc_to_lsp()
|
||||
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/2/93
|
||||
|
||||
This function converts LPC coefficients to LSP
|
||||
coefficients.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#define SIGN_CHANGE(a,b) (((a)&0x70000000)^((b)&0x70000000)||(b==0))
|
||||
#else
|
||||
#define SIGN_CHANGE(a,b) (((a)*(b))<0.0)
|
||||
#endif
|
||||
|
||||
|
||||
int lpc_to_lsp (spx_coef_t *a,int lpcrdr,spx_lsp_t *freq,int nb,spx_word16_t delta, char *stack)
|
||||
/* float *a lpc coefficients */
|
||||
/* int lpcrdr order of LPC coefficients (10) */
|
||||
/* float *freq LSP frequencies in the x domain */
|
||||
/* int nb number of sub-intervals (4) */
|
||||
/* float delta grid spacing interval (0.02) */
|
||||
|
||||
|
||||
{
|
||||
spx_word16_t temp_xr,xl,xr,xm=0;
|
||||
spx_word32_t psuml,psumr,psumm,temp_psumr/*,temp_qsumr*/;
|
||||
int i,j,m,flag,k;
|
||||
VARDECL(spx_word32_t *Q); /* ptrs for memory allocation */
|
||||
VARDECL(spx_word32_t *P);
|
||||
VARDECL(spx_word16_t *Q16); /* ptrs for memory allocation */
|
||||
VARDECL(spx_word16_t *P16);
|
||||
spx_word32_t *px; /* ptrs of respective P'(z) & Q'(z) */
|
||||
spx_word32_t *qx;
|
||||
spx_word32_t *p;
|
||||
spx_word32_t *q;
|
||||
spx_word16_t *pt; /* ptr used for cheb_poly_eval()
|
||||
whether P' or Q' */
|
||||
int roots=0; /* DR 8/2/94: number of roots found */
|
||||
flag = 1; /* program is searching for a root when,
|
||||
1 else has found one */
|
||||
m = lpcrdr/2; /* order of P'(z) & Q'(z) polynomials */
|
||||
|
||||
/* Allocate memory space for polynomials */
|
||||
ALLOC(Q, (m+1), spx_word32_t);
|
||||
ALLOC(P, (m+1), spx_word32_t);
|
||||
|
||||
/* determine P'(z)'s and Q'(z)'s coefficients where
|
||||
P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */
|
||||
|
||||
px = P; /* initialise ptrs */
|
||||
qx = Q;
|
||||
p = px;
|
||||
q = qx;
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
*px++ = LPC_SCALING;
|
||||
*qx++ = LPC_SCALING;
|
||||
for(i=0;i<m;i++){
|
||||
*px++ = SUB32(ADD32(EXTEND32(a[i]),EXTEND32(a[lpcrdr-i-1])), *p++);
|
||||
*qx++ = ADD32(SUB32(EXTEND32(a[i]),EXTEND32(a[lpcrdr-i-1])), *q++);
|
||||
}
|
||||
px = P;
|
||||
qx = Q;
|
||||
for(i=0;i<m;i++)
|
||||
{
|
||||
/*if (fabs(*px)>=32768)
|
||||
speex_warning_int("px", *px);
|
||||
if (fabs(*qx)>=32768)
|
||||
speex_warning_int("qx", *qx);*/
|
||||
*px = PSHR32(*px,2);
|
||||
*qx = PSHR32(*qx,2);
|
||||
px++;
|
||||
qx++;
|
||||
}
|
||||
/* The reason for this lies in the way cheb_poly_eva() is implemented for fixed-point */
|
||||
P[m] = PSHR32(P[m],3);
|
||||
Q[m] = PSHR32(Q[m],3);
|
||||
#else
|
||||
*px++ = LPC_SCALING;
|
||||
*qx++ = LPC_SCALING;
|
||||
for(i=0;i<m;i++){
|
||||
*px++ = (a[i]+a[lpcrdr-1-i]) - *p++;
|
||||
*qx++ = (a[i]-a[lpcrdr-1-i]) + *q++;
|
||||
}
|
||||
px = P;
|
||||
qx = Q;
|
||||
for(i=0;i<m;i++){
|
||||
*px = 2**px;
|
||||
*qx = 2**qx;
|
||||
px++;
|
||||
qx++;
|
||||
}
|
||||
#endif
|
||||
|
||||
px = P; /* re-initialise ptrs */
|
||||
qx = Q;
|
||||
|
||||
/* now that we have computed P and Q convert to 16 bits to
|
||||
speed up cheb_poly_eval */
|
||||
|
||||
ALLOC(P16, m+1, spx_word16_t);
|
||||
ALLOC(Q16, m+1, spx_word16_t);
|
||||
|
||||
for (i=0;i<m+1;i++)
|
||||
{
|
||||
P16[i] = P[i];
|
||||
Q16[i] = Q[i];
|
||||
}
|
||||
|
||||
/* Search for a zero in P'(z) polynomial first and then alternate to Q'(z).
|
||||
Keep alternating between the two polynomials as each zero is found */
|
||||
|
||||
xr = 0; /* initialise xr to zero */
|
||||
xl = FREQ_SCALE; /* start at point xl = 1 */
|
||||
|
||||
for(j=0;j<lpcrdr;j++){
|
||||
if(j&1) /* determines whether P' or Q' is eval. */
|
||||
pt = Q16;
|
||||
else
|
||||
pt = P16;
|
||||
|
||||
psuml = cheb_poly_eva(pt,xl,m,stack); /* evals poly. at xl */
|
||||
flag = 1;
|
||||
while(flag && (xr >= -FREQ_SCALE)){
|
||||
spx_word16_t dd;
|
||||
/* Modified by JMV to provide smaller steps around x=+-1 */
|
||||
#ifdef FIXED_POINT
|
||||
dd = MULT16_16_Q15(delta,SUB16(FREQ_SCALE, MULT16_16_Q14(MULT16_16_Q14(xl,xl),14000)));
|
||||
if (psuml<512 && psuml>-512)
|
||||
dd = PSHR16(dd,1);
|
||||
#else
|
||||
dd=delta*(1-.9*xl*xl);
|
||||
if (fabs(psuml)<.2)
|
||||
dd *= .5;
|
||||
#endif
|
||||
xr = SUB16(xl, dd); /* interval spacing */
|
||||
psumr = cheb_poly_eva(pt,xr,m,stack);/* poly(xl-delta_x) */
|
||||
temp_psumr = psumr;
|
||||
temp_xr = xr;
|
||||
|
||||
/* if no sign change increment xr and re-evaluate poly(xr). Repeat til
|
||||
sign change.
|
||||
if a sign change has occurred the interval is bisected and then
|
||||
checked again for a sign change which determines in which
|
||||
interval the zero lies in.
|
||||
If there is no sign change between poly(xm) and poly(xl) set interval
|
||||
between xm and xr else set interval between xl and xr and repeat till
|
||||
root is located within the specified limits */
|
||||
|
||||
if(SIGN_CHANGE(psumr,psuml))
|
||||
{
|
||||
roots++;
|
||||
|
||||
psumm=psuml;
|
||||
for(k=0;k<=nb;k++){
|
||||
#ifdef FIXED_POINT
|
||||
xm = ADD16(PSHR16(xl,1),PSHR16(xr,1)); /* bisect the interval */
|
||||
#else
|
||||
xm = .5*(xl+xr); /* bisect the interval */
|
||||
#endif
|
||||
psumm=cheb_poly_eva(pt,xm,m,stack);
|
||||
/*if(psumm*psuml>0.)*/
|
||||
if(!SIGN_CHANGE(psumm,psuml))
|
||||
{
|
||||
psuml=psumm;
|
||||
xl=xm;
|
||||
} else {
|
||||
psumr=psumm;
|
||||
xr=xm;
|
||||
}
|
||||
}
|
||||
|
||||
/* once zero is found, reset initial interval to xr */
|
||||
freq[j] = X2ANGLE(xm);
|
||||
xl = xm;
|
||||
flag = 0; /* reset flag for next search */
|
||||
}
|
||||
else{
|
||||
psuml=temp_psumr;
|
||||
xl=temp_xr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(roots);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FUNCTION....: lsp_to_lpc()
|
||||
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/2/93
|
||||
|
||||
Converts LSP coefficients to LPC coefficients.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)
|
||||
/* float *freq array of LSP frequencies in the x domain */
|
||||
/* float *ak array of LPC coefficients */
|
||||
/* int lpcrdr order of LPC coefficients */
|
||||
{
|
||||
int i,j;
|
||||
spx_word32_t xout1,xout2,xin;
|
||||
spx_word32_t mult, a;
|
||||
VARDECL(spx_word16_t *freqn);
|
||||
VARDECL(spx_word32_t **xp);
|
||||
VARDECL(spx_word32_t *xpmem);
|
||||
VARDECL(spx_word32_t **xq);
|
||||
VARDECL(spx_word32_t *xqmem);
|
||||
int m = lpcrdr>>1;
|
||||
|
||||
/*
|
||||
|
||||
Reconstruct P(z) and Q(z) by cascading second order polynomials
|
||||
in form 1 - 2cos(w)z(-1) + z(-2), where w is the LSP frequency.
|
||||
In the time domain this is:
|
||||
|
||||
y(n) = x(n) - 2cos(w)x(n-1) + x(n-2)
|
||||
|
||||
This is what the ALLOCS below are trying to do:
|
||||
|
||||
int xp[m+1][lpcrdr+1+2]; // P matrix in QIMP
|
||||
int xq[m+1][lpcrdr+1+2]; // Q matrix in QIMP
|
||||
|
||||
These matrices store the output of each stage on each row. The
|
||||
final (m-th) row has the output of the final (m-th) cascaded
|
||||
2nd order filter. The first row is the impulse input to the
|
||||
system (not written as it is known).
|
||||
|
||||
The version below takes advantage of the fact that a lot of the
|
||||
outputs are zero or known, for example if we put an inpulse
|
||||
into the first section the "clock" it 10 times only the first 3
|
||||
outputs samples are non-zero (it's an FIR filter).
|
||||
*/
|
||||
|
||||
ALLOC(xp, (m+1), spx_word32_t*);
|
||||
ALLOC(xpmem, (m+1)*(lpcrdr+1+2), spx_word32_t);
|
||||
|
||||
ALLOC(xq, (m+1), spx_word32_t*);
|
||||
ALLOC(xqmem, (m+1)*(lpcrdr+1+2), spx_word32_t);
|
||||
|
||||
for(i=0; i<=m; i++) {
|
||||
xp[i] = xpmem + i*(lpcrdr+1+2);
|
||||
xq[i] = xqmem + i*(lpcrdr+1+2);
|
||||
}
|
||||
|
||||
/* work out 2cos terms in Q14 */
|
||||
|
||||
ALLOC(freqn, lpcrdr, spx_word16_t);
|
||||
for (i=0;i<lpcrdr;i++)
|
||||
freqn[i] = ANGLE2X(freq[i]);
|
||||
|
||||
#define QIMP 21 /* scaling for impulse */
|
||||
|
||||
xin = SHL32(EXTEND32(1), (QIMP-1)); /* 0.5 in QIMP format */
|
||||
|
||||
/* first col and last non-zero values of each row are trivial */
|
||||
|
||||
for(i=0;i<=m;i++) {
|
||||
xp[i][1] = 0;
|
||||
xp[i][2] = xin;
|
||||
xp[i][2+2*i] = xin;
|
||||
xq[i][1] = 0;
|
||||
xq[i][2] = xin;
|
||||
xq[i][2+2*i] = xin;
|
||||
}
|
||||
|
||||
/* 2nd row (first output row) is trivial */
|
||||
|
||||
xp[1][3] = -MULT16_32_Q14(freqn[0],xp[0][2]);
|
||||
xq[1][3] = -MULT16_32_Q14(freqn[1],xq[0][2]);
|
||||
|
||||
xout1 = xout2 = 0;
|
||||
|
||||
/* now generate remaining rows */
|
||||
|
||||
for(i=1;i<m;i++) {
|
||||
|
||||
for(j=1;j<2*(i+1)-1;j++) {
|
||||
mult = MULT16_32_Q14(freqn[2*i],xp[i][j+1]);
|
||||
xp[i+1][j+2] = ADD32(SUB32(xp[i][j+2], mult), xp[i][j]);
|
||||
mult = MULT16_32_Q14(freqn[2*i+1],xq[i][j+1]);
|
||||
xq[i+1][j+2] = ADD32(SUB32(xq[i][j+2], mult), xq[i][j]);
|
||||
}
|
||||
|
||||
/* for last col xp[i][j+2] = xq[i][j+2] = 0 */
|
||||
|
||||
mult = MULT16_32_Q14(freqn[2*i],xp[i][j+1]);
|
||||
xp[i+1][j+2] = SUB32(xp[i][j], mult);
|
||||
mult = MULT16_32_Q14(freqn[2*i+1],xq[i][j+1]);
|
||||
xq[i+1][j+2] = SUB32(xq[i][j], mult);
|
||||
}
|
||||
|
||||
/* process last row to extra a{k} */
|
||||
|
||||
for(j=1;j<=lpcrdr;j++) {
|
||||
int shift = QIMP-13;
|
||||
|
||||
/* final filter sections */
|
||||
a = PSHR32(xp[m][j+2] + xout1 + xq[m][j+2] - xout2, shift);
|
||||
xout1 = xp[m][j+2];
|
||||
xout2 = xq[m][j+2];
|
||||
|
||||
/* hard limit ak's to +/- 32767 */
|
||||
|
||||
if (a < -32767) a = -32767;
|
||||
if (a > 32767) a = 32767;
|
||||
ak[j-1] = (short)a;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)
|
||||
/* float *freq array of LSP frequencies in the x domain */
|
||||
/* float *ak array of LPC coefficients */
|
||||
/* int lpcrdr order of LPC coefficients */
|
||||
|
||||
|
||||
{
|
||||
int i,j;
|
||||
float xout1,xout2,xin1,xin2;
|
||||
VARDECL(float *Wp);
|
||||
float *pw,*n1,*n2,*n3,*n4=NULL;
|
||||
VARDECL(float *x_freq);
|
||||
int m = lpcrdr>>1;
|
||||
|
||||
ALLOC(Wp, 4*m+2, float);
|
||||
pw = Wp;
|
||||
|
||||
/* initialise contents of array */
|
||||
|
||||
for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */
|
||||
*pw++ = 0.0;
|
||||
}
|
||||
|
||||
/* Set pointers up */
|
||||
|
||||
pw = Wp;
|
||||
xin1 = 1.0;
|
||||
xin2 = 1.0;
|
||||
|
||||
ALLOC(x_freq, lpcrdr, float);
|
||||
for (i=0;i<lpcrdr;i++)
|
||||
x_freq[i] = ANGLE2X(freq[i]);
|
||||
|
||||
/* reconstruct P(z) and Q(z) by cascading second order
|
||||
polynomials in form 1 - 2xz(-1) +z(-2), where x is the
|
||||
LSP coefficient */
|
||||
|
||||
for(j=0;j<=lpcrdr;j++){
|
||||
int i2=0;
|
||||
for(i=0;i<m;i++,i2+=2){
|
||||
n1 = pw+(i*4);
|
||||
n2 = n1 + 1;
|
||||
n3 = n2 + 1;
|
||||
n4 = n3 + 1;
|
||||
xout1 = xin1 - 2.f*x_freq[i2] * *n1 + *n2;
|
||||
xout2 = xin2 - 2.f*x_freq[i2+1] * *n3 + *n4;
|
||||
*n2 = *n1;
|
||||
*n4 = *n3;
|
||||
*n1 = xin1;
|
||||
*n3 = xin2;
|
||||
xin1 = xout1;
|
||||
xin2 = xout2;
|
||||
}
|
||||
xout1 = xin1 + *(n4+1);
|
||||
xout2 = xin2 - *(n4+2);
|
||||
if (j>0)
|
||||
ak[j-1] = (xout1 + xout2)*0.5f;
|
||||
*(n4+1) = xin1;
|
||||
*(n4+2) = xin2;
|
||||
|
||||
xin1 = 0.0;
|
||||
xin2 = 0.0;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
/*Makes sure the LSPs are stable*/
|
||||
void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin)
|
||||
{
|
||||
int i;
|
||||
spx_word16_t m = margin;
|
||||
spx_word16_t m2 = 25736-margin;
|
||||
|
||||
if (lsp[0]<m)
|
||||
lsp[0]=m;
|
||||
if (lsp[len-1]>m2)
|
||||
lsp[len-1]=m2;
|
||||
for (i=1;i<len-1;i++)
|
||||
{
|
||||
if (lsp[i]<lsp[i-1]+m)
|
||||
lsp[i]=lsp[i-1]+m;
|
||||
|
||||
if (lsp[i]>lsp[i+1]-m)
|
||||
lsp[i]= SHR16(lsp[i],1) + SHR16(lsp[i+1]-m,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes)
|
||||
{
|
||||
int i;
|
||||
spx_word16_t tmp = DIV32_16(SHL32(EXTEND32(1 + subframe),14),nb_subframes);
|
||||
spx_word16_t tmp2 = 16384-tmp;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
interp_lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*Makes sure the LSPs are stable*/
|
||||
void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin)
|
||||
{
|
||||
int i;
|
||||
if (lsp[0]<LSP_SCALING*margin)
|
||||
lsp[0]=LSP_SCALING*margin;
|
||||
if (lsp[len-1]>LSP_SCALING*(M_PI-margin))
|
||||
lsp[len-1]=LSP_SCALING*(M_PI-margin);
|
||||
for (i=1;i<len-1;i++)
|
||||
{
|
||||
if (lsp[i]<lsp[i-1]+LSP_SCALING*margin)
|
||||
lsp[i]=lsp[i-1]+LSP_SCALING*margin;
|
||||
|
||||
if (lsp[i]>lsp[i+1]-LSP_SCALING*margin)
|
||||
lsp[i]= .5f* (lsp[i] + lsp[i+1]-LSP_SCALING*margin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes)
|
||||
{
|
||||
int i;
|
||||
float tmp = (1.0f + subframe)/nb_subframes;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
interp_lsp[i] = (1-tmp)*old_lsp[i] + tmp*new_lsp[i];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,64 +0,0 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
Original Copyright
|
||||
FILE........: AK2LSPD.H
|
||||
TYPE........: Turbo C header file
|
||||
COMPANY.....: Voicetronix
|
||||
AUTHOR......: James Whitehall
|
||||
DATE CREATED: 21/11/95
|
||||
|
||||
Modified by Jean-Marc Valin
|
||||
|
||||
This file contains functions for converting Linear Prediction
|
||||
Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the
|
||||
LSP coefficients are not in radians format but in the x domain of the
|
||||
unit circle.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file lsp.h
|
||||
@brief Line Spectral Pair (LSP) functions.
|
||||
*/
|
||||
/* Speex License:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __AK2LSPD__
|
||||
#define __AK2LSPD__
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack);
|
||||
void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack);
|
||||
|
||||
/*Added by JMV*/
|
||||
void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin);
|
||||
|
||||
void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes);
|
||||
|
||||
#endif /* __AK2LSPD__ */
|
|
@ -1,89 +0,0 @@
|
|||
/* Copyright (C) 2006 David Rowe */
|
||||
/**
|
||||
@file lsp_bfin.h
|
||||
@author David Rowe
|
||||
@brief LSP routines optimised for the Blackfin
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define OVERRIDE_CHEB_POLY_EVA
|
||||
#ifdef OVERRIDE_CHEB_POLY_EVA
|
||||
static inline spx_word32_t cheb_poly_eva(
|
||||
spx_word16_t *coef, /* P or Q coefs in Q13 format */
|
||||
spx_word16_t x, /* cos of freq (-1.0 to 1.0) in Q14 format */
|
||||
int m, /* LPC order/2 */
|
||||
char *stack
|
||||
)
|
||||
{
|
||||
spx_word32_t sum;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"P0 = %2;\n\t" /* P0: coef[m], coef[m-1],..., coef[0] */
|
||||
"R4 = 8192;\n\t" /* R4: rounding constant */
|
||||
"R2 = %1;\n\t" /* R2: x */
|
||||
|
||||
"R5 = -16383;\n\t"
|
||||
"R2 = MAX(R2,R5);\n\t"
|
||||
"R5 = 16383;\n\t"
|
||||
"R2 = MIN(R2,R5);\n\t"
|
||||
|
||||
"R3 = W[P0--] (X);\n\t" /* R3: sum */
|
||||
"R5 = W[P0--] (X);\n\t"
|
||||
"R5 = R5.L * R2.L (IS);\n\t"
|
||||
"R5 = R5 + R4;\n\t"
|
||||
"R5 >>>= 14;\n\t"
|
||||
"R3 = R3 + R5;\n\t"
|
||||
|
||||
"R0 = R2;\n\t" /* R0: b0 */
|
||||
"R1 = 16384;\n\t" /* R1: b1 */
|
||||
"LOOP cpe%= LC0 = %3;\n\t"
|
||||
"LOOP_BEGIN cpe%=;\n\t"
|
||||
"P1 = R0;\n\t"
|
||||
"R0 = R2.L * R0.L (IS) || R5 = W[P0--] (X);\n\t"
|
||||
"R0 >>>= 13;\n\t"
|
||||
"R0 = R0 - R1;\n\t"
|
||||
"R1 = P1;\n\t"
|
||||
"R5 = R5.L * R0.L (IS);\n\t"
|
||||
"R5 = R5 + R4;\n\t"
|
||||
"R5 >>>= 14;\n\t"
|
||||
"R3 = R3 + R5;\n\t"
|
||||
"LOOP_END cpe%=;\n\t"
|
||||
"%0 = R3;\n\t"
|
||||
: "=&d" (sum)
|
||||
: "a" (x), "a" (&coef[m]), "a" (m-1)
|
||||
: "R0", "R1", "R3", "R2", "R4", "R5", "P0", "P1"
|
||||
);
|
||||
return sum;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -1,360 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: lsp_tables_nb.c
|
||||
Codebooks for LSPs in narrowband CELP mode
|
||||
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
const signed char cdbk_nb[640]={
|
||||
30,19,38,34,40,32,46,43,58,43,
|
||||
5,-18,-25,-40,-33,-55,-52,20,34,28,
|
||||
-20,-63,-97,-92,61,53,47,49,53,75,
|
||||
-14,-53,-77,-79,0,-3,-5,19,22,26,
|
||||
-9,-53,-55,66,90,72,85,68,74,52,
|
||||
-4,-41,-58,-31,-18,-31,27,32,30,18,
|
||||
24,3,8,5,-12,-3,26,28,74,63,
|
||||
-2,-39,-67,-77,-106,-74,59,59,73,65,
|
||||
44,40,71,72,82,83,98,88,89,60,
|
||||
-6,-31,-47,-48,-13,-39,-9,7,2,79,
|
||||
-1,-39,-60,-17,87,81,65,50,45,19,
|
||||
-21,-67,-91,-87,-41,-50,7,18,39,74,
|
||||
10,-31,-28,39,24,13,23,5,56,45,
|
||||
29,10,-5,-13,-11,-35,-18,-8,-10,-8,
|
||||
-25,-71,-77,-21,2,16,50,63,87,87,
|
||||
5,-32,-40,-51,-68,0,12,6,54,34,
|
||||
5,-12,32,52,68,64,69,59,65,45,
|
||||
14,-16,-31,-40,-65,-67,41,49,47,37,
|
||||
-11,-52,-75,-84,-4,57,48,42,42,33,
|
||||
-11,-51,-68,-6,13,0,8,-8,26,32,
|
||||
-23,-53,0,36,56,76,97,105,111,97,
|
||||
-1,-28,-39,-40,-43,-54,-44,-40,-18,35,
|
||||
16,-20,-19,-28,-42,29,47,38,74,45,
|
||||
3,-29,-48,-62,-80,-104,-33,56,59,59,
|
||||
10,17,46,72,84,101,117,123,123,106,
|
||||
-7,-33,-49,-51,-70,-67,-27,-31,70,67,
|
||||
-16,-62,-85,-20,82,71,86,80,85,74,
|
||||
-19,-58,-75,-45,-29,-33,-18,-25,45,57,
|
||||
-12,-42,-5,12,28,36,52,64,81,82,
|
||||
13,-9,-27,-28,22,3,2,22,26,6,
|
||||
-6,-44,-51,2,15,10,48,43,49,34,
|
||||
-19,-62,-84,-89,-102,-24,8,17,61,68,
|
||||
39,24,23,19,16,-5,12,15,27,15,
|
||||
-8,-44,-49,-60,-18,-32,-28,52,54,62,
|
||||
-8,-48,-77,-70,66,101,83,63,61,37,
|
||||
-12,-50,-75,-64,33,17,13,25,15,77,
|
||||
1,-42,-29,72,64,46,49,31,61,44,
|
||||
-8,-47,-54,-46,-30,19,20,-1,-16,0,
|
||||
16,-12,-18,-9,-26,-27,-10,-22,53,45,
|
||||
-10,-47,-75,-82,-105,-109,8,25,49,77,
|
||||
50,65,114,117,124,118,115,96,90,61,
|
||||
-9,-45,-63,-60,-75,-57,8,11,20,29,
|
||||
0,-35,-49,-43,40,47,35,40,55,38,
|
||||
-24,-76,-103,-112,-27,3,23,34,52,75,
|
||||
8,-29,-43,12,63,38,35,29,24,8,
|
||||
25,11,1,-15,-18,-43,-7,37,40,21,
|
||||
-20,-56,-19,-19,-4,-2,11,29,51,63,
|
||||
-2,-44,-62,-75,-89,30,57,51,74,51,
|
||||
50,46,68,64,65,52,63,55,65,43,
|
||||
18,-9,-26,-35,-55,-69,3,6,8,17,
|
||||
-15,-61,-86,-97,1,86,93,74,78,67,
|
||||
-1,-38,-66,-48,48,39,29,25,17,-1,
|
||||
13,13,29,39,50,51,69,82,97,98,
|
||||
-2,-36,-46,-27,-16,-30,-13,-4,-7,-4,
|
||||
25,-5,-11,-6,-25,-21,33,12,31,29,
|
||||
-8,-38,-52,-63,-68,-89,-33,-1,10,74,
|
||||
-2,-15,59,91,105,105,101,87,84,62,
|
||||
-7,-33,-50,-35,-54,-47,25,17,82,81,
|
||||
-13,-56,-83,21,58,31,42,25,72,65,
|
||||
-24,-66,-91,-56,9,-2,21,10,69,75,
|
||||
2,-24,11,22,25,28,38,34,48,33,
|
||||
7,-29,-26,17,15,-1,14,0,-2,0,
|
||||
-6,-41,-67,6,-2,-9,19,2,85,74,
|
||||
-22,-67,-84,-71,-50,3,11,-9,2,62};
|
||||
|
||||
const signed char cdbk_nb_low1[320]={
|
||||
-34,-52,-15,45,2,
|
||||
23,21,52,24,-33,
|
||||
-9,-1,9,-44,-41,
|
||||
-13,-17,44,22,-17,
|
||||
-6,-4,-1,22,38,
|
||||
26,16,2,50,27,
|
||||
-35,-34,-9,-41,6,
|
||||
0,-16,-34,51,8,
|
||||
-14,-31,-49,15,-33,
|
||||
45,49,33,-11,-37,
|
||||
-62,-54,45,11,-5,
|
||||
-72,11,-1,-12,-11,
|
||||
24,27,-11,-43,46,
|
||||
43,33,-12,-9,-1,
|
||||
1,-4,-23,-57,-71,
|
||||
11,8,16,17,-8,
|
||||
-20,-31,-41,53,48,
|
||||
-16,3,65,-24,-8,
|
||||
-23,-32,-37,-32,-49,
|
||||
-10,-17,6,38,5,
|
||||
-9,-17,-46,8,52,
|
||||
3,6,45,40,39,
|
||||
-7,-6,-34,-74,31,
|
||||
8,1,-16,43,68,
|
||||
-11,-19,-31,4,6,
|
||||
0,-6,-17,-16,-38,
|
||||
-16,-30,2,9,-39,
|
||||
-16,-1,43,-10,48,
|
||||
3,3,-16,-31,-3,
|
||||
62,68,43,13,3,
|
||||
-10,8,20,-56,12,
|
||||
12,-2,-18,22,-15,
|
||||
-40,-36,1,7,41,
|
||||
0,1,46,-6,-62,
|
||||
-4,-12,-2,-11,-83,
|
||||
-13,-2,91,33,-10,
|
||||
0,4,-11,-16,79,
|
||||
32,37,14,9,51,
|
||||
-21,-28,-56,-34,0,
|
||||
21,9,-26,11,28,
|
||||
-42,-54,-23,-2,-15,
|
||||
31,30,8,-39,-66,
|
||||
-39,-36,31,-28,-40,
|
||||
-46,35,40,22,24,
|
||||
33,48,23,-34,14,
|
||||
40,32,17,27,-3,
|
||||
25,26,-13,-61,-17,
|
||||
11,4,31,60,-6,
|
||||
-26,-41,-64,13,16,
|
||||
-26,54,31,-11,-23,
|
||||
-9,-11,-34,-71,-21,
|
||||
-34,-35,55,50,29,
|
||||
-22,-27,-50,-38,57,
|
||||
33,42,57,48,26,
|
||||
11,0,-49,-31,26,
|
||||
-4,-14,5,78,37,
|
||||
17,0,-49,-12,-23,
|
||||
26,14,2,2,-43,
|
||||
-17,-12,10,-8,-4,
|
||||
8,18,12,-6,20,
|
||||
-12,-6,-13,-25,34,
|
||||
15,40,49,7,8,
|
||||
13,20,20,-19,-22,
|
||||
-2,-8,2,51,-51};
|
||||
|
||||
const signed char cdbk_nb_low2[320]={
|
||||
-6,53,-21,-24,4,
|
||||
26,17,-4,-37,25,
|
||||
17,-36,-13,31,3,
|
||||
-6,27,15,-10,31,
|
||||
28,26,-10,-10,-40,
|
||||
16,-7,15,13,41,
|
||||
-9,0,-4,50,-6,
|
||||
-7,14,38,22,0,
|
||||
-48,2,1,-13,-19,
|
||||
32,-3,-60,11,-17,
|
||||
-1,-24,-34,-1,35,
|
||||
-5,-27,28,44,13,
|
||||
25,15,42,-11,15,
|
||||
51,35,-36,20,8,
|
||||
-4,-12,-29,19,-47,
|
||||
49,-15,-4,16,-29,
|
||||
-39,14,-30,4,25,
|
||||
-9,-5,-51,-14,-3,
|
||||
-40,-32,38,5,-9,
|
||||
-8,-4,-1,-22,71,
|
||||
-3,14,26,-18,-22,
|
||||
24,-41,-25,-24,6,
|
||||
23,19,-10,39,-26,
|
||||
-27,65,45,2,-7,
|
||||
-26,-8,22,-12,16,
|
||||
15,16,-35,-5,33,
|
||||
-21,-8,0,23,33,
|
||||
34,6,21,36,6,
|
||||
-7,-22,8,-37,-14,
|
||||
31,38,11,-4,-3,
|
||||
-39,-32,-8,32,-23,
|
||||
-6,-12,16,20,-28,
|
||||
-4,23,13,-52,-1,
|
||||
22,6,-33,-40,-6,
|
||||
4,-62,13,5,-26,
|
||||
35,39,11,2,57,
|
||||
-11,9,-20,-28,-33,
|
||||
52,-5,-6,-2,22,
|
||||
-14,-16,-48,35,1,
|
||||
-58,20,13,33,-1,
|
||||
-74,56,-18,-22,-31,
|
||||
12,6,-14,4,-2,
|
||||
-9,-47,10,-3,29,
|
||||
-17,-5,61,14,47,
|
||||
-12,2,72,-39,-17,
|
||||
92,64,-53,-51,-15,
|
||||
-30,-38,-41,-29,-28,
|
||||
27,9,36,9,-35,
|
||||
-42,81,-21,20,25,
|
||||
-16,-5,-17,-35,21,
|
||||
15,-28,48,2,-2,
|
||||
9,-19,29,-40,30,
|
||||
-18,-18,18,-16,-57,
|
||||
15,-20,-12,-15,-37,
|
||||
-15,33,-39,21,-22,
|
||||
-13,35,11,13,-38,
|
||||
-63,29,23,-27,32,
|
||||
18,3,-26,42,33,
|
||||
-64,-66,-17,16,56,
|
||||
2,36,3,31,21,
|
||||
-41,-39,8,-57,14,
|
||||
37,-2,19,-36,-19,
|
||||
-23,-29,-16,1,-3,
|
||||
-8,-10,31,64,-65};
|
||||
|
||||
const signed char cdbk_nb_high1[320]={
|
||||
-26,-8,29,21,4,
|
||||
19,-39,33,-7,-36,
|
||||
56,54,48,40,29,
|
||||
-4,-24,-42,-66,-43,
|
||||
-60,19,-2,37,41,
|
||||
-10,-37,-60,-64,18,
|
||||
-22,77,73,40,25,
|
||||
4,19,-19,-66,-2,
|
||||
11,5,21,14,26,
|
||||
-25,-86,-4,18,1,
|
||||
26,-37,10,37,-1,
|
||||
24,-12,-59,-11,20,
|
||||
-6,34,-16,-16,42,
|
||||
19,-28,-51,53,32,
|
||||
4,10,62,21,-12,
|
||||
-34,27,4,-48,-48,
|
||||
-50,-49,31,-7,-21,
|
||||
-42,-25,-4,-43,-22,
|
||||
59,2,27,12,-9,
|
||||
-6,-16,-8,-32,-58,
|
||||
-16,-29,-5,41,23,
|
||||
-30,-33,-46,-13,-10,
|
||||
-38,52,52,1,-17,
|
||||
-9,10,26,-25,-6,
|
||||
33,-20,53,55,25,
|
||||
-32,-5,-42,23,21,
|
||||
66,5,-28,20,9,
|
||||
75,29,-7,-42,-39,
|
||||
15,3,-23,21,6,
|
||||
11,1,-29,14,63,
|
||||
10,54,26,-24,-51,
|
||||
-49,7,-23,-51,15,
|
||||
-66,1,60,25,10,
|
||||
0,-30,-4,-15,17,
|
||||
19,59,40,4,-5,
|
||||
33,6,-22,-58,-70,
|
||||
-5,23,-6,60,44,
|
||||
-29,-16,-47,-29,52,
|
||||
-19,50,28,16,35,
|
||||
31,36,0,-21,6,
|
||||
21,27,22,42,7,
|
||||
-66,-40,-8,7,19,
|
||||
46,0,-4,60,36,
|
||||
45,-7,-29,-6,-32,
|
||||
-39,2,6,-9,33,
|
||||
20,-51,-34,18,-6,
|
||||
19,6,11,5,-19,
|
||||
-29,-2,42,-11,-45,
|
||||
-21,-55,57,37,2,
|
||||
-14,-67,-16,-27,-38,
|
||||
69,48,19,2,-17,
|
||||
20,-20,-16,-34,-17,
|
||||
-25,-61,10,73,45,
|
||||
16,-40,-64,-17,-29,
|
||||
-22,56,17,-39,8,
|
||||
-11,8,-25,-18,-13,
|
||||
-19,8,54,57,36,
|
||||
-17,-26,-4,6,-21,
|
||||
40,42,-4,20,31,
|
||||
53,10,-34,-53,31,
|
||||
-17,35,0,15,-6,
|
||||
-20,-63,-73,22,25,
|
||||
29,17,8,-29,-39,
|
||||
-69,18,15,-15,-5};
|
||||
|
||||
const signed char cdbk_nb_high2[320]={
|
||||
11,47,16,-9,-46,
|
||||
-32,26,-64,34,-5,
|
||||
38,-7,47,20,2,
|
||||
-73,-99,-3,-45,20,
|
||||
70,-52,15,-6,-7,
|
||||
-82,31,21,47,51,
|
||||
39,-3,9,0,-41,
|
||||
-7,-15,-54,2,0,
|
||||
27,-31,9,-45,-22,
|
||||
-38,-24,-24,8,-33,
|
||||
23,5,50,-36,-17,
|
||||
-18,-51,-2,13,19,
|
||||
43,12,-15,-12,61,
|
||||
38,38,7,13,0,
|
||||
6,-1,3,62,9,
|
||||
27,22,-33,38,-35,
|
||||
-9,30,-43,-9,-32,
|
||||
-1,4,-4,1,-5,
|
||||
-11,-8,38,31,11,
|
||||
-10,-42,-21,-37,1,
|
||||
43,15,-13,-35,-19,
|
||||
-18,15,23,-26,59,
|
||||
1,-21,53,8,-41,
|
||||
-50,-14,-28,4,21,
|
||||
25,-28,-40,5,-40,
|
||||
-41,4,51,-33,-8,
|
||||
-8,1,17,-60,12,
|
||||
25,-41,17,34,43,
|
||||
19,45,7,-37,24,
|
||||
-15,56,-2,35,-10,
|
||||
48,4,-47,-2,5,
|
||||
-5,-54,5,-3,-33,
|
||||
-10,30,-2,-44,-24,
|
||||
-38,9,-9,42,4,
|
||||
6,-56,44,-16,9,
|
||||
-40,-26,18,-20,10,
|
||||
28,-41,-21,-4,13,
|
||||
-18,32,-30,-3,37,
|
||||
15,22,28,50,-40,
|
||||
3,-29,-64,7,51,
|
||||
-19,-11,17,-27,-40,
|
||||
-64,24,-12,-7,-27,
|
||||
3,37,48,-1,2,
|
||||
-9,-38,-34,46,1,
|
||||
27,-6,19,-13,26,
|
||||
10,34,20,25,40,
|
||||
50,-6,-7,30,9,
|
||||
-24,0,-23,71,-61,
|
||||
22,58,-34,-4,2,
|
||||
-49,-33,25,30,-8,
|
||||
-6,-16,77,2,38,
|
||||
-8,-35,-6,-30,56,
|
||||
78,31,33,-20,13,
|
||||
-39,20,22,4,21,
|
||||
-8,4,-6,10,-83,
|
||||
-41,9,-25,-43,15,
|
||||
-7,-12,-34,-39,-37,
|
||||
-33,19,30,16,-33,
|
||||
42,-25,25,-68,44,
|
||||
-15,-11,-4,23,50,
|
||||
14,4,-39,-43,20,
|
||||
-30,60,9,-20,7,
|
||||
16,19,-33,37,29,
|
||||
16,-35,7,38,-27};
|
|
@ -1,839 +0,0 @@
|
|||
/* Copyright (C) 2002-2006 Jean-Marc Valin
|
||||
File: ltp.c
|
||||
Long-Term Prediction 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.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include "ltp.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "filters.h"
|
||||
#include <speex/speex_bits.h>
|
||||
#include "math_approx.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#include "ltp_sse.h"
|
||||
#elif defined (ARM4_ASM) || defined(ARM5E_ASM)
|
||||
#include "ltp_arm4.h"
|
||||
#elif defined (BFIN_ASM)
|
||||
#include "ltp_bfin.h"
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_INNER_PROD
|
||||
spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
|
||||
{
|
||||
spx_word32_t sum=0;
|
||||
len >>= 2;
|
||||
while(len--)
|
||||
{
|
||||
spx_word32_t part=0;
|
||||
part = MAC16_16(part,*x++,*y++);
|
||||
part = MAC16_16(part,*x++,*y++);
|
||||
part = MAC16_16(part,*x++,*y++);
|
||||
part = MAC16_16(part,*x++,*y++);
|
||||
/* HINT: If you had a 40-bit accumulator, you could shift only at the end */
|
||||
sum = ADD32(sum,SHR32(part,6));
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_PITCH_XCORR
|
||||
#if 0 /* HINT: Enable this for machines with enough registers (i.e. not x86) */
|
||||
void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
|
||||
{
|
||||
int i,j;
|
||||
for (i=0;i<nb_pitch;i+=4)
|
||||
{
|
||||
/* Compute correlation*/
|
||||
/*corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);*/
|
||||
spx_word32_t sum1=0;
|
||||
spx_word32_t sum2=0;
|
||||
spx_word32_t sum3=0;
|
||||
spx_word32_t sum4=0;
|
||||
const spx_word16_t *y = _y+i;
|
||||
const spx_word16_t *x = _x;
|
||||
spx_word16_t y0, y1, y2, y3;
|
||||
/*y0=y[0];y1=y[1];y2=y[2];y3=y[3];*/
|
||||
y0=*y++;
|
||||
y1=*y++;
|
||||
y2=*y++;
|
||||
y3=*y++;
|
||||
for (j=0;j<len;j+=4)
|
||||
{
|
||||
spx_word32_t part1;
|
||||
spx_word32_t part2;
|
||||
spx_word32_t part3;
|
||||
spx_word32_t part4;
|
||||
part1 = MULT16_16(*x,y0);
|
||||
part2 = MULT16_16(*x,y1);
|
||||
part3 = MULT16_16(*x,y2);
|
||||
part4 = MULT16_16(*x,y3);
|
||||
x++;
|
||||
y0=*y++;
|
||||
part1 = MAC16_16(part1,*x,y1);
|
||||
part2 = MAC16_16(part2,*x,y2);
|
||||
part3 = MAC16_16(part3,*x,y3);
|
||||
part4 = MAC16_16(part4,*x,y0);
|
||||
x++;
|
||||
y1=*y++;
|
||||
part1 = MAC16_16(part1,*x,y2);
|
||||
part2 = MAC16_16(part2,*x,y3);
|
||||
part3 = MAC16_16(part3,*x,y0);
|
||||
part4 = MAC16_16(part4,*x,y1);
|
||||
x++;
|
||||
y2=*y++;
|
||||
part1 = MAC16_16(part1,*x,y3);
|
||||
part2 = MAC16_16(part2,*x,y0);
|
||||
part3 = MAC16_16(part3,*x,y1);
|
||||
part4 = MAC16_16(part4,*x,y2);
|
||||
x++;
|
||||
y3=*y++;
|
||||
|
||||
sum1 = ADD32(sum1,SHR32(part1,6));
|
||||
sum2 = ADD32(sum2,SHR32(part2,6));
|
||||
sum3 = ADD32(sum3,SHR32(part3,6));
|
||||
sum4 = ADD32(sum4,SHR32(part4,6));
|
||||
}
|
||||
corr[nb_pitch-1-i]=sum1;
|
||||
corr[nb_pitch-2-i]=sum2;
|
||||
corr[nb_pitch-3-i]=sum3;
|
||||
corr[nb_pitch-4-i]=sum4;
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<nb_pitch;i++)
|
||||
{
|
||||
/* Compute correlation*/
|
||||
corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_COMPUTE_PITCH_ERROR
|
||||
static SPEEX_INLINE spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control)
|
||||
{
|
||||
spx_word32_t sum = 0;
|
||||
sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0]));
|
||||
sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1]));
|
||||
sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2]));
|
||||
sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3]));
|
||||
sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4]));
|
||||
sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5]));
|
||||
sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6]));
|
||||
sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7]));
|
||||
sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8]));
|
||||
return sum;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_OPEN_LOOP_NBEST_PITCH
|
||||
void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)
|
||||
{
|
||||
int i,j,k;
|
||||
VARDECL(spx_word32_t *best_score);
|
||||
VARDECL(spx_word32_t *best_ener);
|
||||
spx_word32_t e0;
|
||||
VARDECL(spx_word32_t *corr);
|
||||
#ifdef FIXED_POINT
|
||||
/* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16)
|
||||
arrays for (normalized) 16-bit values */
|
||||
VARDECL(spx_word16_t *corr16);
|
||||
VARDECL(spx_word16_t *ener16);
|
||||
spx_word32_t *energy;
|
||||
int cshift=0, eshift=0;
|
||||
int scaledown = 0;
|
||||
ALLOC(corr16, end-start+1, spx_word16_t);
|
||||
ALLOC(ener16, end-start+1, spx_word16_t);
|
||||
ALLOC(corr, end-start+1, spx_word32_t);
|
||||
energy = corr;
|
||||
#else
|
||||
/* In floating-point, we need to float arrays and no normalized copies */
|
||||
VARDECL(spx_word32_t *energy);
|
||||
spx_word16_t *corr16;
|
||||
spx_word16_t *ener16;
|
||||
ALLOC(energy, end-start+2, spx_word32_t);
|
||||
ALLOC(corr, end-start+1, spx_word32_t);
|
||||
corr16 = corr;
|
||||
ener16 = energy;
|
||||
#endif
|
||||
|
||||
ALLOC(best_score, N, spx_word32_t);
|
||||
ALLOC(best_ener, N, spx_word32_t);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
best_score[i]=-1;
|
||||
best_ener[i]=0;
|
||||
pitch[i]=start;
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
for (i=-end;i<len;i++)
|
||||
{
|
||||
if (ABS16(sw[i])>16383)
|
||||
{
|
||||
scaledown=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If the weighted input is close to saturation, then we scale it down */
|
||||
if (scaledown)
|
||||
{
|
||||
for (i=-end;i<len;i++)
|
||||
{
|
||||
sw[i]=SHR16(sw[i],1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
energy[0]=inner_prod(sw-start, sw-start, len);
|
||||
e0=inner_prod(sw, sw, len);
|
||||
for (i=start;i<end;i++)
|
||||
{
|
||||
/* Update energy for next pitch*/
|
||||
energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(sw[-i-1],sw[-i-1]),6)), SHR32(MULT16_16(sw[-i+len-1],sw[-i+len-1]),6));
|
||||
if (energy[i-start+1] < 0)
|
||||
energy[i-start+1] = 0;
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
eshift = normalize16(energy, ener16, 32766, end-start+1);
|
||||
#endif
|
||||
|
||||
/* In fixed-point, this actually overrites the energy array (aliased to corr) */
|
||||
pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
/* Normalize to 180 so we can square it and it still fits in 16 bits */
|
||||
cshift = normalize16(corr, corr16, 180, end-start+1);
|
||||
/* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */
|
||||
if (scaledown)
|
||||
{
|
||||
for (i=-end;i<len;i++)
|
||||
{
|
||||
sw[i]=SHL16(sw[i],1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Search for the best pitch prediction gain */
|
||||
for (i=start;i<=end;i++)
|
||||
{
|
||||
spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);
|
||||
/* Instead of dividing the tmp by the energy, we multiply on the other side */
|
||||
if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
|
||||
{
|
||||
/* We can safely put it last and then check */
|
||||
best_score[N-1]=tmp;
|
||||
best_ener[N-1]=ener16[i-start]+1;
|
||||
pitch[N-1]=i;
|
||||
/* Check if it comes in front of others */
|
||||
for (j=0;j<N-1;j++)
|
||||
{
|
||||
if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
|
||||
{
|
||||
for (k=N-1;k>j;k--)
|
||||
{
|
||||
best_score[k]=best_score[k-1];
|
||||
best_ener[k]=best_ener[k-1];
|
||||
pitch[k]=pitch[k-1];
|
||||
}
|
||||
best_score[j]=tmp;
|
||||
best_ener[j]=ener16[i-start]+1;
|
||||
pitch[j]=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute open-loop gain if necessary */
|
||||
if (gain)
|
||||
{
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
spx_word16_t g;
|
||||
i=pitch[j];
|
||||
g = DIV32(SHL32(EXTEND32(corr16[i-start]),cshift), 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(SHL32(EXTEND32(ener16[i-start]),eshift))),6));
|
||||
/* FIXME: g = max(g,corr/energy) */
|
||||
if (g<0)
|
||||
g = 0;
|
||||
gain[j]=g;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ
|
||||
static int pitch_gain_search_3tap_vq(
|
||||
const signed char *gain_cdbk,
|
||||
int gain_cdbk_size,
|
||||
spx_word16_t *C16,
|
||||
spx_word16_t max_gain
|
||||
)
|
||||
{
|
||||
const signed char *ptr=gain_cdbk;
|
||||
int best_cdbk=0;
|
||||
spx_word32_t best_sum=-VERY_LARGE32;
|
||||
spx_word32_t sum=0;
|
||||
spx_word16_t g[3];
|
||||
spx_word16_t pitch_control=64;
|
||||
spx_word16_t gain_sum;
|
||||
int i;
|
||||
|
||||
for (i=0;i<gain_cdbk_size;i++) {
|
||||
|
||||
ptr = gain_cdbk+4*i;
|
||||
g[0]=ADD16((spx_word16_t)ptr[0],32);
|
||||
g[1]=ADD16((spx_word16_t)ptr[1],32);
|
||||
g[2]=ADD16((spx_word16_t)ptr[2],32);
|
||||
gain_sum = (spx_word16_t)ptr[3];
|
||||
|
||||
sum = compute_pitch_error(C16, g, pitch_control);
|
||||
|
||||
if (sum>best_sum && gain_sum<=max_gain) {
|
||||
best_sum=sum;
|
||||
best_cdbk=i;
|
||||
}
|
||||
}
|
||||
|
||||
return best_cdbk;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
|
||||
static spx_word32_t pitch_gain_search_3tap(
|
||||
const spx_word16_t target[], /* Target vector */
|
||||
const spx_coef_t ak[], /* LPCs for this subframe */
|
||||
const spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
const spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
spx_sig_t exc[], /* Excitation */
|
||||
const signed char *gain_cdbk,
|
||||
int gain_cdbk_size,
|
||||
int pitch, /* Pitch value */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
const spx_word16_t *exc2,
|
||||
const spx_word16_t *r,
|
||||
spx_word16_t *new_target,
|
||||
int *cdbk_index,
|
||||
int plc_tuning,
|
||||
spx_word32_t cumul_gain,
|
||||
int scaledown
|
||||
)
|
||||
{
|
||||
int i,j;
|
||||
VARDECL(spx_word16_t *tmp1);
|
||||
VARDECL(spx_word16_t *e);
|
||||
spx_word16_t *x[3];
|
||||
spx_word32_t corr[3];
|
||||
spx_word32_t A[3][3];
|
||||
spx_word16_t gain[3];
|
||||
spx_word32_t err;
|
||||
spx_word16_t max_gain=128;
|
||||
int best_cdbk=0;
|
||||
|
||||
ALLOC(tmp1, 3*nsf, spx_word16_t);
|
||||
ALLOC(e, nsf, spx_word16_t);
|
||||
|
||||
if (cumul_gain > 262144)
|
||||
max_gain = 31;
|
||||
|
||||
x[0]=tmp1;
|
||||
x[1]=tmp1+nsf;
|
||||
x[2]=tmp1+2*nsf;
|
||||
|
||||
for (j=0;j<nsf;j++)
|
||||
new_target[j] = target[j];
|
||||
|
||||
{
|
||||
VARDECL(spx_mem_t *mm);
|
||||
int pp=pitch-1;
|
||||
ALLOC(mm, p, spx_mem_t);
|
||||
for (j=0;j<nsf;j++)
|
||||
{
|
||||
if (j-pp<0)
|
||||
e[j]=exc2[j-pp];
|
||||
else if (j-pp-pitch<0)
|
||||
e[j]=exc2[j-pp-pitch];
|
||||
else
|
||||
e[j]=0;
|
||||
}
|
||||
#ifdef FIXED_POINT
|
||||
/* Scale target and excitation down if needed (avoiding overflow) */
|
||||
if (scaledown)
|
||||
{
|
||||
for (j=0;j<nsf;j++)
|
||||
e[j] = SHR16(e[j],1);
|
||||
for (j=0;j<nsf;j++)
|
||||
new_target[j] = SHR16(new_target[j],1);
|
||||
}
|
||||
#endif
|
||||
for (j=0;j<p;j++)
|
||||
mm[j] = 0;
|
||||
iir_mem16(e, ak, e, nsf, p, mm, stack);
|
||||
for (j=0;j<p;j++)
|
||||
mm[j] = 0;
|
||||
filter_mem16(e, awk1, awk2, e, nsf, p, mm, stack);
|
||||
for (j=0;j<nsf;j++)
|
||||
x[2][j] = e[j];
|
||||
}
|
||||
for (i=1;i>=0;i--)
|
||||
{
|
||||
spx_word16_t e0=exc2[-pitch-1+i];
|
||||
#ifdef FIXED_POINT
|
||||
/* Scale excitation down if needed (avoiding overflow) */
|
||||
if (scaledown)
|
||||
e0 = SHR16(e0,1);
|
||||
#endif
|
||||
x[i][0]=MULT16_16_Q14(r[0], e0);
|
||||
for (j=0;j<nsf-1;j++)
|
||||
x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));
|
||||
}
|
||||
|
||||
for (i=0;i<3;i++)
|
||||
corr[i]=inner_prod(x[i],new_target,nsf);
|
||||
for (i=0;i<3;i++)
|
||||
for (j=0;j<=i;j++)
|
||||
A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
|
||||
|
||||
{
|
||||
spx_word32_t C[9];
|
||||
#ifdef FIXED_POINT
|
||||
spx_word16_t C16[9];
|
||||
#else
|
||||
spx_word16_t *C16=C;
|
||||
#endif
|
||||
C[0]=corr[2];
|
||||
C[1]=corr[1];
|
||||
C[2]=corr[0];
|
||||
C[3]=A[1][2];
|
||||
C[4]=A[0][1];
|
||||
C[5]=A[0][2];
|
||||
C[6]=A[2][2];
|
||||
C[7]=A[1][1];
|
||||
C[8]=A[0][0];
|
||||
|
||||
/*plc_tuning *= 2;*/
|
||||
if (plc_tuning<2)
|
||||
plc_tuning=2;
|
||||
if (plc_tuning>30)
|
||||
plc_tuning=30;
|
||||
#ifdef FIXED_POINT
|
||||
C[0] = SHL32(C[0],1);
|
||||
C[1] = SHL32(C[1],1);
|
||||
C[2] = SHL32(C[2],1);
|
||||
C[3] = SHL32(C[3],1);
|
||||
C[4] = SHL32(C[4],1);
|
||||
C[5] = SHL32(C[5],1);
|
||||
C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]);
|
||||
C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]);
|
||||
C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]);
|
||||
normalize16(C, C16, 32767, 9);
|
||||
#else
|
||||
C[6]*=.5*(1+.02*plc_tuning);
|
||||
C[7]*=.5*(1+.02*plc_tuning);
|
||||
C[8]*=.5*(1+.02*plc_tuning);
|
||||
#endif
|
||||
|
||||
best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]);
|
||||
gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]);
|
||||
gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+2]);
|
||||
/*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/
|
||||
#else
|
||||
gain[0] = 0.015625*gain_cdbk[best_cdbk*4] + .5;
|
||||
gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5;
|
||||
gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5;
|
||||
#endif
|
||||
*cdbk_index=best_cdbk;
|
||||
}
|
||||
|
||||
SPEEX_MEMSET(exc, 0, nsf);
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
int j;
|
||||
int tmp1, tmp3;
|
||||
int pp=pitch+1-i;
|
||||
tmp1=nsf;
|
||||
if (tmp1>pp)
|
||||
tmp1=pp;
|
||||
for (j=0;j<tmp1;j++)
|
||||
exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]);
|
||||
tmp3=nsf;
|
||||
if (tmp3>pp+pitch)
|
||||
tmp3=pp+pitch;
|
||||
for (j=tmp1;j<tmp3;j++)
|
||||
exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]);
|
||||
}
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])),
|
||||
MULT16_16(gain[2],x[0][i]));
|
||||
new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6)));
|
||||
}
|
||||
err = inner_prod(new_target, new_target, nsf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
|
||||
int pitch_search_3tap(
|
||||
spx_word16_t target[], /* Target vector */
|
||||
spx_word16_t *sw,
|
||||
spx_coef_t ak[], /* LPCs for this subframe */
|
||||
spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
spx_sig_t exc[], /* Excitation */
|
||||
const void *par,
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
spx_word16_t *exc2,
|
||||
spx_word16_t *r,
|
||||
int complexity,
|
||||
int cdbk_offset,
|
||||
int plc_tuning,
|
||||
spx_word32_t *cumul_gain
|
||||
)
|
||||
{
|
||||
int i;
|
||||
int cdbk_index, pitch=0, best_gain_index=0;
|
||||
VARDECL(spx_sig_t *best_exc);
|
||||
VARDECL(spx_word16_t *new_target);
|
||||
VARDECL(spx_word16_t *best_target);
|
||||
int best_pitch=0;
|
||||
spx_word32_t err, best_err=-1;
|
||||
int N;
|
||||
const ltp_params *params;
|
||||
const signed char *gain_cdbk;
|
||||
int gain_cdbk_size;
|
||||
int scaledown=0;
|
||||
|
||||
VARDECL(int *nbest);
|
||||
|
||||
params = (const ltp_params*) par;
|
||||
gain_cdbk_size = 1<<params->gain_bits;
|
||||
gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
|
||||
|
||||
N=complexity;
|
||||
if (N>10)
|
||||
N=10;
|
||||
if (N<1)
|
||||
N=1;
|
||||
|
||||
ALLOC(nbest, N, int);
|
||||
params = (const ltp_params*) par;
|
||||
|
||||
if (end<start)
|
||||
{
|
||||
speex_bits_pack(bits, 0, params->pitch_bits);
|
||||
speex_bits_pack(bits, 0, params->gain_bits);
|
||||
SPEEX_MEMSET(exc, 0, nsf);
|
||||
return start;
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
/* Check if we need to scale everything down in the pitch search to avoid overflows */
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
if (ABS16(target[i])>16383)
|
||||
{
|
||||
scaledown=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i=-end;i<nsf;i++)
|
||||
{
|
||||
if (ABS16(exc2[i])>16383)
|
||||
{
|
||||
scaledown=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (N>end-start+1)
|
||||
N=end-start+1;
|
||||
if (end != start)
|
||||
open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack);
|
||||
else
|
||||
nbest[0] = start;
|
||||
|
||||
ALLOC(best_exc, nsf, spx_sig_t);
|
||||
ALLOC(new_target, nsf, spx_word16_t);
|
||||
ALLOC(best_target, nsf, spx_word16_t);
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
pitch=nbest[i];
|
||||
SPEEX_MEMSET(exc, 0, nsf);
|
||||
err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf,
|
||||
bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown);
|
||||
if (err<best_err || best_err<0)
|
||||
{
|
||||
SPEEX_COPY(best_exc, exc, nsf);
|
||||
SPEEX_COPY(best_target, new_target, nsf);
|
||||
best_err=err;
|
||||
best_pitch=pitch;
|
||||
best_gain_index=cdbk_index;
|
||||
}
|
||||
}
|
||||
/*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
|
||||
speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
|
||||
speex_bits_pack(bits, best_gain_index, params->gain_bits);
|
||||
#ifdef FIXED_POINT
|
||||
*cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain));
|
||||
#else
|
||||
*cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3];
|
||||
#endif
|
||||
/*printf ("%f\n", cumul_gain);*/
|
||||
/*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
|
||||
SPEEX_COPY(exc, best_exc, nsf);
|
||||
SPEEX_COPY(target, best_target, nsf);
|
||||
#ifdef FIXED_POINT
|
||||
/* Scale target back up if needed */
|
||||
if (scaledown)
|
||||
{
|
||||
for (i=0;i<nsf;i++)
|
||||
target[i]=SHL16(target[i],1);
|
||||
}
|
||||
#endif
|
||||
return pitch;
|
||||
}
|
||||
|
||||
void pitch_unquant_3tap(
|
||||
spx_word16_t exc[], /* Input excitation */
|
||||
spx_word32_t exc_out[], /* Output excitation */
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
|
||||
const void *par,
|
||||
int nsf, /* Number of samples in subframe */
|
||||
int *pitch_val,
|
||||
spx_word16_t *gain_val,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int count_lost,
|
||||
int subframe_offset,
|
||||
spx_word16_t last_pitch_gain,
|
||||
int cdbk_offset
|
||||
)
|
||||
{
|
||||
int i;
|
||||
int pitch;
|
||||
int gain_index;
|
||||
spx_word16_t gain[3];
|
||||
const signed char *gain_cdbk;
|
||||
int gain_cdbk_size;
|
||||
const ltp_params *params;
|
||||
|
||||
params = (const ltp_params*) par;
|
||||
gain_cdbk_size = 1<<params->gain_bits;
|
||||
gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
|
||||
|
||||
pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
|
||||
pitch += start;
|
||||
gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
|
||||
/*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
|
||||
#ifdef FIXED_POINT
|
||||
gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]);
|
||||
gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]);
|
||||
gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]);
|
||||
#else
|
||||
gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5;
|
||||
gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5;
|
||||
gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5;
|
||||
#endif
|
||||
|
||||
if (count_lost && pitch > subframe_offset)
|
||||
{
|
||||
spx_word16_t gain_sum;
|
||||
if (1) {
|
||||
#ifdef FIXED_POINT
|
||||
spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1);
|
||||
if (tmp>62)
|
||||
tmp=62;
|
||||
#else
|
||||
spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain;
|
||||
if (tmp>.95)
|
||||
tmp=.95;
|
||||
#endif
|
||||
gain_sum = gain_3tap_to_1tap(gain);
|
||||
|
||||
if (gain_sum > tmp)
|
||||
{
|
||||
spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum);
|
||||
for (i=0;i<3;i++)
|
||||
gain[i]=MULT16_16_Q14(fact,gain[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*pitch_val = pitch;
|
||||
gain_val[0]=gain[0];
|
||||
gain_val[1]=gain[1];
|
||||
gain_val[2]=gain[2];
|
||||
gain[0] = SHL16(gain[0],7);
|
||||
gain[1] = SHL16(gain[1],7);
|
||||
gain[2] = SHL16(gain[2],7);
|
||||
SPEEX_MEMSET(exc_out, 0, nsf);
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
int j;
|
||||
int tmp1, tmp3;
|
||||
int pp=pitch+1-i;
|
||||
tmp1=nsf;
|
||||
if (tmp1>pp)
|
||||
tmp1=pp;
|
||||
for (j=0;j<tmp1;j++)
|
||||
exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]);
|
||||
tmp3=nsf;
|
||||
if (tmp3>pp+pitch)
|
||||
tmp3=pp+pitch;
|
||||
for (j=tmp1;j<tmp3;j++)
|
||||
exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]);
|
||||
}
|
||||
/*for (i=0;i<nsf;i++)
|
||||
exc[i]=PSHR32(exc32[i],13);*/
|
||||
}
|
||||
|
||||
|
||||
/** Forced pitch delay and gain */
|
||||
int forced_pitch_quant(
|
||||
spx_word16_t target[], /* Target vector */
|
||||
spx_word16_t *sw,
|
||||
spx_coef_t ak[], /* LPCs for this subframe */
|
||||
spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
spx_sig_t exc[], /* Excitation */
|
||||
const void *par,
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
spx_word16_t *exc2,
|
||||
spx_word16_t *r,
|
||||
int complexity,
|
||||
int cdbk_offset,
|
||||
int plc_tuning,
|
||||
spx_word32_t *cumul_gain
|
||||
)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_word16_t *res);
|
||||
ALLOC(res, nsf, spx_word16_t);
|
||||
#ifdef FIXED_POINT
|
||||
if (pitch_coef>63)
|
||||
pitch_coef=63;
|
||||
#else
|
||||
if (pitch_coef>.99)
|
||||
pitch_coef=.99;
|
||||
#endif
|
||||
for (i=0;i<nsf&&i<start;i++)
|
||||
{
|
||||
exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]);
|
||||
}
|
||||
for (;i<nsf;i++)
|
||||
{
|
||||
exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]);
|
||||
}
|
||||
for (i=0;i<nsf;i++)
|
||||
res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1));
|
||||
syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack);
|
||||
for (i=0;i<nsf;i++)
|
||||
target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700));
|
||||
return start;
|
||||
}
|
||||
|
||||
/** Unquantize forced pitch delay and gain */
|
||||
void forced_pitch_unquant(
|
||||
spx_word16_t exc[], /* Input excitation */
|
||||
spx_word32_t exc_out[], /* Output excitation */
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
|
||||
const void *par,
|
||||
int nsf, /* Number of samples in subframe */
|
||||
int *pitch_val,
|
||||
spx_word16_t *gain_val,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int count_lost,
|
||||
int subframe_offset,
|
||||
spx_word16_t last_pitch_gain,
|
||||
int cdbk_offset
|
||||
)
|
||||
{
|
||||
int i;
|
||||
#ifdef FIXED_POINT
|
||||
if (pitch_coef>63)
|
||||
pitch_coef=63;
|
||||
#else
|
||||
if (pitch_coef>.99)
|
||||
pitch_coef=.99;
|
||||
#endif
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));
|
||||
exc[i] = EXTRACT16(PSHR32(exc_out[i],13));
|
||||
}
|
||||
*pitch_val = start;
|
||||
gain_val[0]=gain_val[2]=0;
|
||||
gain_val[1] = pitch_coef;
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file ltp.h
|
||||
@brief Long-Term Prediction 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.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "arch.h"
|
||||
|
||||
/** LTP parameters. */
|
||||
typedef struct {
|
||||
const signed char *gain_cdbk;
|
||||
int gain_bits;
|
||||
int pitch_bits;
|
||||
} ltp_params;
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -SHR16(g[0],1)) + (g[2]>0 ? g[2] : -SHR16(g[2],1)))
|
||||
#else
|
||||
#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -.5*g[0]) + (g[2]>0 ? g[2] : -.5*g[2]))
|
||||
#endif
|
||||
|
||||
spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len);
|
||||
void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack);
|
||||
|
||||
void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack);
|
||||
|
||||
|
||||
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
|
||||
int pitch_search_3tap(
|
||||
spx_word16_t target[], /* Target vector */
|
||||
spx_word16_t *sw,
|
||||
spx_coef_t ak[], /* LPCs for this subframe */
|
||||
spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
spx_sig_t exc[], /* Overlapping codebook */
|
||||
const void *par,
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
spx_word16_t *exc2,
|
||||
spx_word16_t *r,
|
||||
int complexity,
|
||||
int cdbk_offset,
|
||||
int plc_tuning,
|
||||
spx_word32_t *cumul_gain
|
||||
);
|
||||
|
||||
/*Unquantize adaptive codebook and update pitch contribution*/
|
||||
void pitch_unquant_3tap(
|
||||
spx_word16_t exc[], /* Input excitation */
|
||||
spx_word32_t exc_out[], /* Output excitation */
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
|
||||
const void *par,
|
||||
int nsf, /* Number of samples in subframe */
|
||||
int *pitch_val,
|
||||
spx_word16_t *gain_val,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int lost,
|
||||
int subframe_offset,
|
||||
spx_word16_t last_pitch_gain,
|
||||
int cdbk_offset
|
||||
);
|
||||
|
||||
/** Forced pitch delay and gain */
|
||||
int forced_pitch_quant(
|
||||
spx_word16_t target[], /* Target vector */
|
||||
spx_word16_t *sw,
|
||||
spx_coef_t ak[], /* LPCs for this subframe */
|
||||
spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
spx_sig_t exc[], /* Excitation */
|
||||
const void *par,
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
spx_word16_t *exc2,
|
||||
spx_word16_t *r,
|
||||
int complexity,
|
||||
int cdbk_offset,
|
||||
int plc_tuning,
|
||||
spx_word32_t *cumul_gain
|
||||
);
|
||||
|
||||
/** Unquantize forced pitch delay and gain */
|
||||
void forced_pitch_unquant(
|
||||
spx_word16_t exc[], /* Input excitation */
|
||||
spx_word32_t exc_out[], /* Output excitation */
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
|
||||
const void *par,
|
||||
int nsf, /* Number of samples in subframe */
|
||||
int *pitch_val,
|
||||
spx_word16_t *gain_val,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int lost,
|
||||
int subframe_offset,
|
||||
spx_word16_t last_pitch_gain,
|
||||
int cdbk_offset
|
||||
);
|
|
@ -1,187 +0,0 @@
|
|||
/* Copyright (C) 2004 Jean-Marc Valin */
|
||||
/**
|
||||
@file ltp_arm4.h
|
||||
@brief Long-Term Prediction functions (ARM4 version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define OVERRIDE_INNER_PROD
|
||||
spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
|
||||
{
|
||||
spx_word32_t sum1=0,sum2=0;
|
||||
spx_word16_t *deadx, *deady;
|
||||
int deadlen, dead1, dead2, dead3, dead4, dead5, dead6;
|
||||
__asm__ __volatile__ (
|
||||
"\tldrsh %5, [%0], #2 \n"
|
||||
"\tldrsh %6, [%1], #2 \n"
|
||||
".inner_prod_loop%=:\n"
|
||||
"\tsub %7, %7, %7\n"
|
||||
"\tsub %10, %10, %10\n"
|
||||
|
||||
"\tldrsh %8, [%0], #2 \n"
|
||||
"\tldrsh %9, [%1], #2 \n"
|
||||
"\tmla %7, %5, %6, %7\n"
|
||||
"\tldrsh %5, [%0], #2 \n"
|
||||
"\tldrsh %6, [%1], #2 \n"
|
||||
"\tmla %10, %8, %9, %10\n"
|
||||
"\tldrsh %8, [%0], #2 \n"
|
||||
"\tldrsh %9, [%1], #2 \n"
|
||||
"\tmla %7, %5, %6, %7\n"
|
||||
"\tldrsh %5, [%0], #2 \n"
|
||||
"\tldrsh %6, [%1], #2 \n"
|
||||
"\tmla %10, %8, %9, %10\n"
|
||||
|
||||
"\tldrsh %8, [%0], #2 \n"
|
||||
"\tldrsh %9, [%1], #2 \n"
|
||||
"\tmla %7, %5, %6, %7\n"
|
||||
"\tldrsh %5, [%0], #2 \n"
|
||||
"\tldrsh %6, [%1], #2 \n"
|
||||
"\tmla %10, %8, %9, %10\n"
|
||||
"\tldrsh %8, [%0], #2 \n"
|
||||
"\tldrsh %9, [%1], #2 \n"
|
||||
"\tmla %7, %5, %6, %7\n"
|
||||
"\tldrsh %5, [%0], #2 \n"
|
||||
"\tldrsh %6, [%1], #2 \n"
|
||||
"\tmla %10, %8, %9, %10\n"
|
||||
|
||||
"\tsubs %4, %4, #1\n"
|
||||
"\tadd %2, %2, %7, asr #5\n"
|
||||
"\tadd %3, %3, %10, asr #5\n"
|
||||
"\tbne .inner_prod_loop%=\n"
|
||||
: "=r" (deadx), "=r" (deady), "+r" (sum1), "+r" (sum2),
|
||||
"=r" (deadlen), "=r" (dead1), "=r" (dead2), "=r" (dead3),
|
||||
"=r" (dead4), "=r" (dead5), "=r" (dead6)
|
||||
: "0" (x), "1" (y), "4" (len>>3)
|
||||
: "cc"
|
||||
);
|
||||
return (sum1+sum2)>>1;
|
||||
}
|
||||
|
||||
#define OVERRIDE_PITCH_XCORR
|
||||
void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
|
||||
{
|
||||
int i,j;
|
||||
for (i=0;i<nb_pitch;i+=4)
|
||||
{
|
||||
/* Compute correlation*/
|
||||
//corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);
|
||||
spx_word32_t sum1=0;
|
||||
spx_word32_t sum2=0;
|
||||
spx_word32_t sum3=0;
|
||||
spx_word32_t sum4=0;
|
||||
const spx_word16_t *y = _y+i;
|
||||
const spx_word16_t *x = _x;
|
||||
spx_word32_t y0, y1, y2, y3;
|
||||
y0=*y++;
|
||||
y1=*y++;
|
||||
y2=*y++;
|
||||
y3=*y++;
|
||||
for (j=0;j<len;j+=4)
|
||||
{
|
||||
spx_word32_t part1, part2, part3, part4, x0;
|
||||
spx_word32_t dead1;
|
||||
__asm__ __volatile__ (
|
||||
#ifdef SHORTCUTS
|
||||
"\tldrsh %10, [%8], #4 \n"
|
||||
"\tmul %4, %10, %0 \n"
|
||||
"\tldrsh %15, [%8], #4 \n"
|
||||
"\tmul %5, %10, %1 \n"
|
||||
"\tldrsh %0, [%9], #2 \n"
|
||||
"\tmul %6, %10, %2 \n"
|
||||
"\tldrsh %1, [%9], #2 \n"
|
||||
"\tmul %7, %10, %3 \n"
|
||||
|
||||
|
||||
"\tmla %4, %15, %2, %4 \n"
|
||||
"\tldrsh %2, [%9], #2 \n"
|
||||
"\tmla %5, %15, %3, %5 \n"
|
||||
"\tldrsh %3, [%9], #2 \n"
|
||||
"\tmla %6, %15, %0, %6 \n"
|
||||
"\tmla %7, %15, %1, %7 \n"
|
||||
|
||||
#else
|
||||
"\tldrsh %10, [%8], #2 \n"
|
||||
"\tmul %4, %10, %0 \n"
|
||||
"\tmul %5, %10, %1 \n"
|
||||
"\tmul %6, %10, %2 \n"
|
||||
"\tmul %7, %10, %3 \n"
|
||||
|
||||
"\tldrsh %10, [%8], #2 \n"
|
||||
"\tldrsh %0, [%9], #2 \n"
|
||||
"\tmla %4, %10, %1, %4 \n"
|
||||
"\tmla %5, %10, %2, %5 \n"
|
||||
"\tmla %6, %10, %3, %6 \n"
|
||||
"\tmla %7, %10, %0, %7 \n"
|
||||
|
||||
"\tldrsh %10, [%8], #2 \n"
|
||||
"\tldrsh %1, [%9], #2 \n"
|
||||
"\tmla %4, %10, %2, %4 \n"
|
||||
"\tmla %5, %10, %3, %5 \n"
|
||||
"\tmla %6, %10, %0, %6 \n"
|
||||
"\tmla %7, %10, %1, %7 \n"
|
||||
|
||||
"\tldrsh %10, [%8], #2 \n"
|
||||
"\tldrsh %2, [%9], #2 \n"
|
||||
"\tmla %4, %10, %3, %4 \n"
|
||||
"\tmla %5, %10, %0, %5 \n"
|
||||
"\tmla %6, %10, %1, %6 \n"
|
||||
"\tmla %7, %10, %2, %7 \n"
|
||||
|
||||
"\tldrsh %3, [%9], #2 \n"
|
||||
#endif
|
||||
|
||||
"\tldr %10, %11 \n"
|
||||
"\tldr %15, %12 \n"
|
||||
"\tadd %4, %10, %4, asr #6 \n"
|
||||
"\tstr %4, %11 \n"
|
||||
"\tldr %10, %13 \n"
|
||||
"\tadd %5, %15, %5, asr #6 \n"
|
||||
"\tstr %5, %12 \n"
|
||||
"\tldr %15, %14 \n"
|
||||
"\tadd %6, %10, %6, asr #6 \n"
|
||||
"\tadd %7, %15, %7, asr #6 \n"
|
||||
"\tstr %6, %13 \n"
|
||||
"\tstr %7, %14 \n"
|
||||
|
||||
: "+r" (y0), "+r" (y1), "+r" (y2), "+r" (y3),
|
||||
"=r" (part1), "=r" (part2), "=r" (part3), "=r" (part4),
|
||||
"+r" (x), "+r" (y), "=r" (x0), "+m" (sum1),
|
||||
"+m" (sum2), "+m" (sum3), "+m" (sum4), "=r" (dead1)
|
||||
:
|
||||
: "cc", "memory"
|
||||
);
|
||||
}
|
||||
corr[nb_pitch-1-i]=sum1;
|
||||
corr[nb_pitch-2-i]=sum2;
|
||||
corr[nb_pitch-3-i]=sum3;
|
||||
corr[nb_pitch-4-i]=sum4;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,419 +0,0 @@
|
|||
/* Copyright (C) 2005 Analog Devices */
|
||||
/**
|
||||
@file ltp_bfin.h
|
||||
@author Jean-Marc Valin
|
||||
@brief Long-Term Prediction functions (Blackfin version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define OVERRIDE_INNER_PROD
|
||||
spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
|
||||
{
|
||||
spx_word32_t sum=0;
|
||||
__asm__ __volatile__ (
|
||||
"P0 = %3;\n\t"
|
||||
"P1 = %1;\n\t"
|
||||
"P2 = %2;\n\t"
|
||||
"I0 = P1;\n\t"
|
||||
"I1 = P2;\n\t"
|
||||
"L0 = 0;\n\t"
|
||||
"L1 = 0;\n\t"
|
||||
"A0 = 0;\n\t"
|
||||
"R0.L = W[I0++] || R1.L = W[I1++];\n\t"
|
||||
"LOOP inner%= LC0 = P0;\n\t"
|
||||
"LOOP_BEGIN inner%=;\n\t"
|
||||
"A0 += R0.L*R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\n\t"
|
||||
"LOOP_END inner%=;\n\t"
|
||||
"A0 += R0.L*R1.L (IS);\n\t"
|
||||
"A0 = A0 >>> 6;\n\t"
|
||||
"R0 = A0;\n\t"
|
||||
"%0 = R0;\n\t"
|
||||
: "=m" (sum)
|
||||
: "m" (x), "m" (y), "d" (len-1)
|
||||
: "P0", "P1", "P2", "R0", "R1", "A0", "I0", "I1", "L0", "L1", "R3"
|
||||
);
|
||||
return sum;
|
||||
}
|
||||
|
||||
#define OVERRIDE_PITCH_XCORR
|
||||
void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
|
||||
{
|
||||
corr += nb_pitch - 1;
|
||||
__asm__ __volatile__ (
|
||||
"P2 = %0;\n\t"
|
||||
"I0 = P2;\n\t" /* x in I0 */
|
||||
"B0 = P2;\n\t" /* x in B0 */
|
||||
"R0 = %3;\n\t" /* len in R0 */
|
||||
"P3 = %3;\n\t"
|
||||
"P3 += -2;\n\t" /* len in R0 */
|
||||
"P4 = %4;\n\t" /* nb_pitch in R0 */
|
||||
"R1 = R0 << 1;\n\t" /* number of bytes in x */
|
||||
"L0 = R1;\n\t"
|
||||
"P0 = %1;\n\t"
|
||||
|
||||
"P1 = %2;\n\t"
|
||||
"B1 = P1;\n\t"
|
||||
"L1 = 0;\n\t" /*Disable looping on I1*/
|
||||
|
||||
"r0 = [I0++];\n\t"
|
||||
"LOOP pitch%= LC0 = P4 >> 1;\n\t"
|
||||
"LOOP_BEGIN pitch%=;\n\t"
|
||||
"I1 = P0;\n\t"
|
||||
"A1 = A0 = 0;\n\t"
|
||||
"R1 = [I1++];\n\t"
|
||||
"LOOP inner_prod%= LC1 = P3 >> 1;\n\t"
|
||||
"LOOP_BEGIN inner_prod%=;\n\t"
|
||||
"A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\n\t"
|
||||
"A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R1.H = W[I1++] || R0 = [I0++];\n\t"
|
||||
"LOOP_END inner_prod%=;\n\t"
|
||||
"A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\n\t"
|
||||
"A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R0 = [I0++];\n\t"
|
||||
"A0 = A0 >>> 6;\n\t"
|
||||
"A1 = A1 >>> 6;\n\t"
|
||||
"R2 = A0, R3 = A1;\n\t"
|
||||
"[P1--] = r2;\n\t"
|
||||
"[P1--] = r3;\n\t"
|
||||
"P0 += 4;\n\t"
|
||||
"LOOP_END pitch%=;\n\t"
|
||||
"L0 = 0;\n\t"
|
||||
: : "m" (_x), "m" (_y), "m" (corr), "m" (len), "m" (nb_pitch)
|
||||
: "A0", "A1", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "R3", "I0", "I1", "L0", "L1", "B0", "B1", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#define OVERRIDE_COMPUTE_PITCH_ERROR
|
||||
static inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control)
|
||||
{
|
||||
spx_word32_t sum;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"A0 = 0;\n\t"
|
||||
|
||||
"R0 = W[%1++];\n\t"
|
||||
"R1.L = %2.L*%5.L (IS);\n\t"
|
||||
"A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
|
||||
|
||||
"R1.L = %3.L*%5.L (IS);\n\t"
|
||||
"A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
|
||||
|
||||
"R1.L = %4.L*%5.L (IS);\n\t"
|
||||
"A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
|
||||
|
||||
"R1.L = %2.L*%3.L (IS);\n\t"
|
||||
"A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
|
||||
|
||||
"R1.L = %4.L*%3.L (IS);\n\t"
|
||||
"A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
|
||||
|
||||
"R1.L = %4.L*%2.L (IS);\n\t"
|
||||
"A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
|
||||
|
||||
"R1.L = %2.L*%2.L (IS);\n\t"
|
||||
"A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
|
||||
|
||||
"R1.L = %3.L*%3.L (IS);\n\t"
|
||||
"A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t"
|
||||
|
||||
"R1.L = %4.L*%4.L (IS);\n\t"
|
||||
"A0 -= R1.L*R0.L (IS);\n\t"
|
||||
|
||||
"%0 = A0;\n\t"
|
||||
: "=&D" (sum), "=a" (C)
|
||||
: "d" (g[0]), "d" (g[1]), "d" (g[2]), "d" (pitch_control), "1" (C)
|
||||
: "R0", "R1", "R2", "A0"
|
||||
);
|
||||
return sum;
|
||||
}
|
||||
|
||||
#define OVERRIDE_OPEN_LOOP_NBEST_PITCH
|
||||
#ifdef OVERRIDE_OPEN_LOOP_NBEST_PITCH
|
||||
void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)
|
||||
{
|
||||
int i,j,k;
|
||||
VARDECL(spx_word32_t *best_score);
|
||||
VARDECL(spx_word32_t *best_ener);
|
||||
spx_word32_t e0;
|
||||
VARDECL(spx_word32_t *corr);
|
||||
VARDECL(spx_word32_t *energy);
|
||||
|
||||
ALLOC(best_score, N, spx_word32_t);
|
||||
ALLOC(best_ener, N, spx_word32_t);
|
||||
ALLOC(corr, end-start+1, spx_word32_t);
|
||||
ALLOC(energy, end-start+2, spx_word32_t);
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
best_score[i]=-1;
|
||||
best_ener[i]=0;
|
||||
pitch[i]=start;
|
||||
}
|
||||
|
||||
energy[0]=inner_prod(sw-start, sw-start, len);
|
||||
e0=inner_prod(sw, sw, len);
|
||||
|
||||
/* energy update -------------------------------------*/
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
" P0 = %0;\n\t"
|
||||
" I1 = %1;\n\t"
|
||||
" L1 = 0;\n\t"
|
||||
" I2 = %2;\n\t"
|
||||
" L2 = 0;\n\t"
|
||||
" R2 = [P0++];\n\t"
|
||||
" R3 = 0;\n\t"
|
||||
" LSETUP (eu1, eu2) LC1 = %3;\n\t"
|
||||
"eu1: R1.L = W [I1--] || R0.L = W [I2--] ;\n\t"
|
||||
" R1 = R1.L * R1.L (IS);\n\t"
|
||||
" R0 = R0.L * R0.L (IS);\n\t"
|
||||
" R1 >>>= 6;\n\t"
|
||||
" R1 = R1 + R2;\n\t"
|
||||
" R0 >>>= 6;\n\t"
|
||||
" R1 = R1 - R0;\n\t"
|
||||
" R2 = MAX(R1,R3);\n\t"
|
||||
"eu2: [P0++] = R2;\n\t"
|
||||
: : "d" (energy), "d" (&sw[-start-1]), "d" (&sw[-start+len-1]),
|
||||
"a" (end-start)
|
||||
: "P0", "I1", "I2", "R0", "R1", "R2", "R3"
|
||||
#if (__GNUC__ == 4)
|
||||
, "LC1"
|
||||
#endif
|
||||
);
|
||||
|
||||
pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);
|
||||
|
||||
/* FIXME: Fixed-point and floating-point code should be merged */
|
||||
{
|
||||
VARDECL(spx_word16_t *corr16);
|
||||
VARDECL(spx_word16_t *ener16);
|
||||
ALLOC(corr16, end-start+1, spx_word16_t);
|
||||
ALLOC(ener16, end-start+1, spx_word16_t);
|
||||
/* Normalize to 180 so we can square it and it still fits in 16 bits */
|
||||
normalize16(corr, corr16, 180, end-start+1);
|
||||
normalize16(energy, ener16, 180, end-start+1);
|
||||
|
||||
if (N == 1) {
|
||||
/* optimised asm to handle N==1 case */
|
||||
__asm__ __volatile__
|
||||
(
|
||||
" I0 = %1;\n\t" /* I0: corr16[] */
|
||||
" L0 = 0;\n\t"
|
||||
" I1 = %2;\n\t" /* I1: energy */
|
||||
" L1 = 0;\n\t"
|
||||
" R2 = -1;\n\t" /* R2: best score */
|
||||
" R3 = 0;\n\t" /* R3: best energy */
|
||||
" P0 = %4;\n\t" /* P0: best pitch */
|
||||
" P1 = %4;\n\t" /* P1: counter */
|
||||
" LSETUP (sl1, sl2) LC1 = %3;\n\t"
|
||||
"sl1: R0.L = W [I0++] || R1.L = W [I1++];\n\t"
|
||||
" R0 = R0.L * R0.L (IS);\n\t"
|
||||
" R1 += 1;\n\t"
|
||||
" R4 = R0.L * R3.L;\n\t"
|
||||
" R5 = R2.L * R1.L;\n\t"
|
||||
" cc = R5 < R4;\n\t"
|
||||
" if cc R2 = R0;\n\t"
|
||||
" if cc R3 = R1;\n\t"
|
||||
" if cc P0 = P1;\n\t"
|
||||
"sl2: P1 += 1;\n\t"
|
||||
" %0 = P0;\n\t"
|
||||
: "=&d" (pitch[0])
|
||||
: "a" (corr16), "a" (ener16), "a" (end+1-start), "d" (start)
|
||||
: "P0", "P1", "I0", "I1", "R0", "R1", "R2", "R3", "R4", "R5"
|
||||
#if (__GNUC__ == 4)
|
||||
, "LC1"
|
||||
#endif
|
||||
);
|
||||
|
||||
}
|
||||
else {
|
||||
for (i=start;i<=end;i++)
|
||||
{
|
||||
spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);
|
||||
/* Instead of dividing the tmp by the energy, we multiply on the other side */
|
||||
if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
|
||||
{
|
||||
/* We can safely put it last and then check */
|
||||
best_score[N-1]=tmp;
|
||||
best_ener[N-1]=ener16[i-start]+1;
|
||||
pitch[N-1]=i;
|
||||
/* Check if it comes in front of others */
|
||||
for (j=0;j<N-1;j++)
|
||||
{
|
||||
if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
|
||||
{
|
||||
for (k=N-1;k>j;k--)
|
||||
{
|
||||
best_score[k]=best_score[k-1];
|
||||
best_ener[k]=best_ener[k-1];
|
||||
pitch[k]=pitch[k-1];
|
||||
}
|
||||
best_score[j]=tmp;
|
||||
best_ener[j]=ener16[i-start]+1;
|
||||
pitch[j]=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute open-loop gain */
|
||||
if (gain)
|
||||
{
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
spx_word16_t g;
|
||||
i=pitch[j];
|
||||
g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6));
|
||||
/* FIXME: g = max(g,corr/energy) */
|
||||
if (g<0)
|
||||
g = 0;
|
||||
gain[j]=g;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ
|
||||
#ifdef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ
|
||||
static int pitch_gain_search_3tap_vq(
|
||||
const signed char *gain_cdbk,
|
||||
int gain_cdbk_size,
|
||||
spx_word16_t *C16,
|
||||
spx_word16_t max_gain
|
||||
)
|
||||
{
|
||||
const signed char *ptr=gain_cdbk;
|
||||
int best_cdbk=0;
|
||||
spx_word32_t best_sum=-VERY_LARGE32;
|
||||
spx_word32_t sum=0;
|
||||
spx_word16_t g[3];
|
||||
spx_word16_t pitch_control=64;
|
||||
spx_word16_t gain_sum;
|
||||
int i;
|
||||
|
||||
/* fast asm version of VQ codebook search */
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
|
||||
" P0 = %2;\n\t" /* P0: ptr to gain_cdbk */
|
||||
" L1 = 0;\n\t" /* no circ addr for L1 */
|
||||
" %0 = 0;\n\t" /* %0: best_sum */
|
||||
" %1 = 0;\n\t" /* %1: best_cbdk */
|
||||
" P1 = 0;\n\t" /* P1: loop counter */
|
||||
|
||||
" LSETUP (pgs1, pgs2) LC1 = %4;\n\t"
|
||||
"pgs1: R2 = B [P0++] (X);\n\t" /* R2: g[0] */
|
||||
" R3 = B [P0++] (X);\n\t" /* R3: g[1] */
|
||||
" R4 = B [P0++] (X);\n\t" /* R4: g[2] */
|
||||
" R2 += 32;\n\t"
|
||||
" R3 += 32;\n\t"
|
||||
" R4 += 32;\n\t"
|
||||
" R4.H = 64;\n\t" /* R4.H: pitch_control */
|
||||
|
||||
" R0 = B [P0++] (X);\n\t"
|
||||
" B0 = R0;\n\t" /* BO: gain_sum */
|
||||
|
||||
/* compute_pitch_error() -------------------------------*/
|
||||
|
||||
" I1 = %3;\n\t" /* I1: ptr to C */
|
||||
" A0 = 0;\n\t"
|
||||
|
||||
" R0.L = W[I1++];\n\t"
|
||||
" R1.L = R2.L*R4.H (IS);\n\t"
|
||||
" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R3.L*R4.H (IS);\n\t"
|
||||
" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R4.L*R4.H (IS);\n\t"
|
||||
" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R2.L*R3.L (IS);\n\t"
|
||||
" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R4.L*R3.L (IS);\n\t"
|
||||
" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R4.L*R2.L (IS);\n\t"
|
||||
" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R2.L*R2.L (IS);\n\t"
|
||||
" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R3.L*R3.L (IS);\n\t"
|
||||
" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R4.L*R4.L (IS);\n\t"
|
||||
" R0 = (A0 -= R1.L*R0.L) (IS);\n\t"
|
||||
|
||||
/*
|
||||
Re-arrange the if-then to code efficiently on the Blackfin:
|
||||
|
||||
if (sum>best_sum && gain_sum<=max_gain) ------ (1)
|
||||
|
||||
if (sum>best_sum && !(gain_sum>max_gain)) ------ (2)
|
||||
|
||||
if (max_gain<=gain_sum) { ------ (3)
|
||||
sum = -VERY_LARGE32;
|
||||
}
|
||||
if (best_sum<=sum)
|
||||
|
||||
The blackin cc instructions are all of the form:
|
||||
|
||||
cc = x < y (or cc = x <= y)
|
||||
*/
|
||||
" R1 = B0\n\t"
|
||||
" R2 = %5\n\t"
|
||||
" R3 = %6\n\t"
|
||||
" cc = R2 <= R1;\n\t"
|
||||
" if cc R0 = R3;\n\t"
|
||||
" cc = %0 <= R0;\n\t"
|
||||
" if cc %0 = R0;\n\t"
|
||||
" if cc %1 = P1;\n\t"
|
||||
|
||||
"pgs2: P1 += 1;\n\t"
|
||||
|
||||
: "=&d" (best_sum), "=&d" (best_cdbk)
|
||||
: "a" (gain_cdbk), "a" (C16), "a" (gain_cdbk_size), "a" (max_gain),
|
||||
"b" (-VERY_LARGE32)
|
||||
: "R0", "R1", "R2", "R3", "R4", "P0",
|
||||
"P1", "I1", "L1", "A0", "B0"
|
||||
#if (__GNUC__ == 4)
|
||||
, "LC1"
|
||||
#endif
|
||||
);
|
||||
|
||||
return best_cdbk;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file ltp_sse.h
|
||||
@brief Long-Term Prediction functions (SSE version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define OVERRIDE_INNER_PROD
|
||||
float inner_prod(const float *a, const float *b, int len)
|
||||
{
|
||||
int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
for (i=0;i<(len>>2);i+=2)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+0), _mm_loadu_ps(b+0)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+4), _mm_loadu_ps(b+4)));
|
||||
a += 8;
|
||||
b += 8;
|
||||
}
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define OVERRIDE_PITCH_XCORR
|
||||
void pitch_xcorr(const float *_x, const float *_y, float *corr, int len, int nb_pitch, char *stack)
|
||||
{
|
||||
int i, offset;
|
||||
VARDECL(__m128 *x);
|
||||
VARDECL(__m128 *y);
|
||||
int N, L;
|
||||
N = len>>2;
|
||||
L = nb_pitch>>2;
|
||||
ALLOC(x, N, __m128);
|
||||
ALLOC(y, N+L, __m128);
|
||||
for (i=0;i<N;i++)
|
||||
x[i] = _mm_loadu_ps(_x+(i<<2));
|
||||
for (offset=0;offset<4;offset++)
|
||||
{
|
||||
for (i=0;i<N+L;i++)
|
||||
y[i] = _mm_loadu_ps(_y+(i<<2)+offset);
|
||||
for (i=0;i<L;i++)
|
||||
{
|
||||
int j;
|
||||
__m128 sum, *xx, *yy;
|
||||
sum = _mm_setzero_ps();
|
||||
yy = y+i;
|
||||
xx = x;
|
||||
for (j=0;j<N;j+=2)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(xx[0], yy[0]));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(xx[1], yy[1]));
|
||||
xx += 2;
|
||||
yy += 2;
|
||||
}
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(corr+nb_pitch-1-(i<<2)-offset, sum);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,333 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file math_approx.h
|
||||
@brief Various math approximation functions for Speex
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MATH_APPROX_H
|
||||
#define MATH_APPROX_H
|
||||
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#ifndef FIXED_POINT
|
||||
|
||||
#define spx_sqrt sqrt
|
||||
#define spx_acos acos
|
||||
#define spx_exp exp
|
||||
#define spx_cos_norm(x) (cos((.5f*M_PI)*(x)))
|
||||
#define spx_atan atan
|
||||
|
||||
/** Generate a pseudo-random number */
|
||||
static SPEEX_INLINE spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
|
||||
{
|
||||
const unsigned int jflone = 0x3f800000;
|
||||
const unsigned int jflmsk = 0x007fffff;
|
||||
union {int i; float f;} ran;
|
||||
*seed = 1664525 * *seed + 1013904223;
|
||||
ran.i = jflone | (jflmsk & *seed);
|
||||
ran.f -= 1.5;
|
||||
return 3.4642*std*ran.f;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static SPEEX_INLINE spx_int16_t spx_ilog2(spx_uint32_t x)
|
||||
{
|
||||
int r=0;
|
||||
if (x>=(spx_int32_t)65536)
|
||||
{
|
||||
x >>= 16;
|
||||
r += 16;
|
||||
}
|
||||
if (x>=256)
|
||||
{
|
||||
x >>= 8;
|
||||
r += 8;
|
||||
}
|
||||
if (x>=16)
|
||||
{
|
||||
x >>= 4;
|
||||
r += 4;
|
||||
}
|
||||
if (x>=4)
|
||||
{
|
||||
x >>= 2;
|
||||
r += 2;
|
||||
}
|
||||
if (x>=2)
|
||||
{
|
||||
r += 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static SPEEX_INLINE spx_int16_t spx_ilog4(spx_uint32_t x)
|
||||
{
|
||||
int r=0;
|
||||
if (x>=(spx_int32_t)65536)
|
||||
{
|
||||
x >>= 16;
|
||||
r += 8;
|
||||
}
|
||||
if (x>=256)
|
||||
{
|
||||
x >>= 8;
|
||||
r += 4;
|
||||
}
|
||||
if (x>=16)
|
||||
{
|
||||
x >>= 4;
|
||||
r += 2;
|
||||
}
|
||||
if (x>=4)
|
||||
{
|
||||
r += 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
/** Generate a pseudo-random number */
|
||||
static SPEEX_INLINE spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
|
||||
{
|
||||
spx_word32_t res;
|
||||
*seed = 1664525 * *seed + 1013904223;
|
||||
res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
|
||||
return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14));
|
||||
}
|
||||
|
||||
/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
|
||||
/*#define C0 3634
|
||||
#define C1 21173
|
||||
#define C2 -12627
|
||||
#define C3 4215*/
|
||||
|
||||
/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */
|
||||
#define C0 3634
|
||||
#define C1 21173
|
||||
#define C2 -12627
|
||||
#define C3 4204
|
||||
|
||||
static SPEEX_INLINE spx_word16_t spx_sqrt(spx_word32_t x)
|
||||
{
|
||||
int k;
|
||||
spx_word32_t rt;
|
||||
k = spx_ilog4(x)-6;
|
||||
x = VSHR32(x, (k<<1));
|
||||
rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
|
||||
rt = VSHR32(rt,7-k);
|
||||
return rt;
|
||||
}
|
||||
|
||||
/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
|
||||
|
||||
|
||||
#define A1 16469
|
||||
#define A2 2242
|
||||
#define A3 1486
|
||||
|
||||
static SPEEX_INLINE spx_word16_t spx_acos(spx_word16_t x)
|
||||
{
|
||||
int s=0;
|
||||
spx_word16_t ret;
|
||||
spx_word16_t sq;
|
||||
if (x<0)
|
||||
{
|
||||
s=1;
|
||||
x = NEG16(x);
|
||||
}
|
||||
x = SUB16(16384,x);
|
||||
|
||||
x = x >> 1;
|
||||
sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
|
||||
ret = spx_sqrt(SHL32(EXTEND32(sq),13));
|
||||
|
||||
/*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
|
||||
if (s)
|
||||
ret = SUB16(25736,ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#define K1 8192
|
||||
#define K2 -4096
|
||||
#define K3 340
|
||||
#define K4 -10
|
||||
|
||||
static SPEEX_INLINE spx_word16_t spx_cos(spx_word16_t x)
|
||||
{
|
||||
spx_word16_t x2;
|
||||
|
||||
if (x<12868)
|
||||
{
|
||||
x2 = MULT16_16_P13(x,x);
|
||||
return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
|
||||
} else {
|
||||
x = SUB16(25736,x);
|
||||
x2 = MULT16_16_P13(x,x);
|
||||
return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
|
||||
}
|
||||
}
|
||||
|
||||
#define L1 32767
|
||||
#define L2 -7651
|
||||
#define L3 8277
|
||||
#define L4 -626
|
||||
|
||||
static SPEEX_INLINE spx_word16_t _spx_cos_pi_2(spx_word16_t x)
|
||||
{
|
||||
spx_word16_t 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))))))));
|
||||
}
|
||||
|
||||
static SPEEX_INLINE spx_word16_t spx_cos_norm(spx_word32_t 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 _spx_cos_pi_2(EXTRACT16(x));
|
||||
} else {
|
||||
return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x)));
|
||||
}
|
||||
} else {
|
||||
if (x&0x0000ffff)
|
||||
return 0;
|
||||
else if (x&0x0001ffff)
|
||||
return -32767;
|
||||
else
|
||||
return 32767;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
K0 = 1
|
||||
K1 = log(2)
|
||||
K2 = 3-4*log(2)
|
||||
K3 = 3*log(2) - 2
|
||||
*/
|
||||
#define D0 16384
|
||||
#define D1 11356
|
||||
#define D2 3726
|
||||
#define D3 1301
|
||||
/* Input in Q11 format, output in Q16 */
|
||||
static SPEEX_INLINE spx_word32_t spx_exp2(spx_word16_t x)
|
||||
{
|
||||
int integer;
|
||||
spx_word16_t frac;
|
||||
integer = SHR16(x,11);
|
||||
if (integer>14)
|
||||
return 0x7fffffff;
|
||||
else if (integer < -15)
|
||||
return 0;
|
||||
frac = SHL16(x-SHL16(integer,11),3);
|
||||
frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac))))));
|
||||
return VSHR32(EXTEND32(frac), -integer-2);
|
||||
}
|
||||
|
||||
/* Input in Q11 format, output in Q16 */
|
||||
static SPEEX_INLINE spx_word32_t spx_exp(spx_word16_t x)
|
||||
{
|
||||
if (x>21290)
|
||||
return 0x7fffffff;
|
||||
else if (x<-21290)
|
||||
return 0;
|
||||
else
|
||||
return spx_exp2(MULT16_16_P14(23637,x));
|
||||
}
|
||||
#define M1 32767
|
||||
#define M2 -21
|
||||
#define M3 -11943
|
||||
#define M4 4936
|
||||
|
||||
static SPEEX_INLINE spx_word16_t spx_atan01(spx_word16_t 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
|
||||
|
||||
/* Input in Q15, output in Q14 */
|
||||
static SPEEX_INLINE spx_word16_t spx_atan(spx_word32_t x)
|
||||
{
|
||||
if (x <= 32767)
|
||||
{
|
||||
return SHR16(spx_atan01(x),1);
|
||||
} else {
|
||||
int e = spx_ilog2(x);
|
||||
if (e>=29)
|
||||
return 25736;
|
||||
x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14)));
|
||||
return SUB16(25736, SHR16(spx_atan01(x),1));
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 /* pi */
|
||||
#endif
|
||||
|
||||
#define C1 0.9999932946f
|
||||
#define C2 -0.4999124376f
|
||||
#define C3 0.0414877472f
|
||||
#define C4 -0.0012712095f
|
||||
|
||||
|
||||
#define SPX_PI_2 1.5707963268
|
||||
static SPEEX_INLINE spx_word16_t spx_cos(spx_word16_t x)
|
||||
{
|
||||
if (x<SPX_PI_2)
|
||||
{
|
||||
x *= x;
|
||||
return C1 + x*(C2+x*(C3+C4*x));
|
||||
} else {
|
||||
x = M_PI-x;
|
||||
x *= x;
|
||||
return NEG16(C1 + x*(C2+x*(C3+C4*x)));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
1285
drivers/speex/mdf.c
1285
drivers/speex/mdf.c
File diff suppressed because it is too large
Load diff
|
@ -1,54 +0,0 @@
|
|||
/* Copyright (C) 2005 Analog Devices */
|
||||
/**
|
||||
@file misc_bfin.h
|
||||
@author Jean-Marc Valin
|
||||
@brief Various compatibility routines for Speex (Blackfin version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define OVERRIDE_SPEEX_MOVE
|
||||
void *speex_move (void *dest, void *src, int n)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"L0 = 0;\n\t"
|
||||
"I0 = %0;\n\t"
|
||||
"R0 = [I0++];\n\t"
|
||||
"LOOP move%= LC0 = %2;\n\t"
|
||||
"LOOP_BEGIN move%=;\n\t"
|
||||
"[%1++] = R0 || R0 = [I0++];\n\t"
|
||||
"LOOP_END move%=;\n\t"
|
||||
"[%1++] = R0;\n\t"
|
||||
: "=a" (src), "=a" (dest)
|
||||
: "a" ((n>>2)-1), "0" (src), "1" (dest)
|
||||
: "R0", "I0", "L0", "memory"
|
||||
);
|
||||
return dest;
|
||||
}
|
|
@ -1,366 +0,0 @@
|
|||
/* Copyright (C) 2002-2006 Jean-Marc Valin
|
||||
File: modes.c
|
||||
|
||||
Describes the different modes of the codec
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "modes.h"
|
||||
#include "ltp.h"
|
||||
#include "quant_lsp.h"
|
||||
#include "cb_search.h"
|
||||
#include "sb_celp.h"
|
||||
#include "nb_celp.h"
|
||||
#include "vbr.h"
|
||||
#include "arch.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
|
||||
/* Extern declarations for all codebooks we use here */
|
||||
extern const signed char gain_cdbk_nb[];
|
||||
extern const signed char gain_cdbk_lbr[];
|
||||
extern const signed char exc_5_256_table[];
|
||||
extern const signed char exc_5_64_table[];
|
||||
extern const signed char exc_8_128_table[];
|
||||
extern const signed char exc_10_32_table[];
|
||||
extern const signed char exc_10_16_table[];
|
||||
extern const signed char exc_20_32_table[];
|
||||
|
||||
|
||||
/* Parameters for Long-Term Prediction (LTP)*/
|
||||
static const ltp_params ltp_params_nb = {
|
||||
gain_cdbk_nb,
|
||||
7,
|
||||
7
|
||||
};
|
||||
|
||||
/* Parameters for Long-Term Prediction (LTP)*/
|
||||
static const ltp_params ltp_params_vlbr = {
|
||||
gain_cdbk_lbr,
|
||||
5,
|
||||
0
|
||||
};
|
||||
|
||||
/* Parameters for Long-Term Prediction (LTP)*/
|
||||
static const ltp_params ltp_params_lbr = {
|
||||
gain_cdbk_lbr,
|
||||
5,
|
||||
7
|
||||
};
|
||||
|
||||
/* Parameters for Long-Term Prediction (LTP)*/
|
||||
static const ltp_params ltp_params_med = {
|
||||
gain_cdbk_lbr,
|
||||
5,
|
||||
7
|
||||
};
|
||||
|
||||
/* Split-VQ innovation parameters for very low bit-rate narrowband */
|
||||
static const split_cb_params split_cb_nb_vlbr = {
|
||||
10, /*subvect_size*/
|
||||
4, /*nb_subvect*/
|
||||
exc_10_16_table, /*shape_cb*/
|
||||
4, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
/* Split-VQ innovation parameters for very low bit-rate narrowband */
|
||||
static const split_cb_params split_cb_nb_ulbr = {
|
||||
20, /*subvect_size*/
|
||||
2, /*nb_subvect*/
|
||||
exc_20_32_table, /*shape_cb*/
|
||||
5, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
/* Split-VQ innovation parameters for low bit-rate narrowband */
|
||||
static const split_cb_params split_cb_nb_lbr = {
|
||||
10, /*subvect_size*/
|
||||
4, /*nb_subvect*/
|
||||
exc_10_32_table, /*shape_cb*/
|
||||
5, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
/* Split-VQ innovation parameters narrowband */
|
||||
static const split_cb_params split_cb_nb = {
|
||||
5, /*subvect_size*/
|
||||
8, /*nb_subvect*/
|
||||
exc_5_64_table, /*shape_cb*/
|
||||
6, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
/* Split-VQ innovation parameters narrowband */
|
||||
static const split_cb_params split_cb_nb_med = {
|
||||
8, /*subvect_size*/
|
||||
5, /*nb_subvect*/
|
||||
exc_8_128_table, /*shape_cb*/
|
||||
7, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
/* Split-VQ innovation for low-band wideband */
|
||||
static const split_cb_params split_cb_sb = {
|
||||
5, /*subvect_size*/
|
||||
8, /*nb_subvect*/
|
||||
exc_5_256_table, /*shape_cb*/
|
||||
8, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* 2150 bps "vocoder-like" mode for comfort noise */
|
||||
static const SpeexSubmode nb_submode1 = {
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
/* LSP quantization */
|
||||
lsp_quant_lbr,
|
||||
lsp_unquant_lbr,
|
||||
/* No pitch quantization */
|
||||
forced_pitch_quant,
|
||||
forced_pitch_unquant,
|
||||
NULL,
|
||||
/* No innovation quantization (noise only) */
|
||||
noise_codebook_quant,
|
||||
noise_codebook_unquant,
|
||||
NULL,
|
||||
-1,
|
||||
43
|
||||
};
|
||||
|
||||
/* 3.95 kbps very low bit-rate mode */
|
||||
static const SpeexSubmode nb_submode8 = {
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_lbr,
|
||||
lsp_unquant_lbr,
|
||||
/*No pitch quantization*/
|
||||
forced_pitch_quant,
|
||||
forced_pitch_unquant,
|
||||
NULL,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb_ulbr,
|
||||
QCONST16(.5,15),
|
||||
79
|
||||
};
|
||||
|
||||
/* 5.95 kbps very low bit-rate mode */
|
||||
static const SpeexSubmode nb_submode2 = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_lbr,
|
||||
lsp_unquant_lbr,
|
||||
/*No pitch quantization*/
|
||||
pitch_search_3tap,
|
||||
pitch_unquant_3tap,
|
||||
<p_params_vlbr,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb_vlbr,
|
||||
QCONST16(.6,15),
|
||||
119
|
||||
};
|
||||
|
||||
/* 8 kbps low bit-rate mode */
|
||||
static const SpeexSubmode nb_submode3 = {
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_lbr,
|
||||
lsp_unquant_lbr,
|
||||
/*Pitch quantization*/
|
||||
pitch_search_3tap,
|
||||
pitch_unquant_3tap,
|
||||
<p_params_lbr,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb_lbr,
|
||||
QCONST16(.55,15),
|
||||
160
|
||||
};
|
||||
|
||||
/* 11 kbps medium bit-rate mode */
|
||||
static const SpeexSubmode nb_submode4 = {
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_lbr,
|
||||
lsp_unquant_lbr,
|
||||
/*Pitch quantization*/
|
||||
pitch_search_3tap,
|
||||
pitch_unquant_3tap,
|
||||
<p_params_med,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb_med,
|
||||
QCONST16(.45,15),
|
||||
220
|
||||
};
|
||||
|
||||
/* 15 kbps high bit-rate mode */
|
||||
static const SpeexSubmode nb_submode5 = {
|
||||
-1,
|
||||
0,
|
||||
3,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_nb,
|
||||
lsp_unquant_nb,
|
||||
/*Pitch quantization*/
|
||||
pitch_search_3tap,
|
||||
pitch_unquant_3tap,
|
||||
<p_params_nb,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb,
|
||||
QCONST16(.3,15),
|
||||
300
|
||||
};
|
||||
|
||||
/* 18.2 high bit-rate mode */
|
||||
static const SpeexSubmode nb_submode6 = {
|
||||
-1,
|
||||
0,
|
||||
3,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_nb,
|
||||
lsp_unquant_nb,
|
||||
/*Pitch quantization*/
|
||||
pitch_search_3tap,
|
||||
pitch_unquant_3tap,
|
||||
<p_params_nb,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_sb,
|
||||
QCONST16(.2,15),
|
||||
364
|
||||
};
|
||||
|
||||
/* 24.6 kbps high bit-rate mode */
|
||||
static const SpeexSubmode nb_submode7 = {
|
||||
-1,
|
||||
0,
|
||||
3,
|
||||
1,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_nb,
|
||||
lsp_unquant_nb,
|
||||
/*Pitch quantization*/
|
||||
pitch_search_3tap,
|
||||
pitch_unquant_3tap,
|
||||
<p_params_nb,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb,
|
||||
QCONST16(.1,15),
|
||||
492
|
||||
};
|
||||
|
||||
|
||||
/* Default mode for narrowband */
|
||||
static const SpeexNBMode nb_mode = {
|
||||
160, /*frameSize*/
|
||||
40, /*subframeSize*/
|
||||
10, /*lpcSize*/
|
||||
17, /*pitchStart*/
|
||||
144, /*pitchEnd*/
|
||||
#ifdef FIXED_POINT
|
||||
29491, 19661, /* gamma1, gamma2 */
|
||||
#else
|
||||
0.9, 0.6, /* gamma1, gamma2 */
|
||||
#endif
|
||||
QCONST16(.0002,15), /*lpc_floor*/
|
||||
{NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7,
|
||||
&nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
5,
|
||||
{1, 8, 2, 3, 3, 4, 4, 5, 5, 6, 7}
|
||||
};
|
||||
|
||||
|
||||
/* Default mode for narrowband */
|
||||
EXPORT const SpeexMode speex_nb_mode = {
|
||||
&nb_mode,
|
||||
nb_mode_query,
|
||||
"narrowband",
|
||||
0,
|
||||
4,
|
||||
&nb_encoder_init,
|
||||
&nb_encoder_destroy,
|
||||
&nb_encode,
|
||||
&nb_decoder_init,
|
||||
&nb_decoder_destroy,
|
||||
&nb_decode,
|
||||
&nb_encoder_ctl,
|
||||
&nb_decoder_ctl,
|
||||
};
|
||||
|
||||
|
||||
|
||||
EXPORT int speex_mode_query(const SpeexMode *mode, int request, void *ptr)
|
||||
{
|
||||
return mode->query(mode->mode, request, ptr);
|
||||
}
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
long long spx_mips=0;
|
||||
#endif
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
/* Copyright (C) 2002-2006 Jean-Marc Valin */
|
||||
/**
|
||||
@file modes.h
|
||||
@brief Describes the different modes of the codec
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef MODES_H
|
||||
#define MODES_H
|
||||
|
||||
#include <speex/speex.h>
|
||||
#include <speex/speex_bits.h>
|
||||
#include "arch.h"
|
||||
|
||||
#define NB_SUBMODES 16
|
||||
#define NB_SUBMODE_BITS 4
|
||||
|
||||
#define SB_SUBMODES 8
|
||||
#define SB_SUBMODE_BITS 3
|
||||
|
||||
/* Used internally, NOT TO BE USED in applications */
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_PI_GAIN 100
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_EXC 101
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_INNOV 102
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_DTX_STATUS 103
|
||||
/** Used internally*/
|
||||
#define SPEEX_SET_INNOVATION_SAVE 104
|
||||
/** Used internally*/
|
||||
#define SPEEX_SET_WIDEBAND 105
|
||||
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_STACK 106
|
||||
|
||||
|
||||
/** Quantizes LSPs */
|
||||
typedef void (*lsp_quant_func)(spx_lsp_t *, spx_lsp_t *, int, SpeexBits *);
|
||||
|
||||
/** Decodes quantized LSPs */
|
||||
typedef void (*lsp_unquant_func)(spx_lsp_t *, int, SpeexBits *);
|
||||
|
||||
|
||||
/** Long-term predictor quantization */
|
||||
typedef int (*ltp_quant_func)(spx_word16_t *, spx_word16_t *, spx_coef_t *, spx_coef_t *,
|
||||
spx_coef_t *, spx_sig_t *, const void *, int, int, spx_word16_t,
|
||||
int, int, SpeexBits*, char *, spx_word16_t *, spx_word16_t *, int, int, int, spx_word32_t *);
|
||||
|
||||
/** Long-term un-quantize */
|
||||
typedef void (*ltp_unquant_func)(spx_word16_t *, spx_word32_t *, int, int, spx_word16_t, const void *, int, int *,
|
||||
spx_word16_t *, SpeexBits*, char*, int, int, spx_word16_t, int);
|
||||
|
||||
|
||||
/** Innovation quantization function */
|
||||
typedef void (*innovation_quant_func)(spx_word16_t *, spx_coef_t *, spx_coef_t *, spx_coef_t *, const void *, int, int,
|
||||
spx_sig_t *, spx_word16_t *, SpeexBits *, char *, int, int);
|
||||
|
||||
/** Innovation unquantization function */
|
||||
typedef void (*innovation_unquant_func)(spx_sig_t *, const void *, int, SpeexBits*, char *, spx_int32_t *);
|
||||
|
||||
/** Description of a Speex sub-mode (wither narrowband or wideband */
|
||||
typedef struct SpeexSubmode {
|
||||
int lbr_pitch; /**< Set to -1 for "normal" modes, otherwise encode pitch using a global pitch and allowing a +- lbr_pitch variation (for low not-rates)*/
|
||||
int forced_pitch_gain; /**< Use the same (forced) pitch gain for all sub-frames */
|
||||
int have_subframe_gain; /**< Number of bits to use as sub-frame innovation gain */
|
||||
int double_codebook; /**< Apply innovation quantization twice for higher quality (and higher bit-rate)*/
|
||||
/*LSP functions*/
|
||||
lsp_quant_func lsp_quant; /**< LSP quantization function */
|
||||
lsp_unquant_func lsp_unquant; /**< LSP unquantization function */
|
||||
|
||||
/*Long-term predictor functions*/
|
||||
ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */
|
||||
ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */
|
||||
const void *ltp_params; /**< Pitch parameters (options) */
|
||||
|
||||
/*Quantization of innovation*/
|
||||
innovation_quant_func innovation_quant; /**< Innovation quantization */
|
||||
innovation_unquant_func innovation_unquant; /**< Innovation un-quantization */
|
||||
const void *innovation_params; /**< Innovation quantization parameters*/
|
||||
|
||||
spx_word16_t comb_gain; /**< Gain of enhancer comb filter */
|
||||
|
||||
int bits_per_frame; /**< Number of bits per frame after encoding*/
|
||||
} SpeexSubmode;
|
||||
|
||||
/** Struct defining the encoding/decoding mode*/
|
||||
typedef struct SpeexNBMode {
|
||||
int frameSize; /**< Size of frames used for encoding */
|
||||
int subframeSize; /**< Size of sub-frames used for encoding */
|
||||
int lpcSize; /**< Order of LPC filter */
|
||||
int pitchStart; /**< Smallest pitch value allowed */
|
||||
int pitchEnd; /**< Largest pitch value allowed */
|
||||
|
||||
spx_word16_t gamma1; /**< Perceptual filter parameter #1 */
|
||||
spx_word16_t gamma2; /**< Perceptual filter parameter #2 */
|
||||
spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */
|
||||
|
||||
const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */
|
||||
int defaultSubmode; /**< Default sub-mode to use when encoding */
|
||||
int quality_map[11]; /**< Mode corresponding to each quality setting */
|
||||
} SpeexNBMode;
|
||||
|
||||
|
||||
/** Struct defining the encoding/decoding mode for SB-CELP (wideband) */
|
||||
typedef struct SpeexSBMode {
|
||||
const SpeexMode *nb_mode; /**< Embedded narrowband mode */
|
||||
int frameSize; /**< Size of frames used for encoding */
|
||||
int subframeSize; /**< Size of sub-frames used for encoding */
|
||||
int lpcSize; /**< Order of LPC filter */
|
||||
spx_word16_t gamma1; /**< Perceptual filter parameter #1 */
|
||||
spx_word16_t gamma2; /**< Perceptual filter parameter #1 */
|
||||
spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */
|
||||
spx_word16_t folding_gain;
|
||||
|
||||
const SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */
|
||||
int defaultSubmode; /**< Default sub-mode to use when encoding */
|
||||
int low_quality_map[11]; /**< Mode corresponding to each quality setting */
|
||||
int quality_map[11]; /**< Mode corresponding to each quality setting */
|
||||
#ifndef DISABLE_VBR
|
||||
const float (*vbr_thresh)[11];
|
||||
#endif
|
||||
int nb_modes;
|
||||
} SpeexSBMode;
|
||||
|
||||
int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits);
|
||||
int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out);
|
||||
|
||||
int nb_mode_query(const void *mode, int request, void *ptr);
|
||||
int wb_mode_query(const void *mode, int request, void *ptr);
|
||||
|
||||
#endif
|
|
@ -1,300 +0,0 @@
|
|||
/* Copyright (C) 2002-2007 Jean-Marc Valin
|
||||
File: modes.c
|
||||
|
||||
Describes the wideband modes of the codec
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "modes.h"
|
||||
#include "ltp.h"
|
||||
#include "quant_lsp.h"
|
||||
#include "cb_search.h"
|
||||
#include "sb_celp.h"
|
||||
#include "nb_celp.h"
|
||||
#include "vbr.h"
|
||||
#include "arch.h"
|
||||
#include <math.h>
|
||||
#include "os_support.h"
|
||||
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
EXPORT const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
|
||||
|
||||
extern const signed char hexc_table[];
|
||||
extern const signed char hexc_10_32_table[];
|
||||
|
||||
#ifndef DISABLE_WIDEBAND
|
||||
|
||||
/* Split-VQ innovation for high-band wideband */
|
||||
static const split_cb_params split_cb_high = {
|
||||
8, /*subvect_size*/
|
||||
5, /*nb_subvect*/
|
||||
hexc_table, /*shape_cb*/
|
||||
7, /*shape_bits*/
|
||||
1,
|
||||
};
|
||||
|
||||
|
||||
/* Split-VQ innovation for high-band wideband */
|
||||
static const split_cb_params split_cb_high_lbr = {
|
||||
10, /*subvect_size*/
|
||||
4, /*nb_subvect*/
|
||||
hexc_10_32_table, /*shape_cb*/
|
||||
5, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static const SpeexSubmode wb_submode1 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*No innovation quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
-1,
|
||||
36
|
||||
};
|
||||
|
||||
|
||||
static const SpeexSubmode wb_submode2 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
NULL,
|
||||
#else
|
||||
&split_cb_high_lbr,
|
||||
#endif
|
||||
-1,
|
||||
112
|
||||
};
|
||||
|
||||
|
||||
static const SpeexSubmode wb_submode3 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
NULL,
|
||||
#else
|
||||
&split_cb_high,
|
||||
#endif
|
||||
-1,
|
||||
192
|
||||
};
|
||||
|
||||
static const SpeexSubmode wb_submode4 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
NULL,
|
||||
#else
|
||||
&split_cb_high,
|
||||
#endif
|
||||
-1,
|
||||
352
|
||||
};
|
||||
|
||||
|
||||
/* Split-band wideband CELP mode*/
|
||||
static const SpeexSBMode sb_wb_mode = {
|
||||
&speex_nb_mode,
|
||||
160, /*frameSize*/
|
||||
40, /*subframeSize*/
|
||||
8, /*lpcSize*/
|
||||
#ifdef FIXED_POINT
|
||||
29491, 19661, /* gamma1, gamma2 */
|
||||
#else
|
||||
0.9, 0.6, /* gamma1, gamma2 */
|
||||
#endif
|
||||
QCONST16(.0002,15), /*lpc_floor*/
|
||||
QCONST16(0.9f,15),
|
||||
{NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
|
||||
3,
|
||||
{1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
|
||||
{1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
|
||||
#ifndef DISABLE_VBR
|
||||
vbr_hb_thresh,
|
||||
#endif
|
||||
5
|
||||
};
|
||||
|
||||
|
||||
EXPORT const SpeexMode speex_wb_mode = {
|
||||
&sb_wb_mode,
|
||||
wb_mode_query,
|
||||
"wideband (sub-band CELP)",
|
||||
1,
|
||||
4,
|
||||
&sb_encoder_init,
|
||||
&sb_encoder_destroy,
|
||||
&sb_encode,
|
||||
&sb_decoder_init,
|
||||
&sb_decoder_destroy,
|
||||
&sb_decode,
|
||||
&sb_encoder_ctl,
|
||||
&sb_decoder_ctl,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* "Ultra-wideband" mode stuff */
|
||||
|
||||
|
||||
|
||||
/* Split-band "ultra-wideband" (32 kbps) CELP mode*/
|
||||
static const SpeexSBMode sb_uwb_mode = {
|
||||
&speex_wb_mode,
|
||||
320, /*frameSize*/
|
||||
80, /*subframeSize*/
|
||||
8, /*lpcSize*/
|
||||
#ifdef FIXED_POINT
|
||||
29491, 19661, /* gamma1, gamma2 */
|
||||
#else
|
||||
0.9, 0.6, /* gamma1, gamma2 */
|
||||
#endif
|
||||
QCONST16(.0002,15), /*lpc_floor*/
|
||||
QCONST16(0.7f,15),
|
||||
{NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
1,
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
#ifndef DISABLE_VBR
|
||||
vbr_uhb_thresh,
|
||||
#endif
|
||||
2
|
||||
};
|
||||
|
||||
int wb_mode_query(const void *mode, int request, void *ptr)
|
||||
{
|
||||
const SpeexSBMode *m = (const SpeexSBMode*)mode;
|
||||
|
||||
switch (request)
|
||||
{
|
||||
case SPEEX_MODE_FRAME_SIZE:
|
||||
*((int*)ptr)=2*m->frameSize;
|
||||
break;
|
||||
case SPEEX_SUBMODE_BITS_PER_FRAME:
|
||||
if (*((int*)ptr)==0)
|
||||
*((int*)ptr) = SB_SUBMODE_BITS+1;
|
||||
else if (m->submodes[*((int*)ptr)]==NULL)
|
||||
*((int*)ptr) = -1;
|
||||
else
|
||||
*((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
|
||||
break;
|
||||
default:
|
||||
speex_warning_int("Unknown wb_mode_query request: ", request);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
EXPORT const SpeexMode speex_uwb_mode = {
|
||||
&sb_uwb_mode,
|
||||
wb_mode_query,
|
||||
"ultra-wideband (sub-band CELP)",
|
||||
2,
|
||||
4,
|
||||
&sb_encoder_init,
|
||||
&sb_encoder_destroy,
|
||||
&sb_encode,
|
||||
&sb_decoder_init,
|
||||
&sb_decoder_destroy,
|
||||
&sb_decode,
|
||||
&sb_encoder_ctl,
|
||||
&sb_decoder_ctl,
|
||||
};
|
||||
|
||||
/* We have defined speex_lib_get_mode() as a macro in speex.h */
|
||||
#undef speex_lib_get_mode
|
||||
|
||||
EXPORT const SpeexMode * speex_lib_get_mode (int mode)
|
||||
{
|
||||
if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL;
|
||||
|
||||
return speex_mode_list[mode];
|
||||
}
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,203 +0,0 @@
|
|||
/* Copyright (C) 2002-2006 Jean-Marc Valin */
|
||||
/**
|
||||
@file nb_celp.h
|
||||
@brief Narrowband CELP encoder/decoder
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NB_CELP_H
|
||||
#define NB_CELP_H
|
||||
|
||||
#include "modes.h"
|
||||
#include <speex/speex_bits.h>
|
||||
#include <speex/speex_callbacks.h>
|
||||
#include "vbr.h"
|
||||
#include "filters.h"
|
||||
|
||||
#ifdef VORBIS_PSYCHO
|
||||
#include "vorbis_psy.h"
|
||||
#endif
|
||||
|
||||
/**Structure representing the full state of the narrowband encoder*/
|
||||
typedef struct EncState {
|
||||
const SpeexMode *mode; /**< Mode corresponding to the state */
|
||||
int first; /**< Is this the first frame? */
|
||||
int frameSize; /**< Size of frames */
|
||||
int subframeSize; /**< Size of sub-frames */
|
||||
int nbSubframes; /**< Number of sub-frames */
|
||||
int windowSize; /**< Analysis (LPC) window length */
|
||||
int lpcSize; /**< LPC order */
|
||||
int min_pitch; /**< Minimum pitch value allowed */
|
||||
int max_pitch; /**< Maximum pitch value allowed */
|
||||
|
||||
spx_word32_t cumul_gain; /**< Product of previously used pitch gains (Q10) */
|
||||
int bounded_pitch; /**< Next frame should not rely on previous frames for pitch */
|
||||
int ol_pitch; /**< Open-loop pitch */
|
||||
int ol_voiced; /**< Open-loop voiced/non-voiced decision */
|
||||
int *pitch;
|
||||
|
||||
#ifdef VORBIS_PSYCHO
|
||||
VorbisPsy *psy;
|
||||
float *psy_window;
|
||||
float *curve;
|
||||
float *old_curve;
|
||||
#endif
|
||||
|
||||
spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */
|
||||
spx_word16_t gamma2; /**< Perceptual filter: A(z/gamma2) */
|
||||
spx_word16_t lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/
|
||||
char *stack; /**< Pseudo-stack allocation for temporary memory */
|
||||
spx_word16_t *winBuf; /**< Input buffer (original signal) */
|
||||
spx_word16_t *excBuf; /**< Excitation buffer */
|
||||
spx_word16_t *exc; /**< Start of excitation frame */
|
||||
spx_word16_t *swBuf; /**< Weighted signal buffer */
|
||||
spx_word16_t *sw; /**< Start of weighted signal frame */
|
||||
const spx_word16_t *window; /**< Temporary (Hanning) window */
|
||||
const spx_word16_t *lagWindow; /**< Window applied to auto-correlation */
|
||||
spx_lsp_t *old_lsp; /**< LSPs for previous frame */
|
||||
spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */
|
||||
spx_mem_t *mem_sp; /**< Filter memory for signal synthesis */
|
||||
spx_mem_t *mem_sw; /**< Filter memory for perceptually-weighted signal */
|
||||
spx_mem_t *mem_sw_whole; /**< Filter memory for perceptually-weighted signal (whole frame)*/
|
||||
spx_mem_t *mem_exc; /**< Filter memory for excitation (whole frame) */
|
||||
spx_mem_t *mem_exc2; /**< Filter memory for excitation (whole frame) */
|
||||
spx_mem_t mem_hp[2]; /**< High-pass filter memory */
|
||||
spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */
|
||||
spx_word16_t *innov_rms_save; /**< If non-NULL, innovation RMS is copied here */
|
||||
|
||||
#ifndef DISABLE_VBR
|
||||
VBRState *vbr; /**< State of the VBR data */
|
||||
float vbr_quality; /**< Quality setting for VBR encoding */
|
||||
float relative_quality; /**< Relative quality that will be needed by VBR */
|
||||
spx_int32_t vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */
|
||||
spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode */
|
||||
int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */
|
||||
int dtx_enabled; /**< 1 for enabling DTX, 0 otherwise */
|
||||
int dtx_count; /**< Number of consecutive DTX frames */
|
||||
spx_int32_t abr_enabled; /**< ABR setting (in bps), 0 if off */
|
||||
float abr_drift;
|
||||
float abr_drift2;
|
||||
float abr_count;
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
||||
int complexity; /**< Complexity setting (0-10 from least complex to most complex) */
|
||||
spx_int32_t sampling_rate;
|
||||
int plc_tuning;
|
||||
int encode_submode;
|
||||
const SpeexSubmode * const *submodes; /**< Sub-mode data */
|
||||
int submodeID; /**< Activated sub-mode */
|
||||
int submodeSelect; /**< Mode chosen by the user (may differ from submodeID if VAD is on) */
|
||||
int isWideband; /**< Is this used as part of the embedded wideband codec */
|
||||
int highpass_enabled; /**< Is the input filter enabled */
|
||||
} EncState;
|
||||
|
||||
/**Structure representing the full state of the narrowband decoder*/
|
||||
typedef struct DecState {
|
||||
const SpeexMode *mode; /**< Mode corresponding to the state */
|
||||
int first; /**< Is this the first frame? */
|
||||
int count_lost; /**< Was the last frame lost? */
|
||||
int frameSize; /**< Size of frames */
|
||||
int subframeSize; /**< Size of sub-frames */
|
||||
int nbSubframes; /**< Number of sub-frames */
|
||||
int lpcSize; /**< LPC order */
|
||||
int min_pitch; /**< Minimum pitch value allowed */
|
||||
int max_pitch; /**< Maximum pitch value allowed */
|
||||
spx_int32_t sampling_rate;
|
||||
|
||||
spx_word16_t last_ol_gain; /**< Open-loop gain for previous frame */
|
||||
|
||||
char *stack; /**< Pseudo-stack allocation for temporary memory */
|
||||
spx_word16_t *excBuf; /**< Excitation buffer */
|
||||
spx_word16_t *exc; /**< Start of excitation frame */
|
||||
spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */
|
||||
spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs */
|
||||
spx_mem_t *mem_sp; /**< Filter memory for synthesis signal */
|
||||
spx_mem_t mem_hp[2]; /**< High-pass filter memory */
|
||||
spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */
|
||||
spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */
|
||||
|
||||
spx_word16_t level;
|
||||
spx_word16_t max_level;
|
||||
spx_word16_t min_level;
|
||||
|
||||
/* This is used in packet loss concealment */
|
||||
int last_pitch; /**< Pitch of last correctly decoded frame */
|
||||
spx_word16_t last_pitch_gain; /**< Pitch gain of last correctly decoded frame */
|
||||
spx_word16_t pitch_gain_buf[3]; /**< Pitch gain of last decoded frames */
|
||||
int pitch_gain_buf_idx; /**< Tail of the buffer */
|
||||
spx_int32_t seed; /** Seed used for random number generation */
|
||||
|
||||
int encode_submode;
|
||||
const SpeexSubmode * const *submodes; /**< Sub-mode data */
|
||||
int submodeID; /**< Activated sub-mode */
|
||||
int lpc_enh_enabled; /**< 1 when LPC enhancer is on, 0 otherwise */
|
||||
SpeexCallback speex_callbacks[SPEEX_MAX_CALLBACKS];
|
||||
|
||||
SpeexCallback user_callback;
|
||||
|
||||
/*Vocoder data*/
|
||||
spx_word16_t voc_m1;
|
||||
spx_word32_t voc_m2;
|
||||
spx_word16_t voc_mean;
|
||||
int voc_offset;
|
||||
|
||||
int dtx_enabled;
|
||||
int isWideband; /**< Is this used as part of the embedded wideband codec */
|
||||
int highpass_enabled; /**< Is the input filter enabled */
|
||||
} DecState;
|
||||
|
||||
/** Initializes encoder state*/
|
||||
void *nb_encoder_init(const SpeexMode *m);
|
||||
|
||||
/** De-allocates encoder state resources*/
|
||||
void nb_encoder_destroy(void *state);
|
||||
|
||||
/** Encodes one frame*/
|
||||
int nb_encode(void *state, void *in, SpeexBits *bits);
|
||||
|
||||
|
||||
/** Initializes decoder state*/
|
||||
void *nb_decoder_init(const SpeexMode *m);
|
||||
|
||||
/** De-allocates decoder state resources*/
|
||||
void nb_decoder_destroy(void *state);
|
||||
|
||||
/** Decodes one frame*/
|
||||
int nb_decode(void *state, SpeexBits *bits, void *out);
|
||||
|
||||
/** ioctl-like function for controlling a narrowband encoder */
|
||||
int nb_encoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
/** ioctl-like function for controlling a narrowband decoder */
|
||||
int nb_decoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
|
||||
#endif
|
|
@ -1,172 +0,0 @@
|
|||
/* 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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef OS_SUPPORT_CUSTOM
|
||||
#include "os_support_custom.h"
|
||||
#endif
|
||||
|
||||
#include "speex_bind.h"
|
||||
|
||||
|
||||
/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free
|
||||
NOTE: speex_alloc needs to CLEAR THE MEMORY */
|
||||
#ifndef OVERRIDE_SPEEX_ALLOC
|
||||
static SPEEX_INLINE void *speex_alloc (int size)
|
||||
{
|
||||
/* WARNING: this is not equivalent to malloc(). If you want to use malloc()
|
||||
or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise
|
||||
you will experience strange bugs */
|
||||
return calloc(size,1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
|
||||
#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH
|
||||
static SPEEX_INLINE void *speex_alloc_scratch (int size)
|
||||
{
|
||||
/* Scratch space doesn't need to be cleared */
|
||||
return calloc(size,1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */
|
||||
#ifndef OVERRIDE_SPEEX_REALLOC
|
||||
static SPEEX_INLINE void *speex_realloc (void *ptr, int size)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */
|
||||
#ifndef OVERRIDE_SPEEX_FREE
|
||||
static SPEEX_INLINE void speex_free (void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Same as speex_free, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
|
||||
#ifndef OVERRIDE_SPEEX_FREE_SCRATCH
|
||||
static SPEEX_INLINE void speex_free_scratch (void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking */
|
||||
#ifndef OVERRIDE_SPEEX_COPY
|
||||
#define SPEEX_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_SPEEX_MOVE
|
||||
#define SPEEX_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
|
||||
#endif
|
||||
|
||||
/** Set n bytes of memory to value of c, starting at address s */
|
||||
#ifndef OVERRIDE_SPEEX_MEMSET
|
||||
#define SPEEX_MEMSET(dst, c, n) (memset((dst), (c), (n)*sizeof(*(dst))))
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_FATAL
|
||||
static SPEEX_INLINE void _speex_fatal(const char *str, const char *file, int line)
|
||||
{
|
||||
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_WARNING
|
||||
static SPEEX_INLINE void speex_warning(const char *str)
|
||||
{
|
||||
#ifndef DISABLE_WARNINGS
|
||||
fprintf (stderr, "warning: %s\n", str);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_WARNING_INT
|
||||
static SPEEX_INLINE void speex_warning_int(const char *str, int val)
|
||||
{
|
||||
#ifndef DISABLE_WARNINGS
|
||||
fprintf (stderr, "warning: %s %d\n", str, val);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_NOTIFY
|
||||
static SPEEX_INLINE void speex_notify(const char *str)
|
||||
{
|
||||
#ifndef DISABLE_NOTIFICATIONS
|
||||
fprintf (stderr, "notification: %s\n", str);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_PUTC
|
||||
/** Speex wrapper for putc */
|
||||
static SPEEX_INLINE void _speex_putc(int ch, void *file)
|
||||
{
|
||||
FILE *f = (FILE *)file;
|
||||
fprintf(f, "%c", ch);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__);
|
||||
#define speex_assert(cond) {if (!(cond)) {speex_fatal("assertion failed: " #cond);}}
|
||||
|
||||
#ifndef RELEASE
|
||||
static SPEEX_INLINE void print_vec(float *vec, int len, char *name)
|
||||
{
|
||||
int i;
|
||||
printf ("%s ", name);
|
||||
for (i=0;i<len;i++)
|
||||
printf (" %f", vec[i]);
|
||||
printf ("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,379 +0,0 @@
|
|||
/* Copyright (C) 2005 Jean-Marc Valin */
|
||||
/**
|
||||
@file pseudofloat.h
|
||||
@brief Pseudo-floating point
|
||||
* This header file provides a lightweight floating point type for
|
||||
* use on fixed-point platforms when a large dynamic range is
|
||||
* required. The new type is not compatible with the 32-bit IEEE format,
|
||||
* it is not even remotely as accurate as 32-bit floats, and is not
|
||||
* even guaranteed to produce even remotely correct results for code
|
||||
* other than Speex. It makes all kinds of shortcuts that are acceptable
|
||||
* for Speex, but may not be acceptable for your application. You're
|
||||
* quite welcome to reuse this code and improve it, but don't assume
|
||||
* it works out of the box. Most likely, it doesn't.
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef PSEUDOFLOAT_H
|
||||
#define PSEUDOFLOAT_H
|
||||
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
#include "math_approx.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
typedef struct {
|
||||
spx_int16_t m;
|
||||
spx_int16_t e;
|
||||
} spx_float_t;
|
||||
|
||||
static const spx_float_t FLOAT_ZERO = {0,0};
|
||||
static const spx_float_t FLOAT_ONE = {16384,-14};
|
||||
static const spx_float_t FLOAT_HALF = {16384,-15};
|
||||
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
static inline spx_float_t PSEUDOFLOAT(spx_int32_t x)
|
||||
{
|
||||
int e=0;
|
||||
int sign=0;
|
||||
if (x<0)
|
||||
{
|
||||
sign = 1;
|
||||
x = -x;
|
||||
}
|
||||
if (x==0)
|
||||
{
|
||||
spx_float_t r = {0,0};
|
||||
return r;
|
||||
}
|
||||
e = spx_ilog2(ABS32(x))-14;
|
||||
x = VSHR32(x, e);
|
||||
if (sign)
|
||||
{
|
||||
spx_float_t r;
|
||||
r.m = -x;
|
||||
r.e = e;
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
spx_float_t r;
|
||||
r.m = x;
|
||||
r.e = e;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline spx_float_t FLOAT_ADD(spx_float_t a, spx_float_t b)
|
||||
{
|
||||
spx_float_t r;
|
||||
if (a.m==0)
|
||||
return b;
|
||||
else if (b.m==0)
|
||||
return a;
|
||||
if ((a).e > (b).e)
|
||||
{
|
||||
r.m = ((a).m>>1) + ((b).m>>MIN(15,(a).e-(b).e+1));
|
||||
r.e = (a).e+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
r.m = ((b).m>>1) + ((a).m>>MIN(15,(b).e-(a).e+1));
|
||||
r.e = (b).e+1;
|
||||
}
|
||||
if (r.m>0)
|
||||
{
|
||||
if (r.m<16384)
|
||||
{
|
||||
r.m<<=1;
|
||||
r.e-=1;
|
||||
}
|
||||
} else {
|
||||
if (r.m>-16384)
|
||||
{
|
||||
r.m<<=1;
|
||||
r.e-=1;
|
||||
}
|
||||
}
|
||||
/*printf ("%f + %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline spx_float_t FLOAT_SUB(spx_float_t a, spx_float_t b)
|
||||
{
|
||||
spx_float_t r;
|
||||
if (a.m==0)
|
||||
return b;
|
||||
else if (b.m==0)
|
||||
return a;
|
||||
if ((a).e > (b).e)
|
||||
{
|
||||
r.m = ((a).m>>1) - ((b).m>>MIN(15,(a).e-(b).e+1));
|
||||
r.e = (a).e+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
r.m = ((a).m>>MIN(15,(b).e-(a).e+1)) - ((b).m>>1);
|
||||
r.e = (b).e+1;
|
||||
}
|
||||
if (r.m>0)
|
||||
{
|
||||
if (r.m<16384)
|
||||
{
|
||||
r.m<<=1;
|
||||
r.e-=1;
|
||||
}
|
||||
} else {
|
||||
if (r.m>-16384)
|
||||
{
|
||||
r.m<<=1;
|
||||
r.e-=1;
|
||||
}
|
||||
}
|
||||
/*printf ("%f + %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline int FLOAT_LT(spx_float_t a, spx_float_t b)
|
||||
{
|
||||
if (a.m==0)
|
||||
return b.m>0;
|
||||
else if (b.m==0)
|
||||
return a.m<0;
|
||||
if ((a).e > (b).e)
|
||||
return ((a).m>>1) < ((b).m>>MIN(15,(a).e-(b).e+1));
|
||||
else
|
||||
return ((b).m>>1) > ((a).m>>MIN(15,(b).e-(a).e+1));
|
||||
|
||||
}
|
||||
|
||||
static inline int FLOAT_GT(spx_float_t a, spx_float_t b)
|
||||
{
|
||||
return FLOAT_LT(b,a);
|
||||
}
|
||||
|
||||
static inline spx_float_t FLOAT_MULT(spx_float_t a, spx_float_t b)
|
||||
{
|
||||
spx_float_t r;
|
||||
r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15);
|
||||
r.e = (a).e+(b).e+15;
|
||||
if (r.m>0)
|
||||
{
|
||||
if (r.m<16384)
|
||||
{
|
||||
r.m<<=1;
|
||||
r.e-=1;
|
||||
}
|
||||
} else {
|
||||
if (r.m>-16384)
|
||||
{
|
||||
r.m<<=1;
|
||||
r.e-=1;
|
||||
}
|
||||
}
|
||||
/*printf ("%f * %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline spx_float_t FLOAT_AMULT(spx_float_t a, spx_float_t b)
|
||||
{
|
||||
spx_float_t r;
|
||||
r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15);
|
||||
r.e = (a).e+(b).e+15;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static inline spx_float_t FLOAT_SHL(spx_float_t a, int b)
|
||||
{
|
||||
spx_float_t r;
|
||||
r.m = a.m;
|
||||
r.e = a.e+b;
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline spx_int16_t FLOAT_EXTRACT16(spx_float_t a)
|
||||
{
|
||||
if (a.e<0)
|
||||
return EXTRACT16((EXTEND32(a.m)+(EXTEND32(1)<<(-a.e-1)))>>-a.e);
|
||||
else
|
||||
return a.m<<a.e;
|
||||
}
|
||||
|
||||
static inline spx_int32_t FLOAT_EXTRACT32(spx_float_t a)
|
||||
{
|
||||
if (a.e<0)
|
||||
return (EXTEND32(a.m)+(EXTEND32(1)<<(-a.e-1)))>>-a.e;
|
||||
else
|
||||
return EXTEND32(a.m)<<a.e;
|
||||
}
|
||||
|
||||
static inline spx_int32_t FLOAT_MUL32(spx_float_t a, spx_word32_t b)
|
||||
{
|
||||
return VSHR32(MULT16_32_Q15(a.m, b),-a.e-15);
|
||||
}
|
||||
|
||||
static inline spx_float_t FLOAT_MUL32U(spx_word32_t a, spx_word32_t b)
|
||||
{
|
||||
int e1, e2;
|
||||
spx_float_t r;
|
||||
if (a==0 || b==0)
|
||||
{
|
||||
return FLOAT_ZERO;
|
||||
}
|
||||
e1 = spx_ilog2(ABS32(a));
|
||||
a = VSHR32(a, e1-14);
|
||||
e2 = spx_ilog2(ABS32(b));
|
||||
b = VSHR32(b, e2-14);
|
||||
r.m = MULT16_16_Q15(a,b);
|
||||
r.e = e1+e2-13;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Do NOT attempt to divide by a negative number */
|
||||
static inline spx_float_t FLOAT_DIV32_FLOAT(spx_word32_t a, spx_float_t b)
|
||||
{
|
||||
int e=0;
|
||||
spx_float_t r;
|
||||
if (a==0)
|
||||
{
|
||||
return FLOAT_ZERO;
|
||||
}
|
||||
e = spx_ilog2(ABS32(a))-spx_ilog2(b.m-1)-15;
|
||||
a = VSHR32(a, e);
|
||||
if (ABS32(a)>=SHL32(EXTEND32(b.m-1),15))
|
||||
{
|
||||
a >>= 1;
|
||||
e++;
|
||||
}
|
||||
r.m = DIV32_16(a,b.m);
|
||||
r.e = e-b.e;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* Do NOT attempt to divide by a negative number */
|
||||
static inline spx_float_t FLOAT_DIV32(spx_word32_t a, spx_word32_t b)
|
||||
{
|
||||
int e0=0,e=0;
|
||||
spx_float_t r;
|
||||
if (a==0)
|
||||
{
|
||||
return FLOAT_ZERO;
|
||||
}
|
||||
if (b>32767)
|
||||
{
|
||||
e0 = spx_ilog2(b)-14;
|
||||
b = VSHR32(b, e0);
|
||||
e0 = -e0;
|
||||
}
|
||||
e = spx_ilog2(ABS32(a))-spx_ilog2(b-1)-15;
|
||||
a = VSHR32(a, e);
|
||||
if (ABS32(a)>=SHL32(EXTEND32(b-1),15))
|
||||
{
|
||||
a >>= 1;
|
||||
e++;
|
||||
}
|
||||
e += e0;
|
||||
r.m = DIV32_16(a,b);
|
||||
r.e = e;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Do NOT attempt to divide by a negative number */
|
||||
static inline spx_float_t FLOAT_DIVU(spx_float_t a, spx_float_t b)
|
||||
{
|
||||
int e=0;
|
||||
spx_int32_t num;
|
||||
spx_float_t r;
|
||||
if (b.m<=0)
|
||||
{
|
||||
speex_warning_int("Attempted to divide by", b.m);
|
||||
return FLOAT_ONE;
|
||||
}
|
||||
num = a.m;
|
||||
a.m = ABS16(a.m);
|
||||
while (a.m >= b.m)
|
||||
{
|
||||
e++;
|
||||
a.m >>= 1;
|
||||
}
|
||||
num = num << (15-e);
|
||||
r.m = DIV32_16(num,b.m);
|
||||
r.e = a.e-b.e-15+e;
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline spx_float_t FLOAT_SQRT(spx_float_t a)
|
||||
{
|
||||
spx_float_t r;
|
||||
spx_int32_t m;
|
||||
m = SHL32(EXTEND32(a.m), 14);
|
||||
r.e = a.e - 14;
|
||||
if (r.e & 1)
|
||||
{
|
||||
r.e -= 1;
|
||||
m <<= 1;
|
||||
}
|
||||
r.e >>= 1;
|
||||
r.m = spx_sqrt(m);
|
||||
return r;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define spx_float_t float
|
||||
#define FLOAT_ZERO 0.f
|
||||
#define FLOAT_ONE 1.f
|
||||
#define FLOAT_HALF 0.5f
|
||||
#define PSEUDOFLOAT(x) (x)
|
||||
#define FLOAT_MULT(a,b) ((a)*(b))
|
||||
#define FLOAT_AMULT(a,b) ((a)*(b))
|
||||
#define FLOAT_MUL32(a,b) ((a)*(b))
|
||||
#define FLOAT_DIV32(a,b) ((a)/(b))
|
||||
#define FLOAT_EXTRACT16(a) (a)
|
||||
#define FLOAT_EXTRACT32(a) (a)
|
||||
#define FLOAT_ADD(a,b) ((a)+(b))
|
||||
#define FLOAT_SUB(a,b) ((a)-(b))
|
||||
#define REALFLOAT(x) (x)
|
||||
#define FLOAT_DIV32_FLOAT(a,b) ((a)/(b))
|
||||
#define FLOAT_MUL32U(a,b) ((a)*(b))
|
||||
#define FLOAT_SHL(a,b) (a)
|
||||
#define FLOAT_LT(a,b) ((a)<(b))
|
||||
#define FLOAT_GT(a,b) ((a)>(b))
|
||||
#define FLOAT_DIVU(a,b) ((a)/(b))
|
||||
#define FLOAT_SQRT(a) (spx_sqrt(a))
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,385 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: quant_lsp.c
|
||||
LSP vector quantization
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "quant_lsp.h"
|
||||
#include "os_support.h"
|
||||
#include <math.h>
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
#ifdef BFIN_ASM
|
||||
#include "quant_lsp_bfin.h"
|
||||
#endif
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
#define LSP_LINEAR(i) (SHL16(i+1,11))
|
||||
#define LSP_LINEAR_HIGH(i) (ADD16(MULT16_16_16(i,2560),6144))
|
||||
#define LSP_DIV_256(x) (SHL16((spx_word16_t)x, 5))
|
||||
#define LSP_DIV_512(x) (SHL16((spx_word16_t)x, 4))
|
||||
#define LSP_DIV_1024(x) (SHL16((spx_word16_t)x, 3))
|
||||
#define LSP_PI 25736
|
||||
|
||||
#else
|
||||
|
||||
#define LSP_LINEAR(i) (.25*(i)+.25)
|
||||
#define LSP_LINEAR_HIGH(i) (.3125*(i)+.75)
|
||||
#define LSP_SCALE 256.
|
||||
#define LSP_DIV_256(x) (0.0039062*(x))
|
||||
#define LSP_DIV_512(x) (0.0019531*(x))
|
||||
#define LSP_DIV_1024(x) (0.00097656*(x))
|
||||
#define LSP_PI M_PI
|
||||
|
||||
#endif
|
||||
|
||||
static void compute_quant_weights(spx_lsp_t *qlsp, spx_word16_t *quant_weight, int order)
|
||||
{
|
||||
int i;
|
||||
spx_word16_t tmp1, tmp2;
|
||||
for (i=0;i<order;i++)
|
||||
{
|
||||
if (i==0)
|
||||
tmp1 = qlsp[i];
|
||||
else
|
||||
tmp1 = qlsp[i]-qlsp[i-1];
|
||||
if (i==order-1)
|
||||
tmp2 = LSP_PI-qlsp[i];
|
||||
else
|
||||
tmp2 = qlsp[i+1]-qlsp[i];
|
||||
if (tmp2<tmp1)
|
||||
tmp1 = tmp2;
|
||||
#ifdef FIXED_POINT
|
||||
quant_weight[i] = DIV32_16(81920,ADD16(300,tmp1));
|
||||
#else
|
||||
quant_weight[i] = 10/(.04+tmp1);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Note: x is modified*/
|
||||
#ifndef OVERRIDE_LSP_QUANT
|
||||
static int lsp_quant(spx_word16_t *x, const signed char *cdbk, int nbVec, int nbDim)
|
||||
{
|
||||
int i,j;
|
||||
spx_word32_t dist;
|
||||
spx_word16_t tmp;
|
||||
spx_word32_t best_dist=VERY_LARGE32;
|
||||
int best_id=0;
|
||||
const signed char *ptr=cdbk;
|
||||
for (i=0;i<nbVec;i++)
|
||||
{
|
||||
dist=0;
|
||||
for (j=0;j<nbDim;j++)
|
||||
{
|
||||
tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));
|
||||
dist=MAC16_16(dist,tmp,tmp);
|
||||
}
|
||||
if (dist<best_dist)
|
||||
{
|
||||
best_dist=dist;
|
||||
best_id=i;
|
||||
}
|
||||
}
|
||||
|
||||
for (j=0;j<nbDim;j++)
|
||||
x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
|
||||
|
||||
return best_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note: x is modified*/
|
||||
#ifndef OVERRIDE_LSP_WEIGHT_QUANT
|
||||
static int lsp_weight_quant(spx_word16_t *x, spx_word16_t *weight, const signed char *cdbk, int nbVec, int nbDim)
|
||||
{
|
||||
int i,j;
|
||||
spx_word32_t dist;
|
||||
spx_word16_t tmp;
|
||||
spx_word32_t best_dist=VERY_LARGE32;
|
||||
int best_id=0;
|
||||
const signed char *ptr=cdbk;
|
||||
for (i=0;i<nbVec;i++)
|
||||
{
|
||||
dist=0;
|
||||
for (j=0;j<nbDim;j++)
|
||||
{
|
||||
tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));
|
||||
dist=MAC16_32_Q15(dist,weight[j],MULT16_16(tmp,tmp));
|
||||
}
|
||||
if (dist<best_dist)
|
||||
{
|
||||
best_dist=dist;
|
||||
best_id=i;
|
||||
}
|
||||
}
|
||||
|
||||
for (j=0;j<nbDim;j++)
|
||||
x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
|
||||
return best_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
int id;
|
||||
spx_word16_t quant_weight[10];
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i];
|
||||
|
||||
compute_quant_weights(qlsp, quant_weight, order);
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));
|
||||
|
||||
#ifndef FIXED_POINT
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i] = LSP_SCALE*qlsp[i];
|
||||
#endif
|
||||
id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]*=2;
|
||||
|
||||
id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
for (i=0;i<5;i++)
|
||||
qlsp[i]*=2;
|
||||
|
||||
id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
for (i=5;i<10;i++)
|
||||
qlsp[i]*=2;
|
||||
|
||||
id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=PSHR16(qlsp[i],2);
|
||||
#else
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=qlsp[i] * .00097656;
|
||||
#endif
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i]-qlsp[i];
|
||||
}
|
||||
|
||||
void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i, id;
|
||||
for (i=0;i<order;i++)
|
||||
lsp[i]=LSP_LINEAR(i);
|
||||
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<10;i++)
|
||||
lsp[i] = ADD32(lsp[i], LSP_DIV_256(cdbk_nb[id*10+i]));
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<5;i++)
|
||||
lsp[i] = ADD16(lsp[i], LSP_DIV_512(cdbk_nb_low1[id*5+i]));
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<5;i++)
|
||||
lsp[i] = ADD32(lsp[i], LSP_DIV_1024(cdbk_nb_low2[id*5+i]));
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<5;i++)
|
||||
lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_512(cdbk_nb_high1[id*5+i]));
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<5;i++)
|
||||
lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_1024(cdbk_nb_high2[id*5+i]));
|
||||
}
|
||||
|
||||
|
||||
void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
int id;
|
||||
spx_word16_t quant_weight[10];
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i];
|
||||
|
||||
compute_quant_weights(qlsp, quant_weight, order);
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));
|
||||
#ifndef FIXED_POINT
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=qlsp[i]*LSP_SCALE;
|
||||
#endif
|
||||
id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]*=2;
|
||||
|
||||
id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i] = PSHR16(qlsp[i],1);
|
||||
#else
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i] = qlsp[i]*0.0019531;
|
||||
#endif
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i]-qlsp[i];
|
||||
}
|
||||
|
||||
void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i, id;
|
||||
for (i=0;i<order;i++)
|
||||
lsp[i]=LSP_LINEAR(i);
|
||||
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<10;i++)
|
||||
lsp[i] += LSP_DIV_256(cdbk_nb[id*10+i]);
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<5;i++)
|
||||
lsp[i] += LSP_DIV_512(cdbk_nb_low1[id*5+i]);
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<5;i++)
|
||||
lsp[i+5] += LSP_DIV_512(cdbk_nb_high1[id*5+i]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
|
||||
{
|
||||
speex_fatal("Wideband and Ultra-wideband are disabled");
|
||||
}
|
||||
void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
{
|
||||
speex_fatal("Wideband and Ultra-wideband are disabled");
|
||||
}
|
||||
#else
|
||||
extern const signed char high_lsp_cdbk[];
|
||||
extern const signed char high_lsp_cdbk2[];
|
||||
|
||||
|
||||
void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
int id;
|
||||
spx_word16_t quant_weight[10];
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i];
|
||||
|
||||
compute_quant_weights(qlsp, quant_weight, order);
|
||||
|
||||
/* quant_weight[0] = 10/(qlsp[1]-qlsp[0]);
|
||||
quant_weight[order-1] = 10/(qlsp[order-1]-qlsp[order-2]);
|
||||
for (i=1;i<order-1;i++)
|
||||
{
|
||||
tmp1 = 10/(qlsp[i]-qlsp[i-1]);
|
||||
tmp2 = 10/(qlsp[i+1]-qlsp[i]);
|
||||
quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
|
||||
}*/
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=SUB16(qlsp[i],LSP_LINEAR_HIGH(i));
|
||||
#ifndef FIXED_POINT
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i] = qlsp[i]*LSP_SCALE;
|
||||
#endif
|
||||
id = lsp_quant(qlsp, high_lsp_cdbk, 64, order);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]*=2;
|
||||
|
||||
id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i] = PSHR16(qlsp[i],1);
|
||||
#else
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i] = qlsp[i]*0.0019531;
|
||||
#endif
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i]-qlsp[i];
|
||||
}
|
||||
|
||||
void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
{
|
||||
|
||||
int i, id;
|
||||
for (i=0;i<order;i++)
|
||||
lsp[i]=LSP_LINEAR_HIGH(i);
|
||||
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<order;i++)
|
||||
lsp[i] += LSP_DIV_256(high_lsp_cdbk[id*order+i]);
|
||||
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<order;i++)
|
||||
lsp[i] += LSP_DIV_512(high_lsp_cdbk2[id*order+i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file quant_lsp.h
|
||||
@brief LSP vector quantization
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef QUANT_LSP_H
|
||||
#define QUANT_LSP_H
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "arch.h"
|
||||
|
||||
#define MAX_LSP_SIZE 20
|
||||
|
||||
#define NB_CDBK_SIZE 64
|
||||
#define NB_CDBK_SIZE_LOW1 64
|
||||
#define NB_CDBK_SIZE_LOW2 64
|
||||
#define NB_CDBK_SIZE_HIGH1 64
|
||||
#define NB_CDBK_SIZE_HIGH2 64
|
||||
|
||||
/*Narrowband codebooks*/
|
||||
extern const signed char cdbk_nb[];
|
||||
extern const signed char cdbk_nb_low1[];
|
||||
extern const signed char cdbk_nb_low2[];
|
||||
extern const signed char cdbk_nb_high1[];
|
||||
extern const signed char cdbk_nb_high2[];
|
||||
|
||||
/* Quantizes narrowband LSPs with 30 bits */
|
||||
void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
|
||||
|
||||
/* Decodes quantized narrowband LSPs */
|
||||
void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits);
|
||||
|
||||
/* Quantizes low bit-rate narrowband LSPs with 18 bits */
|
||||
void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
|
||||
|
||||
/* Decodes quantized low bit-rate narrowband LSPs */
|
||||
void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits);
|
||||
|
||||
/* Quantizes high-band LSPs with 12 bits */
|
||||
void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
|
||||
|
||||
/* Decodes high-band LSPs */
|
||||
void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits);
|
||||
|
||||
#endif
|
|
@ -1,165 +0,0 @@
|
|||
/* Copyright (C) 2006 David Rowe */
|
||||
/**
|
||||
@file quant_lsp_bfin.h
|
||||
@author David Rowe
|
||||
@brief Various compatibility routines for Speex (Blackfin version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define OVERRIDE_LSP_QUANT
|
||||
#ifdef OVERRIDE_LSP_QUANT
|
||||
|
||||
/*
|
||||
Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
|
||||
well tell you all the magic resgister constraints used below
|
||||
for gcc in-line asm.
|
||||
*/
|
||||
|
||||
static int lsp_quant(
|
||||
spx_word16_t *x,
|
||||
const signed char *cdbk,
|
||||
int nbVec,
|
||||
int nbDim
|
||||
)
|
||||
{
|
||||
int j;
|
||||
spx_word32_t best_dist=1<<30;
|
||||
int best_id=0;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
" %0 = 1 (X);\n\t" /* %0: best_dist */
|
||||
" %0 <<= 30;\n\t"
|
||||
" %1 = 0 (X);\n\t" /* %1: best_i */
|
||||
" P2 = %3\n\t" /* P2: ptr to cdbk */
|
||||
" R5 = 0;\n\t" /* R5: best cb entry */
|
||||
|
||||
" R0 = %5;\n\t" /* set up circ addr */
|
||||
" R0 <<= 1;\n\t"
|
||||
" L0 = R0;\n\t"
|
||||
" I0 = %2;\n\t" /* %2: &x[0] */
|
||||
" B0 = %2;\n\t"
|
||||
|
||||
" R2.L = W [I0++];\n\t"
|
||||
" LSETUP (1f, 2f) LC0 = %4;\n\t"
|
||||
"1: R3 = 0;\n\t" /* R3: dist */
|
||||
" LSETUP (3f, 4f) LC1 = %5;\n\t"
|
||||
"3: R1 = B [P2++] (X);\n\t"
|
||||
" R1 <<= 5;\n\t"
|
||||
" R0.L = R2.L - R1.L || R2.L = W [I0++];\n\t"
|
||||
" R0 = R0.L*R0.L;\n\t"
|
||||
"4: R3 = R3 + R0;\n\t"
|
||||
|
||||
" cc =R3<%0;\n\t"
|
||||
" if cc %0=R3;\n\t"
|
||||
" if cc %1=R5;\n\t"
|
||||
"2: R5 += 1;\n\t"
|
||||
" L0 = 0;\n\t"
|
||||
: "=&d" (best_dist), "=&d" (best_id)
|
||||
: "a" (x), "b" (cdbk), "a" (nbVec), "a" (nbDim)
|
||||
: "I0", "P2", "R0", "R1", "R2", "R3", "R5", "L0", "B0", "A0"
|
||||
);
|
||||
|
||||
for (j=0;j<nbDim;j++) {
|
||||
x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
|
||||
}
|
||||
return best_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define OVERRIDE_LSP_WEIGHT_QUANT
|
||||
#ifdef OVERRIDE_LSP_WEIGHT_QUANT
|
||||
|
||||
/*
|
||||
Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
|
||||
well tell you all the magic resgister constraints used below
|
||||
for gcc in-line asm.
|
||||
*/
|
||||
|
||||
static int lsp_weight_quant(
|
||||
spx_word16_t *x,
|
||||
spx_word16_t *weight,
|
||||
const signed char *cdbk,
|
||||
int nbVec,
|
||||
int nbDim
|
||||
)
|
||||
{
|
||||
int j;
|
||||
spx_word32_t best_dist=1<<30;
|
||||
int best_id=0;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
" %0 = 1 (X);\n\t" /* %0: best_dist */
|
||||
" %0 <<= 30;\n\t"
|
||||
" %1 = 0 (X);\n\t" /* %1: best_i */
|
||||
" P2 = %4\n\t" /* P2: ptr to cdbk */
|
||||
" R5 = 0;\n\t" /* R5: best cb entry */
|
||||
|
||||
" R0 = %6;\n\t" /* set up circ addr */
|
||||
" R0 <<= 1;\n\t"
|
||||
" L0 = R0;\n\t"
|
||||
" L1 = R0;\n\t"
|
||||
" I0 = %2;\n\t" /* %2: &x[0] */
|
||||
" I1 = %3;\n\t" /* %3: &weight[0] */
|
||||
" B0 = %2;\n\t"
|
||||
" B1 = %3;\n\t"
|
||||
|
||||
" LSETUP (1f, 2f) LC0 = %5;\n\t"
|
||||
"1: R3 = 0 (X);\n\t" /* R3: dist */
|
||||
" LSETUP (3f, 4f) LC1 = %6;\n\t"
|
||||
"3: R0.L = W [I0++] || R2.L = W [I1++];\n\t"
|
||||
" R1 = B [P2++] (X);\n\t"
|
||||
" R1 <<= 5;\n\t"
|
||||
" R0.L = R0.L - R1.L;\n\t"
|
||||
" R0 = R0.L*R0.L;\n\t"
|
||||
" A1 = R2.L*R0.L (M,IS);\n\t"
|
||||
" A1 = A1 >>> 16;\n\t"
|
||||
" R1 = (A1 += R2.L*R0.H) (IS);\n\t"
|
||||
"4: R3 = R3 + R1;\n\t"
|
||||
|
||||
" cc =R3<%0;\n\t"
|
||||
" if cc %0=R3;\n\t"
|
||||
" if cc %1=R5;\n\t"
|
||||
"2: R5 += 1;\n\t"
|
||||
" L0 = 0;\n\t"
|
||||
" L1 = 0;\n\t"
|
||||
: "=&d" (best_dist), "=&d" (best_id)
|
||||
: "a" (x), "a" (weight), "b" (cdbk), "a" (nbVec), "a" (nbDim)
|
||||
: "I0", "I1", "P2", "R0", "R1", "R2", "R3", "R5", "A1",
|
||||
"L0", "L1", "B0", "B1"
|
||||
);
|
||||
|
||||
for (j=0;j<nbDim;j++) {
|
||||
x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
|
||||
}
|
||||
return best_id;
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -1,128 +0,0 @@
|
|||
/* Copyright (C) 2007-2008 Jean-Marc Valin
|
||||
* Copyright (C) 2008 Thorvald Natvig
|
||||
*/
|
||||
/**
|
||||
@file resample_sse.h
|
||||
@brief Resampler functions (SSE version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define OVERRIDE_INNER_PRODUCT_SINGLE
|
||||
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
|
||||
{
|
||||
int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
for (i=0;i<len;i+=8)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)));
|
||||
}
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
|
||||
static inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
|
||||
int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
__m128 f = _mm_loadu_ps(frac);
|
||||
for(i=0;i<len;i+=2)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)));
|
||||
}
|
||||
sum = _mm_mul_ps(f, sum);
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef _USE_SSE2
|
||||
#include <emmintrin.h>
|
||||
#define OVERRIDE_INNER_PRODUCT_DOUBLE
|
||||
|
||||
static inline double inner_product_double(const float *a, const float *b, unsigned int len)
|
||||
{
|
||||
int i;
|
||||
double ret;
|
||||
__m128d sum = _mm_setzero_pd();
|
||||
__m128 t;
|
||||
for (i=0;i<len;i+=8)
|
||||
{
|
||||
t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
|
||||
t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
}
|
||||
sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum));
|
||||
_mm_store_sd(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
|
||||
static inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
|
||||
int i;
|
||||
double ret;
|
||||
__m128d sum;
|
||||
__m128d sum1 = _mm_setzero_pd();
|
||||
__m128d sum2 = _mm_setzero_pd();
|
||||
__m128 f = _mm_loadu_ps(frac);
|
||||
__m128d f1 = _mm_cvtps_pd(f);
|
||||
__m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f));
|
||||
__m128 t;
|
||||
for(i=0;i<len;i+=2)
|
||||
{
|
||||
t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample));
|
||||
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
|
||||
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
|
||||
t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample));
|
||||
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
|
||||
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
}
|
||||
sum1 = _mm_mul_pd(f1, sum1);
|
||||
sum2 = _mm_mul_pd(f2, sum2);
|
||||
sum = _mm_add_pd(sum1, sum2);
|
||||
sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum));
|
||||
_mm_store_sd(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -1,155 +0,0 @@
|
|||
/* Copyright (C) 2002-2006 Jean-Marc Valin */
|
||||
/**
|
||||
@file sb_celp.h
|
||||
@brief Sub-band CELP mode used for wideband encoding
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SB_CELP_H
|
||||
#define SB_CELP_H
|
||||
|
||||
#include "modes.h"
|
||||
#include <speex/speex_bits.h>
|
||||
#include "nb_celp.h"
|
||||
|
||||
/**Structure representing the full state of the sub-band encoder*/
|
||||
typedef struct SBEncState {
|
||||
const SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */
|
||||
void *st_low; /**< State of the low-band (narrowband) encoder */
|
||||
int full_frame_size; /**< Length of full-band frames*/
|
||||
int frame_size; /**< Length of high-band frames*/
|
||||
int subframeSize; /**< Length of high-band sub-frames*/
|
||||
int nbSubframes; /**< Number of high-band sub-frames*/
|
||||
int windowSize; /**< Length of high-band LPC window*/
|
||||
int lpcSize; /**< Order of high-band LPC analysis */
|
||||
int first; /**< First frame? */
|
||||
spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */
|
||||
spx_word16_t gamma1; /**< Perceptual weighting coef 1 */
|
||||
spx_word16_t gamma2; /**< Perceptual weighting coef 2 */
|
||||
|
||||
char *stack; /**< Temporary allocation stack */
|
||||
spx_word16_t *high; /**< High-band signal (buffer) */
|
||||
spx_word16_t *h0_mem, *h1_mem;
|
||||
|
||||
const spx_word16_t *window; /**< LPC analysis window */
|
||||
const spx_word16_t *lagWindow; /**< Auto-correlation window */
|
||||
spx_lsp_t *old_lsp; /**< LSPs of previous frame */
|
||||
spx_lsp_t *old_qlsp; /**< Quantized LSPs of previous frame */
|
||||
spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */
|
||||
|
||||
spx_mem_t *mem_sp; /**< Synthesis signal memory */
|
||||
spx_mem_t *mem_sp2;
|
||||
spx_mem_t *mem_sw; /**< Perceptual signal memory */
|
||||
spx_word32_t *pi_gain;
|
||||
spx_word16_t *exc_rms;
|
||||
spx_word16_t *innov_rms_save; /**< If non-NULL, innovation is copied here */
|
||||
|
||||
#ifndef DISABLE_VBR
|
||||
float vbr_quality; /**< Quality setting for VBR encoding */
|
||||
int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */
|
||||
spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode (total) */
|
||||
spx_int32_t vbr_max_high; /**< Max bit-rate allowed in VBR mode for the high-band */
|
||||
spx_int32_t abr_enabled; /**< ABR setting (in bps), 0 if off */
|
||||
float abr_drift;
|
||||
float abr_drift2;
|
||||
float abr_count;
|
||||
int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */
|
||||
float relative_quality;
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
||||
int encode_submode;
|
||||
const SpeexSubmode * const *submodes;
|
||||
int submodeID;
|
||||
int submodeSelect;
|
||||
int complexity;
|
||||
spx_int32_t sampling_rate;
|
||||
|
||||
} SBEncState;
|
||||
|
||||
|
||||
/**Structure representing the full state of the sub-band decoder*/
|
||||
typedef struct SBDecState {
|
||||
const SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */
|
||||
void *st_low; /**< State of the low-band (narrowband) encoder */
|
||||
int full_frame_size;
|
||||
int frame_size;
|
||||
int subframeSize;
|
||||
int nbSubframes;
|
||||
int lpcSize;
|
||||
int first;
|
||||
spx_int32_t sampling_rate;
|
||||
int lpc_enh_enabled;
|
||||
|
||||
char *stack;
|
||||
spx_word16_t *g0_mem, *g1_mem;
|
||||
|
||||
spx_word16_t *excBuf;
|
||||
spx_lsp_t *old_qlsp;
|
||||
spx_coef_t *interp_qlpc;
|
||||
|
||||
spx_mem_t *mem_sp;
|
||||
spx_word32_t *pi_gain;
|
||||
spx_word16_t *exc_rms;
|
||||
spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */
|
||||
|
||||
spx_word16_t last_ener;
|
||||
spx_int32_t seed;
|
||||
|
||||
int encode_submode;
|
||||
const SpeexSubmode * const *submodes;
|
||||
int submodeID;
|
||||
} SBDecState;
|
||||
|
||||
|
||||
/**Initializes encoder state*/
|
||||
void *sb_encoder_init(const SpeexMode *m);
|
||||
|
||||
/**De-allocates encoder state resources*/
|
||||
void sb_encoder_destroy(void *state);
|
||||
|
||||
/**Encodes one frame*/
|
||||
int sb_encode(void *state, void *in, SpeexBits *bits);
|
||||
|
||||
|
||||
/**Initializes decoder state*/
|
||||
void *sb_decoder_init(const SpeexMode *m);
|
||||
|
||||
/**De-allocates decoder state resources*/
|
||||
void sb_decoder_destroy(void *state);
|
||||
|
||||
/**Decodes one frame*/
|
||||
int sb_decode(void *state, SpeexBits *bits, void *out);
|
||||
|
||||
int sb_encoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
int sb_decoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
#endif
|
|
@ -1,289 +0,0 @@
|
|||
/* Copyright (C) 2006-2008 CSIRO, Jean-Marc Valin, Xiph.Org Foundation
|
||||
|
||||
File: scal.c
|
||||
Shaped comb-allpass filter for channel decorrelation
|
||||
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
The algorithm implemented here is described in:
|
||||
|
||||
* J.-M. Valin, Perceptually-Motivated Nonlinear Channel Decorrelation For
|
||||
Stereo Acoustic Echo Cancellation, Accepted for Joint Workshop on
|
||||
Handsfree Speech Communication and Microphone Arrays (HSCMA), 2008.
|
||||
http://people.xiph.org/~jm/papers/valin_hscma2008.pdf
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "speex/speex_echo.h"
|
||||
#include "vorbis_psy.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
#include "smallft.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ALLPASS_ORDER 20
|
||||
|
||||
struct SpeexDecorrState_ {
|
||||
int rate;
|
||||
int channels;
|
||||
int frame_size;
|
||||
#ifdef VORBIS_PSYCHO
|
||||
VorbisPsy *psy;
|
||||
struct drft_lookup lookup;
|
||||
float *wola_mem;
|
||||
float *curve;
|
||||
#endif
|
||||
float *vorbis_win;
|
||||
int seed;
|
||||
float *y;
|
||||
|
||||
/* Per-channel stuff */
|
||||
float *buff;
|
||||
float (*ring)[ALLPASS_ORDER];
|
||||
int *ringID;
|
||||
int *order;
|
||||
float *alpha;
|
||||
};
|
||||
|
||||
|
||||
|
||||
EXPORT SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size)
|
||||
{
|
||||
int i, ch;
|
||||
SpeexDecorrState *st = speex_alloc(sizeof(SpeexDecorrState));
|
||||
st->rate = rate;
|
||||
st->channels = channels;
|
||||
st->frame_size = frame_size;
|
||||
#ifdef VORBIS_PSYCHO
|
||||
st->psy = vorbis_psy_init(rate, 2*frame_size);
|
||||
spx_drft_init(&st->lookup, 2*frame_size);
|
||||
st->wola_mem = speex_alloc(frame_size*sizeof(float));
|
||||
st->curve = speex_alloc(frame_size*sizeof(float));
|
||||
#endif
|
||||
st->y = speex_alloc(frame_size*sizeof(float));
|
||||
|
||||
st->buff = speex_alloc(channels*2*frame_size*sizeof(float));
|
||||
st->ringID = speex_alloc(channels*sizeof(int));
|
||||
st->order = speex_alloc(channels*sizeof(int));
|
||||
st->alpha = speex_alloc(channels*sizeof(float));
|
||||
st->ring = speex_alloc(channels*ALLPASS_ORDER*sizeof(float));
|
||||
|
||||
/*FIXME: The +20 is there only as a kludge for ALL_PASS_OLA*/
|
||||
st->vorbis_win = speex_alloc((2*frame_size+20)*sizeof(float));
|
||||
for (i=0;i<2*frame_size;i++)
|
||||
st->vorbis_win[i] = sin(.5*SPEEX_PI* sin(SPEEX_PI*i/(2*frame_size))*sin(SPEEX_PI*i/(2*frame_size)) );
|
||||
st->seed = rand();
|
||||
|
||||
for (ch=0;ch<channels;ch++)
|
||||
{
|
||||
for (i=0;i<ALLPASS_ORDER;i++)
|
||||
st->ring[ch][i] = 0;
|
||||
st->ringID[ch] = 0;
|
||||
st->alpha[ch] = 0;
|
||||
st->order[ch] = 10;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
static float uni_rand(int *seed)
|
||||
{
|
||||
const unsigned int jflone = 0x3f800000;
|
||||
const unsigned int jflmsk = 0x007fffff;
|
||||
union {int i; float f;} ran;
|
||||
*seed = 1664525 * *seed + 1013904223;
|
||||
ran.i = jflone | (jflmsk & *seed);
|
||||
ran.f -= 1.5;
|
||||
return 2*ran.f;
|
||||
}
|
||||
|
||||
static unsigned int irand(int *seed)
|
||||
{
|
||||
*seed = 1664525 * *seed + 1013904223;
|
||||
return ((unsigned int)*seed)>>16;
|
||||
}
|
||||
|
||||
|
||||
EXPORT void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength)
|
||||
{
|
||||
int ch;
|
||||
float amount;
|
||||
|
||||
if (strength<0)
|
||||
strength = 0;
|
||||
if (strength>100)
|
||||
strength = 100;
|
||||
|
||||
amount = .01*strength;
|
||||
for (ch=0;ch<st->channels;ch++)
|
||||
{
|
||||
int i;
|
||||
int N=2*st->frame_size;
|
||||
float beta, beta2;
|
||||
float *x;
|
||||
float max_alpha = 0;
|
||||
|
||||
float *buff;
|
||||
float *ring;
|
||||
int ringID;
|
||||
int order;
|
||||
float alpha;
|
||||
|
||||
buff = st->buff+ch*2*st->frame_size;
|
||||
ring = st->ring[ch];
|
||||
ringID = st->ringID[ch];
|
||||
order = st->order[ch];
|
||||
alpha = st->alpha[ch];
|
||||
|
||||
for (i=0;i<st->frame_size;i++)
|
||||
buff[i] = buff[i+st->frame_size];
|
||||
for (i=0;i<st->frame_size;i++)
|
||||
buff[i+st->frame_size] = in[i*st->channels+ch];
|
||||
|
||||
x = buff+st->frame_size;
|
||||
beta = 1.-.3*amount*amount;
|
||||
if (amount>1)
|
||||
beta = 1-sqrt(.4*amount);
|
||||
else
|
||||
beta = 1-0.63246*amount;
|
||||
if (beta<0)
|
||||
beta = 0;
|
||||
|
||||
beta2 = beta;
|
||||
for (i=0;i<st->frame_size;i++)
|
||||
{
|
||||
st->y[i] = alpha*(x[i-ALLPASS_ORDER+order]-beta*x[i-ALLPASS_ORDER+order-1])*st->vorbis_win[st->frame_size+i+order]
|
||||
+ x[i-ALLPASS_ORDER]*st->vorbis_win[st->frame_size+i]
|
||||
- alpha*(ring[ringID]
|
||||
- beta*ring[ringID+1>=order?0:ringID+1]);
|
||||
ring[ringID++]=st->y[i];
|
||||
st->y[i] *= st->vorbis_win[st->frame_size+i];
|
||||
if (ringID>=order)
|
||||
ringID=0;
|
||||
}
|
||||
order = order+(irand(&st->seed)%3)-1;
|
||||
if (order < 5)
|
||||
order = 5;
|
||||
if (order > 10)
|
||||
order = 10;
|
||||
/*order = 5+(irand(&st->seed)%6);*/
|
||||
max_alpha = pow(.96+.04*(amount-1),order);
|
||||
if (max_alpha > .98/(1.+beta2))
|
||||
max_alpha = .98/(1.+beta2);
|
||||
|
||||
alpha = alpha + .4*uni_rand(&st->seed);
|
||||
if (alpha > max_alpha)
|
||||
alpha = max_alpha;
|
||||
if (alpha < -max_alpha)
|
||||
alpha = -max_alpha;
|
||||
for (i=0;i<ALLPASS_ORDER;i++)
|
||||
ring[i] = 0;
|
||||
ringID = 0;
|
||||
for (i=0;i<st->frame_size;i++)
|
||||
{
|
||||
float tmp = alpha*(x[i-ALLPASS_ORDER+order]-beta*x[i-ALLPASS_ORDER+order-1])*st->vorbis_win[i+order]
|
||||
+ x[i-ALLPASS_ORDER]*st->vorbis_win[i]
|
||||
- alpha*(ring[ringID]
|
||||
- beta*ring[ringID+1>=order?0:ringID+1]);
|
||||
ring[ringID++]=tmp;
|
||||
tmp *= st->vorbis_win[i];
|
||||
if (ringID>=order)
|
||||
ringID=0;
|
||||
st->y[i] += tmp;
|
||||
}
|
||||
|
||||
#ifdef VORBIS_PSYCHO
|
||||
float frame[N];
|
||||
float scale = 1./N;
|
||||
for (i=0;i<2*st->frame_size;i++)
|
||||
frame[i] = buff[i];
|
||||
//float coef = .5*0.78130;
|
||||
float coef = SPEEX_PI*0.075063 * 0.93763 * amount * .8 * 0.707;
|
||||
compute_curve(st->psy, buff, st->curve);
|
||||
for (i=1;i<st->frame_size;i++)
|
||||
{
|
||||
float x1,x2;
|
||||
float gain;
|
||||
do {
|
||||
x1 = uni_rand(&st->seed);
|
||||
x2 = uni_rand(&st->seed);
|
||||
} while (x1*x1+x2*x2 > 1.);
|
||||
gain = coef*sqrt(.1+st->curve[i]);
|
||||
frame[2*i-1] = gain*x1;
|
||||
frame[2*i] = gain*x2;
|
||||
}
|
||||
frame[0] = coef*uni_rand(&st->seed)*sqrt(.1+st->curve[0]);
|
||||
frame[2*st->frame_size-1] = coef*uni_rand(&st->seed)*sqrt(.1+st->curve[st->frame_size-1]);
|
||||
spx_drft_backward(&st->lookup,frame);
|
||||
for (i=0;i<2*st->frame_size;i++)
|
||||
frame[i] *= st->vorbis_win[i];
|
||||
#endif
|
||||
|
||||
for (i=0;i<st->frame_size;i++)
|
||||
{
|
||||
#ifdef VORBIS_PSYCHO
|
||||
float tmp = st->y[i] + frame[i] + st->wola_mem[i];
|
||||
st->wola_mem[i] = frame[i+st->frame_size];
|
||||
#else
|
||||
float tmp = st->y[i];
|
||||
#endif
|
||||
if (tmp>32767)
|
||||
tmp = 32767;
|
||||
if (tmp < -32767)
|
||||
tmp = -32767;
|
||||
out[i*st->channels+ch] = tmp;
|
||||
}
|
||||
|
||||
st->ringID[ch] = ringID;
|
||||
st->order[ch] = order;
|
||||
st->alpha[ch] = alpha;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT void speex_decorrelate_destroy(SpeexDecorrState *st)
|
||||
{
|
||||
#ifdef VORBIS_PSYCHO
|
||||
vorbis_psy_destroy(st->psy);
|
||||
speex_free(st->wola_mem);
|
||||
speex_free(st->curve);
|
||||
#endif
|
||||
speex_free(st->buff);
|
||||
speex_free(st->ring);
|
||||
speex_free(st->ringID);
|
||||
speex_free(st->alpha);
|
||||
speex_free(st->vorbis_win);
|
||||
speex_free(st->order);
|
||||
speex_free(st->y);
|
||||
speex_free(st);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,46 +0,0 @@
|
|||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
|
||||
* by the XIPHOPHORUS Company http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: fft transform
|
||||
last mod: $Id: smallft.h,v 1.3 2003/09/16 18:35:45 jm Exp $
|
||||
|
||||
********************************************************************/
|
||||
/**
|
||||
@file smallft.h
|
||||
@brief Discrete Rotational Fourier Transform (DRFT)
|
||||
*/
|
||||
|
||||
#ifndef _V_SMFT_H_
|
||||
#define _V_SMFT_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Discrete Rotational Fourier Transform lookup */
|
||||
struct drft_lookup{
|
||||
int n;
|
||||
float *trigcache;
|
||||
int *splitcache;
|
||||
};
|
||||
|
||||
extern void spx_drft_forward(struct drft_lookup *l,float *data);
|
||||
extern void spx_drft_backward(struct drft_lookup *l,float *data);
|
||||
extern void spx_drft_init(struct drft_lookup *l,int n);
|
||||
extern void spx_drft_clear(struct drft_lookup *l);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,250 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: speex.c
|
||||
|
||||
Basic Speex 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.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "modes.h"
|
||||
#include <math.h>
|
||||
#include "os_support.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define MAX_IN_SAMPLES 640
|
||||
|
||||
|
||||
|
||||
EXPORT void *speex_encoder_init(const SpeexMode *mode)
|
||||
{
|
||||
return mode->enc_init(mode);
|
||||
}
|
||||
|
||||
EXPORT void *speex_decoder_init(const SpeexMode *mode)
|
||||
{
|
||||
return mode->dec_init(mode);
|
||||
}
|
||||
|
||||
EXPORT void speex_encoder_destroy(void *state)
|
||||
{
|
||||
(*((SpeexMode**)state))->enc_destroy(state);
|
||||
}
|
||||
|
||||
EXPORT void speex_decoder_destroy(void *state)
|
||||
{
|
||||
(*((SpeexMode**)state))->dec_destroy(state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits)
|
||||
{
|
||||
return (*((SpeexMode**)state))->enc(state, in, bits);
|
||||
}
|
||||
|
||||
int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out)
|
||||
{
|
||||
return (*((SpeexMode**)state))->dec(state, bits, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
EXPORT int speex_encode(void *state, float *in, SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
spx_int32_t N;
|
||||
spx_int16_t short_in[MAX_IN_SAMPLES];
|
||||
speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
if (in[i]>32767.f)
|
||||
short_in[i] = 32767;
|
||||
else if (in[i]<-32768.f)
|
||||
short_in[i] = -32768;
|
||||
else
|
||||
short_in[i] = (spx_int16_t)floor(.5+in[i]);
|
||||
}
|
||||
return (*((SpeexMode**)state))->enc(state, short_in, bits);
|
||||
}
|
||||
#endif /* #ifndef DISABLE_FLOAT_API */
|
||||
|
||||
EXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
|
||||
{
|
||||
SpeexMode *mode;
|
||||
mode = *(SpeexMode**)state;
|
||||
return (mode)->enc(state, in, bits);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
EXPORT int speex_decode(void *state, SpeexBits *bits, float *out)
|
||||
{
|
||||
int i, ret;
|
||||
spx_int32_t N;
|
||||
spx_int16_t short_out[MAX_IN_SAMPLES];
|
||||
speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
|
||||
ret = (*((SpeexMode**)state))->dec(state, bits, short_out);
|
||||
for (i=0;i<N;i++)
|
||||
out[i] = short_out[i];
|
||||
return ret;
|
||||
}
|
||||
#endif /* #ifndef DISABLE_FLOAT_API */
|
||||
|
||||
EXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
|
||||
{
|
||||
SpeexMode *mode = *(SpeexMode**)state;
|
||||
return (mode)->dec(state, bits, out);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
EXPORT int speex_encode(void *state, float *in, SpeexBits *bits)
|
||||
{
|
||||
return (*((SpeexMode**)state))->enc(state, in, bits);
|
||||
}
|
||||
|
||||
EXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
spx_int32_t N;
|
||||
float float_in[MAX_IN_SAMPLES];
|
||||
speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
|
||||
for (i=0;i<N;i++)
|
||||
float_in[i] = in[i];
|
||||
return (*((SpeexMode**)state))->enc(state, float_in, bits);
|
||||
}
|
||||
|
||||
EXPORT int speex_decode(void *state, SpeexBits *bits, float *out)
|
||||
{
|
||||
return (*((SpeexMode**)state))->dec(state, bits, out);
|
||||
}
|
||||
|
||||
EXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
|
||||
{
|
||||
int i;
|
||||
spx_int32_t N;
|
||||
float float_out[MAX_IN_SAMPLES];
|
||||
int ret;
|
||||
speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
|
||||
ret = (*((SpeexMode**)state))->dec(state, bits, float_out);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
if (float_out[i]>32767.f)
|
||||
out[i] = 32767;
|
||||
else if (float_out[i]<-32768.f)
|
||||
out[i] = -32768;
|
||||
else
|
||||
out[i] = (spx_int16_t)floor(.5+float_out[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
EXPORT int speex_encoder_ctl(void *state, int request, void *ptr)
|
||||
{
|
||||
return (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
|
||||
}
|
||||
|
||||
EXPORT int speex_decoder_ctl(void *state, int request, void *ptr)
|
||||
{
|
||||
return (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int nb_mode_query(const void *mode, int request, void *ptr)
|
||||
{
|
||||
const SpeexNBMode *m = (const SpeexNBMode*)mode;
|
||||
|
||||
switch (request)
|
||||
{
|
||||
case SPEEX_MODE_FRAME_SIZE:
|
||||
*((int*)ptr)=m->frameSize;
|
||||
break;
|
||||
case SPEEX_SUBMODE_BITS_PER_FRAME:
|
||||
if (*((int*)ptr)==0)
|
||||
*((int*)ptr) = NB_SUBMODE_BITS+1;
|
||||
else if (m->submodes[*((int*)ptr)]==NULL)
|
||||
*((int*)ptr) = -1;
|
||||
else
|
||||
*((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
|
||||
break;
|
||||
default:
|
||||
speex_warning_int("Unknown nb_mode_query request: ", request);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EXPORT int speex_lib_ctl(int request, void *ptr)
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
case SPEEX_LIB_GET_MAJOR_VERSION:
|
||||
*((int*)ptr) = SPEEX_MAJOR_VERSION;
|
||||
break;
|
||||
case SPEEX_LIB_GET_MINOR_VERSION:
|
||||
*((int*)ptr) = SPEEX_MINOR_VERSION;
|
||||
break;
|
||||
case SPEEX_LIB_GET_MICRO_VERSION:
|
||||
*((int*)ptr) = SPEEX_MICRO_VERSION;
|
||||
break;
|
||||
case SPEEX_LIB_GET_EXTRA_VERSION:
|
||||
*((const char**)ptr) = SPEEX_EXTRA_VERSION;
|
||||
break;
|
||||
case SPEEX_LIB_GET_VERSION_STRING:
|
||||
*((const char**)ptr) = SPEEX_VERSION;
|
||||
break;
|
||||
/*case SPEEX_LIB_SET_ALLOC_FUNC:
|
||||
break;
|
||||
case SPEEX_LIB_GET_ALLOC_FUNC:
|
||||
break;
|
||||
case SPEEX_LIB_SET_FREE_FUNC:
|
||||
break;
|
||||
case SPEEX_LIB_GET_FREE_FUNC:
|
||||
break;*/
|
||||
default:
|
||||
speex_warning_int("Unknown wb_mode_query request: ", request);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,424 +0,0 @@
|
|||
/* Copyright (C) 2002-2006 Jean-Marc Valin*/
|
||||
/**
|
||||
@file speex.h
|
||||
@brief Describes the different modes of the codec
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SPEEX_H
|
||||
#define SPEEX_H
|
||||
/** @defgroup Codec Speex encoder and decoder
|
||||
* This is the Speex codec itself.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex/speex_bits.h"
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Values allowed for *ctl() requests */
|
||||
|
||||
/** Set enhancement on/off (decoder only) */
|
||||
#define SPEEX_SET_ENH 0
|
||||
/** Get enhancement state (decoder only) */
|
||||
#define SPEEX_GET_ENH 1
|
||||
|
||||
/*Would be SPEEX_SET_FRAME_SIZE, but it's (currently) invalid*/
|
||||
/** Obtain frame size used by encoder/decoder */
|
||||
#define SPEEX_GET_FRAME_SIZE 3
|
||||
|
||||
/** Set quality value */
|
||||
#define SPEEX_SET_QUALITY 4
|
||||
/** Get current quality setting */
|
||||
/* #define SPEEX_GET_QUALITY 5 -- Doesn't make much sense, does it? */
|
||||
|
||||
/** Set sub-mode to use */
|
||||
#define SPEEX_SET_MODE 6
|
||||
/** Get current sub-mode in use */
|
||||
#define SPEEX_GET_MODE 7
|
||||
|
||||
/** Set low-band sub-mode to use (wideband only)*/
|
||||
#define SPEEX_SET_LOW_MODE 8
|
||||
/** Get current low-band mode in use (wideband only)*/
|
||||
#define SPEEX_GET_LOW_MODE 9
|
||||
|
||||
/** Set high-band sub-mode to use (wideband only)*/
|
||||
#define SPEEX_SET_HIGH_MODE 10
|
||||
/** Get current high-band mode in use (wideband only)*/
|
||||
#define SPEEX_GET_HIGH_MODE 11
|
||||
|
||||
/** Set VBR on (1) or off (0) */
|
||||
#define SPEEX_SET_VBR 12
|
||||
/** Get VBR status (1 for on, 0 for off) */
|
||||
#define SPEEX_GET_VBR 13
|
||||
|
||||
/** Set quality value for VBR encoding (0-10) */
|
||||
#define SPEEX_SET_VBR_QUALITY 14
|
||||
/** Get current quality value for VBR encoding (0-10) */
|
||||
#define SPEEX_GET_VBR_QUALITY 15
|
||||
|
||||
/** Set complexity of the encoder (0-10) */
|
||||
#define SPEEX_SET_COMPLEXITY 16
|
||||
/** Get current complexity of the encoder (0-10) */
|
||||
#define SPEEX_GET_COMPLEXITY 17
|
||||
|
||||
/** Set bit-rate used by the encoder (or lower) */
|
||||
#define SPEEX_SET_BITRATE 18
|
||||
/** Get current bit-rate used by the encoder or decoder */
|
||||
#define SPEEX_GET_BITRATE 19
|
||||
|
||||
/** Define a handler function for in-band Speex request*/
|
||||
#define SPEEX_SET_HANDLER 20
|
||||
|
||||
/** Define a handler function for in-band user-defined request*/
|
||||
#define SPEEX_SET_USER_HANDLER 22
|
||||
|
||||
/** Set sampling rate used in bit-rate computation */
|
||||
#define SPEEX_SET_SAMPLING_RATE 24
|
||||
/** Get sampling rate used in bit-rate computation */
|
||||
#define SPEEX_GET_SAMPLING_RATE 25
|
||||
|
||||
/** Reset the encoder/decoder memories to zero*/
|
||||
#define SPEEX_RESET_STATE 26
|
||||
|
||||
/** Get VBR info (mostly used internally) */
|
||||
#define SPEEX_GET_RELATIVE_QUALITY 29
|
||||
|
||||
/** Set VAD status (1 for on, 0 for off) */
|
||||
#define SPEEX_SET_VAD 30
|
||||
|
||||
/** Get VAD status (1 for on, 0 for off) */
|
||||
#define SPEEX_GET_VAD 31
|
||||
|
||||
/** Set Average Bit-Rate (ABR) to n bits per seconds */
|
||||
#define SPEEX_SET_ABR 32
|
||||
/** Get Average Bit-Rate (ABR) setting (in bps) */
|
||||
#define SPEEX_GET_ABR 33
|
||||
|
||||
/** Set DTX status (1 for on, 0 for off) */
|
||||
#define SPEEX_SET_DTX 34
|
||||
/** Get DTX status (1 for on, 0 for off) */
|
||||
#define SPEEX_GET_DTX 35
|
||||
|
||||
/** Set submode encoding in each frame (1 for yes, 0 for no, setting to no breaks the standard) */
|
||||
#define SPEEX_SET_SUBMODE_ENCODING 36
|
||||
/** Get submode encoding in each frame */
|
||||
#define SPEEX_GET_SUBMODE_ENCODING 37
|
||||
|
||||
/*#define SPEEX_SET_LOOKAHEAD 38*/
|
||||
/** Returns the lookahead used by Speex */
|
||||
#define SPEEX_GET_LOOKAHEAD 39
|
||||
|
||||
/** Sets tuning for packet-loss concealment (expected loss rate) */
|
||||
#define SPEEX_SET_PLC_TUNING 40
|
||||
/** Gets tuning for PLC */
|
||||
#define SPEEX_GET_PLC_TUNING 41
|
||||
|
||||
/** Sets the max bit-rate allowed in VBR mode */
|
||||
#define SPEEX_SET_VBR_MAX_BITRATE 42
|
||||
/** Gets the max bit-rate allowed in VBR mode */
|
||||
#define SPEEX_GET_VBR_MAX_BITRATE 43
|
||||
|
||||
/** Turn on/off input/output high-pass filtering */
|
||||
#define SPEEX_SET_HIGHPASS 44
|
||||
/** Get status of input/output high-pass filtering */
|
||||
#define SPEEX_GET_HIGHPASS 45
|
||||
|
||||
/** Get "activity level" of the last decoded frame, i.e.
|
||||
how much damage we cause if we remove the frame */
|
||||
#define SPEEX_GET_ACTIVITY 47
|
||||
|
||||
|
||||
/* Preserving compatibility:*/
|
||||
/** Equivalent to SPEEX_SET_ENH */
|
||||
#define SPEEX_SET_PF 0
|
||||
/** Equivalent to SPEEX_GET_ENH */
|
||||
#define SPEEX_GET_PF 1
|
||||
|
||||
|
||||
|
||||
|
||||
/* Values allowed for mode queries */
|
||||
/** Query the frame size of a mode */
|
||||
#define SPEEX_MODE_FRAME_SIZE 0
|
||||
|
||||
/** Query the size of an encoded frame for a particular sub-mode */
|
||||
#define SPEEX_SUBMODE_BITS_PER_FRAME 1
|
||||
|
||||
|
||||
|
||||
/** Get major Speex version */
|
||||
#define SPEEX_LIB_GET_MAJOR_VERSION 1
|
||||
/** Get minor Speex version */
|
||||
#define SPEEX_LIB_GET_MINOR_VERSION 3
|
||||
/** Get micro Speex version */
|
||||
#define SPEEX_LIB_GET_MICRO_VERSION 5
|
||||
/** Get extra Speex version */
|
||||
#define SPEEX_LIB_GET_EXTRA_VERSION 7
|
||||
/** Get Speex version string */
|
||||
#define SPEEX_LIB_GET_VERSION_STRING 9
|
||||
|
||||
/*#define SPEEX_LIB_SET_ALLOC_FUNC 10
|
||||
#define SPEEX_LIB_GET_ALLOC_FUNC 11
|
||||
#define SPEEX_LIB_SET_FREE_FUNC 12
|
||||
#define SPEEX_LIB_GET_FREE_FUNC 13
|
||||
|
||||
#define SPEEX_LIB_SET_WARNING_FUNC 14
|
||||
#define SPEEX_LIB_GET_WARNING_FUNC 15
|
||||
#define SPEEX_LIB_SET_ERROR_FUNC 16
|
||||
#define SPEEX_LIB_GET_ERROR_FUNC 17
|
||||
*/
|
||||
|
||||
/** Number of defined modes in Speex */
|
||||
#define SPEEX_NB_MODES 3
|
||||
|
||||
/** modeID for the defined narrowband mode */
|
||||
#define SPEEX_MODEID_NB 0
|
||||
|
||||
/** modeID for the defined wideband mode */
|
||||
#define SPEEX_MODEID_WB 1
|
||||
|
||||
/** modeID for the defined ultra-wideband mode */
|
||||
#define SPEEX_MODEID_UWB 2
|
||||
|
||||
struct SpeexMode;
|
||||
|
||||
|
||||
/* Prototypes for mode function pointers */
|
||||
|
||||
/** Encoder state initialization function */
|
||||
typedef void *(*encoder_init_func)(const struct SpeexMode *mode);
|
||||
|
||||
/** Encoder state destruction function */
|
||||
typedef void (*encoder_destroy_func)(void *st);
|
||||
|
||||
/** Main encoding function */
|
||||
typedef int (*encode_func)(void *state, void *in, SpeexBits *bits);
|
||||
|
||||
/** Function for controlling the encoder options */
|
||||
typedef int (*encoder_ctl_func)(void *state, int request, void *ptr);
|
||||
|
||||
/** Decoder state initialization function */
|
||||
typedef void *(*decoder_init_func)(const struct SpeexMode *mode);
|
||||
|
||||
/** Decoder state destruction function */
|
||||
typedef void (*decoder_destroy_func)(void *st);
|
||||
|
||||
/** Main decoding function */
|
||||
typedef int (*decode_func)(void *state, SpeexBits *bits, void *out);
|
||||
|
||||
/** Function for controlling the decoder options */
|
||||
typedef int (*decoder_ctl_func)(void *state, int request, void *ptr);
|
||||
|
||||
|
||||
/** Query function for a mode */
|
||||
typedef int (*mode_query_func)(const void *mode, int request, void *ptr);
|
||||
|
||||
/** Struct defining a Speex mode */
|
||||
typedef struct SpeexMode {
|
||||
/** Pointer to the low-level mode data */
|
||||
const void *mode;
|
||||
|
||||
/** Pointer to the mode query function */
|
||||
mode_query_func query;
|
||||
|
||||
/** The name of the mode (you should not rely on this to identify the mode)*/
|
||||
const char *modeName;
|
||||
|
||||
/**ID of the mode*/
|
||||
int modeID;
|
||||
|
||||
/**Version number of the bitstream (incremented every time we break
|
||||
bitstream compatibility*/
|
||||
int bitstream_version;
|
||||
|
||||
/** Pointer to encoder initialization function */
|
||||
encoder_init_func enc_init;
|
||||
|
||||
/** Pointer to encoder destruction function */
|
||||
encoder_destroy_func enc_destroy;
|
||||
|
||||
/** Pointer to frame encoding function */
|
||||
encode_func enc;
|
||||
|
||||
/** Pointer to decoder initialization function */
|
||||
decoder_init_func dec_init;
|
||||
|
||||
/** Pointer to decoder destruction function */
|
||||
decoder_destroy_func dec_destroy;
|
||||
|
||||
/** Pointer to frame decoding function */
|
||||
decode_func dec;
|
||||
|
||||
/** ioctl-like requests for encoder */
|
||||
encoder_ctl_func enc_ctl;
|
||||
|
||||
/** ioctl-like requests for decoder */
|
||||
decoder_ctl_func dec_ctl;
|
||||
|
||||
} SpeexMode;
|
||||
|
||||
/**
|
||||
* Returns a handle to a newly created Speex encoder state structure. For now,
|
||||
* the "mode" argument can be &nb_mode or &wb_mode . In the future, more modes
|
||||
* may be added. Note that for now if you have more than one channels to
|
||||
* encode, you need one state per channel.
|
||||
*
|
||||
* @param mode The mode to use (either speex_nb_mode or speex_wb.mode)
|
||||
* @return A newly created encoder state or NULL if state allocation fails
|
||||
*/
|
||||
void *speex_encoder_init(const SpeexMode *mode);
|
||||
|
||||
/** Frees all resources associated to an existing Speex encoder state.
|
||||
* @param state Encoder state to be destroyed */
|
||||
void speex_encoder_destroy(void *state);
|
||||
|
||||
/** Uses an existing encoder state to encode one frame of speech pointed to by
|
||||
"in". The encoded bit-stream is saved in "bits".
|
||||
@param state Encoder state
|
||||
@param in Frame that will be encoded with a +-2^15 range. This data MAY be
|
||||
overwritten by the encoder and should be considered uninitialised
|
||||
after the call.
|
||||
@param bits Bit-stream where the data will be written
|
||||
@return 0 if frame needs not be transmitted (DTX only), 1 otherwise
|
||||
*/
|
||||
int speex_encode(void *state, float *in, SpeexBits *bits);
|
||||
|
||||
/** Uses an existing encoder state to encode one frame of speech pointed to by
|
||||
"in". The encoded bit-stream is saved in "bits".
|
||||
@param state Encoder state
|
||||
@param in Frame that will be encoded with a +-2^15 range
|
||||
@param bits Bit-stream where the data will be written
|
||||
@return 0 if frame needs not be transmitted (DTX only), 1 otherwise
|
||||
*/
|
||||
int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits);
|
||||
|
||||
/** Used like the ioctl function to control the encoder parameters
|
||||
*
|
||||
* @param state Encoder state
|
||||
* @param request ioctl-type request (one of the SPEEX_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
|
||||
*/
|
||||
int speex_encoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
|
||||
/** Returns a handle to a newly created decoder state structure. For now,
|
||||
* the mode argument can be &nb_mode or &wb_mode . In the future, more modes
|
||||
* may be added. Note that for now if you have more than one channels to
|
||||
* decode, you need one state per channel.
|
||||
*
|
||||
* @param mode Speex mode (one of speex_nb_mode or speex_wb_mode)
|
||||
* @return A newly created decoder state or NULL if state allocation fails
|
||||
*/
|
||||
void *speex_decoder_init(const SpeexMode *mode);
|
||||
|
||||
/** Frees all resources associated to an existing decoder state.
|
||||
*
|
||||
* @param state State to be destroyed
|
||||
*/
|
||||
void speex_decoder_destroy(void *state);
|
||||
|
||||
/** Uses an existing decoder state to decode one frame of speech from
|
||||
* bit-stream bits. The output speech is saved written to out.
|
||||
*
|
||||
* @param state Decoder state
|
||||
* @param bits Bit-stream from which to decode the frame (NULL if the packet was lost)
|
||||
* @param out Where to write the decoded frame
|
||||
* @return return status (0 for no error, -1 for end of stream, -2 corrupt stream)
|
||||
*/
|
||||
int speex_decode(void *state, SpeexBits *bits, float *out);
|
||||
|
||||
/** Uses an existing decoder state to decode one frame of speech from
|
||||
* bit-stream bits. The output speech is saved written to out.
|
||||
*
|
||||
* @param state Decoder state
|
||||
* @param bits Bit-stream from which to decode the frame (NULL if the packet was lost)
|
||||
* @param out Where to write the decoded frame
|
||||
* @return return status (0 for no error, -1 for end of stream, -2 corrupt stream)
|
||||
*/
|
||||
int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out);
|
||||
|
||||
/** Used like the ioctl function to control the encoder parameters
|
||||
*
|
||||
* @param state Decoder state
|
||||
* @param request ioctl-type request (one of the SPEEX_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
|
||||
*/
|
||||
int speex_decoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
|
||||
/** Query function for mode information
|
||||
*
|
||||
* @param mode Speex mode
|
||||
* @param request ioctl-type request (one of the SPEEX_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
|
||||
*/
|
||||
int speex_mode_query(const SpeexMode *mode, int request, void *ptr);
|
||||
|
||||
/** Functions for controlling the behavior of libspeex
|
||||
* @param request ioctl-type request (one of the SPEEX_LIB_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
|
||||
*/
|
||||
int speex_lib_ctl(int request, void *ptr);
|
||||
|
||||
/** Default narrowband mode */
|
||||
extern const SpeexMode speex_nb_mode;
|
||||
|
||||
/** Default wideband mode */
|
||||
extern const SpeexMode speex_wb_mode;
|
||||
|
||||
/** Default "ultra-wideband" mode */
|
||||
extern const SpeexMode speex_uwb_mode;
|
||||
|
||||
/** List of all modes available */
|
||||
extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES];
|
||||
|
||||
/** Obtain one of the modes available */
|
||||
const SpeexMode * speex_lib_get_mode (int mode);
|
||||
|
||||
#ifndef WIN32
|
||||
/* We actually override the function in the narrowband case so that we can avoid linking in the wideband stuff */
|
||||
#define speex_lib_get_mode(mode) ((mode)==SPEEX_MODEID_NB ? &speex_nb_mode : speex_lib_get_mode (mode))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
#endif
|
|
@ -1,64 +0,0 @@
|
|||
|
||||
#include "memory.h"
|
||||
#include "speex_bind.h"
|
||||
#include
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void *speex_alloc (int size) {
|
||||
|
||||
uint8_t * mem = (uint8_t*)memalloc(size);
|
||||
for(int i=0;i<size;i++)
|
||||
mem[i]=0;
|
||||
return mem;
|
||||
}
|
||||
|
||||
void *speex_alloc_scratch (int size) {
|
||||
|
||||
return memalloc(size);
|
||||
}
|
||||
|
||||
void *speex_realloc (void *ptr, int size) {
|
||||
|
||||
return memrealloc(ptr,size);
|
||||
}
|
||||
|
||||
void speex_free (void *ptr) {
|
||||
|
||||
memfree(ptr);
|
||||
}
|
||||
|
||||
void speex_free_scratch (void *ptr) {
|
||||
|
||||
memfree(ptr);
|
||||
}
|
||||
|
||||
void _speex_fatal(const char *str, const char *file, int line) {
|
||||
|
||||
_err_print_error("SPEEX ERROR",p_file,p_line,str);
|
||||
}
|
||||
|
||||
void speex_warning(const char *str) {
|
||||
|
||||
_err_print_error("SPEEX WARNING","",0,str);
|
||||
}
|
||||
|
||||
void speex_warning_int(const char *str, int val) {
|
||||
|
||||
_err_print_error("SPEEX WARNING INT","Value",val,str);
|
||||
}
|
||||
|
||||
void speex_notify(const char *str) {
|
||||
|
||||
print_line(str);
|
||||
}
|
||||
|
||||
void _speex_putc(int ch, void *file) {
|
||||
|
||||
// will not putc, no.
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,48 +0,0 @@
|
|||
#ifndef SPEEX_BIND_H
|
||||
#define SPEEX_BIND_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
#define OVERRIDE_SPEEX_ALLOC
|
||||
#define OVERRIDE_SPEEX_ALLOC_SCRATCH
|
||||
#define OVERRIDE_SPEEX_REALLOC
|
||||
#define OVERRIDE_SPEEX_FREE
|
||||
#define OVERRIDE_SPEEX_FREE_SCRATCH
|
||||
#define OVERRIDE_SPEEX_FATAL
|
||||
#define OVERRIDE_SPEEX_WARNING
|
||||
#define OVERRIDE_SPEEX_WARNING_INT
|
||||
#define OVERRIDE_SPEEX_NOTIFY
|
||||
#define OVERRIDE_SPEEX_PUTC
|
||||
|
||||
void *speex_alloc (int size);
|
||||
void *speex_alloc_scratch (int size);
|
||||
void *speex_realloc (void *ptr, int size);
|
||||
void speex_free (void *ptr);
|
||||
void speex_free_scratch (void *ptr);
|
||||
void _speex_fatal(const char *str, const char *file, int line);
|
||||
void speex_warning(const char *str);
|
||||
void speex_warning_int(const char *str, int val);
|
||||
void speex_notify(const char *str);
|
||||
void _speex_putc(int ch, void *file);
|
||||
|
||||
|
||||
*/
|
||||
#define RELEASE
|
||||
#define SPEEX_PI 3.14159265358979323846
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define SPEEX_INLINE __inline
|
||||
#else
|
||||
#define SPEEX_INLINE inline
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SPEEX_BIND_H
|
|
@ -1,174 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file speex_bits.h
|
||||
@brief Handles bit packing/unpacking
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef BITS_H
|
||||
#define BITS_H
|
||||
/** @defgroup SpeexBits SpeexBits: Bit-stream manipulations
|
||||
* This is the structure that holds the bit-stream when encoding or decoding
|
||||
* with Speex. It allows some manipulations as well.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Bit-packing data structure representing (part of) a bit-stream. */
|
||||
typedef struct SpeexBits {
|
||||
char *chars; /**< "raw" data */
|
||||
int nbBits; /**< Total number of bits stored in the stream*/
|
||||
int charPtr; /**< Position of the byte "cursor" */
|
||||
int bitPtr; /**< Position of the bit "cursor" within the current char */
|
||||
int owner; /**< Does the struct "own" the "raw" buffer (member "chars") */
|
||||
int overflow;/**< Set to one if we try to read past the valid data */
|
||||
int buf_size;/**< Allocated size for buffer */
|
||||
int reserved1; /**< Reserved for future use */
|
||||
void *reserved2; /**< Reserved for future use */
|
||||
} SpeexBits;
|
||||
|
||||
/** Initializes and allocates resources for a SpeexBits struct */
|
||||
void speex_bits_init(SpeexBits *bits);
|
||||
|
||||
/** Initializes SpeexBits struct using a pre-allocated buffer*/
|
||||
void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size);
|
||||
|
||||
/** Sets the bits in a SpeexBits struct to use data from an existing buffer (for decoding without copying data) */
|
||||
void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size);
|
||||
|
||||
/** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/
|
||||
void speex_bits_destroy(SpeexBits *bits);
|
||||
|
||||
/** Resets bits to initial value (just after initialization, erasing content)*/
|
||||
void speex_bits_reset(SpeexBits *bits);
|
||||
|
||||
/** Rewind the bit-stream to the beginning (ready for read) without erasing the content */
|
||||
void speex_bits_rewind(SpeexBits *bits);
|
||||
|
||||
/** Initializes the bit-stream from the data in an area of memory */
|
||||
void speex_bits_read_from(SpeexBits *bits, char *bytes, int len);
|
||||
|
||||
/** Append bytes to the bit-stream
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @param bytes pointer to the bytes what will be appended
|
||||
* @param len Number of bytes of append
|
||||
*/
|
||||
void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len);
|
||||
|
||||
/** Write the content of a bit-stream to an area of memory
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @param bytes Memory location where to write the bits
|
||||
* @param max_len Maximum number of bytes to write (i.e. size of the "bytes" buffer)
|
||||
* @return Number of bytes written to the "bytes" buffer
|
||||
*/
|
||||
int speex_bits_write(SpeexBits *bits, char *bytes, int max_len);
|
||||
|
||||
/** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */
|
||||
int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len);
|
||||
|
||||
/** Append bits to the bit-stream
|
||||
* @param bits Bit-stream to operate on
|
||||
* @param data Value to append as integer
|
||||
* @param nbBits number of bits to consider in "data"
|
||||
*/
|
||||
void speex_bits_pack(SpeexBits *bits, int data, int nbBits);
|
||||
|
||||
/** Interpret the next bits in the bit-stream as a signed integer
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @param nbBits Number of bits to interpret
|
||||
* @return A signed integer represented by the bits read
|
||||
*/
|
||||
int speex_bits_unpack_signed(SpeexBits *bits, int nbBits);
|
||||
|
||||
/** Interpret the next bits in the bit-stream as an unsigned integer
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @param nbBits Number of bits to interpret
|
||||
* @return An unsigned integer represented by the bits read
|
||||
*/
|
||||
unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits);
|
||||
|
||||
/** Returns the number of bytes in the bit-stream, including the last one even if it is not "full"
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @return Number of bytes in the stream
|
||||
*/
|
||||
int speex_bits_nbytes(SpeexBits *bits);
|
||||
|
||||
/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @param nbBits Number of bits to look for
|
||||
* @return Value of the bits peeked, interpreted as unsigned
|
||||
*/
|
||||
unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits);
|
||||
|
||||
/** Get the value of the next bit in the stream, without modifying the
|
||||
* "cursor" position
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @return Value of the bit peeked (one bit only)
|
||||
*/
|
||||
int speex_bits_peek(SpeexBits *bits);
|
||||
|
||||
/** Advances the position of the "bit cursor" in the stream
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @param n Number of bits to advance
|
||||
*/
|
||||
void speex_bits_advance(SpeexBits *bits, int n);
|
||||
|
||||
/** Returns the number of bits remaining to be read in a stream
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @return Number of bits that can still be read from the stream
|
||||
*/
|
||||
int speex_bits_remaining(SpeexBits *bits);
|
||||
|
||||
/** Insert a terminator so that the data can be sent as a packet while auto-detecting
|
||||
* the number of frames in each packet
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
*/
|
||||
void speex_bits_insert_terminator(SpeexBits *bits);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* @} */
|
||||
#endif
|
|
@ -1,68 +0,0 @@
|
|||
/* Copyright (C) 2007 Jean-Marc Valin
|
||||
|
||||
File: speex_buffer.h
|
||||
This is a very simple ring buffer implementation. It is not thread-safe
|
||||
so you need to do your own locking.
|
||||
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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 SPEEX_BUFFER_H
|
||||
#define SPEEX_BUFFER_H
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct SpeexBuffer_;
|
||||
typedef struct SpeexBuffer_ SpeexBuffer;
|
||||
|
||||
SpeexBuffer *speex_buffer_init(int size);
|
||||
|
||||
void speex_buffer_destroy(SpeexBuffer *st);
|
||||
|
||||
int speex_buffer_write(SpeexBuffer *st, void *data, int len);
|
||||
|
||||
int speex_buffer_writezeros(SpeexBuffer *st, int len);
|
||||
|
||||
int speex_buffer_read(SpeexBuffer *st, void *data, int len);
|
||||
|
||||
int speex_buffer_get_available(SpeexBuffer *st);
|
||||
|
||||
int speex_buffer_resize(SpeexBuffer *st, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File speex_callbacks.c
|
||||
Callback handling and in-band signalling
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <speex/speex_callbacks.h>
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
EXPORT int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state)
|
||||
{
|
||||
int id;
|
||||
SpeexCallback *callback;
|
||||
/*speex_bits_advance(bits, 5);*/
|
||||
id=speex_bits_unpack_unsigned(bits, 4);
|
||||
callback = callback_list+id;
|
||||
|
||||
if (callback->func)
|
||||
{
|
||||
return callback->func(bits, state, callback->data);
|
||||
} else
|
||||
/*If callback is not registered, skip the right number of bits*/
|
||||
{
|
||||
int adv;
|
||||
if (id<2)
|
||||
adv = 1;
|
||||
else if (id<8)
|
||||
adv = 4;
|
||||
else if (id<10)
|
||||
adv = 8;
|
||||
else if (id<12)
|
||||
adv = 16;
|
||||
else if (id<14)
|
||||
adv = 32;
|
||||
else
|
||||
adv = 64;
|
||||
speex_bits_advance(bits, adv);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
spx_int32_t m;
|
||||
m = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_encoder_ctl(data, SPEEX_SET_MODE, &m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
spx_int32_t m;
|
||||
m = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_encoder_ctl(data, SPEEX_SET_LOW_MODE, &m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
spx_int32_t m;
|
||||
m = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_encoder_ctl(data, SPEEX_SET_HIGH_MODE, &m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_VBR
|
||||
EXPORT int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
spx_int32_t vbr;
|
||||
vbr = speex_bits_unpack_unsigned(bits, 1);
|
||||
speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr);
|
||||
return 0;
|
||||
}
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
||||
EXPORT int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
spx_int32_t enh;
|
||||
enh = speex_bits_unpack_unsigned(bits, 1);
|
||||
speex_decoder_ctl(data, SPEEX_SET_ENH, &enh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_VBR
|
||||
EXPORT int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
float qual;
|
||||
qual = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual);
|
||||
return 0;
|
||||
}
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
||||
EXPORT int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
unsigned char ch;
|
||||
ch = speex_bits_unpack_unsigned(bits, 8);
|
||||
_speex_putc(ch, data);
|
||||
/*printf("speex_std_char_handler ch=%x\n", ch);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Default handler for user callbacks: skip it */
|
||||
EXPORT int speex_default_user_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
int req_size = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_bits_advance(bits, 5+8*req_size);
|
||||
return 0;
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin*/
|
||||
/**
|
||||
@file speex_callbacks.h
|
||||
@brief Describes callback handling and in-band signalling
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SPEEX_CALLBACKS_H
|
||||
#define SPEEX_CALLBACKS_H
|
||||
/** @defgroup SpeexCallbacks Various definitions for Speex callbacks supported by the decoder.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Total number of callbacks */
|
||||
#define SPEEX_MAX_CALLBACKS 16
|
||||
|
||||
/* Describes all the in-band requests */
|
||||
|
||||
/*These are 1-bit requests*/
|
||||
/** Request for perceptual enhancement (1 for on, 0 for off) */
|
||||
#define SPEEX_INBAND_ENH_REQUEST 0
|
||||
/** Reserved */
|
||||
#define SPEEX_INBAND_RESERVED1 1
|
||||
|
||||
/*These are 4-bit requests*/
|
||||
/** Request for a mode change */
|
||||
#define SPEEX_INBAND_MODE_REQUEST 2
|
||||
/** Request for a low mode change */
|
||||
#define SPEEX_INBAND_LOW_MODE_REQUEST 3
|
||||
/** Request for a high mode change */
|
||||
#define SPEEX_INBAND_HIGH_MODE_REQUEST 4
|
||||
/** Request for VBR (1 on, 0 off) */
|
||||
#define SPEEX_INBAND_VBR_QUALITY_REQUEST 5
|
||||
/** Request to be sent acknowledge */
|
||||
#define SPEEX_INBAND_ACKNOWLEDGE_REQUEST 6
|
||||
/** Request for VBR (1 for on, 0 for off) */
|
||||
#define SPEEX_INBAND_VBR_REQUEST 7
|
||||
|
||||
/*These are 8-bit requests*/
|
||||
/** Send a character in-band */
|
||||
#define SPEEX_INBAND_CHAR 8
|
||||
/** Intensity stereo information */
|
||||
#define SPEEX_INBAND_STEREO 9
|
||||
|
||||
/*These are 16-bit requests*/
|
||||
/** Transmit max bit-rate allowed */
|
||||
#define SPEEX_INBAND_MAX_BITRATE 10
|
||||
|
||||
/*These are 32-bit requests*/
|
||||
/** Acknowledge packet reception */
|
||||
#define SPEEX_INBAND_ACKNOWLEDGE 12
|
||||
|
||||
/** Callback function type */
|
||||
typedef int (*speex_callback_func)(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
/** Callback information */
|
||||
typedef struct SpeexCallback {
|
||||
int callback_id; /**< ID associated to the callback */
|
||||
speex_callback_func func; /**< Callback handler function */
|
||||
void *data; /**< Data that will be sent to the handler */
|
||||
void *reserved1; /**< Reserved for future use */
|
||||
int reserved2; /**< Reserved for future use */
|
||||
} SpeexCallback;
|
||||
|
||||
/** Handle in-band request */
|
||||
int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state);
|
||||
|
||||
/** Standard handler for mode request (change mode, no questions asked) */
|
||||
int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
/** Standard handler for high mode request (change high mode, no questions asked) */
|
||||
int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
/** Standard handler for in-band characters (write to stderr) */
|
||||
int speex_std_char_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
/** Default handler for user-defined requests: in this case, just ignore */
|
||||
int speex_default_user_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
|
||||
|
||||
/** Standard handler for low mode request (change low mode, no questions asked) */
|
||||
int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
/** Standard handler for VBR request (Set VBR, no questions asked) */
|
||||
int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
/** Standard handler for enhancer request (Turn enhancer on/off, no questions asked) */
|
||||
int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
/** Standard handler for VBR quality request (Set VBR quality, no questions asked) */
|
||||
int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef __SPEEX_TYPES_H__
|
||||
#define __SPEEX_TYPES_H__
|
||||
|
||||
/* these are filled in by configure */
|
||||
typedef short spx_int16_t;
|
||||
typedef unsigned short spx_uint16_t;
|
||||
typedef int spx_int32_t;
|
||||
typedef unsigned int spx_uint32_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
/* Copyright (C) Jean-Marc Valin */
|
||||
/**
|
||||
@file speex_echo.h
|
||||
@brief Echo cancellation
|
||||
*/
|
||||
/*
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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 SPEEX_ECHO_H
|
||||
#define SPEEX_ECHO_H
|
||||
/** @defgroup SpeexEchoState SpeexEchoState: Acoustic echo canceller
|
||||
* This is the acoustic echo canceller module.
|
||||
* @{
|
||||
*/
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Obtain frame size used by the AEC */
|
||||
#define SPEEX_ECHO_GET_FRAME_SIZE 3
|
||||
|
||||
/** Set sampling rate */
|
||||
#define SPEEX_ECHO_SET_SAMPLING_RATE 24
|
||||
/** Get sampling rate */
|
||||
#define SPEEX_ECHO_GET_SAMPLING_RATE 25
|
||||
|
||||
/* Can't set window sizes */
|
||||
/** Get size of impulse response (int32) */
|
||||
#define SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE 27
|
||||
|
||||
/* Can't set window content */
|
||||
/** Get impulse response (int32[]) */
|
||||
#define SPEEX_ECHO_GET_IMPULSE_RESPONSE 29
|
||||
|
||||
/** Internal echo canceller state. Should never be accessed directly. */
|
||||
struct SpeexEchoState_;
|
||||
|
||||
/** @class SpeexEchoState
|
||||
* This holds the state of the echo canceller. You need one per channel.
|
||||
*/
|
||||
|
||||
/** Internal echo canceller state. Should never be accessed directly. */
|
||||
typedef struct SpeexEchoState_ SpeexEchoState;
|
||||
|
||||
/** Creates a new echo canceller state
|
||||
* @param frame_size Number of samples to process at one time (should correspond to 10-20 ms)
|
||||
* @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms)
|
||||
* @return Newly-created echo canceller state
|
||||
*/
|
||||
SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length);
|
||||
|
||||
/** Creates a new multi-channel echo canceller state
|
||||
* @param frame_size Number of samples to process at one time (should correspond to 10-20 ms)
|
||||
* @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms)
|
||||
* @param nb_mic Number of microphone channels
|
||||
* @param nb_speakers Number of speaker channels
|
||||
* @return Newly-created echo canceller state
|
||||
*/
|
||||
SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_length, int nb_mic, int nb_speakers);
|
||||
|
||||
/** Destroys an echo canceller state
|
||||
* @param st Echo canceller state
|
||||
*/
|
||||
void speex_echo_state_destroy(SpeexEchoState *st);
|
||||
|
||||
/** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added
|
||||
* to playback in this form)
|
||||
*
|
||||
* @param st Echo canceller state
|
||||
* @param rec Signal from the microphone (near end + far end echo)
|
||||
* @param play Signal played to the speaker (received from far end)
|
||||
* @param out Returns near-end signal with echo removed
|
||||
*/
|
||||
void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out);
|
||||
|
||||
/** Performs echo cancellation a frame (deprecated) */
|
||||
void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout);
|
||||
|
||||
/** Perform echo cancellation using internal playback buffer, which is delayed by two frames
|
||||
* to account for the delay introduced by most soundcards (but it could be off!)
|
||||
* @param st Echo canceller state
|
||||
* @param rec Signal from the microphone (near end + far end echo)
|
||||
* @param out Returns near-end signal with echo removed
|
||||
*/
|
||||
void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out);
|
||||
|
||||
/** Let the echo canceller know that a frame was just queued to the soundcard
|
||||
* @param st Echo canceller state
|
||||
* @param play Signal played to the speaker (received from far end)
|
||||
*/
|
||||
void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play);
|
||||
|
||||
/** Reset the echo canceller to its original state
|
||||
* @param st Echo canceller state
|
||||
*/
|
||||
void speex_echo_state_reset(SpeexEchoState *st);
|
||||
|
||||
/** Used like the ioctl function to control the echo canceller parameters
|
||||
*
|
||||
* @param st Echo canceller state
|
||||
* @param request ioctl-type request (one of the SPEEX_ECHO_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown
|
||||
*/
|
||||
int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr);
|
||||
|
||||
|
||||
|
||||
struct SpeexDecorrState_;
|
||||
|
||||
typedef struct SpeexDecorrState_ SpeexDecorrState;
|
||||
|
||||
|
||||
/** Create a state for the channel decorrelation algorithm
|
||||
This is useful for multi-channel echo cancellation only
|
||||
* @param rate Sampling rate
|
||||
* @param channels Number of channels (it's a bit pointless if you don't have at least 2)
|
||||
* @param frame_size Size of the frame to process at ones (counting samples *per* channel)
|
||||
*/
|
||||
SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size);
|
||||
|
||||
/** Remove correlation between the channels by modifying the phase and possibly
|
||||
adding noise in a way that is not (or little) perceptible.
|
||||
* @param st Decorrelator state
|
||||
* @param in Input audio in interleaved format
|
||||
* @param out Result of the decorrelation (out *may* alias in)
|
||||
* @param strength How much alteration of the audio to apply from 0 to 100.
|
||||
*/
|
||||
void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength);
|
||||
|
||||
/** Destroy a Decorrelation state
|
||||
* @param st State to destroy
|
||||
*/
|
||||
void speex_decorrelate_destroy(SpeexDecorrState *st);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @}*/
|
||||
#endif
|
|
@ -1,200 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: speex_header.c
|
||||
Describes the Speex header
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "arch.h"
|
||||
#include <speex/speex_header.h>
|
||||
#include <speex/speex.h>
|
||||
#include "os_support.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/** Convert little endian */
|
||||
static SPEEX_INLINE spx_int32_t le_int(spx_int32_t i)
|
||||
{
|
||||
#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) /* || defined(BIG_ENDIAN_ENABLED) */ )
|
||||
spx_uint32_t ui, ret;
|
||||
ui = i;
|
||||
ret = ui>>24;
|
||||
ret |= (ui>>8)&0x0000ff00;
|
||||
ret |= (ui<<8)&0x00ff0000;
|
||||
ret |= (ui<<24);
|
||||
return ret;
|
||||
#else
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ENDIAN_SWITCH(x) {x=le_int(x);}
|
||||
|
||||
|
||||
/*
|
||||
typedef struct SpeexHeader {
|
||||
char speex_string[8];
|
||||
char speex_version[SPEEX_HEADER_VERSION_LENGTH];
|
||||
int speex_version_id;
|
||||
int header_size;
|
||||
int rate;
|
||||
int mode;
|
||||
int mode_bitstream_version;
|
||||
int nb_channels;
|
||||
int bitrate;
|
||||
int frame_size;
|
||||
int vbr;
|
||||
int frames_per_packet;
|
||||
int extra_headers;
|
||||
int reserved1;
|
||||
int reserved2;
|
||||
} SpeexHeader;
|
||||
*/
|
||||
|
||||
EXPORT void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m)
|
||||
{
|
||||
int i;
|
||||
const char *h="Speex ";
|
||||
/*
|
||||
strncpy(header->speex_string, "Speex ", 8);
|
||||
strncpy(header->speex_version, SPEEX_VERSION, SPEEX_HEADER_VERSION_LENGTH-1);
|
||||
header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0;
|
||||
*/
|
||||
for (i=0;i<8;i++)
|
||||
header->speex_string[i]=h[i];
|
||||
for (i=0;i<SPEEX_HEADER_VERSION_LENGTH-1 && SPEEX_VERSION[i];i++)
|
||||
header->speex_version[i]=SPEEX_VERSION[i];
|
||||
for (;i<SPEEX_HEADER_VERSION_LENGTH;i++)
|
||||
header->speex_version[i]=0;
|
||||
|
||||
header->speex_version_id = 1;
|
||||
header->header_size = sizeof(SpeexHeader);
|
||||
|
||||
header->rate = rate;
|
||||
header->mode = m->modeID;
|
||||
header->mode_bitstream_version = m->bitstream_version;
|
||||
if (m->modeID<0)
|
||||
speex_warning("This mode is meant to be used alone");
|
||||
header->nb_channels = nb_channels;
|
||||
header->bitrate = -1;
|
||||
speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size);
|
||||
header->vbr = 0;
|
||||
|
||||
header->frames_per_packet = 0;
|
||||
header->extra_headers = 0;
|
||||
header->reserved1 = 0;
|
||||
header->reserved2 = 0;
|
||||
}
|
||||
|
||||
EXPORT char *speex_header_to_packet(SpeexHeader *header, int *size)
|
||||
{
|
||||
SpeexHeader *le_header;
|
||||
le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
|
||||
|
||||
SPEEX_COPY(le_header, header, 1);
|
||||
|
||||
/*Make sure everything is now little-endian*/
|
||||
ENDIAN_SWITCH(le_header->speex_version_id);
|
||||
ENDIAN_SWITCH(le_header->header_size);
|
||||
ENDIAN_SWITCH(le_header->rate);
|
||||
ENDIAN_SWITCH(le_header->mode);
|
||||
ENDIAN_SWITCH(le_header->mode_bitstream_version);
|
||||
ENDIAN_SWITCH(le_header->nb_channels);
|
||||
ENDIAN_SWITCH(le_header->bitrate);
|
||||
ENDIAN_SWITCH(le_header->frame_size);
|
||||
ENDIAN_SWITCH(le_header->vbr);
|
||||
ENDIAN_SWITCH(le_header->frames_per_packet);
|
||||
ENDIAN_SWITCH(le_header->extra_headers);
|
||||
|
||||
*size = sizeof(SpeexHeader);
|
||||
return (char *)le_header;
|
||||
}
|
||||
|
||||
EXPORT SpeexHeader *speex_packet_to_header(char *packet, int size)
|
||||
{
|
||||
int i;
|
||||
SpeexHeader *le_header;
|
||||
const char *h = "Speex ";
|
||||
for (i=0;i<8;i++)
|
||||
if (packet[i]!=h[i])
|
||||
{
|
||||
speex_notify("This doesn't look like a Speex file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*FIXME: Do we allow larger headers?*/
|
||||
if (size < (int)sizeof(SpeexHeader))
|
||||
{
|
||||
speex_notify("Speex header too small");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
|
||||
|
||||
SPEEX_COPY(le_header, (SpeexHeader*)packet, 1);
|
||||
|
||||
/*Make sure everything is converted correctly from little-endian*/
|
||||
ENDIAN_SWITCH(le_header->speex_version_id);
|
||||
ENDIAN_SWITCH(le_header->header_size);
|
||||
ENDIAN_SWITCH(le_header->rate);
|
||||
ENDIAN_SWITCH(le_header->mode);
|
||||
ENDIAN_SWITCH(le_header->mode_bitstream_version);
|
||||
ENDIAN_SWITCH(le_header->nb_channels);
|
||||
ENDIAN_SWITCH(le_header->bitrate);
|
||||
ENDIAN_SWITCH(le_header->frame_size);
|
||||
ENDIAN_SWITCH(le_header->vbr);
|
||||
ENDIAN_SWITCH(le_header->frames_per_packet);
|
||||
ENDIAN_SWITCH(le_header->extra_headers);
|
||||
|
||||
if (le_header->mode >= SPEEX_NB_MODES || le_header->mode < 0)
|
||||
{
|
||||
speex_notify("Invalid mode specified in Speex header");
|
||||
speex_free (le_header);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (le_header->nb_channels>2)
|
||||
le_header->nb_channels = 2;
|
||||
if (le_header->nb_channels<1)
|
||||
le_header->nb_channels = 1;
|
||||
|
||||
return le_header;
|
||||
|
||||
}
|
||||
|
||||
EXPORT void speex_header_free(void *ptr)
|
||||
{
|
||||
speex_free(ptr);
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file speex_header.h
|
||||
@brief Describes the Speex header
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SPEEX_HEADER_H
|
||||
#define SPEEX_HEADER_H
|
||||
/** @defgroup SpeexHeader SpeexHeader: Makes it easy to write/parse an Ogg/Speex header
|
||||
* This is the Speex header for the Ogg encapsulation. You don't need that if you just use RTP.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct SpeexMode;
|
||||
|
||||
/** Length of the Speex header identifier */
|
||||
#define SPEEX_HEADER_STRING_LENGTH 8
|
||||
|
||||
/** Maximum number of characters for encoding the Speex version number in the header */
|
||||
#define SPEEX_HEADER_VERSION_LENGTH 20
|
||||
|
||||
/** Speex header info for file-based formats */
|
||||
typedef struct SpeexHeader {
|
||||
char speex_string[SPEEX_HEADER_STRING_LENGTH]; /**< Identifies a Speex bit-stream, always set to "Speex " */
|
||||
char speex_version[SPEEX_HEADER_VERSION_LENGTH]; /**< Speex version */
|
||||
spx_int32_t speex_version_id; /**< Version for Speex (for checking compatibility) */
|
||||
spx_int32_t header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */
|
||||
spx_int32_t rate; /**< Sampling rate used */
|
||||
spx_int32_t mode; /**< Mode used (0 for narrowband, 1 for wideband) */
|
||||
spx_int32_t mode_bitstream_version; /**< Version ID of the bit-stream */
|
||||
spx_int32_t nb_channels; /**< Number of channels encoded */
|
||||
spx_int32_t bitrate; /**< Bit-rate used */
|
||||
spx_int32_t frame_size; /**< Size of frames */
|
||||
spx_int32_t vbr; /**< 1 for a VBR encoding, 0 otherwise */
|
||||
spx_int32_t frames_per_packet; /**< Number of frames stored per Ogg packet */
|
||||
spx_int32_t extra_headers; /**< Number of additional headers after the comments */
|
||||
spx_int32_t reserved1; /**< Reserved for future use, must be zero */
|
||||
spx_int32_t reserved2; /**< Reserved for future use, must be zero */
|
||||
} SpeexHeader;
|
||||
|
||||
/** Initializes a SpeexHeader using basic information */
|
||||
void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const struct SpeexMode *m);
|
||||
|
||||
/** Creates the header packet from the header itself (mostly involves endianness conversion) */
|
||||
char *speex_header_to_packet(SpeexHeader *header, int *size);
|
||||
|
||||
/** Creates a SpeexHeader from a packet */
|
||||
SpeexHeader *speex_packet_to_header(char *packet, int size);
|
||||
|
||||
/** Frees the memory allocated by either speex_header_to_packet() or speex_packet_to_header() */
|
||||
void speex_header_free(void *ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif
|
|
@ -1,197 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file speex_jitter.h
|
||||
@brief Adaptive jitter buffer for Speex
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SPEEX_JITTER_H
|
||||
#define SPEEX_JITTER_H
|
||||
/** @defgroup JitterBuffer JitterBuffer: Adaptive jitter buffer
|
||||
* This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size
|
||||
* to maintain good quality and low latency.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Generic adaptive jitter buffer state */
|
||||
struct JitterBuffer_;
|
||||
|
||||
/** Generic adaptive jitter buffer state */
|
||||
typedef struct JitterBuffer_ JitterBuffer;
|
||||
|
||||
/** Definition of an incoming packet */
|
||||
typedef struct _JitterBufferPacket JitterBufferPacket;
|
||||
|
||||
/** Definition of an incoming packet */
|
||||
struct _JitterBufferPacket {
|
||||
char *data; /**< Data bytes contained in the packet */
|
||||
spx_uint32_t len; /**< Length of the packet in bytes */
|
||||
spx_uint32_t timestamp; /**< Timestamp for the packet */
|
||||
spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */
|
||||
spx_uint16_t sequence; /**< RTP Sequence number if available (0 otherwise) */
|
||||
spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */
|
||||
};
|
||||
|
||||
/** Packet has been retrieved */
|
||||
#define JITTER_BUFFER_OK 0
|
||||
/** Packet is lost or is late */
|
||||
#define JITTER_BUFFER_MISSING 1
|
||||
/** A "fake" packet is meant to be inserted here to increase buffering */
|
||||
#define JITTER_BUFFER_INSERTION 2
|
||||
/** There was an error in the jitter buffer */
|
||||
#define JITTER_BUFFER_INTERNAL_ERROR -1
|
||||
/** Invalid argument */
|
||||
#define JITTER_BUFFER_BAD_ARGUMENT -2
|
||||
|
||||
|
||||
/** Set minimum amount of extra buffering required (margin) */
|
||||
#define JITTER_BUFFER_SET_MARGIN 0
|
||||
/** Get minimum amount of extra buffering required (margin) */
|
||||
#define JITTER_BUFFER_GET_MARGIN 1
|
||||
/* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */
|
||||
|
||||
/** Get the amount of available packets currently buffered */
|
||||
#define JITTER_BUFFER_GET_AVAILABLE_COUNT 3
|
||||
/** Included because of an early misspelling (will remove in next release) */
|
||||
#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3
|
||||
|
||||
/** Assign a function to destroy unused packet. When setting that, the jitter
|
||||
buffer no longer copies packet data. */
|
||||
#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4
|
||||
/** */
|
||||
#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5
|
||||
|
||||
/** Tell the jitter buffer to only adjust the delay in multiples of the step parameter provided */
|
||||
#define JITTER_BUFFER_SET_DELAY_STEP 6
|
||||
/** */
|
||||
#define JITTER_BUFFER_GET_DELAY_STEP 7
|
||||
|
||||
/** Tell the jitter buffer to only do concealment in multiples of the size parameter provided */
|
||||
#define JITTER_BUFFER_SET_CONCEALMENT_SIZE 8
|
||||
#define JITTER_BUFFER_GET_CONCEALMENT_SIZE 9
|
||||
|
||||
/** Absolute max amount of loss that can be tolerated regardless of the delay. Typical loss
|
||||
should be half of that or less. */
|
||||
#define JITTER_BUFFER_SET_MAX_LATE_RATE 10
|
||||
#define JITTER_BUFFER_GET_MAX_LATE_RATE 11
|
||||
|
||||
/** Equivalent cost of one percent late packet in timestamp units */
|
||||
#define JITTER_BUFFER_SET_LATE_COST 12
|
||||
#define JITTER_BUFFER_GET_LATE_COST 13
|
||||
|
||||
|
||||
/** Initialises jitter buffer
|
||||
*
|
||||
* @param step_size Starting value for the size of concleanment packets and delay
|
||||
adjustment steps. Can be changed at any time using JITTER_BUFFER_SET_DELAY_STEP
|
||||
and JITTER_BUFFER_GET_CONCEALMENT_SIZE.
|
||||
* @return Newly created jitter buffer state
|
||||
*/
|
||||
JitterBuffer *jitter_buffer_init(int step_size);
|
||||
|
||||
/** Restores jitter buffer to its original state
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
*/
|
||||
void jitter_buffer_reset(JitterBuffer *jitter);
|
||||
|
||||
/** Destroys jitter buffer
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
*/
|
||||
void jitter_buffer_destroy(JitterBuffer *jitter);
|
||||
|
||||
/** Put one packet into the jitter buffer
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
* @param packet Incoming packet
|
||||
*/
|
||||
void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet);
|
||||
|
||||
/** Get one packet from the jitter buffer
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
* @param packet Returned packet
|
||||
* @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee)
|
||||
* @param current_timestamp Timestamp for the returned packet
|
||||
*/
|
||||
int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset);
|
||||
|
||||
/** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp.
|
||||
* This is mainly useful for media where a single "frame" can be split into several packets.
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
* @param packet Returned packet
|
||||
*/
|
||||
int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet);
|
||||
|
||||
/** Get pointer timestamp of jitter buffer
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
*/
|
||||
int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter);
|
||||
|
||||
/** Advance by one tick
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
*/
|
||||
void jitter_buffer_tick(JitterBuffer *jitter);
|
||||
|
||||
/** Telling the jitter buffer about the remaining data in the application buffer
|
||||
* @param jitter Jitter buffer state
|
||||
* @param rem Amount of data buffered by the application (timestamp units)
|
||||
*/
|
||||
void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem);
|
||||
|
||||
/** Used like the ioctl function to control the jitter buffer parameters
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
* @param request ioctl-type request (one of the JITTER_BUFFER_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown
|
||||
*/
|
||||
int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr);
|
||||
|
||||
int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset);
|
||||
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,219 +0,0 @@
|
|||
/* Copyright (C) 2003 Epic Games
|
||||
Written by Jean-Marc Valin */
|
||||
/**
|
||||
* @file speex_preprocess.h
|
||||
* @brief Speex preprocessor. The preprocess can do noise suppression,
|
||||
* residual echo suppression (after using the echo canceller), automatic
|
||||
* gain control (AGC) and voice activity detection (VAD).
|
||||
*/
|
||||
/*
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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 SPEEX_PREPROCESS_H
|
||||
#define SPEEX_PREPROCESS_H
|
||||
/** @defgroup SpeexPreprocessState SpeexPreprocessState: The Speex preprocessor
|
||||
* This is the Speex preprocessor. The preprocess can do noise suppression,
|
||||
* residual echo suppression (after using the echo canceller), automatic
|
||||
* gain control (AGC) and voice activity detection (VAD).
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** State of the preprocessor (one per channel). Should never be accessed directly. */
|
||||
struct SpeexPreprocessState_;
|
||||
|
||||
/** State of the preprocessor (one per channel). Should never be accessed directly. */
|
||||
typedef struct SpeexPreprocessState_ SpeexPreprocessState;
|
||||
|
||||
|
||||
/** Creates a new preprocessing state. You MUST create one state per channel processed.
|
||||
* @param frame_size Number of samples to process at one time (should correspond to 10-20 ms). Must be
|
||||
* the same value as that used for the echo canceller for residual echo cancellation to work.
|
||||
* @param sampling_rate Sampling rate used for the input.
|
||||
* @return Newly created preprocessor state
|
||||
*/
|
||||
SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate);
|
||||
|
||||
/** Destroys a preprocessor state
|
||||
* @param st Preprocessor state to destroy
|
||||
*/
|
||||
void speex_preprocess_state_destroy(SpeexPreprocessState *st);
|
||||
|
||||
/** Preprocess a frame
|
||||
* @param st Preprocessor state
|
||||
* @param x Audio sample vector (in and out). Must be same size as specified in speex_preprocess_state_init().
|
||||
* @return Bool value for voice activity (1 for speech, 0 for noise/silence), ONLY if VAD turned on.
|
||||
*/
|
||||
int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x);
|
||||
|
||||
/** Preprocess a frame (deprecated, use speex_preprocess_run() instead)*/
|
||||
int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo);
|
||||
|
||||
/** Update preprocessor state, but do not compute the output
|
||||
* @param st Preprocessor state
|
||||
* @param x Audio sample vector (in only). Must be same size as specified in speex_preprocess_state_init().
|
||||
*/
|
||||
void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x);
|
||||
|
||||
/** Used like the ioctl function to control the preprocessor parameters
|
||||
* @param st Preprocessor state
|
||||
* @param request ioctl-type request (one of the SPEEX_PREPROCESS_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown
|
||||
*/
|
||||
int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr);
|
||||
|
||||
|
||||
|
||||
/** Set preprocessor denoiser state */
|
||||
#define SPEEX_PREPROCESS_SET_DENOISE 0
|
||||
/** Get preprocessor denoiser state */
|
||||
#define SPEEX_PREPROCESS_GET_DENOISE 1
|
||||
|
||||
/** Set preprocessor Automatic Gain Control state */
|
||||
#define SPEEX_PREPROCESS_SET_AGC 2
|
||||
/** Get preprocessor Automatic Gain Control state */
|
||||
#define SPEEX_PREPROCESS_GET_AGC 3
|
||||
|
||||
/** Set preprocessor Voice Activity Detection state */
|
||||
#define SPEEX_PREPROCESS_SET_VAD 4
|
||||
/** Get preprocessor Voice Activity Detection state */
|
||||
#define SPEEX_PREPROCESS_GET_VAD 5
|
||||
|
||||
/** Set preprocessor Automatic Gain Control level (float) */
|
||||
#define SPEEX_PREPROCESS_SET_AGC_LEVEL 6
|
||||
/** Get preprocessor Automatic Gain Control level (float) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_LEVEL 7
|
||||
|
||||
/** Set preprocessor dereverb state */
|
||||
#define SPEEX_PREPROCESS_SET_DEREVERB 8
|
||||
/** Get preprocessor dereverb state */
|
||||
#define SPEEX_PREPROCESS_GET_DEREVERB 9
|
||||
|
||||
/** Set preprocessor dereverb level */
|
||||
#define SPEEX_PREPROCESS_SET_DEREVERB_LEVEL 10
|
||||
/** Get preprocessor dereverb level */
|
||||
#define SPEEX_PREPROCESS_GET_DEREVERB_LEVEL 11
|
||||
|
||||
/** Set preprocessor dereverb decay */
|
||||
#define SPEEX_PREPROCESS_SET_DEREVERB_DECAY 12
|
||||
/** Get preprocessor dereverb decay */
|
||||
#define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13
|
||||
|
||||
/** Set probability required for the VAD to go from silence to voice */
|
||||
#define SPEEX_PREPROCESS_SET_PROB_START 14
|
||||
/** Get probability required for the VAD to go from silence to voice */
|
||||
#define SPEEX_PREPROCESS_GET_PROB_START 15
|
||||
|
||||
/** Set probability required for the VAD to stay in the voice state (integer percent) */
|
||||
#define SPEEX_PREPROCESS_SET_PROB_CONTINUE 16
|
||||
/** Get probability required for the VAD to stay in the voice state (integer percent) */
|
||||
#define SPEEX_PREPROCESS_GET_PROB_CONTINUE 17
|
||||
|
||||
/** Set maximum attenuation of the noise in dB (negative number) */
|
||||
#define SPEEX_PREPROCESS_SET_NOISE_SUPPRESS 18
|
||||
/** Get maximum attenuation of the noise in dB (negative number) */
|
||||
#define SPEEX_PREPROCESS_GET_NOISE_SUPPRESS 19
|
||||
|
||||
/** Set maximum attenuation of the residual echo in dB (negative number) */
|
||||
#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS 20
|
||||
/** Get maximum attenuation of the residual echo in dB (negative number) */
|
||||
#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS 21
|
||||
|
||||
/** Set maximum attenuation of the residual echo in dB when near end is active (negative number) */
|
||||
#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE 22
|
||||
/** Get maximum attenuation of the residual echo in dB when near end is active (negative number) */
|
||||
#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE 23
|
||||
|
||||
/** Set the corresponding echo canceller state so that residual echo suppression can be performed (NULL for no residual echo suppression) */
|
||||
#define SPEEX_PREPROCESS_SET_ECHO_STATE 24
|
||||
/** Get the corresponding echo canceller state */
|
||||
#define SPEEX_PREPROCESS_GET_ECHO_STATE 25
|
||||
|
||||
/** Set maximal gain increase in dB/second (int32) */
|
||||
#define SPEEX_PREPROCESS_SET_AGC_INCREMENT 26
|
||||
|
||||
/** Get maximal gain increase in dB/second (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_INCREMENT 27
|
||||
|
||||
/** Set maximal gain decrease in dB/second (int32) */
|
||||
#define SPEEX_PREPROCESS_SET_AGC_DECREMENT 28
|
||||
|
||||
/** Get maximal gain decrease in dB/second (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_DECREMENT 29
|
||||
|
||||
/** Set maximal gain in dB (int32) */
|
||||
#define SPEEX_PREPROCESS_SET_AGC_MAX_GAIN 30
|
||||
|
||||
/** Get maximal gain in dB (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31
|
||||
|
||||
/* Can't set loudness */
|
||||
/** Get loudness */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33
|
||||
|
||||
/* Can't set gain */
|
||||
/** Get current gain (int32 percent) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_GAIN 35
|
||||
|
||||
/* Can't set spectrum size */
|
||||
/** Get spectrum size for power spectrum (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_PSD_SIZE 37
|
||||
|
||||
/* Can't set power spectrum */
|
||||
/** Get power spectrum (int32[] of squared values) */
|
||||
#define SPEEX_PREPROCESS_GET_PSD 39
|
||||
|
||||
/* Can't set noise size */
|
||||
/** Get spectrum size for noise estimate (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE 41
|
||||
|
||||
/* Can't set noise estimate */
|
||||
/** Get noise estimate (int32[] of squared values) */
|
||||
#define SPEEX_PREPROCESS_GET_NOISE_PSD 43
|
||||
|
||||
/* Can't set speech probability */
|
||||
/** Get speech probability in last frame (int32). */
|
||||
#define SPEEX_PREPROCESS_GET_PROB 45
|
||||
|
||||
/** Set preprocessor Automatic Gain Control level (int32) */
|
||||
#define SPEEX_PREPROCESS_SET_AGC_TARGET 46
|
||||
/** Get preprocessor Automatic Gain Control level (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_TARGET 47
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
#endif
|
|
@ -1,340 +0,0 @@
|
|||
/* Copyright (C) 2007 Jean-Marc Valin
|
||||
|
||||
File: speex_resampler.h
|
||||
Resampling code
|
||||
|
||||
The design goals of this code are:
|
||||
- Very fast algorithm
|
||||
- Low memory requirement
|
||||
- Good *perceptual* quality (and not best SNR)
|
||||
|
||||
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.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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 SPEEX_RESAMPLER_H
|
||||
#define SPEEX_RESAMPLER_H
|
||||
|
||||
#ifdef OUTSIDE_SPEEX
|
||||
|
||||
/********* WARNING: MENTAL SANITY ENDS HERE *************/
|
||||
|
||||
/* If the resampler is defined outside of Speex, we change the symbol names so that
|
||||
there won't be any clash if linking with Speex later on. */
|
||||
|
||||
/* #define RANDOM_PREFIX your software name here */
|
||||
#ifndef RANDOM_PREFIX
|
||||
#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes"
|
||||
#endif
|
||||
|
||||
#define CAT_PREFIX2(a,b) a ## b
|
||||
#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)
|
||||
|
||||
#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)
|
||||
#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)
|
||||
#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)
|
||||
#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float)
|
||||
#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int)
|
||||
#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float)
|
||||
#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int)
|
||||
#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate)
|
||||
#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate)
|
||||
#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac)
|
||||
#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio)
|
||||
#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality)
|
||||
#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality)
|
||||
#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride)
|
||||
#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride)
|
||||
#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride)
|
||||
#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride)
|
||||
#define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency)
|
||||
#define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency)
|
||||
#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros)
|
||||
#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
|
||||
#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
|
||||
|
||||
#define spx_int16_t short
|
||||
#define spx_int32_t int
|
||||
#define spx_uint16_t unsigned short
|
||||
#define spx_uint32_t unsigned int
|
||||
|
||||
#else /* OUTSIDE_SPEEX */
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#endif /* OUTSIDE_SPEEX */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SPEEX_RESAMPLER_QUALITY_MAX 10
|
||||
#define SPEEX_RESAMPLER_QUALITY_MIN 0
|
||||
#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
|
||||
#define SPEEX_RESAMPLER_QUALITY_VOIP 3
|
||||
#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
|
||||
|
||||
enum {
|
||||
RESAMPLER_ERR_SUCCESS = 0,
|
||||
RESAMPLER_ERR_ALLOC_FAILED = 1,
|
||||
RESAMPLER_ERR_BAD_STATE = 2,
|
||||
RESAMPLER_ERR_INVALID_ARG = 3,
|
||||
RESAMPLER_ERR_PTR_OVERLAP = 4,
|
||||
|
||||
RESAMPLER_ERR_MAX_ERROR
|
||||
};
|
||||
|
||||
struct SpeexResamplerState_;
|
||||
typedef struct SpeexResamplerState_ SpeexResamplerState;
|
||||
|
||||
/** Create a new resampler with integer input and output rates.
|
||||
* @param nb_channels Number of channels to be processed
|
||||
* @param in_rate Input sampling rate (integer number of Hz).
|
||||
* @param out_rate Output sampling rate (integer number of Hz).
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor quality
|
||||
* and 10 has very high quality.
|
||||
* @return Newly created resampler state
|
||||
* @retval NULL Error: not enough memory
|
||||
*/
|
||||
SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate,
|
||||
int quality,
|
||||
int *err);
|
||||
|
||||
/** Create a new resampler with fractional input/output rates. The sampling
|
||||
* rate ratio is an arbitrary rational number with both the numerator and
|
||||
* denominator being 32-bit integers.
|
||||
* @param nb_channels Number of channels to be processed
|
||||
* @param ratio_num Numerator of the sampling rate ratio
|
||||
* @param ratio_den Denominator of the sampling rate ratio
|
||||
* @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
|
||||
* @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor quality
|
||||
* and 10 has very high quality.
|
||||
* @return Newly created resampler state
|
||||
* @retval NULL Error: not enough memory
|
||||
*/
|
||||
SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
|
||||
spx_uint32_t ratio_num,
|
||||
spx_uint32_t ratio_den,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate,
|
||||
int quality,
|
||||
int *err);
|
||||
|
||||
/** Destroy a resampler state.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
void speex_resampler_destroy(SpeexResamplerState *st);
|
||||
|
||||
/** Resample a float array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param channel_index Index of the channel to process for the multi-channel
|
||||
* base (0 otherwise)
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the
|
||||
* number of samples processed
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written
|
||||
*/
|
||||
int speex_resampler_process_float(SpeexResamplerState *st,
|
||||
spx_uint32_t channel_index,
|
||||
const float *in,
|
||||
spx_uint32_t *in_len,
|
||||
float *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Resample an int array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param channel_index Index of the channel to process for the multi-channel
|
||||
* base (0 otherwise)
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the number
|
||||
* of samples processed
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written
|
||||
*/
|
||||
int speex_resampler_process_int(SpeexResamplerState *st,
|
||||
spx_uint32_t channel_index,
|
||||
const spx_int16_t *in,
|
||||
spx_uint32_t *in_len,
|
||||
spx_int16_t *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Resample an interleaved float array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the number
|
||||
* of samples processed. This is all per-channel.
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written.
|
||||
* This is all per-channel.
|
||||
*/
|
||||
int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
|
||||
const float *in,
|
||||
spx_uint32_t *in_len,
|
||||
float *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Resample an interleaved int array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the number
|
||||
* of samples processed. This is all per-channel.
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written.
|
||||
* This is all per-channel.
|
||||
*/
|
||||
int speex_resampler_process_interleaved_int(SpeexResamplerState *st,
|
||||
const spx_int16_t *in,
|
||||
spx_uint32_t *in_len,
|
||||
spx_int16_t *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Set (change) the input/output sampling rates (integer value).
|
||||
* @param st Resampler state
|
||||
* @param in_rate Input sampling rate (integer number of Hz).
|
||||
* @param out_rate Output sampling rate (integer number of Hz).
|
||||
*/
|
||||
int speex_resampler_set_rate(SpeexResamplerState *st,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate);
|
||||
|
||||
/** Get the current input/output sampling rates (integer value).
|
||||
* @param st Resampler state
|
||||
* @param in_rate Input sampling rate (integer number of Hz) copied.
|
||||
* @param out_rate Output sampling rate (integer number of Hz) copied.
|
||||
*/
|
||||
void speex_resampler_get_rate(SpeexResamplerState *st,
|
||||
spx_uint32_t *in_rate,
|
||||
spx_uint32_t *out_rate);
|
||||
|
||||
/** Set (change) the input/output sampling rates and resampling ratio
|
||||
* (fractional values in Hz supported).
|
||||
* @param st Resampler state
|
||||
* @param ratio_num Numerator of the sampling rate ratio
|
||||
* @param ratio_den Denominator of the sampling rate ratio
|
||||
* @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
|
||||
* @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
|
||||
*/
|
||||
int speex_resampler_set_rate_frac(SpeexResamplerState *st,
|
||||
spx_uint32_t ratio_num,
|
||||
spx_uint32_t ratio_den,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate);
|
||||
|
||||
/** Get the current resampling ratio. This will be reduced to the least
|
||||
* common denominator.
|
||||
* @param st Resampler state
|
||||
* @param ratio_num Numerator of the sampling rate ratio copied
|
||||
* @param ratio_den Denominator of the sampling rate ratio copied
|
||||
*/
|
||||
void speex_resampler_get_ratio(SpeexResamplerState *st,
|
||||
spx_uint32_t *ratio_num,
|
||||
spx_uint32_t *ratio_den);
|
||||
|
||||
/** Set (change) the conversion quality.
|
||||
* @param st Resampler state
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor
|
||||
* quality and 10 has very high quality.
|
||||
*/
|
||||
int speex_resampler_set_quality(SpeexResamplerState *st,
|
||||
int quality);
|
||||
|
||||
/** Get the conversion quality.
|
||||
* @param st Resampler state
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor
|
||||
* quality and 10 has very high quality.
|
||||
*/
|
||||
void speex_resampler_get_quality(SpeexResamplerState *st,
|
||||
int *quality);
|
||||
|
||||
/** Set (change) the input stride.
|
||||
* @param st Resampler state
|
||||
* @param stride Input stride
|
||||
*/
|
||||
void speex_resampler_set_input_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t stride);
|
||||
|
||||
/** Get the input stride.
|
||||
* @param st Resampler state
|
||||
* @param stride Input stride copied
|
||||
*/
|
||||
void speex_resampler_get_input_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t *stride);
|
||||
|
||||
/** Set (change) the output stride.
|
||||
* @param st Resampler state
|
||||
* @param stride Output stride
|
||||
*/
|
||||
void speex_resampler_set_output_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t stride);
|
||||
|
||||
/** Get the output stride.
|
||||
* @param st Resampler state copied
|
||||
* @param stride Output stride
|
||||
*/
|
||||
void speex_resampler_get_output_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t *stride);
|
||||
|
||||
/** Get the latency in input samples introduced by the resampler.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_get_input_latency(SpeexResamplerState *st);
|
||||
|
||||
/** Get the latency in output samples introduced by the resampler.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_get_output_latency(SpeexResamplerState *st);
|
||||
|
||||
/** Make sure that the first samples to go out of the resamplers don't have
|
||||
* leading zeros. This is only useful before starting to use a newly created
|
||||
* resampler. It is recommended to use that when resampling an audio file, as
|
||||
* it will generate a file with the same length. For real-time processing,
|
||||
* it is probably easier not to use this call (so that the output duration
|
||||
* is the same for the first frame).
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_skip_zeros(SpeexResamplerState *st);
|
||||
|
||||
/** Reset a resampler so a new (unrelated) stream can be processed.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_reset_mem(SpeexResamplerState *st);
|
||||
|
||||
/** Returns the English meaning for an error code
|
||||
* @param err Error code
|
||||
* @return English string
|
||||
*/
|
||||
const char *speex_resampler_strerror(int err);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,91 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin*/
|
||||
/**
|
||||
@file speex_stereo.h
|
||||
@brief Describes the handling for intensity stereo
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef STEREO_H
|
||||
#define STEREO_H
|
||||
/** @defgroup SpeexStereoState SpeexStereoState: Handling Speex stereo files
|
||||
* This describes the Speex intensity stereo encoding/decoding
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
#include "speex/speex_bits.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** If you access any of these fields directly, I'll personally come and bite you */
|
||||
typedef struct SpeexStereoState {
|
||||
float balance; /**< Left/right balance info */
|
||||
float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */
|
||||
float smooth_left; /**< Smoothed left channel gain */
|
||||
float smooth_right; /**< Smoothed right channel gain */
|
||||
float reserved1; /**< Reserved for future use */
|
||||
float reserved2; /**< Reserved for future use */
|
||||
} SpeexStereoState;
|
||||
|
||||
/** Deprecated. Use speex_stereo_state_init() instead. */
|
||||
#define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0}
|
||||
|
||||
/** Initialise/create a stereo stereo state */
|
||||
SpeexStereoState *speex_stereo_state_init();
|
||||
|
||||
/** Reset/re-initialise an already allocated stereo state */
|
||||
void speex_stereo_state_reset(SpeexStereoState *stereo);
|
||||
|
||||
/** Destroy a stereo stereo state */
|
||||
void speex_stereo_state_destroy(SpeexStereoState *stereo);
|
||||
|
||||
/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */
|
||||
void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits);
|
||||
|
||||
/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */
|
||||
void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits);
|
||||
|
||||
/** Transforms a mono frame into a stereo frame using intensity stereo info */
|
||||
void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo);
|
||||
|
||||
/** Transforms a mono frame into a stereo frame using intensity stereo info */
|
||||
void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo);
|
||||
|
||||
/** Callback handler for intensity stereo info */
|
||||
int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif
|
|
@ -1,126 +0,0 @@
|
|||
/* speex_types.h taken from libogg */
|
||||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: #ifdef jail to whip a few platforms into the UNIX ideal.
|
||||
last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $
|
||||
|
||||
********************************************************************/
|
||||
/**
|
||||
@file speex_types.h
|
||||
@brief Speex types
|
||||
*/
|
||||
#ifndef _SPEEX_TYPES_H
|
||||
#define _SPEEX_TYPES_H
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
# if defined(__CYGWIN__)
|
||||
# include <_G_config.h>
|
||||
typedef _G_int32_t spx_int32_t;
|
||||
typedef _G_uint32_t spx_uint32_t;
|
||||
typedef _G_int16_t spx_int16_t;
|
||||
typedef _G_uint16_t spx_uint16_t;
|
||||
# elif defined(__MINGW32__)
|
||||
typedef short spx_int16_t;
|
||||
typedef unsigned short spx_uint16_t;
|
||||
typedef int spx_int32_t;
|
||||
typedef unsigned int spx_uint32_t;
|
||||
# elif defined(__MWERKS__)
|
||||
typedef int spx_int32_t;
|
||||
typedef unsigned int spx_uint32_t;
|
||||
typedef short spx_int16_t;
|
||||
typedef unsigned short spx_uint16_t;
|
||||
# else
|
||||
/* MSVC/Borland */
|
||||
typedef __int32 spx_int32_t;
|
||||
typedef unsigned __int32 spx_uint32_t;
|
||||
typedef __int16 spx_int16_t;
|
||||
typedef unsigned __int16 spx_uint16_t;
|
||||
# endif
|
||||
|
||||
#elif defined(__MACOS__)
|
||||
|
||||
# include <sys/types.h>
|
||||
typedef SInt16 spx_int16_t;
|
||||
typedef UInt16 spx_uint16_t;
|
||||
typedef SInt32 spx_int32_t;
|
||||
typedef UInt32 spx_uint32_t;
|
||||
|
||||
#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
|
||||
|
||||
# include <sys/types.h>
|
||||
typedef int16_t spx_int16_t;
|
||||
typedef u_int16_t spx_uint16_t;
|
||||
typedef int32_t spx_int32_t;
|
||||
typedef u_int32_t spx_uint32_t;
|
||||
|
||||
#elif defined(__BEOS__)
|
||||
|
||||
/* Be */
|
||||
# include <inttypes.h>
|
||||
typedef int16_t spx_int16_t;
|
||||
typedef u_int16_t spx_uint16_t;
|
||||
typedef int32_t spx_int32_t;
|
||||
typedef u_int32_t spx_uint32_t;
|
||||
|
||||
#elif defined (__EMX__)
|
||||
|
||||
/* OS/2 GCC */
|
||||
typedef short spx_int16_t;
|
||||
typedef unsigned short spx_uint16_t;
|
||||
typedef int spx_int32_t;
|
||||
typedef unsigned int spx_uint32_t;
|
||||
|
||||
#elif defined (DJGPP)
|
||||
|
||||
/* DJGPP */
|
||||
typedef short spx_int16_t;
|
||||
typedef int spx_int32_t;
|
||||
typedef unsigned int spx_uint32_t;
|
||||
|
||||
#elif defined(R5900)
|
||||
|
||||
/* PS2 EE */
|
||||
typedef int spx_int32_t;
|
||||
typedef unsigned spx_uint32_t;
|
||||
typedef short spx_int16_t;
|
||||
|
||||
#elif defined(__SYMBIAN32__)
|
||||
|
||||
/* Symbian GCC */
|
||||
typedef signed short spx_int16_t;
|
||||
typedef unsigned short spx_uint16_t;
|
||||
typedef signed int spx_int32_t;
|
||||
typedef unsigned int spx_uint32_t;
|
||||
|
||||
#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
|
||||
|
||||
typedef short spx_int16_t;
|
||||
typedef unsigned short spx_uint16_t;
|
||||
typedef long spx_int32_t;
|
||||
typedef unsigned long spx_uint32_t;
|
||||
|
||||
#elif defined(CONFIG_TI_C6X)
|
||||
|
||||
typedef short spx_int16_t;
|
||||
typedef unsigned short spx_uint16_t;
|
||||
typedef int spx_int32_t;
|
||||
typedef unsigned int spx_uint32_t;
|
||||
|
||||
#else
|
||||
|
||||
# include <speex/speex_config_types.h>
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SPEEX_TYPES_H */
|
|
@ -1,115 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@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.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef STACK_ALLOC_H
|
||||
#define STACK_ALLOC_H
|
||||
|
||||
#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
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_VALGRIND
|
||||
|
||||
#include <valgrind/memcheck.h>
|
||||
|
||||
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
|
||||
|
||||
#define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
|
||||
|
||||
#else
|
||||
|
||||
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
|
||||
|
||||
#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(VAR_ARRAYS)
|
||||
#define VARDECL(var)
|
||||
#define ALLOC(var, size, type) type var[size]
|
||||
#elif defined(USE_ALLOCA)
|
||||
#define VARDECL(var) var
|
||||
#define ALLOC(var, size, type) var = alloca(sizeof(type)*(size))
|
||||
#else
|
||||
#define VARDECL(var) var
|
||||
#define ALLOC(var, size, type) var = PUSH(stack, size, type)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -1,296 +0,0 @@
|
|||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: stereo.c
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include <speex/speex_stereo.h>
|
||||
#include <speex/speex_callbacks.h>
|
||||
#include "math_approx.h"
|
||||
#include "vq.h"
|
||||
#include <math.h>
|
||||
#include "os_support.h"
|
||||
|
||||
typedef struct RealSpeexStereoState {
|
||||
spx_word32_t balance; /**< Left/right balance info */
|
||||
spx_word32_t e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */
|
||||
spx_word32_t smooth_left; /**< Smoothed left channel gain */
|
||||
spx_word32_t smooth_right; /**< Smoothed right channel gain */
|
||||
spx_uint32_t reserved1; /**< Reserved for future use */
|
||||
spx_int32_t reserved2; /**< Reserved for future use */
|
||||
} RealSpeexStereoState;
|
||||
|
||||
|
||||
/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/
|
||||
#ifndef FIXED_POINT
|
||||
static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f};
|
||||
static const float e_ratio_quant_bounds[3] = {0.2825f, 0.356f, 0.4485f};
|
||||
#else
|
||||
static const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384};
|
||||
static const spx_word16_t e_ratio_quant_bounds[3] = {9257, 11665, 14696};
|
||||
static const spx_word16_t balance_bounds[31] = {18, 23, 30, 38, 49, 63, 81, 104,
|
||||
134, 172, 221, 284, 364, 468, 600, 771,
|
||||
990, 1271, 1632, 2096, 2691, 3455, 4436, 5696,
|
||||
7314, 9392, 12059, 15484, 19882, 25529, 32766};
|
||||
#endif
|
||||
|
||||
/* This is an ugly compatibility hack that properly resets the stereo state
|
||||
In case it it compiled in fixed-point, but initialised with the deprecated
|
||||
floating point static initialiser */
|
||||
#ifdef FIXED_POINT
|
||||
#define COMPATIBILITY_HACK(s) do {if ((s)->reserved1 != 0xdeadbeef) speex_stereo_state_reset((SpeexStereoState*)s); } while (0);
|
||||
#else
|
||||
#define COMPATIBILITY_HACK(s)
|
||||
#endif
|
||||
|
||||
EXPORT SpeexStereoState *speex_stereo_state_init()
|
||||
{
|
||||
SpeexStereoState *stereo = speex_alloc(sizeof(SpeexStereoState));
|
||||
speex_stereo_state_reset(stereo);
|
||||
return stereo;
|
||||
}
|
||||
|
||||
EXPORT void speex_stereo_state_reset(SpeexStereoState *_stereo)
|
||||
{
|
||||
RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
|
||||
#ifdef FIXED_POINT
|
||||
stereo->balance = 65536;
|
||||
stereo->e_ratio = 16384;
|
||||
stereo->smooth_left = 16384;
|
||||
stereo->smooth_right = 16384;
|
||||
stereo->reserved1 = 0xdeadbeef;
|
||||
stereo->reserved2 = 0;
|
||||
#else
|
||||
stereo->balance = 1.0f;
|
||||
stereo->e_ratio = .5f;
|
||||
stereo->smooth_left = 1.f;
|
||||
stereo->smooth_right = 1.f;
|
||||
stereo->reserved1 = 0;
|
||||
stereo->reserved2 = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
EXPORT void speex_stereo_state_destroy(SpeexStereoState *stereo)
|
||||
{
|
||||
speex_free(stereo);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
EXPORT void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
|
||||
{
|
||||
int i, tmp;
|
||||
float e_left=0, e_right=0, e_tot=0;
|
||||
float balance, e_ratio;
|
||||
for (i=0;i<frame_size;i++)
|
||||
{
|
||||
e_left += ((float)data[2*i])*data[2*i];
|
||||
e_right += ((float)data[2*i+1])*data[2*i+1];
|
||||
data[i] = .5*(((float)data[2*i])+data[2*i+1]);
|
||||
e_tot += ((float)data[i])*data[i];
|
||||
}
|
||||
balance=(e_left+1)/(e_right+1);
|
||||
e_ratio = e_tot/(1+e_left+e_right);
|
||||
|
||||
/*Quantization*/
|
||||
speex_bits_pack(bits, 14, 5);
|
||||
speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
|
||||
|
||||
balance=4*log(balance);
|
||||
|
||||
/*Pack sign*/
|
||||
if (balance>0)
|
||||
speex_bits_pack(bits, 0, 1);
|
||||
else
|
||||
speex_bits_pack(bits, 1, 1);
|
||||
balance=floor(.5+fabs(balance));
|
||||
if (balance>30)
|
||||
balance=31;
|
||||
|
||||
speex_bits_pack(bits, (int)balance, 5);
|
||||
|
||||
/* FIXME: this is a hack */
|
||||
tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 4);
|
||||
speex_bits_pack(bits, tmp, 2);
|
||||
}
|
||||
#endif /* #ifndef DISABLE_FLOAT_API */
|
||||
|
||||
EXPORT void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits)
|
||||
{
|
||||
int i, tmp;
|
||||
spx_word32_t e_left=0, e_right=0, e_tot=0;
|
||||
spx_word32_t balance, e_ratio;
|
||||
spx_word32_t largest, smallest;
|
||||
int balance_id;
|
||||
#ifdef FIXED_POINT
|
||||
int shift;
|
||||
#endif
|
||||
|
||||
/* In band marker */
|
||||
speex_bits_pack(bits, 14, 5);
|
||||
/* Stereo marker */
|
||||
speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
|
||||
|
||||
for (i=0;i<frame_size;i++)
|
||||
{
|
||||
e_left += SHR32(MULT16_16(data[2*i],data[2*i]),8);
|
||||
e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),8);
|
||||
#ifdef FIXED_POINT
|
||||
/* I think this is actually unbiased */
|
||||
data[i] = SHR16(data[2*i],1)+PSHR16(data[2*i+1],1);
|
||||
#else
|
||||
data[i] = .5*(((float)data[2*i])+data[2*i+1]);
|
||||
#endif
|
||||
e_tot += SHR32(MULT16_16(data[i],data[i]),8);
|
||||
}
|
||||
if (e_left > e_right)
|
||||
{
|
||||
speex_bits_pack(bits, 0, 1);
|
||||
largest = e_left;
|
||||
smallest = e_right;
|
||||
} else {
|
||||
speex_bits_pack(bits, 1, 1);
|
||||
largest = e_right;
|
||||
smallest = e_left;
|
||||
}
|
||||
|
||||
/* Balance quantization */
|
||||
#ifdef FIXED_POINT
|
||||
shift = spx_ilog2(largest)-15;
|
||||
largest = VSHR32(largest, shift-4);
|
||||
smallest = VSHR32(smallest, shift);
|
||||
balance = DIV32(largest, ADD32(smallest, 1));
|
||||
if (balance > 32767)
|
||||
balance = 32767;
|
||||
balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32);
|
||||
#else
|
||||
balance=(largest+1.)/(smallest+1.);
|
||||
balance=4*log(balance);
|
||||
balance_id=floor(.5+fabs(balance));
|
||||
if (balance_id>30)
|
||||
balance_id=31;
|
||||
#endif
|
||||
|
||||
speex_bits_pack(bits, balance_id, 5);
|
||||
|
||||
/* "coherence" quantisation */
|
||||
#ifdef FIXED_POINT
|
||||
shift = spx_ilog2(e_tot);
|
||||
e_tot = VSHR32(e_tot, shift-25);
|
||||
e_left = VSHR32(e_left, shift-10);
|
||||
e_right = VSHR32(e_right, shift-10);
|
||||
e_ratio = DIV32(e_tot, e_left+e_right+1);
|
||||
#else
|
||||
e_ratio = e_tot/(1.+e_left+e_right);
|
||||
#endif
|
||||
|
||||
tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4);
|
||||
/*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio);*/
|
||||
speex_bits_pack(bits, tmp, 2);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
EXPORT void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo)
|
||||
{
|
||||
int i;
|
||||
spx_word32_t balance;
|
||||
spx_word16_t e_left, e_right, e_ratio;
|
||||
RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
|
||||
|
||||
COMPATIBILITY_HACK(stereo);
|
||||
|
||||
balance=stereo->balance;
|
||||
e_ratio=stereo->e_ratio;
|
||||
|
||||
/* These two are Q14, with max value just below 2. */
|
||||
e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));
|
||||
e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);
|
||||
|
||||
for (i=frame_size-1;i>=0;i--)
|
||||
{
|
||||
spx_word16_t tmp=data[i];
|
||||
stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));
|
||||
stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));
|
||||
data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp);
|
||||
data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp);
|
||||
}
|
||||
}
|
||||
#endif /* #ifndef DISABLE_FLOAT_API */
|
||||
|
||||
EXPORT void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo)
|
||||
{
|
||||
int i;
|
||||
spx_word32_t balance;
|
||||
spx_word16_t e_left, e_right, e_ratio;
|
||||
RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
|
||||
|
||||
COMPATIBILITY_HACK(stereo);
|
||||
|
||||
balance=stereo->balance;
|
||||
e_ratio=stereo->e_ratio;
|
||||
|
||||
/* These two are Q14, with max value just below 2. */
|
||||
e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));
|
||||
e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);
|
||||
|
||||
for (i=frame_size-1;i>=0;i--)
|
||||
{
|
||||
spx_int16_t tmp=data[i];
|
||||
stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));
|
||||
stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));
|
||||
data[2*i] = (spx_int16_t)MULT16_16_P14(stereo->smooth_left, tmp);
|
||||
data[2*i+1] = (spx_int16_t)MULT16_16_P14(stereo->smooth_right, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
RealSpeexStereoState *stereo;
|
||||
spx_word16_t sign=1, dexp;
|
||||
int tmp;
|
||||
|
||||
stereo = (RealSpeexStereoState*)data;
|
||||
|
||||
COMPATIBILITY_HACK(stereo);
|
||||
|
||||
if (speex_bits_unpack_unsigned(bits, 1))
|
||||
sign=-1;
|
||||
dexp = speex_bits_unpack_unsigned(bits, 5);
|
||||
#ifndef FIXED_POINT
|
||||
stereo->balance = exp(sign*.25*dexp);
|
||||
#else
|
||||
stereo->balance = spx_exp(MULT16_16(sign, SHL16(dexp, 9)));
|
||||
#endif
|
||||
tmp = speex_bits_unpack_unsigned(bits, 2);
|
||||
stereo->e_ratio = e_ratio_quant[tmp];
|
||||
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue