mirror of
https://github.com/rehlds/revoice.git
synced 2025-03-03 17:15:25 +03:00
Update speex codec to version 1.2.1
This commit is contained in:
parent
c7f858e7af
commit
0095b8b5ad
118
external/speex/CMakeLists.txt
vendored
118
external/speex/CMakeLists.txt
vendored
@ -2,7 +2,19 @@
|
||||
# Project Definition
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
project("Speex")
|
||||
project( "Speex"
|
||||
VERSION "1.2.1"
|
||||
DESCRIPTION "Speex voice codec"
|
||||
HOMEPAGE_URL "https://gitlab.xiph.org/xiph/speex"
|
||||
LANGUAGES "C"
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Options
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
option(SPEEX_ENABLE_VORBIS_PSY "Enable Vorbis psychoacoustic model" OFF)
|
||||
option(SPEEX_USE_KISS_FFT "Use KISS Fast Fourier Transform (otherwise OggVorbis)" OFF)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Target Definition
|
||||
@ -22,12 +34,18 @@ target_sources("${TARGET_NAME}"
|
||||
PUBLIC
|
||||
"include/speex/speex_bits.h"
|
||||
"include/speex/speex_callbacks.h"
|
||||
"include/speex/speex_config_types.h"
|
||||
"include/speex/speex_header.h"
|
||||
"include/speex/speex_stereo.h"
|
||||
"include/speex/speex_types.h"
|
||||
"include/speex/speex.h"
|
||||
|
||||
PRIVATE
|
||||
"src/arch.h"
|
||||
"src/bfin.h"
|
||||
"src/bits.c"
|
||||
"src/cb_search_bfin.h"
|
||||
"src/cb_search_sse.h"
|
||||
"src/cb_search.c"
|
||||
"src/cb_search.h"
|
||||
"src/exc_10_16_table.c"
|
||||
@ -36,42 +54,73 @@ target_sources("${TARGET_NAME}"
|
||||
"src/exc_5_256_table.c"
|
||||
"src/exc_5_64_table.c"
|
||||
"src/exc_8_128_table.c"
|
||||
"src/fftwrap.h"
|
||||
"src/filters_bfin.h"
|
||||
"src/filters_sse.h"
|
||||
"src/filters.c"
|
||||
"src/filters.h"
|
||||
"src/fixed_bfin.h"
|
||||
"src/fixed_debug.h"
|
||||
"src/fixed_generic.h"
|
||||
"src/gain_table_lbr.c"
|
||||
"src/gain_table.c"
|
||||
"src/hexc_10_32_table.c"
|
||||
"src/hexc_table.c"
|
||||
"src/high_lsp_tables.c"
|
||||
"src/lpc_bfin.h"
|
||||
"src/lpc.c"
|
||||
"src/lpc.h"
|
||||
"src/lsp_bfin.h"
|
||||
"src/lsp_tables_nb.c"
|
||||
"src/lsp.c"
|
||||
"src/lsp.h"
|
||||
"src/ltp_bfin.h"
|
||||
"src/ltp_sse.h"
|
||||
"src/ltp.c"
|
||||
"src/ltp.h"
|
||||
"src/math_approx.c"
|
||||
"src/math_approx.h"
|
||||
"src/misc.c"
|
||||
"src/misc.h"
|
||||
"src/misc_bfin.h"
|
||||
"src/modes_wb.c"
|
||||
"src/modes.c"
|
||||
"src/modes.h"
|
||||
"src/nb_celp.c"
|
||||
"src/nb_celp.h"
|
||||
"src/os_support.h"
|
||||
"src/quant_lsp_bfin.h"
|
||||
"src/quant_lsp.c"
|
||||
"src/quant_lsp.h"
|
||||
"src/sb_celp.c"
|
||||
"src/sb_celp.h"
|
||||
"src/speex_callbacks.c"
|
||||
"src/speex_header.c"
|
||||
"src/speex.c"
|
||||
"src/stack_alloc.h"
|
||||
"src/stereo.c"
|
||||
"src/vbr.c"
|
||||
"src/vbr.h"
|
||||
"src/vq_bfin.h"
|
||||
"src/vq_sse.h"
|
||||
"src/vq.c"
|
||||
"src/vq.h"
|
||||
"src/window.c"
|
||||
|
||||
$<$<BOOL:${SPEEX_USE_KISS_FFT}>:
|
||||
"src/_kiss_fft_guts.h"
|
||||
"src/kiss_fft.c"
|
||||
"src/kiss_fft.h"
|
||||
"src/kiss_fftr.c"
|
||||
"src/kiss_fftr.h"
|
||||
>
|
||||
|
||||
$<$<NOT:$<BOOL:${SPEEX_USE_KISS_FFT}>>:
|
||||
"src/smallft.c"
|
||||
"src/smallft.h"
|
||||
>
|
||||
|
||||
$<$<BOOL:${SPEEX_ENABLE_VORBIS_PSY}>:
|
||||
"src/vorbis_psy.c"
|
||||
"src/vorbis_psy.h"
|
||||
>
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -86,11 +135,70 @@ target_include_directories("${TARGET_NAME}"
|
||||
"${PROJECT_SOURCE_DIR}/include/speex"
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Compile Definitions
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
target_compile_definitions("${TARGET_NAME}"
|
||||
PRIVATE
|
||||
_USE_SSE
|
||||
FLOATING_POINT
|
||||
|
||||
SPEEX_MAJOR_VERSION=${PROJECT_VERSION_MAJOR}
|
||||
SPEEX_MINOR_VERSION=${PROJECT_VERSION_MINOR}
|
||||
SPEEX_MICRO_VERSION=${PROJECT_VERSION_PATCH}
|
||||
SPEEX_VERSION="${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
|
||||
SPEEX_EXTRA_VERSION=""
|
||||
|
||||
$<$<PLATFORM_ID:Windows>:
|
||||
_USE_SSE2
|
||||
_USE_MATH_DEFINES
|
||||
alloca=_alloca
|
||||
inline=__inline
|
||||
EXPORT=
|
||||
>
|
||||
|
||||
$<$<NOT:$<PLATFORM_ID:Windows>>:
|
||||
HAVE_ALLOCA_H
|
||||
HAVE_GETOPT_H
|
||||
USE_ALLOCA
|
||||
VAR_ARRAYS
|
||||
EXPORT=__attribute__\(\(visibility\(\"default\"\)\)\)
|
||||
>
|
||||
|
||||
$<$<BOOL:${SPEEX_ENABLE_VORBIS_PSY}>:VORBIS_PSYCHO>
|
||||
$<IF:$<BOOL:${SPEEX_USE_KISS_FFT}>,USE_KISS_FFT,USE_SMALLFT>
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Compile Options
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
target_compile_options("${TARGET_NAME}"
|
||||
PRIVATE
|
||||
$<IF:$<CXX_COMPILER_ID:MSVC>,/W0,-w>
|
||||
-UARM4_ASM
|
||||
-UARM5E_ASM
|
||||
-UBFIN_ASM
|
||||
-UDISABLE_FLOAT_API
|
||||
-UDISABLE_VBR
|
||||
-UENABLE_VALGRIND
|
||||
-UFIXED_POINT_DEBUG
|
||||
|
||||
$<$<PLATFORM_ID:Windows>:
|
||||
-UHAVE_GETOPT_H
|
||||
-UUSE_ALLOCA
|
||||
>
|
||||
|
||||
$<IF:$<C_COMPILER_ID:MSVC>,/W0,-w>
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Link Libraries
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
target_link_libraries("${TARGET_NAME}"
|
||||
PUBLIC
|
||||
$<$<NOT:$<PLATFORM_ID:Windows>>:
|
||||
"m"
|
||||
>
|
||||
)
|
||||
|
162
external/speex/include/speex/speex.h
vendored
162
external/speex/include/speex/speex.h
vendored
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin*/
|
||||
/* Copyright (C) 2002-2006 Jean-Marc Valin*/
|
||||
/**
|
||||
@file speex.h
|
||||
@brief Describes the different modes of the codec
|
||||
@ -35,7 +35,12 @@
|
||||
|
||||
#ifndef SPEEX_H
|
||||
#define SPEEX_H
|
||||
/** @defgroup Codec Speex encoder and decoder
|
||||
* This is the Speex codec itself.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex_types.h"
|
||||
#include "speex_bits.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -56,7 +61,7 @@ extern "C" {
|
||||
/** Set quality value */
|
||||
#define SPEEX_SET_QUALITY 4
|
||||
/** Get current quality setting */
|
||||
#define SPEEX_GET_QUALITY 5
|
||||
/* #define SPEEX_GET_QUALITY 5 -- Doesn't make much sense, does it? */
|
||||
|
||||
/** Set sub-mode to use */
|
||||
#define SPEEX_SET_MODE 6
|
||||
@ -93,10 +98,10 @@ extern "C" {
|
||||
/** 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 a handler function for in-band Speex request*/
|
||||
#define SPEEX_SET_HANDLER 20
|
||||
|
||||
/**Define a handler function for in-band user-defined request*/
|
||||
/** Define a handler function for in-band user-defined request*/
|
||||
#define SPEEX_SET_USER_HANDLER 22
|
||||
|
||||
/** Set sampling rate used in bit-rate computation */
|
||||
@ -126,16 +131,34 @@ extern "C" {
|
||||
/** 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
|
||||
|
||||
/* 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
|
||||
/*#define SPEEX_SET_LOOKAHEAD 38*/
|
||||
/** Returns the lookahead used by Speex separately for an encoder and a decoder.
|
||||
* Sum encoder and decoder lookahead values to get the total codec lookahead. */
|
||||
#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:*/
|
||||
@ -145,6 +168,8 @@ extern "C" {
|
||||
#define SPEEX_GET_PF 1
|
||||
|
||||
|
||||
|
||||
|
||||
/* Values allowed for mode queries */
|
||||
/** Query the frame size of a mode */
|
||||
#define SPEEX_MODE_FRAME_SIZE 0
|
||||
@ -153,52 +178,84 @@ extern "C" {
|
||||
#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)(struct SpeexMode *mode);
|
||||
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, float *in, SpeexBits *bits);
|
||||
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)(struct SpeexMode *mode);
|
||||
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, float *out);
|
||||
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)(void *mode, int request, void *ptr);
|
||||
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 */
|
||||
void *mode;
|
||||
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)*/
|
||||
char *modeName;
|
||||
const char *modeName;
|
||||
|
||||
/**ID of the mode*/
|
||||
int modeID;
|
||||
@ -240,9 +297,9 @@ typedef struct SpeexMode {
|
||||
* 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
|
||||
* @return A newly created encoder state or NULL if state allocation fails
|
||||
*/
|
||||
void *speex_encoder_init(SpeexMode *mode);
|
||||
void *speex_encoder_init(const SpeexMode *mode);
|
||||
|
||||
/** Frees all resources associated to an existing Speex encoder state.
|
||||
* @param state Encoder state to be destroyed */
|
||||
@ -251,17 +308,29 @@ 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^16 range
|
||||
@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 frame needs not be transmitted (DTX only), 1 otherwise
|
||||
* @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
|
||||
*/
|
||||
int speex_encoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
@ -272,9 +341,9 @@ int speex_encoder_ctl(void *state, int request, void *ptr);
|
||||
* 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
|
||||
* @return A newly created decoder state or NULL if state allocation fails
|
||||
*/
|
||||
void *speex_decoder_init(SpeexMode *mode);
|
||||
void *speex_decoder_init(const SpeexMode *mode);
|
||||
|
||||
/** Frees all resources associated to an existing decoder state.
|
||||
*
|
||||
@ -288,16 +357,26 @@ void speex_decoder_destroy(void *state);
|
||||
* @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 other)
|
||||
* @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 for no error, 1 if a terminator is reached, 2 for another error
|
||||
* @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
|
||||
*/
|
||||
int speex_decoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
@ -307,25 +386,40 @@ int speex_decoder_ctl(void *state, int request, void *ptr);
|
||||
* @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(SpeexMode *mode, int request, void *ptr);
|
||||
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 SpeexMode speex_nb_mode;
|
||||
extern const SpeexMode speex_nb_mode;
|
||||
|
||||
/** Default wideband mode */
|
||||
extern SpeexMode speex_wb_mode;
|
||||
extern const SpeexMode speex_wb_mode;
|
||||
|
||||
/** Default "ultra-wideband" mode */
|
||||
extern SpeexMode speex_uwb_mode;
|
||||
extern const SpeexMode speex_uwb_mode;
|
||||
|
||||
/** List of all modes available */
|
||||
extern SpeexMode *speex_mode_list[SPEEX_NB_MODES];
|
||||
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
|
||||
|
42
external/speex/include/speex/speex_bits.h
vendored
42
external/speex/include/speex/speex_bits.h
vendored
@ -35,21 +35,23 @@
|
||||
|
||||
#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
|
||||
|
||||
/** Maximum size of the bit-stream (for fixed-size allocation) */
|
||||
#define MAX_BYTES_PER_FRAME 2000
|
||||
|
||||
/** Bit-packing data structure representing (part of) a bit-stream. */
|
||||
typedef struct SpeexBits {
|
||||
char *bytes; /**< "raw" data */
|
||||
char *chars; /**< "raw" data */
|
||||
int nbBits; /**< Total number of bits stored in the stream*/
|
||||
int bytePtr; /**< Position of the byte "cursor" */
|
||||
int bitPtr; /**< Position of the bit "cursor" within the current byte */
|
||||
int owner; /**< Does the struct "own" the "raw" buffer (member "bytes") */
|
||||
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 */
|
||||
@ -62,6 +64,9 @@ 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);
|
||||
|
||||
@ -72,16 +77,23 @@ void speex_bits_reset(SpeexBits *bits);
|
||||
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);
|
||||
void speex_bits_read_from(SpeexBits *bits, const 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);
|
||||
void speex_bits_read_whole_bytes(SpeexBits *bits, const char *bytes, int len);
|
||||
|
||||
/** Write the content of a bit-stream to an area of memory */
|
||||
/** 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 */
|
||||
@ -117,13 +129,19 @@ unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits);
|
||||
*/
|
||||
int speex_bits_nbytes(SpeexBits *bits);
|
||||
|
||||
/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position */
|
||||
/** 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);
|
||||
|
||||
@ -137,6 +155,7 @@ 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);
|
||||
|
||||
@ -151,4 +170,5 @@ void speex_bits_insert_terminator(SpeexBits *bits);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* @} */
|
||||
#endif
|
||||
|
10
external/speex/include/speex/speex_callbacks.h
vendored
10
external/speex/include/speex/speex_callbacks.h
vendored
@ -35,6 +35,9 @@
|
||||
|
||||
#ifndef SPEEX_CALLBACKS_H
|
||||
#define SPEEX_CALLBACKS_H
|
||||
/** @defgroup SpeexCallbacks Various definitions for Speex callbacks supported by the decoder.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex.h"
|
||||
|
||||
@ -110,13 +113,16 @@ 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);
|
||||
|
||||
|
||||
@ -124,5 +130,5 @@ int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *da
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @} */
|
||||
#endif
|
||||
|
12
external/speex/include/speex/speex_config_types.h
vendored
Normal file
12
external/speex/include/speex/speex_config_types.h
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef __SPEEX_TYPES_H__
|
||||
#define __SPEEX_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int16_t spx_int16_t;
|
||||
typedef uint16_t spx_uint16_t;
|
||||
typedef int32_t spx_int32_t;
|
||||
typedef uint32_t spx_uint32_t;
|
||||
|
||||
#endif
|
||||
|
44
external/speex/include/speex/speex_header.h
vendored
44
external/speex/include/speex/speex_header.h
vendored
@ -36,6 +36,12 @@
|
||||
|
||||
#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_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -43,30 +49,33 @@ extern "C" {
|
||||
|
||||
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[8]; /**< Identifies a Speex bit-stream, always set to "Speex " */
|
||||
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 */
|
||||
int speex_version_id; /**< Version for Speex (for checking compatibility) */
|
||||
int header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */
|
||||
int rate; /**< Sampling rate used */
|
||||
int mode; /**< Mode used (0 for narrowband, 1 for wideband) */
|
||||
int mode_bitstream_version; /**< Version ID of the bit-stream */
|
||||
int nb_channels; /**< Number of channels encoded */
|
||||
int bitrate; /**< Bit-rate used */
|
||||
int frame_size; /**< Size of frames */
|
||||
int vbr; /**< 1 for a VBR encoding, 0 otherwise */
|
||||
int frames_per_packet; /**< Number of frames stored per Ogg packet */
|
||||
int extra_headers; /**< Number of additional headers after the comments */
|
||||
int reserved1; /**< Reserved for future use, must be zero */
|
||||
int reserved2; /**< Reserved for future use, must be zero */
|
||||
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, struct SpeexMode *m);
|
||||
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);
|
||||
@ -74,9 +83,12 @@ 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
|
||||
|
36
external/speex/include/speex/speex_stereo.h
vendored
36
external/speex/include/speex/speex_stereo.h
vendored
@ -34,10 +34,20 @@
|
||||
|
||||
#ifndef STEREO_H
|
||||
#define STEREO_H
|
||||
/** @defgroup SpeexStereoState SpeexStereoState: Handling Speex stereo files
|
||||
* This describes the Speex intensity stereo encoding/decoding
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex_types.h"
|
||||
#include "speex_bits.h"
|
||||
|
||||
/** State used for decoding (intensity) stereo information */
|
||||
|
||||
#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)] */
|
||||
@ -47,16 +57,36 @@ typedef struct SpeexStereoState {
|
||||
float reserved2; /**< Reserved for future use */
|
||||
} SpeexStereoState;
|
||||
|
||||
/** Initialization value for a stereo state */
|
||||
#define SPEEX_STEREO_STATE_INIT {1,.5,1,1}
|
||||
/** 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(void);
|
||||
|
||||
/** 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
|
||||
|
126
external/speex/include/speex/speex_types.h
vendored
Normal file
126
external/speex/include/speex/speex_types.h
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
/* 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_config_types.h"
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SPEEX_TYPES_H */
|
160
external/speex/src/_kiss_fft_guts.h
vendored
Normal file
160
external/speex/src/_kiss_fft_guts.h
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
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) )
|
236
external/speex/src/arch.h
vendored
Normal file
236
external/speex/src/arch.h
vendored
Normal file
@ -0,0 +1,236 @@
|
||||
/* 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 2 /**< Minor Speex version. */
|
||||
#define SPEEX_MICRO_VERSION 1 /**< Micro Speex version. */
|
||||
#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */
|
||||
#define SPEEX_VERSION "speex-1.2.1" /**< Speex version string. */
|
||||
#endif
|
||||
|
||||
/* A couple test to catch stupid option combinations */
|
||||
#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
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#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 EPSILON 1
|
||||
#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 EPSILON 1e-15f
|
||||
#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_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_Q15(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
|
15
external/speex/src/bfin.h
vendored
Normal file
15
external/speex/src/bfin.h
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/* Common Blackfin assembly defines
|
||||
*
|
||||
* Copyright (C) 2005-2009 Analog Devices
|
||||
*/
|
||||
|
||||
#if __GNUC__ <= 3
|
||||
/* GCC-3.4 and older did not use hardware loops and thus did not have
|
||||
* register constraints for declaring clobbers.
|
||||
*/
|
||||
# define BFIN_HWLOOP0_REGS
|
||||
# define BFIN_HWLOOP1_REGS
|
||||
#else
|
||||
# define BFIN_HWLOOP0_REGS , "LB0", "LT0", "LC0"
|
||||
# define BFIN_HWLOOP1_REGS , "LB1", "LT1", "LC1"
|
||||
#endif
|
296
external/speex/src/bits.c
vendored
296
external/speex/src/bits.c
vendored
@ -32,184 +32,215 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "speex_bits.h"
|
||||
#include "misc.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
void speex_bits_init(SpeexBits *bits)
|
||||
#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)
|
||||
{
|
||||
int i;
|
||||
bits->bytes = (char*)speex_alloc(MAX_BYTES_PER_FRAME);
|
||||
bits->buf_size = MAX_BYTES_PER_FRAME;
|
||||
bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);
|
||||
if (!bits->chars)
|
||||
return;
|
||||
|
||||
bits->buf_size = MAX_CHARS_PER_FRAME;
|
||||
|
||||
for (i=0;i<bits->buf_size;i++)
|
||||
bits->bytes[i]=0;
|
||||
bits->nbBits=0;
|
||||
bits->bytePtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->owner=1;
|
||||
bits->overflow=0;
|
||||
|
||||
speex_bits_reset(bits);
|
||||
}
|
||||
|
||||
void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
|
||||
EXPORT void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
|
||||
{
|
||||
int i;
|
||||
bits->bytes = (char*)buff;
|
||||
bits->chars = (char*)buff;
|
||||
bits->buf_size = buf_size;
|
||||
|
||||
for (i=0;i<buf_size;i++)
|
||||
bits->bytes[i]=0;
|
||||
bits->nbBits=0;
|
||||
bits->bytePtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->owner=0;
|
||||
bits->overflow=0;
|
||||
|
||||
speex_bits_reset(bits);
|
||||
}
|
||||
|
||||
void speex_bits_destroy(SpeexBits *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->bytes);
|
||||
speex_free(bits->chars);
|
||||
/* Will do something once the allocation is dynamic */
|
||||
}
|
||||
|
||||
void speex_bits_reset(SpeexBits *bits)
|
||||
EXPORT void speex_bits_reset(SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<bits->buf_size;i++)
|
||||
bits->bytes[i]=0;
|
||||
/* We only need to clear the first byte now */
|
||||
bits->chars[0]=0;
|
||||
bits->nbBits=0;
|
||||
bits->bytePtr=0;
|
||||
bits->charPtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
void speex_bits_rewind(SpeexBits *bits)
|
||||
EXPORT void speex_bits_rewind(SpeexBits *bits)
|
||||
{
|
||||
bits->bytePtr=0;
|
||||
bits->charPtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
void speex_bits_read_from(SpeexBits *bits, char *bytes, int len)
|
||||
EXPORT void speex_bits_read_from(SpeexBits *bits, const char *chars, int len)
|
||||
{
|
||||
int i;
|
||||
if (len > bits->buf_size)
|
||||
int nchars = len / BYTES_PER_CHAR;
|
||||
if (nchars > bits->buf_size)
|
||||
{
|
||||
speex_warning_int("Packet if larger than allocated buffer: ", len);
|
||||
speex_notify("Packet is larger than allocated buffer");
|
||||
if (bits->owner)
|
||||
{
|
||||
char *tmp = (char*)speex_realloc(bits->bytes, len);
|
||||
char *tmp = (char*)speex_realloc(bits->chars, nchars);
|
||||
if (tmp)
|
||||
{
|
||||
bits->buf_size=len;
|
||||
bits->bytes=tmp;
|
||||
bits->buf_size=nchars;
|
||||
bits->chars=tmp;
|
||||
} else {
|
||||
len=bits->buf_size;
|
||||
nchars=bits->buf_size;
|
||||
speex_warning("Could not resize input buffer: truncating input");
|
||||
}
|
||||
} else {
|
||||
speex_warning("Do not own input buffer: truncating input");
|
||||
len=bits->buf_size;
|
||||
speex_warning("Do not own input buffer: truncating oversize input");
|
||||
nchars=bits->buf_size;
|
||||
}
|
||||
}
|
||||
for (i=0;i<len;i++)
|
||||
bits->bytes[i]=bytes[i];
|
||||
bits->nbBits=len<<3;
|
||||
bits->bytePtr=0;
|
||||
#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 i;
|
||||
if (bits->bytePtr>0)
|
||||
{
|
||||
for (i=bits->bytePtr;i<((bits->nbBits+7)>>3);i++)
|
||||
bits->bytes[i-bits->bytePtr]=bits->bytes[i];
|
||||
}
|
||||
bits->nbBits -= bits->bytePtr<<3;
|
||||
bits->bytePtr=0;
|
||||
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;
|
||||
}
|
||||
|
||||
void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len)
|
||||
EXPORT void speex_bits_read_whole_bytes(SpeexBits *bits, const char *chars, int nbytes)
|
||||
{
|
||||
int i,pos;
|
||||
int nchars = nbytes/BYTES_PER_CHAR;
|
||||
|
||||
if ((bits->nbBits>>3)+len+1 > bits->buf_size)
|
||||
if (((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)+nchars > bits->buf_size)
|
||||
{
|
||||
speex_warning_int("Packet if larger than allocated buffer: ", len);
|
||||
/* Packet is larger than allocated buffer */
|
||||
if (bits->owner)
|
||||
{
|
||||
char *tmp = (char*)speex_realloc(bits->bytes, (bits->nbBits>>3)+len+1);
|
||||
char *tmp = (char*)speex_realloc(bits->chars, (bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1);
|
||||
if (tmp)
|
||||
{
|
||||
bits->buf_size=(bits->nbBits>>3)+len+1;
|
||||
bits->bytes=tmp;
|
||||
bits->buf_size=(bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1;
|
||||
bits->chars=tmp;
|
||||
} else {
|
||||
len=bits->buf_size-(bits->nbBits>>3)-1;
|
||||
speex_warning("Could not resize input buffer: truncating input");
|
||||
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 input");
|
||||
len=bits->buf_size;
|
||||
speex_warning("Do not own input buffer: truncating oversize input");
|
||||
nchars=bits->buf_size;
|
||||
}
|
||||
}
|
||||
|
||||
speex_bits_flush(bits);
|
||||
pos=bits->nbBits>>3;
|
||||
for (i=0;i<len;i++)
|
||||
bits->bytes[pos+i]=bytes[i];
|
||||
bits->nbBits+=len<<3;
|
||||
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;
|
||||
}
|
||||
|
||||
int speex_bits_write(SpeexBits *bits, char *bytes, int max_len)
|
||||
EXPORT int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
|
||||
{
|
||||
int i;
|
||||
if (max_len > ((bits->nbBits+7)>>3))
|
||||
max_len = ((bits->nbBits+7)>>3);
|
||||
for (i=0;i<max_len;i++)
|
||||
bytes[i]=bits->bytes[i];
|
||||
return max_len;
|
||||
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;
|
||||
}
|
||||
|
||||
int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len)
|
||||
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_len > ((bits->nbBits)>>3))
|
||||
max_len = ((bits->nbBits)>>3);
|
||||
for (i=0;i<max_len;i++)
|
||||
bytes[i]=bits->bytes[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->bytes[0]=bits->bytes[max_len];
|
||||
bits->chars[0]=bits->chars[max_nchars];
|
||||
else
|
||||
bits->bytes[0]=0;
|
||||
for (i=1;i<((bits->nbBits)>>3)+1;i++)
|
||||
bits->bytes[i]=0;
|
||||
bits->bytePtr=0;
|
||||
bits->nbBits &= 7;
|
||||
return max_len;
|
||||
bits->chars[0]=0;
|
||||
bits->charPtr=0;
|
||||
bits->nbBits &= (BITS_PER_CHAR-1);
|
||||
return max_nchars*BYTES_PER_CHAR;
|
||||
}
|
||||
|
||||
|
||||
void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
|
||||
EXPORT void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
|
||||
{
|
||||
int i;
|
||||
unsigned int d=data;
|
||||
|
||||
if (bits->bytePtr+((nbBits+bits->bitPtr)>>3) >= bits->buf_size)
|
||||
if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
|
||||
{
|
||||
speex_warning("Buffer too small to pack bits");
|
||||
speex_notify("Buffer too small to pack bits");
|
||||
if (bits->owner)
|
||||
{
|
||||
char *tmp = (char*)speex_realloc(bits->bytes, ((bits->buf_size+5)*3)>>1);
|
||||
int new_nchars = ((bits->buf_size+5)*3)>>1;
|
||||
char *tmp = (char*)speex_realloc(bits->chars, new_nchars);
|
||||
if (tmp)
|
||||
{
|
||||
for (i=bits->buf_size;i<(((bits->buf_size+5)*3)>>1);i++)
|
||||
tmp[i]=0;
|
||||
bits->buf_size=((bits->buf_size+5)*3)>>1;
|
||||
bits->bytes=tmp;
|
||||
bits->buf_size=new_nchars;
|
||||
bits->chars=tmp;
|
||||
} else {
|
||||
speex_warning("Could not resize input buffer: not packing");
|
||||
return;
|
||||
@ -224,129 +255,118 @@ void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
|
||||
{
|
||||
int bit;
|
||||
bit = (d>>(nbBits-1))&1;
|
||||
bits->bytes[bits->bytePtr] |= bit<<(7-bits->bitPtr);
|
||||
bits->chars[bits->charPtr] |= bit<<(BITS_PER_CHAR-1-bits->bitPtr);
|
||||
bits->bitPtr++;
|
||||
|
||||
if (bits->bitPtr==8)
|
||||
if (bits->bitPtr==BITS_PER_CHAR)
|
||||
{
|
||||
bits->bitPtr=0;
|
||||
bits->bytePtr++;
|
||||
bits->charPtr++;
|
||||
bits->chars[bits->charPtr] = 0;
|
||||
}
|
||||
bits->nbBits++;
|
||||
nbBits--;
|
||||
}
|
||||
}
|
||||
|
||||
int speex_bits_unpack_signed(SpeexBits *bits, int 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;
|
||||
d |= (~0u)<<nbBits;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
|
||||
EXPORT unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=0;
|
||||
if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
|
||||
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->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
|
||||
d |= (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
|
||||
bits->bitPtr++;
|
||||
if (bits->bitPtr==8)
|
||||
if (bits->bitPtr==BITS_PER_CHAR)
|
||||
{
|
||||
bits->bitPtr=0;
|
||||
bits->bytePtr++;
|
||||
bits->charPtr++;
|
||||
}
|
||||
nbBits--;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
|
||||
EXPORT unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=0;
|
||||
int bitPtr, bytePtr;
|
||||
char *bytes;
|
||||
int bitPtr, charPtr;
|
||||
char *chars;
|
||||
|
||||
if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
|
||||
if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
|
||||
bits->overflow=1;
|
||||
if (bits->overflow)
|
||||
return 0;
|
||||
|
||||
bitPtr=bits->bitPtr;
|
||||
bytePtr=bits->bytePtr;
|
||||
bytes = bits->bytes;
|
||||
charPtr=bits->charPtr;
|
||||
chars = bits->chars;
|
||||
while(nbBits)
|
||||
{
|
||||
d<<=1;
|
||||
d |= (bytes[bytePtr]>>(7-bitPtr))&1;
|
||||
d |= (chars[charPtr]>>(BITS_PER_CHAR-1 - bitPtr))&1;
|
||||
bitPtr++;
|
||||
if (bitPtr==8)
|
||||
if (bitPtr==BITS_PER_CHAR)
|
||||
{
|
||||
bitPtr=0;
|
||||
bytePtr++;
|
||||
charPtr++;
|
||||
}
|
||||
nbBits--;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
int speex_bits_peek(SpeexBits *bits)
|
||||
EXPORT int speex_bits_peek(SpeexBits *bits)
|
||||
{
|
||||
if ((bits->bytePtr<<3)+bits->bitPtr+1>bits->nbBits)
|
||||
if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)
|
||||
bits->overflow=1;
|
||||
if (bits->overflow)
|
||||
return 0;
|
||||
return (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
|
||||
return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
|
||||
}
|
||||
|
||||
void speex_bits_advance(SpeexBits *bits, int n)
|
||||
EXPORT void speex_bits_advance(SpeexBits *bits, int n)
|
||||
{
|
||||
int nbytes, nbits;
|
||||
|
||||
if ((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits)
|
||||
if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
|
||||
bits->overflow=1;
|
||||
if (bits->overflow)
|
||||
return;
|
||||
|
||||
nbytes = n >> 3;
|
||||
nbits = n & 7;
|
||||
|
||||
bits->bytePtr += nbytes;
|
||||
bits->bitPtr += nbits;
|
||||
|
||||
if (bits->bitPtr>7)
|
||||
{
|
||||
bits->bitPtr-=8;
|
||||
bits->bytePtr++;
|
||||
}
|
||||
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 */
|
||||
}
|
||||
|
||||
int speex_bits_remaining(SpeexBits *bits)
|
||||
EXPORT int speex_bits_remaining(SpeexBits *bits)
|
||||
{
|
||||
if (bits->overflow)
|
||||
return -1;
|
||||
else
|
||||
return bits->nbBits-((bits->bytePtr<<3)+bits->bitPtr);
|
||||
return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);
|
||||
}
|
||||
|
||||
int speex_bits_nbytes(SpeexBits *bits)
|
||||
EXPORT int speex_bits_nbytes(SpeexBits *bits)
|
||||
{
|
||||
return ((bits->nbBits+7)>>3);
|
||||
return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
|
||||
}
|
||||
|
||||
void speex_bits_insert_terminator(SpeexBits *bits)
|
||||
EXPORT void speex_bits_insert_terminator(SpeexBits *bits)
|
||||
{
|
||||
if (bits->bitPtr<7)
|
||||
if (bits->bitPtr)
|
||||
speex_bits_pack(bits, 0, 1);
|
||||
while (bits->bitPtr<7)
|
||||
while (bits->bitPtr)
|
||||
speex_bits_pack(bits, 1, 1);
|
||||
}
|
||||
|
624
external/speex/src/cb_search.c
vendored
624
external/speex/src/cb_search.c
vendored
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
/* Copyright (C) 2002-2006 Jean-Marc Valin
|
||||
File: cb_search.c
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -29,159 +29,149 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "cb_search.h"
|
||||
#include "filters.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "vq.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "math_approx.h"
|
||||
#include "os_support.h"
|
||||
|
||||
void split_cb_search_shape_sign(
|
||||
float target[], /* target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs for this subframe */
|
||||
float awk2[], /* Weighted LPCs for this subframe */
|
||||
void *par, /* Codebook/search parameters*/
|
||||
#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 DISABLE_ENCODER
|
||||
|
||||
#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 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 */
|
||||
float *exc,
|
||||
float *r,
|
||||
spx_sig_t *exc,
|
||||
spx_word16_t *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity
|
||||
int update_target
|
||||
)
|
||||
{
|
||||
int i,j,k,m,n,q;
|
||||
float *resp;
|
||||
float *t, *e, *E, *r2;
|
||||
float *tmp;
|
||||
float *ndist, *odist;
|
||||
int *itmp;
|
||||
float **ot, **nt;
|
||||
int **nind, **oind;
|
||||
int *ind;
|
||||
signed char *shape_cb;
|
||||
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;
|
||||
split_cb_params *params;
|
||||
int N=2;
|
||||
int *best_index;
|
||||
float *best_dist;
|
||||
const split_cb_params *params;
|
||||
int best_index;
|
||||
spx_word32_t best_dist;
|
||||
int have_sign;
|
||||
|
||||
N=complexity;
|
||||
if (N>10)
|
||||
N=10;
|
||||
|
||||
ot=PUSH(stack, N, float*);
|
||||
nt=PUSH(stack, N, float*);
|
||||
oind=PUSH(stack, N, int*);
|
||||
nind=PUSH(stack, N, int*);
|
||||
|
||||
params = (split_cb_params *) par;
|
||||
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;
|
||||
resp = PUSH(stack, shape_cb_size*subvect_size, float);
|
||||
t = PUSH(stack, nsf, float);
|
||||
e = PUSH(stack, nsf, float);
|
||||
r2 = PUSH(stack, nsf, float);
|
||||
E = PUSH(stack, shape_cb_size, float);
|
||||
ind = PUSH(stack, nb_subvect, int);
|
||||
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);
|
||||
|
||||
tmp = PUSH(stack, 2*N*nsf, float);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
ot[i]=tmp;
|
||||
tmp += nsf;
|
||||
nt[i]=tmp;
|
||||
tmp += nsf;
|
||||
}
|
||||
/* FIXME: Do we still need to copy the target? */
|
||||
SPEEX_COPY(t, target, nsf);
|
||||
|
||||
best_index = PUSH(stack, N, int);
|
||||
best_dist = PUSH(stack, N, float);
|
||||
ndist = PUSH(stack, N, float);
|
||||
odist = PUSH(stack, N, float);
|
||||
compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
|
||||
|
||||
itmp = PUSH(stack, 2*N*nb_subvect, int);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
nind[i]=itmp;
|
||||
itmp+=nb_subvect;
|
||||
oind[i]=itmp;
|
||||
itmp+=nb_subvect;
|
||||
for (j=0;j<nb_subvect;j++)
|
||||
nind[i][j]=oind[i][j]=-1;
|
||||
}
|
||||
|
||||
for (j=0;j<N;j++)
|
||||
for (i=0;i<nsf;i++)
|
||||
ot[j][i]=target[i];
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
t[i]=target[i];
|
||||
|
||||
/* Pre-compute codewords response and energy */
|
||||
for (i=0;i<shape_cb_size;i++)
|
||||
{
|
||||
float *res;
|
||||
signed char *shape;
|
||||
|
||||
res = resp+i*subvect_size;
|
||||
shape = shape_cb+i*subvect_size;
|
||||
|
||||
/* Compute codeword response using convolution with impulse response */
|
||||
for(j=0;j<subvect_size;j++)
|
||||
{
|
||||
res[j]=0;
|
||||
for (k=0;k<=j;k++)
|
||||
res[j] += 0.03125*shape[k]*r[j-k];
|
||||
}
|
||||
|
||||
/* Compute codeword energy */
|
||||
E[i]=0;
|
||||
for(j=0;j<subvect_size;j++)
|
||||
E[i]+=res[j]*res[j];
|
||||
}
|
||||
|
||||
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]=-1;
|
||||
|
||||
/*For all n-bests of previous subvector*/
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
float *x=ot[j]+subvect_size*i;
|
||||
spx_word16_t *x=t+subvect_size*i;
|
||||
/*Find new n-best based on previous n-best j*/
|
||||
#ifndef DISABLE_WIDEBAND
|
||||
if (have_sign)
|
||||
vq_nbest_sign(x, resp, subvect_size, shape_cb_size, E, N, best_index, best_dist);
|
||||
vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
|
||||
else
|
||||
vq_nbest(x, resp, subvect_size, shape_cb_size, E, N, best_index, best_dist);
|
||||
#endif /* DISABLE_WIDEBAND */
|
||||
vq_nbest(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
|
||||
|
||||
/*For all new n-bests*/
|
||||
for (k=0;k<N;k++)
|
||||
{
|
||||
float *ct;
|
||||
float err=0;
|
||||
ct = ot[j];
|
||||
/*update target*/
|
||||
speex_bits_pack(bits,best_index,params->shape_bits+have_sign);
|
||||
|
||||
/*previous target*/
|
||||
for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
|
||||
t[m]=ct[m];
|
||||
|
||||
/* New code: update only enough of the target to calculate error*/
|
||||
{
|
||||
int rind;
|
||||
float *res;
|
||||
float sign=1;
|
||||
rind = best_index[k];
|
||||
spx_word16_t *res;
|
||||
spx_word16_t sign=1;
|
||||
rind = best_index;
|
||||
if (rind>=shape_cb_size)
|
||||
{
|
||||
sign=-1;
|
||||
@ -190,61 +180,237 @@ int complexity
|
||||
res = resp+rind*subvect_size;
|
||||
if (sign>0)
|
||||
for (m=0;m<subvect_size;m++)
|
||||
t[subvect_size*i+m] -= res[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] += res[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
|
||||
|
||||
}
|
||||
|
||||
/*compute error (distance)*/
|
||||
err=odist[j];
|
||||
for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
|
||||
err += t[m]*t[m];
|
||||
/*update n-best list*/
|
||||
if (err<ndist[N-1] || ndist[N-1]<-.5)
|
||||
{
|
||||
|
||||
/*previous target (we don't care what happened before*/
|
||||
for (m=(i+1)*subvect_size;m<nsf;m++)
|
||||
t[m]=ct[m];
|
||||
/* New code: update the rest of the target only if it's worth it */
|
||||
for (m=0;m<subvect_size;m++)
|
||||
{
|
||||
float g;
|
||||
spx_word16_t g;
|
||||
int rind;
|
||||
float sign=1;
|
||||
rind = best_index[k];
|
||||
spx_word16_t sign=1;
|
||||
rind = best_index;
|
||||
if (rind>=shape_cb_size)
|
||||
{
|
||||
sign=-1;
|
||||
rind-=shape_cb_size;
|
||||
}
|
||||
|
||||
g=sign*0.03125*shape_cb[rind*subvect_size+m];
|
||||
q=subvect_size-m;
|
||||
for (n=subvect_size*(i+1);n<nsf;n++,q++)
|
||||
t[n] -= g*r[q];
|
||||
#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 additional 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*/
|
||||
#ifndef DISABLE_WIDEBAND
|
||||
if (have_sign)
|
||||
vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
|
||||
else
|
||||
#endif /* DISABLE_WIDEBAND */
|
||||
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] || ndist[m]<-.5)
|
||||
if (err < ndist[m])
|
||||
{
|
||||
for (n=N-1;n>m;n--)
|
||||
{
|
||||
for (q=(i+1)*subvect_size;q<nsf;q++)
|
||||
nt[n][q]=nt[n-1][q];
|
||||
for (q=0;q<nb_subvect;q++)
|
||||
nind[n][q]=nind[n-1][q];
|
||||
ndist[n]=ndist[n-1];
|
||||
ndist[n] = ndist[n-1];
|
||||
best_nind[n] = best_nind[n-1];
|
||||
best_ntarget[n] = best_ntarget[n-1];
|
||||
}
|
||||
for (q=(i+1)*subvect_size;q<nsf;q++)
|
||||
nt[m][q]=t[q];
|
||||
for (q=0;q<nb_subvect;q++)
|
||||
nind[m][q]=oind[j][q];
|
||||
nind[m][i]=best_index[k];
|
||||
ndist[m]=err;
|
||||
/* n is equal to m here, so they're interchangeable */
|
||||
ndist[m] = err;
|
||||
best_nind[n] = best_index[k];
|
||||
best_ntarget[n] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -253,11 +419,43 @@ int complexity
|
||||
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 */
|
||||
{
|
||||
float **tmp2;
|
||||
spx_word16_t **tmp2;
|
||||
tmp2=ot;
|
||||
ot=nt;
|
||||
nt=tmp2;
|
||||
@ -280,53 +478,72 @@ int complexity
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
int rind;
|
||||
float sign=1;
|
||||
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]+=e[j];
|
||||
exc[j]=ADD32(exc[j],e[j]);
|
||||
|
||||
/* Update target */
|
||||
syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack);
|
||||
/* 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++)
|
||||
target[j]-=r2[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));
|
||||
}
|
||||
}
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
|
||||
#ifndef DISABLE_DECODER
|
||||
void split_cb_shape_sign_unquant(
|
||||
float *exc,
|
||||
void *par, /* non-overlapping codebook */
|
||||
spx_sig_t *exc,
|
||||
const void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack
|
||||
char *stack,
|
||||
spx_uint32_t *seed
|
||||
)
|
||||
{
|
||||
int i,j;
|
||||
int *ind, *signs;
|
||||
signed char *shape_cb;
|
||||
int shape_cb_size, subvect_size, nb_subvect;
|
||||
split_cb_params *params;
|
||||
VARDECL(int *ind);
|
||||
VARDECL(int *signs);
|
||||
const signed char *shape_cb;
|
||||
int subvect_size, nb_subvect;
|
||||
const split_cb_params *params;
|
||||
int have_sign;
|
||||
|
||||
params = (split_cb_params *) par;
|
||||
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;
|
||||
|
||||
ind = PUSH(stack, nb_subvect, int);
|
||||
signs = PUSH(stack, nb_subvect, int);
|
||||
ALLOC(ind, nb_subvect, int);
|
||||
ALLOC(signs, nb_subvect, int);
|
||||
|
||||
/* Decode codewords and gains */
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
@ -340,48 +557,67 @@ char *stack
|
||||
/* Compute decoded excitation */
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
float s=1;
|
||||
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
|
||||
}
|
||||
}
|
||||
#endif /* DISABLE_DECODER */
|
||||
|
||||
#ifndef DISABLE_ENCODER
|
||||
void noise_codebook_quant(
|
||||
float target[], /* target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs for this subframe */
|
||||
float awk2[], /* Weighted LPCs for this subframe */
|
||||
void *par, /* Codebook/search parameters*/
|
||||
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 */
|
||||
float *exc,
|
||||
float *r,
|
||||
spx_sig_t *exc,
|
||||
spx_word16_t *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity
|
||||
int complexity,
|
||||
int update_target
|
||||
)
|
||||
{
|
||||
int i;
|
||||
float *tmp=PUSH(stack, nsf, float);
|
||||
residue_percep_zero(target, ak, awk1, awk2, tmp, nsf, p, stack);
|
||||
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]+=tmp[i];
|
||||
for (i=0;i<nsf;i++)
|
||||
target[i]=0;
|
||||
|
||||
exc[i]+=SHL32(EXTEND32(tmp[i]),8);
|
||||
SPEEX_MEMSET(target, 0, nsf);
|
||||
}
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
|
||||
#ifndef DISABLE_DECODER
|
||||
void noise_codebook_unquant(
|
||||
float *exc,
|
||||
void *par, /* non-overlapping codebook */
|
||||
spx_sig_t *exc,
|
||||
const void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack
|
||||
char *stack,
|
||||
spx_uint32_t *seed
|
||||
)
|
||||
{
|
||||
speex_rand_vec(1, exc, nsf);
|
||||
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);
|
||||
}
|
||||
#endif /* DISABLE_DECODER */
|
||||
|
64
external/speex/src/cb_search.h
vendored
64
external/speex/src/cb_search.h
vendored
@ -1,7 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin & David Rowe
|
||||
File: cb_search.c
|
||||
Overlapped codebook search
|
||||
|
||||
/* 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:
|
||||
@ -33,63 +35,69 @@
|
||||
#ifndef CB_SEARCH_H
|
||||
#define CB_SEARCH_H
|
||||
|
||||
#include "speex_bits.h"
|
||||
#include "speex/speex_bits.h"
|
||||
#include "arch.h"
|
||||
|
||||
/** Split codebook parameters. */
|
||||
typedef struct split_cb_params {
|
||||
int subvect_size;
|
||||
int nb_subvect;
|
||||
signed char *shape_cb;
|
||||
const signed char *shape_cb;
|
||||
int shape_bits;
|
||||
int have_sign;
|
||||
} split_cb_params;
|
||||
|
||||
|
||||
void split_cb_search_shape_sign(
|
||||
float target[], /* target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs for this subframe */
|
||||
float awk2[], /* Weighted LPCs for this subframe */
|
||||
void *par, /* Codebook/search parameters*/
|
||||
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 */
|
||||
float *exc,
|
||||
float *r,
|
||||
spx_sig_t *exc,
|
||||
spx_word16_t *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity
|
||||
int complexity,
|
||||
int update_target
|
||||
);
|
||||
|
||||
void split_cb_shape_sign_unquant(
|
||||
float *exc,
|
||||
void *par, /* non-overlapping codebook */
|
||||
spx_sig_t *exc,
|
||||
const void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack
|
||||
char *stack,
|
||||
spx_uint32_t *seed
|
||||
);
|
||||
|
||||
|
||||
void noise_codebook_quant(
|
||||
float target[], /* target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs for this subframe */
|
||||
float awk2[], /* Weighted LPCs for this subframe */
|
||||
void *par, /* Codebook/search parameters*/
|
||||
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 */
|
||||
float *exc,
|
||||
float *r,
|
||||
spx_sig_t *exc,
|
||||
spx_word16_t *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity
|
||||
int complexity,
|
||||
int update_target
|
||||
);
|
||||
|
||||
|
||||
void noise_codebook_unquant(
|
||||
float *exc,
|
||||
void *par, /* non-overlapping codebook */
|
||||
spx_sig_t *exc,
|
||||
const void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack
|
||||
char *stack,
|
||||
spx_uint32_t *seed
|
||||
);
|
||||
|
||||
#endif
|
||||
|
137
external/speex/src/cb_search_arm4.h
vendored
Normal file
137
external/speex/src/cb_search_arm4.h
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
/* 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 temporarily 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
|
111
external/speex/src/cb_search_bfin.h
vendored
Normal file
111
external/speex/src/cb_search_bfin.h
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "bfin.h"
|
||||
|
||||
#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 outer%= LC0;\n\t"
|
||||
"LOOP_BEGIN outer%=;\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 outer%=;\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", "ASTAT" BFIN_HWLOOP0_REGS BFIN_HWLOOP1_REGS
|
||||
);
|
||||
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", "ASTAT" BFIN_HWLOOP0_REGS
|
||||
);
|
||||
}
|
84
external/speex/src/cb_search_sse.h
vendored
Normal file
84
external/speex/src/cb_search_sse.h
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
/* 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;
|
||||
}
|
||||
}
|
2
external/speex/src/exc_10_16_table.c
vendored
2
external/speex/src/exc_10_16_table.c
vendored
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_10_16_table[160] = {
|
||||
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,
|
||||
|
2
external/speex/src/exc_10_32_table.c
vendored
2
external/speex/src/exc_10_32_table.c
vendored
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_10_32_table[320] = {
|
||||
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,
|
||||
|
2
external/speex/src/exc_20_32_table.c
vendored
2
external/speex/src/exc_20_32_table.c
vendored
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_20_32_table[640] = {
|
||||
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,
|
||||
|
2
external/speex/src/exc_5_256_table.c
vendored
2
external/speex/src/exc_5_256_table.c
vendored
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_5_256_table[1280] = {
|
||||
const signed char exc_5_256_table[1280] = {
|
||||
-8,-37,5,-43,5,
|
||||
73,61,39,12,-3,
|
||||
-61,-32,2,42,30,
|
||||
|
2
external/speex/src/exc_5_64_table.c
vendored
2
external/speex/src/exc_5_64_table.c
vendored
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_5_64_table[320]={
|
||||
const signed char exc_5_64_table[320]={
|
||||
1,5,-15,49,-66,
|
||||
-48,-4,50,-44,7,
|
||||
37,16,-18,25,-26,
|
||||
|
2
external/speex/src/exc_8_128_table.c
vendored
2
external/speex/src/exc_8_128_table.c
vendored
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_8_128_table[1024] = {
|
||||
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,
|
||||
|
448
external/speex/src/fftwrap.c
vendored
Normal file
448
external/speex/src/fftwrap.c
vendored
Normal file
@ -0,0 +1,448 @@
|
||||
/* 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.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#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_INTEL_IPP)
|
||||
|
||||
#include <ipps.h>
|
||||
|
||||
struct ipp_fft_config
|
||||
{
|
||||
IppsDFTSpec_R_32f *dftSpec;
|
||||
Ipp8u *buffer;
|
||||
};
|
||||
|
||||
void *spx_fft_init(int size)
|
||||
{
|
||||
int bufferSize = 0;
|
||||
int hint;
|
||||
struct ipp_fft_config *table;
|
||||
|
||||
table = (struct ipp_fft_config *)speex_alloc(sizeof(struct ipp_fft_config));
|
||||
|
||||
/* there appears to be no performance difference between ippAlgHintFast and
|
||||
ippAlgHintAccurate when using the with the floating point version
|
||||
of the fft. */
|
||||
hint = ippAlgHintAccurate;
|
||||
|
||||
ippsDFTInitAlloc_R_32f(&table->dftSpec, size, IPP_FFT_DIV_FWD_BY_N, hint);
|
||||
|
||||
ippsDFTGetBufSize_R_32f(table->dftSpec, &bufferSize);
|
||||
table->buffer = ippsMalloc_8u(bufferSize);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
void spx_fft_destroy(void *table)
|
||||
{
|
||||
struct ipp_fft_config *t = (struct ipp_fft_config *)table;
|
||||
ippsFree(t->buffer);
|
||||
ippsDFTFree_R_32f(t->dftSpec);
|
||||
speex_free(t);
|
||||
}
|
||||
|
||||
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
struct ipp_fft_config *t = (struct ipp_fft_config *)table;
|
||||
ippsDFTFwd_RToPack_32f(in, out, t->dftSpec, t->buffer);
|
||||
}
|
||||
|
||||
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
struct ipp_fft_config *t = (struct ipp_fft_config *)table;
|
||||
ippsDFTInv_PackToR_32f(in, out, t->dftSpec, t->buffer);
|
||||
}
|
||||
|
||||
#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,9 +1,8 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file misc.h
|
||||
@brief Various compatibility routines for Speex
|
||||
*/
|
||||
/*
|
||||
/* 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:
|
||||
@ -30,54 +29,30 @@
|
||||
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 MISC_H
|
||||
#define MISC_H
|
||||
#ifndef FFTWRAP_H
|
||||
#define FFTWRAP_H
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "speex-1.0"
|
||||
#endif
|
||||
#include "arch.h"
|
||||
|
||||
/*Disable some warnings on VC++*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4305)
|
||||
#endif
|
||||
/** Compute tables for an FFT */
|
||||
void *spx_fft_init(int size);
|
||||
|
||||
#ifndef RELEASE
|
||||
void print_vec(float *vec, int len, char *name);
|
||||
#endif
|
||||
/** Destroy tables for an FFT */
|
||||
void spx_fft_destroy(void *table);
|
||||
|
||||
unsigned int be_int(unsigned int i);
|
||||
unsigned int le_int(unsigned int i);
|
||||
/** 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);
|
||||
|
||||
unsigned short be_short(unsigned short s);
|
||||
unsigned short le_short(unsigned short s);
|
||||
/** Forward (real to half-complex) transform of float data */
|
||||
void spx_fft_float(void *table, float *in, float *out);
|
||||
|
||||
/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free */
|
||||
void *speex_alloc (int size);
|
||||
|
||||
/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */
|
||||
void *speex_realloc (void *ptr, int size);
|
||||
|
||||
/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */
|
||||
void speex_free (void *ptr);
|
||||
|
||||
/** Speex wrapper for mem_move */
|
||||
void *speex_move (void *dest, void *src, int n);
|
||||
|
||||
void speex_error(char *str);
|
||||
|
||||
void speex_warning(char *str);
|
||||
|
||||
void speex_warning_int(char *str, int val);
|
||||
|
||||
void speex_rand_vec(float std, float *data, int len);
|
||||
|
||||
float speex_rand(float std);
|
||||
|
||||
void _speex_putc(int ch, void *file);
|
||||
/** Backward (half-complex to real) transform of float data */
|
||||
void spx_ifft_float(void *table, float *in, float *out);
|
||||
|
||||
#endif
|
858
external/speex/src/filters.c
vendored
858
external/speex/src/filters.c
vendored
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
/* Copyright (C) 2002-2006 Jean-Marc Valin
|
||||
File: filters.c
|
||||
Various analysis/synthesis filters
|
||||
|
||||
@ -30,263 +30,807 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "filters.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "arch.h"
|
||||
#include "math_approx.h"
|
||||
#include "ltp.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order)
|
||||
{
|
||||
int i;
|
||||
float tmp=1;
|
||||
for (i=0;i<order+1;i++)
|
||||
{
|
||||
lpc_out[i] = tmp * lpc_in[i];
|
||||
tmp *= gamma;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#include "filters_sse.h"
|
||||
#else
|
||||
void filter_mem2(float *x, float *num, float *den, float *y, int N, int ord, float *mem)
|
||||
#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,j;
|
||||
float xi,yi;
|
||||
for (i=0;i<N;i++)
|
||||
int i;
|
||||
spx_word16_t tmp=gamma;
|
||||
for (i=0;i<order;i++)
|
||||
{
|
||||
xi=x[i];
|
||||
y[i] = num[0]*xi + mem[0];
|
||||
yi=y[i];
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = mem[j+1] + num[j+1]*xi - den[j+1]*yi;
|
||||
}
|
||||
mem[ord-1] = num[ord]*xi - den[ord]*yi;
|
||||
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 iir_mem2(float *x, float *den, float *y, int N, int ord, float *mem)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DISABLE_ENCODER
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
#else /* FIXED_POINT */
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
#ifndef DISABLE_ENCODER
|
||||
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 /* DISABLE_ENCODER */
|
||||
|
||||
#endif /* !FIXED_POINT */
|
||||
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
|
||||
|
||||
#if !defined (DISABLE_WIDEBAND) && !defined (DISABLE_ENCODER)
|
||||
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));
|
||||
}
|
||||
#endif /* !defined (DISABLE_WIDEBAND) && !defined (DISABLE_ENCODER) */
|
||||
|
||||
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
|
||||
|
||||
#ifdef MERGE_FILTERS
|
||||
const spx_word16_t zeros[10] = {0,0,0,0,0,0,0,0,0,0};
|
||||
#endif /* MERGE_FILTERS */
|
||||
|
||||
#if !defined(OVERRIDE_FILTER_MEM16) && !defined(DISABLE_ENCODER)
|
||||
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++)
|
||||
{
|
||||
y[i] = x[i] + mem[0];
|
||||
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] = mem[j+1] - den[j+1]*y[i];
|
||||
mem[j] = MAC16_16(MAC16_16(mem[j+1], num[j],xi), den[j],nyi);
|
||||
}
|
||||
mem[ord-1] = - den[ord]*y[i];
|
||||
mem[ord-1] = ADD32(MULT16_16(num[ord-1],xi), MULT16_16(den[ord-1],nyi));
|
||||
y[i] = yi;
|
||||
}
|
||||
}
|
||||
#endif /* !defined(OVERRIDE_FILTER_MEM16) && !defined(DISABLE_ENCODER) */
|
||||
|
||||
#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
|
||||
|
||||
void fir_mem2(float *x, float *num, float *y, int N, int ord, float *mem)
|
||||
#if !defined(OVERRIDE_FIR_MEM16) && !defined(DISABLE_ENCODER)
|
||||
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;
|
||||
float xi;
|
||||
spx_word16_t xi,yi;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
xi=x[i];
|
||||
y[i] = num[0]*xi + mem[0];
|
||||
yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = mem[j+1] + num[j+1]*xi;
|
||||
mem[j] = MAC16_16(mem[j+1], num[j],xi);
|
||||
}
|
||||
mem[ord-1] = num[ord]*xi;
|
||||
mem[ord-1] = MULT16_16(num[ord-1],xi);
|
||||
y[i] = yi;
|
||||
}
|
||||
}
|
||||
#endif /* !defined(OVERRIDE_FIR_MEM16) && !defined(DISABLE_ENCODER) */
|
||||
|
||||
void syn_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack)
|
||||
#ifndef DISABLE_ENCODER
|
||||
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;
|
||||
float *mem = PUSH(stack,ord, float);
|
||||
VARDECL(spx_mem_t *mem);
|
||||
ALLOC(mem, ord, spx_mem_t);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
filter_mem2(xx, awk1, ak, y, N, ord, mem);
|
||||
iir_mem16(xx, ak, y, N, ord, mem, stack);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
iir_mem2(y, awk2, y, N, ord, mem);
|
||||
filter_mem16(y, awk1, awk2, y, N, ord, mem, stack);
|
||||
}
|
||||
|
||||
void residue_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *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)
|
||||
{
|
||||
int i;
|
||||
float *mem = PUSH(stack,ord, float);
|
||||
VARDECL(spx_mem_t *mem);
|
||||
ALLOC(mem, ord, spx_mem_t);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
filter_mem2(xx, ak, awk1, y, N, ord, mem);
|
||||
filter_mem16(xx, ak, awk1, y, N, ord, mem, stack);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
fir_mem2(y, awk2, y, N, ord, mem);
|
||||
fir_mem16(y, awk2, y, N, ord, mem, stack);
|
||||
}
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
#if !defined(OVERRIDE_COMPUTE_IMPULSE_RESPONSE) && !defined(DISABLE_ENCODER)
|
||||
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);
|
||||
|
||||
void qmf_decomp(float *xx, float *aa, float *y1, float *y2, int N, int M, float *mem, char *stack)
|
||||
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 /* !defined(OVERRIDE_COMPUTE_IMPULSE_RESPONSE) && !defined(DISABLE_ENCODER) */
|
||||
|
||||
#ifndef DISABLE_WIDEBAND
|
||||
/* 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;
|
||||
float *a;
|
||||
float *x;
|
||||
float *x2;
|
||||
VARDECL(spx_word16_t *a);
|
||||
VARDECL(spx_word16_t *x);
|
||||
spx_word16_t *x2;
|
||||
|
||||
a = PUSH(stack, M, float);
|
||||
x = PUSH(stack, N+M-1, float);
|
||||
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];
|
||||
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]=xx[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++)
|
||||
{
|
||||
y1[k]=0;
|
||||
y2[k]=0;
|
||||
spx_word32_t y1k=0, y2k=0;
|
||||
for (j=0;j<M2;j++)
|
||||
{
|
||||
y1[k]+=a[j]*(x[i+j]+x2[i-j]);
|
||||
y2[k]-=a[j]*(x[i+j]-x2[i-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++;
|
||||
y1[k]+=a[j]*(x[i+j]+x2[i-j]);
|
||||
y2[k]+=a[j]*(x[i+j]-x2[i-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));
|
||||
}
|
||||
for (i=0;i<M-1;i++)
|
||||
mem[i]=xx[N-i-1];
|
||||
}
|
||||
|
||||
/* By segher */
|
||||
void fir_mem_up(float *x, float *a, float *y, int N, int M, float *mem, char *stack)
|
||||
/* 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;
|
||||
float *xx=PUSH(stack, M+N-1, float);
|
||||
int M2, N2;
|
||||
VARDECL(spx_word16_t *xx1);
|
||||
VARDECL(spx_word16_t *xx2);
|
||||
|
||||
for (i = 0; i < N/2; i++)
|
||||
xx[2*i] = x[N/2-1-i];
|
||||
for (i = 0; i < M - 1; i += 2)
|
||||
xx[N+i] = mem[i+1];
|
||||
M2 = M>>1;
|
||||
N2 = N>>1;
|
||||
ALLOC(xx1, M2+N2, spx_word16_t);
|
||||
ALLOC(xx2, M2+N2, spx_word16_t);
|
||||
|
||||
for (i = 0; i < N; i += 4) {
|
||||
float y0, y1, y2, y3;
|
||||
float x0;
|
||||
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];
|
||||
|
||||
y0 = y1 = y2 = y3 = 0.f;
|
||||
x0 = xx[N-4-i];
|
||||
for (i = 0; i < N2; i += 2) {
|
||||
spx_sig_t y0, y1, y2, y3;
|
||||
spx_word16_t x10, x20;
|
||||
|
||||
for (j = 0; j < M; j += 4) {
|
||||
float x1;
|
||||
float a0, a1;
|
||||
y0 = y1 = y2 = y3 = 0;
|
||||
x10 = xx1[N2-2-i];
|
||||
x20 = xx2[N2-2-i];
|
||||
|
||||
a0 = a[j];
|
||||
a1 = a[j+1];
|
||||
x1 = xx[N-2+j-i];
|
||||
for (j = 0; j < M2; j += 2) {
|
||||
spx_word16_t x11, x21;
|
||||
spx_word16_t a0, a1;
|
||||
|
||||
y0 += a0 * x1;
|
||||
y1 += a1 * x1;
|
||||
y2 += a0 * x0;
|
||||
y3 += a1 * x0;
|
||||
a0 = a[2*j];
|
||||
a1 = a[2*j+1];
|
||||
x11 = xx1[N2-1+j-i];
|
||||
x21 = xx2[N2-1+j-i];
|
||||
|
||||
a0 = a[j+2];
|
||||
a1 = a[j+3];
|
||||
x0 = xx[N+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];
|
||||
|
||||
y0 += a0 * x0;
|
||||
y1 += a1 * x0;
|
||||
y2 += a0 * x1;
|
||||
y3 += a1 * x1;
|
||||
#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
|
||||
}
|
||||
y[i] = y0;
|
||||
y[i+1] = y1;
|
||||
y[i+2] = y2;
|
||||
y[i+3] = y3;
|
||||
#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 < M - 1; i += 2)
|
||||
mem[i+1] = xx[i];
|
||||
for (i = 0; i < M2; i++)
|
||||
mem1[2*i+1] = xx1[i];
|
||||
for (i = 0; i < M2; i++)
|
||||
mem2[2*i+1] = xx2[i];
|
||||
}
|
||||
#endif /* DISABLE_WIDEBAND */
|
||||
|
||||
|
||||
void comp_filter_mem_init (CombFilterMem *mem)
|
||||
#ifndef DISABLE_DECODER
|
||||
|
||||
#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
|
||||
|
||||
static int interp_pitch(
|
||||
spx_word16_t *exc, /*decoded excitation*/
|
||||
spx_word16_t *interp, /*decoded excitation*/
|
||||
int pitch, /*pitch period*/
|
||||
int len
|
||||
)
|
||||
{
|
||||
mem->last_pitch=0;
|
||||
mem->last_pitch_gain[0]=mem->last_pitch_gain[1]=mem->last_pitch_gain[2]=0;
|
||||
mem->smooth_gain=1;
|
||||
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 comb_filter_(
|
||||
float *exc, /*decoded excitation*/
|
||||
float *new_exc, /*enhanced excitation*/
|
||||
float *ak, /*LPC filter coefs*/
|
||||
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*/
|
||||
float *pitch_gain, /*pitch gain (3-tap)*/
|
||||
float comb_gain, /*gain of comb filter*/
|
||||
CombFilterMem *mem
|
||||
int max_pitch,
|
||||
spx_word16_t comb_gain, /*gain of comb filter*/
|
||||
char *stack
|
||||
)
|
||||
{
|
||||
int i;
|
||||
float exc_energy=0, new_exc_energy=0;
|
||||
float gain;
|
||||
float step;
|
||||
float fact;
|
||||
/*Compute excitation energy prior to enhancement*/
|
||||
for (i=0;i<nsf;i++)
|
||||
exc_energy+=exc[i]*exc[i];
|
||||
VARDECL(spx_word16_t *iexc);
|
||||
spx_word16_t old_ener, new_ener;
|
||||
int corr_pitch;
|
||||
|
||||
/*Some gain adjustment is pitch is too high or if unvoiced*/
|
||||
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++)
|
||||
{
|
||||
float g=0;
|
||||
g = .5*fabs(pitch_gain[0]+pitch_gain[1]+pitch_gain[2] +
|
||||
mem->last_pitch_gain[0] + mem->last_pitch_gain[1] + mem->last_pitch_gain[2]);
|
||||
if (g>1.3)
|
||||
comb_gain*=1.3/g;
|
||||
if (g<.5)
|
||||
comb_gain*=2*g;
|
||||
#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];
|
||||
}
|
||||
step = 1.0/nsf;
|
||||
fact=0;
|
||||
/*Apply pitch comb-filter (filter out noise between pitch harmonics)*/
|
||||
}
|
||||
#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++)
|
||||
{
|
||||
fact += step;
|
||||
|
||||
new_exc[i] = exc[i] + comb_gain * fact * (
|
||||
pitch_gain[0]*exc[i-pitch+1] +
|
||||
pitch_gain[1]*exc[i-pitch] +
|
||||
pitch_gain[2]*exc[i-pitch-1]
|
||||
)
|
||||
+ comb_gain * (1-fact) * (
|
||||
mem->last_pitch_gain[0]*exc[i-mem->last_pitch+1] +
|
||||
mem->last_pitch_gain[1]*exc[i-mem->last_pitch] +
|
||||
mem->last_pitch_gain[2]*exc[i-mem->last_pitch-1]
|
||||
);
|
||||
}
|
||||
|
||||
mem->last_pitch_gain[0] = pitch_gain[0];
|
||||
mem->last_pitch_gain[1] = pitch_gain[1];
|
||||
mem->last_pitch_gain[2] = pitch_gain[2];
|
||||
mem->last_pitch = pitch;
|
||||
|
||||
/*Gain after enhancement*/
|
||||
for (i=0;i<nsf;i++)
|
||||
new_exc_energy+=new_exc[i]*new_exc[i];
|
||||
|
||||
/*Compute scaling factor and normalize energy*/
|
||||
gain = sqrt(exc_energy)/sqrt(.1+new_exc_energy);
|
||||
if (gain < .5)
|
||||
gain=.5;
|
||||
if (gain>1)
|
||||
gain=1;
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
if (ABS16(exc[i])>16383)
|
||||
{
|
||||
mem->smooth_gain = .96*mem->smooth_gain + .04*gain;
|
||||
new_exc[i] *= mem->smooth_gain;
|
||||
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
|
||||
}
|
||||
|
||||
#endif /* DISABLE_DECODER */
|
||||
|
86
external/speex/src/filters.h
vendored
86
external/speex/src/filters.h
vendored
@ -1,7 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: filters.h
|
||||
Various analysis/synthesis filters
|
||||
|
||||
/* 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:
|
||||
@ -33,47 +35,71 @@
|
||||
#ifndef FILTERS_H
|
||||
#define FILTERS_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
typedef struct CombFilterMem {
|
||||
int last_pitch;
|
||||
float last_pitch_gain[3];
|
||||
float smooth_gain;
|
||||
} CombFilterMem;
|
||||
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
|
||||
|
||||
|
||||
void qmf_decomp(float *xx, float *aa, float *y1, float *y2, int N, int M, float *mem, char *stack);
|
||||
void fir_mem_up(float *x, float *a, float *y, int N, int M, float *mem, char *stack);
|
||||
#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 filter_mem2(float *x, float *num, float *den, float *y, int N, int ord, float *mem);
|
||||
void fir_mem2(float *x, float *num, float *y, int N, int ord, float *mem);
|
||||
void iir_mem2(float *x, float *den, float *y, int N, int ord, float *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);
|
||||
|
||||
#ifdef MERGE_FILTERS
|
||||
|
||||
#define OVERRIDE_IIR_MEM16
|
||||
#define OVERRIDE_FIR_MEM16
|
||||
extern const spx_word16_t zeros[];
|
||||
#define iir_mem16(x, den, y, N, ord, mem, stack) filter_mem16(x, zeros, den, y, N, ord, mem, stack)
|
||||
#define fir_mem16(x, num, y, N, ord, mem, stack) filter_mem16(x, num, zeros, y, N, ord, mem, stack)
|
||||
|
||||
#else /* MERGE_FILTERS */
|
||||
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);
|
||||
#endif /* MERGE_FILTERS */
|
||||
|
||||
/* Apply bandwidth expansion on LPC coef */
|
||||
void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order);
|
||||
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);
|
||||
|
||||
/* FIR filter */
|
||||
void fir_decim_mem(float *x, float *a, float *y, int N, int M, float *mem);
|
||||
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 syn_percep_zero(float *x, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack);
|
||||
|
||||
void residue_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack);
|
||||
|
||||
void comp_filter_mem_init (CombFilterMem *mem);
|
||||
|
||||
void comb_filter_(
|
||||
float *exc, /*decoded excitation*/
|
||||
float *new_exc, /*enhanced excitation*/
|
||||
float *ak, /*LPC filter coefs*/
|
||||
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*/
|
||||
float *pitch_gain, /*pitch gain (3-tap)*/
|
||||
float comb_gain, /*gain of comb filter*/
|
||||
CombFilterMem *mem
|
||||
int max_pitch, /*pitch gain (3-tap)*/
|
||||
spx_word16_t comb_gain, /*gain of comb filter*/
|
||||
char *stack
|
||||
);
|
||||
|
||||
|
||||
#define filter10(x, num, den, y, N, mem, stack) filter_mem16(x, num, den, y, N, 10, mem, stack)
|
||||
|
||||
|
||||
#endif
|
||||
|
96
external/speex/src/filters_arm4.h
vendored
Normal file
96
external/speex/src/filters_arm4.h
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/* 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"
|
||||
"\tcmp %4, %1 \n"
|
||||
"\tmovgt %1, %4 \n"
|
||||
"\tcmp %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;
|
||||
}
|
||||
|
520
external/speex/src/filters_bfin.h
vendored
Normal file
520
external/speex/src/filters_bfin.h
vendored
Normal file
@ -0,0 +1,520 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "bfin.h"
|
||||
|
||||
#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", "ASTAT" BFIN_HWLOOP0_REGS
|
||||
);
|
||||
|
||||
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", "ASTAT" BFIN_HWLOOP0_REGS
|
||||
);
|
||||
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",
|
||||
"ASTAT" BFIN_HWLOOP0_REGS BFIN_HWLOOP1_REGS
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#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",
|
||||
"ASTAT" BFIN_HWLOOP0_REGS BFIN_HWLOOP1_REGS
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#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",
|
||||
"ASTAT" BFIN_HWLOOP0_REGS BFIN_HWLOOP1_REGS
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#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
|
547
external/speex/src/filters_sse.h
vendored
547
external/speex/src/filters_sse.h
vendored
@ -1,7 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: filters.c
|
||||
Various analysis/synthesis filters
|
||||
|
||||
/* 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:
|
||||
@ -30,260 +32,305 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
void filter_mem2(float *x, float *_num, float *_den, float *y, int N, int ord, float *_mem)
|
||||
#include <xmmintrin.h>
|
||||
|
||||
void filter_mem16_10(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
float __num[20], __den[20], __mem[20];
|
||||
float *num, *den, *mem;
|
||||
__m128 num[3], den[3], mem[3];
|
||||
|
||||
int i;
|
||||
|
||||
num = (float*)(((int)(__num+4))&0xfffffff0)-1;
|
||||
den = (float*)(((int)(__den+4))&0xfffffff0)-1;
|
||||
mem = (float*)(((int)(__mem+4))&0xfffffff0)-1;
|
||||
for (i=0;i<=10;i++)
|
||||
num[i]=den[i]=0;
|
||||
for (i=0;i<10;i++)
|
||||
mem[i]=0;
|
||||
|
||||
for (i=0;i<ord+1;i++)
|
||||
/* Copy numerator, denominator and memory to aligned xmm */
|
||||
for (i=0;i<2;i++)
|
||||
{
|
||||
num[i]=_num[i];
|
||||
den[i]=_den[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<ord;i++)
|
||||
mem[i]=_mem[i];
|
||||
for (i=0;i<N;i+=4)
|
||||
{
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmovss (%1), %%xmm0\n"
|
||||
"\tmovss (%0), %%xmm1\n"
|
||||
"\taddss %%xmm0, %%xmm1\n"
|
||||
"\tmovss %%xmm1, (%2)\n"
|
||||
"\tshufps $0x00, %%xmm0, %%xmm0\n"
|
||||
"\tshufps $0x00, %%xmm1, %%xmm1\n"
|
||||
|
||||
"\tmovaps 4(%3), %%xmm2\n"
|
||||
"\tmovaps 4(%4), %%xmm3\n"
|
||||
"\tmulps %%xmm0, %%xmm2\n"
|
||||
"\tmulps %%xmm1, %%xmm3\n"
|
||||
"\tmovaps 20(%3), %%xmm4\n"
|
||||
"\tmulps %%xmm0, %%xmm4\n"
|
||||
"\taddps 4(%0), %%xmm2\n"
|
||||
"\tmovaps 20(%4), %%xmm5\n"
|
||||
"\tmulps %%xmm1, %%xmm5\n"
|
||||
"\taddps 20(%0), %%xmm4\n"
|
||||
"\tsubps %%xmm3, %%xmm2\n"
|
||||
"\tmovups %%xmm2, (%0)\n"
|
||||
"\tsubps %%xmm5, %%xmm4\n"
|
||||
"\tmovups %%xmm4, 16(%0)\n"
|
||||
|
||||
"\tmovss 36(%3), %%xmm2\n"
|
||||
"\tmulss %%xmm0, %%xmm2\n"
|
||||
"\tmovss 36(%4), %%xmm3\n"
|
||||
"\tmulss %%xmm1, %%xmm3\n"
|
||||
"\taddss 36(%0), %%xmm2\n"
|
||||
"\tmovss 40(%3), %%xmm4\n"
|
||||
"\tmulss %%xmm0, %%xmm4\n"
|
||||
"\tmovss 40(%4), %%xmm5\n"
|
||||
"\tmulss %%xmm1, %%xmm5\n"
|
||||
"\tsubss %%xmm3, %%xmm2\n"
|
||||
"\tmovss %%xmm2, 32(%0) \n"
|
||||
"\tsubss %%xmm5, %%xmm4\n"
|
||||
"\tmovss %%xmm4, 36(%0)\n"
|
||||
|
||||
|
||||
|
||||
"\tmovss 4(%1), %%xmm0\n"
|
||||
"\tmovss (%0), %%xmm1\n"
|
||||
"\taddss %%xmm0, %%xmm1\n"
|
||||
"\tmovss %%xmm1, 4(%2)\n"
|
||||
"\tshufps $0x00, %%xmm0, %%xmm0\n"
|
||||
"\tshufps $0x00, %%xmm1, %%xmm1\n"
|
||||
|
||||
"\tmovaps 4(%3), %%xmm2\n"
|
||||
"\tmovaps 4(%4), %%xmm3\n"
|
||||
"\tmulps %%xmm0, %%xmm2\n"
|
||||
"\tmulps %%xmm1, %%xmm3\n"
|
||||
"\tmovaps 20(%3), %%xmm4\n"
|
||||
"\tmulps %%xmm0, %%xmm4\n"
|
||||
"\taddps 4(%0), %%xmm2\n"
|
||||
"\tmovaps 20(%4), %%xmm5\n"
|
||||
"\tmulps %%xmm1, %%xmm5\n"
|
||||
"\taddps 20(%0), %%xmm4\n"
|
||||
"\tsubps %%xmm3, %%xmm2\n"
|
||||
"\tmovups %%xmm2, (%0)\n"
|
||||
"\tsubps %%xmm5, %%xmm4\n"
|
||||
"\tmovups %%xmm4, 16(%0)\n"
|
||||
|
||||
"\tmovss 36(%3), %%xmm2\n"
|
||||
"\tmulss %%xmm0, %%xmm2\n"
|
||||
"\tmovss 36(%4), %%xmm3\n"
|
||||
"\tmulss %%xmm1, %%xmm3\n"
|
||||
"\taddss 36(%0), %%xmm2\n"
|
||||
"\tmovss 40(%3), %%xmm4\n"
|
||||
"\tmulss %%xmm0, %%xmm4\n"
|
||||
"\tmovss 40(%4), %%xmm5\n"
|
||||
"\tmulss %%xmm1, %%xmm5\n"
|
||||
"\tsubss %%xmm3, %%xmm2\n"
|
||||
"\tmovss %%xmm2, 32(%0) \n"
|
||||
"\tsubss %%xmm5, %%xmm4\n"
|
||||
"\tmovss %%xmm4, 36(%0)\n"
|
||||
|
||||
|
||||
|
||||
"\tmovss 8(%1), %%xmm0\n"
|
||||
"\tmovss (%0), %%xmm1\n"
|
||||
"\taddss %%xmm0, %%xmm1\n"
|
||||
"\tmovss %%xmm1, 8(%2)\n"
|
||||
"\tshufps $0x00, %%xmm0, %%xmm0\n"
|
||||
"\tshufps $0x00, %%xmm1, %%xmm1\n"
|
||||
|
||||
"\tmovaps 4(%3), %%xmm2\n"
|
||||
"\tmovaps 4(%4), %%xmm3\n"
|
||||
"\tmulps %%xmm0, %%xmm2\n"
|
||||
"\tmulps %%xmm1, %%xmm3\n"
|
||||
"\tmovaps 20(%3), %%xmm4\n"
|
||||
"\tmulps %%xmm0, %%xmm4\n"
|
||||
"\taddps 4(%0), %%xmm2\n"
|
||||
"\tmovaps 20(%4), %%xmm5\n"
|
||||
"\tmulps %%xmm1, %%xmm5\n"
|
||||
"\taddps 20(%0), %%xmm4\n"
|
||||
"\tsubps %%xmm3, %%xmm2\n"
|
||||
"\tmovups %%xmm2, (%0)\n"
|
||||
"\tsubps %%xmm5, %%xmm4\n"
|
||||
"\tmovups %%xmm4, 16(%0)\n"
|
||||
|
||||
"\tmovss 36(%3), %%xmm2\n"
|
||||
"\tmulss %%xmm0, %%xmm2\n"
|
||||
"\tmovss 36(%4), %%xmm3\n"
|
||||
"\tmulss %%xmm1, %%xmm3\n"
|
||||
"\taddss 36(%0), %%xmm2\n"
|
||||
"\tmovss 40(%3), %%xmm4\n"
|
||||
"\tmulss %%xmm0, %%xmm4\n"
|
||||
"\tmovss 40(%4), %%xmm5\n"
|
||||
"\tmulss %%xmm1, %%xmm5\n"
|
||||
"\tsubss %%xmm3, %%xmm2\n"
|
||||
"\tmovss %%xmm2, 32(%0) \n"
|
||||
"\tsubss %%xmm5, %%xmm4\n"
|
||||
"\tmovss %%xmm4, 36(%0)\n"
|
||||
|
||||
|
||||
|
||||
"\tmovss 12(%1), %%xmm0\n"
|
||||
"\tmovss (%0), %%xmm1\n"
|
||||
"\taddss %%xmm0, %%xmm1\n"
|
||||
"\tmovss %%xmm1, 12(%2)\n"
|
||||
"\tshufps $0x00, %%xmm0, %%xmm0\n"
|
||||
"\tshufps $0x00, %%xmm1, %%xmm1\n"
|
||||
|
||||
"\tmovaps 4(%3), %%xmm2\n"
|
||||
"\tmovaps 4(%4), %%xmm3\n"
|
||||
"\tmulps %%xmm0, %%xmm2\n"
|
||||
"\tmulps %%xmm1, %%xmm3\n"
|
||||
"\tmovaps 20(%3), %%xmm4\n"
|
||||
"\tmulps %%xmm0, %%xmm4\n"
|
||||
"\taddps 4(%0), %%xmm2\n"
|
||||
"\tmovaps 20(%4), %%xmm5\n"
|
||||
"\tmulps %%xmm1, %%xmm5\n"
|
||||
"\taddps 20(%0), %%xmm4\n"
|
||||
"\tsubps %%xmm3, %%xmm2\n"
|
||||
"\tmovups %%xmm2, (%0)\n"
|
||||
"\tsubps %%xmm5, %%xmm4\n"
|
||||
"\tmovups %%xmm4, 16(%0)\n"
|
||||
|
||||
"\tmovss 36(%3), %%xmm2\n"
|
||||
"\tmulss %%xmm0, %%xmm2\n"
|
||||
"\tmovss 36(%4), %%xmm3\n"
|
||||
"\tmulss %%xmm1, %%xmm3\n"
|
||||
"\taddss 36(%0), %%xmm2\n"
|
||||
"\tmovss 40(%3), %%xmm4\n"
|
||||
"\tmulss %%xmm0, %%xmm4\n"
|
||||
"\tmovss 40(%4), %%xmm5\n"
|
||||
"\tmulss %%xmm1, %%xmm5\n"
|
||||
"\tsubss %%xmm3, %%xmm2\n"
|
||||
"\tmovss %%xmm2, 32(%0) \n"
|
||||
"\tsubss %%xmm5, %%xmm4\n"
|
||||
"\tmovss %%xmm4, 36(%0)\n"
|
||||
|
||||
: : "r" (mem), "r" (x+i), "r" (y+i), "r" (num), "r" (den)
|
||||
: "memory" );
|
||||
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
_mem[i]=mem[i];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void iir_mem2(float *x, float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
float __den[20], __mem[20];
|
||||
float *den, *mem;
|
||||
int i;
|
||||
|
||||
den = (float*)(((int)(__den+4))&0xfffffff0)-1;
|
||||
mem = (float*)(((int)(__mem+4))&0xfffffff0)-1;
|
||||
for (i=0;i<=10;i++)
|
||||
den[i]=0;
|
||||
for (i=0;i<10;i++)
|
||||
mem[i]=0;
|
||||
for (i=0;i<ord+1;i++)
|
||||
{
|
||||
den[i]=_den[i];
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=_mem[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++)
|
||||
{
|
||||
#if 0
|
||||
y[i] = x[i] + mem[0];
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = mem[j+1] - den[j+1]*y[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]));
|
||||
}
|
||||
mem[ord-1] = - den[ord]*y[i];
|
||||
#else
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmovss (%1), %%xmm0\n"
|
||||
"\tmovss (%0), %%xmm1\n"
|
||||
"\taddss %%xmm0, %%xmm1\n"
|
||||
"\tmovss %%xmm1, (%2)\n"
|
||||
"\tshufps $0x00, %%xmm0, %%xmm0\n"
|
||||
"\tshufps $0x00, %%xmm1, %%xmm1\n"
|
||||
|
||||
|
||||
"\tmovaps 4(%3), %%xmm2\n"
|
||||
"\tmovaps 20(%3), %%xmm3\n"
|
||||
"\tmulps %%xmm1, %%xmm2\n"
|
||||
"\tmulps %%xmm1, %%xmm3\n"
|
||||
"\tmovss 36(%3), %%xmm4\n"
|
||||
"\tmovss 40(%3), %%xmm5\n"
|
||||
"\tmulss %%xmm1, %%xmm4\n"
|
||||
"\tmulss %%xmm1, %%xmm5\n"
|
||||
"\tmovaps 4(%0), %%xmm6\n"
|
||||
"\tsubps %%xmm2, %%xmm6\n"
|
||||
"\tmovups %%xmm6, (%0)\n"
|
||||
"\tmovaps 20(%0), %%xmm7\n"
|
||||
"\tsubps %%xmm3, %%xmm7\n"
|
||||
"\tmovups %%xmm7, 16(%0)\n"
|
||||
|
||||
|
||||
"\tmovss 36(%0), %%xmm7\n"
|
||||
"\tsubss %%xmm4, %%xmm7\n"
|
||||
"\tmovss %%xmm7, 32(%0) \n"
|
||||
"\txorps %%xmm2, %%xmm2\n"
|
||||
"\tsubss %%xmm5, %%xmm2\n"
|
||||
"\tmovss %%xmm2, 36(%0)\n"
|
||||
|
||||
: : "r" (mem), "r" (x+i), "r" (y+i), "r" (den)
|
||||
: "memory" );
|
||||
#endif
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
_mem[i]=mem[i];
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
148
external/speex/src/fixed_arm4.h
vendored
Normal file
148
external/speex/src/fixed_arm4.h
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
/* 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
|
160
external/speex/src/fixed_arm5e.h
vendored
Normal file
160
external/speex/src/fixed_arm5e.h
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
/* 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 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
|
176
external/speex/src/fixed_bfin.h
vendored
Normal file
176
external/speex/src/fixed_bfin.h
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
/* 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
|
||||
|
||||
#include "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", "ASTAT" BFIN_HWLOOP0_REGS);
|
||||
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", "ASTAT" BFIN_HWLOOP0_REGS);
|
||||
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)
|
||||
: "ASTAT"
|
||||
);
|
||||
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", "ASTAT"
|
||||
);
|
||||
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", "ASTAT"
|
||||
);
|
||||
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", "ASTAT"
|
||||
);
|
||||
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", "ASTAT"
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
484
external/speex/src/fixed_debug.h
vendored
Normal file
484
external/speex/src/fixed_debug.h
vendored
Normal file
@ -0,0 +1,484 @@
|
||||
/* 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 = (int)((unsigned)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 = (long long)((unsigned long long)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_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
|
102
external/speex/src/fixed_generic.h
vendored
Normal file
102
external/speex/src/fixed_generic.h
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
/* 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) ((spx_int16_t)((spx_uint16_t)(a) << (shift)))
|
||||
#define SHR32(a,shift) ((a) >> (shift))
|
||||
#define SHL32(a,shift) ((spx_int32_t)((spx_uint32_t)(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_int32_t)((spx_uint32_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_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_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
|
258
external/speex/src/gain_table.c
vendored
258
external/speex/src/gain_table.c
vendored
@ -29,132 +29,132 @@
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char gain_cdbk_nb[384] = {
|
||||
-32,-32,-32,
|
||||
-28,-67,-5,
|
||||
-42,-6,-32,
|
||||
-57,-10,-54,
|
||||
-16,27,-41,
|
||||
19,-19,-40,
|
||||
-45,24,-21,
|
||||
-8,-14,-18,
|
||||
1,14,-58,
|
||||
-18,-88,-39,
|
||||
-38,21,-18,
|
||||
-19,20,-43,
|
||||
10,17,-48,
|
||||
-52,-58,-13,
|
||||
-44,-1,-11,
|
||||
-12,-11,-34,
|
||||
14,0,-46,
|
||||
-37,-35,-34,
|
||||
-25,44,-30,
|
||||
6,-4,-63,
|
||||
-31,43,-41,
|
||||
-23,30,-43,
|
||||
-43,26,-14,
|
||||
-33,1,-13,
|
||||
-13,18,-37,
|
||||
-46,-73,-45,
|
||||
-36,24,-25,
|
||||
-36,-11,-20,
|
||||
-25,12,-18,
|
||||
-36,-69,-59,
|
||||
-45,6,8,
|
||||
-22,-14,-24,
|
||||
-1,13,-44,
|
||||
-39,-48,-26,
|
||||
-32,31,-37,
|
||||
-33,15,-46,
|
||||
-24,30,-36,
|
||||
-41,31,-23,
|
||||
-50,22,-4,
|
||||
-22,2,-21,
|
||||
-17,30,-34,
|
||||
-7,-60,-28,
|
||||
-38,42,-28,
|
||||
-44,-11,21,
|
||||
-16,8,-44,
|
||||
-39,-55,-43,
|
||||
-11,-35,26,
|
||||
-9,0,-34,
|
||||
-8,121,-81,
|
||||
7,-16,-22,
|
||||
-37,33,-31,
|
||||
-27,-7,-36,
|
||||
-34,70,-57,
|
||||
-37,-11,-48,
|
||||
-40,17,-1,
|
||||
-33,6,-6,
|
||||
-9,0,-20,
|
||||
-21,69,-33,
|
||||
-29,33,-31,
|
||||
-55,12,-1,
|
||||
-33,27,-22,
|
||||
-50,-33,-47,
|
||||
-50,54,51,
|
||||
-1,-5,-44,
|
||||
-4,22,-40,
|
||||
-39,-66,-25,
|
||||
-33,1,-26,
|
||||
-24,-23,-25,
|
||||
-11,21,-45,
|
||||
-25,-45,-19,
|
||||
-43,105,-16,
|
||||
5,-21,1,
|
||||
-16,11,-33,
|
||||
-13,-99,-4,
|
||||
-37,33,-15,
|
||||
-25,37,-63,
|
||||
-36,24,-31,
|
||||
-53,-56,-38,
|
||||
-41,-4,4,
|
||||
-33,13,-30,
|
||||
49,52,-94,
|
||||
-5,-30,-15,
|
||||
1,38,-40,
|
||||
-23,12,-36,
|
||||
-17,40,-47,
|
||||
-37,-41,-39,
|
||||
-49,34,0,
|
||||
-18,-7,-4,
|
||||
-16,17,-27,
|
||||
30,5,-62,
|
||||
4,48,-68,
|
||||
-43,11,-11,
|
||||
-18,19,-15,
|
||||
-23,-62,-39,
|
||||
-42,10,-2,
|
||||
-21,-13,-13,
|
||||
-9,13,-47,
|
||||
-23,-62,-24,
|
||||
-44,60,-21,
|
||||
-18,-3,-52,
|
||||
-22,22,-36,
|
||||
-75,57,16,
|
||||
-19,3,10,
|
||||
-29,23,-38,
|
||||
-5,-62,-51,
|
||||
-51,40,-18,
|
||||
-42,13,-24,
|
||||
-34,14,-20,
|
||||
-56,-75,-26,
|
||||
-26,32,15,
|
||||
-26,17,-29,
|
||||
-7,28,-52,
|
||||
-12,-30,5,
|
||||
-5,-48,-5,
|
||||
2,2,-43,
|
||||
21,16,16,
|
||||
-25,-45,-32,
|
||||
-43,18,-10,
|
||||
9,0,-1,
|
||||
-1,7,-30,
|
||||
19,-48,-4,
|
||||
-28,25,-29,
|
||||
-22,0,-31,
|
||||
-32,17,-10,
|
||||
-64,-41,-62,
|
||||
-52,15,16,
|
||||
-30,-22,-32,
|
||||
-7,9,-38};
|
||||
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};
|
||||
|
66
external/speex/src/gain_table_lbr.c
vendored
66
external/speex/src/gain_table_lbr.c
vendored
@ -29,36 +29,36 @@
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char gain_cdbk_lbr[96] = {
|
||||
-32,-32,-32,
|
||||
-31,-58,-16,
|
||||
-41,-24,-43,
|
||||
-56,-22,-55,
|
||||
-13,33,-41,
|
||||
-4,-39,-9,
|
||||
-41,15,-12,
|
||||
-8,-15,-12,
|
||||
1,2,-44,
|
||||
-22,-66,-42,
|
||||
-38,28,-23,
|
||||
-21,14,-37,
|
||||
0,21,-50,
|
||||
-53,-71,-27,
|
||||
-37,-1,-19,
|
||||
-19,-5,-28,
|
||||
6,65,-44,
|
||||
-33,-48,-33,
|
||||
-40,57,-14,
|
||||
-17,4,-45,
|
||||
-31,38,-33,
|
||||
-23,28,-40,
|
||||
-43,29,-12,
|
||||
-34,13,-23,
|
||||
-16,15,-27,
|
||||
-14,-82,-15,
|
||||
-31,25,-32,
|
||||
-21,5,-5,
|
||||
-47,-63,-51,
|
||||
-46,12,3,
|
||||
-28,-17,-29,
|
||||
-10,14,-40};
|
||||
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};
|
||||
|
2
external/speex/src/hexc_10_32_table.c
vendored
2
external/speex/src/hexc_10_32_table.c
vendored
@ -30,7 +30,7 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char hexc_10_32_table[320] = {
|
||||
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,
|
||||
|
4
external/speex/src/hexc_table.c
vendored
4
external/speex/src/hexc_table.c
vendored
@ -30,7 +30,7 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char hexc_table[1024] = {
|
||||
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,
|
||||
@ -52,7 +52,7 @@ signed char hexc_table[1024] = {
|
||||
-1, 6, -25, 14, -22, -20, 47, -11,
|
||||
16, 2, 38, -23, -19, -30, -9, 40,
|
||||
-11, 5, 4, -6, 8, 26, -21, -11,
|
||||
131, 4, 1, 6, -9, 2, -7, -2,
|
||||
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,
|
||||
|
4
external/speex/src/high_lsp_tables.c
vendored
4
external/speex/src/high_lsp_tables.c
vendored
@ -29,7 +29,7 @@
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char high_lsp_cdbk[512]={
|
||||
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,
|
||||
@ -96,7 +96,7 @@ signed char high_lsp_cdbk[512]={
|
||||
-42,-74,-48,21,-4,70,52,10};
|
||||
|
||||
|
||||
signed char high_lsp_cdbk2[512]={
|
||||
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,
|
||||
|
523
external/speex/src/kiss_fft.c
vendored
Normal file
523
external/speex/src/kiss_fft.c
vendored
Normal file
@ -0,0 +1,523 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#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 declares 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);
|
||||
}
|
||||
|
108
external/speex/src/kiss_fft.h
vendored
Normal file
108
external/speex/src/kiss_fft.h
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
#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
|
297
external/speex/src/kiss_fftr.c
vendored
Normal file
297
external/speex/src/kiss_fftr.c
vendored
Normal file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#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);
|
||||
}
|
51
external/speex/src/kiss_fftr.h
vendored
Normal file
51
external/speex/src/kiss_fftr.h
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
#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
|
149
external/speex/src/lpc.c
vendored
149
external/speex/src/lpc.c
vendored
@ -17,7 +17,7 @@
|
||||
Carsten Bormann
|
||||
|
||||
|
||||
Code slightly modified by Jean-Marc Valin
|
||||
Code modified by Jean-Marc Valin
|
||||
|
||||
Speex License:
|
||||
|
||||
@ -49,9 +49,19 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_ENCODER
|
||||
|
||||
/* LPC- and Reflection Coefficients
|
||||
#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
|
||||
@ -61,45 +71,103 @@
|
||||
/* Invented by N. Levinson in 1947, modified by J. Durbin in 1959.
|
||||
*/
|
||||
|
||||
#include "lpc.h"
|
||||
|
||||
float /* returns minimum mean square error */
|
||||
wld(
|
||||
float * lpc, /* [0...p-1] LPC coefficients */
|
||||
const float * ac, /* in: [0...p] autocorrelation values */
|
||||
float * ref, /* out: [0...p-1] reflection coef's */
|
||||
int p
|
||||
)
|
||||
/* 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; float r, error = ac[0];
|
||||
|
||||
if (ac[0] == 0) {
|
||||
for (i = 0; i < p; i++) ref[i] = 0; return 0; }
|
||||
int i, j;
|
||||
spx_word16_t r;
|
||||
spx_word16_t error = ac[0];
|
||||
|
||||
for (i = 0; i < p; i++) {
|
||||
|
||||
/* Sum up this iteration's reflection coefficient.
|
||||
*/
|
||||
r = -ac[i + 1];
|
||||
for (j = 0; j < i; j++) r -= lpc[j] * ac[i - j];
|
||||
ref[i] = r /= error;
|
||||
|
||||
/* Update LPC coefficients and total error.
|
||||
*/
|
||||
/* 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/2; j++) {
|
||||
float tmp = lpc[j];
|
||||
lpc[j] += r * lpc[i-1-j];
|
||||
lpc[i-1-j] += r * tmp;
|
||||
for (j = 0; j < (i+1)>>1; j++)
|
||||
{
|
||||
spx_word16_t tmp1, tmp2;
|
||||
/* It could be that j == i-1-j, in which case, we're updating the same value twice, which is OK */
|
||||
tmp1 = lpc[j];
|
||||
tmp2 = lpc[i-1-j];
|
||||
lpc[j] = MAC16_16_P13(tmp1,r,tmp2);
|
||||
lpc[i-1-j] = MAC16_16_P13(tmp2,r,tmp1);
|
||||
}
|
||||
if (i % 2) lpc[j] += lpc[j] * r;
|
||||
|
||||
error *= 1.0 - r * 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
|
||||
@ -107,13 +175,24 @@ wld(
|
||||
* for lags between 0 and lag-1, and x == 0 outside 0...n-1
|
||||
*/
|
||||
void _spx_autocorr(
|
||||
const float * x, /* in: [0...n-1] samples x */
|
||||
float *ac, /* out: [0...lag-1] ac values */
|
||||
int lag, int n)
|
||||
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];
|
||||
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
|
||||
|
||||
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
25
external/speex/src/lpc.h
vendored
25
external/speex/src/lpc.h
vendored
@ -1,7 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: lpc.h
|
||||
Functions for LPC (Linear Prediction Coefficients) analysis
|
||||
|
||||
/* 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:
|
||||
@ -33,16 +35,17 @@
|
||||
#ifndef LPC_H
|
||||
#define LPC_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
void _spx_autocorr(
|
||||
const float * x, /* in: [0...n-1] samples x */
|
||||
float *ac, /* out: [0...lag-1] ac values */
|
||||
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);
|
||||
|
||||
float /* returns minimum mean square error */
|
||||
wld(
|
||||
float * lpc, /* [0...p-1] LPC coefficients */
|
||||
const float * ac, /* in: [0...p] autocorrelation values */
|
||||
float * ref, /* out: [0...p-1] reflection coef's */
|
||||
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
|
||||
);
|
||||
|
||||
|
134
external/speex/src/lpc_bfin.h
vendored
Normal file
134
external/speex/src/lpc_bfin.h
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "bfin.h"
|
||||
|
||||
#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",
|
||||
"ASTAT" BFIN_HWLOOP0_REGS BFIN_HWLOOP1_REGS
|
||||
);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
487
external/speex/src/lsp.c
vendored
487
external/speex/src/lsp.c
vendored
@ -1,12 +1,11 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Original copyright
|
||||
FILE........: AKSLSPD.C
|
||||
TYPE........: Turbo C
|
||||
COMPANY.....: Voicetronix
|
||||
FILE........: lsp.c
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/2/93
|
||||
|
||||
Modified by Jean-Marc Valin
|
||||
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
|
||||
@ -43,10 +42,51 @@ Modified by Jean-Marc Valin
|
||||
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}.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include "lsp.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
#include "math_approx.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 /* pi */
|
||||
@ -56,6 +96,34 @@ Modified by Jean-Marc Valin
|
||||
#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
|
||||
|
||||
#ifndef DISABLE_ENCODER
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FUNCTION....: cheb_poly_eva()
|
||||
@ -67,37 +135,68 @@ Modified by Jean-Marc Valin
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
|
||||
static float cheb_poly_eva(float *coef,float x,int m,char *stack)
|
||||
/* float coef[] coefficients of the polynomial to be evaluated */
|
||||
/* float x the point where polynomial is to be evaluated */
|
||||
/* int m order of the polynomial */
|
||||
#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;
|
||||
float *T,sum;
|
||||
int m2=m>>1;
|
||||
spx_word16_t b0, b1;
|
||||
spx_word32_t sum;
|
||||
|
||||
/* Allocate memory for Chebyshev series formulation */
|
||||
T=PUSH(stack, m2+1, float);
|
||||
/*Prevents overflows*/
|
||||
if (x>16383)
|
||||
x = 16383;
|
||||
if (x<-16383)
|
||||
x = -16383;
|
||||
|
||||
/* Initialise values */
|
||||
T[0]=1;
|
||||
T[1]=x;
|
||||
b1=16384;
|
||||
b0=x;
|
||||
|
||||
/* Evaluate Chebyshev series formulation using iterative approach */
|
||||
/* Evaluate polynomial and return value also free memory space */
|
||||
sum = coef[m2] + coef[m2-1]*x;
|
||||
x *= 2;
|
||||
for(i=2;i<=m2;i++)
|
||||
/* Evaluate Chebyshev series formulation using an iterative approach */
|
||||
sum = ADD32(EXTEND32(coef[m]), EXTEND32(MULT16_16_P14(coef[m-1],x)));
|
||||
for(i=2;i<=m;i++)
|
||||
{
|
||||
T[i] = x*T[i-1] - T[i-2];
|
||||
sum += coef[m2-i] * T[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
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
@ -111,8 +210,14 @@ static float cheb_poly_eva(float *coef,float x,int m,char *stack)
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#define SIGN_CHANGE(a,b) ((((a)^(b))&0x80000000)||(b==0))
|
||||
#else
|
||||
#define SIGN_CHANGE(a,b) (((a)*(b))<0.0)
|
||||
#endif
|
||||
|
||||
int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack)
|
||||
|
||||
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 */
|
||||
@ -121,27 +226,25 @@ int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack)
|
||||
|
||||
|
||||
{
|
||||
|
||||
float psuml,psumr,psumm,temp_xr,xl,xr,xm=0;
|
||||
float temp_psumr/*,temp_qsumr*/;
|
||||
int i,j,m,flag,k;
|
||||
float *Q; /* ptrs for memory allocation */
|
||||
float *P;
|
||||
float *px; /* ptrs of respective P'(z) & Q'(z) */
|
||||
float *qx;
|
||||
float *p;
|
||||
float *q;
|
||||
float *pt; /* ptr used for cheb_poly_eval()
|
||||
spx_word16_t temp_xr,xl,xr,xm=0;
|
||||
spx_word32_t psuml,psumr,psumm,temp_psumr/*,temp_qsumr*/;
|
||||
int i,j,m,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 */
|
||||
Q = PUSH(stack, (m+1), float);
|
||||
P = PUSH(stack, (m+1), float);
|
||||
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)) */
|
||||
@ -150,11 +253,36 @@ int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack)
|
||||
qx = Q;
|
||||
p = px;
|
||||
q = qx;
|
||||
*px++ = 1.0;
|
||||
*qx++ = 1.0;
|
||||
for(i=1;i<=m;i++){
|
||||
*px++ = a[i]+a[lpcrdr+1-i]-*p++;
|
||||
*qx++ = a[i]-a[lpcrdr+1-i]+*q++;
|
||||
|
||||
#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;
|
||||
@ -164,33 +292,51 @@ int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack)
|
||||
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 = 1.0; /* start at point xl = 1 */
|
||||
|
||||
xl = FREQ_SCALE; /* start at point xl = 1 */
|
||||
|
||||
for(j=0;j<lpcrdr;j++){
|
||||
if(j%2) /* determines whether P' or Q' is eval. */
|
||||
pt = qx;
|
||||
if(j&1) /* determines whether P' or Q' is eval. */
|
||||
pt = Q16;
|
||||
else
|
||||
pt = px;
|
||||
pt = P16;
|
||||
|
||||
psuml = cheb_poly_eva(pt,xl,lpcrdr,stack); /* evals poly. at xl */
|
||||
flag = 1;
|
||||
while(flag && (xr >= -1.0)){
|
||||
float dd;
|
||||
psuml = cheb_poly_eva(pt,xl,m,stack); /* evals poly. at xl */
|
||||
|
||||
while(xr >= -FREQ_SCALE){
|
||||
spx_word16_t dd;
|
||||
/* Modified by JMV to provide smaller steps around x=+-1 */
|
||||
dd=(delta*(1-.9*xl*xl));
|
||||
#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;
|
||||
|
||||
xr = xl - dd; /* interval spacing */
|
||||
psumr = cheb_poly_eva(pt,xr,lpcrdr,stack);/* poly(xl-delta_x) */
|
||||
#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;
|
||||
|
||||
@ -203,27 +349,33 @@ int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack)
|
||||
between xm and xr else set interval between xl and xr and repeat till
|
||||
root is located within the specified limits */
|
||||
|
||||
if((psumr*psuml)<0.0){
|
||||
if(SIGN_CHANGE(psumr,psuml))
|
||||
{
|
||||
roots++;
|
||||
|
||||
psumm=psuml;
|
||||
for(k=0;k<=nb;k++){
|
||||
xm = (xl+xr)/2; /* bisect the interval */
|
||||
psumm=cheb_poly_eva(pt,xm,lpcrdr,stack);
|
||||
if(psumm*psuml>0.){
|
||||
#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{
|
||||
} else {
|
||||
psumr=psumm;
|
||||
xr=xm;
|
||||
}
|
||||
}
|
||||
|
||||
/* once zero is found, reset initial interval to xr */
|
||||
freq[j] = (xm);
|
||||
freq[j] = X2ANGLE(xm);
|
||||
xl = xm;
|
||||
flag = 0; /* reset flag for next search */
|
||||
break;
|
||||
}
|
||||
else{
|
||||
psuml=temp_psumr;
|
||||
@ -234,7 +386,7 @@ int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack)
|
||||
return(roots);
|
||||
}
|
||||
|
||||
|
||||
#endif /* DISABLE_ENCODER */
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FUNCTION....: lsp_to_lpc()
|
||||
@ -242,13 +394,132 @@ int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack)
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/2/93
|
||||
|
||||
lsp_to_lpc: This function converts LSP coefficients to LPC
|
||||
coefficients.
|
||||
Converts LSP coefficients to LPC coefficients.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
void lsp_to_lpc(float *freq,float *ak,int lpcrdr, char *stack)
|
||||
void lsp_to_lpc(const 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(const 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 */
|
||||
@ -257,11 +528,12 @@ void lsp_to_lpc(float *freq,float *ak,int lpcrdr, char *stack)
|
||||
{
|
||||
int i,j;
|
||||
float xout1,xout2,xin1,xin2;
|
||||
float *Wp;
|
||||
VARDECL(float *Wp);
|
||||
float *pw,*n1,*n2,*n3,*n4=NULL;
|
||||
int m = lpcrdr/2;
|
||||
VARDECL(float *x_freq);
|
||||
int m = lpcrdr>>1;
|
||||
|
||||
Wp = PUSH(stack, 4*m+2, float);
|
||||
ALLOC(Wp, 4*m+2, float);
|
||||
pw = Wp;
|
||||
|
||||
/* initialise contents of array */
|
||||
@ -276,6 +548,10 @@ void lsp_to_lpc(float *freq,float *ak,int lpcrdr, char *stack)
|
||||
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 */
|
||||
@ -287,8 +563,8 @@ void lsp_to_lpc(float *freq,float *ak,int lpcrdr, char *stack)
|
||||
n2 = n1 + 1;
|
||||
n3 = n2 + 1;
|
||||
n4 = n3 + 1;
|
||||
xout1 = xin1 - 2*(freq[i2]) * *n1 + *n2;
|
||||
xout2 = xin2 - 2*(freq[i2+1]) * *n3 + *n4;
|
||||
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;
|
||||
@ -298,7 +574,8 @@ void lsp_to_lpc(float *freq,float *ak,int lpcrdr, char *stack)
|
||||
}
|
||||
xout1 = xin1 + *(n4+1);
|
||||
xout2 = xin2 - *(n4+2);
|
||||
ak[j] = (xout1 + xout2)*0.5;
|
||||
if (j>0)
|
||||
ak[j-1] = (xout1 + xout2)*0.5f;
|
||||
*(n4+1) = xin1;
|
||||
*(n4+2) = xin2;
|
||||
|
||||
@ -307,22 +584,58 @@ void lsp_to_lpc(float *freq,float *ak,int lpcrdr, char *stack)
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/*Added by JMV
|
||||
Makes sure the LSPs are stable*/
|
||||
void lsp_enforce_margin(float *lsp, int len, float margin)
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
|
||||
void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *lsp, int len, int subframe, int nb_subframes, spx_word16_t margin)
|
||||
{
|
||||
int i;
|
||||
if (lsp[0]<margin)
|
||||
lsp[0]=margin;
|
||||
if (lsp[len-1]>M_PI-margin)
|
||||
lsp[len-1]=M_PI-margin;
|
||||
spx_word16_t m = margin;
|
||||
spx_word16_t m2 = 25736-margin;
|
||||
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++)
|
||||
lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]);
|
||||
/* Enforce margin to sure the LSPs are stable*/
|
||||
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]+margin)
|
||||
lsp[i]=lsp[i-1]+margin;
|
||||
if (lsp[i]<lsp[i-1]+m)
|
||||
lsp[i]=lsp[i-1]+m;
|
||||
|
||||
if (lsp[i]>lsp[i+1]-margin)
|
||||
lsp[i]= .5* (lsp[i] + lsp[i+1]-margin);
|
||||
if (lsp[i]>lsp[i+1]-m)
|
||||
lsp[i]= SHR16(lsp[i],1) + SHR16(lsp[i+1]-m,1);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *lsp, int len, int subframe, int nb_subframes, spx_word16_t margin)
|
||||
{
|
||||
int i;
|
||||
float tmp = (1.0f + subframe)/nb_subframes;
|
||||
for (i=0;i<len;i++)
|
||||
lsp[i] = (1-tmp)*old_lsp[i] + tmp*new_lsp[i];
|
||||
/* Enforce margin to sure the LSPs are stable*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
13
external/speex/src/lsp.h
vendored
13
external/speex/src/lsp.h
vendored
@ -14,6 +14,10 @@ Modified by Jean-Marc Valin
|
||||
unit circle.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file lsp.h
|
||||
@brief Line Spectral Pair (LSP) functions.
|
||||
*/
|
||||
/* Speex License:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -47,11 +51,12 @@ Modified by Jean-Marc Valin
|
||||
#ifndef __AK2LSPD__
|
||||
#define __AK2LSPD__
|
||||
|
||||
int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta, char *stack);
|
||||
void lsp_to_lpc(float *freq, float *ak, int lpcrdr, char *stack);
|
||||
#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(const spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack);
|
||||
|
||||
/*Added by JMV*/
|
||||
void lsp_enforce_margin(float *lsp, int len, float 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, spx_word16_t margin);
|
||||
|
||||
#endif /* __AK2LSPD__ */
|
||||
|
89
external/speex/src/lsp_bfin.h
vendored
Normal file
89
external/speex/src/lsp_bfin.h
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/* 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", "ASTAT" BFIN_HWLOOP0_REGS
|
||||
);
|
||||
return sum;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
10
external/speex/src/lsp_tables_nb.c
vendored
10
external/speex/src/lsp_tables_nb.c
vendored
@ -29,7 +29,7 @@
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char cdbk_nb[640]={
|
||||
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,
|
||||
@ -95,7 +95,7 @@ signed char cdbk_nb[640]={
|
||||
-6,-41,-67,6,-2,-9,19,2,85,74,
|
||||
-22,-67,-84,-71,-50,3,11,-9,2,62};
|
||||
|
||||
signed char cdbk_nb_low1[320]={
|
||||
const signed char cdbk_nb_low1[320]={
|
||||
-34,-52,-15,45,2,
|
||||
23,21,52,24,-33,
|
||||
-9,-1,9,-44,-41,
|
||||
@ -161,7 +161,7 @@ signed char cdbk_nb_low1[320]={
|
||||
13,20,20,-19,-22,
|
||||
-2,-8,2,51,-51};
|
||||
|
||||
signed char cdbk_nb_low2[320]={
|
||||
const signed char cdbk_nb_low2[320]={
|
||||
-6,53,-21,-24,4,
|
||||
26,17,-4,-37,25,
|
||||
17,-36,-13,31,3,
|
||||
@ -227,7 +227,7 @@ signed char cdbk_nb_low2[320]={
|
||||
-23,-29,-16,1,-3,
|
||||
-8,-10,31,64,-65};
|
||||
|
||||
signed char cdbk_nb_high1[320]={
|
||||
const signed char cdbk_nb_high1[320]={
|
||||
-26,-8,29,21,4,
|
||||
19,-39,33,-7,-36,
|
||||
56,54,48,40,29,
|
||||
@ -293,7 +293,7 @@ signed char cdbk_nb_high1[320]={
|
||||
29,17,8,-29,-39,
|
||||
-69,18,15,-15,-5};
|
||||
|
||||
signed char cdbk_nb_high2[320]={
|
||||
const signed char cdbk_nb_high2[320]={
|
||||
11,47,16,-9,-46,
|
||||
-32,26,-64,34,-5,
|
||||
38,-7,47,20,2,
|
||||
|
882
external/speex/src/ltp.c
vendored
882
external/speex/src/ltp.c
vendored
File diff suppressed because it is too large
Load Diff
123
external/speex/src/ltp.h
vendored
123
external/speex/src/ltp.h
vendored
@ -1,7 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: ltp.h
|
||||
Long-Term Prediction functions
|
||||
|
||||
/* 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:
|
||||
@ -30,109 +32,114 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "speex_bits.h"
|
||||
#ifndef LTP_H
|
||||
#define LTP_H
|
||||
|
||||
#include "speex/speex_bits.h"
|
||||
#include "arch.h"
|
||||
|
||||
typedef struct ltp_params {
|
||||
signed char *gain_cdbk;
|
||||
/** 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
|
||||
|
||||
void open_loop_nbest_pitch(float *sw, int start, int end, int len, int *pitch, float *gain, int N, char *stack);
|
||||
spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len);
|
||||
|
||||
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(
|
||||
float target[], /* Target vector */
|
||||
float *sw,
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
float awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
float exc[], /* Overlapping codebook */
|
||||
void *par,
|
||||
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 */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
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,
|
||||
float *exc2,
|
||||
float *r,
|
||||
int complexity
|
||||
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(
|
||||
float exc[], /* Excitation */
|
||||
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 */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
void *par,
|
||||
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
|
||||
const void *par,
|
||||
int nsf, /* Number of samples in subframe */
|
||||
int *pitch_val,
|
||||
float *gain_val,
|
||||
spx_word16_t *gain_val,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int lost,
|
||||
int subframe_offset,
|
||||
float last_pitch_gain
|
||||
spx_word16_t last_pitch_gain,
|
||||
int cdbk_offset
|
||||
);
|
||||
|
||||
float pitch_gain_search_3tap(
|
||||
float target[], /* Target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
float awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
float exc[], /* Excitation */
|
||||
void *par,
|
||||
int pitch, /* Pitch value */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
float *exc2,
|
||||
float *r,
|
||||
int *cdbk_index
|
||||
);
|
||||
|
||||
|
||||
/** Forced pitch delay and gain */
|
||||
int forced_pitch_quant(
|
||||
float target[], /* Target vector */
|
||||
float *sw,
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
float awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
float exc[], /* Excitation */
|
||||
void *par,
|
||||
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 */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
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,
|
||||
float *exc2,
|
||||
float *r,
|
||||
int complexity
|
||||
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(
|
||||
float exc[], /* Excitation */
|
||||
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 */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
void *par,
|
||||
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
|
||||
const void *par,
|
||||
int nsf, /* Number of samples in subframe */
|
||||
int *pitch_val,
|
||||
float *gain_val,
|
||||
spx_word16_t *gain_val,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int lost,
|
||||
int subframe_offset,
|
||||
float last_pitch_gain
|
||||
spx_word16_t last_pitch_gain,
|
||||
int cdbk_offset
|
||||
);
|
||||
|
||||
#endif /* LTP_H */
|
||||
|
187
external/speex/src/ltp_arm4.h
vendored
Normal file
187
external/speex/src/ltp_arm4.h
vendored
Normal file
@ -0,0 +1,187 @@
|
||||
/* 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;
|
||||
}
|
||||
|
||||
}
|
414
external/speex/src/ltp_bfin.h
vendored
Normal file
414
external/speex/src/ltp_bfin.h
vendored
Normal file
@ -0,0 +1,414 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "bfin.h"
|
||||
|
||||
#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", "ASTAT" BFIN_HWLOOP0_REGS
|
||||
);
|
||||
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",
|
||||
"ASTAT" BFIN_HWLOOP0_REGS BFIN_HWLOOP1_REGS
|
||||
);
|
||||
}
|
||||
|
||||
#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", "ASTAT"
|
||||
);
|
||||
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", "ASTAT" BFIN_HWLOOP1_REGS
|
||||
);
|
||||
|
||||
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",
|
||||
"ASTAT", "CC" BFIN_HWLOOP1_REGS
|
||||
);
|
||||
|
||||
}
|
||||
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", "CC", "ASTAT" BFIN_HWLOOP1_REGS
|
||||
);
|
||||
|
||||
return best_cdbk;
|
||||
}
|
||||
#endif
|
||||
|
125
external/speex/src/ltp_sse.h
vendored
125
external/speex/src/ltp_sse.h
vendored
@ -1,7 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: ltp.c
|
||||
Lont-Term Prediction functions
|
||||
|
||||
/* 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:
|
||||
@ -30,66 +32,61 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
static float inner_prod(float *a, float *b, int len)
|
||||
#define OVERRIDE_INNER_PROD
|
||||
float inner_prod(const float *a, const float *b, int len)
|
||||
{
|
||||
float sum;
|
||||
__asm__ __volatile__ (
|
||||
"\tpush %%eax\n"
|
||||
"\tpush %%edi\n"
|
||||
"\tpush %%ecx\n"
|
||||
"\txorps %%xmm3, %%xmm3\n"
|
||||
"\txorps %%xmm4, %%xmm4\n"
|
||||
|
||||
"\tsub $20, %%ecx\n"
|
||||
|
||||
".mul20_loop%=:\n"
|
||||
|
||||
"\tmovups (%%eax), %%xmm0\n"
|
||||
"\tmovups (%%edi), %%xmm1\n"
|
||||
"\tmulps %%xmm0, %%xmm1\n"
|
||||
|
||||
"\tmovups 16(%%eax), %%xmm5\n"
|
||||
"\tmovups 16(%%edi), %%xmm6\n"
|
||||
"\tmulps %%xmm5, %%xmm6\n"
|
||||
"\taddps %%xmm1, %%xmm3\n"
|
||||
|
||||
"\tmovups 32(%%eax), %%xmm0\n"
|
||||
"\tmovups 32(%%edi), %%xmm1\n"
|
||||
"\tmulps %%xmm0, %%xmm1\n"
|
||||
"\taddps %%xmm6, %%xmm4\n"
|
||||
|
||||
"\tmovups 48(%%eax), %%xmm5\n"
|
||||
"\tmovups 48(%%edi), %%xmm6\n"
|
||||
"\tmulps %%xmm5, %%xmm6\n"
|
||||
"\taddps %%xmm1, %%xmm3\n"
|
||||
|
||||
"\tmovups 64(%%eax), %%xmm0\n"
|
||||
"\tmovups 64(%%edi), %%xmm1\n"
|
||||
"\tmulps %%xmm0, %%xmm1\n"
|
||||
"\taddps %%xmm6, %%xmm4\n"
|
||||
"\taddps %%xmm1, %%xmm3\n"
|
||||
|
||||
|
||||
"\tadd $80, %%eax\n"
|
||||
"\tadd $80, %%edi\n"
|
||||
|
||||
"\tsub $20, %%ecx\n"
|
||||
|
||||
"\tjae .mul20_loop%=\n"
|
||||
|
||||
"\taddps %%xmm4, %%xmm3\n"
|
||||
|
||||
"\tmovhlps %%xmm3, %%xmm4\n"
|
||||
"\taddps %%xmm4, %%xmm3\n"
|
||||
"\tmovaps %%xmm3, %%xmm4\n"
|
||||
"\tshufps $0x55, %%xmm4, %%xmm4\n"
|
||||
"\taddss %%xmm4, %%xmm3\n"
|
||||
"\tmovss %%xmm3, (%%edx)\n"
|
||||
|
||||
"\tpop %%ecx\n"
|
||||
"\tpop %%edi\n"
|
||||
"\tpop %%eax\n"
|
||||
: : "a" (a), "D" (b), "c" (len), "d" (&sum) : "memory");
|
||||
return sum;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
105
external/speex/src/math_approx.c
vendored
105
external/speex/src/math_approx.c
vendored
@ -1,105 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: math_approx.c
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "math_approx.h"
|
||||
|
||||
#ifdef SLOW_TRIG
|
||||
|
||||
float cos_sin[102] = {
|
||||
1.00000000, 0.00000000,
|
||||
0.99804751, 0.06245932,
|
||||
0.99219767, 0.12467473,
|
||||
0.98247331, 0.18640330,
|
||||
0.96891242, 0.24740396,
|
||||
0.95156795, 0.30743851,
|
||||
0.93050762, 0.36627253,
|
||||
0.90581368, 0.42367626,
|
||||
0.87758256, 0.47942554,
|
||||
0.84592450, 0.53330267,
|
||||
0.81096312, 0.58509727,
|
||||
0.77283495, 0.63460708,
|
||||
0.73168887, 0.68163876,
|
||||
0.68768556, 0.72600866,
|
||||
0.64099686, 0.76754350,
|
||||
0.59180508, 0.80608111,
|
||||
0.54030231, 0.84147098,
|
||||
0.48668967, 0.87357494,
|
||||
0.43117652, 0.90226759,
|
||||
0.37397963, 0.92743692,
|
||||
0.31532236, 0.94898462,
|
||||
0.25543377, 0.96682656,
|
||||
0.19454771, 0.98089306,
|
||||
0.13290194, 0.99112919,
|
||||
0.07073720, 0.99749499,
|
||||
0.00829623, 0.99996559,
|
||||
-0.05417714, 0.99853134,
|
||||
-0.11643894, 0.99319785,
|
||||
-0.17824606, 0.98398595,
|
||||
-0.23935712, 0.97093160,
|
||||
-0.29953351, 0.95408578,
|
||||
-0.35854022, 0.93351428,
|
||||
-0.41614684, 0.90929743,
|
||||
-0.47212841, 0.88152979,
|
||||
-0.52626633, 0.85031979,
|
||||
-0.57834920, 0.81578931,
|
||||
-0.62817362, 0.77807320,
|
||||
-0.67554504, 0.73731872,
|
||||
-0.72027847, 0.69368503,
|
||||
-0.76219923, 0.64734252,
|
||||
-0.80114362, 0.59847214,
|
||||
-0.83695955, 0.54726475,
|
||||
-0.86950718, 0.49392030,
|
||||
-0.89865940, 0.43864710,
|
||||
-0.92430238, 0.38166099,
|
||||
-0.94633597, 0.32318451,
|
||||
-0.96467415, 0.26344599,
|
||||
-0.97924529, 0.20267873,
|
||||
-0.98999250, 0.14112001,
|
||||
-0.99687381, 0.07901022,
|
||||
-0.99986235, 0.01659189
|
||||
};
|
||||
|
||||
float speex_cos(float x)
|
||||
{
|
||||
int ind;
|
||||
float delta;
|
||||
ind = (int)floor(x*16+.5);
|
||||
delta = x-0.062500*ind;
|
||||
ind <<= 1;
|
||||
return cos_sin[ind] - delta*(cos_sin[ind+1] +
|
||||
.5*delta*(cos_sin[ind] -
|
||||
.3333333*delta*cos_sin[ind+1]));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
303
external/speex/src/math_approx.h
vendored
303
external/speex/src/math_approx.h
vendored
@ -1,7 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: math_approx.c
|
||||
Various math approximation functions for Speex
|
||||
|
||||
/* 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:
|
||||
@ -33,7 +35,298 @@
|
||||
#ifndef MATH_APPROX_H
|
||||
#define MATH_APPROX_H
|
||||
|
||||
float speex_cos(float x);
|
||||
#include "arch.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 inline spx_word16_t speex_rand(spx_word16_t std, spx_uint32_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 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 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 inline spx_word16_t speex_rand(spx_word16_t std, spx_uint32_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 inline spx_word16_t spx_sqrt(spx_word32_t x)
|
||||
{
|
||||
int k;
|
||||
spx_word32_t rt;
|
||||
k = spx_ilog4(x)-6;
|
||||
x = VSHR32(x, (int)((unsigned)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 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 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 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 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 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 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 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 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 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
|
||||
|
145
external/speex/src/misc.c
vendored
145
external/speex/src/misc.c
vendored
@ -1,145 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: mics.c
|
||||
Various utility routines 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.
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef RELEASE
|
||||
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
|
||||
|
||||
unsigned int be_int(unsigned int i)
|
||||
{
|
||||
unsigned int ret=i;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
ret = i>>24;
|
||||
ret += (i>>8)&0x0000ff00;
|
||||
ret += (i<<8)&0x00ff0000;
|
||||
ret += (i<<24);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int le_int(unsigned int i)
|
||||
{
|
||||
unsigned int ret=i;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
ret = i>>24;
|
||||
ret += (i>>8)&0x0000ff00;
|
||||
ret += (i<<8)&0x00ff0000;
|
||||
ret += (i<<24);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned short be_short(unsigned short s)
|
||||
{
|
||||
unsigned short ret=s;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
ret = s>>8;
|
||||
ret += s<<8;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned short le_short(unsigned short s)
|
||||
{
|
||||
unsigned short ret=s;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
ret = s>>8;
|
||||
ret += s<<8;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *speex_alloc (int size)
|
||||
{
|
||||
return calloc(size,1);
|
||||
}
|
||||
|
||||
void *speex_realloc (void *ptr, int size)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
void speex_free (void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void *speex_move (void *dest, void *src, int n)
|
||||
{
|
||||
return memmove(dest,src,n);
|
||||
}
|
||||
|
||||
void speex_error(char *str)
|
||||
{
|
||||
fprintf (stderr, "Fatal error: %s\n", str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void speex_warning(char *str)
|
||||
{
|
||||
fprintf (stderr, "warning: %s\n", str);
|
||||
}
|
||||
|
||||
void speex_warning_int(char *str, int val)
|
||||
{
|
||||
fprintf (stderr, "warning: %s %d\n", str, val);
|
||||
}
|
||||
|
||||
void speex_rand_vec(float std, float *data, int len)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<len;i++)
|
||||
data[i]+=3*std*((((float)rand())/RAND_MAX)-.5);
|
||||
}
|
||||
|
||||
float speex_rand(float std)
|
||||
{
|
||||
return 3*std*((((float)rand())/RAND_MAX)-.5);
|
||||
}
|
||||
|
||||
void _speex_putc(int ch, void *file)
|
||||
{
|
||||
FILE *f = (FILE *)file;
|
||||
fputc(ch, f);
|
||||
}
|
56
external/speex/src/misc_bfin.h
vendored
Normal file
56
external/speex/src/misc_bfin.h
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "bfin.h"
|
||||
|
||||
#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" BFIN_HWLOOP0_REGS
|
||||
);
|
||||
return dest;
|
||||
}
|
444
external/speex/src/modes.c
vendored
444
external/speex/src/modes.c
vendored
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
/* Copyright (C) 2002-2006 Jean-Marc Valin
|
||||
File: modes.c
|
||||
|
||||
Describes the different modes of the codec
|
||||
@ -32,6 +32,10 @@
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "modes.h"
|
||||
#include "ltp.h"
|
||||
#include "quant_lsp.h"
|
||||
@ -39,59 +43,82 @@
|
||||
#include "sb_celp.h"
|
||||
#include "nb_celp.h"
|
||||
#include "vbr.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
SpeexMode *speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
|
||||
#ifdef DISABLE_ENCODER
|
||||
#define nb_encoder_init NULL
|
||||
#define nb_encoder_destroy NULL
|
||||
#define nb_encode NULL
|
||||
#define nb_encoder_ctl NULL
|
||||
|
||||
#define split_cb_search_shape_sign NULL
|
||||
#define noise_codebook_quant NULL
|
||||
#define pitch_search_3tap NULL
|
||||
#define forced_pitch_quant NULL
|
||||
#define lsp_quant_nb NULL
|
||||
#define lsp_quant_lbr NULL
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
#ifdef DISABLE_DECODER
|
||||
#define nb_decoder_init NULL
|
||||
#define nb_decoder_destroy NULL
|
||||
#define nb_decode NULL
|
||||
#define nb_decoder_ctl NULL
|
||||
|
||||
#define noise_codebook_unquant NULL
|
||||
#define split_cb_shape_sign_unquant NULL
|
||||
#define lsp_unquant_nb NULL
|
||||
#define lsp_unquant_lbr NULL
|
||||
#define pitch_unquant_3tap NULL
|
||||
#define forced_pitch_unquant NULL
|
||||
#endif /* DISABLE_DECODER */
|
||||
|
||||
/* Extern declarations for all codebooks we use here */
|
||||
extern signed char gain_cdbk_nb[];
|
||||
extern signed char gain_cdbk_lbr[];
|
||||
extern signed char hexc_table[];
|
||||
extern signed char exc_5_256_table[];
|
||||
extern signed char exc_5_64_table[];
|
||||
extern signed char exc_8_128_table[];
|
||||
extern signed char exc_10_32_table[];
|
||||
extern signed char exc_10_16_table[];
|
||||
extern signed char exc_20_32_table[];
|
||||
extern signed char hexc_10_32_table[];
|
||||
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[];
|
||||
|
||||
static int nb_mode_query(void *mode, int request, void *ptr);
|
||||
static int wb_mode_query(void *mode, int request, void *ptr);
|
||||
|
||||
/* Parameters for Long-Term Prediction (LTP)*/
|
||||
static ltp_params ltp_params_nb = {
|
||||
static const ltp_params ltp_params_nb = {
|
||||
gain_cdbk_nb,
|
||||
7,
|
||||
7
|
||||
};
|
||||
|
||||
/* Parameters for Long-Term Prediction (LTP)*/
|
||||
static ltp_params ltp_params_vlbr = {
|
||||
static const ltp_params ltp_params_vlbr = {
|
||||
gain_cdbk_lbr,
|
||||
5,
|
||||
0
|
||||
};
|
||||
|
||||
/* Parameters for Long-Term Prediction (LTP)*/
|
||||
static ltp_params ltp_params_lbr = {
|
||||
static const ltp_params ltp_params_lbr = {
|
||||
gain_cdbk_lbr,
|
||||
5,
|
||||
7
|
||||
};
|
||||
|
||||
/* Parameters for Long-Term Prediction (LTP)*/
|
||||
static ltp_params ltp_params_med = {
|
||||
static const ltp_params ltp_params_med = {
|
||||
gain_cdbk_lbr,
|
||||
5,
|
||||
7
|
||||
};
|
||||
|
||||
/* Split-VQ innovation parameters for very low bit-rate narrowband */
|
||||
static split_cb_params split_cb_nb_vlbr = {
|
||||
static const split_cb_params split_cb_nb_vlbr = {
|
||||
10, /*subvect_size*/
|
||||
4, /*nb_subvect*/
|
||||
exc_10_16_table, /*shape_cb*/
|
||||
@ -100,7 +127,7 @@ static split_cb_params split_cb_nb_vlbr = {
|
||||
};
|
||||
|
||||
/* Split-VQ innovation parameters for very low bit-rate narrowband */
|
||||
static split_cb_params split_cb_nb_ulbr = {
|
||||
static const split_cb_params split_cb_nb_ulbr = {
|
||||
20, /*subvect_size*/
|
||||
2, /*nb_subvect*/
|
||||
exc_20_32_table, /*shape_cb*/
|
||||
@ -109,7 +136,7 @@ static split_cb_params split_cb_nb_ulbr = {
|
||||
};
|
||||
|
||||
/* Split-VQ innovation parameters for low bit-rate narrowband */
|
||||
static split_cb_params split_cb_nb_lbr = {
|
||||
static const split_cb_params split_cb_nb_lbr = {
|
||||
10, /*subvect_size*/
|
||||
4, /*nb_subvect*/
|
||||
exc_10_32_table, /*shape_cb*/
|
||||
@ -119,7 +146,7 @@ static split_cb_params split_cb_nb_lbr = {
|
||||
|
||||
|
||||
/* Split-VQ innovation parameters narrowband */
|
||||
static split_cb_params split_cb_nb = {
|
||||
static const split_cb_params split_cb_nb = {
|
||||
5, /*subvect_size*/
|
||||
8, /*nb_subvect*/
|
||||
exc_5_64_table, /*shape_cb*/
|
||||
@ -128,7 +155,7 @@ static split_cb_params split_cb_nb = {
|
||||
};
|
||||
|
||||
/* Split-VQ innovation parameters narrowband */
|
||||
static split_cb_params split_cb_nb_med = {
|
||||
static const split_cb_params split_cb_nb_med = {
|
||||
8, /*subvect_size*/
|
||||
5, /*nb_subvect*/
|
||||
exc_8_128_table, /*shape_cb*/
|
||||
@ -137,7 +164,7 @@ static split_cb_params split_cb_nb_med = {
|
||||
};
|
||||
|
||||
/* Split-VQ innovation for low-band wideband */
|
||||
static split_cb_params split_cb_sb = {
|
||||
static const split_cb_params split_cb_sb = {
|
||||
5, /*subvect_size*/
|
||||
8, /*nb_subvect*/
|
||||
exc_5_256_table, /*shape_cb*/
|
||||
@ -145,27 +172,10 @@ static split_cb_params split_cb_sb = {
|
||||
0,
|
||||
};
|
||||
|
||||
/* Split-VQ innovation for high-band wideband */
|
||||
static 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 split_cb_params split_cb_high_lbr = {
|
||||
10, /*subvect_size*/
|
||||
4, /*nb_subvect*/
|
||||
hexc_10_32_table, /*shape_cb*/
|
||||
5, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
/* 2150 bps "vocoder-like" mode for comfort noise */
|
||||
static SpeexSubmode nb_submode1 = {
|
||||
static const SpeexSubmode nb_submode1 = {
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
@ -181,12 +191,12 @@ static SpeexSubmode nb_submode1 = {
|
||||
noise_codebook_quant,
|
||||
noise_codebook_unquant,
|
||||
NULL,
|
||||
.7, .7, -1,
|
||||
-1,
|
||||
43
|
||||
};
|
||||
|
||||
/* 3.95 kbps very low bit-rate mode */
|
||||
static SpeexSubmode nb_submode8 = {
|
||||
static const SpeexSubmode nb_submode8 = {
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
@ -202,13 +212,12 @@ static SpeexSubmode nb_submode8 = {
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb_ulbr,
|
||||
|
||||
0.7, 0.5, .65,
|
||||
QCONST16(.5,15),
|
||||
79
|
||||
};
|
||||
|
||||
/* 5.95 kbps very low bit-rate mode */
|
||||
static SpeexSubmode nb_submode2 = {
|
||||
static const SpeexSubmode nb_submode2 = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@ -224,13 +233,12 @@ static SpeexSubmode nb_submode2 = {
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb_vlbr,
|
||||
|
||||
0.7, 0.5, .55,
|
||||
QCONST16(.6,15),
|
||||
119
|
||||
};
|
||||
|
||||
/* 8 kbps low bit-rate mode */
|
||||
static SpeexSubmode nb_submode3 = {
|
||||
static const SpeexSubmode nb_submode3 = {
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
@ -246,13 +254,12 @@ static SpeexSubmode nb_submode3 = {
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb_lbr,
|
||||
|
||||
0.7, 0.55, .45,
|
||||
QCONST16(.55,15),
|
||||
160
|
||||
};
|
||||
|
||||
/* 11 kbps medium bit-rate mode */
|
||||
static SpeexSubmode nb_submode4 = {
|
||||
static const SpeexSubmode nb_submode4 = {
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
@ -268,13 +275,12 @@ static SpeexSubmode nb_submode4 = {
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb_med,
|
||||
|
||||
0.7, 0.63, .35,
|
||||
QCONST16(.45,15),
|
||||
220
|
||||
};
|
||||
|
||||
/* 15 kbps high bit-rate mode */
|
||||
static SpeexSubmode nb_submode5 = {
|
||||
static const SpeexSubmode nb_submode5 = {
|
||||
-1,
|
||||
0,
|
||||
3,
|
||||
@ -290,13 +296,12 @@ static SpeexSubmode nb_submode5 = {
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb,
|
||||
|
||||
0.7, 0.65, .25,
|
||||
QCONST16(.25,15),
|
||||
300
|
||||
};
|
||||
|
||||
/* 18.2 high bit-rate mode */
|
||||
static SpeexSubmode nb_submode6 = {
|
||||
static const SpeexSubmode nb_submode6 = {
|
||||
-1,
|
||||
0,
|
||||
3,
|
||||
@ -312,13 +317,12 @@ static SpeexSubmode nb_submode6 = {
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_sb,
|
||||
|
||||
0.68, 0.65, .1,
|
||||
QCONST16(.15,15),
|
||||
364
|
||||
};
|
||||
|
||||
/* 24.6 kbps high bit-rate mode */
|
||||
static SpeexSubmode nb_submode7 = {
|
||||
static const SpeexSubmode nb_submode7 = {
|
||||
-1,
|
||||
0,
|
||||
3,
|
||||
@ -334,25 +338,21 @@ static SpeexSubmode nb_submode7 = {
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb,
|
||||
|
||||
0.65, 0.65, -1,
|
||||
QCONST16(.05,15),
|
||||
492
|
||||
};
|
||||
|
||||
|
||||
/* Default mode for narrowband */
|
||||
static SpeexNBMode nb_mode = {
|
||||
160, /*frameSize*/
|
||||
40, /*subframeSize*/
|
||||
10, /*lpcSize*/
|
||||
640, /*bufSize*/
|
||||
17, /*pitchStart*/
|
||||
144, /*pitchEnd*/
|
||||
0.9, /*gamma1*/
|
||||
0.6, /*gamma2*/
|
||||
.01, /*lag_factor*/
|
||||
1.0001, /*lpc_floor*/
|
||||
0.0, /*preemph*/
|
||||
static const SpeexNBMode nb_mode = {
|
||||
NB_FRAME_SIZE, /*frameSize*/
|
||||
NB_SUBFRAME_SIZE, /*subframeSize*/
|
||||
NB_ORDER, /*lpcSize*/
|
||||
NB_PITCH_START, /*pitchStart*/
|
||||
NB_PITCH_END, /*pitchEnd*/
|
||||
QCONST16(0.92,15), /* gamma1 */
|
||||
QCONST16(0.6,15), /* gamma2 */
|
||||
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,
|
||||
@ -361,290 +361,30 @@ static SpeexNBMode nb_mode = {
|
||||
|
||||
|
||||
/* Default mode for narrowband */
|
||||
SpeexMode speex_nb_mode = {
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
/* Wideband part */
|
||||
|
||||
static 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,
|
||||
|
||||
.75, .75, -1,
|
||||
36
|
||||
};
|
||||
|
||||
|
||||
static 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,
|
||||
&split_cb_high_lbr,
|
||||
|
||||
.85, .6, -1,
|
||||
112
|
||||
};
|
||||
|
||||
|
||||
static 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,
|
||||
&split_cb_high,
|
||||
|
||||
.75, .7, -1,
|
||||
192
|
||||
};
|
||||
|
||||
static 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,
|
||||
&split_cb_high,
|
||||
|
||||
.75, .75, -1,
|
||||
352
|
||||
};
|
||||
|
||||
|
||||
/* Split-band wideband CELP mode*/
|
||||
static SpeexSBMode sb_wb_mode = {
|
||||
&speex_nb_mode,
|
||||
160, /*frameSize*/
|
||||
40, /*subframeSize*/
|
||||
8, /*lpcSize*/
|
||||
640, /*bufSize*/
|
||||
.9, /*gamma1*/
|
||||
0.6, /*gamma2*/
|
||||
.002, /*lag_factor*/
|
||||
1.0001, /*lpc_floor*/
|
||||
0.0, /*preemph*/
|
||||
0.9,
|
||||
{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},
|
||||
vbr_hb_thresh,
|
||||
5
|
||||
};
|
||||
|
||||
|
||||
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,
|
||||
nb_encoder_init,
|
||||
nb_encoder_destroy,
|
||||
nb_encode,
|
||||
nb_decoder_init,
|
||||
nb_decoder_destroy,
|
||||
nb_decode,
|
||||
nb_encoder_ctl,
|
||||
nb_decoder_ctl,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* "Ultra-wideband" mode stuff */
|
||||
|
||||
|
||||
|
||||
/* Split-band "ultra-wideband" (32 kbps) CELP mode*/
|
||||
static SpeexSBMode sb_uwb_mode = {
|
||||
&speex_wb_mode,
|
||||
320, /*frameSize*/
|
||||
80, /*subframeSize*/
|
||||
8, /*lpcSize*/
|
||||
1280, /*bufSize*/
|
||||
.9, /*gamma1*/
|
||||
0.6, /*gamma2*/
|
||||
.002, /*lag_factor*/
|
||||
1.0001, /*lpc_floor*/
|
||||
0.0, /*preemph*/
|
||||
0.7,
|
||||
{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},
|
||||
vbr_uhb_thresh,
|
||||
2
|
||||
};
|
||||
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
void *speex_encoder_init(SpeexMode *mode)
|
||||
{
|
||||
return mode->enc_init(mode);
|
||||
}
|
||||
|
||||
void *speex_decoder_init(SpeexMode *mode)
|
||||
{
|
||||
return mode->dec_init(mode);
|
||||
}
|
||||
|
||||
void speex_encoder_destroy(void *state)
|
||||
{
|
||||
(*((SpeexMode**)state))->enc_destroy(state);
|
||||
}
|
||||
|
||||
int speex_encode(void *state, float *in, SpeexBits *bits)
|
||||
{
|
||||
return (*((SpeexMode**)state))->enc(state, in, bits);
|
||||
}
|
||||
|
||||
void speex_decoder_destroy(void *state)
|
||||
{
|
||||
(*((SpeexMode**)state))->dec_destroy(state);
|
||||
}
|
||||
|
||||
int speex_decode(void *state, SpeexBits *bits, float *out)
|
||||
{
|
||||
return (*((SpeexMode**)state))->dec(state, bits, out);
|
||||
}
|
||||
|
||||
|
||||
int speex_encoder_ctl(void *state, int request, void *ptr)
|
||||
{
|
||||
return (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
|
||||
}
|
||||
|
||||
int speex_decoder_ctl(void *state, int request, void *ptr)
|
||||
{
|
||||
return (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int nb_mode_query(void *mode, int request, void *ptr)
|
||||
{
|
||||
SpeexNBMode *m = (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;
|
||||
}
|
||||
|
||||
static int wb_mode_query(void *mode, int request, void *ptr)
|
||||
{
|
||||
SpeexSBMode *m = (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;
|
||||
}
|
||||
|
||||
|
||||
int speex_mode_query(SpeexMode *mode, int request, void *ptr)
|
||||
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
|
||||
|
||||
|
92
external/speex/src/modes.h
vendored
92
external/speex/src/modes.h
vendored
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/* Copyright (C) 2002-2006 Jean-Marc Valin */
|
||||
/**
|
||||
@file modes.h
|
||||
@brief Describes the different modes of the codec
|
||||
@ -36,9 +36,8 @@
|
||||
#ifndef MODES_H
|
||||
#define MODES_H
|
||||
|
||||
#include "speex.h"
|
||||
#include "speex_bits.h"
|
||||
|
||||
#include "speex/speex.h"
|
||||
#include "arch.h"
|
||||
|
||||
#define NB_SUBMODES 16
|
||||
#define NB_SUBMODE_BITS 4
|
||||
@ -46,32 +45,49 @@
|
||||
#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)(float *, float *, int, SpeexBits *);
|
||||
typedef void (*lsp_quant_func)(spx_lsp_t *, spx_lsp_t *, int, SpeexBits *);
|
||||
|
||||
/** Decodes quantized LSPs */
|
||||
typedef void (*lsp_unquant_func)(float *, int, SpeexBits *);
|
||||
typedef void (*lsp_unquant_func)(spx_lsp_t *, int, SpeexBits *);
|
||||
|
||||
|
||||
/** Long-term predictor quantization */
|
||||
typedef int (*ltp_quant_func)(float *, float *, float *, float *,
|
||||
float *, float *, void *, int, int, float,
|
||||
int, int, SpeexBits*, char *, float *, float *, int);
|
||||
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)(float *, int, int, float, void *, int, int *,
|
||||
float *, SpeexBits*, char*, int, int, float);
|
||||
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)(float *, float *, float *, float *, void *, int, int,
|
||||
float *, float *, SpeexBits *, char *, int);
|
||||
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)(float *, void *, int, SpeexBits*, char *);
|
||||
typedef void (*innovation_unquant_func)(spx_sig_t *, const void *, int, SpeexBits*, char *, spx_uint32_t *);
|
||||
|
||||
/** Description of a Speex sub-mode (wither narrowband or wideband */
|
||||
/** Description of a Speex sub-mode (either 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 */
|
||||
@ -81,20 +97,17 @@ typedef struct SpeexSubmode {
|
||||
lsp_quant_func lsp_quant; /**< LSP quantization function */
|
||||
lsp_unquant_func lsp_unquant; /**< LSP unquantization function */
|
||||
|
||||
/*Lont-term predictor functions*/
|
||||
/*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 */
|
||||
void *ltp_params; /**< Pitch parameters (options) */
|
||||
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 */
|
||||
void *innovation_params; /**< Innovation quantization parameters*/
|
||||
const void *innovation_params; /**< Innovation quantization parameters*/
|
||||
|
||||
/*Synthesis filter enhancement*/
|
||||
float lpc_enh_k1; /**< Enhancer constant */
|
||||
float lpc_enh_k2; /**< Enhancer constant */
|
||||
float comb_gain; /**< Gain of enhancer comb filter */
|
||||
spx_word16_t comb_gain; /**< Gain of enhancer comb filter */
|
||||
|
||||
int bits_per_frame; /**< Number of bits per frame after encoding*/
|
||||
} SpeexSubmode;
|
||||
@ -104,17 +117,14 @@ 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 bufSize; /**< Size of signal buffer to use in encoder */
|
||||
int pitchStart; /**< Smallest pitch value allowed */
|
||||
int pitchEnd; /**< Largest pitch value allowed */
|
||||
|
||||
float gamma1; /**< Perceptual filter parameter #1 */
|
||||
float gamma2; /**< Perceptual filter parameter #2 */
|
||||
float lag_factor; /**< Lag-windowing parameter */
|
||||
float lpc_floor; /**< Noise floor for LPC analysis */
|
||||
float preemph; /**< Pre-emphasis */
|
||||
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 */
|
||||
|
||||
SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */
|
||||
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;
|
||||
@ -122,25 +132,29 @@ typedef struct SpeexNBMode {
|
||||
|
||||
/** Struct defining the encoding/decoding mode for SB-CELP (wideband) */
|
||||
typedef struct SpeexSBMode {
|
||||
SpeexMode *nb_mode; /**< Embedded narrowband mode */
|
||||
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 */
|
||||
int bufSize; /**< Signal buffer size in encoder */
|
||||
float gamma1; /**< Perceptual filter parameter #1 */
|
||||
float gamma2; /**< Perceptual filter parameter #1 */
|
||||
float lag_factor; /**< Lag-windowing parameter */
|
||||
float lpc_floor; /**< Noise floor for LPC analysis */
|
||||
float preemph; /**< Pre-emphasis */
|
||||
float folding_gain;
|
||||
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;
|
||||
|
||||
SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */
|
||||
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 */
|
||||
float (*vbr_thresh)[11];
|
||||
#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
|
||||
|
322
external/speex/src/modes_wb.c
vendored
Normal file
322
external/speex/src/modes_wb.c
vendored
Normal file
@ -0,0 +1,322 @@
|
||||
/* 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.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
#if defined(DISABLE_ENCODER) || defined(DISABLE_WIDEBAND)
|
||||
#define split_cb_search_shape_sign NULL
|
||||
#define noise_codebook_quant NULL
|
||||
#define pitch_search_3tap NULL
|
||||
#define forced_pitch_quant NULL
|
||||
#define sb_encoder_init NULL
|
||||
#define sb_encoder_destroy NULL
|
||||
#define sb_encode NULL
|
||||
#define sb_encoder_ctl NULL
|
||||
#define lsp_quant_high NULL
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
#if defined(DISABLE_DECODER) || defined(DISABLE_WIDEBAND)
|
||||
#define noise_codebook_unquant NULL
|
||||
#define split_cb_shape_sign_unquant NULL
|
||||
#define lsp_unquant_high NULL
|
||||
#define sb_decoder_init NULL
|
||||
#define sb_decoder_destroy NULL
|
||||
#define sb_decode NULL
|
||||
#define sb_decoder_ctl NULL
|
||||
#endif /* DISABLE_DECODER */
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
|
2432
external/speex/src/nb_celp.c
vendored
2432
external/speex/src/nb_celp.c
vendored
File diff suppressed because it is too large
Load Diff
191
external/speex/src/nb_celp.h
vendored
191
external/speex/src/nb_celp.h
vendored
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/* Copyright (C) 2002-2006 Jean-Marc Valin */
|
||||
/**
|
||||
@file nb_celp.h
|
||||
@brief Narrowband CELP encoder/decoder
|
||||
@ -37,160 +37,157 @@
|
||||
#define NB_CELP_H
|
||||
|
||||
#include "modes.h"
|
||||
#include "speex_bits.h"
|
||||
#include "speex_callbacks.h"
|
||||
#include "speex/speex_callbacks.h"
|
||||
#include "vbr.h"
|
||||
#include "filters.h"
|
||||
|
||||
#ifdef VORBIS_PSYCHO
|
||||
#include "vorbis_psy.h"
|
||||
#endif
|
||||
|
||||
#define NB_ORDER 10
|
||||
#define NB_FRAME_SIZE 160
|
||||
#define NB_SUBFRAME_SIZE 40
|
||||
#define NB_NB_SUBFRAMES 4
|
||||
#define NB_PITCH_START 17
|
||||
#define NB_PITCH_END 144
|
||||
|
||||
#define NB_WINDOW_SIZE (NB_FRAME_SIZE+NB_SUBFRAME_SIZE)
|
||||
#define NB_EXCBUF (NB_FRAME_SIZE+NB_PITCH_END+2)
|
||||
#define NB_DEC_BUFFER (NB_FRAME_SIZE+2*NB_PITCH_END+NB_SUBFRAME_SIZE+12)
|
||||
/**Structure representing the full state of the narrowband encoder*/
|
||||
typedef struct EncState {
|
||||
SpeexMode *mode; /**< Mode corresponding to the state */
|
||||
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 bufSize; /**< Buffer size */
|
||||
int min_pitch; /**< Minimum pitch value allowed */
|
||||
int max_pitch; /**< Maximum pitch value allowed */
|
||||
|
||||
int safe_pitch; /**< Don't use too large values for pitch (in case we lose a packet) */
|
||||
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;
|
||||
float gamma1; /**< Perceptual filter: A(z/gamma1) */
|
||||
float gamma2; /**< Perceptual filter: A(z/gamma2) */
|
||||
float lag_factor; /**< Lag windowing Gaussian width */
|
||||
float lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/
|
||||
float preemph; /**< Pre-emphasis: P(z) = 1 - a*z^-1*/
|
||||
float pre_mem; /**< 1-element memory for pre-emphasis */
|
||||
float pre_mem2; /**< 1-element memory for pre-emphasis */
|
||||
char *stack; /**< Pseudo-stack allocation for temporary memory */
|
||||
float *inBuf; /**< Input buffer (original signal) */
|
||||
float *frame; /**< Start of original frame */
|
||||
float *excBuf; /**< Excitation buffer */
|
||||
float *exc; /**< Start of excitation frame */
|
||||
float *exc2Buf; /**< "Pitch enhanced" excitation */
|
||||
float *exc2; /**< "Pitch enhanced" excitation */
|
||||
float *swBuf; /**< Weighted signal buffer */
|
||||
float *sw; /**< Start of weighted signal frame */
|
||||
float *innov; /**< Innovation for the frame */
|
||||
float *window; /**< Temporary (Hanning) window */
|
||||
float *buf2; /**< 2nd temporary buffer */
|
||||
float *autocorr; /**< auto-correlation */
|
||||
float *lagWindow; /**< Window applied to auto-correlation */
|
||||
float *lpc; /**< LPCs for current frame */
|
||||
float *lsp; /**< LSPs for current frame */
|
||||
float *qlsp; /**< Quantized LSPs for current frame */
|
||||
float *old_lsp; /**< LSPs for previous frame */
|
||||
float *old_qlsp; /**< Quantized LSPs for previous frame */
|
||||
float *interp_lsp; /**< Interpolated LSPs */
|
||||
float *interp_qlsp; /**< Interpolated quantized LSPs */
|
||||
float *interp_lpc; /**< Interpolated LPCs */
|
||||
float *interp_qlpc; /**< Interpolated quantized LPCs */
|
||||
float *bw_lpc1; /**< LPCs after bandwidth expansion by gamma1 for perceptual weighting*/
|
||||
float *bw_lpc2; /**< LPCs after bandwidth expansion by gamma2 for perceptual weighting*/
|
||||
float *rc; /**< Reflection coefficients */
|
||||
float *mem_sp; /**< Filter memory for signal synthesis */
|
||||
float *mem_sw; /**< Filter memory for perceptually-weighted signal */
|
||||
float *mem_sw_whole; /**< Filter memory for perceptually-weighted signal (whole frame)*/
|
||||
float *mem_exc; /**< Filter memory for excitation (whole frame) */
|
||||
float *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */
|
||||
int pitch[NB_NB_SUBFRAMES];
|
||||
|
||||
VBRState *vbr; /**< State of the VBR data */
|
||||
#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[NB_WINDOW_SIZE-NB_FRAME_SIZE]; /**< Input buffer (original signal) */
|
||||
spx_word16_t excBuf[NB_EXCBUF]; /**< Excitation buffer */
|
||||
spx_word16_t *exc; /**< Start of excitation frame */
|
||||
spx_word16_t swBuf[NB_EXCBUF]; /**< 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[NB_ORDER]; /**< LSPs for previous frame */
|
||||
spx_lsp_t old_qlsp[NB_ORDER]; /**< Quantized LSPs for previous frame */
|
||||
spx_mem_t mem_sp[NB_ORDER]; /**< Filter memory for signal synthesis */
|
||||
spx_mem_t mem_sw[NB_ORDER]; /**< Filter memory for perceptually-weighted signal */
|
||||
spx_mem_t mem_sw_whole[NB_ORDER]; /**< Filter memory for perceptually-weighted signal (whole frame)*/
|
||||
spx_mem_t mem_exc[NB_ORDER]; /**< Filter memory for excitation (whole frame) */
|
||||
spx_mem_t mem_exc2[NB_ORDER]; /**< Filter memory for excitation (whole frame) */
|
||||
spx_mem_t mem_hp[2]; /**< High-pass filter memory */
|
||||
spx_word32_t pi_gain[NB_NB_SUBFRAMES]; /**< 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 */
|
||||
int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */
|
||||
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 */
|
||||
int abr_enabled; /**< ABR setting (in bps), 0 if off */
|
||||
spx_int32_t abr_enabled; /**< ABR setting (in bps), 0 if off */
|
||||
float abr_drift;
|
||||
float abr_drift2;
|
||||
float abr_count;
|
||||
int complexity; /**< Complexity setting (0-10 from least complex to most complex) */
|
||||
int sampling_rate;
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
||||
SpeexSubmode **submodes; /**< Sub-mode data */
|
||||
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 {
|
||||
SpeexMode *mode; /**< Mode corresponding to the state */
|
||||
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 windowSize; /**< Analysis (LPC) window length */
|
||||
int lpcSize; /**< LPC order */
|
||||
int bufSize; /**< Buffer size */
|
||||
int min_pitch; /**< Minimum pitch value allowed */
|
||||
int max_pitch; /**< Maximum pitch value allowed */
|
||||
int sampling_rate;
|
||||
float last_ol_gain; /**< Open-loop gain for previous frame */
|
||||
spx_int32_t sampling_rate;
|
||||
|
||||
spx_word16_t last_ol_gain; /**< Open-loop gain for previous frame */
|
||||
|
||||
float gamma1; /**< Perceptual filter: A(z/gamma1) */
|
||||
float gamma2; /**< Perceptual filter: A(z/gamma2) */
|
||||
float preemph; /**< Pre-emphasis: P(z) = 1 - a*z^-1*/
|
||||
float pre_mem; /**< 1-element memory for pre-emphasis */
|
||||
char *stack; /**< Pseudo-stack allocation for temporary memory */
|
||||
float *inBuf; /**< Input buffer (original signal) */
|
||||
float *frame; /**< Start of original frame */
|
||||
float *excBuf; /**< Excitation buffer */
|
||||
float *exc; /**< Start of excitation frame */
|
||||
float *innov; /**< Innovation for the frame */
|
||||
float *qlsp; /**< Quantized LSPs for current frame */
|
||||
float *old_qlsp; /**< Quantized LSPs for previous frame */
|
||||
float *interp_qlsp; /**< Interpolated quantized LSPs */
|
||||
float *interp_qlpc; /**< Interpolated quantized LPCs */
|
||||
float *mem_sp; /**< Filter memory for synthesis signal */
|
||||
float *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */
|
||||
int last_pitch; /**< Pitch of last correctly decoded frame */
|
||||
float last_pitch_gain; /**< Pitch gain of last correctly decoded frame */
|
||||
float pitch_gain_buf[3]; /**< Pitch gain of last decoded frames */
|
||||
int pitch_gain_buf_idx; /**< Tail of the buffer */
|
||||
spx_word16_t excBuf[NB_DEC_BUFFER]; /**< Excitation buffer */
|
||||
spx_word16_t *exc; /**< Start of excitation frame */
|
||||
spx_lsp_t old_qlsp[NB_ORDER]; /**< Quantized LSPs for previous frame */
|
||||
spx_coef_t interp_qlpc[NB_ORDER]; /**< Interpolated quantized LPCs */
|
||||
spx_mem_t mem_sp[NB_ORDER]; /**< Filter memory for synthesis signal */
|
||||
spx_mem_t mem_hp[2]; /**< High-pass filter memory */
|
||||
spx_word32_t pi_gain[NB_NB_SUBFRAMES]; /**< Gain of LPC filter at theta=pi (fe/2) */
|
||||
spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */
|
||||
|
||||
SpeexSubmode **submodes; /**< Sub-mode data */
|
||||
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_uint32_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 */
|
||||
CombFilterMem *comb_mem;
|
||||
SpeexCallback speex_callbacks[SPEEX_MAX_CALLBACKS];
|
||||
|
||||
SpeexCallback user_callback;
|
||||
|
||||
/*Vocoder data*/
|
||||
float voc_m1;
|
||||
float voc_m2;
|
||||
float voc_mean;
|
||||
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(SpeexMode *m);
|
||||
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, float *in, SpeexBits *bits);
|
||||
int nb_encode(void *state, void *in, SpeexBits *bits);
|
||||
|
||||
|
||||
/** Initializes decoder state*/
|
||||
void *nb_decoder_init(SpeexMode *m);
|
||||
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, float *out);
|
||||
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);
|
||||
|
169
external/speex/src/os_support.h
vendored
Normal file
169
external/speex/src/os_support.h
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
/* 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>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#ifdef OS_SUPPORT_CUSTOM
|
||||
#include "os_support_custom.h"
|
||||
#endif
|
||||
|
||||
/** 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 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 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 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 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 inline void speex_free_scratch (void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Copy n elements 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 elements 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
|
||||
|
||||
/** For n elements worth of memory, set every byte to the value of c, starting at address dst */
|
||||
#ifndef OVERRIDE_SPEEX_MEMSET
|
||||
#define SPEEX_MEMSET(dst, c, n) (memset((dst), (c), (n)*sizeof(*(dst))))
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_FATAL
|
||||
static 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 inline void speex_warning(const char *str)
|
||||
{
|
||||
#ifndef DISABLE_WARNINGS
|
||||
fprintf (stderr, "warning: %s\n", str);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_WARNING_INT
|
||||
static 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 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 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 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
|
||||
|
329
external/speex/src/quant_lsp.c
vendored
329
external/speex/src/quant_lsp.c
vendored
@ -30,97 +30,151 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "quant_lsp.h"
|
||||
#include "os_support.h"
|
||||
#include <math.h>
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
extern int lsp_nb_vqid[64];
|
||||
static float quant_weight[MAX_LSP_SIZE];
|
||||
#include "arch.h"
|
||||
|
||||
/* Note: x is modified*/
|
||||
static int lsp_quant(float *x, signed char *cdbk, int nbVec, int nbDim)
|
||||
{
|
||||
int i,j;
|
||||
float dist, tmp;
|
||||
float best_dist=0;
|
||||
int best_id=0;
|
||||
signed char *ptr=cdbk;
|
||||
for (i=0;i<nbVec;i++)
|
||||
{
|
||||
dist=0;
|
||||
for (j=0;j<nbDim;j++)
|
||||
{
|
||||
tmp=(x[j]-*ptr++);
|
||||
dist+=tmp*tmp;
|
||||
}
|
||||
if (dist<best_dist || i==0)
|
||||
{
|
||||
best_dist=dist;
|
||||
best_id=i;
|
||||
}
|
||||
}
|
||||
#ifdef BFIN_ASM
|
||||
#include "quant_lsp_bfin.h"
|
||||
#endif
|
||||
|
||||
for (j=0;j<nbDim;j++)
|
||||
x[j] -= cdbk[best_id*nbDim+j];
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
return best_id;
|
||||
}
|
||||
#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
|
||||
|
||||
/* Note: x is modified*/
|
||||
static int lsp_weight_quant(float *x, float *weight, signed char *cdbk, int nbVec, int nbDim)
|
||||
{
|
||||
int i,j;
|
||||
float dist, tmp;
|
||||
float best_dist=0;
|
||||
int best_id=0;
|
||||
signed char *ptr=cdbk;
|
||||
for (i=0;i<nbVec;i++)
|
||||
{
|
||||
dist=0;
|
||||
for (j=0;j<nbDim;j++)
|
||||
{
|
||||
tmp=(x[j]-*ptr++);
|
||||
dist+=weight[j]*tmp*tmp;
|
||||
}
|
||||
if (dist<best_dist || i==0)
|
||||
{
|
||||
best_dist=dist;
|
||||
best_id=i;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
for (j=0;j<nbDim;j++)
|
||||
x[j] -= cdbk[best_id*nbDim+j];
|
||||
return best_id;
|
||||
}
|
||||
#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
|
||||
|
||||
void lsp_quant_nb(float *lsp, float *qlsp, int order, SpeexBits *bits)
|
||||
#ifndef DISABLE_ENCODER
|
||||
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;
|
||||
float tmp1, tmp2;
|
||||
int id;
|
||||
spx_word16_t quant_weight[10];
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i];
|
||||
|
||||
quant_weight[0] = 1/(qlsp[1]-qlsp[0]);
|
||||
quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]);
|
||||
for (i=1;i<order-1;i++)
|
||||
{
|
||||
#if 1
|
||||
tmp1 = 1/((.15+qlsp[i]-qlsp[i-1])*(.15+qlsp[i]-qlsp[i-1]));
|
||||
tmp2 = 1/((.15+qlsp[i+1]-qlsp[i])*(.15+qlsp[i+1]-qlsp[i]));
|
||||
#else
|
||||
tmp1 = 1/(qlsp[i]-qlsp[i-1]);
|
||||
tmp2 = 1/(qlsp[i+1]-qlsp[i]);
|
||||
#endif
|
||||
quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
|
||||
}
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]-=(.25*i+.25);
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]*=256;
|
||||
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);
|
||||
|
||||
@ -145,70 +199,67 @@ void lsp_quant_nb(float *lsp, float *qlsp, int order, SpeexBits *bits)
|
||||
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]*=.00097656;
|
||||
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];
|
||||
}
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
void lsp_unquant_nb(float *lsp, int order, SpeexBits *bits)
|
||||
#ifndef DISABLE_DECODER
|
||||
void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i, id;
|
||||
for (i=0;i<order;i++)
|
||||
lsp[i]=.25*i+.25;
|
||||
lsp[i]=LSP_LINEAR(i);
|
||||
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<10;i++)
|
||||
lsp[i] += 0.0039062*cdbk_nb[id*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] += 0.0019531 * cdbk_nb_low1[id*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] += 0.00097656 * cdbk_nb_low2[id*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] += 0.0019531 * cdbk_nb_high1[id*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] += 0.00097656 * cdbk_nb_high2[id*5+i];
|
||||
lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_1024(cdbk_nb_high2[id*5+i]));
|
||||
}
|
||||
#endif /* DISABLE_DECODER */
|
||||
|
||||
|
||||
void lsp_quant_lbr(float *lsp, float *qlsp, int order, SpeexBits *bits)
|
||||
#ifndef DISABLE_ENCODER
|
||||
void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
float tmp1, tmp2;
|
||||
int id;
|
||||
spx_word16_t quant_weight[10];
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i];
|
||||
|
||||
quant_weight[0] = 1/(qlsp[1]-qlsp[0]);
|
||||
quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]);
|
||||
for (i=1;i<order-1;i++)
|
||||
{
|
||||
#if 1
|
||||
tmp1 = 1/((.15+qlsp[i]-qlsp[i-1])*(.15+qlsp[i]-qlsp[i-1]));
|
||||
tmp2 = 1/((.15+qlsp[i+1]-qlsp[i])*(.15+qlsp[i+1]-qlsp[i]));
|
||||
#else
|
||||
tmp1 = 1/(qlsp[i]-qlsp[i-1]);
|
||||
tmp2 = 1/(qlsp[i+1]-qlsp[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
|
||||
quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
|
||||
}
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]-=(.25*i+.25);
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]*=256;
|
||||
|
||||
id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
@ -221,61 +272,73 @@ void lsp_quant_lbr(float *lsp, float *qlsp, int order, SpeexBits *bits)
|
||||
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]*=0.0019531;
|
||||
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];
|
||||
}
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
void lsp_unquant_lbr(float *lsp, int order, SpeexBits *bits)
|
||||
#ifndef DISABLE_DECODER
|
||||
void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i, id;
|
||||
for (i=0;i<order;i++)
|
||||
lsp[i]=.25*i+.25;
|
||||
lsp[i]=LSP_LINEAR(i);
|
||||
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<10;i++)
|
||||
lsp[i] += 0.0039062*cdbk_nb[id*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] += 0.0019531*cdbk_nb_low1[id*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] += 0.0019531*cdbk_nb_high1[id*5+i];
|
||||
lsp[i+5] += LSP_DIV_512(cdbk_nb_high1[id*5+i]);
|
||||
|
||||
}
|
||||
#endif /* DISABLE_DECODER */
|
||||
|
||||
#ifndef DISABLE_WIDEBAND
|
||||
extern const signed char high_lsp_cdbk[];
|
||||
extern const signed char high_lsp_cdbk2[];
|
||||
|
||||
extern signed char high_lsp_cdbk[];
|
||||
extern signed char high_lsp_cdbk2[];
|
||||
|
||||
|
||||
void lsp_quant_high(float *lsp, float *qlsp, int order, SpeexBits *bits)
|
||||
#ifndef DISABLE_ENCODER
|
||||
void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
float tmp1, tmp2;
|
||||
int id;
|
||||
spx_word16_t quant_weight[10];
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i];
|
||||
|
||||
quant_weight[0] = 1/(qlsp[1]-qlsp[0]);
|
||||
quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]);
|
||||
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 = 1/(qlsp[i]-qlsp[i-1]);
|
||||
tmp2 = 1/(qlsp[i+1]-qlsp[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]-=(.3125*i+.75);
|
||||
qlsp[i]=SUB16(qlsp[i],LSP_LINEAR_HIGH(i));
|
||||
#ifndef FIXED_POINT
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]*=256;
|
||||
|
||||
qlsp[i] = qlsp[i]*LSP_SCALE;
|
||||
#endif
|
||||
id = lsp_quant(qlsp, high_lsp_cdbk, 64, order);
|
||||
speex_bits_pack(bits, id, 6);
|
||||
|
||||
@ -285,27 +348,39 @@ void lsp_quant_high(float *lsp, float *qlsp, int order, SpeexBits *bits)
|
||||
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]*=0.0019531;
|
||||
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];
|
||||
}
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
void lsp_unquant_high(float *lsp, int order, SpeexBits *bits)
|
||||
|
||||
#ifndef DISABLE_DECODER
|
||||
void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
{
|
||||
|
||||
int i, id;
|
||||
for (i=0;i<order;i++)
|
||||
lsp[i]=.3125*i+.75;
|
||||
lsp[i]=LSP_LINEAR_HIGH(i);
|
||||
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 6);
|
||||
for (i=0;i<order;i++)
|
||||
lsp[i] += 0.0039062*high_lsp_cdbk[id*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] += 0.0019531*high_lsp_cdbk2[id*order+i];
|
||||
lsp[i] += LSP_DIV_512(high_lsp_cdbk2[id*order+i]);
|
||||
}
|
||||
#endif /* DISABLE_DECODER */
|
||||
|
||||
#endif /* DISABLE_WIDEBAND */
|
||||
|
||||
|
35
external/speex/src/quant_lsp.h
vendored
35
external/speex/src/quant_lsp.h
vendored
@ -1,7 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: quant_lsp.h
|
||||
LSP vector quantization
|
||||
|
||||
/* 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:
|
||||
@ -33,7 +35,8 @@
|
||||
#ifndef QUANT_LSP_H
|
||||
#define QUANT_LSP_H
|
||||
|
||||
#include "speex_bits.h"
|
||||
#include "speex/speex_bits.h"
|
||||
#include "arch.h"
|
||||
|
||||
#define MAX_LSP_SIZE 20
|
||||
|
||||
@ -44,28 +47,28 @@
|
||||
#define NB_CDBK_SIZE_HIGH2 64
|
||||
|
||||
/*Narrowband codebooks*/
|
||||
extern signed char cdbk_nb[];
|
||||
extern signed char cdbk_nb_low1[];
|
||||
extern signed char cdbk_nb_low2[];
|
||||
extern signed char cdbk_nb_high1[];
|
||||
extern signed char cdbk_nb_high2[];
|
||||
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(float *lsp, float *qlsp, int order, SpeexBits *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(float *lsp, int order, SpeexBits *bits);
|
||||
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(float *lsp, float *qlsp, int order, SpeexBits *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(float *lsp, int order, SpeexBits *bits);
|
||||
void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits);
|
||||
|
||||
/* Quantizes high-band LSPs with 12 bits */
|
||||
void lsp_quant_high(float *lsp, float *qlsp, int order, SpeexBits *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(float *lsp, int order, SpeexBits *bits);
|
||||
void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits);
|
||||
|
||||
#endif
|
||||
|
168
external/speex/src/quant_lsp_bfin.h
vendored
Normal file
168
external/speex/src/quant_lsp_bfin.h
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
/* 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
|
||||
|
||||
#include "bfin.h"
|
||||
|
||||
/*
|
||||
Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
|
||||
well tell you all the magic register 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",
|
||||
"CC", "ASTAT" BFIN_HWLOOP0_REGS BFIN_HWLOOP1_REGS
|
||||
);
|
||||
|
||||
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 register 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", "CC", "ASTAT" BFIN_HWLOOP0_REGS BFIN_HWLOOP1_REGS
|
||||
);
|
||||
|
||||
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
|
1715
external/speex/src/sb_celp.c
vendored
1715
external/speex/src/sb_celp.c
vendored
File diff suppressed because it is too large
Load Diff
103
external/speex/src/sb_celp.h
vendored
103
external/speex/src/sb_celp.h
vendored
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/* Copyright (C) 2002-2006 Jean-Marc Valin */
|
||||
/**
|
||||
@file sb_celp.h
|
||||
@brief Sub-band CELP mode used for wideband encoding
|
||||
@ -37,12 +37,11 @@
|
||||
#define SB_CELP_H
|
||||
|
||||
#include "modes.h"
|
||||
#include "speex_bits.h"
|
||||
#include "nb_celp.h"
|
||||
|
||||
/**Structure representing the full state of the sub-band encoder*/
|
||||
typedef struct SBEncState {
|
||||
SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */
|
||||
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*/
|
||||
@ -50,67 +49,54 @@ typedef struct SBEncState {
|
||||
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 bufSize; /**< Buffer size */
|
||||
int first; /**< First frame? */
|
||||
float lag_factor; /**< Lag-windowing control parameter */
|
||||
float lpc_floor; /**< Controls LPC analysis noise floor */
|
||||
float gamma1; /**< Perceptual weighting coef 1 */
|
||||
float gamma2; /**< Perceptual weighting coef 2 */
|
||||
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 */
|
||||
float *x0d, *x1d; /**< QMF filter signals*/
|
||||
float *high; /**< High-band signal (buffer) */
|
||||
float *y0, *y1; /**< QMF synthesis signals */
|
||||
float *h0_mem, *h1_mem, *g0_mem, *g1_mem; /**< QMF memories */
|
||||
spx_word16_t *high; /**< High-band signal (buffer) */
|
||||
spx_word16_t *h0_mem;
|
||||
|
||||
float *excBuf; /**< High-band excitation */
|
||||
float *exc; /**< High-band excitation (for QMF only)*/
|
||||
float *buf; /**< Temporary buffer */
|
||||
float *res; /**< Zero-input response (ringing) */
|
||||
float *sw; /**< Perceptually weighted signal */
|
||||
float *target; /**< Weighted target signal (analysis by synthesis) */
|
||||
float *window; /**< LPC analysis window */
|
||||
float *lagWindow; /**< Auto-correlation window */
|
||||
float *autocorr; /**< Auto-correlation (for LPC analysis) */
|
||||
float *rc; /**< Reflection coefficients (unused) */
|
||||
float *lpc; /**< LPC coefficients */
|
||||
float *lsp; /**< LSP coefficients */
|
||||
float *qlsp; /**< Quantized LSPs */
|
||||
float *old_lsp; /**< LSPs of previous frame */
|
||||
float *old_qlsp; /**< Quantized LSPs of previous frame */
|
||||
float *interp_lsp; /**< Interpolated LSPs for current sub-frame */
|
||||
float *interp_qlsp; /**< Interpolated quantized LSPs for current sub-frame */
|
||||
float *interp_lpc; /**< Interpolated LPCs for current sub-frame */
|
||||
float *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */
|
||||
float *bw_lpc1; /**< Bandwidth-expanded version of LPCs (#1) */
|
||||
float *bw_lpc2; /**< Bandwidth-expanded version of LPCs (#2) */
|
||||
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 */
|
||||
|
||||
float *mem_sp; /**< Synthesis signal memory */
|
||||
float *mem_sp2;
|
||||
float *mem_sw; /**< Perceptual signal memory */
|
||||
float *pi_gain;
|
||||
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 */
|
||||
int abr_enabled; /**< ABR setting (in bps), 0 if off */
|
||||
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 */
|
||||
|
||||
SpeexSubmode **submodes;
|
||||
int encode_submode;
|
||||
const SpeexSubmode * const *submodes;
|
||||
int submodeID;
|
||||
int submodeSelect;
|
||||
int complexity;
|
||||
int sampling_rate;
|
||||
spx_int32_t sampling_rate;
|
||||
|
||||
} SBEncState;
|
||||
|
||||
|
||||
/**Structure representing the full state of the sub-band decoder*/
|
||||
typedef struct SBDecState {
|
||||
SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */
|
||||
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;
|
||||
@ -118,47 +104,48 @@ typedef struct SBDecState {
|
||||
int nbSubframes;
|
||||
int lpcSize;
|
||||
int first;
|
||||
int sampling_rate;
|
||||
spx_int32_t sampling_rate;
|
||||
int lpc_enh_enabled;
|
||||
|
||||
char *stack;
|
||||
float *x0d, *x1d;
|
||||
float *high;
|
||||
float *y0, *y1;
|
||||
float *h0_mem, *h1_mem, *g0_mem, *g1_mem;
|
||||
spx_word16_t *g0_mem, *g1_mem;
|
||||
|
||||
float *exc;
|
||||
float *qlsp;
|
||||
float *old_qlsp;
|
||||
float *interp_qlsp;
|
||||
float *interp_qlpc;
|
||||
spx_word16_t *excBuf;
|
||||
spx_lsp_t *old_qlsp;
|
||||
spx_coef_t *interp_qlpc;
|
||||
|
||||
float *mem_sp;
|
||||
float *pi_gain;
|
||||
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 */
|
||||
|
||||
SpeexSubmode **submodes;
|
||||
spx_word16_t last_ener;
|
||||
spx_uint32_t seed;
|
||||
|
||||
int encode_submode;
|
||||
const SpeexSubmode * const *submodes;
|
||||
int submodeID;
|
||||
} SBDecState;
|
||||
|
||||
|
||||
/**Initializes encoder state*/
|
||||
void *sb_encoder_init(SpeexMode *m);
|
||||
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, float *in, SpeexBits *bits);
|
||||
int sb_encode(void *state, void *in, SpeexBits *bits);
|
||||
|
||||
|
||||
/**Initializes decoder state*/
|
||||
void *sb_decoder_init(SpeexMode *m);
|
||||
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, float *out);
|
||||
int sb_decode(void *state, SpeexBits *bits, void *out);
|
||||
|
||||
int sb_encoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
|
1261
external/speex/src/smallft.c
vendored
Normal file
1261
external/speex/src/smallft.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
46
external/speex/src/smallft.h
vendored
Normal file
46
external/speex/src/smallft.h
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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
|
253
external/speex/src/speex.c
vendored
Normal file
253
external/speex/src/speex.c
vendored
Normal file
@ -0,0 +1,253 @@
|
||||
/* 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.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#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);
|
||||
if (ret == 0)
|
||||
{
|
||||
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;
|
||||
}
|
45
external/speex/src/speex_callbacks.c
vendored
45
external/speex/src/speex_callbacks.c
vendored
@ -32,10 +32,15 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "speex_callbacks.h"
|
||||
#include "misc.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state)
|
||||
#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;
|
||||
@ -67,67 +72,71 @@ int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *st
|
||||
return 0;
|
||||
}
|
||||
|
||||
int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
int m;
|
||||
spx_int32_t m;
|
||||
m = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_encoder_ctl(data, SPEEX_SET_MODE, &m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
int m;
|
||||
spx_int32_t m;
|
||||
m = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_encoder_ctl(data, SPEEX_SET_LOW_MODE, &m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
int m;
|
||||
spx_int32_t m;
|
||||
m = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_encoder_ctl(data, SPEEX_SET_HIGH_MODE, &m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
#ifndef DISABLE_VBR
|
||||
EXPORT int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
int vbr;
|
||||
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 */
|
||||
|
||||
int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
int enh;
|
||||
spx_int32_t enh;
|
||||
enh = speex_bits_unpack_unsigned(bits, 1);
|
||||
speex_decoder_ctl(data, SPEEX_SET_ENH, &enh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
#ifndef DISABLE_VBR
|
||||
EXPORT int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
int qual;
|
||||
float qual;
|
||||
qual = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual);
|
||||
return 0;
|
||||
}
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
||||
|
||||
int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
|
||||
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 */
|
||||
int speex_default_user_handler(SpeexBits *bits, void *state, void *data)
|
||||
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);
|
||||
|
78
external/speex/src/speex_header.c
vendored
78
external/speex/src/speex_header.c
vendored
@ -31,14 +31,35 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "speex_header.h"
|
||||
#include "misc.h"
|
||||
#include "speex.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#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 inline spx_int32_t le_int(spx_int32_t i)
|
||||
{
|
||||
#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
|
||||
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);}
|
||||
|
||||
|
||||
@ -62,19 +83,19 @@ typedef struct SpeexHeader {
|
||||
} SpeexHeader;
|
||||
*/
|
||||
|
||||
void speex_init_header(SpeexHeader *header, int rate, int nb_channels, SpeexMode *m)
|
||||
EXPORT void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m)
|
||||
{
|
||||
int i;
|
||||
char *h="Speex ";
|
||||
const char *h="Speex ";
|
||||
/*
|
||||
strncpy(header->speex_string, "Speex ", 8);
|
||||
strncpy(header->speex_version, VERSION, SPEEX_HEADER_VERSION_LENGTH-1);
|
||||
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 && VERSION[i];i++)
|
||||
header->speex_version[i]=VERSION[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;
|
||||
|
||||
@ -97,12 +118,12 @@ void speex_init_header(SpeexHeader *header, int rate, int nb_channels, SpeexMode
|
||||
header->reserved2 = 0;
|
||||
}
|
||||
|
||||
char *speex_header_to_packet(SpeexHeader *header, int *size)
|
||||
EXPORT char *speex_header_to_packet(SpeexHeader *header, int *size)
|
||||
{
|
||||
SpeexHeader *le_header;
|
||||
le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
|
||||
|
||||
speex_move(le_header, header, sizeof(SpeexHeader));
|
||||
SPEEX_COPY(le_header, header, 1);
|
||||
|
||||
/*Make sure everything is now little-endian*/
|
||||
ENDIAN_SWITCH(le_header->speex_version_id);
|
||||
@ -121,28 +142,30 @@ char *speex_header_to_packet(SpeexHeader *header, int *size)
|
||||
return (char *)le_header;
|
||||
}
|
||||
|
||||
SpeexHeader *speex_packet_to_header(char *packet, int size)
|
||||
EXPORT SpeexHeader *speex_packet_to_header(char *packet, int size)
|
||||
{
|
||||
int i;
|
||||
SpeexHeader *le_header;
|
||||
char *h = "Speex ";
|
||||
for (i=0;i<8;i++)
|
||||
if (packet[i]!=h[i])
|
||||
const char *h = "Speex ";
|
||||
|
||||
/*FIXME: Do we allow larger headers?*/
|
||||
if (size < (int)sizeof(SpeexHeader))
|
||||
{
|
||||
speex_warning ("This doesn't look like a Speex file");
|
||||
speex_notify("Speex header too small");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*FIXME: Do we allow larger headers?*/
|
||||
if (size < sizeof(SpeexHeader))
|
||||
|
||||
for (i=0;i<8;i++)
|
||||
if (packet[i]!=h[i])
|
||||
{
|
||||
speex_warning("Speex header too small");
|
||||
/* This doesn't look like a Speex file */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
|
||||
|
||||
speex_move(le_header, packet, 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);
|
||||
@ -157,6 +180,23 @@ SpeexHeader *speex_packet_to_header(char *packet, int size)
|
||||
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);
|
||||
}
|
||||
|
91
external/speex/src/stack_alloc.h
vendored
91
external/speex/src/stack_alloc.h
vendored
@ -1,8 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: stack_alloc.h
|
||||
|
||||
Temporary memory allocation on stack
|
||||
|
||||
/* 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:
|
||||
@ -34,29 +35,81 @@
|
||||
#ifndef STACK_ALLOC_H
|
||||
#define STACK_ALLOC_H
|
||||
|
||||
#if 0
|
||||
#ifdef USE_ALLOCA
|
||||
# ifdef _WIN32
|
||||
# include <malloc.h>
|
||||
# else
|
||||
# ifdef HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*Aligns the stack to a 'size' boundary */
|
||||
#define ALIGN(stack, size) (stack=(void*)((((int)stack)+((size)-1)) & (-(size))))
|
||||
/*Aligns the stack to a 'size' boundary minus k */
|
||||
#define ALIGN_1(stack, size, k) (stack=(void*)(((((int)stack)+((size)-1+(k))) & (-(size)))-(k)))
|
||||
/**
|
||||
* @def ALIGN(stack, size)
|
||||
*
|
||||
* Aligns the stack to a 'size' boundary
|
||||
*
|
||||
* @param stack Stack
|
||||
* @param size New size boundary
|
||||
*/
|
||||
|
||||
/* Allocates 'size' elements of type 'type' on the stack */
|
||||
#define PUSH(stack, size, type) (ALIGN(stack,sizeof(type)),stack=(void*)(((int)stack)+((size)*sizeof(type))),(type*)(((int)stack)-((size)*sizeof(type))))
|
||||
/**
|
||||
* @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
|
||||
|
||||
/*Aligns the stack to a 'size' boundary */
|
||||
#define ALIGN(stack, size) ((stack) += ((size) - (int)(stack)) & ((size) - 1))
|
||||
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
|
||||
|
||||
/* Allocates 'size' elements of type 'type' on the stack */
|
||||
#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
|
||||
|
||||
/* Allocates a struct stack */
|
||||
#define PUSHS(stack, type) (ALIGN((stack),sizeof(long)),(stack)+=(sizeof(type)),(type*)((stack)-(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
|
||||
|
||||
#endif
|
||||
|
247
external/speex/src/stereo.c
vendored
247
external/speex/src/stereo.c
vendored
@ -29,25 +29,94 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "speex_stereo.h"
|
||||
#include "speex_callbacks.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#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};*/
|
||||
static float e_ratio_quant[4] = {.25, .315, .397, .5};
|
||||
#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
|
||||
|
||||
void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
|
||||
/* 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_ENCODER
|
||||
#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 += data[2*i]*data[2*i];
|
||||
e_right += data[2*i+1]*data[2*i+1];
|
||||
data[i] = .5*(data[2*i]+data[2*i+1]);
|
||||
e_tot += data[i]*data[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);
|
||||
@ -69,52 +138,168 @@ void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
|
||||
|
||||
speex_bits_pack(bits, (int)balance, 5);
|
||||
|
||||
/*Quantize energy ratio*/
|
||||
tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4);
|
||||
/* 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 */
|
||||
|
||||
void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo)
|
||||
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;
|
||||
int sqr_shift;
|
||||
|
||||
/* Avoid overflows when summing squares */
|
||||
sqr_shift = frame_size >= 512 ? 9 : 8;
|
||||
#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]),sqr_shift);
|
||||
e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),sqr_shift);
|
||||
#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]),sqr_shift);
|
||||
}
|
||||
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);
|
||||
}
|
||||
#else /* DISABLE_ENCODER */
|
||||
EXPORT void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits)
|
||||
{
|
||||
}
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
EXPORT void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo)
|
||||
{
|
||||
float balance, e_ratio;
|
||||
int i;
|
||||
float e_tot=0, e_left, e_right, e_sum;
|
||||
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--)
|
||||
{
|
||||
e_tot += data[i]*data[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);
|
||||
}
|
||||
e_sum=e_tot/e_ratio;
|
||||
e_left = e_sum*balance / (1+balance);
|
||||
e_right = e_sum-e_left;
|
||||
}
|
||||
#endif /* #ifndef DISABLE_FLOAT_API */
|
||||
|
||||
e_left = sqrt(e_left/(e_tot+.01));
|
||||
e_right = sqrt(e_right/(e_tot+.01));
|
||||
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--)
|
||||
{
|
||||
float ftmp=data[i];
|
||||
stereo->smooth_left = .98*stereo->smooth_left + .02*e_left;
|
||||
stereo->smooth_right = .98*stereo->smooth_right + .02*e_right;
|
||||
data[2*i] = stereo->smooth_left*ftmp;
|
||||
data[2*i+1] = stereo->smooth_right*ftmp;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
SpeexStereoState *stereo;
|
||||
float sign=1;
|
||||
RealSpeexStereoState *stereo;
|
||||
spx_word16_t sign=1, dexp;
|
||||
int tmp;
|
||||
|
||||
stereo = (SpeexStereoState*)data;
|
||||
stereo = (RealSpeexStereoState*)data;
|
||||
|
||||
COMPATIBILITY_HACK(stereo);
|
||||
|
||||
if (speex_bits_unpack_unsigned(bits, 1))
|
||||
sign=-1;
|
||||
tmp = speex_bits_unpack_unsigned(bits, 5);
|
||||
stereo->balance = exp(sign*.25*tmp);
|
||||
|
||||
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];
|
||||
|
||||
|
145
external/speex/src/testenc.c
vendored
Normal file
145
external/speex/src/testenc.c
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "speex/speex_callbacks.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
extern long long spx_mips;
|
||||
#endif
|
||||
|
||||
#define FRAME_SIZE 160
|
||||
#include <math.h>
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *inFile, *outFile, *bitsFile;
|
||||
FILE *fin, *fout, *fbits=NULL;
|
||||
short in_short[FRAME_SIZE];
|
||||
short out_short[FRAME_SIZE];
|
||||
int snr_frames = 0;
|
||||
char cbits[200];
|
||||
int nbBits;
|
||||
int i;
|
||||
void *st;
|
||||
void *dec;
|
||||
SpeexBits bits;
|
||||
spx_int32_t tmp;
|
||||
int bitCount=0;
|
||||
spx_int32_t skip_group_delay;
|
||||
SpeexCallback callback;
|
||||
|
||||
st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
|
||||
dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
|
||||
|
||||
/* BEGIN: You probably don't need the following in a real application */
|
||||
callback.callback_id = SPEEX_INBAND_CHAR;
|
||||
callback.func = speex_std_char_handler;
|
||||
callback.data = stderr;
|
||||
speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
|
||||
|
||||
callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
|
||||
callback.func = speex_std_mode_request_handler;
|
||||
callback.data = st;
|
||||
speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
|
||||
/* END of unnecessary stuff */
|
||||
|
||||
tmp=1;
|
||||
speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
|
||||
tmp=0;
|
||||
speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
|
||||
tmp=8;
|
||||
speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
|
||||
tmp=1;
|
||||
speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
|
||||
|
||||
/* Turn this off if you want to measure SNR (on by default) */
|
||||
tmp=1;
|
||||
speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &tmp);
|
||||
speex_decoder_ctl(dec, SPEEX_SET_HIGHPASS, &tmp);
|
||||
|
||||
speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay);
|
||||
speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp);
|
||||
skip_group_delay += tmp;
|
||||
|
||||
if (argc != 4 && argc != 3)
|
||||
{
|
||||
fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
|
||||
exit(1);
|
||||
}
|
||||
inFile = argv[1];
|
||||
fin = fopen(inFile, "rb");
|
||||
outFile = argv[2];
|
||||
fout = fopen(outFile, "wb+");
|
||||
if (argc==4)
|
||||
{
|
||||
bitsFile = argv[3];
|
||||
fbits = fopen(bitsFile, "wb");
|
||||
}
|
||||
speex_bits_init(&bits);
|
||||
while (!feof(fin))
|
||||
{
|
||||
fread(in_short, sizeof(short), FRAME_SIZE, fin);
|
||||
if (feof(fin))
|
||||
break;
|
||||
speex_bits_reset(&bits);
|
||||
|
||||
speex_encode_int(st, in_short, &bits);
|
||||
nbBits = speex_bits_write(&bits, cbits, 200);
|
||||
bitCount+=bits.nbBits;
|
||||
|
||||
if (argc==4)
|
||||
fwrite(cbits, 1, nbBits, fbits);
|
||||
speex_bits_rewind(&bits);
|
||||
|
||||
speex_decode_int(dec, &bits, out_short);
|
||||
speex_bits_reset(&bits);
|
||||
|
||||
fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
|
||||
skip_group_delay = 0;
|
||||
}
|
||||
fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
|
||||
speex_encoder_destroy(st);
|
||||
speex_decoder_destroy(dec);
|
||||
speex_bits_destroy(&bits);
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
{
|
||||
float sigpow,errpow,snr, seg_snr=0;
|
||||
sigpow = 0;
|
||||
errpow = 0;
|
||||
|
||||
/* This code just computes SNR, so you don't need it either */
|
||||
rewind(fin);
|
||||
rewind(fout);
|
||||
|
||||
while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin)
|
||||
&&
|
||||
FRAME_SIZE == fread(out_short, sizeof(short), FRAME_SIZE,fout) )
|
||||
{
|
||||
float s=0, e=0;
|
||||
for (i=0;i<FRAME_SIZE;++i) {
|
||||
s += (float)in_short[i] * in_short[i];
|
||||
e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
|
||||
}
|
||||
seg_snr += 10*log10((s+160)/(e+160));
|
||||
sigpow += s;
|
||||
errpow += e;
|
||||
snr_frames++;
|
||||
}
|
||||
snr = 10 * log10( sigpow / errpow );
|
||||
seg_snr /= snr_frames;
|
||||
fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
return 0;
|
||||
}
|
133
external/speex/src/testenc_uwb.c
vendored
Normal file
133
external/speex/src/testenc_uwb.c
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "speex/speex_callbacks.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
extern long long spx_mips;
|
||||
#endif
|
||||
|
||||
#define FRAME_SIZE 640
|
||||
#include <math.h>
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *inFile, *outFile, *bitsFile;
|
||||
FILE *fin, *fout, *fbits=NULL;
|
||||
short in_short[FRAME_SIZE];
|
||||
short out_short[FRAME_SIZE];
|
||||
float sigpow,errpow,snr, seg_snr=0;
|
||||
int snr_frames = 0;
|
||||
char cbits[200];
|
||||
int nbBits;
|
||||
int i;
|
||||
void *st;
|
||||
void *dec;
|
||||
SpeexBits bits;
|
||||
spx_int32_t tmp;
|
||||
int bitCount=0;
|
||||
spx_int32_t skip_group_delay;
|
||||
SpeexCallback callback;
|
||||
|
||||
sigpow = 0;
|
||||
errpow = 0;
|
||||
|
||||
st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));
|
||||
dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));
|
||||
|
||||
callback.callback_id = SPEEX_INBAND_CHAR;
|
||||
callback.func = speex_std_char_handler;
|
||||
callback.data = stderr;
|
||||
speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
|
||||
|
||||
callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
|
||||
callback.func = speex_std_mode_request_handler;
|
||||
callback.data = st;
|
||||
speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
|
||||
|
||||
tmp=0;
|
||||
speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
|
||||
tmp=0;
|
||||
speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
|
||||
tmp=7;
|
||||
speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
|
||||
tmp=1;
|
||||
speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
|
||||
|
||||
speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay);
|
||||
speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp);
|
||||
skip_group_delay += tmp;
|
||||
|
||||
|
||||
if (argc != 4 && argc != 3)
|
||||
{
|
||||
fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
|
||||
exit(1);
|
||||
}
|
||||
inFile = argv[1];
|
||||
fin = fopen(inFile, "rb");
|
||||
outFile = argv[2];
|
||||
fout = fopen(outFile, "wb+");
|
||||
if (argc==4)
|
||||
{
|
||||
bitsFile = argv[3];
|
||||
fbits = fopen(bitsFile, "wb");
|
||||
}
|
||||
speex_bits_init(&bits);
|
||||
while (!feof(fin))
|
||||
{
|
||||
fread(in_short, sizeof(short), FRAME_SIZE, fin);
|
||||
if (feof(fin))
|
||||
break;
|
||||
speex_bits_reset(&bits);
|
||||
|
||||
speex_encode_int(st, in_short, &bits);
|
||||
nbBits = speex_bits_write(&bits, cbits, 200);
|
||||
bitCount+=bits.nbBits;
|
||||
|
||||
if (argc==4)
|
||||
fwrite(cbits, 1, nbBits, fbits);
|
||||
speex_bits_rewind(&bits);
|
||||
|
||||
speex_decode_int(dec, &bits, out_short);
|
||||
speex_bits_reset(&bits);
|
||||
|
||||
fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
|
||||
skip_group_delay = 0;
|
||||
}
|
||||
fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
|
||||
speex_encoder_destroy(st);
|
||||
speex_decoder_destroy(dec);
|
||||
|
||||
rewind(fin);
|
||||
rewind(fout);
|
||||
|
||||
while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin)
|
||||
&&
|
||||
FRAME_SIZE == fread(out_short, sizeof(short), FRAME_SIZE,fout) )
|
||||
{
|
||||
float s=0, e=0;
|
||||
for (i=0;i<FRAME_SIZE;++i) {
|
||||
s += (float)in_short[i] * in_short[i];
|
||||
e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
|
||||
}
|
||||
seg_snr += 10*log10((s+1)/(e+1));
|
||||
sigpow += s;
|
||||
errpow += e;
|
||||
snr_frames++;
|
||||
}
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
snr = 10 * log10( sigpow / errpow );
|
||||
seg_snr /= snr_frames;
|
||||
fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
139
external/speex/src/testenc_wb.c
vendored
Normal file
139
external/speex/src/testenc_wb.c
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "speex/speex_callbacks.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
extern long long spx_mips;
|
||||
#endif
|
||||
|
||||
#define FRAME_SIZE 320
|
||||
#include <math.h>
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *inFile, *outFile, *bitsFile;
|
||||
FILE *fin, *fout, *fbits=NULL;
|
||||
short in_short[FRAME_SIZE];
|
||||
short out_short[FRAME_SIZE];
|
||||
float sigpow,errpow,snr, seg_snr=0;
|
||||
int snr_frames = 0;
|
||||
char cbits[200];
|
||||
int nbBits;
|
||||
int i;
|
||||
void *st;
|
||||
void *dec;
|
||||
SpeexBits bits;
|
||||
spx_int32_t tmp;
|
||||
int bitCount=0;
|
||||
spx_int32_t skip_group_delay;
|
||||
SpeexCallback callback;
|
||||
|
||||
sigpow = 0;
|
||||
errpow = 0;
|
||||
|
||||
st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));
|
||||
dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));
|
||||
|
||||
callback.callback_id = SPEEX_INBAND_CHAR;
|
||||
callback.func = speex_std_char_handler;
|
||||
callback.data = stderr;
|
||||
speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
|
||||
|
||||
callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
|
||||
callback.func = speex_std_mode_request_handler;
|
||||
callback.data = st;
|
||||
speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
|
||||
|
||||
tmp=1;
|
||||
speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
|
||||
tmp=0;
|
||||
speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
|
||||
tmp=8;
|
||||
speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
|
||||
tmp=3;
|
||||
speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
|
||||
/*tmp=3;
|
||||
speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp);
|
||||
tmp=6;
|
||||
speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp);
|
||||
*/
|
||||
|
||||
speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay);
|
||||
speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp);
|
||||
skip_group_delay += tmp;
|
||||
|
||||
|
||||
if (argc != 4 && argc != 3)
|
||||
{
|
||||
fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
|
||||
exit(1);
|
||||
}
|
||||
inFile = argv[1];
|
||||
fin = fopen(inFile, "rb");
|
||||
outFile = argv[2];
|
||||
fout = fopen(outFile, "wb+");
|
||||
if (argc==4)
|
||||
{
|
||||
bitsFile = argv[3];
|
||||
fbits = fopen(bitsFile, "wb");
|
||||
}
|
||||
speex_bits_init(&bits);
|
||||
while (!feof(fin))
|
||||
{
|
||||
fread(in_short, sizeof(short), FRAME_SIZE, fin);
|
||||
if (feof(fin))
|
||||
break;
|
||||
speex_bits_reset(&bits);
|
||||
|
||||
speex_encode_int(st, in_short, &bits);
|
||||
nbBits = speex_bits_write(&bits, cbits, 200);
|
||||
bitCount+=bits.nbBits;
|
||||
|
||||
if (argc==4)
|
||||
fwrite(cbits, 1, nbBits, fbits);
|
||||
speex_bits_rewind(&bits);
|
||||
|
||||
speex_decode_int(dec, &bits, out_short);
|
||||
speex_bits_reset(&bits);
|
||||
|
||||
fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
|
||||
skip_group_delay = 0;
|
||||
}
|
||||
fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
|
||||
speex_encoder_destroy(st);
|
||||
speex_decoder_destroy(dec);
|
||||
speex_bits_destroy(&bits);
|
||||
|
||||
rewind(fin);
|
||||
rewind(fout);
|
||||
|
||||
while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin)
|
||||
&&
|
||||
FRAME_SIZE == fread(out_short, sizeof(short), FRAME_SIZE,fout) )
|
||||
{
|
||||
float s=0, e=0;
|
||||
for (i=0;i<FRAME_SIZE;++i) {
|
||||
s += (float)in_short[i] * in_short[i];
|
||||
e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
|
||||
}
|
||||
seg_snr += 10*log10((s+160)/(e+160));
|
||||
sigpow += s;
|
||||
errpow += e;
|
||||
snr_frames++;
|
||||
}
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
snr = 10 * log10( sigpow / errpow );
|
||||
seg_snr /= snr_frames;
|
||||
fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
114
external/speex/src/vbr.c
vendored
114
external/speex/src/vbr.c
vendored
@ -32,55 +32,59 @@
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "vbr.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#define sqr(x) ((x)*(x))
|
||||
|
||||
#define MIN_ENERGY 6000.0f
|
||||
#define NOISE_POW .3f
|
||||
#define MIN_ENERGY 6000
|
||||
#define NOISE_POW .3
|
||||
|
||||
#ifndef DISABLE_VBR
|
||||
|
||||
float vbr_nb_thresh[9][11]={
|
||||
{-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* CNG */
|
||||
{ 3.5, 2.5, 2.0, 1.2, 0.5, 0.0, -0.5, -0.7, -0.8, -0.9, -1.0}, /* 2 kbps */
|
||||
{10.0, 6.5, 5.2, 4.5, 3.9, 3.5, 3.0, 2.5, 2.3, 1.8, 1.0}, /* 6 kbps */
|
||||
{11.0, 8.8, 7.5, 6.5, 5.0, 3.9, 3.9, 3.9, 3.5, 3.0, 1.0}, /* 8 kbps */
|
||||
{11.0, 11.0, 9.9, 9.0, 8.0, 7.0, 6.5, 6.0, 5.0, 4.0, 2.0}, /* 11 kbps */
|
||||
{11.0, 11.0, 11.0, 11.0, 9.5, 9.0, 8.0, 7.0, 6.5, 5.0, 3.0}, /* 15 kbps */
|
||||
{11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.5, 8.0, 6.5, 4.0}, /* 18 kbps */
|
||||
{11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5}, /* 24 kbps */
|
||||
{ 8.0, 5.0, 3.7, 3.0, 2.5, 2.0, 1.8, 1.5, 1.0, 0.0, 0.0} /* 4 kbps */
|
||||
const float vbr_nb_thresh[9][11]={
|
||||
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* CNG */
|
||||
{ 4.0f, 2.5f, 2.0f, 1.2f, 0.5f,-0.25f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /* 2 kbps */
|
||||
{10.0f, 6.5f, 5.2f, 4.5f, 3.9f, 3.7f, 3.0f, 2.5f, 2.3f, 1.8f, 1.0f}, /* 6 kbps */
|
||||
{11.0f, 8.8f, 7.5f, 6.5f, 5.0f, 4.2f, 3.9f, 3.9f, 3.5f, 3.0f, 1.0f}, /* 8 kbps */
|
||||
{11.0f, 11.0f, 9.9f, 8.5f, 7.0f, 5.25f, 4.5f, 4.0f, 4.0f, 4.0f, 2.0f}, /* 11 kbps */
|
||||
{11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 9.25f, 8.0f, 7.0f, 5.0f, 4.0f, 3.0f}, /* 15 kbps */
|
||||
{11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 6.2f, 5.2f, 5.0f}, /* 18 kbps */
|
||||
{11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 10.0f, 9.8f, 7.5f}, /* 24 kbps */
|
||||
{ 7.0f, 4.5f, 3.7f, 3.0f, 2.5f, 1.0f, 1.8f, 1.5f, 1.0f, 0.0f, 0.0f} /* 4 kbps */
|
||||
};
|
||||
|
||||
|
||||
float vbr_hb_thresh[5][11]={
|
||||
{-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */
|
||||
{-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* 2 kbps */
|
||||
{11.0, 11.0, 9.5, 8.5, 7.5, 6.0, 5.0, 3.9, 3.0, 2.0, 1.0}, /* 6 kbps */
|
||||
{11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.7, 7.8, 7.0, 6.5, 4.0}, /* 10 kbps */
|
||||
{11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5} /* 18 kbps */
|
||||
const float vbr_hb_thresh[5][11]={
|
||||
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */
|
||||
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* 2 kbps */
|
||||
{11.0f, 11.0f, 9.5f, 8.5f, 7.5f, 6.0f, 5.0f, 3.9f, 3.0f, 2.0f, 1.0f}, /* 6 kbps */
|
||||
{11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.7f, 7.8f, 7.0f, 6.5f, 4.0f}, /* 10 kbps */
|
||||
{11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 7.5f, 5.5f} /* 18 kbps */
|
||||
};
|
||||
|
||||
float vbr_uhb_thresh[2][11]={
|
||||
{-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */
|
||||
{ 3.9, 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0} /* 2 kbps */
|
||||
const float vbr_uhb_thresh[2][11]={
|
||||
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */
|
||||
{ 3.9f, 2.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f} /* 2 kbps */
|
||||
};
|
||||
|
||||
void vbr_init(VBRState *vbr)
|
||||
{
|
||||
int i;
|
||||
|
||||
vbr->average_energy=0;
|
||||
vbr->average_energy=1600000;
|
||||
vbr->last_energy=1;
|
||||
vbr->accum_sum=0;
|
||||
vbr->energy_alpha=.1;
|
||||
vbr->soft_pitch=0;
|
||||
vbr->last_pitch_coef=0;
|
||||
vbr->last_quality=0;
|
||||
|
||||
vbr->noise_accum = .05f*pow(MIN_ENERGY, NOISE_POW);
|
||||
vbr->noise_accum = .05*pow(MIN_ENERGY, NOISE_POW);
|
||||
vbr->noise_accum_count=.05;
|
||||
vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count;
|
||||
vbr->consec_noise=0;
|
||||
@ -116,22 +120,21 @@ void vbr_init(VBRState *vbr)
|
||||
|
||||
*/
|
||||
|
||||
float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_coef)
|
||||
float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef)
|
||||
{
|
||||
int i;
|
||||
float ener=0, ener1=0, ener2=0;
|
||||
float qual=7;
|
||||
int va;
|
||||
float log_energy;
|
||||
float non_st=0;
|
||||
float voicing;
|
||||
float pow_ener;
|
||||
|
||||
for (i=0;i<len>>1;i++)
|
||||
ener1 += sig[i]*sig[i];
|
||||
ener1 += ((float)sig[i])*sig[i];
|
||||
|
||||
for (i=len>>1;i<len;i++)
|
||||
ener2 += sig[i]*sig[i];
|
||||
ener2 += ((float)sig[i])*sig[i];
|
||||
ener=ener1+ener2;
|
||||
|
||||
log_energy = log(ener+MIN_ENERGY);
|
||||
@ -141,12 +144,12 @@ float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_co
|
||||
if (non_st>1)
|
||||
non_st=1;
|
||||
|
||||
voicing = 3*(pitch_coef-.4f)*fabs(pitch_coef-.4f);
|
||||
vbr->average_energy = (1-vbr->energy_alpha)*vbr->average_energy + vbr->energy_alpha*ener;
|
||||
voicing = 3*(pitch_coef-.4)*fabs(pitch_coef-.4);
|
||||
vbr->average_energy = 0.9*vbr->average_energy + .1*ener;
|
||||
vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count;
|
||||
pow_ener = pow(ener,NOISE_POW);
|
||||
if (vbr->noise_accum_count<.06 && ener>MIN_ENERGY)
|
||||
vbr->noise_accum = .05f*pow_ener;
|
||||
vbr->noise_accum = .05*pow_ener;
|
||||
|
||||
if ((voicing<.3 && non_st < .2 && pow_ener < 1.2*vbr->noise_level)
|
||||
|| (voicing<.3 && non_st < .05 && pow_ener < 1.5*vbr->noise_level)
|
||||
@ -154,7 +157,7 @@ float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_co
|
||||
|| (voicing<0 && non_st < .05))
|
||||
{
|
||||
float tmp;
|
||||
va = 0;
|
||||
|
||||
vbr->consec_noise++;
|
||||
if (pow_ener > 3*vbr->noise_level)
|
||||
tmp = 3*vbr->noise_level;
|
||||
@ -162,28 +165,27 @@ float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_co
|
||||
tmp = pow_ener;
|
||||
if (vbr->consec_noise>=4)
|
||||
{
|
||||
vbr->noise_accum = .95f*vbr->noise_accum + .05f*tmp;
|
||||
vbr->noise_accum_count = .95f*vbr->noise_accum_count + .05f;
|
||||
vbr->noise_accum = .95*vbr->noise_accum + .05*tmp;
|
||||
vbr->noise_accum_count = .95*vbr->noise_accum_count + .05;
|
||||
}
|
||||
} else {
|
||||
va = 1;
|
||||
vbr->consec_noise=0;
|
||||
}
|
||||
|
||||
if (pow_ener < vbr->noise_level && ener>MIN_ENERGY)
|
||||
{
|
||||
vbr->noise_accum = .95f*vbr->noise_accum + .05f*pow_ener;
|
||||
vbr->noise_accum_count = .95f*vbr->noise_accum_count + .05f;
|
||||
vbr->noise_accum = .95*vbr->noise_accum + .05*pow_ener;
|
||||
vbr->noise_accum_count = .95*vbr->noise_accum_count + .05;
|
||||
}
|
||||
|
||||
/* Checking for very low absolute energy */
|
||||
if (ener < 30000)
|
||||
{
|
||||
qual -= .7f;
|
||||
qual -= .7;
|
||||
if (ener < 10000)
|
||||
qual-=.7f;
|
||||
qual-=.7;
|
||||
if (ener < 3000)
|
||||
qual-=.7f;
|
||||
qual-=.7;
|
||||
} else {
|
||||
float short_diff, long_diff;
|
||||
short_diff = log((ener+1)/(1+vbr->last_energy));
|
||||
@ -196,25 +198,25 @@ float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_co
|
||||
long_diff=2;
|
||||
|
||||
if (long_diff>0)
|
||||
qual += .6f*long_diff;
|
||||
qual += .6*long_diff;
|
||||
if (long_diff<0)
|
||||
qual += .5f*long_diff;
|
||||
qual += .5*long_diff;
|
||||
if (short_diff>0)
|
||||
{
|
||||
if (short_diff>5)
|
||||
short_diff=5;
|
||||
qual += .5f*short_diff;
|
||||
qual += 1*short_diff;
|
||||
}
|
||||
/* Checking for energy increases */
|
||||
if (ener2 > 1.6f*ener1)
|
||||
qual += .5f;
|
||||
if (ener2 > 1.6*ener1)
|
||||
qual += .5;
|
||||
}
|
||||
vbr->last_energy = ener;
|
||||
vbr->soft_pitch = .6f*vbr->soft_pitch + .4f*pitch_coef;
|
||||
qual += 2.2f*((pitch_coef-.4f) + (vbr->soft_pitch-.4f));
|
||||
vbr->soft_pitch = .8*vbr->soft_pitch + .2*pitch_coef;
|
||||
qual += 2.2*((pitch_coef-.4) + (vbr->soft_pitch-.4));
|
||||
|
||||
if (qual < vbr->last_quality)
|
||||
qual = .5f*qual + .5f*vbr->last_quality;
|
||||
qual = .5*qual + .5*vbr->last_quality;
|
||||
if (qual<4)
|
||||
qual=4;
|
||||
if (qual>10)
|
||||
@ -232,24 +234,24 @@ float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_co
|
||||
qual=4;
|
||||
|
||||
if (vbr->consec_noise)
|
||||
qual -= 1.0 * (log(3.0 + vbr->consec_noise)-log(3.0f));
|
||||
qual -= 1.0 * (log(3.0 + vbr->consec_noise)-log(3));
|
||||
if (qual<0)
|
||||
qual=0;
|
||||
|
||||
if (ener<60000)
|
||||
if (ener<1600000)
|
||||
{
|
||||
if (vbr->consec_noise>2)
|
||||
qual-=0.5f*(log(3.0 + vbr->consec_noise)-log(3.0f));
|
||||
qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3));
|
||||
if (ener<10000&&vbr->consec_noise>2)
|
||||
qual-=0.5f*(log(3.0 + vbr->consec_noise)-log(3.0f));
|
||||
qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3));
|
||||
if (qual<0)
|
||||
qual=0;
|
||||
qual += .3f*log(ener/60000.0);
|
||||
qual += .3*log(.0001+ener/1600000.0);
|
||||
}
|
||||
if (qual<-1)
|
||||
qual=-1;
|
||||
|
||||
/*printf ("%f %f %f %f %d\n", qual, voicing, non_st, pow_ener/(.01+vbr->noise_level), va);*/
|
||||
/*printf ("%f %f %f %f\n", qual, voicing, non_st, pow_ener/(.01+vbr->noise_level));*/
|
||||
|
||||
vbr->last_pitch_coef = pitch_coef;
|
||||
vbr->last_quality = qual;
|
||||
@ -258,7 +260,7 @@ float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_co
|
||||
vbr->last_log_energy[i] = vbr->last_log_energy[i-1];
|
||||
vbr->last_log_energy[0] = log_energy;
|
||||
|
||||
/*printf ("VBR: %f %f %f %d %f\n", (float)(log_energy-log(vbr->average_energy+MIN_ENERGY)), non_st, voicing, va, vbr->noise_level);*/
|
||||
/*printf ("VBR: %f %f %f %f\n", (float)(log_energy-log(vbr->average_energy+MIN_ENERGY)), non_st, voicing, vbr->noise_level);*/
|
||||
|
||||
return qual;
|
||||
}
|
||||
@ -266,3 +268,5 @@ float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_co
|
||||
void vbr_destroy(VBRState *vbr)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
23
external/speex/src/vbr.h
vendored
23
external/speex/src/vbr.h
vendored
@ -1,8 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: vbr.h
|
||||
|
||||
VBR-related routines
|
||||
|
||||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file vbr.h
|
||||
@brief Variable Bit-Rate (VBR) related routines
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
@ -36,14 +37,16 @@
|
||||
#ifndef VBR_H
|
||||
#define VBR_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
#define VBR_MEMORY_SIZE 5
|
||||
|
||||
extern float vbr_nb_thresh[9][11];
|
||||
extern float vbr_hb_thresh[5][11];
|
||||
extern float vbr_uhb_thresh[2][11];
|
||||
extern const float vbr_nb_thresh[9][11];
|
||||
extern const float vbr_hb_thresh[5][11];
|
||||
extern const float vbr_uhb_thresh[2][11];
|
||||
|
||||
/** VBR state. */
|
||||
typedef struct VBRState {
|
||||
float energy_alpha;
|
||||
float average_energy;
|
||||
float last_energy;
|
||||
float last_log_energy[VBR_MEMORY_SIZE];
|
||||
@ -59,7 +62,7 @@ typedef struct VBRState {
|
||||
|
||||
void vbr_init(VBRState *vbr);
|
||||
|
||||
float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_coef);
|
||||
float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef);
|
||||
|
||||
void vbr_destroy(VBRState *vbr);
|
||||
|
||||
|
513
external/speex/src/vorbis_psy.c
vendored
Normal file
513
external/speex/src/vorbis_psy.c
vendored
Normal file
@ -0,0 +1,513 @@
|
||||
/* Copyright (C) 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery
|
||||
File: vorbis_psy.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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef VORBIS_PSYCHO
|
||||
|
||||
#include "arch.h"
|
||||
#include "smallft.h"
|
||||
#include "lpc.h"
|
||||
#include "vorbis_psy.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* psychoacoustic setup ********************************************/
|
||||
|
||||
static VorbisPsyInfo example_tuning = {
|
||||
|
||||
.5,.5,
|
||||
3,3,25,
|
||||
|
||||
/*63 125 250 500 1k 2k 4k 8k 16k*/
|
||||
// vorbis mode 4 style
|
||||
//{-32,-32,-32,-32,-28,-24,-22,-20,-20, -20, -20, -8, -6, -6, -6, -6, -6},
|
||||
{ -4, -6, -6, -6, -6, -6, -6, -6, -8, -8,-10,-10, -8, -6, -4, -4, -2},
|
||||
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 5, 5, /* 7dB */
|
||||
6, 6, 6, 5, 4, 4, 4, 4, /* 15dB */
|
||||
4, 4, 5, 5, 5, 6, 6, 6, /* 23dB */
|
||||
7, 7, 7, 8, 8, 8, 9, 10, /* 31dB */
|
||||
11,12,13,14,15,16,17, 18, /* 39dB */
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* there was no great place to put this.... */
|
||||
#include <stdio.h>
|
||||
static void _analysis_output(char *base,int i,float *v,int n,int bark,int dB){
|
||||
int j;
|
||||
FILE *of;
|
||||
char buffer[80];
|
||||
|
||||
sprintf(buffer,"%s_%d.m",base,i);
|
||||
of=fopen(buffer,"w");
|
||||
|
||||
if(!of)perror("failed to open data dump file");
|
||||
|
||||
for(j=0;j<n;j++){
|
||||
if(bark){
|
||||
float b=toBARK((4000.f*j/n)+.25);
|
||||
fprintf(of,"%f ",b);
|
||||
}else
|
||||
fprintf(of,"%f ",(double)j);
|
||||
|
||||
if(dB){
|
||||
float val;
|
||||
if(v[j]==0.)
|
||||
val=-140.;
|
||||
else
|
||||
val=todB(v[j]);
|
||||
fprintf(of,"%f\n",val);
|
||||
}else{
|
||||
fprintf(of,"%f\n",v[j]);
|
||||
}
|
||||
}
|
||||
fclose(of);
|
||||
}
|
||||
|
||||
static void bark_noise_hybridmp(int n,const long *b,
|
||||
const float *f,
|
||||
float *noise,
|
||||
const float offset,
|
||||
const int fixed){
|
||||
|
||||
float *N=alloca(n*sizeof(*N));
|
||||
float *X=alloca(n*sizeof(*N));
|
||||
float *XX=alloca(n*sizeof(*N));
|
||||
float *Y=alloca(n*sizeof(*N));
|
||||
float *XY=alloca(n*sizeof(*N));
|
||||
|
||||
float tN, tX, tXX, tY, tXY;
|
||||
int i;
|
||||
|
||||
int lo, hi;
|
||||
float R, A, B, D;
|
||||
float w, x, y;
|
||||
|
||||
tN = tX = tXX = tY = tXY = 0.f;
|
||||
|
||||
y = f[0] + offset;
|
||||
if (y < 1.f) y = 1.f;
|
||||
|
||||
w = y * y * .5;
|
||||
|
||||
tN += w;
|
||||
tX += w;
|
||||
tY += w * y;
|
||||
|
||||
N[0] = tN;
|
||||
X[0] = tX;
|
||||
XX[0] = tXX;
|
||||
Y[0] = tY;
|
||||
XY[0] = tXY;
|
||||
|
||||
for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
|
||||
|
||||
y = f[i] + offset;
|
||||
if (y < 1.f) y = 1.f;
|
||||
|
||||
w = y * y;
|
||||
|
||||
tN += w;
|
||||
tX += w * x;
|
||||
tXX += w * x * x;
|
||||
tY += w * y;
|
||||
tXY += w * x * y;
|
||||
|
||||
N[i] = tN;
|
||||
X[i] = tX;
|
||||
XX[i] = tXX;
|
||||
Y[i] = tY;
|
||||
XY[i] = tXY;
|
||||
}
|
||||
|
||||
for (i = 0, x = 0.f;; i++, x += 1.f) {
|
||||
|
||||
lo = b[i] >> 16;
|
||||
if( lo>=0 ) break;
|
||||
hi = b[i] & 0xffff;
|
||||
|
||||
tN = N[hi] + N[-lo];
|
||||
tX = X[hi] - X[-lo];
|
||||
tXX = XX[hi] + XX[-lo];
|
||||
tY = Y[hi] + Y[-lo];
|
||||
tXY = XY[hi] - XY[-lo];
|
||||
|
||||
A = tY * tXX - tX * tXY;
|
||||
B = tN * tXY - tX * tY;
|
||||
D = tN * tXX - tX * tX;
|
||||
R = (A + x * B) / D;
|
||||
if (R < 0.f)
|
||||
R = 0.f;
|
||||
|
||||
noise[i] = R - offset;
|
||||
}
|
||||
|
||||
for ( ;; i++, x += 1.f) {
|
||||
|
||||
lo = b[i] >> 16;
|
||||
hi = b[i] & 0xffff;
|
||||
if(hi>=n)break;
|
||||
|
||||
tN = N[hi] - N[lo];
|
||||
tX = X[hi] - X[lo];
|
||||
tXX = XX[hi] - XX[lo];
|
||||
tY = Y[hi] - Y[lo];
|
||||
tXY = XY[hi] - XY[lo];
|
||||
|
||||
A = tY * tXX - tX * tXY;
|
||||
B = tN * tXY - tX * tY;
|
||||
D = tN * tXX - tX * tX;
|
||||
R = (A + x * B) / D;
|
||||
if (R < 0.f) R = 0.f;
|
||||
|
||||
noise[i] = R - offset;
|
||||
}
|
||||
for ( ; i < n; i++, x += 1.f) {
|
||||
|
||||
R = (A + x * B) / D;
|
||||
if (R < 0.f) R = 0.f;
|
||||
|
||||
noise[i] = R - offset;
|
||||
}
|
||||
|
||||
if (fixed <= 0) return;
|
||||
|
||||
for (i = 0, x = 0.f;; i++, x += 1.f) {
|
||||
hi = i + fixed / 2;
|
||||
lo = hi - fixed;
|
||||
if(lo>=0)break;
|
||||
|
||||
tN = N[hi] + N[-lo];
|
||||
tX = X[hi] - X[-lo];
|
||||
tXX = XX[hi] + XX[-lo];
|
||||
tY = Y[hi] + Y[-lo];
|
||||
tXY = XY[hi] - XY[-lo];
|
||||
|
||||
|
||||
A = tY * tXX - tX * tXY;
|
||||
B = tN * tXY - tX * tY;
|
||||
D = tN * tXX - tX * tX;
|
||||
R = (A + x * B) / D;
|
||||
|
||||
if (R - offset < noise[i]) noise[i] = R - offset;
|
||||
}
|
||||
for ( ;; i++, x += 1.f) {
|
||||
|
||||
hi = i + fixed / 2;
|
||||
lo = hi - fixed;
|
||||
if(hi>=n)break;
|
||||
|
||||
tN = N[hi] - N[lo];
|
||||
tX = X[hi] - X[lo];
|
||||
tXX = XX[hi] - XX[lo];
|
||||
tY = Y[hi] - Y[lo];
|
||||
tXY = XY[hi] - XY[lo];
|
||||
|
||||
A = tY * tXX - tX * tXY;
|
||||
B = tN * tXY - tX * tY;
|
||||
D = tN * tXX - tX * tX;
|
||||
R = (A + x * B) / D;
|
||||
|
||||
if (R - offset < noise[i]) noise[i] = R - offset;
|
||||
}
|
||||
for ( ; i < n; i++, x += 1.f) {
|
||||
R = (A + x * B) / D;
|
||||
if (R - offset < noise[i]) noise[i] = R - offset;
|
||||
}
|
||||
}
|
||||
|
||||
static void _vp_noisemask(VorbisPsy *p,
|
||||
float *logfreq,
|
||||
float *logmask){
|
||||
|
||||
int i,n=p->n/2;
|
||||
float *work=alloca(n*sizeof(*work));
|
||||
|
||||
bark_noise_hybridmp(n,p->bark,logfreq,logmask,
|
||||
140.,-1);
|
||||
|
||||
for(i=0;i<n;i++)work[i]=logfreq[i]-logmask[i];
|
||||
|
||||
bark_noise_hybridmp(n,p->bark,work,logmask,0.,
|
||||
p->vi->noisewindowfixed);
|
||||
|
||||
for(i=0;i<n;i++)work[i]=logfreq[i]-work[i];
|
||||
|
||||
{
|
||||
static int seq=0;
|
||||
|
||||
float work2[n];
|
||||
for(i=0;i<n;i++){
|
||||
work2[i]=logmask[i]+work[i];
|
||||
}
|
||||
|
||||
//_analysis_output("logfreq",seq,logfreq,n,0,0);
|
||||
//_analysis_output("median",seq,work,n,0,0);
|
||||
//_analysis_output("envelope",seq,work2,n,0,0);
|
||||
seq++;
|
||||
}
|
||||
|
||||
for(i=0;i<n;i++){
|
||||
int dB=logmask[i]+.5;
|
||||
if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;
|
||||
if(dB<0)dB=0;
|
||||
logmask[i]= work[i]+p->vi->noisecompand[dB]+p->noiseoffset[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VorbisPsy *vorbis_psy_init(int rate, int n)
|
||||
{
|
||||
long i,j,lo=-99,hi=1;
|
||||
VorbisPsy *p = speex_alloc(sizeof(VorbisPsy));
|
||||
memset(p,0,sizeof(*p));
|
||||
|
||||
p->n = n;
|
||||
spx_drft_init(&p->lookup, n);
|
||||
p->bark = speex_alloc(n*sizeof(*p->bark));
|
||||
p->rate=rate;
|
||||
p->vi = &example_tuning;
|
||||
|
||||
/* BH4 window */
|
||||
p->window = speex_alloc(sizeof(*p->window)*n);
|
||||
float a0 = .35875f;
|
||||
float a1 = .48829f;
|
||||
float a2 = .14128f;
|
||||
float a3 = .01168f;
|
||||
for(i=0;i<n;i++)
|
||||
p->window[i] = //a0 - a1*cos(2.*M_PI/n*(i+.5)) + a2*cos(4.*M_PI/n*(i+.5)) - a3*cos(6.*M_PI/n*(i+.5));
|
||||
sin((i+.5)/n * M_PI)*sin((i+.5)/n * M_PI);
|
||||
/* bark scale lookups */
|
||||
for(i=0;i<n;i++){
|
||||
float bark=toBARK(rate/(2*n)*i);
|
||||
|
||||
for(;lo+p->vi->noisewindowlomin<i &&
|
||||
toBARK(rate/(2*n)*lo)<(bark-p->vi->noisewindowlo);lo++);
|
||||
|
||||
for(;hi<=n && (hi<i+p->vi->noisewindowhimin ||
|
||||
toBARK(rate/(2*n)*hi)<(bark+p->vi->noisewindowhi));hi++);
|
||||
|
||||
p->bark[i]=((lo-1)<<16)+(hi-1);
|
||||
|
||||
}
|
||||
|
||||
/* set up rolling noise median */
|
||||
p->noiseoffset=speex_alloc(n*sizeof(*p->noiseoffset));
|
||||
|
||||
for(i=0;i<n;i++){
|
||||
float halfoc=toOC((i+.5)*rate/(2.*n))*2.;
|
||||
int inthalfoc;
|
||||
float del;
|
||||
|
||||
if(halfoc<0)halfoc=0;
|
||||
if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
|
||||
inthalfoc=(int)halfoc;
|
||||
/*If we hit the P_BANDS-1 clamp above, inthalfoc+1 will be out of bounds,
|
||||
even though it will have an interpolation weight of 0.
|
||||
Shift the interval so we don't read past the end of the array.*/
|
||||
if(inthalfoc>=P_BANDS-2)inthalfoc=P_BANDS-2;
|
||||
del=halfoc-inthalfoc;
|
||||
|
||||
p->noiseoffset[i]=
|
||||
p->vi->noiseoff[inthalfoc]*(1.-del) +
|
||||
p->vi->noiseoff[inthalfoc+1]*del;
|
||||
|
||||
}
|
||||
#if 0
|
||||
_analysis_output_always("noiseoff0",ls,p->noiseoffset,n,1,0,0);
|
||||
#endif
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void vorbis_psy_destroy(VorbisPsy *p)
|
||||
{
|
||||
if(p){
|
||||
spx_drft_clear(&p->lookup);
|
||||
if(p->bark)
|
||||
speex_free(p->bark);
|
||||
if(p->noiseoffset)
|
||||
speex_free(p->noiseoffset);
|
||||
if(p->window)
|
||||
speex_free(p->window);
|
||||
memset(p,0,sizeof(*p));
|
||||
speex_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
void compute_curve(VorbisPsy *psy, float *audio, float *curve)
|
||||
{
|
||||
int i;
|
||||
float work[psy->n];
|
||||
|
||||
float scale=4.f/psy->n;
|
||||
float scale_dB;
|
||||
|
||||
scale_dB=todB(scale);
|
||||
|
||||
/* window the PCM data; use a BH4 window, not vorbis */
|
||||
for(i=0;i<psy->n;i++)
|
||||
work[i]=audio[i] * psy->window[i];
|
||||
|
||||
{
|
||||
static int seq=0;
|
||||
|
||||
//_analysis_output("win",seq,work,psy->n,0,0);
|
||||
|
||||
seq++;
|
||||
}
|
||||
|
||||
/* FFT yields more accurate tonal estimation (not phase sensitive) */
|
||||
spx_drft_forward(&psy->lookup,work);
|
||||
|
||||
/* magnitudes */
|
||||
work[0]=scale_dB+todB(work[0]);
|
||||
for(i=1;i<psy->n-1;i+=2){
|
||||
float temp = work[i]*work[i] + work[i+1]*work[i+1];
|
||||
work[(i+1)>>1] = scale_dB+.5f * todB(temp);
|
||||
}
|
||||
|
||||
/* derive a noise curve */
|
||||
_vp_noisemask(psy,work,curve);
|
||||
#define SIDEL 12
|
||||
for (i=0;i<SIDEL;i++)
|
||||
{
|
||||
curve[i]=curve[SIDEL];
|
||||
}
|
||||
#define SIDEH 12
|
||||
for (i=0;i<SIDEH;i++)
|
||||
{
|
||||
curve[(psy->n>>1)-i-1]=curve[(psy->n>>1)-SIDEH];
|
||||
}
|
||||
for(i=0;i<((psy->n)>>1);i++)
|
||||
curve[i] = fromdB(1.2*curve[i]+.2*i);
|
||||
//curve[i] = fromdB(0.8*curve[i]+.35*i);
|
||||
//curve[i] = fromdB(0.9*curve[i])*pow(1.0*i+45,1.3);
|
||||
}
|
||||
|
||||
/* Transform a masking curve (power spectrum) into a pole-zero filter */
|
||||
void curve_to_lpc(VorbisPsy *psy, float *curve, float *awk1, float *awk2, int ord)
|
||||
{
|
||||
int i;
|
||||
float ac[psy->n];
|
||||
float tmp;
|
||||
int len = psy->n >> 1;
|
||||
for (i=0;i<2*len;i++)
|
||||
ac[i] = 0;
|
||||
for (i=1;i<len;i++)
|
||||
ac[2*i-1] = curve[i];
|
||||
ac[0] = curve[0];
|
||||
ac[2*len-1] = curve[len-1];
|
||||
|
||||
spx_drft_backward(&psy->lookup, ac);
|
||||
_spx_lpc(awk1, ac, ord);
|
||||
tmp = 1.;
|
||||
for (i=0;i<ord;i++)
|
||||
{
|
||||
tmp *= .99;
|
||||
awk1[i] *= tmp;
|
||||
}
|
||||
#if 0
|
||||
for (i=0;i<ord;i++)
|
||||
awk2[i] = 0;
|
||||
#else
|
||||
/* Use the second (awk2) filter to correct the first one */
|
||||
for (i=0;i<2*len;i++)
|
||||
ac[i] = 0;
|
||||
for (i=0;i<ord;i++)
|
||||
ac[i+1] = awk1[i];
|
||||
ac[0] = 1;
|
||||
spx_drft_forward(&psy->lookup, ac);
|
||||
/* Compute (power) response of awk1 (all zero) */
|
||||
ac[0] *= ac[0];
|
||||
for (i=1;i<len;i++)
|
||||
ac[i] = ac[2*i-1]*ac[2*i-1] + ac[2*i]*ac[2*i];
|
||||
ac[len] = ac[2*len-1]*ac[2*len-1];
|
||||
/* Compute correction required */
|
||||
for (i=0;i<len;i++)
|
||||
curve[i] = 1. / (1e-6f+curve[i]*ac[i]);
|
||||
|
||||
for (i=0;i<2*len;i++)
|
||||
ac[i] = 0;
|
||||
for (i=1;i<len;i++)
|
||||
ac[2*i-1] = curve[i];
|
||||
ac[0] = curve[0];
|
||||
ac[2*len-1] = curve[len-1];
|
||||
|
||||
spx_drft_backward(&psy->lookup, ac);
|
||||
_spx_lpc(awk2, ac, ord);
|
||||
tmp = 1;
|
||||
for (i=0;i<ord;i++)
|
||||
{
|
||||
tmp *= .99;
|
||||
awk2[i] *= tmp;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define ORDER 10
|
||||
#define CURVE_SIZE 24
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
float curve[CURVE_SIZE];
|
||||
float awk1[ORDER], awk2[ORDER];
|
||||
for (i=0;i<CURVE_SIZE;i++)
|
||||
scanf("%f ", &curve[i]);
|
||||
for (i=0;i<CURVE_SIZE;i++)
|
||||
curve[i] = pow(10.f, .1*curve[i]);
|
||||
curve_to_lpc(curve, CURVE_SIZE, awk1, awk2, ORDER);
|
||||
for (i=0;i<ORDER;i++)
|
||||
printf("%f ", awk1[i]);
|
||||
printf ("\n");
|
||||
for (i=0;i<ORDER;i++)
|
||||
printf("%f ", awk2[i]);
|
||||
printf ("\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
97
external/speex/src/vorbis_psy.h
vendored
Normal file
97
external/speex/src/vorbis_psy.h
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
/* Copyright (C) 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery
|
||||
File: vorbis_psy.h
|
||||
|
||||
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 VORBIS_PSY_H
|
||||
#define VORBIS_PSY_H
|
||||
|
||||
#ifdef VORBIS_PSYCHO
|
||||
|
||||
#include "smallft.h"
|
||||
#define P_BANDS 17 /* 62Hz to 16kHz */
|
||||
#define NOISE_COMPAND_LEVELS 40
|
||||
|
||||
|
||||
#define todB(x) ((x)>1e-13?log((x)*(x))*4.34294480f:-30)
|
||||
#define fromdB(x) (exp((x)*.11512925f))
|
||||
|
||||
/* The bark scale equations are approximations, since the original
|
||||
table was somewhat hand rolled. The below are chosen to have the
|
||||
best possible fit to the rolled tables, thus their somewhat odd
|
||||
appearance (these are more accurate and over a longer range than
|
||||
the oft-quoted bark equations found in the texts I have). The
|
||||
approximations are valid from 0 - 30kHz (nyquist) or so.
|
||||
|
||||
all f in Hz, z in Bark */
|
||||
|
||||
#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
|
||||
#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f)
|
||||
|
||||
/* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave
|
||||
0.0 */
|
||||
|
||||
#define toOC(n) (log(n)*1.442695f-5.965784f)
|
||||
#define fromOC(o) (exp(((o)+5.965784f)*.693147f))
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
float noisewindowlo;
|
||||
float noisewindowhi;
|
||||
int noisewindowlomin;
|
||||
int noisewindowhimin;
|
||||
int noisewindowfixed;
|
||||
float noiseoff[P_BANDS];
|
||||
float noisecompand[NOISE_COMPAND_LEVELS];
|
||||
|
||||
} VorbisPsyInfo;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
int n;
|
||||
int rate;
|
||||
struct drft_lookup lookup;
|
||||
VorbisPsyInfo *vi;
|
||||
|
||||
float *window;
|
||||
float *noiseoffset;
|
||||
long *bark;
|
||||
|
||||
} VorbisPsy;
|
||||
|
||||
|
||||
VorbisPsy *vorbis_psy_init(int rate, int size);
|
||||
void vorbis_psy_destroy(VorbisPsy *psy);
|
||||
void compute_curve(VorbisPsy *psy, float *audio, float *curve);
|
||||
void curve_to_lpc(VorbisPsy *psy, float *curve, float *awk1, float *awk2, int ord);
|
||||
|
||||
#endif
|
||||
#endif
|
87
external/speex/src/vq.c
vendored
87
external/speex/src/vq.c
vendored
@ -30,42 +30,63 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "vq.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/*Finds the index of the entry in a codebook that best matches the input*/
|
||||
int vq_index(float *in, float *codebook, int len, int entries)
|
||||
#include "vq.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#include <xmmintrin.h>
|
||||
#include "vq_sse.h"
|
||||
#elif defined(SHORTCUTS) && (defined(ARM4_ASM) || defined(ARM5E_ASM))
|
||||
#include "vq_arm4.h"
|
||||
#elif defined(BFIN_ASM)
|
||||
#include "vq_bfin.h"
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_ENCODER
|
||||
int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries)
|
||||
{
|
||||
int i,j;
|
||||
float min_dist=0;
|
||||
int best_index=0;
|
||||
for (i=0;i<entries;i++)
|
||||
int i=0;
|
||||
while (i<entries-1 && in>boundary[0])
|
||||
{
|
||||
float dist=0;
|
||||
for (j=0;j<len;j++)
|
||||
{
|
||||
float tmp = in[j]-*codebook++;
|
||||
dist += tmp*tmp;
|
||||
boundary++;
|
||||
i++;
|
||||
}
|
||||
if (i==0 || dist<min_dist)
|
||||
{
|
||||
min_dist=dist;
|
||||
best_index=i;
|
||||
}
|
||||
}
|
||||
return best_index;
|
||||
return i;
|
||||
}
|
||||
|
||||
int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries)
|
||||
{
|
||||
int i=0;
|
||||
while (i<entries-1 && in>boundary[0])
|
||||
{
|
||||
boundary++;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif /* DISABLE_ENCODER */
|
||||
|
||||
#if !defined(OVERRIDE_VQ_NBEST) && !defined(DISABLE_ENCODER)
|
||||
/*Finds the indices of the n-best entries in a codebook*/
|
||||
void vq_nbest(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist)
|
||||
void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
|
||||
{
|
||||
int i,j,k,used;
|
||||
used = 0;
|
||||
for (i=0;i<entries;i++)
|
||||
{
|
||||
float dist=.5*E[i];
|
||||
spx_word32_t dist=0;
|
||||
for (j=0;j<len;j++)
|
||||
dist -= in[j]**codebook++;
|
||||
dist = MAC16_16(dist,in[j],*codebook++);
|
||||
#ifdef FIXED_POINT
|
||||
dist=SUB32(SHR32(E[i],1),dist);
|
||||
#else
|
||||
dist=.5f*E[i]-dist;
|
||||
#endif
|
||||
if (i<N || dist<best_dist[N-1])
|
||||
{
|
||||
for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)
|
||||
@ -79,26 +100,35 @@ void vq_nbest(float *in, float *codebook, int len, int entries, float *E, int N,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* !defined(OVERRIDE_VQ_NBEST) && !defined(DISABLE_ENCODER) */
|
||||
|
||||
|
||||
|
||||
|
||||
#if !defined(OVERRIDE_VQ_NBEST_SIGN) && !defined(DISABLE_WIDEBAND) && !defined(DISABLE_ENCODER)
|
||||
/*Finds the indices of the n-best entries in a codebook with sign*/
|
||||
void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist)
|
||||
void vq_nbest_sign(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
|
||||
{
|
||||
int i,j,k, sign, used;
|
||||
used=0;
|
||||
for (i=0;i<entries;i++)
|
||||
{
|
||||
float dist=0;
|
||||
spx_word32_t dist=0;
|
||||
for (j=0;j<len;j++)
|
||||
dist -= in[j]**codebook++;
|
||||
dist = MAC16_16(dist,in[j],*codebook++);
|
||||
if (dist>0)
|
||||
{
|
||||
sign=1;
|
||||
sign=0;
|
||||
dist=-dist;
|
||||
} else
|
||||
{
|
||||
sign=0;
|
||||
sign=1;
|
||||
}
|
||||
dist += .5*E[i];
|
||||
#ifdef FIXED_POINT
|
||||
dist = ADD32(dist,SHR32(E[i],1));
|
||||
#else
|
||||
dist = ADD32(dist,.5f*E[i]);
|
||||
#endif
|
||||
if (i<N || dist<best_dist[N-1])
|
||||
{
|
||||
for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)
|
||||
@ -114,3 +144,4 @@ void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, i
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* !defined(OVERRIDE_VQ_NBEST_SIGN) && !defined(DISABLE_WIDEBAND) && !defined(DISABLE_ENCODER) */
|
||||
|
26
external/speex/src/vq.h
vendored
26
external/speex/src/vq.h
vendored
@ -1,7 +1,9 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: vq.h
|
||||
Vector quantization
|
||||
|
||||
/* Copyright (C) 2002 Jean-Marc Valin */
|
||||
/**
|
||||
@file vq.h
|
||||
@brief Vector quantization
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
@ -33,10 +35,20 @@
|
||||
#ifndef VQ_H
|
||||
#define VQ_H
|
||||
|
||||
int vq_index(float *in, float *codebook, int len, int entries);
|
||||
#include "arch.h"
|
||||
|
||||
void vq_nbest(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist);
|
||||
int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries);
|
||||
int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries);
|
||||
|
||||
void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist);
|
||||
#ifdef _USE_SSE
|
||||
#include <xmmintrin.h>
|
||||
void vq_nbest(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
|
||||
|
||||
void vq_nbest_sign(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
|
||||
#else
|
||||
void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
|
||||
|
||||
void vq_nbest_sign(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
115
external/speex/src/vq_arm4.h
vendored
Normal file
115
external/speex/src/vq_arm4.h
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
/* Copyright (C) 2004 Jean-Marc Valin */
|
||||
/**
|
||||
@file vq_arm4.h
|
||||
@brief ARM4-optimized vq routine
|
||||
*/
|
||||
/*
|
||||
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_VQ_NBEST
|
||||
void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
|
||||
{
|
||||
int i,j;
|
||||
for (i=0;i<entries;i+=4)
|
||||
{
|
||||
#if 1
|
||||
spx_word32_t dist1, dist2, dist3, dist4;
|
||||
int 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"
|
||||
"mov %10, %4 \n\t"
|
||||
"add %4, %4, %4\n\t"
|
||||
".vqloop%=:\n\t"
|
||||
"ldrsh %7, [%5], #2 \n\t"
|
||||
"ldrsh %8, [%6] \n\t"
|
||||
"mov %9, %6 \n\t"
|
||||
"mla %0, %7, %8, %0 \n\t"
|
||||
"ldrsh %8, [%9, %4]! \n\t"
|
||||
"mla %1, %7, %8, %1 \n\t"
|
||||
"ldrsh %8, [%9, %4]!\n\t"
|
||||
"mla %2, %7, %8, %2 \n\t"
|
||||
"ldrsh %8, [%9, %4]! \n\t"
|
||||
"mla %3, %7, %8, %3 \n\t"
|
||||
"subs %10, %10, #1 \n\t"
|
||||
"add %6, %6, #2 \n\t"
|
||||
"bne .vqloop%="
|
||||
: "=r" (dist1), "=r" (dist2), "=r" (dist3), "=r" (dist4),
|
||||
"=r" (dead1), "=r" (dead2), "=r" (codebook), "=r" (dead4),
|
||||
"=r" (dead5), "=r" (dead6), "=r" (dead7)
|
||||
: "4" (len), "5" (in), "6" (codebook)
|
||||
: "cc");
|
||||
#else
|
||||
dist1=dist2=dist3=dist4=0;
|
||||
/* spx_word32_t dist1=0;
|
||||
spx_word32_t dist2=0;
|
||||
spx_word32_t dist3=0;
|
||||
spx_word32_t dist4=0;*/
|
||||
for (j=0;j<2;j++)
|
||||
{
|
||||
const spx_word16_t *code = codebook;
|
||||
dist1 = MAC16_16(dist1,in[j],*code);
|
||||
code += len;
|
||||
dist2 = MAC16_16(dist2,in[j],*code);
|
||||
code += len;
|
||||
dist3 = MAC16_16(dist3,in[j],*code);
|
||||
code += len;
|
||||
dist4 = MAC16_16(dist4,in[j],*code);
|
||||
codebook++;
|
||||
}
|
||||
#endif
|
||||
dist1=SUB32(SHR(*E++,1),dist1);
|
||||
if (dist1<*best_dist || i==0)
|
||||
{
|
||||
*best_dist=dist1;
|
||||
*nbest=i;
|
||||
}
|
||||
dist2=SUB32(SHR(*E++,1),dist2);
|
||||
if (dist2<*best_dist)
|
||||
{
|
||||
*best_dist=dist2;
|
||||
*nbest=i+1;
|
||||
}
|
||||
dist3=SUB32(SHR(*E++,1),dist3);
|
||||
if (dist3<*best_dist)
|
||||
{
|
||||
*best_dist=dist3;
|
||||
*nbest=i+2;
|
||||
}
|
||||
dist4=SUB32(SHR(*E++,1),dist4);
|
||||
if (dist4<*best_dist)
|
||||
{
|
||||
*best_dist=dist4;
|
||||
*nbest=i+3;
|
||||
}
|
||||
codebook += 3*len;
|
||||
}
|
||||
}
|
110
external/speex/src/vq_bfin.h
vendored
Normal file
110
external/speex/src/vq_bfin.h
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
/* Copyright (C) 2005 Analog Devices */
|
||||
/**
|
||||
@file vq_bfin.h
|
||||
@author Jean-Marc Valin
|
||||
@brief Blackfin-optimized vq routine
|
||||
*/
|
||||
/*
|
||||
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 "bfin.h"
|
||||
|
||||
#define OVERRIDE_VQ_NBEST
|
||||
void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
|
||||
{
|
||||
if (N==1)
|
||||
{
|
||||
best_dist[0] = 2147483647;
|
||||
{
|
||||
spx_word32_t dist;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"LC0 = %8;\n\t"
|
||||
"R2 = 0;\n\t"
|
||||
"I0 = %6;\n\t"
|
||||
"B0 = %6;\n\t"
|
||||
"L0 = %9;\n\t"
|
||||
"LOOP entries_loop%= LC0;\n\t"
|
||||
"LOOP_BEGIN entries_loop%=;\n\t"
|
||||
"%0 = [%4++];\n\t"
|
||||
"%0 >>= 1;\n\t"
|
||||
"A0 = %0;\n\t"
|
||||
"R0.L = W[%1++%7] || R1.L = W[I0++];\n\t"
|
||||
"LOOP vq_loop%= LC1 = %5;\n\t"
|
||||
"LOOP_BEGIN vq_loop%=;\n\t"
|
||||
"%0 = (A0 -= R0.L*R1.L) (IS) || R0.L = W[%1++%7] || R1.L = W[I0++];\n\t"
|
||||
"LOOP_END vq_loop%=;\n\t"
|
||||
"%0 = (A0 -= R0.L*R1.L) (IS);\n\t"
|
||||
"cc = %0 < %2;\n\t"
|
||||
"if cc %2 = %0;\n\t"
|
||||
"if cc %3 = R2;\n\t"
|
||||
"R2 += 1;\n\t"
|
||||
"LOOP_END entries_loop%=;\n\t"
|
||||
: "=&D" (dist), "=&a" (codebook), "=&d" (best_dist[0]), "=&d" (nbest[0]), "=&a" (E)
|
||||
: "a" (len-1), "a" (in), "a" (2), "d" (entries), "d" (len<<1), "1" (codebook), "4" (E), "2" (best_dist[0]), "3" (nbest[0])
|
||||
: "R0", "R1", "R2", "I0", "L0", "B0", "A0", "cc", "memory",
|
||||
"ASTAT" BFIN_HWLOOP0_REGS BFIN_HWLOOP1_REGS
|
||||
);
|
||||
}
|
||||
} else {
|
||||
int i,k,used;
|
||||
used = 0;
|
||||
for (i=0;i<entries;i++)
|
||||
{
|
||||
spx_word32_t dist;
|
||||
__asm__
|
||||
(
|
||||
"%0 >>= 1;\n\t"
|
||||
"A0 = %0;\n\t"
|
||||
"I0 = %3;\n\t"
|
||||
"L0 = 0;\n\t"
|
||||
"R0.L = W[%1++%4] || R1.L = W[I0++];\n\t"
|
||||
"LOOP vq_loop%= LC0 = %2;\n\t"
|
||||
"LOOP_BEGIN vq_loop%=;\n\t"
|
||||
"%0 = (A0 -= R0.L*R1.L) (IS) || R0.L = W[%1++%4] || R1.L = W[I0++];\n\t"
|
||||
"LOOP_END vq_loop%=;\n\t"
|
||||
"%0 = (A0 -= R0.L*R1.L) (IS);\n\t"
|
||||
: "=D" (dist), "=a" (codebook)
|
||||
: "a" (len-1), "a" (in), "a" (2), "1" (codebook), "0" (E[i])
|
||||
: "R0", "R1", "I0", "L0", "A0", "ASTAT" BFIN_HWLOOP0_REGS
|
||||
);
|
||||
if (i<N || dist<best_dist[N-1])
|
||||
{
|
||||
for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)
|
||||
{
|
||||
best_dist[k]=best_dist[k-1];
|
||||
nbest[k] = nbest[k-1];
|
||||
}
|
||||
best_dist[k]=dist;
|
||||
nbest[k]=i;
|
||||
used++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
120
external/speex/src/vq_sse.h
vendored
Normal file
120
external/speex/src/vq_sse.h
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
/* Copyright (C) 2004 Jean-Marc Valin */
|
||||
/**
|
||||
@file vq_sse.h
|
||||
@brief SSE-optimized vq routine
|
||||
*/
|
||||
/*
|
||||
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_VQ_NBEST
|
||||
void vq_nbest(spx_word16_t *_in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
|
||||
{
|
||||
int i,j,k,used;
|
||||
VARDECL(float *dist);
|
||||
VARDECL(__m128 *in);
|
||||
__m128 half;
|
||||
used = 0;
|
||||
ALLOC(dist, entries, float);
|
||||
half = _mm_set_ps1(.5f);
|
||||
ALLOC(in, len, __m128);
|
||||
for (i=0;i<len;i++)
|
||||
in[i] = _mm_set_ps1(_in[i]);
|
||||
for (i=0;i<entries>>2;i++)
|
||||
{
|
||||
__m128 d = _mm_mul_ps(E[i], half);
|
||||
for (j=0;j<len;j++)
|
||||
d = _mm_sub_ps(d, _mm_mul_ps(in[j], *codebook++));
|
||||
_mm_storeu_ps(dist+4*i, d);
|
||||
}
|
||||
for (i=0;i<entries;i++)
|
||||
{
|
||||
if (i<N || dist[i]<best_dist[N-1])
|
||||
{
|
||||
for (k=N-1; (k >= 1) && (k > used || dist[i] < best_dist[k-1]); k--)
|
||||
{
|
||||
best_dist[k]=best_dist[k-1];
|
||||
nbest[k] = nbest[k-1];
|
||||
}
|
||||
best_dist[k]=dist[i];
|
||||
nbest[k]=i;
|
||||
used++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define OVERRIDE_VQ_NBEST_SIGN
|
||||
void vq_nbest_sign(spx_word16_t *_in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
|
||||
{
|
||||
int i,j,k,used;
|
||||
VARDECL(float *dist);
|
||||
VARDECL(__m128 *in);
|
||||
|
||||
used = 0;
|
||||
ALLOC(dist, entries, float);
|
||||
|
||||
ALLOC(in, len, __m128);
|
||||
for (i=0;i<len;i++)
|
||||
in[i] = _mm_set_ps1(_in[i]);
|
||||
for (i=0;i<entries>>2;i++)
|
||||
{
|
||||
__m128 d = _mm_setzero_ps();
|
||||
for (j=0;j<len;j++)
|
||||
d = _mm_add_ps(d, _mm_mul_ps(in[j], *codebook++));
|
||||
_mm_storeu_ps(dist+4*i, d);
|
||||
}
|
||||
for (i=0;i<entries;i++)
|
||||
{
|
||||
int sign;
|
||||
if (dist[i]>0)
|
||||
{
|
||||
sign=0;
|
||||
dist[i]=-dist[i];
|
||||
} else
|
||||
{
|
||||
sign=1;
|
||||
}
|
||||
dist[i] += .5f*((float*)E)[i];
|
||||
if (i<N || dist[i]<best_dist[N-1])
|
||||
{
|
||||
for (k=N-1; (k >= 1) && (k > used || dist[i] < best_dist[k-1]); k--)
|
||||
{
|
||||
best_dist[k]=best_dist[k-1];
|
||||
nbest[k] = nbest[k-1];
|
||||
}
|
||||
best_dist[k]=dist[i];
|
||||
nbest[k]=i;
|
||||
used++;
|
||||
if (sign)
|
||||
nbest[k]+=entries;
|
||||
}
|
||||
}
|
||||
}
|
102
external/speex/src/window.c
vendored
Normal file
102
external/speex/src/window.c
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
/* Copyright (C) 2006 Jean-Marc Valin
|
||||
File: window.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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
const spx_word16_t lag_window[11] = {
|
||||
32767, 32675, 32397, 31940, 31311, 30520, 29581, 28508, 27318, 26029, 24661
|
||||
};
|
||||
|
||||
const spx_word16_t lpc_window[200] = {
|
||||
2621, 2627, 2642, 2668, 2704, 2750, 2807, 2874,
|
||||
2951, 3038, 3135, 3242, 3359, 3486, 3623, 3769,
|
||||
3925, 4090, 4264, 4448, 4641, 4843, 5053, 5272,
|
||||
5500, 5736, 5981, 6233, 6493, 6761, 7036, 7319,
|
||||
7609, 7905, 8209, 8519, 8835, 9157, 9485, 9819,
|
||||
10158, 10502, 10852, 11206, 11564, 11926, 12293, 12663,
|
||||
13037, 13414, 13793, 14176, 14561, 14948, 15337, 15727,
|
||||
16119, 16512, 16906, 17300, 17695, 18089, 18484, 18877,
|
||||
19270, 19662, 20053, 20442, 20829, 21214, 21596, 21976,
|
||||
22353, 22726, 23096, 23463, 23826, 24184, 24538, 24887,
|
||||
25231, 25570, 25904, 26232, 26555, 26871, 27181, 27484,
|
||||
27781, 28070, 28353, 28628, 28896, 29157, 29409, 29653,
|
||||
29889, 30117, 30336, 30547, 30749, 30941, 31125, 31300,
|
||||
31465, 31621, 31767, 31903, 32030, 32147, 32254, 32352,
|
||||
32439, 32516, 32582, 32639, 32685, 32722, 32747, 32763,
|
||||
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
|
||||
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
|
||||
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
|
||||
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
|
||||
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
|
||||
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
|
||||
32767, 32767, 32767, 32723, 32590, 32368, 32058, 31661,
|
||||
31177, 30610, 29959, 29227, 28416, 27528, 26566, 25532,
|
||||
24430, 23263, 22034, 20747, 19406, 18015, 16579, 15104,
|
||||
13594, 12058, 10503, 8941, 7391, 5887, 4498, 3392
|
||||
};
|
||||
#else
|
||||
const spx_word16_t lag_window[11] = {
|
||||
1.00000f, 0.99716f, 0.98869f, 0.97474f, 0.95554f, 0.93140f, 0.90273f, 0.86998f, 0.83367f, 0.79434f, 0.75258f
|
||||
};
|
||||
|
||||
const spx_word16_t lpc_window[200] = {
|
||||
0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f,
|
||||
0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f,
|
||||
0.119769f, 0.124811f, 0.130137f, 0.135744f, 0.141628f, 0.147786f, 0.154212f, 0.160902f,
|
||||
0.167852f, 0.175057f, 0.182513f, 0.190213f, 0.198153f, 0.206328f, 0.214731f, 0.223357f,
|
||||
0.232200f, 0.241254f, 0.250513f, 0.259970f, 0.269619f, 0.279453f, 0.289466f, 0.299651f,
|
||||
0.310000f, 0.320507f, 0.331164f, 0.341965f, 0.352901f, 0.363966f, 0.375151f, 0.386449f,
|
||||
0.397852f, 0.409353f, 0.420943f, 0.432615f, 0.444361f, 0.456172f, 0.468040f, 0.479958f,
|
||||
0.491917f, 0.503909f, 0.515925f, 0.527959f, 0.540000f, 0.552041f, 0.564075f, 0.576091f,
|
||||
0.588083f, 0.600042f, 0.611960f, 0.623828f, 0.635639f, 0.647385f, 0.659057f, 0.670647f,
|
||||
0.682148f, 0.693551f, 0.704849f, 0.716034f, 0.727099f, 0.738035f, 0.748836f, 0.759493f,
|
||||
0.770000f, 0.780349f, 0.790534f, 0.800547f, 0.810381f, 0.820030f, 0.829487f, 0.838746f,
|
||||
0.847800f, 0.856643f, 0.865269f, 0.873672f, 0.881847f, 0.889787f, 0.897487f, 0.904943f,
|
||||
0.912148f, 0.919098f, 0.925788f, 0.932214f, 0.938372f, 0.944256f, 0.949863f, 0.955189f,
|
||||
0.960231f, 0.964985f, 0.969447f, 0.973615f, 0.977486f, 0.981057f, 0.984326f, 0.987290f,
|
||||
0.989948f, 0.992297f, 0.994337f, 0.996065f, 0.997480f, 0.998582f, 0.999370f, 0.999842f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 0.998640f, 0.994566f, 0.987787f, 0.978324f, 0.966203f,
|
||||
0.951458f, 0.934131f, 0.914270f, 0.891931f, 0.867179f, 0.840084f, 0.810723f, 0.779182f,
|
||||
0.745551f, 0.709930f, 0.672424f, 0.633148f, 0.592223f, 0.549781f, 0.505964f, 0.460932f,
|
||||
0.414863f, 0.367968f, 0.320511f, 0.272858f, 0.225569f, 0.179655f, 0.137254f, 0.103524f
|
||||
};
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user