change pretty much everything so it does what I want :^)

This commit is contained in:
2021-05-01 18:38:37 +02:00
parent 73ba4f105e
commit 36a3225a2b
402 changed files with 106422 additions and 18837 deletions

98
external/SILK_SDK_SRC_FLP_v1.0.9/Makefile vendored Executable file
View File

@ -0,0 +1,98 @@
#
# Makefile for Silk SDK
#
# Copyright (c) 2012, Skype Limited
# All rights reserved.
#
#Platform detection and settings
BUILD_OS := $(shell uname | sed -e 's/^.*Darwin.*/MacOS-X/ ; s/^.*CYGWIN.*/Windows/')
BUILD_ARCHITECTURE := $(shell uname -m | sed -e 's/i686/i386/')
EXESUFFIX =
LIBPREFIX = lib
LIBSUFFIX = .a
OBJSUFFIX = .o
CC = $(TOOLCHAIN_PREFIX)gcc$(TOOLCHAIN_SUFFIX)
AR = $(TOOLCHAIN_PREFIX)ar
RANLIB = $(TOOLCHAIN_PREFIX)ranlib
CP = $(TOOLCHAIN_PREFIX)cp
cflags-from-defines = $(addprefix -D,$(1))
cflags-from-includes = $(addprefix -I,$(1))
ldflags-from-ldlibdirs = $(addprefix -L,$(1))
ldlibs-from-libs = $(addprefix -l,$(1))
CFLAGS += -Wall -enable-threads -O3
CFLAGS += $(call cflags-from-defines,$(CDEFINES))
CFLAGS += $(call cflags-from-defines,$(ADDED_DEFINES))
CFLAGS += $(call cflags-from-includes,$(CINCLUDES))
LDFLAGS += $(call ldflags-from-ldlibdirs,$(LDLIBDIRS))
LDLIBS += $(call ldlibs-from-libs,$(LIBS))
COMPILE.c.cmdline = $(CC) -c $(CFLAGS) -o $@ $<
LINK.o.cmdline = $(LINK.o) $^ $(LDLIBS) -lm -o $@$(EXESUFFIX)
ARCHIVE.cmdline = $(AR) $(ARFLAGS) $@ $^ && $(RANLIB) $@
%$(OBJSUFFIX):%.c
$(COMPILE.c.cmdline)
# Directives
CINCLUDES += interface src test
# VPATH e.g. VPATH = src:../headers
VPATH = ./ \
interface \
src \
test
# Variable definitions
LIB_NAME = SKP_SILK_SDK
TARGET = $(LIBPREFIX)$(LIB_NAME)$(LIBSUFFIX)
SRCS_C = $(wildcard src/*.c)
OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(SRCS_C))
ENCODER_SRCS_C = test/Encoder.c
ENCODER_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(ENCODER_SRCS_C))
DECODER_SRCS_C = test/Decoder.c
DECODER_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(DECODER_SRCS_C))
SIGNALCMP_SRCS_C = test/signalCompare.c
SIGNALCMP_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(SIGNALCMP_SRCS_C))
LIBS = \
$(LIB_NAME)
LDLIBDIRS = ./
# Rules
default: all
all: $(TARGET) encoder decoder signalcompare
lib: $(TARGET)
$(TARGET): $(OBJS)
$(ARCHIVE.cmdline)
encoder$(EXESUFFIX): $(ENCODER_OBJS)
$(LINK.o.cmdline)
decoder$(EXESUFFIX): $(DECODER_OBJS)
$(LINK.o.cmdline)
signalcompare$(EXESUFFIX): $(SIGNALCMP_OBJS)
$(LINK.o.cmdline)
clean:
$(RM) $(TARGET)* $(OBJS) $(ENCODER_OBJS) $(DECODER_OBJS) \
$(SIGNALCMP_OBJS) $(TEST_OBJS) \
encoder$(EXESUFFIX) decoder$(EXESUFFIX) signalcompare$(EXESUFFIX)

56
external/SILK_SDK_SRC_FLP_v1.0.9/Silk_SDK.sln vendored Executable file
View File

@ -0,0 +1,56 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dec_SDK", "test\Dec_SDK.vcxproj", "{82685D7F-0589-42BD-877C-31A952D53A8E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Enc_SDK", "test\Enc_SDK.vcxproj", "{6D97A8EF-5724-4D85-8BF4-C583714BBA78}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Silk_FLP", "src\Silk_FLP.vcxproj", "{56B91D01-9150-4BBF-AFA1-5B68AB991B76}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SignalCompare", "test\SignalCompare.vcxproj", "{7FE8F544-9175-40C3-A187-7F15CE9A75D8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{82685D7F-0589-42BD-877C-31A952D53A8E}.Debug|Win32.ActiveCfg = Debug|Win32
{82685D7F-0589-42BD-877C-31A952D53A8E}.Debug|Win32.Build.0 = Debug|Win32
{82685D7F-0589-42BD-877C-31A952D53A8E}.Debug|x64.ActiveCfg = Debug|x64
{82685D7F-0589-42BD-877C-31A952D53A8E}.Debug|x64.Build.0 = Debug|x64
{82685D7F-0589-42BD-877C-31A952D53A8E}.Release|Win32.ActiveCfg = Release|Win32
{82685D7F-0589-42BD-877C-31A952D53A8E}.Release|Win32.Build.0 = Release|Win32
{82685D7F-0589-42BD-877C-31A952D53A8E}.Release|x64.ActiveCfg = Release|x64
{82685D7F-0589-42BD-877C-31A952D53A8E}.Release|x64.Build.0 = Release|x64
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Debug|Win32.ActiveCfg = Debug|Win32
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Debug|Win32.Build.0 = Debug|Win32
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Debug|x64.ActiveCfg = Debug|x64
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Debug|x64.Build.0 = Debug|x64
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Release|Win32.ActiveCfg = Release|Win32
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Release|Win32.Build.0 = Release|Win32
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Release|x64.ActiveCfg = Release|x64
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Release|x64.Build.0 = Release|x64
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Debug|Win32.ActiveCfg = Debug|Win32
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Debug|Win32.Build.0 = Debug|Win32
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Debug|x64.ActiveCfg = Debug|x64
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Debug|x64.Build.0 = Debug|x64
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Release|Win32.ActiveCfg = Release|Win32
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Release|Win32.Build.0 = Release|Win32
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Release|x64.ActiveCfg = Release|x64
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Release|x64.Build.0 = Release|x64
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Debug|Win32.ActiveCfg = Debug|Win32
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Debug|Win32.Build.0 = Debug|Win32
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Debug|x64.ActiveCfg = Debug|x64
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Debug|x64.Build.0 = Debug|x64
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Release|Win32.ActiveCfg = Release|Win32
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Release|Win32.Build.0 = Release|Win32
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Release|x64.ActiveCfg = Release|x64
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,44 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dec_SDK", "test\Dec_SDK.vcproj", "{82685D7F-0589-42BD-877C-31A952D53A8E}"
ProjectSection(ProjectDependencies) = postProject
{56B91D01-9150-4BBF-AFA1-5B68AB991B76} = {56B91D01-9150-4BBF-AFA1-5B68AB991B76}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Enc_SDK", "test\Enc_SDK.vcproj", "{6D97A8EF-5724-4D85-8BF4-C583714BBA78}"
ProjectSection(ProjectDependencies) = postProject
{56B91D01-9150-4BBF-AFA1-5B68AB991B76} = {56B91D01-9150-4BBF-AFA1-5B68AB991B76}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Silk_FLP", "src\Silk_FLP.vcproj", "{56B91D01-9150-4BBF-AFA1-5B68AB991B76}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SignalCompare", "test\SignalCompare.vcproj", "{7FE8F544-9175-40C3-A187-7F15CE9A75D8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{82685D7F-0589-42BD-877C-31A952D53A8E}.Debug|Win32.ActiveCfg = Debug|Win32
{82685D7F-0589-42BD-877C-31A952D53A8E}.Debug|Win32.Build.0 = Debug|Win32
{82685D7F-0589-42BD-877C-31A952D53A8E}.Release|Win32.ActiveCfg = Release|Win32
{82685D7F-0589-42BD-877C-31A952D53A8E}.Release|Win32.Build.0 = Release|Win32
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Debug|Win32.ActiveCfg = Debug|Win32
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Debug|Win32.Build.0 = Debug|Win32
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Release|Win32.ActiveCfg = Release|Win32
{6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Release|Win32.Build.0 = Release|Win32
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Debug|Win32.ActiveCfg = Debug|Win32
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Debug|Win32.Build.0 = Debug|Win32
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Release|Win32.ActiveCfg = Release|Win32
{56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Release|Win32.Build.0 = Release|Win32
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Debug|Win32.ActiveCfg = Debug|Win32
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Debug|Win32.Build.0 = Debug|Win32
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Release|Win32.ActiveCfg = Release|Win32
{7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,152 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef SKP_SILK_SDK_API_H
#define SKP_SILK_SDK_API_H
#include "SKP_Silk_control.h"
#include "SKP_Silk_typedef.h"
#include "SKP_Silk_errors.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define SILK_MAX_FRAMES_PER_PACKET 5
/* Struct for TOC (Table of Contents) */
typedef struct {
SKP_int framesInPacket; /* Number of 20 ms frames in packet */
SKP_int fs_kHz; /* Sampling frequency in packet */
SKP_int inbandLBRR; /* Does packet contain LBRR information */
SKP_int corrupt; /* Packet is corrupt */
SKP_int vadFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* VAD flag for each frame in packet */
SKP_int sigtypeFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Signal type for each frame in packet */
} SKP_Silk_TOC_struct;
/****************************************/
/* Encoder functions */
/****************************************/
/***********************************************/
/* Get size in bytes of the Silk encoder state */
/***********************************************/
SKP_int SKP_Silk_SDK_Get_Encoder_Size(
SKP_int32 *encSizeBytes /* O: Number of bytes in SILK encoder state */
);
/*************************/
/* Init or reset encoder */
/*************************/
SKP_int SKP_Silk_SDK_InitEncoder(
void *encState, /* I/O: State */
SKP_SILK_SDK_EncControlStruct *encStatus /* O: Encoder Status */
);
/***************************************/
/* Read control structure from encoder */
/***************************************/
SKP_int SKP_Silk_SDK_QueryEncoder(
const void *encState, /* I: State */
SKP_SILK_SDK_EncControlStruct *encStatus /* O: Encoder Status */
);
/**************************/
/* Encode frame with Silk */
/**************************/
SKP_int SKP_Silk_SDK_Encode(
void *encState, /* I/O: State */
const SKP_SILK_SDK_EncControlStruct *encControl, /* I: Control status */
const SKP_int16 *samplesIn, /* I: Speech sample input vector */
SKP_int nSamplesIn, /* I: Number of samples in input vector */
SKP_uint8 *outData, /* O: Encoded output vector */
SKP_int16 *nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */
);
/****************************************/
/* Decoder functions */
/****************************************/
/***********************************************/
/* Get size in bytes of the Silk decoder state */
/***********************************************/
SKP_int SKP_Silk_SDK_Get_Decoder_Size(
SKP_int32 *decSizeBytes /* O: Number of bytes in SILK decoder state */
);
/*************************/
/* Init or Reset decoder */
/*************************/
SKP_int SKP_Silk_SDK_InitDecoder(
void *decState /* I/O: State */
);
/******************/
/* Decode a frame */
/******************/
SKP_int SKP_Silk_SDK_Decode(
void* decState, /* I/O: State */
SKP_SILK_SDK_DecControlStruct* decControl, /* I/O: Control Structure */
SKP_int lostFlag, /* I: 0: no loss, 1 loss */
const SKP_uint8 *inData, /* I: Encoded input vector */
const SKP_int nBytesIn, /* I: Number of input bytes */
SKP_int16 *samplesOut, /* O: Decoded output speech vector */
SKP_int16 *nSamplesOut /* I/O: Number of samples (vector/decoded) */
);
/***************************************************************/
/* Find Low Bit Rate Redundancy (LBRR) information in a packet */
/***************************************************************/
void SKP_Silk_SDK_search_for_LBRR(
const SKP_uint8 *inData, /* I: Encoded input vector */
const SKP_int nBytesIn, /* I: Number of input Bytes */
SKP_int lost_offset, /* I: Offset from lost packet */
SKP_uint8 *LBRRData, /* O: LBRR payload */
SKP_int16 *nLBRRBytes /* O: Number of LBRR Bytes */
);
/**************************************/
/* Get table of contents for a packet */
/**************************************/
void SKP_Silk_SDK_get_TOC(
const SKP_uint8 *inData, /* I: Encoded input vector */
const SKP_int nBytesIn, /* I: Number of input bytes */
SKP_Silk_TOC_struct *Silk_TOC /* O: Table of contents */
);
/**************************/
/* Get the version number */
/**************************/
/* Return a pointer to string specifying the version */
const char *SKP_Silk_SDK_get_version();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,91 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef SKP_SILK_CONTROL_H
#define SKP_SILK_CONTROL_H
#include "SKP_Silk_typedef.h"
#ifdef __cplusplus
extern "C"
{
#endif
/***********************************************/
/* Structure for controlling encoder operation */
/***********************************************/
typedef struct {
/* I: Input signal sampling rate in Hertz; 8000/12000/16000/24000 */
SKP_int32 API_sampleRate;
/* I: Maximum internal sampling rate in Hertz; 8000/12000/16000/24000 */
SKP_int32 maxInternalSampleRate;
/* I: Number of samples per packet; must be equivalent of 20, 40, 60, 80 or 100 ms */
SKP_int packetSize;
/* I: Bitrate during active speech in bits/second; internally limited */
SKP_int32 bitRate;
/* I: Uplink packet loss in percent (0-100) */
SKP_int packetLossPercentage;
/* I: Complexity mode; 0 is lowest; 1 is medium and 2 is highest complexity */
SKP_int complexity;
/* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */
SKP_int useInBandFEC;
/* I: Flag to enable discontinuous transmission (DTX); 0/1 */
SKP_int useDTX;
} SKP_SILK_SDK_EncControlStruct;
/**************************************************************************/
/* Structure for controlling decoder operation and reading decoder status */
/**************************************************************************/
typedef struct {
/* I: Output signal sampling rate in Hertz; 8000/12000/16000/24000 */
SKP_int32 API_sampleRate;
/* O: Number of samples per frame */
SKP_int frameSize;
/* O: Frames per packet 1, 2, 3, 4, 5 */
SKP_int framesPerPacket;
/* O: Flag to indicate that the decoder has remaining payloads internally */
SKP_int moreInternalDecoderFrames;
/* O: Distance between main payload and redundant payload in packets */
SKP_int inBandFECOffset;
} SKP_SILK_SDK_DecControlStruct;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,89 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef SKP_SILK_ERRORS_H
#define SKP_SILK_ERRORS_H
#ifdef __cplusplus
extern "C"
{
#endif
/******************/
/* Error messages */
/******************/
#define SKP_SILK_NO_ERROR 0
/**************************/
/* Encoder error messages */
/**************************/
/* Input length is not a multiplum of 10 ms, or length is longer than the packet length */
#define SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -1
/* Sampling frequency not 8000, 12000, 16000 or 24000 Hertz */
#define SKP_SILK_ENC_FS_NOT_SUPPORTED -2
/* Packet size not 20, 40, 60, 80 or 100 ms */
#define SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -3
/* Allocated payload buffer too short */
#define SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT -4
/* Loss rate not between 0 and 100 percent */
#define SKP_SILK_ENC_INVALID_LOSS_RATE -5
/* Complexity setting not valid, use 0, 1 or 2 */
#define SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING -6
/* Inband FEC setting not valid, use 0 or 1 */
#define SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING -7
/* DTX setting not valid, use 0 or 1 */
#define SKP_SILK_ENC_INVALID_DTX_SETTING -8
/* Internal encoder error */
#define SKP_SILK_ENC_INTERNAL_ERROR -9
/**************************/
/* Decoder error messages */
/**************************/
/* Output sampling frequency lower than internal decoded sampling frequency */
#define SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY -10
/* Payload size exceeded the maximum allowed 1024 bytes */
#define SKP_SILK_DEC_PAYLOAD_TOO_LARGE -11
/* Payload has bit errors */
#define SKP_SILK_DEC_PAYLOAD_ERROR -12
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,107 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef _SKP_SILK_API_TYPDEF_H_
#define _SKP_SILK_API_TYPDEF_H_
#ifndef SKP_USE_DOUBLE_PRECISION_FLOATS
#define SKP_USE_DOUBLE_PRECISION_FLOATS 0
#endif
#include <float.h>
#if defined( __GNUC__ )
#include <stdint.h>
#endif
#define SKP_int int /* used for counters etc; at least 16 bits */
#ifdef __GNUC__
# define SKP_int64 int64_t
#else
# define SKP_int64 long long
#endif
#define SKP_int32 int
#define SKP_int16 short
#define SKP_int8 signed char
#define SKP_uint unsigned int /* used for counters etc; at least 16 bits */
#ifdef __GNUC__
# define SKP_uint64 uint64_t
#else
# define SKP_uint64 unsigned long long
#endif
#define SKP_uint32 unsigned int
#define SKP_uint16 unsigned short
#define SKP_uint8 unsigned char
#define SKP_int_ptr_size intptr_t
#if SKP_USE_DOUBLE_PRECISION_FLOATS
# define SKP_float double
# define SKP_float_MAX DBL_MAX
#else
# define SKP_float float
# define SKP_float_MAX FLT_MAX
#endif
#define SKP_INLINE static __inline
#ifdef _WIN32
# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) _stricmp(x, y)
#else
# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) strcasecmp(x, y)
#endif
#define SKP_int64_MAX ((SKP_int64)0x7FFFFFFFFFFFFFFFLL) /* 2^63 - 1 */
#define SKP_int64_MIN ((SKP_int64)0x8000000000000000LL) /* -2^63 */
#define SKP_int32_MAX 0x7FFFFFFF /* 2^31 - 1 = 2147483647*/
#define SKP_int32_MIN ((SKP_int32)0x80000000) /* -2^31 = -2147483648*/
#define SKP_int16_MAX 0x7FFF /* 2^15 - 1 = 32767*/
#define SKP_int16_MIN ((SKP_int16)0x8000) /* -2^15 = -32768*/
#define SKP_int8_MAX 0x7F /* 2^7 - 1 = 127*/
#define SKP_int8_MIN ((SKP_int8)0x80) /* -2^7 = -128*/
#define SKP_uint32_MAX 0xFFFFFFFF /* 2^32 - 1 = 4294967295 */
#define SKP_uint32_MIN 0x00000000
#define SKP_uint16_MAX 0xFFFF /* 2^16 - 1 = 65535 */
#define SKP_uint16_MIN 0x0000
#define SKP_uint8_MAX 0xFF /* 2^8 - 1 = 255 */
#define SKP_uint8_MIN 0x00
#define SKP_TRUE 1
#define SKP_FALSE 0
/* assertions */
#if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS))
# ifndef SKP_assert
# include <crtdbg.h> /* ASSERTE() */
# define SKP_assert(COND) _ASSERTE(COND)
# endif
#else
# define SKP_assert(COND)
#endif
#endif

94
external/SILK_SDK_SRC_FLP_v1.0.9/readme.txt vendored Executable file
View File

@ -0,0 +1,94 @@
************************************************************************
Floating Point SILK SDK 1.0.9 source code package
Copyright 2012 (c), Skype Limited
https://developer.skype.com/silk/
************************************************************************
Date: 03/08/2012 (Format: DD/MM/YYYY)
I. Description
This package contains files for compilation and evaluation of the floating
point SILK SDK library. The following is included in this package:
o Source code for the floating point SILK SDK library
o Source code for creating encoder and decoder executables
o Test vectors
o Comparison tool
o Microsoft Visual Studio solutions and project files
o Makefile for GNU C-compiler (GCC)
II. Files and Folders
o doc/ - contains more information about the SILK SDK
o interface/ - contains API header files
o src/ - contains all SILK SDK library source files
o test/ - contains source files for testing the SILK SDK
o test_vectors/ - contains test vectors
o Makefile - Makefile for compiling with GCC
o readme.txt - this file
o Silk_SDK.sln - Visual Studio 2010 solution for all SILK SDK code
o Silk_SDK_VS2005.sln - Visual Studio 2005 solution for all SILK SDK code
III. How to use the Makefile
1. How to clean and compile the SILK SDK library:
make clean lib
2. How to compile an encoder executable:
make encoder
3. How to compile a decoder executable:
make decoder
4. How to clean and compile all of the above:
make clean all
5. How to build for big endian CPU's
Make clean all ADDED_DEFINES+=_SYSTEM_IS_BIG_ENDIAN
To be able to use the test vectors with big endian CPU's the test programs
need to be compiled in a different way. Note that the 16 bit input and output
from the test programs will have the upper and lower bytes swapped with this setting.
6. How to use the comparison tool:
See 'How to use the test vectors.txt' in the test_vectors folder.
IV. History
Version 1.0.9 - Added 64-bit support. Added iOS LLVM compiler support. Lowered DTX mode bitrate. Bugfixes for ARM builds. Various other small fixes.
Version 1.0.8 - Improved noise shaping, various other improvements, and various bugfixes. Added a MIPS version
Version 1.0.7 - Updated with bugfixes for LBRR and pitch estimator. SignalCompare updated
Version 1.0.6 - Updated with bugfixes for ARM builds
Version 1.0.5 - Updated with bugfixes for ARM builds
Version 1.0.4 - Updated with various bugfixes and improvements, including some API changes
Added support for big endian platforms
Added resampler support for additional API sample rates
Version 1.0.3 - Updated with various bugfixes and improvements
Version 1.0.2 - Updated with various bugfixes and improvements
Version 1.0.1 - First beta source code release
V. Compatibility
This package has been tested on the following platforms:
Windows 7 Professional, 32-bit version, Intel Core i7 CPU
Windows 7 Professional, 64-bit version, Intel Core i7 CPU
Mac OS X Version 10.7.4, 64-bit version, Intel Core i7 CPU
Ubuntu Linux 10.04 LTS, 32-bit version, Intel Core i7 CPU
Ubuntu Linux 12.04 LTS, 64-bit version, Intel Core 2 Duo CPU
VI. Known Issues
None
VII. Additional Resources
For more information, visit the SILK SDK web site at:
<https://developer.skype.com/silk/>

View File

@ -0,0 +1,279 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* Conversion between prediction filter coefficients and NLSFs */
/* Requires the order to be an even number */
/* A piecewise linear approximation maps LSF <-> cos(LSF) */
/* Therefore the result is not accurate NLSFs, but the two */
/* function are accurate inverses of each other */
#include "SKP_Silk_SigProc_FIX.h"
/* Number of binary divisions */
#define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
#define QPoly 16
#define MAX_ITERATIONS_A2NLSF_FIX 30
/* Flag for using 2x as many cosine sampling points, reduces the risk of missing a root */
#define OVERSAMPLE_COSINE_TABLE 0
/* Helper function for A2NLSF(..) */
/* Transforms polynomials from cos(n*f) to cos(f)^n */
SKP_INLINE void SKP_Silk_A2NLSF_trans_poly(
SKP_int32 *p, /* I/O Polynomial */
const SKP_int dd /* I Polynomial order (= filter order / 2 ) */
)
{
SKP_int k, n;
for( k = 2; k <= dd; k++ ) {
for( n = dd; n > k; n-- ) {
p[ n - 2 ] -= p[ n ];
}
p[ k - 2 ] -= SKP_LSHIFT( p[ k ], 1 );
}
}
/* Helper function for A2NLSF(..) */
/* Polynomial evaluation */
SKP_INLINE SKP_int32 SKP_Silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly */
SKP_int32 *p, /* I Polynomial, QPoly */
const SKP_int32 x, /* I Evaluation point, Q12 */
const SKP_int dd /* I Order */
)
{
SKP_int n;
SKP_int32 x_Q16, y32;
y32 = p[ dd ]; /* QPoly */
x_Q16 = SKP_LSHIFT( x, 4 );
for( n = dd - 1; n >= 0; n-- ) {
y32 = SKP_SMLAWW( p[ n ], y32, x_Q16 ); /* QPoly */
}
return y32;
}
SKP_INLINE void SKP_Silk_A2NLSF_init(
const SKP_int32 *a_Q16,
SKP_int32 *P,
SKP_int32 *Q,
const SKP_int dd
)
{
SKP_int k;
/* Convert filter coefs to even and odd polynomials */
P[dd] = SKP_LSHIFT( 1, QPoly );
Q[dd] = SKP_LSHIFT( 1, QPoly );
for( k = 0; k < dd; k++ ) {
#if( QPoly < 16 )
P[ k ] = SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */
Q[ k ] = SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */
#elif( QPoly == 16 )
P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; // QPoly
Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; // QPoly
#else
P[ k ] = SKP_LSHIFT( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */
Q[ k ] = SKP_LSHIFT( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */
#endif
}
/* Divide out zeros as we have that for even filter orders, */
/* z = 1 is always a root in Q, and */
/* z = -1 is always a root in P */
for( k = dd; k > 0; k-- ) {
P[ k - 1 ] -= P[ k ];
Q[ k - 1 ] += Q[ k ];
}
/* Transform polynomials from cos(n*f) to cos(f)^n */
SKP_Silk_A2NLSF_trans_poly( P, dd );
SKP_Silk_A2NLSF_trans_poly( Q, dd );
}
/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
void SKP_Silk_A2NLSF(
SKP_int *NLSF, /* O Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] */
SKP_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */
const SKP_int d /* I Filter order (must be even) */
)
{
SKP_int i, k, m, dd, root_ix, ffrac;
SKP_int32 xlo, xhi, xmid;
SKP_int32 ylo, yhi, ymid;
SKP_int32 nom, den;
SKP_int32 P[ SKP_Silk_MAX_ORDER_LPC / 2 + 1 ];
SKP_int32 Q[ SKP_Silk_MAX_ORDER_LPC / 2 + 1 ];
SKP_int32 *PQ[ 2 ];
SKP_int32 *p;
/* Store pointers to array */
PQ[ 0 ] = P;
PQ[ 1 ] = Q;
dd = SKP_RSHIFT( d, 1 );
SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd );
/* Find roots, alternating between P and Q */
p = P; /* Pointer to polynomial */
xlo = SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12
ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
if( ylo < 0 ) {
/* Set the first NLSF to zero and move on to the next */
NLSF[ 0 ] = 0;
p = Q; /* Pointer to polynomial */
ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
root_ix = 1; /* Index of current root */
} else {
root_ix = 0; /* Index of current root */
}
k = 1; /* Loop counter */
i = 0; /* Counter for bandwidth expansions applied */
while( 1 ) {
/* Evaluate polynomial */
#if OVERSAMPLE_COSINE_TABLE
xhi = SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] +
( ( SKP_Silk_LSFCosTab_FIX_Q12[ ( k + 1 ) >> 1 ] -
SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] ) >> 1 ); /* Q12 */
#else
xhi = SKP_Silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */
#endif
yhi = SKP_Silk_A2NLSF_eval_poly( p, xhi, dd );
/* Detect zero crossing */
if( ( ylo <= 0 && yhi >= 0 ) || ( ylo >= 0 && yhi <= 0 ) ) {
/* Binary division */
#if OVERSAMPLE_COSINE_TABLE
ffrac = -128;
#else
ffrac = -256;
#endif
for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) {
/* Evaluate polynomial */
xmid = SKP_RSHIFT_ROUND( xlo + xhi, 1 );
ymid = SKP_Silk_A2NLSF_eval_poly( p, xmid, dd );
/* Detect zero crossing */
if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) {
/* Reduce frequency */
xhi = xmid;
yhi = ymid;
} else {
/* Increase frequency */
xlo = xmid;
ylo = ymid;
#if OVERSAMPLE_COSINE_TABLE
ffrac = SKP_ADD_RSHIFT( ffrac, 64, m );
#else
ffrac = SKP_ADD_RSHIFT( ffrac, 128, m );
#endif
}
}
/* Interpolate */
if( SKP_abs( ylo ) < 65536 ) {
/* Avoid dividing by zero */
den = ylo - yhi;
nom = SKP_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + SKP_RSHIFT( den, 1 );
if( den != 0 ) {
ffrac += SKP_DIV32( nom, den );
}
} else {
/* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */
ffrac += SKP_DIV32( ylo, SKP_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) );
}
#if OVERSAMPLE_COSINE_TABLE
NLSF[ root_ix ] = (SKP_int)SKP_min_32( SKP_LSHIFT( (SKP_int32)k, 7 ) + ffrac, SKP_int16_MAX );
#else
NLSF[ root_ix ] = (SKP_int)SKP_min_32( SKP_LSHIFT( (SKP_int32)k, 8 ) + ffrac, SKP_int16_MAX );
#endif
SKP_assert( NLSF[ root_ix ] >= 0 );
SKP_assert( NLSF[ root_ix ] <= 32767 );
root_ix++; /* Next root */
if( root_ix >= d ) {
/* Found all roots */
break;
}
/* Alternate pointer to polynomial */
p = PQ[ root_ix & 1 ];
/* Evaluate polynomial */
#if OVERSAMPLE_COSINE_TABLE
xlo = SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] +
( ( SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] -
SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] ) >> 1 ); // Q12
#else
xlo = SKP_Silk_LSFCosTab_FIX_Q12[ k - 1 ]; // Q12
#endif
ylo = SKP_LSHIFT( 1 - ( root_ix & 2 ), 12 );
} else {
/* Increment loop counter */
k++;
xlo = xhi;
ylo = yhi;
#if OVERSAMPLE_COSINE_TABLE
if( k > 2 * LSF_COS_TAB_SZ_FIX ) {
#else
if( k > LSF_COS_TAB_SZ_FIX ) {
#endif
i++;
if( i > MAX_ITERATIONS_A2NLSF_FIX ) {
/* Set NLSFs to white spectrum and exit */
NLSF[ 0 ] = SKP_DIV32_16( 1 << 15, d + 1 );
for( k = 1; k < d; k++ ) {
NLSF[ k ] = SKP_SMULBB( k + 1, NLSF[ 0 ] );
}
return;
}
/* Error: Apply progressively more bandwidth expansion and run again */
SKP_Silk_bwexpander_32( a_Q16, d, 65536 - SKP_SMULBB( 10 + i, i ) ); // 10_Q16 = 0.00015
SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd );
p = P; /* Pointer to polynomial */
xlo = SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12
ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
if( ylo < 0 ) {
/* Set the first NLSF to zero and move on to the next */
NLSF[ 0 ] = 0;
p = Q; /* Pointer to polynomial */
ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
root_ix = 1; /* Index of current root */
} else {
root_ix = 0; /* Index of current root */
}
k = 1; /* Reset loop counter */
}
}
}
}

View File

@ -0,0 +1,149 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/* Generates excitation for CNG LPC synthesis */
SKP_INLINE void SKP_Silk_CNG_exc(
SKP_int16 residual[], /* O CNG residual signal Q0 */
SKP_int32 exc_buf_Q10[], /* I Random samples buffer Q10 */
SKP_int32 Gain_Q16, /* I Gain to apply */
SKP_int length, /* I Length */
SKP_int32 *rand_seed /* I/O Seed to random index generator */
)
{
SKP_int32 seed;
SKP_int i, idx, exc_mask;
exc_mask = CNG_BUF_MASK_MAX;
while( exc_mask > length ) {
exc_mask = SKP_RSHIFT( exc_mask, 1 );
}
seed = *rand_seed;
for( i = 0; i < length; i++ ) {
seed = SKP_RAND( seed );
idx = ( SKP_int )( SKP_RSHIFT( seed, 24 ) & exc_mask );
SKP_assert( idx >= 0 );
SKP_assert( idx <= CNG_BUF_MASK_MAX );
residual[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ), 10 ) );
}
*rand_seed = seed;
}
void SKP_Silk_CNG_Reset(
SKP_Silk_decoder_state *psDec /* I/O Decoder state */
)
{
SKP_int i, NLSF_step_Q15, NLSF_acc_Q15;
NLSF_step_Q15 = SKP_DIV32_16( SKP_int16_MAX, psDec->LPC_order + 1 );
NLSF_acc_Q15 = 0;
for( i = 0; i < psDec->LPC_order; i++ ) {
NLSF_acc_Q15 += NLSF_step_Q15;
psDec->sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15;
}
psDec->sCNG.CNG_smth_Gain_Q16 = 0;
psDec->sCNG.rand_seed = 3176576;
}
/* Updates CNG estimate, and applies the CNG when packet was lost */
void SKP_Silk_CNG(
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int16 signal[], /* I/O Signal */
SKP_int length /* I Length of residual */
)
{
SKP_int i, subfr;
SKP_int32 tmp_32, Gain_Q26, max_Gain_Q16;
SKP_int16 LPC_buf[ MAX_LPC_ORDER ];
SKP_int16 CNG_sig[ MAX_FRAME_LENGTH ];
SKP_Silk_CNG_struct *psCNG;
psCNG = &psDec->sCNG;
if( psDec->fs_kHz != psCNG->fs_kHz ) {
/* Reset state */
SKP_Silk_CNG_Reset( psDec );
psCNG->fs_kHz = psDec->fs_kHz;
}
if( psDec->lossCnt == 0 && psDec->vadFlag == NO_VOICE_ACTIVITY ) {
/* Update CNG parameters */
/* Smoothing of LSF's */
for( i = 0; i < psDec->LPC_order; i++ ) {
psCNG->CNG_smth_NLSF_Q15[ i ] += SKP_SMULWB( psDec->prevNLSF_Q15[ i ] - psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 );
}
/* Find the subframe with the highest gain */
max_Gain_Q16 = 0;
subfr = 0;
for( i = 0; i < NB_SUBFR; i++ ) {
if( psDecCtrl->Gains_Q16[ i ] > max_Gain_Q16 ) {
max_Gain_Q16 = psDecCtrl->Gains_Q16[ i ];
subfr = i;
}
}
/* Update CNG excitation buffer with excitation from this subframe */
SKP_memmove( &psCNG->CNG_exc_buf_Q10[ psDec->subfr_length ], psCNG->CNG_exc_buf_Q10, ( NB_SUBFR - 1 ) * psDec->subfr_length * sizeof( SKP_int32 ) );
SKP_memcpy( psCNG->CNG_exc_buf_Q10, &psDec->exc_Q10[ subfr * psDec->subfr_length ], psDec->subfr_length * sizeof( SKP_int32 ) );
/* Smooth gains */
for( i = 0; i < NB_SUBFR; i++ ) {
psCNG->CNG_smth_Gain_Q16 += SKP_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 );
}
}
/* Add CNG when packet is lost and / or when low speech activity */
if( psDec->lossCnt ) {//|| psDec->vadFlag == NO_VOICE_ACTIVITY ) {
/* Generate CNG excitation */
SKP_Silk_CNG_exc( CNG_sig, psCNG->CNG_exc_buf_Q10,
psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed );
/* Convert CNG NLSF to filter representation */
SKP_Silk_NLSF2A_stable( LPC_buf, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );
Gain_Q26 = ( SKP_int32 )1 << 26; /* 1.0 */
/* Generate CNG signal, by synthesis filtering */
if( psDec->LPC_order == 16 ) {
SKP_Silk_LPC_synthesis_order16( CNG_sig, LPC_buf,
Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length );
} else {
SKP_Silk_LPC_synthesis_filter( CNG_sig, LPC_buf,
Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length, psDec->LPC_order );
}
/* Mix with signal */
for( i = 0; i < length; i++ ) {
tmp_32 = signal[ i ] + CNG_sig[ i ];
signal[ i ] = SKP_SAT16( tmp_32 );
}
} else {
SKP_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( SKP_int32 ) );
}
}

View File

@ -0,0 +1,104 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
#include "SKP_Silk_tuning_parameters.h"
#if HIGH_PASS_INPUT
/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
void SKP_Silk_HP_variable_cutoff_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
SKP_int16 *out, /* O High-pass filtered output signal */
const SKP_int16 *in /* I Input signal */
)
{
SKP_float pitch_freq_Hz, pitch_freq_log, quality, delta_freq, smth_coef, Fc, r;
SKP_int32 B_Q28[ 3 ], A_Q28[ 2 ];
/*********************************************/
/* Estimate low end of pitch frequency range */
/*********************************************/
if( psEnc->sCmn.prev_sigtype == SIG_TYPE_VOICED ) {
/* Difference, in log domain */
pitch_freq_Hz = 1e3f * psEnc->sCmn.fs_kHz / psEnc->sCmn.prevLag;
pitch_freq_log = SKP_Silk_log2( pitch_freq_Hz );
/* Adjustment based on quality */
quality = psEncCtrl->input_quality_bands[ 0 ];
pitch_freq_log -= quality * quality * ( pitch_freq_log - SKP_Silk_log2( VARIABLE_HP_MIN_FREQ ) );
pitch_freq_log += 0.5f * ( 0.6f - quality );
delta_freq = pitch_freq_log - psEnc->variable_HP_smth1;
if( delta_freq < 0.0 ) {
/* Less smoothing for decreasing pitch frequency, to track something close to the minimum */
delta_freq *= 3.0f;
}
/* Limit delta, to reduce impact of outliers */
delta_freq = SKP_LIMIT_float( delta_freq, -VARIABLE_HP_MAX_DELTA_FREQ, VARIABLE_HP_MAX_DELTA_FREQ );
/* Update smoother */
smth_coef = VARIABLE_HP_SMTH_COEF1 * psEnc->speech_activity;
psEnc->variable_HP_smth1 += smth_coef * delta_freq;
}
/* Second smoother */
psEnc->variable_HP_smth2 += VARIABLE_HP_SMTH_COEF2 * ( psEnc->variable_HP_smth1 - psEnc->variable_HP_smth2 );
/* Convert from log scale to Hertz */
psEncCtrl->pitch_freq_low_Hz = ( SKP_float )pow( 2.0f, psEnc->variable_HP_smth2 );
/* Limit frequency range */
psEncCtrl->pitch_freq_low_Hz = SKP_LIMIT_float( psEncCtrl->pitch_freq_low_Hz, VARIABLE_HP_MIN_FREQ, VARIABLE_HP_MAX_FREQ );
/*******************************/
/* Compute filter coefficients */
/*******************************/
/* Compute cut-off frequency, in radians */
Fc = ( SKP_float )( 0.45f * 2.0f * 3.14159265359 * psEncCtrl->pitch_freq_low_Hz / ( 1e3f * psEnc->sCmn.fs_kHz ) );
/* 2nd order ARMA coefficients */
r = 1.0f - 0.92f * Fc;
/* b = r * [1; -2; 1]; */
/* a = [1; -2 * r * (1 - 0.5 * Fc^2); r^2]; */
B_Q28[ 0 ] = SKP_float2int( ( 1 << 28 ) * r );
B_Q28[ 1 ] = SKP_float2int( ( 1 << 28 ) * -2.0f * r );
B_Q28[ 2 ] = B_Q28[ 0 ];
A_Q28[ 0 ] = SKP_float2int( ( 1 << 28 ) * -2.0f * r * ( 1.0f - 0.5f * Fc * Fc ) );
A_Q28[ 1 ] = SKP_float2int( ( 1 << 28 ) * r * r );
/********************/
/* High-pass filter */
/********************/
SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psEnc->sCmn.In_HP_State, out, psEnc->sCmn.frame_length );
}
#endif // HIGH_PASS_INPUT

View File

@ -0,0 +1,278 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/*! \file SKP_Silk_Inlines.h
* \brief SigProcFix_Inlines.h defines inline signal processing functions.
*/
#ifndef _SKP_SILK_FIX_INLINES_H_
#define _SKP_SILK_FIX_INLINES_H_
#include <assert.h>
#ifdef __cplusplus
extern "C"
{
#endif
/* count leading zeros of SKP_int64 */
SKP_INLINE SKP_int32 SKP_Silk_CLZ64(SKP_int64 in)
{
SKP_int32 in_upper;
in_upper = (SKP_int32)SKP_RSHIFT64(in, 32);
if (in_upper == 0) {
/* Search in the lower 32 bits */
return 32 + SKP_Silk_CLZ32( (SKP_int32) in );
} else {
/* Search in the upper 32 bits */
return SKP_Silk_CLZ32( in_upper );
}
}
/* get number of leading zeros and fractional part (the bits right after the leading one */
SKP_INLINE void SKP_Silk_CLZ_FRAC(SKP_int32 in, /* I: input */
SKP_int32 *lz, /* O: number of leading zeros */
SKP_int32 *frac_Q7) /* O: the 7 bits right after the leading one */
{
SKP_int32 lzeros = SKP_Silk_CLZ32(in);
* lz = lzeros;
* frac_Q7 = SKP_ROR32(in, 24 - lzeros) & 0x7f;
}
/* Approximation of square root */
/* Accuracy: < +/- 10% for output values > 15 */
/* < +/- 2.5% for output values > 120 */
SKP_INLINE SKP_int32 SKP_Silk_SQRT_APPROX(SKP_int32 x)
{
SKP_int32 y, lz, frac_Q7;
if( x <= 0 ) {
return 0;
}
SKP_Silk_CLZ_FRAC(x, &lz, &frac_Q7);
if( lz & 1 ) {
y = 32768;
} else {
y = 46214; /* 46214 = sqrt(2) * 32768 */
}
/* get scaling right */
y >>= SKP_RSHIFT(lz, 1);
/* increment using fractional part of input */
y = SKP_SMLAWB(y, y, SKP_SMULBB(213, frac_Q7));
return y;
}
/* returns the number of left shifts before overflow for a 16 bit number (ITU definition with norm(0)=0) */
SKP_INLINE SKP_int32 SKP_Silk_norm16(SKP_int16 a) {
SKP_int32 a32;
/* if ((a == 0) || (a == SKP_int16_MIN)) return(0); */
if ((a << 1) == 0) return(0);
a32 = a;
/* if (a32 < 0) a32 = -a32 - 1; */
a32 ^= SKP_RSHIFT(a32, 31);
return SKP_Silk_CLZ32(a32) - 17;
}
/* returns the number of left shifts before overflow for a 32 bit number (ITU definition with norm(0)=0) */
SKP_INLINE SKP_int32 SKP_Silk_norm32(SKP_int32 a) {
/* if ((a == 0) || (a == SKP_int32_MIN)) return(0); */
if ((a << 1) == 0) return(0);
/* if (a < 0) a = -a - 1; */
a ^= SKP_RSHIFT(a, 31);
return SKP_Silk_CLZ32(a) - 1;
}
/* Divide two int32 values and return result as int32 in a given Q-domain */
SKP_INLINE SKP_int32 SKP_DIV32_varQ( /* O returns a good approximation of "(a32 << Qres) / b32" */
const SKP_int32 a32, /* I numerator (Q0) */
const SKP_int32 b32, /* I denominator (Q0) */
const SKP_int Qres /* I Q-domain of result (>= 0) */
)
{
SKP_int a_headrm, b_headrm, lshift;
SKP_int32 b32_inv, a32_nrm, b32_nrm, result;
SKP_assert( b32 != 0 );
SKP_assert( Qres >= 0 );
/* Compute number of bits head room and normalize inputs */
a_headrm = SKP_Silk_CLZ32( SKP_abs(a32) ) - 1;
a32_nrm = SKP_LSHIFT(a32, a_headrm); /* Q: a_headrm */
b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1;
b32_nrm = SKP_LSHIFT(b32, b_headrm); /* Q: b_headrm */
/* Inverse of b32, with 14 bits of precision */
b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */
/* First approximation */
result = SKP_SMULWB(a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */
/* Compute residual by subtracting product of denominator and first approximation */
a32_nrm -= SKP_LSHIFT_ovflw( SKP_SMMUL(b32_nrm, result), 3 ); /* Q: a_headrm */
/* Refinement */
result = SKP_SMLAWB(result, a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */
/* Convert to Qres domain */
lshift = 29 + a_headrm - b_headrm - Qres;
if( lshift <= 0 ) {
return SKP_LSHIFT_SAT32(result, -lshift);
} else {
if( lshift < 32){
return SKP_RSHIFT(result, lshift);
} else {
/* Avoid undefined result */
return 0;
}
}
}
/* Invert int32 value and return result as int32 in a given Q-domain */
SKP_INLINE SKP_int32 SKP_INVERSE32_varQ( /* O returns a good approximation of "(1 << Qres) / b32" */
const SKP_int32 b32, /* I denominator (Q0) */
const SKP_int Qres /* I Q-domain of result (> 0) */
)
{
SKP_int b_headrm, lshift;
SKP_int32 b32_inv, b32_nrm, err_Q32, result;
SKP_assert( b32 != 0 );
SKP_assert( b32 != SKP_int32_MIN ); /* SKP_int32_MIN is not handled by SKP_abs */
SKP_assert( Qres > 0 );
/* Compute number of bits head room and normalize input */
b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1;
b32_nrm = SKP_LSHIFT(b32, b_headrm); /* Q: b_headrm */
/* Inverse of b32, with 14 bits of precision */
b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */
/* First approximation */
result = SKP_LSHIFT(b32_inv, 16); /* Q: 61 - b_headrm */
/* Compute residual by subtracting product of denominator and first approximation from one */
err_Q32 = SKP_LSHIFT_ovflw( -SKP_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */
/* Refinement */
result = SKP_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */
/* Convert to Qres domain */
lshift = 61 - b_headrm - Qres;
if( lshift <= 0 ) {
return SKP_LSHIFT_SAT32(result, -lshift);
} else {
if( lshift < 32){
return SKP_RSHIFT(result, lshift);
}else{
/* Avoid undefined result */
return 0;
}
}
}
#define SKP_SIN_APPROX_CONST0 (1073735400)
#define SKP_SIN_APPROX_CONST1 (-82778932)
#define SKP_SIN_APPROX_CONST2 (1059577)
#define SKP_SIN_APPROX_CONST3 (-5013)
/* Sine approximation; an input of 65536 corresponds to 2 * pi */
/* Uses polynomial expansion of the input to the power 0, 2, 4 and 6 */
/* The relative error is below 1e-5 */
SKP_INLINE SKP_int32 SKP_Silk_SIN_APPROX_Q24( /* O returns approximately 2^24 * sin(x * 2 * pi / 65536) */
SKP_int32 x
)
{
SKP_int y_Q30;
/* Keep only bottom 16 bits (the function repeats itself with period 65536) */
x &= 65535;
/* Split range in four quadrants */
if( x <= 32768 ) {
if( x < 16384 ) {
/* Return cos(pi/2 - x) */
x = 16384 - x;
} else {
/* Return cos(x - pi/2) */
x -= 16384;
}
if( x < 1100 ) {
/* Special case: high accuracy */
return SKP_SMLAWB( 1 << 24, SKP_MUL( x, x ), -5053 );
}
x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x ); /* contains x^2 in Q20 */
y_Q30 = SKP_SMLAWB( SKP_SIN_APPROX_CONST2, x, SKP_SIN_APPROX_CONST3 );
y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST1, x, y_Q30 );
y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST0 + 66, x, y_Q30 );
} else {
if( x < 49152 ) {
/* Return -cos(3*pi/2 - x) */
x = 49152 - x;
} else {
/* Return -cos(x - 3*pi/2) */
x -= 49152;
}
if( x < 1100 ) {
/* Special case: high accuracy */
return SKP_SMLAWB( -1 << 24, SKP_MUL( x, x ), 5053 );
}
x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x ); /* contains x^2 in Q20 */
y_Q30 = SKP_SMLAWB( -SKP_SIN_APPROX_CONST2, x, -SKP_SIN_APPROX_CONST3 );
y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST1, x, y_Q30 );
y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST0, x, y_Q30 );
}
return SKP_RSHIFT_ROUND( y_Q30, 6 );
}
/* Cosine approximation; an input of 65536 corresponds to 2 * pi */
/* The relative error is below 1e-5 */
SKP_INLINE SKP_int32 SKP_Silk_COS_APPROX_Q24( /* O returns approximately 2^24 * cos(x * 2 * pi / 65536) */
SKP_int32 x
)
{
return SKP_Silk_SIN_APPROX_Q24( x + 16384 );
}
#ifdef __cplusplus
}
#endif
#endif /*_SKP_SILK_FIX_INLINES_H_*/

View File

@ -0,0 +1,40 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/* Resets LBRR buffer, used if packet size changes */
void SKP_Silk_LBRR_reset(
SKP_Silk_encoder_state *psEncC /* I/O state */
)
{
SKP_int i;
for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
psEncC->LBRR_buffer[ i ].usage = SKP_SILK_NO_LBRR;
}
}

View File

@ -0,0 +1,238 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include <stdlib.h>
#include "SKP_Silk_main_FLP.h"
/*******************************************/
/* LPC analysis filter */
/* NB! State is kept internally and the */
/* filter always starts with zero state */
/* first Order output samples are not set */
/*******************************************/
void SKP_Silk_LPC_analysis_filter_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length, /* I Length of input signal */
const SKP_int Order /* I LPC order */
)
{
SKP_assert( Order <= length );
switch( Order ) {
case 6:
SKP_Silk_LPC_analysis_filter6_FLP( r_LPC, PredCoef, s, length );
break;
case 8:
SKP_Silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, length );
break;
case 10:
SKP_Silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length );
break;
case 12:
SKP_Silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length );
break;
case 16:
SKP_Silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length );
break;
default:
SKP_assert( 0 );
break;
}
/* Set first LPC Order samples to zero instead of undefined */
SKP_memset( r_LPC, 0, Order * sizeof( SKP_float ) );
}
/* 16th order LPC analysis filter, does not write first 16 samples */
void SKP_Silk_LPC_analysis_filter16_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length /* I Length of input signal */
)
{
SKP_int ix = 16;
SKP_float LPC_pred;
const SKP_float *s_ptr;
for ( ; ix < length; ix++) {
s_ptr = &s[ix - 1];
/* short-term prediction */
LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
s_ptr[-1] * PredCoef[ 1 ] +
s_ptr[-2] * PredCoef[ 2 ] +
s_ptr[-3] * PredCoef[ 3 ] +
s_ptr[-4] * PredCoef[ 4 ] +
s_ptr[-5] * PredCoef[ 5 ] +
s_ptr[-6] * PredCoef[ 6 ] +
s_ptr[-7] * PredCoef[ 7 ] +
s_ptr[-8] * PredCoef[ 8 ] +
s_ptr[-9] * PredCoef[ 9 ] +
s_ptr[-10] * PredCoef[ 10 ] +
s_ptr[-11] * PredCoef[ 11 ] +
s_ptr[-12] * PredCoef[ 12 ] +
s_ptr[-13] * PredCoef[ 13 ] +
s_ptr[-14] * PredCoef[ 14 ] +
s_ptr[-15] * PredCoef[ 15 ];
/* prediction error */
r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
}
}
/* 12th order LPC analysis filter, does not write first 12 samples */
void SKP_Silk_LPC_analysis_filter12_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length /* I Length of input signal */
)
{
SKP_int ix = 12;
SKP_float LPC_pred;
const SKP_float *s_ptr;
for ( ; ix < length; ix++) {
s_ptr = &s[ix - 1];
/* short-term prediction */
LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
s_ptr[-1] * PredCoef[ 1 ] +
s_ptr[-2] * PredCoef[ 2 ] +
s_ptr[-3] * PredCoef[ 3 ] +
s_ptr[-4] * PredCoef[ 4 ] +
s_ptr[-5] * PredCoef[ 5 ] +
s_ptr[-6] * PredCoef[ 6 ] +
s_ptr[-7] * PredCoef[ 7 ] +
s_ptr[-8] * PredCoef[ 8 ] +
s_ptr[-9] * PredCoef[ 9 ] +
s_ptr[-10] * PredCoef[ 10 ] +
s_ptr[-11] * PredCoef[ 11 ];
/* prediction error */
r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
}
}
/* 10th order LPC analysis filter, does not write first 10 samples */
void SKP_Silk_LPC_analysis_filter10_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length /* I Length of input signal */
)
{
SKP_int ix = 10;
SKP_float LPC_pred;
const SKP_float *s_ptr;
for ( ; ix < length; ix++) {
s_ptr = &s[ix - 1];
/* short-term prediction */
LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
s_ptr[-1] * PredCoef[ 1 ] +
s_ptr[-2] * PredCoef[ 2 ] +
s_ptr[-3] * PredCoef[ 3 ] +
s_ptr[-4] * PredCoef[ 4 ] +
s_ptr[-5] * PredCoef[ 5 ] +
s_ptr[-6] * PredCoef[ 6 ] +
s_ptr[-7] * PredCoef[ 7 ] +
s_ptr[-8] * PredCoef[ 8 ] +
s_ptr[-9] * PredCoef[ 9 ];
/* prediction error */
r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
}
}
/* 8th order LPC analysis filter, does not write first 8 samples */
void SKP_Silk_LPC_analysis_filter8_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length /* I Length of input signal */
)
{
SKP_int ix = 8;
SKP_float LPC_pred;
const SKP_float *s_ptr;
for ( ; ix < length; ix++) {
s_ptr = &s[ix - 1];
/* short-term prediction */
LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
s_ptr[ -1 ] * PredCoef[ 1 ] +
s_ptr[ -2 ] * PredCoef[ 2 ] +
s_ptr[ -3 ] * PredCoef[ 3 ] +
s_ptr[ -4 ] * PredCoef[ 4 ] +
s_ptr[ -5 ] * PredCoef[ 5 ] +
s_ptr[ -6 ] * PredCoef[ 6 ] +
s_ptr[ -7 ] * PredCoef[ 7 ];
/* prediction error */
r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
}
}
/* 6th order LPC analysis filter, does not write first 6 samples */
void SKP_Silk_LPC_analysis_filter6_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length /* I Length of input signal */
)
{
SKP_int ix = 6;
SKP_float LPC_pred;
const SKP_float *s_ptr;
for ( ; ix < length; ix++) {
s_ptr = &s[ix - 1];
/* short-term prediction */
LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
s_ptr[ -1 ] * PredCoef[ 1 ] +
s_ptr[ -2 ] * PredCoef[ 2 ] +
s_ptr[ -3 ] * PredCoef[ 3 ] +
s_ptr[ -4 ] * PredCoef[ 4 ] +
s_ptr[ -5 ] * PredCoef[ 5 ];
/* prediction error */
r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
}
}

View File

@ -0,0 +1,153 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_LPC_inverse_pred_gain.c *
* *
* Compute inverse of LPC prediction gain, and *
* test if LPC coefficients are stable (all poles within unit circle) *
* *
* Copyright 2008 (c), Skype Limited *
* */
#include "SKP_Silk_SigProc_FIX.h"
#define QA 16
#define A_LIMIT SKP_FIX_CONST( 0.99975, QA )
/* Compute inverse of LPC prediction gain, and */
/* test if LPC coefficients are stable (all poles within unit circle) */
static SKP_int LPC_inverse_pred_gain_QA( /* O: Returns 1 if unstable, otherwise 0 */
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
SKP_int32 A_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ],
/* I: Prediction coefficients */
const SKP_int order /* I: Prediction order */
)
{
SKP_int k, n, headrm;
SKP_int32 rc_Q31, rc_mult1_Q30, rc_mult2_Q16, tmp_QA;
SKP_int32 *Aold_QA, *Anew_QA;
Anew_QA = A_QA[ order & 1 ];
*invGain_Q30 = ( 1 << 30 );
for( k = order - 1; k > 0; k-- ) {
/* Check for stability */
if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {
return 1;
}
/* Set RC equal to negated AR coef */
rc_Q31 = -SKP_LSHIFT( Anew_QA[ k ], 31 - QA );
/* rc_mult1_Q30 range: [ 1 : 2^30-1 ] */
rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );
SKP_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */
SKP_assert( rc_mult1_Q30 < ( 1 << 30 ) );
/* rc_mult2_Q16 range: [ 2^16 : SKP_int32_MAX ] */
rc_mult2_Q16 = SKP_INVERSE32_varQ( rc_mult1_Q30, 46 ); /* 16 = 46 - 30 */
/* Update inverse gain */
/* invGain_Q30 range: [ 0 : 2^30 ] */
*invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );
SKP_assert( *invGain_Q30 >= 0 );
SKP_assert( *invGain_Q30 <= ( 1 << 30 ) );
/* Swap pointers */
Aold_QA = Anew_QA;
Anew_QA = A_QA[ k & 1 ];
/* Update AR coefficient */
headrm = SKP_Silk_CLZ32( rc_mult2_Q16 ) - 1;
rc_mult2_Q16 = SKP_LSHIFT( rc_mult2_Q16, headrm ); /* Q: 16 + headrm */
for( n = 0; n < k; n++ ) {
tmp_QA = Aold_QA[ n ] - SKP_LSHIFT( SKP_SMMUL( Aold_QA[ k - n - 1 ], rc_Q31 ), 1 );
Anew_QA[ n ] = SKP_LSHIFT( SKP_SMMUL( tmp_QA, rc_mult2_Q16 ), 16 - headrm );
}
}
/* Check for stability */
if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {
return 1;
}
/* Set RC equal to negated AR coef */
rc_Q31 = -SKP_LSHIFT( Anew_QA[ 0 ], 31 - QA );
/* Range: [ 1 : 2^30 ] */
rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );
/* Update inverse gain */
/* Range: [ 0 : 2^30 ] */
*invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );
SKP_assert( *invGain_Q30 >= 0 );
SKP_assert( *invGain_Q30 <= 1<<30 );
return 0;
}
/* For input in Q12 domain */
SKP_int SKP_Silk_LPC_inverse_pred_gain( /* O: Returns 1 if unstable, otherwise 0 */
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
const SKP_int16 *A_Q12, /* I: Prediction coefficients, Q12 [order] */
const SKP_int order /* I: Prediction order */
)
{
SKP_int k;
SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ];
SKP_int32 *Anew_QA;
Anew_QA = Atmp_QA[ order & 1 ];
/* Increase Q domain of the AR coefficients */
for( k = 0; k < order; k++ ) {
Anew_QA[ k ] = SKP_LSHIFT( (SKP_int32)A_Q12[ k ], QA - 12 );
}
return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
}
/* For input in Q24 domain */
SKP_int SKP_Silk_LPC_inverse_pred_gain_Q24( /* O: Returns 1 if unstable, otherwise 0 */
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
const SKP_int32 *A_Q24, /* I: Prediction coefficients, Q24 [order] */
const SKP_int order /* I: Prediction order */
)
{
SKP_int k;
SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ];
SKP_int32 *Anew_QA;
Anew_QA = Atmp_QA[ order & 1 ];
/* Increase Q domain of the AR coefficients */
for( k = 0; k < order; k++ ) {
Anew_QA[ k ] = SKP_RSHIFT_ROUND( A_Q24[ k ], 24 - QA );
}
return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
}

View File

@ -0,0 +1,81 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_LPC_inverse_pred_gain.c *
* *
* compute inverse of LPC prediction gain, and *
* test if LPC coefficients are stable (all poles within unit circle) *
* *
* Copyright 2008 (c), Skype Limited *
* */
#include "SKP_Silk_SigProc_FIX.h"
#include "SKP_Silk_SigProc_FLP.h"
#define RC_THRESHOLD 0.9999f
/* compute inverse of LPC prediction gain, and */
/* test if LPC coefficients are stable (all poles within unit circle) */
/* this code is based on SKP_Silk_a2k_FLP() */
SKP_int SKP_Silk_LPC_inverse_pred_gain_FLP( /* O: returns 1 if unstable, otherwise 0 */
SKP_float *invGain, /* O: inverse prediction gain, energy domain */
const SKP_float *A, /* I: prediction coefficients [order] */
SKP_int32 order /* I: prediction order */
)
{
SKP_int k, n;
double rc, rc_mult1, rc_mult2;
SKP_float Atmp[ 2 ][ SKP_Silk_MAX_ORDER_LPC ];
SKP_float *Aold, *Anew;
Anew = Atmp[ order & 1 ];
SKP_memcpy( Anew, A, order * sizeof(SKP_float) );
*invGain = 1.0f;
for( k = order - 1; k > 0; k-- ) {
rc = -Anew[ k ];
if (rc > RC_THRESHOLD || rc < -RC_THRESHOLD) {
return 1;
}
rc_mult1 = 1.0f - rc * rc;
rc_mult2 = 1.0f / rc_mult1;
*invGain *= (SKP_float)rc_mult1;
/* swap pointers */
Aold = Anew;
Anew = Atmp[ k & 1 ];
for( n = 0; n < k; n++ ) {
Anew[ n ] = (SKP_float)( ( Aold[ n ] - Aold[ k - n - 1 ] * rc ) * rc_mult2 );
}
}
rc = -Anew[ 0 ];
if ( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
return 1;
}
rc_mult1 = 1.0f - rc * rc;
*invGain *= (SKP_float)rc_mult1;
return 0;
}

View File

@ -0,0 +1,84 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_LPC_synthesis_filter.c *
* Coefficients are in Q12 *
* *
* even order AR filter *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* even order AR filter */
void SKP_Silk_LPC_synthesis_filter(
const SKP_int16 *in, /* I: excitation signal */
const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */
const SKP_int32 Gain_Q26, /* I: gain */
SKP_int32 *S, /* I/O: state vector [Order] */
SKP_int16 *out, /* O: output signal */
const SKP_int32 len, /* I: signal length */
const SKP_int Order /* I: filter order, must be even */
)
{
SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
SKP_int32 SA, SB, out32_Q10, out32;
/* Order must be even */
SKP_assert( 2 * Order_half == Order );
/* S[] values are in Q14 */
for( k = 0; k < len; k++ ) {
SA = S[ Order - 1 ];
out32_Q10 = 0;
for( j = 0; j < ( Order_half - 1 ); j++ ) {
idx = SKP_SMULBB( 2, j ) + 1;
SB = S[ Order - 1 - idx ];
S[ Order - 1 - idx ] = SA;
out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ ( j << 1 ) ] );
out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ ( j << 1 ) + 1 ] );
SA = S[ Order - 2 - idx ];
S[ Order - 2 - idx ] = SB;
}
/* unrolled loop: epilog */
SB = S[ 0 ];
S[ 0 ] = SA;
out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ Order - 2 ] );
out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ Order - 1 ] );
/* apply gain to excitation signal and add to prediction */
out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );
/* scale to Q0 */
out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );
/* saturate output */
out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
/* move result into delay line */
S[ Order - 1 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
}
}

View File

@ -0,0 +1,122 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_LPC_synthesis_order16.c *
* Coefficients are in Q12 *
* *
* 16th order AR filter *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* 16th order AR filter */
void SKP_Silk_LPC_synthesis_order16(const SKP_int16 *in, /* I: excitation signal */
const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */
const SKP_int32 Gain_Q26, /* I: gain */
SKP_int32 *S, /* I/O: state vector [16] */
SKP_int16 *out, /* O: output signal */
const SKP_int32 len /* I: signal length, must be multiple of 16 */
)
{
SKP_int k;
SKP_int32 SA, SB, out32_Q10, out32;
for( k = 0; k < len; k++ ) {
/* unrolled loop: prolog */
/* multiply-add two prediction coefficients per iteration */
SA = S[ 15 ];
SB = S[ 14 ];
S[ 14 ] = SA;
out32_Q10 = SKP_SMULWB( SA, A_Q12[ 0 ] );
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 1 ] );
SA = S[ 13 ];
S[ 13 ] = SB;
/* unrolled loop: main loop */
SB = S[ 12 ];
S[ 12 ] = SA;
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 2 ] );
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 3 ] );
SA = S[ 11 ];
S[ 11 ] = SB;
SB = S[ 10 ];
S[ 10 ] = SA;
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 4 ] );
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 5 ] );
SA = S[ 9 ];
S[ 9 ] = SB;
SB = S[ 8 ];
S[ 8 ] = SA;
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 6 ] );
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 7 ] );
SA = S[ 7 ];
S[ 7 ] = SB;
SB = S[ 6 ];
S[ 6 ] = SA;
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 8 ] );
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 9 ] );
SA = S[ 5 ];
S[ 5 ] = SB;
SB = S[ 4 ];
S[ 4 ] = SA;
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 10 ] );
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 11 ] );
SA = S[ 3 ];
S[ 3 ] = SB;
SB = S[ 2 ];
S[ 2 ] = SA;
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 12 ] );
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 13 ] );
SA = S[ 1 ];
S[ 1 ] = SB;
/* unrolled loop: epilog */
SB = S[ 0 ];
S[ 0 ] = SA;
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 14 ] );
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 15 ] );
/* unrolled loop: end */
/* apply gain to excitation signal and add to prediction */
out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );
/* scale to Q0 */
out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );
/* saturate output */
out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
/* move result into delay line */
S[ 15 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
}
}

View File

@ -0,0 +1,194 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/*
Elliptic/Cauer filters designed with 0.1 dB passband ripple,
80 dB minimum stopband attenuation, and
[0.95 : 0.15 : 0.35] normalized cut off frequencies.
*/
#include "SKP_Silk_main.h"
#if SWITCH_TRANSITION_FILTERING
/* Helper function, that interpolates the filter taps */
SKP_INLINE void SKP_Silk_LP_interpolate_filter_taps(
SKP_int32 B_Q28[ TRANSITION_NB ],
SKP_int32 A_Q28[ TRANSITION_NA ],
const SKP_int ind,
const SKP_int32 fac_Q16
)
{
SKP_int nb, na;
if( ind < TRANSITION_INT_NUM - 1 ) {
if( fac_Q16 > 0 ) {
if( fac_Q16 == SKP_SAT16( fac_Q16 ) ) { /* fac_Q16 is in range of a 16-bit int */
/* Piece-wise linear interpolation of B and A */
for( nb = 0; nb < TRANSITION_NB; nb++ ) {
B_Q28[ nb ] = SKP_SMLAWB(
SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ],
SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ],
fac_Q16 );
}
for( na = 0; na < TRANSITION_NA; na++ ) {
A_Q28[ na ] = SKP_SMLAWB(
SKP_Silk_Transition_LP_A_Q28[ ind ][ na ],
SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
SKP_Silk_Transition_LP_A_Q28[ ind ][ na ],
fac_Q16 );
}
} else if( fac_Q16 == ( 1 << 15 ) ) { /* Neither fac_Q16 nor ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */
/* Piece-wise linear interpolation of B and A */
for( nb = 0; nb < TRANSITION_NB; nb++ ) {
B_Q28[ nb ] = SKP_RSHIFT(
SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ] +
SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
1 );
}
for( na = 0; na < TRANSITION_NA; na++ ) {
A_Q28[ na ] = SKP_RSHIFT(
SKP_Silk_Transition_LP_A_Q28[ ind ][ na ] +
SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
1 );
}
} else { /* ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */
SKP_assert( ( ( 1 << 16 ) - fac_Q16 ) == SKP_SAT16( ( ( 1 << 16 ) - fac_Q16) ) );
/* Piece-wise linear interpolation of B and A */
for( nb = 0; nb < TRANSITION_NB; nb++ ) {
B_Q28[ nb ] = SKP_SMLAWB(
SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ] -
SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
( 1 << 16 ) - fac_Q16 );
}
for( na = 0; na < TRANSITION_NA; na++ ) {
A_Q28[ na ] = SKP_SMLAWB(
SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
SKP_Silk_Transition_LP_A_Q28[ ind ][ na ] -
SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
( 1 << 16 ) - fac_Q16 );
}
}
} else {
SKP_memcpy( B_Q28, SKP_Silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( SKP_int32 ) );
SKP_memcpy( A_Q28, SKP_Silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( SKP_int32 ) );
}
} else {
SKP_memcpy( B_Q28, SKP_Silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( SKP_int32 ) );
SKP_memcpy( A_Q28, SKP_Silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( SKP_int32 ) );
}
}
/* Low-pass filter with variable cutoff frequency based on */
/* piece-wise linear interpolation between elliptic filters */
/* Start by setting psEncC->transition_frame_no = 1; */
/* Deactivate by setting psEncC->transition_frame_no = 0; */
void SKP_Silk_LP_variable_cutoff(
SKP_Silk_LP_state *psLP, /* I/O LP filter state */
SKP_int16 *out, /* O Low-pass filtered output signal */
const SKP_int16 *in, /* I Input signal */
const SKP_int frame_length /* I Frame length */
)
{
SKP_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0;
SKP_int ind = 0;
SKP_assert( psLP->transition_frame_no >= 0 );
SKP_assert( ( ( ( psLP->transition_frame_no <= TRANSITION_FRAMES_DOWN ) && ( psLP->mode == 0 ) ) ||
( ( psLP->transition_frame_no <= TRANSITION_FRAMES_UP ) && ( psLP->mode == 1 ) ) ) );
/* Interpolate filter coefficients if needed */
if( psLP->transition_frame_no > 0 ) {
if( psLP->mode == 0 ) {
if( psLP->transition_frame_no < TRANSITION_FRAMES_DOWN ) {
/* Calculate index and interpolation factor for interpolation */
#if( TRANSITION_INT_STEPS_DOWN == 32 )
fac_Q16 = SKP_LSHIFT( psLP->transition_frame_no, 16 - 5 );
#else
fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( psLP->transition_frame_no, 16 ), TRANSITION_INT_STEPS_DOWN );
#endif
ind = SKP_RSHIFT( fac_Q16, 16 );
fac_Q16 -= SKP_LSHIFT( ind, 16 );
SKP_assert( ind >= 0 );
SKP_assert( ind < TRANSITION_INT_NUM );
/* Interpolate filter coefficients */
SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );
/* Increment transition frame number for next frame */
psLP->transition_frame_no++;
} else {
SKP_assert( psLP->transition_frame_no == TRANSITION_FRAMES_DOWN );
/* End of transition phase */
SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, TRANSITION_INT_NUM - 1, 0 );
}
} else {
SKP_assert( psLP->mode == 1 );
if( psLP->transition_frame_no < TRANSITION_FRAMES_UP ) {
/* Calculate index and interpolation factor for interpolation */
#if( TRANSITION_INT_STEPS_UP == 64 )
fac_Q16 = SKP_LSHIFT( TRANSITION_FRAMES_UP - psLP->transition_frame_no, 16 - 6 );
#else
fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( TRANSITION_FRAMES_UP - psLP->transition_frame_no, 16 ), TRANSITION_INT_STEPS_UP );
#endif
ind = SKP_RSHIFT( fac_Q16, 16 );
fac_Q16 -= SKP_LSHIFT( ind, 16 );
SKP_assert( ind >= 0 );
SKP_assert( ind < TRANSITION_INT_NUM );
/* Interpolate filter coefficients */
SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );
/* Increment transition frame number for next frame */
psLP->transition_frame_no++;
} else {
SKP_assert( psLP->transition_frame_no == TRANSITION_FRAMES_UP );
/* End of transition phase */
SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, 0, 0 );
}
}
}
if( psLP->transition_frame_no > 0 ) {
/* ARMA low-pass filtering */
SKP_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );
SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psLP->In_LP_State, out, frame_length );
} else {
/* Instead of using the filter, copy input directly to output */
SKP_memcpy( out, in, frame_length * sizeof( SKP_int16 ) );
}
}
#endif

View File

@ -0,0 +1,65 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_SigProc_FIX.h"
// Q12 values (even)
const SKP_int SKP_Silk_LSFCosTab_FIX_Q12[LSF_COS_TAB_SZ_FIX + 1] = {
8192, 8190, 8182, 8170,
8152, 8130, 8104, 8072,
8034, 7994, 7946, 7896,
7840, 7778, 7714, 7644,
7568, 7490, 7406, 7318,
7226, 7128, 7026, 6922,
6812, 6698, 6580, 6458,
6332, 6204, 6070, 5934,
5792, 5648, 5502, 5352,
5198, 5040, 4880, 4718,
4552, 4382, 4212, 4038,
3862, 3684, 3502, 3320,
3136, 2948, 2760, 2570,
2378, 2186, 1990, 1794,
1598, 1400, 1202, 1002,
802, 602, 402, 202,
0, -202, -402, -602,
-802, -1002, -1202, -1400,
-1598, -1794, -1990, -2186,
-2378, -2570, -2760, -2948,
-3136, -3320, -3502, -3684,
-3862, -4038, -4212, -4382,
-4552, -4718, -4880, -5040,
-5198, -5352, -5502, -5648,
-5792, -5934, -6070, -6204,
-6332, -6458, -6580, -6698,
-6812, -6922, -7026, -7128,
-7226, -7318, -7406, -7490,
-7568, -7644, -7714, -7778,
-7840, -7896, -7946, -7994,
-8034, -8072, -8104, -8130,
-8152, -8170, -8182, -8190,
-8192
};

View File

@ -0,0 +1,70 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
void SKP_Silk_LTP_analysis_filter_FLP(
SKP_float *LTP_res, /* O LTP res NB_SUBFR*(pre_lgth+subfr_lngth) */
const SKP_float *x, /* I Input signal, with preceeding samples */
const SKP_float B[ LTP_ORDER * NB_SUBFR ], /* I LTP coefficients for each subframe */
const SKP_int pitchL[ NB_SUBFR ], /* I Pitch lags */
const SKP_float invGains[ NB_SUBFR ], /* I Inverse quantization gains */
const SKP_int subfr_length, /* I Length of each subframe */
const SKP_int pre_length /* I Preceeding samples for each subframe */
)
{
const SKP_float *x_ptr, *x_lag_ptr;
SKP_float Btmp[ LTP_ORDER ];
SKP_float *LTP_res_ptr;
SKP_float inv_gain;
SKP_int k, i, j;
x_ptr = x;
LTP_res_ptr = LTP_res;
for( k = 0; k < NB_SUBFR; k++ ) {
x_lag_ptr = x_ptr - pitchL[ k ];
inv_gain = invGains[ k ];
for( i = 0; i < LTP_ORDER; i++ ) {
Btmp[ i ] = B[ k * LTP_ORDER + i ];
}
/* LTP analysis FIR filter */
for( i = 0; i < subfr_length + pre_length; i++ ) {
LTP_res_ptr[ i ] = x_ptr[ i ];
/* Subtract long-term prediction */
for( j = 0; j < LTP_ORDER; j++ ) {
LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ];
}
LTP_res_ptr[ i ] *= inv_gain;
x_lag_ptr++;
}
/* Update pointers */
LTP_res_ptr += subfr_length + pre_length;
x_ptr += subfr_length;
}
}

View File

@ -0,0 +1,85 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
#define NB_THRESHOLDS 11
/* Table containing trained thresholds for LTP scaling */
static const SKP_float LTPScaleThresholds[ NB_THRESHOLDS ] =
{
0.95f, 0.8f, 0.50f, 0.400f, 0.3f, 0.2f,
0.15f, 0.1f, 0.08f, 0.075f, 0.0f
};
void SKP_Silk_LTP_scale_ctrl_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl /* I/O Encoder control FLP */
)
{
SKP_int round_loss, frames_per_packet;
SKP_float g_out, g_limit, thrld1, thrld2;
/* 1st order high-pass filter */
//g_HP(n) = g(n) - g(n-1) + 0.5 * g_HP(n-1); // tune the 0.5: higher means longer impact of jump
psEnc->HPLTPredCodGain = SKP_max_float( psEncCtrl->LTPredCodGain - psEnc->prevLTPredCodGain, 0.0f )
+ 0.5f * psEnc->HPLTPredCodGain;
psEnc->prevLTPredCodGain = psEncCtrl->LTPredCodGain;
/* Combine input and filtered input */
g_out = 0.5f * psEncCtrl->LTPredCodGain + ( 1.0f - 0.5f ) * psEnc->HPLTPredCodGain;
g_limit = SKP_sigmoid( 0.5f * ( g_out - 6 ) );
/* Default is minimum scaling */
psEncCtrl->sCmn.LTP_scaleIndex = 0;
/* Round the loss measure to whole pct */
round_loss = ( SKP_int )( psEnc->sCmn.PacketLoss_perc );
round_loss = SKP_max( 0, round_loss );
/* Only scale if first frame in packet 0% */
if( psEnc->sCmn.nFramesInPayloadBuf == 0 ){
frames_per_packet = psEnc->sCmn.PacketSize_ms / FRAME_LENGTH_MS;
round_loss += ( frames_per_packet - 1 );
thrld1 = LTPScaleThresholds[ SKP_min_int( round_loss, NB_THRESHOLDS - 1 ) ];
thrld2 = LTPScaleThresholds[ SKP_min_int( round_loss + 1, NB_THRESHOLDS - 1 ) ];
if( g_limit > thrld1 ) {
/* High Scaling */
psEncCtrl->sCmn.LTP_scaleIndex = 2;
} else if( g_limit > thrld2 ) {
/* Middle Scaling */
psEncCtrl->sCmn.LTP_scaleIndex = 1;
}
}
psEncCtrl->LTP_scale = ( SKP_float)SKP_Silk_LTPScales_table_Q14[ psEncCtrl->sCmn.LTP_scaleIndex ] / 16384.0f;
}

View File

@ -0,0 +1,116 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_MA.c *
* *
* Variable order MA filter *
* *
* Copyright 2006 (c), Skype Limited *
* Date: 060221 *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* Variable order MA prediction error filter */
void SKP_Silk_MA_Prediction(
const SKP_int16 *in, /* I: Input signal */
const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
SKP_int32 *S, /* I/O: State vector [order] */
SKP_int16 *out, /* O: Output signal */
const SKP_int32 len, /* I: Signal length */
const SKP_int32 order /* I: Filter order */
)
{
SKP_int k, d, in16;
SKP_int32 out32;
for( k = 0; k < len; k++ ) {
in16 = in[ k ];
out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];
out32 = SKP_RSHIFT_ROUND( out32, 12 );
for( d = 0; d < order - 1; d++ ) {
S[ d ] = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B[ d ] );
}
S[ order - 1 ] = SKP_SMULBB( in16, B[ order - 1 ] );
/* Limit */
out[ k ] = (SKP_int16)SKP_SAT16( out32 );
}
}
void SKP_Silk_LPC_analysis_filter(
const SKP_int16 *in, /* I: Input signal */
const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
SKP_int16 *S, /* I/O: State vector [order] */
SKP_int16 *out, /* O: Output signal */
const SKP_int32 len, /* I: Signal length */
const SKP_int32 Order /* I: Filter order */
)
{
SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
SKP_int32 out32_Q12, out32;
SKP_int16 SA, SB;
/* Order must be even */
SKP_assert( 2 * Order_half == Order );
/* S[] values are in Q0 */
for( k = 0; k < len; k++ ) {
SA = S[ 0 ];
out32_Q12 = 0;
for( j = 0; j < ( Order_half - 1 ); j++ ) {
idx = SKP_SMULBB( 2, j ) + 1;
/* Multiply-add two prediction coefficients for each loop */
SB = S[ idx ];
S[ idx ] = SA;
out32_Q12 = SKP_SMLABB( out32_Q12, SA, B[ idx - 1 ] );
out32_Q12 = SKP_SMLABB( out32_Q12, SB, B[ idx ] );
SA = S[ idx + 1 ];
S[ idx + 1 ] = SB;
}
/* Unrolled loop: epilog */
SB = S[ Order - 1 ];
S[ Order - 1 ] = SA;
out32_Q12 = SKP_SMLABB( out32_Q12, SA, B[ Order - 2 ] );
out32_Q12 = SKP_SMLABB( out32_Q12, SB, B[ Order - 1 ] );
/* Subtract prediction */
out32_Q12 = SKP_SUB_SAT32( SKP_LSHIFT( (SKP_int32)in[ k ], 12 ), out32_Q12 );
/* Scale to Q0 */
out32 = SKP_RSHIFT_ROUND( out32_Q12, 12 );
/* Saturate output */
out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
/* Move input line */
S[ 0 ] = in[ k ];
}
}

View File

@ -0,0 +1,151 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* conversion between prediction filter coefficients and LSFs */
/* order should be even */
/* a piecewise linear approximation maps LSF <-> cos(LSF) */
/* therefore the result is not accurate LSFs, but the two */
/* function are accurate inverses of each other */
#include "SKP_Silk_SigProc_FIX.h"
/* helper function for NLSF2A(..) */
SKP_INLINE void SKP_Silk_NLSF2A_find_poly(
SKP_int32 *out, /* o intermediate polynomial, Q20 */
const SKP_int32 *cLSF, /* i vector of interleaved 2*cos(LSFs), Q20 */
SKP_int dd /* i polynomial order (= 1/2 * filter order) */
)
{
SKP_int k, n;
SKP_int32 ftmp;
out[0] = SKP_LSHIFT( 1, 20 );
out[1] = -cLSF[0];
for( k = 1; k < dd; k++ ) {
ftmp = cLSF[2*k]; // Q20
out[k+1] = SKP_LSHIFT( out[k-1], 1 ) - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[k] ), 20 );
for( n = k; n > 1; n-- ) {
out[n] += out[n-2] - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[n-1] ), 20 );
}
out[1] -= ftmp;
}
}
/* compute whitening filter coefficients from normalized line spectral frequencies */
void SKP_Silk_NLSF2A(
SKP_int16 *a, /* o monic whitening filter coefficients in Q12, [d] */
const SKP_int *NLSF, /* i normalized line spectral frequencies in Q15, [d] */
const SKP_int d /* i filter order (should be even) */
)
{
SKP_int k, i, dd;
SKP_int32 cos_LSF_Q20[SKP_Silk_MAX_ORDER_LPC];
SKP_int32 P[SKP_Silk_MAX_ORDER_LPC/2+1], Q[SKP_Silk_MAX_ORDER_LPC/2+1];
SKP_int32 Ptmp, Qtmp;
SKP_int32 f_int;
SKP_int32 f_frac;
SKP_int32 cos_val, delta;
SKP_int32 a_int32[SKP_Silk_MAX_ORDER_LPC];
SKP_int32 maxabs, absval, idx=0, sc_Q16;
SKP_assert(LSF_COS_TAB_SZ_FIX == 128);
/* convert LSFs to 2*cos(LSF(i)), using piecewise linear curve from table */
for( k = 0; k < d; k++ ) {
SKP_assert(NLSF[k] >= 0 );
SKP_assert(NLSF[k] <= 32767 );
/* f_int on a scale 0-127 (rounded down) */
f_int = SKP_RSHIFT( NLSF[k], 15 - 7 );
/* f_frac, range: 0..255 */
f_frac = NLSF[k] - SKP_LSHIFT( f_int, 15 - 7 );
SKP_assert(f_int >= 0);
SKP_assert(f_int < LSF_COS_TAB_SZ_FIX );
/* Read start and end value from table */
cos_val = SKP_Silk_LSFCosTab_FIX_Q12[ f_int ]; /* Q12 */
delta = SKP_Silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */
/* Linear interpolation */
cos_LSF_Q20[k] = SKP_LSHIFT( cos_val, 8 ) + SKP_MUL( delta, f_frac ); /* Q20 */
}
dd = SKP_RSHIFT( d, 1 );
/* generate even and odd polynomials using convolution */
SKP_Silk_NLSF2A_find_poly( P, &cos_LSF_Q20[0], dd );
SKP_Silk_NLSF2A_find_poly( Q, &cos_LSF_Q20[1], dd );
/* convert even and odd polynomials to SKP_int32 Q12 filter coefs */
for( k = 0; k < dd; k++ ) {
Ptmp = P[k+1] + P[k];
Qtmp = Q[k+1] - Q[k];
/* the Ptmp and Qtmp values at this stage need to fit in int32 */
a_int32[k] = -SKP_RSHIFT_ROUND( Ptmp + Qtmp, 9 ); /* Q20 -> Q12 */
a_int32[d-k-1] = SKP_RSHIFT_ROUND( Qtmp - Ptmp, 9 ); /* Q20 -> Q12 */
}
/* Limit the maximum absolute value of the prediction coefficients */
for( i = 0; i < 10; i++ ) {
/* Find maximum absolute value and its index */
maxabs = 0;
for( k = 0; k < d; k++ ) {
absval = SKP_abs( a_int32[k] );
if( absval > maxabs ) {
maxabs = absval;
idx = k;
}
}
if( maxabs > SKP_int16_MAX ) {
/* Reduce magnitude of prediction coefficients */
maxabs = SKP_min( maxabs, 98369 ); // ( SKP_int32_MAX / ( 65470 >> 2 ) ) + SKP_int16_MAX = 98369
sc_Q16 = 65470 - SKP_DIV32( SKP_MUL( 65470 >> 2, maxabs - SKP_int16_MAX ),
SKP_RSHIFT32( SKP_MUL( maxabs, idx + 1), 2 ) );
SKP_Silk_bwexpander_32( a_int32, d, sc_Q16 );
} else {
break;
}
}
/* Reached the last iteration */
if( i == 10 ) {
SKP_assert(0);
for( k = 0; k < d; k++ ) {
a_int32[k] = SKP_SAT16( a_int32[k] );
}
}
/* Return as SKP_int16 Q12 coefficients */
for( k = 0; k < d; k++ ) {
a[k] = (SKP_int16)a_int32[k];
}
}

View File

@ -0,0 +1,58 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/* Convert NLSF parameters to stable AR prediction filter coefficients */
void SKP_Silk_NLSF2A_stable(
SKP_int16 pAR_Q12[ MAX_LPC_ORDER ], /* O Stabilized AR coefs [LPC_order] */
const SKP_int pNLSF[ MAX_LPC_ORDER ], /* I NLSF vector [LPC_order] */
const SKP_int LPC_order /* I LPC/LSF order */
)
{
SKP_int i;
SKP_int32 invGain_Q30;
SKP_Silk_NLSF2A( pAR_Q12, pNLSF, LPC_order );
/* Ensure stable LPCs */
for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
if( SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, pAR_Q12, LPC_order ) == 1 ) {
SKP_Silk_bwexpander( pAR_Q12, LPC_order, 65536 - SKP_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015 */
} else {
break;
}
}
/* Reached the last iteration */
if( i == MAX_LPC_STABILIZE_ITERATIONS ) {
SKP_assert( 0 );
for( i = 0; i < LPC_order; i++ ) {
pAR_Q12[ i ] = 0;
}
}
}

View File

@ -0,0 +1,91 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/* NLSF vector decoder */
void SKP_Silk_NLSF_MSVQ_decode(
SKP_int *pNLSF_Q15, /* O Pointer to decoded output vector [LPC_ORDER x 1] */
const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Pointer to NLSF codebook struct */
const SKP_int *NLSFIndices, /* I Pointer to NLSF indices [nStages x 1] */
const SKP_int LPC_order /* I LPC order used */
)
{
const SKP_int16 *pCB_element;
SKP_int s;
SKP_int i;
/* Check that each index is within valid range */
SKP_assert( 0 <= NLSFIndices[ 0 ] && NLSFIndices[ 0 ] < psNLSF_CB->CBStages[ 0 ].nVectors );
/* Point to the first vector element */
pCB_element = &psNLSF_CB->CBStages[ 0 ].CB_NLSF_Q15[ SKP_MUL( NLSFIndices[ 0 ], LPC_order ) ];
/* Initialize with the codebook vector from stage 0 */
for( i = 0; i < LPC_order; i++ ) {
pNLSF_Q15[ i ] = ( SKP_int )pCB_element[ i ];
}
for( s = 1; s < psNLSF_CB->nStages; s++ ) {
/* Check that each index is within valid range */
SKP_assert( 0 <= NLSFIndices[ s ] && NLSFIndices[ s ] < psNLSF_CB->CBStages[ s ].nVectors );
if( LPC_order == 16 ) {
/* Point to the first vector element */
pCB_element = &psNLSF_CB->CBStages[ s ].CB_NLSF_Q15[ SKP_LSHIFT( NLSFIndices[ s ], 4 ) ];
/* Add the codebook vector from the current stage */
pNLSF_Q15[ 0 ] += pCB_element[ 0 ];
pNLSF_Q15[ 1 ] += pCB_element[ 1 ];
pNLSF_Q15[ 2 ] += pCB_element[ 2 ];
pNLSF_Q15[ 3 ] += pCB_element[ 3 ];
pNLSF_Q15[ 4 ] += pCB_element[ 4 ];
pNLSF_Q15[ 5 ] += pCB_element[ 5 ];
pNLSF_Q15[ 6 ] += pCB_element[ 6 ];
pNLSF_Q15[ 7 ] += pCB_element[ 7 ];
pNLSF_Q15[ 8 ] += pCB_element[ 8 ];
pNLSF_Q15[ 9 ] += pCB_element[ 9 ];
pNLSF_Q15[ 10 ] += pCB_element[ 10 ];
pNLSF_Q15[ 11 ] += pCB_element[ 11 ];
pNLSF_Q15[ 12 ] += pCB_element[ 12 ];
pNLSF_Q15[ 13 ] += pCB_element[ 13 ];
pNLSF_Q15[ 14 ] += pCB_element[ 14 ];
pNLSF_Q15[ 15 ] += pCB_element[ 15 ];
} else {
/* Point to the first vector element */
pCB_element = &psNLSF_CB->CBStages[ s ].CB_NLSF_Q15[ SKP_SMULBB( NLSFIndices[ s ], LPC_order ) ];
/* Add the codebook vector from the current stage */
for( i = 0; i < LPC_order; i++ ) {
pNLSF_Q15[ i ] += pCB_element[ i ];
}
}
}
/* NLSF stabilization */
SKP_Silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->NDeltaMin_Q15, LPC_order );
}

View File

@ -0,0 +1,89 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
/* NLSF vector decoder */
void SKP_Silk_NLSF_MSVQ_decode_FLP(
SKP_float *pNLSF, /* O Decoded output vector [ LPC_ORDER ] */
const SKP_Silk_NLSF_CB_FLP *psNLSF_CB_FLP, /* I NLSF codebook struct */
const SKP_int *NLSFIndices, /* I NLSF indices [ nStages ] */
const SKP_int LPC_order /* I LPC order used */
)
{
const SKP_float *pCB_element;
SKP_int s;
SKP_int i;
/* Check that each index is within valid range */
SKP_assert( 0 <= NLSFIndices[ 0 ] && NLSFIndices[ 0 ] < psNLSF_CB_FLP->CBStages[ 0 ].nVectors );
/* Point to the first vector element */
pCB_element = &psNLSF_CB_FLP->CBStages[ 0 ].CB[ SKP_MUL( NLSFIndices[ 0 ], LPC_order ) ];
/* Initialize with the codebook vector from stage 0 */
SKP_memcpy( pNLSF, pCB_element, LPC_order * sizeof( SKP_float ) );
for( s = 1; s < psNLSF_CB_FLP->nStages; s++ ) {
/* Check that each index is within valid range */
SKP_assert( 0 <= NLSFIndices[ s ] && NLSFIndices[ s ] < psNLSF_CB_FLP->CBStages[ s ].nVectors );
if( LPC_order == 16 ) {
/* Point to the first vector element */
pCB_element = &psNLSF_CB_FLP->CBStages[ s ].CB[ SKP_LSHIFT( NLSFIndices[ s ], 4 ) ];
/* Add the codebook vector from the current stage */
pNLSF[ 0 ] += pCB_element[ 0 ];
pNLSF[ 1 ] += pCB_element[ 1 ];
pNLSF[ 2 ] += pCB_element[ 2 ];
pNLSF[ 3 ] += pCB_element[ 3 ];
pNLSF[ 4 ] += pCB_element[ 4 ];
pNLSF[ 5 ] += pCB_element[ 5 ];
pNLSF[ 6 ] += pCB_element[ 6 ];
pNLSF[ 7 ] += pCB_element[ 7 ];
pNLSF[ 8 ] += pCB_element[ 8 ];
pNLSF[ 9 ] += pCB_element[ 9 ];
pNLSF[ 10 ] += pCB_element[ 10 ];
pNLSF[ 11 ] += pCB_element[ 11 ];
pNLSF[ 12 ] += pCB_element[ 12 ];
pNLSF[ 13 ] += pCB_element[ 13 ];
pNLSF[ 14 ] += pCB_element[ 14 ];
pNLSF[ 15 ] += pCB_element[ 15 ];
} else {
/* Point to the first vector element */
pCB_element = &psNLSF_CB_FLP->CBStages[ s ].CB[ NLSFIndices[ s ] * LPC_order ];
/* Add the codebook vector from the current stage */
for( i = 0; i < LPC_order; i++ ) {
pNLSF[ i ] += pCB_element[ i ];
}
}
}
/* NLSF stabilization */
SKP_Silk_NLSF_stabilize_FLP( pNLSF, psNLSF_CB_FLP->NDeltaMin, LPC_order );
}

View File

@ -0,0 +1,233 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
/***********************/
/* NLSF vector encoder */
/***********************/
void SKP_Silk_NLSF_MSVQ_encode_FLP(
SKP_int *NLSFIndices, /* O Codebook path vector [ CB_STAGES ] */
SKP_float *pNLSF, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
const SKP_Silk_NLSF_CB_FLP *psNLSF_CB_FLP, /* I Codebook object */
const SKP_float *pNLSF_q_prev, /* I Prev. quantized NLSF vector [LPC_ORDER] */
const SKP_float *pW, /* I NLSF weight vector [ LPC_ORDER ] */
const SKP_float NLSF_mu, /* I Rate weight for the RD optimization */
const SKP_float NLSF_mu_fluc_red, /* I Fluctuation reduction error weight */
const SKP_int NLSF_MSVQ_Survivors,/* I Max survivors from each stage */
const SKP_int LPC_order, /* I LPC order */
const SKP_int deactivate_fluc_red /* I Deactivate fluctuation reduction */
)
{
SKP_int i, s, k, cur_survivors, prev_survivors, min_survivors, input_index, cb_index, bestIndex;
SKP_float se, wsse, rateDistThreshold, bestRateDist;
#if( LOW_COMPLEXITY_ONLY == 1 )
SKP_float pRateDist[ NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE ];
SKP_float pRate[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];
SKP_float pRate_new[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];
SKP_int pTempIndices[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];
SKP_int pPath[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ];
SKP_int pPath_new[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ];
SKP_float pRes[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ];
SKP_float pRes_new[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ];
#else
SKP_float pRateDist[ NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED ];
SKP_float pRate[ MAX_NLSF_MSVQ_SURVIVORS ];
SKP_float pRate_new[ MAX_NLSF_MSVQ_SURVIVORS ];
SKP_int pTempIndices[ MAX_NLSF_MSVQ_SURVIVORS ];
SKP_int pPath[ MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ];
SKP_int pPath_new[ MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ];
SKP_float pRes[ MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ];
SKP_float pRes_new[ MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ];
#endif
const SKP_float *pConstFloat;
SKP_float *pFloat;
const SKP_int *pConstInt;
SKP_int *pInt;
const SKP_float *pCB_element;
const SKP_Silk_NLSF_CBS_FLP *pCurrentCBStage;
#ifdef USE_UNQUANTIZED_LSFS
SKP_float NLSF_orig[ MAX_LPC_ORDER ];
SKP_memcpy( NLSF_orig, pNLSF, LPC_order * sizeof( SKP_float ) );
#endif
SKP_assert( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS );
SKP_assert( ( LOW_COMPLEXITY_ONLY == 0 ) || ( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ) );
cur_survivors = NLSF_MSVQ_Survivors;
/****************************************************/
/* Tree search for the multi-stage vector quantizer */
/****************************************************/
/* Clear accumulated rates */
SKP_memset( pRate, 0, NLSF_MSVQ_Survivors * sizeof( SKP_float ) );
/* Copy NLSFs into residual signal vector */
SKP_memcpy( pRes, pNLSF, LPC_order * sizeof( SKP_float ) );
/* Set first stage values */
prev_survivors = 1;
/* Minimum number of survivors */
min_survivors = NLSF_MSVQ_Survivors / 2;
/* Loop over all stages */
for( s = 0; s < psNLSF_CB_FLP->nStages; s++ ) {
/* Set a pointer to the current stage codebook */
pCurrentCBStage = &psNLSF_CB_FLP->CBStages[ s ];
/* Calculate the number of survivors in the current stage */
cur_survivors = SKP_min_32( NLSF_MSVQ_Survivors, prev_survivors * pCurrentCBStage->nVectors );
#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 0 )
/* Find a single best survivor in the last stage, if we */
/* do not need candidates for fluctuation reduction */
if( s == psNLSF_CB_FLP->nStages - 1 ) {
cur_survivors = 1;
}
#endif
/* Nearest neighbor clustering for multiple input data vectors */
SKP_Silk_NLSF_VQ_rate_distortion_FLP( pRateDist, pCurrentCBStage, pRes, pW, pRate, NLSF_mu, prev_survivors, LPC_order );
/* Sort the rate-distortion errors */
SKP_Silk_insertion_sort_increasing_FLP( pRateDist, pTempIndices, prev_survivors * pCurrentCBStage->nVectors, cur_survivors );
/* Discard survivors with rate-distortion values too far above the best one */
rateDistThreshold = ( 1.0f + NLSF_MSVQ_Survivors * NLSF_MSVQ_SURV_MAX_REL_RD ) * pRateDist[ 0 ];
while( pRateDist[ cur_survivors - 1 ] > rateDistThreshold && cur_survivors > min_survivors ) {
cur_survivors--;
}
/* Update accumulated codebook contributions for the 'cur_survivors' best codebook indices */
for( k = 0; k < cur_survivors; k++ ) {
if( s > 0 ) {
/* Find the indices of the input and the codebook vector */
if( pCurrentCBStage->nVectors == 8 ) {
input_index = SKP_RSHIFT( pTempIndices[ k ], 3 );
cb_index = pTempIndices[ k ] & 7;
} else {
input_index = pTempIndices[ k ] / pCurrentCBStage->nVectors;
cb_index = pTempIndices[ k ] - input_index * pCurrentCBStage->nVectors;
}
} else {
/* Find the indices of the input and the codebook vector */
input_index = 0;
cb_index = pTempIndices[ k ];
}
/* Subtract new contribution from the previous residual vector for each of 'cur_survivors' */
pConstFloat = &pRes[ input_index * LPC_order ];
pCB_element = &pCurrentCBStage->CB[ cb_index * LPC_order ];
pFloat = &pRes_new[ k * LPC_order ];
for( i = 0; i < LPC_order; i++ ) {
pFloat[ i ] = pConstFloat[ i ] - pCB_element[ i ];
}
/* Update accumulated rate for stage 1 to the current */
pRate_new[ k ] = pRate[ input_index ] + pCurrentCBStage->Rates[ cb_index ];
/* Copy paths from previous matrix, starting with the best path */
pConstInt = &pPath[ input_index * psNLSF_CB_FLP->nStages ];
pInt = &pPath_new[ k * psNLSF_CB_FLP->nStages ];
for( i = 0; i < s; i++ ) {
pInt[ i ] = pConstInt[ i ];
}
/* Write the current stage indices for the 'cur_survivors' to the best path matrix */
pInt[ s ] = cb_index;
}
if( s < psNLSF_CB_FLP->nStages - 1 ) {
/* Copy NLSF residual matrix for next stage */
SKP_memcpy(pRes, pRes_new, cur_survivors * LPC_order * sizeof( SKP_float ) );
/* Copy rate vector for next stage */
SKP_memcpy(pRate, pRate_new, cur_survivors * sizeof( SKP_float ) );
/* Copy best path matrix for next stage */
SKP_memcpy(pPath, pPath_new, cur_survivors * psNLSF_CB_FLP->nStages * sizeof( SKP_int ) );
}
prev_survivors = cur_survivors;
}
/* (Preliminary) index of the best survivor, later to be decoded */
bestIndex = 0;
#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 )
/******************************/
/* NLSF fluctuation reduction */
/******************************/
if( deactivate_fluc_red != 1 ) {
/* Search among all survivors, now taking also weighted fluctuation errors into account */
bestRateDist = SKP_float_MAX;
for( s = 0; s < cur_survivors; s++ ) {
/* Decode survivor to compare with previous quantized NLSF vector */
SKP_Silk_NLSF_MSVQ_decode_FLP( pNLSF, psNLSF_CB_FLP, &pPath_new[ s * psNLSF_CB_FLP->nStages ], LPC_order );
/* Compare decoded NLSF vector with the previously quantized vector */
wsse = 0;
for( i = 0; i < LPC_order; i += 2 ) {
/* Compute weighted squared quantization error for index i */
se = pNLSF[ i ] - pNLSF_q_prev[ i ];
wsse += pW[ i ] * se * se;
/* Compute weighted squared quantization error for index i + 1 */
se = pNLSF[ i + 1 ] - pNLSF_q_prev[ i + 1 ];
wsse += pW[ i + 1 ] * se * se;
}
/* Add the fluctuation reduction penalty to the rate distortion error */
wsse = pRateDist[s] + wsse * NLSF_mu_fluc_red;
/* Keep index of best survivor */
if( wsse < bestRateDist ) {
bestRateDist = wsse;
bestIndex = s;
}
}
}
#endif
/* Copy best path to output argument */
SKP_memcpy( NLSFIndices, &pPath_new[ bestIndex * psNLSF_CB_FLP->nStages ], psNLSF_CB_FLP->nStages * sizeof( SKP_int ) );
/* Decode and stabilize the best survivor */
SKP_Silk_NLSF_MSVQ_decode_FLP( pNLSF, psNLSF_CB_FLP, NLSFIndices, LPC_order );
#ifdef USE_UNQUANTIZED_LSFS
SKP_memcpy( pNLSF, NLSF_orig, LPC_order * sizeof( SKP_float ) );
#endif
}

View File

@ -0,0 +1,57 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
/* Rate-Distortion calculations for multiple input data vectors */
void SKP_Silk_NLSF_VQ_rate_distortion_FLP(
SKP_float *pRD, /* O Rate-distortion values [psNLSF_CBS_FLP->nVectors*N] */
const SKP_Silk_NLSF_CBS_FLP *psNLSF_CBS_FLP, /* I NLSF codebook stage struct */
const SKP_float *in, /* I Input vectors to be quantized */
const SKP_float *w, /* I Weight vector */
const SKP_float *rate_acc, /* I Accumulated rates from previous stage */
const SKP_float mu, /* I Weight between weighted error and rate */
const SKP_int N, /* I Number of input vectors to be quantized */
const SKP_int LPC_order /* I LPC order */
)
{
SKP_float *pRD_vec;
SKP_int i, n;
/* Compute weighted quantization errors for all input vectors over one codebook stage */
SKP_Silk_NLSF_VQ_sum_error_FLP( pRD, in, w, psNLSF_CBS_FLP->CB, N, psNLSF_CBS_FLP->nVectors, LPC_order );
/* Loop over input vectors */
pRD_vec = pRD;
for( n = 0; n < N; n++ ) {
/* Add rate cost to error for each codebook vector */
for( i = 0; i < psNLSF_CBS_FLP->nVectors; i++ ) {
pRD_vec[ i ] += mu * ( rate_acc[n] + psNLSF_CBS_FLP->Rates[ i ] );
}
pRD_vec += psNLSF_CBS_FLP->nVectors;
}
}

View File

@ -0,0 +1,132 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
/* compute weighted quantization errors for LPC_order element input vectors, over one codebook stage */
void SKP_Silk_NLSF_VQ_sum_error_FLP(
SKP_float *err, /* O Weighted quantization errors [ N * K ] */
const SKP_float *in, /* I Input vectors [ N * LPC_order ] */
const SKP_float *w, /* I Weighting vectors [ N * LPC_order ] */
const SKP_float *pCB, /* I Codebook vectors [ K * LPC_order ] */
const SKP_int N, /* I Number of input vectors */
const SKP_int K, /* I Number of codebook vectors */
const SKP_int LPC_order /* I LPC order */
)
{
SKP_int i, n;
SKP_float diff, sum_error;
SKP_float Wcpy[ MAX_LPC_ORDER ];
const SKP_float *cb_vec;
/* Copy to local stack */
SKP_memcpy( Wcpy, w, LPC_order * sizeof( SKP_float ) );
if( LPC_order == 16 ) {
/* Loop over input vectors */
for( n = 0; n < N; n++ ) {
/* Loop over codebook */
cb_vec = pCB;
for( i = 0; i < K; i++ ) {
/* Compute weighted squared quantization error */
diff = in[ 0 ] - cb_vec[ 0 ];
sum_error = Wcpy[ 0 ] * diff * diff;
diff = in[ 1 ] - cb_vec[ 1 ];
sum_error += Wcpy[ 1 ] * diff * diff;
diff = in[ 2 ] - cb_vec[ 2 ];
sum_error += Wcpy[ 2 ] * diff * diff;
diff = in[ 3 ] - cb_vec[ 3 ];
sum_error += Wcpy[ 3 ] * diff * diff;
diff = in[ 4 ] - cb_vec[ 4 ];
sum_error += Wcpy[ 4 ] * diff * diff;
diff = in[ 5 ] - cb_vec[ 5 ];
sum_error += Wcpy[ 5 ] * diff * diff;
diff = in[ 6 ] - cb_vec[ 6 ];
sum_error += Wcpy[ 6 ] * diff * diff;
diff = in[ 7 ] - cb_vec[ 7 ];
sum_error += Wcpy[ 7 ] * diff * diff;
diff = in[ 8 ] - cb_vec[ 8 ];
sum_error += Wcpy[ 8 ] * diff * diff;
diff = in[ 9 ] - cb_vec[ 9 ];
sum_error += Wcpy[ 9 ] * diff * diff;
diff = in[ 10 ] - cb_vec[ 10 ];
sum_error += Wcpy[ 10 ] * diff * diff;
diff = in[ 11 ] - cb_vec[ 11 ];
sum_error += Wcpy[ 11 ] * diff * diff;
diff = in[ 12 ] - cb_vec[ 12 ];
sum_error += Wcpy[ 12 ] * diff * diff;
diff = in[ 13 ] - cb_vec[ 13 ];
sum_error += Wcpy[ 13 ] * diff * diff;
diff = in[ 14 ] - cb_vec[ 14 ];
sum_error += Wcpy[ 14 ] * diff * diff;
diff = in[ 15 ] - cb_vec[ 15 ];
sum_error += Wcpy[ 15 ] * diff * diff;
err[ i ] = sum_error;
cb_vec += 16;
}
err += K;
in += 16;
}
} else {
SKP_assert( LPC_order == 10 );
/* Loop over input vectors */
for( n = 0; n < N; n++ ) {
/* Loop over codebook */
cb_vec = pCB;
for( i = 0; i < K; i++ ) {
/* Compute weighted squared quantization error */
diff = in[ 0 ] - cb_vec[ 0 ];
sum_error = Wcpy[ 0 ] * diff * diff;
diff = in[ 1 ] - cb_vec[ 1 ];
sum_error += Wcpy[ 1 ] * diff * diff;
diff = in[ 2 ] - cb_vec[ 2 ];
sum_error += Wcpy[ 2 ] * diff * diff;
diff = in[ 3 ] - cb_vec[ 3 ];
sum_error += Wcpy[ 3 ] * diff * diff;
diff = in[ 4 ] - cb_vec[ 4 ];
sum_error += Wcpy[ 4 ] * diff * diff;
diff = in[ 5 ] - cb_vec[ 5 ];
sum_error += Wcpy[ 5 ] * diff * diff;
diff = in[ 6 ] - cb_vec[ 6 ];
sum_error += Wcpy[ 6 ] * diff * diff;
diff = in[ 7 ] - cb_vec[ 7 ];
sum_error += Wcpy[ 7 ] * diff * diff;
diff = in[ 8 ] - cb_vec[ 8 ];
sum_error += Wcpy[ 8 ] * diff * diff;
diff = in[ 9 ] - cb_vec[ 9 ];
sum_error += Wcpy[ 9 ] * diff * diff;
err[ i ] = sum_error;
cb_vec += 10;
}
err += K;
in += 10;
}
}
}

View File

@ -0,0 +1,69 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_SigProc_FLP.h"
/*
R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP
Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech,
Signal Processing, pp. 641-644, 1991.
*/
#define MIN_NDELTA 1e-4f
/* Laroia low complexity NLSF weights */
void SKP_Silk_NLSF_VQ_weights_laroia_FLP(
SKP_float *pXW, /* 0: Pointer to input vector weights [D x 1] */
const SKP_float *pX, /* I: Pointer to input vector [D x 1] */
const SKP_int D /* I: Input vector dimension */
)
{
SKP_int k;
SKP_float tmp1, tmp2;
/* Safety checks */
SKP_assert( D > 0 );
SKP_assert( ( D & 1 ) == 0 );
/* First value */
tmp1 = 1.0f / SKP_max_float( pX[ 0 ], MIN_NDELTA );
tmp2 = 1.0f / SKP_max_float( pX[ 1 ] - pX[ 0 ], MIN_NDELTA );
pXW[ 0 ] = tmp1 + tmp2;
/* Main loop */
for( k = 1; k < D - 1; k += 2 ) {
tmp1 = 1.0f / SKP_max_float( pX[ k + 1 ] - pX[ k ], MIN_NDELTA );
pXW[ k ] = tmp1 + tmp2;
tmp2 = 1.0f / SKP_max_float( pX[ k + 2 ] - pX[ k + 1 ], MIN_NDELTA );
pXW[ k + 1 ] = tmp1 + tmp2;
}
/* Last value */
tmp1 = 1.0f / SKP_max_float( 1.0f - pX[ D - 1 ], MIN_NDELTA );
pXW[ D - 1 ] = tmp1 + tmp2;
}

View File

@ -0,0 +1,139 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* NLSF stabilizer: */
/* */
/* - Moves NLSFs futher apart if they are too close */
/* - Moves NLSFs away from borders if they are too close */
/* - High effort to achieve a modification with minimum */
/* Euclidean distance to input vector */
/* - Output are sorted NLSF coefficients */
/* */
#include "SKP_Silk_SigProc_FIX.h"
/* Constant Definitions */
#define MAX_LOOPS 20
/* NLSF stabilizer, for a single input data vector */
void SKP_Silk_NLSF_stabilize(
SKP_int *NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vector in Q15 [L] */
const SKP_int *NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */
const SKP_int L /* I: Number of NLSF parameters in the input vector */
)
{
SKP_int center_freq_Q15, diff_Q15, min_center_Q15, max_center_Q15;
SKP_int32 min_diff_Q15;
SKP_int loops;
SKP_int i, I=0, k;
/* This is necessary to ensure an output within range of a SKP_int16 */
SKP_assert( NDeltaMin_Q15[L] >= 1 );
for( loops = 0; loops < MAX_LOOPS; loops++ ) {
/**************************/
/* Find smallest distance */
/**************************/
/* First element */
min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0];
I = 0;
/* Middle elements */
for( i = 1; i <= L-1; i++ ) {
diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
if( diff_Q15 < min_diff_Q15 ) {
min_diff_Q15 = diff_Q15;
I = i;
}
}
/* Last element */
diff_Q15 = (1<<15) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] );
if( diff_Q15 < min_diff_Q15 ) {
min_diff_Q15 = diff_Q15;
I = L;
}
/***************************************************/
/* Now check if the smallest distance non-negative */
/***************************************************/
if (min_diff_Q15 >= 0) {
return;
}
if( I == 0 ) {
/* Move away from lower limit */
NLSF_Q15[0] = NDeltaMin_Q15[0];
} else if( I == L) {
/* Move away from higher limit */
NLSF_Q15[L-1] = (1<<15) - NDeltaMin_Q15[L];
} else {
/* Find the lower extreme for the location of the current center frequency */
min_center_Q15 = 0;
for( k = 0; k < I; k++ ) {
min_center_Q15 += NDeltaMin_Q15[k];
}
min_center_Q15 += SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
/* Find the upper extreme for the location of the current center frequency */
max_center_Q15 = (1<<15);
for( k = L; k > I; k-- ) {
max_center_Q15 -= NDeltaMin_Q15[k];
}
max_center_Q15 -= ( NDeltaMin_Q15[I] - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ) );
/* Move apart, sorted by value, keeping the same center frequency */
center_freq_Q15 = SKP_LIMIT_32( SKP_RSHIFT_ROUND( (SKP_int32)NLSF_Q15[I-1] + (SKP_int32)NLSF_Q15[I], 1 ),
min_center_Q15, max_center_Q15 );
NLSF_Q15[I-1] = center_freq_Q15 - SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I];
}
}
/* Safe and simple fall back method, which is less ideal than the above */
if( loops == MAX_LOOPS )
{
/* Insertion sort (fast for already almost sorted arrays): */
/* Best case: O(n) for an already sorted array */
/* Worst case: O(n^2) for an inversely sorted array */
SKP_Silk_insertion_sort_increasing_all_values(&NLSF_Q15[0], L);
/* First NLSF should be no less than NDeltaMin[0] */
NLSF_Q15[0] = SKP_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] );
/* Keep delta_min distance between the NLSFs */
for( i = 1; i < L; i++ )
NLSF_Q15[i] = SKP_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
/* Last NLSF should be no higher than 1 - NDeltaMin[L] */
NLSF_Q15[L-1] = SKP_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );
/* Keep NDeltaMin distance between the NLSFs */
for( i = L-2; i >= 0; i-- )
NLSF_Q15[i] = SKP_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] );
}
}

View File

@ -0,0 +1,421 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
SKP_INLINE void SKP_Silk_nsq_scale_states(
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
const SKP_int16 x[], /* I input in Q0 */
SKP_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
SKP_int subfr_length, /* I length of input */
const SKP_int16 sLTP[], /* I re-whitened LTP state in Q0 */
SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
SKP_int subfr, /* I subframe number */
const SKP_int LTP_scale_Q14, /* I */
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
const SKP_int pitchL[ NB_SUBFR ] /* I */
);
SKP_INLINE void SKP_Silk_noise_shape_quantizer(
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
SKP_int sigtype, /* I Signal type */
const SKP_int32 x_sc_Q10[], /* I */
SKP_int8 q[], /* O */
SKP_int16 xq[], /* O */
SKP_int32 sLTP_Q16[], /* I/O LTP state */
const SKP_int16 a_Q12[], /* I Short term prediction coefs */
const SKP_int16 b_Q14[], /* I Long term prediction coefs */
const SKP_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
SKP_int lag, /* I Pitch lag */
SKP_int32 HarmShapeFIRPacked_Q14, /* I */
SKP_int Tilt_Q14, /* I Spectral tilt */
SKP_int32 LF_shp_Q14, /* I */
SKP_int32 Gain_Q16, /* I */
SKP_int Lambda_Q10, /* I */
SKP_int offset_Q10, /* I */
SKP_int length, /* I Input length */
SKP_int shapingLPCOrder, /* I Noise shaping AR filter order */
SKP_int predictLPCOrder /* I Prediction filter order */
);
void SKP_Silk_NSQ(
SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */
SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
const SKP_int16 x[], /* I prefiltered input signal */
SKP_int8 q[], /* O quantized qulse signal */
const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */
const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefficients */
const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I Long term prediction coefficients */
const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */
const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */
const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */
const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
const SKP_int Lambda_Q10, /* I */
const SKP_int LTP_scale_Q14 /* I LTP state scaling */
)
{
SKP_int k, lag, start_idx, LSF_interpolation_flag;
const SKP_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
SKP_int16 *pxq;
SKP_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];
SKP_int16 sLTP[ 2 * MAX_FRAME_LENGTH ];
SKP_int32 HarmShapeFIRPacked_Q14;
SKP_int offset_Q10;
SKP_int32 FiltState[ MAX_LPC_ORDER ];
SKP_int32 x_sc_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];
NSQ->rand_seed = psEncCtrlC->Seed;
/* Set unvoiced lag to the previous one, overwrite later for voiced */
lag = NSQ->lagPrev;
SKP_assert( NSQ->prev_inv_gain_Q16 != 0 );
offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC->sigtype ][ psEncCtrlC->QuantOffsetType ];
if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) {
LSF_interpolation_flag = 0;
} else {
LSF_interpolation_flag = 1;
}
/* Setup pointers to start of sub frame */
NSQ->sLTP_shp_buf_idx = psEncC->frame_length;
NSQ->sLTP_buf_idx = psEncC->frame_length;
pxq = &NSQ->xq[ psEncC->frame_length ];
for( k = 0; k < NB_SUBFR; k++ ) {
A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
/* Noise shape parameters */
SKP_assert( HarmShapeGain_Q14[ k ] >= 0 );
HarmShapeFIRPacked_Q14 = SKP_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
HarmShapeFIRPacked_Q14 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
NSQ->rewhite_flag = 0;
if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
/* Voiced */
lag = psEncCtrlC->pitchL[ k ];
/* Re-whitening */
if( ( k & ( 3 - SKP_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
/* Rewhiten with new A coefs */
start_idx = psEncC->frame_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
SKP_assert( start_idx >= 0 );
SKP_assert( start_idx <= psEncC->frame_length - psEncC->predictLPCOrder );
SKP_memset( FiltState, 0, psEncC->predictLPCOrder * sizeof( SKP_int32 ) );
SKP_Silk_MA_Prediction( &NSQ->xq[ start_idx + k * ( psEncC->frame_length >> 2 ) ],
A_Q12, FiltState, sLTP + start_idx, psEncC->frame_length - start_idx, psEncC->predictLPCOrder );
NSQ->rewhite_flag = 1;
NSQ->sLTP_buf_idx = psEncC->frame_length;
}
}
SKP_Silk_nsq_scale_states( NSQ, x, x_sc_Q10, psEncC->subfr_length, sLTP,
sLTP_Q16, k, LTP_scale_Q14, Gains_Q16, psEncCtrlC->pitchL );
SKP_Silk_noise_shape_quantizer( NSQ, psEncCtrlC->sigtype, x_sc_Q10, q, pxq, sLTP_Q16, A_Q12, B_Q14,
AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder
);
x += psEncC->subfr_length;
q += psEncC->subfr_length;
pxq += psEncC->subfr_length;
}
/* Update lagPrev for next frame */
NSQ->lagPrev = psEncCtrlC->pitchL[ NB_SUBFR - 1 ];
/* Save quantized speech and noise shaping signals */
SKP_memcpy( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int16 ) );
SKP_memcpy( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int32 ) );
#ifdef USE_UNQUANTIZED_LSFS
DEBUG_STORE_DATA( xq_unq_lsfs.pcm, NSQ->xq, psEncC->frame_length * sizeof( SKP_int16 ) );
#endif
}
/***********************************/
/* SKP_Silk_noise_shape_quantizer */
/***********************************/
SKP_INLINE void SKP_Silk_noise_shape_quantizer(
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
SKP_int sigtype, /* I Signal type */
const SKP_int32 x_sc_Q10[], /* I */
SKP_int8 q[], /* O */
SKP_int16 xq[], /* O */
SKP_int32 sLTP_Q16[], /* I/O LTP state */
const SKP_int16 a_Q12[], /* I Short term prediction coefs */
const SKP_int16 b_Q14[], /* I Long term prediction coefs */
const SKP_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
SKP_int lag, /* I Pitch lag */
SKP_int32 HarmShapeFIRPacked_Q14, /* I */
SKP_int Tilt_Q14, /* I Spectral tilt */
SKP_int32 LF_shp_Q14, /* I */
SKP_int32 Gain_Q16, /* I */
SKP_int Lambda_Q10, /* I */
SKP_int offset_Q10, /* I */
SKP_int length, /* I Input length */
SKP_int shapingLPCOrder, /* I Noise shaping AR filter order */
SKP_int predictLPCOrder /* I Prediction filter order */
)
{
SKP_int i, j;
SKP_int32 LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14;
SKP_int32 n_LF_Q10, r_Q10, q_Q0, q_Q10;
SKP_int32 thr1_Q10, thr2_Q10, thr3_Q10;
SKP_int32 dither, exc_Q10, LPC_exc_Q10, xq_Q10;
SKP_int32 tmp1, tmp2, sLF_AR_shp_Q10;
SKP_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
/* Setup short term AR state */
psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
/* Quantization thresholds */
thr1_Q10 = SKP_SUB_RSHIFT32( -1536, Lambda_Q10, 1 );
thr2_Q10 = SKP_SUB_RSHIFT32( -512, Lambda_Q10, 1 );
thr2_Q10 = SKP_ADD_RSHIFT32( thr2_Q10, SKP_SMULBB( offset_Q10, Lambda_Q10 ), 10 );
thr3_Q10 = SKP_ADD_RSHIFT32( 512, Lambda_Q10, 1 );
for( i = 0; i < length; i++ ) {
/* Generate dither */
NSQ->rand_seed = SKP_RAND( NSQ->rand_seed );
/* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
dither = SKP_RSHIFT( NSQ->rand_seed, 31 );
/* Short-term prediction */
SKP_assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */
/* check that array starts at 4-byte aligned address */
SKP_assert( ( ( SKP_int64 )( ( SKP_int8* )a_Q12 - ( SKP_int8* )0 ) & 3 ) == 0 );
SKP_assert( predictLPCOrder >= 10 ); /* check that unrolling works */
/* Partially unrolled */
LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
for( j = 10; j < predictLPCOrder; j ++ ) {
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], a_Q12[ j ] );
}
/* Long-term prediction */
if( sigtype == SIG_TYPE_VOICED ) {
/* Unrolled loop */
LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
pred_lag_ptr++;
} else {
LTP_pred_Q14 = 0;
}
/* Noise shape feedback */
SKP_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
tmp2 = psLPC_Q14[ 0 ];
tmp1 = NSQ->sAR2_Q14[ 0 ];
NSQ->sAR2_Q14[ 0 ] = tmp2;
n_AR_Q10 = SKP_SMULWB( tmp2, AR_shp_Q13[ 0 ] );
for( j = 2; j < shapingLPCOrder; j += 2 ) {
tmp2 = NSQ->sAR2_Q14[ j - 1 ];
NSQ->sAR2_Q14[ j - 1 ] = tmp1;
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ j - 1 ] );
tmp1 = NSQ->sAR2_Q14[ j + 0 ];
NSQ->sAR2_Q14[ j + 0 ] = tmp2;
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp2, AR_shp_Q13[ j ] );
}
NSQ->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 ); /* Q11 -> Q10 */
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, NSQ->sLF_AR_shp_Q12, Tilt_Q14 );
n_LF_Q10 = SKP_LSHIFT( SKP_SMULWB( NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ), 2 );
n_LF_Q10 = SKP_SMLAWT( n_LF_Q10, NSQ->sLF_AR_shp_Q12, LF_shp_Q14 );
SKP_assert( lag > 0 || sigtype == SIG_TYPE_UNVOICED );
/* Long-term shaping */
if( lag > 0 ) {
/* Symmetric, packed FIR coefficients */
n_LTP_Q14 = SKP_SMULWB( SKP_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
n_LTP_Q14 = SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 );
shp_lag_ptr++;
} else {
n_LTP_Q14 = 0;
}
/* Input minus prediction plus noise feedback */
//r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP;
tmp1 = SKP_SUB32( LTP_pred_Q14, n_LTP_Q14 ); /* Add Q14 stuff */
tmp1 = SKP_RSHIFT( tmp1, 4 ); /* convert to Q10 */
tmp1 = SKP_ADD32( tmp1, LPC_pred_Q10 ); /* add Q10 stuff */
tmp1 = SKP_SUB32( tmp1, n_AR_Q10 ); /* subtract Q10 stuff */
tmp1 = SKP_SUB32( tmp1, n_LF_Q10 ); /* subtract Q10 stuff */
r_Q10 = SKP_SUB32( x_sc_Q10[ i ], tmp1 );
/* Flip sign depending on dither */
r_Q10 = ( r_Q10 ^ dither ) - dither;
r_Q10 = SKP_SUB32( r_Q10, offset_Q10 );
r_Q10 = SKP_LIMIT_32( r_Q10, -64 << 10, 64 << 10 );
/* Quantize */
q_Q0 = 0;
q_Q10 = 0;
if( r_Q10 < thr2_Q10 ) {
if( r_Q10 < thr1_Q10 ) {
q_Q0 = SKP_RSHIFT_ROUND( SKP_ADD_RSHIFT32( r_Q10, Lambda_Q10, 1 ), 10 );
q_Q10 = SKP_LSHIFT( q_Q0, 10 );
} else {
q_Q0 = -1;
q_Q10 = -1024;
}
} else {
if( r_Q10 > thr3_Q10 ) {
q_Q0 = SKP_RSHIFT_ROUND( SKP_SUB_RSHIFT32( r_Q10, Lambda_Q10, 1 ), 10 );
q_Q10 = SKP_LSHIFT( q_Q0, 10 );
}
}
q[ i ] = ( SKP_int8 )q_Q0; /* No saturation needed because max is 64 */
/* Excitation */
exc_Q10 = SKP_ADD32( q_Q10, offset_Q10 );
exc_Q10 = ( exc_Q10 ^ dither ) - dither;
/* Add predictions */
LPC_exc_Q10 = SKP_ADD32( exc_Q10, SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) );
xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
/* Scale XQ back to normal level before saving */
xq[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( xq_Q10, Gain_Q16 ), 10 ) );
/* Update states */
psLPC_Q14++;
*psLPC_Q14 = SKP_LSHIFT( xq_Q10, 4 );
sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 );
NSQ->sLF_AR_shp_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx ] = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
sLTP_Q16[ NSQ->sLTP_buf_idx ] = SKP_LSHIFT( LPC_exc_Q10, 6 );
NSQ->sLTP_shp_buf_idx++;
NSQ->sLTP_buf_idx++;
/* Make dither dependent on quantized signal */
NSQ->rand_seed += q[ i ];
}
/* Update LPC synth buffer */
SKP_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
}
SKP_INLINE void SKP_Silk_nsq_scale_states(
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
const SKP_int16 x[], /* I input in Q0 */
SKP_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
SKP_int subfr_length, /* I length of input */
const SKP_int16 sLTP[], /* I re-whitened LTP state in Q0 */
SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
SKP_int subfr, /* I subframe number */
const SKP_int LTP_scale_Q14, /* I */
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
const SKP_int pitchL[ NB_SUBFR ] /* I */
)
{
SKP_int i, lag;
SKP_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32;
inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gains_Q16[ subfr ], 1 ), 32 );
inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );
lag = pitchL[ subfr ];
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
if( NSQ->rewhite_flag ) {
inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );
if( subfr == 0 ) {
/* Do LTP downscaling */
inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 );
}
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
SKP_assert( i < MAX_FRAME_LENGTH );
sLTP_Q16[ i ] = SKP_SMULWB( inv_gain_Q32, sLTP[ i ] );
}
}
/* Adjust for changing gain */
if( inv_gain_Q16 != NSQ->prev_inv_gain_Q16 ) {
gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, NSQ->prev_inv_gain_Q16, 16 );
/* Scale long-term shaping state */
for( i = NSQ->sLTP_shp_buf_idx - subfr_length * NB_SUBFR; i < NSQ->sLTP_shp_buf_idx; i++ ) {
NSQ->sLTP_shp_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q10[ i ] );
}
/* Scale long-term prediction state */
if( NSQ->rewhite_flag == 0 ) {
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
sLTP_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );
}
}
NSQ->sLF_AR_shp_Q12 = SKP_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q12 );
/* Scale short-term prediction and shaping states */
for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
NSQ->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
}
for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
NSQ->sAR2_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
}
}
/* Scale input */
for( i = 0; i < subfr_length; i++ ) {
x_sc_Q10[ i ] = SKP_RSHIFT( SKP_SMULBB( x[ i ], ( SKP_int16 )inv_gain_Q16 ), 6 );
}
/* save inv_gain */
SKP_assert( inv_gain_Q16 != 0 );
NSQ->prev_inv_gain_Q16 = inv_gain_Q16;
}

View File

@ -0,0 +1,703 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
typedef struct {
SKP_int32 RandState[ DECISION_DELAY ];
SKP_int32 Q_Q10[ DECISION_DELAY ];
SKP_int32 Xq_Q10[ DECISION_DELAY ];
SKP_int32 Pred_Q16[ DECISION_DELAY ];
SKP_int32 Shape_Q10[ DECISION_DELAY ];
SKP_int32 Gain_Q16[ DECISION_DELAY ];
SKP_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
SKP_int32 sLPC_Q14[ MAX_FRAME_LENGTH / NB_SUBFR + NSQ_LPC_BUF_LENGTH ];
SKP_int32 LF_AR_Q12;
SKP_int32 Seed;
SKP_int32 SeedInit;
SKP_int32 RD_Q10;
} NSQ_del_dec_struct;
typedef struct {
SKP_int32 Q_Q10;
SKP_int32 RD_Q10;
SKP_int32 xq_Q14;
SKP_int32 LF_AR_Q12;
SKP_int32 sLTP_shp_Q10;
SKP_int32 LPC_exc_Q16;
} NSQ_sample_struct;
SKP_INLINE void SKP_Silk_copy_del_dec_state(
NSQ_del_dec_struct *DD_dst, /* I Dst del dec state */
NSQ_del_dec_struct *DD_src, /* I Src del dec state */
SKP_int LPC_state_idx /* I Index to LPC buffer */
);
SKP_INLINE void SKP_Silk_nsq_del_dec_scale_states(
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
const SKP_int16 x[], /* I Input in Q0 */
SKP_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
SKP_int subfr_length, /* I Length of input */
const SKP_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
SKP_int subfr, /* I Subframe number */
SKP_int nStatesDelayedDecision, /* I Number of del dec states */
SKP_int smpl_buf_idx, /* I Index to newest samples in buffers */
const SKP_int LTP_scale_Q14, /* I LTP state scaling */
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
const SKP_int pitchL[ NB_SUBFR ] /* I Pitch lag */
);
/******************************************/
/* Noise shape quantizer for one subframe */
/******************************************/
SKP_INLINE void SKP_Silk_noise_shape_quantizer_del_dec(
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
SKP_int sigtype, /* I Signal type */
const SKP_int32 x_Q10[], /* I */
SKP_int8 q[], /* O */
SKP_int16 xq[], /* O */
SKP_int32 sLTP_Q16[], /* I/O LTP filter state */
const SKP_int16 a_Q12[], /* I Short term prediction coefs */
const SKP_int16 b_Q14[], /* I Long term prediction coefs */
const SKP_int16 AR_shp_Q13[], /* I Noise shaping coefs */
SKP_int lag, /* I Pitch lag */
SKP_int32 HarmShapeFIRPacked_Q14, /* I */
SKP_int Tilt_Q14, /* I Spectral tilt */
SKP_int32 LF_shp_Q14, /* I */
SKP_int32 Gain_Q16, /* I */
SKP_int Lambda_Q10, /* I */
SKP_int offset_Q10, /* I */
SKP_int length, /* I Input length */
SKP_int subfr, /* I Subframe number */
SKP_int shapingLPCOrder, /* I Shaping LPC filter order */
SKP_int predictLPCOrder, /* I Prediction filter order */
SKP_int warping_Q16, /* I */
SKP_int nStatesDelayedDecision, /* I Number of states in decision tree */
SKP_int *smpl_buf_idx, /* I Index to newest samples in buffers */
SKP_int decisionDelay /* I */
);
void SKP_Silk_NSQ_del_dec(
SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */
SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
const SKP_int16 x[], /* I Prefiltered input signal */
SKP_int8 q[], /* O Quantized pulse signal */
const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */
const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Prediction coefs */
const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I LT prediction coefs */
const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */
const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */
const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */
const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
const SKP_int Lambda_Q10, /* I */
const SKP_int LTP_scale_Q14 /* I LTP state scaling */
)
{
SKP_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
SKP_int last_smple_idx, smpl_buf_idx, decisionDelay, subfr_length;
const SKP_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
SKP_int16 *pxq;
SKP_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];
SKP_int16 sLTP[ 2 * MAX_FRAME_LENGTH ];
SKP_int32 HarmShapeFIRPacked_Q14;
SKP_int offset_Q10;
SKP_int32 FiltState[ MAX_LPC_ORDER ], RDmin_Q10;
SKP_int32 x_sc_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];
NSQ_del_dec_struct psDelDec[ MAX_DEL_DEC_STATES ];
NSQ_del_dec_struct *psDD;
subfr_length = psEncC->frame_length / NB_SUBFR;
/* Set unvoiced lag to the previous one, overwrite later for voiced */
lag = NSQ->lagPrev;
SKP_assert( NSQ->prev_inv_gain_Q16 != 0 );
/* Initialize delayed decision states */
SKP_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
psDD = &psDelDec[ k ];
psDD->Seed = ( k + psEncCtrlC->Seed ) & 3;
psDD->SeedInit = psDD->Seed;
psDD->RD_Q10 = 0;
psDD->LF_AR_Q12 = NSQ->sLF_AR_shp_Q12;
psDD->Shape_Q10[ 0 ] = NSQ->sLTP_shp_Q10[ psEncC->frame_length - 1 ];
SKP_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
SKP_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
}
offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC->sigtype ][ psEncCtrlC->QuantOffsetType ];
smpl_buf_idx = 0; /* index of oldest samples */
decisionDelay = SKP_min_int( DECISION_DELAY, subfr_length );
/* For voiced frames limit the decision delay to lower than the pitch lag */
if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
for( k = 0; k < NB_SUBFR; k++ ) {
decisionDelay = SKP_min_int( decisionDelay, psEncCtrlC->pitchL[ k ] - LTP_ORDER / 2 - 1 );
}
} else {
if( lag > 0 ) {
decisionDelay = SKP_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
}
}
if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) {
LSF_interpolation_flag = 0;
} else {
LSF_interpolation_flag = 1;
}
/* Setup pointers to start of sub frame */
pxq = &NSQ->xq[ psEncC->frame_length ];
NSQ->sLTP_shp_buf_idx = psEncC->frame_length;
NSQ->sLTP_buf_idx = psEncC->frame_length;
subfr = 0;
for( k = 0; k < NB_SUBFR; k++ ) {
A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
/* Noise shape parameters */
SKP_assert( HarmShapeGain_Q14[ k ] >= 0 );
HarmShapeFIRPacked_Q14 = SKP_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
HarmShapeFIRPacked_Q14 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
NSQ->rewhite_flag = 0;
if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
/* Voiced */
lag = psEncCtrlC->pitchL[ k ];
/* Re-whitening */
if( ( k & ( 3 - SKP_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
if( k == 2 ) {
/* RESET DELAYED DECISIONS */
/* Find winner */
RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
Winner_ind = 0;
for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
RDmin_Q10 = psDelDec[ i ].RD_Q10;
Winner_ind = i;
}
}
for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
if( i != Winner_ind ) {
psDelDec[ i ].RD_Q10 += ( SKP_int32_MAX >> 4 );
SKP_assert( psDelDec[ i ].RD_Q10 >= 0 );
}
}
/* Copy final part of signals from winner state to output and long-term filter states */
psDD = &psDelDec[ Winner_ind ];
last_smple_idx = smpl_buf_idx + decisionDelay;
for( i = 0; i < decisionDelay; i++ ) {
last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );
pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND(
SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ],
psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
}
subfr = 0;
}
/* Rewhiten with new A coefs */
start_idx = psEncC->frame_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
SKP_assert( start_idx >= 0 );
SKP_assert( start_idx <= psEncC->frame_length - psEncC->predictLPCOrder );
SKP_memset( FiltState, 0, psEncC->predictLPCOrder * sizeof( SKP_int32 ) );
SKP_Silk_MA_Prediction( &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
A_Q12, FiltState, sLTP + start_idx, psEncC->frame_length - start_idx, psEncC->predictLPCOrder );
NSQ->sLTP_buf_idx = psEncC->frame_length;
NSQ->rewhite_flag = 1;
}
}
SKP_Silk_nsq_del_dec_scale_states( NSQ, psDelDec, x, x_sc_Q10,
subfr_length, sLTP, sLTP_Q16, k, psEncC->nStatesDelayedDecision, smpl_buf_idx,
LTP_scale_Q14, Gains_Q16, psEncCtrlC->pitchL );
SKP_Silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psEncCtrlC->sigtype, x_sc_Q10, q, pxq, sLTP_Q16,
A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ],
Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, psEncC->predictLPCOrder,
psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
x += psEncC->subfr_length;
q += psEncC->subfr_length;
pxq += psEncC->subfr_length;
}
/* Find winner */
RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
Winner_ind = 0;
for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
RDmin_Q10 = psDelDec[ k ].RD_Q10;
Winner_ind = k;
}
}
/* Copy final part of signals from winner state to output and long-term filter states */
psDD = &psDelDec[ Winner_ind ];
psEncCtrlC->Seed = psDD->SeedInit;
last_smple_idx = smpl_buf_idx + decisionDelay;
for( i = 0; i < decisionDelay; i++ ) {
last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );
pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND(
SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
sLTP_Q16[ NSQ->sLTP_buf_idx - decisionDelay + i ] = psDD->Pred_Q16[ last_smple_idx ];
}
SKP_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
SKP_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
/* Update states */
NSQ->sLF_AR_shp_Q12 = psDD->LF_AR_Q12;
NSQ->lagPrev = psEncCtrlC->pitchL[ NB_SUBFR - 1 ];
/* Save quantized speech and noise shaping signals */
SKP_memcpy( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int16 ) );
SKP_memcpy( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int32 ) );
#ifdef USE_UNQUANTIZED_LSFS
DEBUG_STORE_DATA( xq_unq_lsfs.pcm, NSQ->xq, psEncC->frame_length * sizeof( SKP_int16 ) );
#endif
}
/******************************************/
/* Noise shape quantizer for one subframe */
/******************************************/
SKP_INLINE void SKP_Silk_noise_shape_quantizer_del_dec(
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
SKP_int sigtype, /* I Signal type */
const SKP_int32 x_Q10[], /* I */
SKP_int8 q[], /* O */
SKP_int16 xq[], /* O */
SKP_int32 sLTP_Q16[], /* I/O LTP filter state */
const SKP_int16 a_Q12[], /* I Short term prediction coefs */
const SKP_int16 b_Q14[], /* I Long term prediction coefs */
const SKP_int16 AR_shp_Q13[], /* I Noise shaping coefs */
SKP_int lag, /* I Pitch lag */
SKP_int32 HarmShapeFIRPacked_Q14, /* I */
SKP_int Tilt_Q14, /* I Spectral tilt */
SKP_int32 LF_shp_Q14, /* I */
SKP_int32 Gain_Q16, /* I */
SKP_int Lambda_Q10, /* I */
SKP_int offset_Q10, /* I */
SKP_int length, /* I Input length */
SKP_int subfr, /* I Subframe number */
SKP_int shapingLPCOrder, /* I Shaping LPC filter order */
SKP_int predictLPCOrder, /* I Prediction filter order */
SKP_int warping_Q16, /* I */
SKP_int nStatesDelayedDecision, /* I Number of states in decision tree */
SKP_int *smpl_buf_idx, /* I Index to newest samples in buffers */
SKP_int decisionDelay /* I */
)
{
SKP_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
SKP_int32 Winner_rand_state;
SKP_int32 LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14;
SKP_int32 n_LF_Q10, r_Q10, rr_Q20, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
SKP_int32 q1_Q10, q2_Q10, dither, exc_Q10, LPC_exc_Q10, xq_Q10;
SKP_int32 tmp1, tmp2, sLF_AR_shp_Q10;
SKP_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ];
NSQ_del_dec_struct *psDD;
NSQ_sample_struct *psSS;
shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
for( i = 0; i < length; i++ ) {
/* Perform common calculations used in all states */
/* Long-term prediction */
if( sigtype == SIG_TYPE_VOICED ) {
/* Unrolled loop */
LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
pred_lag_ptr++;
} else {
LTP_pred_Q14 = 0;
}
/* Long-term shaping */
if( lag > 0 ) {
/* Symmetric, packed FIR coefficients */
n_LTP_Q14 = SKP_SMULWB( SKP_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
n_LTP_Q14 = SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 );
shp_lag_ptr++;
} else {
n_LTP_Q14 = 0;
}
for( k = 0; k < nStatesDelayedDecision; k++ ) {
/* Delayed decision state */
psDD = &psDelDec[ k ];
/* Sample state */
psSS = psSampleState[ k ];
/* Generate dither */
psDD->Seed = SKP_RAND( psDD->Seed );
/* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
dither = SKP_RSHIFT( psDD->Seed, 31 );
/* Pointer used in short term prediction and shaping */
psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
/* Short-term prediction */
SKP_assert( predictLPCOrder >= 10 ); /* check that unrolling works */
SKP_assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */
SKP_assert( ( ( ( int )( ( char* )( a_Q12 ) - ( ( char* ) 0 ) ) ) & 3 ) == 0 ); /* check that array starts at 4-byte aligned address */
/* Partially unrolled */
LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
for( j = 10; j < predictLPCOrder; j ++ ) {
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], a_Q12[ j ] );
}
/* Noise shape feedback */
SKP_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
/* Output of lowpass section */
tmp2 = SKP_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
/* Output of allpass section */
tmp1 = SKP_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
psDD->sAR2_Q14[ 0 ] = tmp2;
n_AR_Q10 = SKP_SMULWB( tmp2, AR_shp_Q13[ 0 ] );
/* Loop over allpass sections */
for( j = 2; j < shapingLPCOrder; j += 2 ) {
/* Output of allpass section */
tmp2 = SKP_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
psDD->sAR2_Q14[ j - 1 ] = tmp1;
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ j - 1 ] );
/* Output of allpass section */
tmp1 = SKP_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
psDD->sAR2_Q14[ j + 0 ] = tmp2;
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp2, AR_shp_Q13[ j ] );
}
psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 ); /* Q11 -> Q10 */
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psDD->LF_AR_Q12, Tilt_Q14 );
n_LF_Q10 = SKP_LSHIFT( SKP_SMULWB( psDD->Shape_Q10[ *smpl_buf_idx ], LF_shp_Q14 ), 2 );
n_LF_Q10 = SKP_SMLAWT( n_LF_Q10, psDD->LF_AR_Q12, LF_shp_Q14 );
/* Input minus prediction plus noise feedback */
/* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
tmp1 = SKP_SUB32( LTP_pred_Q14, n_LTP_Q14 ); /* Add Q14 stuff */
tmp1 = SKP_RSHIFT( tmp1, 4 ); /* convert to Q10 */
tmp1 = SKP_ADD32( tmp1, LPC_pred_Q10 ); /* add Q10 stuff */
tmp1 = SKP_SUB32( tmp1, n_AR_Q10 ); /* subtract Q10 stuff */
tmp1 = SKP_SUB32( tmp1, n_LF_Q10 ); /* subtract Q10 stuff */
r_Q10 = SKP_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
/* Flip sign depending on dither */
r_Q10 = ( r_Q10 ^ dither ) - dither;
r_Q10 = SKP_SUB32( r_Q10, offset_Q10 );
r_Q10 = SKP_LIMIT_32( r_Q10, -64 << 10, 64 << 10 );
/* Find two quantization level candidates and measure their rate-distortion */
if( r_Q10 < -1536 ) {
q1_Q10 = SKP_LSHIFT( SKP_RSHIFT_ROUND( r_Q10, 10 ), 10 );
r_Q10 = SKP_SUB32( r_Q10, q1_Q10 );
rd1_Q10 = SKP_RSHIFT( SKP_SMLABB( SKP_MUL( -SKP_ADD32( q1_Q10, offset_Q10 ), Lambda_Q10 ), r_Q10, r_Q10 ), 10 );
rd2_Q10 = SKP_ADD32( rd1_Q10, 1024 );
rd2_Q10 = SKP_SUB32( rd2_Q10, SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ) );
q2_Q10 = SKP_ADD32( q1_Q10, 1024 );
} else if( r_Q10 > 512 ) {
q1_Q10 = SKP_LSHIFT( SKP_RSHIFT_ROUND( r_Q10, 10 ), 10 );
r_Q10 = SKP_SUB32( r_Q10, q1_Q10 );
rd1_Q10 = SKP_RSHIFT( SKP_SMLABB( SKP_MUL( SKP_ADD32( q1_Q10, offset_Q10 ), Lambda_Q10 ), r_Q10, r_Q10 ), 10 );
rd2_Q10 = SKP_ADD32( rd1_Q10, 1024 );
rd2_Q10 = SKP_SUB32( rd2_Q10, SKP_SUB_LSHIFT32( Lambda_Q10, r_Q10, 1 ) );
q2_Q10 = SKP_SUB32( q1_Q10, 1024 );
} else { /* r_Q10 >= -1536 && q1_Q10 <= 512 */
rr_Q20 = SKP_SMULBB( offset_Q10, Lambda_Q10 );
rd2_Q10 = SKP_RSHIFT( SKP_SMLABB( rr_Q20, r_Q10, r_Q10 ), 10 );
rd1_Q10 = SKP_ADD32( rd2_Q10, 1024 );
rd1_Q10 = SKP_ADD32( rd1_Q10, SKP_SUB_RSHIFT32( SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ), rr_Q20, 9 ) );
q1_Q10 = -1024;
q2_Q10 = 0;
}
if( rd1_Q10 < rd2_Q10 ) {
psSS[ 0 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd1_Q10 );
psSS[ 1 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd2_Q10 );
psSS[ 0 ].Q_Q10 = q1_Q10;
psSS[ 1 ].Q_Q10 = q2_Q10;
} else {
psSS[ 0 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd2_Q10 );
psSS[ 1 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd1_Q10 );
psSS[ 0 ].Q_Q10 = q2_Q10;
psSS[ 1 ].Q_Q10 = q1_Q10;
}
/* Update states for best quantization */
/* Quantized excitation */
exc_Q10 = SKP_ADD32( offset_Q10, psSS[ 0 ].Q_Q10 );
exc_Q10 = ( exc_Q10 ^ dither ) - dither;
/* Add predictions */
LPC_exc_Q10 = exc_Q10 + SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 );
xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
/* Update states */
sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 );
psSS[ 0 ].sLTP_shp_Q10 = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
psSS[ 0 ].LF_AR_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );
psSS[ 0 ].xq_Q14 = SKP_LSHIFT( xq_Q10, 4 );
psSS[ 0 ].LPC_exc_Q16 = SKP_LSHIFT( LPC_exc_Q10, 6 );
/* Update states for second best quantization */
/* Quantized excitation */
exc_Q10 = SKP_ADD32( offset_Q10, psSS[ 1 ].Q_Q10 );
exc_Q10 = ( exc_Q10 ^ dither ) - dither;
/* Add predictions */
LPC_exc_Q10 = exc_Q10 + SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 );
xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
/* Update states */
sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 );
psSS[ 1 ].sLTP_shp_Q10 = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
psSS[ 1 ].LF_AR_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );
psSS[ 1 ].xq_Q14 = SKP_LSHIFT( xq_Q10, 4 );
psSS[ 1 ].LPC_exc_Q16 = SKP_LSHIFT( LPC_exc_Q10, 6 );
}
*smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */
last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */
/* Find winner */
RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
Winner_ind = 0;
for( k = 1; k < nStatesDelayedDecision; k++ ) {
if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
Winner_ind = k;
}
}
/* Increase RD values of expired states */
Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
for( k = 0; k < nStatesDelayedDecision; k++ ) {
if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
psSampleState[ k ][ 0 ].RD_Q10 = SKP_ADD32( psSampleState[ k ][ 0 ].RD_Q10, ( SKP_int32_MAX >> 4 ) );
psSampleState[ k ][ 1 ].RD_Q10 = SKP_ADD32( psSampleState[ k ][ 1 ].RD_Q10, ( SKP_int32_MAX >> 4 ) );
SKP_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
}
}
/* Find worst in first set and best in second set */
RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
RDmax_ind = 0;
RDmin_ind = 0;
for( k = 1; k < nStatesDelayedDecision; k++ ) {
/* find worst in first set */
if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
RDmax_ind = k;
}
/* find best in second set */
if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
RDmin_ind = k;
}
}
/* Replace a state if best from second set outperforms worst in first set */
if( RDmin_Q10 < RDmax_Q10 ) {
SKP_Silk_copy_del_dec_state( &psDelDec[ RDmax_ind ], &psDelDec[ RDmin_ind ], i );
SKP_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
}
/* Write samples from winner to output and long-term filter states */
psDD = &psDelDec[ Winner_ind ];
if( subfr > 0 || i >= decisionDelay ) {
q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );
xq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND(
SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q10[ last_smple_idx ];
sLTP_Q16[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q16[ last_smple_idx ];
}
NSQ->sLTP_shp_buf_idx++;
NSQ->sLTP_buf_idx++;
/* Update states */
for( k = 0; k < nStatesDelayedDecision; k++ ) {
psDD = &psDelDec[ k ];
psSS = &psSampleState[ k ][ 0 ];
psDD->LF_AR_Q12 = psSS->LF_AR_Q12;
psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
psDD->Xq_Q10[ *smpl_buf_idx ] = SKP_RSHIFT( psSS->xq_Q14, 4 );
psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
psDD->Pred_Q16[ *smpl_buf_idx ] = psSS->LPC_exc_Q16;
psDD->Shape_Q10[ *smpl_buf_idx ] = psSS->sLTP_shp_Q10;
psDD->Seed = SKP_ADD_RSHIFT32( psDD->Seed, psSS->Q_Q10, 10 );
psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
psDD->RD_Q10 = psSS->RD_Q10;
psDD->Gain_Q16[ *smpl_buf_idx ] = Gain_Q16;
}
}
/* Update LPC states */
for( k = 0; k < nStatesDelayedDecision; k++ ) {
psDD = &psDelDec[ k ];
SKP_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
}
}
SKP_INLINE void SKP_Silk_nsq_del_dec_scale_states(
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
const SKP_int16 x[], /* I Input in Q0 */
SKP_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
SKP_int subfr_length, /* I Length of input */
const SKP_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
SKP_int subfr, /* I Subframe number */
SKP_int nStatesDelayedDecision, /* I Number of del dec states */
SKP_int smpl_buf_idx, /* I Index to newest samples in buffers */
const SKP_int LTP_scale_Q14, /* I LTP state scaling */
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
const SKP_int pitchL[ NB_SUBFR ] /* I Pitch lag */
)
{
SKP_int i, k, lag;
SKP_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32;
NSQ_del_dec_struct *psDD;
inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gains_Q16[ subfr ], 1 ), 32 );
inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );
lag = pitchL[ subfr ];
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
if( NSQ->rewhite_flag ) {
inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );
if( subfr == 0 ) {
/* Do LTP downscaling */
inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 );
}
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
SKP_assert( i < MAX_FRAME_LENGTH );
sLTP_Q16[ i ] = SKP_SMULWB( inv_gain_Q32, sLTP[ i ] );
}
}
/* Adjust for changing gain */
if( inv_gain_Q16 != NSQ->prev_inv_gain_Q16 ) {
gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, NSQ->prev_inv_gain_Q16, 16 );
/* Scale long-term shaping state */
for( i = NSQ->sLTP_shp_buf_idx - subfr_length * NB_SUBFR; i < NSQ->sLTP_shp_buf_idx; i++ ) {
NSQ->sLTP_shp_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q10[ i ] );
}
/* Scale long-term prediction state */
if( NSQ->rewhite_flag == 0 ) {
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
sLTP_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );
}
}
for( k = 0; k < nStatesDelayedDecision; k++ ) {
psDD = &psDelDec[ k ];
/* Scale scalar states */
psDD->LF_AR_Q12 = SKP_SMULWW( gain_adj_Q16, psDD->LF_AR_Q12 );
/* Scale short-term prediction and shaping states */
for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
psDD->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
}
for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
psDD->sAR2_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
}
for( i = 0; i < DECISION_DELAY; i++ ) {
psDD->Pred_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->Pred_Q16[ i ] );
psDD->Shape_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->Shape_Q10[ i ] );
}
}
}
/* Scale input */
for( i = 0; i < subfr_length; i++ ) {
x_sc_Q10[ i ] = SKP_RSHIFT( SKP_SMULBB( x[ i ], ( SKP_int16 )inv_gain_Q16 ), 6 );
}
/* save inv_gain */
SKP_assert( inv_gain_Q16 != 0 );
NSQ->prev_inv_gain_Q16 = inv_gain_Q16;
}
SKP_INLINE void SKP_Silk_copy_del_dec_state(
NSQ_del_dec_struct *DD_dst, /* I Dst del dec state */
NSQ_del_dec_struct *DD_src, /* I Src del dec state */
SKP_int LPC_state_idx /* I Index to LPC buffer */
)
{
SKP_memcpy( DD_dst->RandState, DD_src->RandState, sizeof( DD_src->RandState ) );
SKP_memcpy( DD_dst->Q_Q10, DD_src->Q_Q10, sizeof( DD_src->Q_Q10 ) );
SKP_memcpy( DD_dst->Pred_Q16, DD_src->Pred_Q16, sizeof( DD_src->Pred_Q16 ) );
SKP_memcpy( DD_dst->Shape_Q10, DD_src->Shape_Q10, sizeof( DD_src->Shape_Q10 ) );
SKP_memcpy( DD_dst->Xq_Q10, DD_src->Xq_Q10, sizeof( DD_src->Xq_Q10 ) );
SKP_memcpy( DD_dst->sAR2_Q14, DD_src->sAR2_Q14, sizeof( DD_src->sAR2_Q14 ) );
SKP_memcpy( &DD_dst->sLPC_Q14[ LPC_state_idx ], &DD_src->sLPC_Q14[ LPC_state_idx ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
DD_dst->LF_AR_Q12 = DD_src->LF_AR_Q12;
DD_dst->Seed = DD_src->Seed;
DD_dst->SeedInit = DD_src->SeedInit;
DD_dst->RD_Q10 = DD_src->RD_Q10;
}

View File

@ -0,0 +1,388 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
#include "SKP_Silk_PLC.h"
#define NB_ATT 2
static const SKP_int16 HARM_ATT_Q15[NB_ATT] = { 32440, 31130 }; /* 0.99, 0.95 */
static const SKP_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT] = { 31130, 26214 }; /* 0.95, 0.8 */
static const SKP_int16 PLC_RAND_ATTENUATE_UV_Q15[NB_ATT] = { 32440, 29491 }; /* 0.99, 0.9 */
void SKP_Silk_PLC_Reset(
SKP_Silk_decoder_state *psDec /* I/O Decoder state */
)
{
psDec->sPLC.pitchL_Q8 = SKP_RSHIFT( psDec->frame_length, 1 );
}
void SKP_Silk_PLC(
SKP_Silk_decoder_state *psDec, /* I Decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */
SKP_int16 signal[], /* O Concealed signal */
SKP_int length, /* I length of residual */
SKP_int lost /* I Loss flag */
)
{
/* PLC control function */
if( psDec->fs_kHz != psDec->sPLC.fs_kHz ) {
SKP_Silk_PLC_Reset( psDec );
psDec->sPLC.fs_kHz = psDec->fs_kHz;
}
if( lost ) {
/****************************/
/* Generate Signal */
/****************************/
SKP_Silk_PLC_conceal( psDec, psDecCtrl, signal, length );
psDec->lossCnt++;
} else {
/****************************/
/* Update state */
/****************************/
SKP_Silk_PLC_update( psDec, psDecCtrl, signal, length );
}
}
/**************************************************/
/* Update state of PLC */
/**************************************************/
void SKP_Silk_PLC_update(
SKP_Silk_decoder_state *psDec, /* (I/O) Decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* (I/O) Decoder control */
SKP_int16 signal[],
SKP_int length
)
{
SKP_int32 LTP_Gain_Q14, temp_LTP_Gain_Q14;
SKP_int i, j;
SKP_Silk_PLC_struct *psPLC;
psPLC = &psDec->sPLC;
/* Update parameters used in case of packet loss */
psDec->prev_sigtype = psDecCtrl->sigtype;
LTP_Gain_Q14 = 0;
if( psDecCtrl->sigtype == SIG_TYPE_VOICED ) {
/* Find the parameters for the last subframe which contains a pitch pulse */
for( j = 0; j * psDec->subfr_length < psDecCtrl->pitchL[ NB_SUBFR - 1 ]; j++ ) {
temp_LTP_Gain_Q14 = 0;
for( i = 0; i < LTP_ORDER; i++ ) {
temp_LTP_Gain_Q14 += psDecCtrl->LTPCoef_Q14[ ( NB_SUBFR - 1 - j ) * LTP_ORDER + i ];
}
if( temp_LTP_Gain_Q14 > LTP_Gain_Q14 ) {
LTP_Gain_Q14 = temp_LTP_Gain_Q14;
SKP_memcpy( psPLC->LTPCoef_Q14,
&psDecCtrl->LTPCoef_Q14[ SKP_SMULBB( NB_SUBFR - 1 - j, LTP_ORDER ) ],
LTP_ORDER * sizeof( SKP_int16 ) );
psPLC->pitchL_Q8 = SKP_LSHIFT( psDecCtrl->pitchL[ NB_SUBFR - 1 - j ], 8 );
}
}
#if USE_SINGLE_TAP
SKP_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ) );
psPLC->LTPCoef_Q14[ LTP_ORDER / 2 ] = LTP_Gain_Q14;
#endif
/* Limit LT coefs */
if( LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 ) {
SKP_int scale_Q10;
SKP_int32 tmp;
tmp = SKP_LSHIFT( V_PITCH_GAIN_START_MIN_Q14, 10 );
scale_Q10 = SKP_DIV32( tmp, SKP_max( LTP_Gain_Q14, 1 ) );
for( i = 0; i < LTP_ORDER; i++ ) {
psPLC->LTPCoef_Q14[ i ] = SKP_RSHIFT( SKP_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q10 ), 10 );
}
} else if( LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 ) {
SKP_int scale_Q14;
SKP_int32 tmp;
tmp = SKP_LSHIFT( V_PITCH_GAIN_START_MAX_Q14, 14 );
scale_Q14 = SKP_DIV32( tmp, SKP_max( LTP_Gain_Q14, 1 ) );
for( i = 0; i < LTP_ORDER; i++ ) {
psPLC->LTPCoef_Q14[ i ] = SKP_RSHIFT( SKP_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q14 ), 14 );
}
}
} else {
psPLC->pitchL_Q8 = SKP_LSHIFT( SKP_SMULBB( psDec->fs_kHz, 18 ), 8 );
SKP_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ));
}
/* Save LPC coeficients */
SKP_memcpy( psPLC->prevLPC_Q12, psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( SKP_int16 ) );
psPLC->prevLTP_scale_Q14 = psDecCtrl->LTP_scale_Q14;
/* Save Gains */
SKP_memcpy( psPLC->prevGain_Q16, psDecCtrl->Gains_Q16, NB_SUBFR * sizeof( SKP_int32 ) );
}
void SKP_Silk_PLC_conceal(
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int16 signal[], /* O concealed signal */
SKP_int length /* I length of residual */
)
{
SKP_int i, j, k;
SKP_int16 *B_Q14, exc_buf[ MAX_FRAME_LENGTH ], *exc_buf_ptr;
SKP_int16 rand_scale_Q14;
union {
SKP_int16 as_int16[ MAX_LPC_ORDER ];
SKP_int32 as_int32[ MAX_LPC_ORDER / 2 ];
} A_Q12_tmp;
SKP_int32 rand_seed, harm_Gain_Q15, rand_Gain_Q15;
SKP_int lag, idx, sLTP_buf_idx, shift1, shift2;
SKP_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr;
SKP_int32 sig_Q10[ MAX_FRAME_LENGTH ], *sig_Q10_ptr, LPC_exc_Q10, LPC_pred_Q10, LTP_pred_Q14;
SKP_Silk_PLC_struct *psPLC;
psPLC = &psDec->sPLC;
/* Update LTP buffer */
SKP_memcpy( psDec->sLTP_Q16, &psDec->sLTP_Q16[ psDec->frame_length ], psDec->frame_length * sizeof( SKP_int32 ) );
/* LPC concealment. Apply BWE to previous LPC */
SKP_Silk_bwexpander( psPLC->prevLPC_Q12, psDec->LPC_order, BWE_COEF_Q16 );
/* Find random noise component */
/* Scale previous excitation signal */
exc_buf_ptr = exc_buf;
for( k = ( NB_SUBFR >> 1 ); k < NB_SUBFR; k++ ) {
for( i = 0; i < psDec->subfr_length; i++ ) {
exc_buf_ptr[ i ] = ( SKP_int16 )SKP_RSHIFT(
SKP_SMULWW( psDec->exc_Q10[ i + k * psDec->subfr_length ], psPLC->prevGain_Q16[ k ] ), 10 );
}
exc_buf_ptr += psDec->subfr_length;
}
/* Find the subframe with lowest energy of the last two and use that as random noise generator */
SKP_Silk_sum_sqr_shift( &energy1, &shift1, exc_buf, psDec->subfr_length );
SKP_Silk_sum_sqr_shift( &energy2, &shift2, &exc_buf[ psDec->subfr_length ], psDec->subfr_length );
if( SKP_RSHIFT( energy1, shift2 ) < SKP_RSHIFT( energy2, shift1 ) ) {
/* First sub-frame has lowest energy */
rand_ptr = &psDec->exc_Q10[ SKP_max_int( 0, 3 * psDec->subfr_length - RAND_BUF_SIZE ) ];
} else {
/* Second sub-frame has lowest energy */
rand_ptr = &psDec->exc_Q10[ SKP_max_int( 0, psDec->frame_length - RAND_BUF_SIZE ) ];
}
/* Setup Gain to random noise component */
B_Q14 = psPLC->LTPCoef_Q14;
rand_scale_Q14 = psPLC->randScale_Q14;
/* Setup attenuation gains */
harm_Gain_Q15 = HARM_ATT_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
if( psDec->prev_sigtype == SIG_TYPE_VOICED ) {
rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
} else {
rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
}
/* First Lost frame */
if( psDec->lossCnt == 0 ) {
rand_scale_Q14 = (1 << 14 );
/* Reduce random noise Gain for voiced frames */
if( psDec->prev_sigtype == SIG_TYPE_VOICED ) {
for( i = 0; i < LTP_ORDER; i++ ) {
rand_scale_Q14 -= B_Q14[ i ];
}
rand_scale_Q14 = SKP_max_16( 3277, rand_scale_Q14 ); /* 0.2 */
rand_scale_Q14 = ( SKP_int16 )SKP_RSHIFT( SKP_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 );
}
/* Reduce random noise for unvoiced frames with high LPC gain */
if( psDec->prev_sigtype == SIG_TYPE_UNVOICED ) {
SKP_int32 invGain_Q30, down_scale_Q30;
SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, psPLC->prevLPC_Q12, psDec->LPC_order );
down_scale_Q30 = SKP_min_32( SKP_RSHIFT( ( 1 << 30 ), LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
down_scale_Q30 = SKP_max_32( SKP_RSHIFT( ( 1 << 30 ), LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
down_scale_Q30 = SKP_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES );
rand_Gain_Q15 = SKP_RSHIFT( SKP_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 );
}
}
rand_seed = psPLC->rand_seed;
lag = SKP_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );
sLTP_buf_idx = psDec->frame_length;
/***************************/
/* LTP synthesis filtering */
/***************************/
sig_Q10_ptr = sig_Q10;
for( k = 0; k < NB_SUBFR; k++ ) {
/* Setup pointer */
pred_lag_ptr = &psDec->sLTP_Q16[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
for( i = 0; i < psDec->subfr_length; i++ ) {
rand_seed = SKP_RAND( rand_seed );
idx = SKP_RSHIFT( rand_seed, 25 ) & RAND_BUF_MASK;
/* Unrolled loop */
LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], B_Q14[ 0 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
pred_lag_ptr++;
/* Generate LPC residual */
LPC_exc_Q10 = SKP_LSHIFT( SKP_SMULWB( rand_ptr[ idx ], rand_scale_Q14 ), 2 ); /* Random noise part */
LPC_exc_Q10 = SKP_ADD32( LPC_exc_Q10, SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) ); /* Harmonic part */
/* Update states */
psDec->sLTP_Q16[ sLTP_buf_idx ] = SKP_LSHIFT( LPC_exc_Q10, 6 );
sLTP_buf_idx++;
/* Save LPC residual */
sig_Q10_ptr[ i ] = LPC_exc_Q10;
}
sig_Q10_ptr += psDec->subfr_length;
/* Gradually reduce LTP gain */
for( j = 0; j < LTP_ORDER; j++ ) {
B_Q14[ j ] = SKP_RSHIFT( SKP_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );
}
/* Gradually reduce excitation gain */
rand_scale_Q14 = SKP_RSHIFT( SKP_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
/* Slowly increase pitch lag */
psPLC->pitchL_Q8 += SKP_SMULWB( psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );
psPLC->pitchL_Q8 = SKP_min_32( psPLC->pitchL_Q8, SKP_LSHIFT( SKP_SMULBB( MAX_PITCH_LAG_MS, psDec->fs_kHz ), 8 ) );
lag = SKP_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );
}
/***************************/
/* LPC synthesis filtering */
/***************************/
sig_Q10_ptr = sig_Q10;
/* Preload LPC coeficients to array on stack. Gives small performance gain */
SKP_memcpy( A_Q12_tmp.as_int16, psPLC->prevLPC_Q12, psDec->LPC_order * sizeof( SKP_int16 ) );
SKP_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
for( k = 0; k < NB_SUBFR; k++ ) {
for( i = 0; i < psDec->subfr_length; i++ ){
/* partly unrolled */
LPC_pred_Q10 = SKP_SMULWB( psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp.as_int16[ 0 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp.as_int16[ 1 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp.as_int16[ 2 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp.as_int16[ 3 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp.as_int16[ 4 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp.as_int16[ 5 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp.as_int16[ 6 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp.as_int16[ 7 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp.as_int16[ 8 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp.as_int16[ 9 ] );
for( j = 10; j < psDec->LPC_order; j++ ) {
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp.as_int16[ j ] );
}
/* Add prediction to LPC residual */
sig_Q10_ptr[ i ] = SKP_ADD32( sig_Q10_ptr[ i ], LPC_pred_Q10 );
/* Update states */
psDec->sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT( sig_Q10_ptr[ i ], 4 );
}
sig_Q10_ptr += psDec->subfr_length;
/* Update LPC filter state */
SKP_memcpy( psDec->sLPC_Q14, &psDec->sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) );
}
/* Scale with Gain */
for( i = 0; i < psDec->frame_length; i++ ) {
signal[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( sig_Q10[ i ], psPLC->prevGain_Q16[ NB_SUBFR - 1 ] ), 10 ) );
}
/**************************************/
/* Update states */
/**************************************/
psPLC->rand_seed = rand_seed;
psPLC->randScale_Q14 = rand_scale_Q14;
for( i = 0; i < NB_SUBFR; i++ ) {
psDecCtrl->pitchL[ i ] = lag;
}
}
/* Glues concealed frames with new good recieved frames */
void SKP_Silk_PLC_glue_frames(
SKP_Silk_decoder_state *psDec, /* I/O decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int16 signal[], /* I/O signal */
SKP_int length /* I length of residual */
)
{
SKP_int i, energy_shift;
SKP_int32 energy;
SKP_Silk_PLC_struct *psPLC;
psPLC = &psDec->sPLC;
if( psDec->lossCnt ) {
/* Calculate energy in concealed residual */
SKP_Silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, signal, length );
psPLC->last_frame_lost = 1;
} else {
if( psDec->sPLC.last_frame_lost ) {
/* Calculate residual in decoded signal if last frame was lost */
SKP_Silk_sum_sqr_shift( &energy, &energy_shift, signal, length );
/* Normalize energies */
if( energy_shift > psPLC->conc_energy_shift ) {
psPLC->conc_energy = SKP_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift );
} else if( energy_shift < psPLC->conc_energy_shift ) {
energy = SKP_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift );
}
/* Fade in the energy difference */
if( energy > psPLC->conc_energy ) {
SKP_int32 frac_Q24, LZ;
SKP_int32 gain_Q12, slope_Q12;
LZ = SKP_Silk_CLZ32( psPLC->conc_energy );
LZ = LZ - 1;
psPLC->conc_energy = SKP_LSHIFT( psPLC->conc_energy, LZ );
energy = SKP_RSHIFT( energy, SKP_max_32( 24 - LZ, 0 ) );
frac_Q24 = SKP_DIV32( psPLC->conc_energy, SKP_max( energy, 1 ) );
gain_Q12 = SKP_Silk_SQRT_APPROX( frac_Q24 );
slope_Q12 = SKP_DIV32_16( ( 1 << 12 ) - gain_Q12, length );
for( i = 0; i < length; i++ ) {
signal[ i ] = SKP_RSHIFT( SKP_MUL( gain_Q12, signal[ i ] ), 12 );
gain_Q12 += slope_Q12;
gain_Q12 = SKP_min( gain_Q12, ( 1 << 12 ) );
}
}
}
psPLC->last_frame_lost = 0;
}
}

View File

@ -0,0 +1,79 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef SKP_SILK_PLC_FIX_H
#define SKP_SILK_PLC_FIX_H
#include "SKP_Silk_main.h"
#define BWE_COEF_Q16 64880 /* 0.99 in Q16 */
#define V_PITCH_GAIN_START_MIN_Q14 11469 /* 0.7 in Q14 */
#define V_PITCH_GAIN_START_MAX_Q14 15565 /* 0.95 in Q14 */
#define MAX_PITCH_LAG_MS 18
#define SA_THRES_Q8 50
#define USE_SINGLE_TAP 1
#define RAND_BUF_SIZE 128
#define RAND_BUF_MASK (RAND_BUF_SIZE - 1)
#define LOG2_INV_LPC_GAIN_HIGH_THRES 3 /* 2^3 = 8 dB LPC gain */
#define LOG2_INV_LPC_GAIN_LOW_THRES 8 /* 2^8 = 24 dB LPC gain */
#define PITCH_DRIFT_FAC_Q16 655 /* 0.01 in Q16 */
void SKP_Silk_PLC_Reset(
SKP_Silk_decoder_state *psDec /* I/O Decoder state */
);
void SKP_Silk_PLC(
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int16 signal[], /* I/O signal */
SKP_int length, /* I length of residual */
SKP_int lost /* I Loss flag */
);
void SKP_Silk_PLC_update(
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int16 signal[],
SKP_int length
);
void SKP_Silk_PLC_conceal(
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int16 signal[], /* O LPC residual signal */
SKP_int length /* I length of signal */
);
void SKP_Silk_PLC_glue_frames(
SKP_Silk_decoder_state *psDec, /* I/O decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int16 signal[], /* I/O signal */
SKP_int length /* I length of signal */
);
#endif

View File

@ -0,0 +1,636 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef _SKP_SILK_SIGPROC_FIX_H_
#define _SKP_SILK_SIGPROC_FIX_H_
#ifdef __cplusplus
extern "C"
{
#endif
#define SKP_Silk_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */
#define SKP_Silk_MAX_CORRELATION_LENGTH 640 /* max input length to the correlation */
#include "SKP_Silk_typedef.h"
#include <string.h>
#include <stdlib.h> /* for abs() */
#include "SKP_Silk_resampler_structs.h"
# include "SKP_Silk_macros.h"
/********************************************************************/
/* SIGNAL PROCESSING FUNCTIONS */
/********************************************************************/
/*!
* Initialize/reset the resampler state for a given pair of input/output sampling rates
*/
SKP_int SKP_Silk_resampler_init(
SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */
SKP_int32 Fs_Hz_in, /* I: Input sampling rate (Hz) */
SKP_int32 Fs_Hz_out /* I: Output sampling rate (Hz) */
);
/*!
* Clear the states of all resampling filters, without resetting sampling rate ratio
*/
SKP_int SKP_Silk_resampler_clear(
SKP_Silk_resampler_state_struct *S /* I/O: Resampler state */
);
/*!
* Resampler: convert from one sampling rate to another
*/
SKP_int SKP_Silk_resampler(
SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */
SKP_int16 out[], /* O: Output signal */
const SKP_int16 in[], /* I: Input signal */
SKP_int32 inLen /* I: Number of input samples */
);
/*!
Upsample 2x, low quality
*/
void SKP_Silk_resampler_up2(
SKP_int32 *S, /* I/O: State vector [ 2 ] */
SKP_int16 *out, /* O: Output signal [ 2 * len ] */
const SKP_int16 *in, /* I: Input signal [ len ] */
SKP_int32 len /* I: Number of input samples */
);
/*!
* Downsample 2x, mediocre quality
*/
void SKP_Silk_resampler_down2(
SKP_int32 *S, /* I/O: State vector [ 2 ] */
SKP_int16 *out, /* O: Output signal [ len ] */
const SKP_int16 *in, /* I: Input signal [ floor(len/2) ] */
SKP_int32 inLen /* I: Number of input samples */
);
/*!
* Downsample by a factor 2/3, low quality
*/
void SKP_Silk_resampler_down2_3(
SKP_int32 *S, /* I/O: State vector [ 6 ] */
SKP_int16 *out, /* O: Output signal [ floor(2*inLen/3) ] */
const SKP_int16 *in, /* I: Input signal [ inLen ] */
SKP_int32 inLen /* I: Number of input samples */
);
/*!
* Downsample by a factor 3, low quality
*/
void SKP_Silk_resampler_down3(
SKP_int32 *S, /* I/O: State vector [ 8 ] */
SKP_int16 *out, /* O: Output signal [ floor(inLen/3) ] */
const SKP_int16 *in, /* I: Input signal [ inLen ] */
SKP_int32 inLen /* I: Number of input samples */
);
/*!
* second order ARMA filter
* can handle (slowly) varying coefficients
*/
void SKP_Silk_biquad(
const SKP_int16 *in, /* I: input signal */
const SKP_int16 *B, /* I: MA coefficients, Q13 [3] */
const SKP_int16 *A, /* I: AR coefficients, Q13 [2] */
SKP_int32 *S, /* I/O: state vector [2] */
SKP_int16 *out, /* O: output signal */
const SKP_int32 len /* I: signal length */
);
/*!
* Second order ARMA filter;
* slower than biquad() but uses more precise coefficients
* can handle (slowly) varying coefficients
*/
void SKP_Silk_biquad_alt(
const SKP_int16 *in, /* I: Input signal */
const SKP_int32 *B_Q28, /* I: MA coefficients [3] */
const SKP_int32 *A_Q28, /* I: AR coefficients [2] */
SKP_int32 *S, /* I/O: State vector [2] */
SKP_int16 *out, /* O: Output signal */
const SKP_int32 len /* I: Signal length (must be even) */
);
/*!
* variable order MA filter. Prediction error filter implementation. Coeficients negated and starting with coef to x[n - 1]
*/
void SKP_Silk_MA_Prediction(
const SKP_int16 *in, /* I: Input signal */
const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
SKP_int32 *S, /* I/O: State vector [order] */
SKP_int16 *out, /* O: Output signal */
const SKP_int32 len, /* I: Signal length */
const SKP_int32 order /* I: Filter order */
);
/*!
* 16th order AR filter for LPC synthesis, coefficients are in Q12
*/
void SKP_Silk_LPC_synthesis_order16(
const SKP_int16 *in, /* I: excitation signal */
const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */
const SKP_int32 Gain_Q26, /* I: gain */
SKP_int32 *S, /* I/O: state vector [16] */
SKP_int16 *out, /* O: output signal */
const SKP_int32 len /* I: signal length, must be multiple of 16 */
);
/* variable order MA prediction error filter. */
/* Inverse filter of SKP_Silk_LPC_synthesis_filter */
void SKP_Silk_LPC_analysis_filter(
const SKP_int16 *in, /* I: Input signal */
const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
SKP_int16 *S, /* I/O: State vector [order] */
SKP_int16 *out, /* O: Output signal */
const SKP_int32 len, /* I: Signal length */
const SKP_int32 Order /* I: Filter order */
);
/* even order AR filter */
void SKP_Silk_LPC_synthesis_filter(
const SKP_int16 *in, /* I: excitation signal */
const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */
const SKP_int32 Gain_Q26, /* I: gain */
SKP_int32 *S, /* I/O: state vector [Order] */
SKP_int16 *out, /* O: output signal */
const SKP_int32 len, /* I: signal length */
const SKP_int Order /* I: filter order, must be even */
);
/* Chirp (bandwidth expand) LP AR filter */
void SKP_Silk_bwexpander(
SKP_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */
const SKP_int d, /* I Length of ar */
SKP_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */
);
/* Chirp (bandwidth expand) LP AR filter */
void SKP_Silk_bwexpander_32(
SKP_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */
const SKP_int d, /* I Length of ar */
SKP_int32 chirp_Q16 /* I Chirp factor in Q16 */
);
/* Compute inverse of LPC prediction gain, and */
/* test if LPC coefficients are stable (all poles within unit circle) */
SKP_int SKP_Silk_LPC_inverse_pred_gain( /* O: Returns 1 if unstable, otherwise 0 */
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
const SKP_int16 *A_Q12, /* I: Prediction coefficients, Q12 [order] */
const SKP_int order /* I: Prediction order */
);
SKP_int SKP_Silk_LPC_inverse_pred_gain_Q24( /* O: Returns 1 if unstable, otherwise 0 */
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
const SKP_int32 *A_Q24, /* I: Prediction coefficients, Q24 [order] */
const SKP_int order /* I: Prediction order */
);
/* split signal in two decimated bands using first-order allpass filters */
void SKP_Silk_ana_filt_bank_1(
const SKP_int16 *in, /* I: Input signal [N] */
SKP_int32 *S, /* I/O: State vector [2] */
SKP_int16 *outL, /* O: Low band [N/2] */
SKP_int16 *outH, /* O: High band [N/2] */
SKP_int32 *scratch, /* I: Scratch memory [3*N/2] */
const SKP_int32 N /* I: Number of input samples */
);
/********************************************************************/
/* SCALAR FUNCTIONS */
/********************************************************************/
/* Approximation of 128 * log2() (very close inverse of approx 2^() below) */
/* Convert input to a log scale */
SKP_int32 SKP_Silk_lin2log(const SKP_int32 inLin); /* I: Input in linear scale */
/* Approximation of a sigmoid function */
SKP_int SKP_Silk_sigm_Q15(SKP_int in_Q5);
/* approximation of 2^() (exact inverse of approx log2() above) */
/* convert input to a linear scale */
SKP_int32 SKP_Silk_log2lin(const SKP_int32 inLog_Q7); /* I: input on log scale */
/* Function that returns the maximum absolut value of the input vector */
SKP_int16 SKP_Silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */
const SKP_int16 *vec, /* I Input vector [len] */
const SKP_int32 len /* I Length of input vector */
);
/* Compute number of bits to right shift the sum of squares of a vector */
/* of int16s to make it fit in an int32 */
void SKP_Silk_sum_sqr_shift(
SKP_int32 *energy, /* O Energy of x, after shifting to the right */
SKP_int *shift, /* O Number of bits right shift applied to energy */
const SKP_int16 *x, /* I Input vector */
SKP_int len /* I Length of input vector */
);
/* Calculates the reflection coefficients from the correlation sequence */
/* Faster than schur64(), but much less accurate. */
/* Uses SMLAWB(), requiring armv5E and higher. */
SKP_int32 SKP_Silk_schur( /* O: Returns residual energy */
SKP_int16 *rc_Q15, /* O: reflection coefficients [order] Q15 */
const SKP_int32 *c, /* I: correlations [order+1] */
const SKP_int32 order /* I: prediction order */
);
/* Calculates the reflection coefficients from the correlation sequence */
/* Slower than schur(), but more accurate. */
/* Uses SMULL(), available on armv4 */
SKP_int32 SKP_Silk_schur64( /* O: returns residual energy */
SKP_int32 rc_Q16[], /* O: Reflection coefficients [order] Q16 */
const SKP_int32 c[], /* I: Correlations [order+1] */
SKP_int32 order /* I: Prediction order */
);
/* Step up function, converts reflection coefficients to prediction coefficients */
void SKP_Silk_k2a(
SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
const SKP_int16 *rc_Q15, /* I: Reflection coefficients [order] Q15 */
const SKP_int32 order /* I: Prediction order */
);
/* Step up function, converts reflection coefficients to prediction coefficients */
void SKP_Silk_k2a_Q16(
SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
const SKP_int32 *rc_Q16, /* I: Reflection coefficients [order] Q16 */
const SKP_int32 order /* I: Prediction order */
);
/* Apply sine window to signal vector. */
/* Window types: */
/* 1 -> sine window from 0 to pi/2 */
/* 2 -> sine window from pi/2 to pi */
/* Every other sample is linearly interpolated, for speed. */
void SKP_Silk_apply_sine_window(
SKP_int16 px_win[], /* O Pointer to windowed signal */
const SKP_int16 px[], /* I Pointer to input signal */
const SKP_int win_type, /* I Selects a window type */
const SKP_int length /* I Window length, multiple of 4 */
);
/* Compute autocorrelation */
void SKP_Silk_autocorr(
SKP_int32 *results, /* O Result (length correlationCount) */
SKP_int *scale, /* O Scaling of the correlation vector */
const SKP_int16 *inputData, /* I Input data to correlate */
const SKP_int inputDataSize, /* I Length of input */
const SKP_int correlationCount /* I Number of correlation taps to compute */
);
/* Pitch estimator */
#define SKP_Silk_PITCH_EST_MIN_COMPLEX 0
#define SKP_Silk_PITCH_EST_MID_COMPLEX 1
#define SKP_Silk_PITCH_EST_MAX_COMPLEX 2
void SKP_Silk_decode_pitch(
SKP_int lagIndex, /* I */
SKP_int contourIndex, /* O */
SKP_int pitch_lags[], /* O 4 pitch values */
SKP_int Fs_kHz /* I sampling frequency (kHz) */
);
SKP_int SKP_Silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
const SKP_int16 *signal, /* I Signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz */
SKP_int *pitch_out, /* O 4 pitch lag values */
SKP_int *lagIndex, /* O Lag Index */
SKP_int *contourIndex, /* O Pitch contour Index */
SKP_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */
SKP_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
const SKP_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */
const SKP_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */
const SKP_int Fs_kHz, /* I Sample frequency (kHz) */
const SKP_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
const SKP_int forLJC /* I 1 if this function is called from LJC code, 0 otherwise. */
);
/* parameter defining the size and accuracy of the piecewise linear */
/* cosine approximatin table. */
#define LSF_COS_TAB_SZ_FIX 128
/* rom table with cosine values */
extern const SKP_int SKP_Silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ];
/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
void SKP_Silk_A2NLSF(
SKP_int *NLSF, /* O Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] */
SKP_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */
const SKP_int d /* I Filter order (must be even) */
);
/* compute whitening filter coefficients from normalized line spectral frequencies */
void SKP_Silk_NLSF2A(
SKP_int16 *a, /* o monic whitening filter coefficients in Q12, [d] */
const SKP_int *NLSF, /* i normalized line spectral frequencies in Q15, [d] */
const SKP_int d /* i filter order (should be even) */
);
void SKP_Silk_insertion_sort_increasing(
SKP_int32 *a, /* I/O Unsorted / Sorted vector */
SKP_int *index, /* O: Index vector for the sorted elements */
const SKP_int L, /* I: Vector length */
const SKP_int K /* I: Number of correctly sorted positions */
);
void SKP_Silk_insertion_sort_decreasing_int16(
SKP_int16 *a, /* I/O: Unsorted / Sorted vector */
SKP_int *index, /* O: Index vector for the sorted elements */
const SKP_int L, /* I: Vector length */
const SKP_int K /* I: Number of correctly sorted positions */
);
void SKP_Silk_insertion_sort_increasing_all_values(
SKP_int *a, /* I/O: Unsorted / Sorted vector */
const SKP_int L /* I: Vector length */
);
/* NLSF stabilizer, for a single input data vector */
void SKP_Silk_NLSF_stabilize(
SKP_int *NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vector in Q15 [L] */
const SKP_int *NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */
const SKP_int L /* I: Number of NLSF parameters in the input vector */
);
/* Laroia low complexity NLSF weights */
void SKP_Silk_NLSF_VQ_weights_laroia(
SKP_int *pNLSFW_Q6, /* O: Pointer to input vector weights [D x 1] */
const SKP_int *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */
const SKP_int D /* I: Input vector dimension (even) */
);
/* Compute reflection coefficients from input signal */
void SKP_Silk_burg_modified(
SKP_int32 *res_nrg, /* O residual energy */
SKP_int *res_nrgQ, /* O residual energy Q value */
SKP_int32 A_Q16[], /* O prediction coefficients (length order) */
const SKP_int16 x[], /* I input signal, length: nb_subfr * ( D + subfr_length ) */
const SKP_int subfr_length, /* I input signal subframe length (including D preceeding samples) */
const SKP_int nb_subfr, /* I number of subframes stacked in x */
const SKP_int32 WhiteNoiseFrac_Q32, /* I fraction added to zero-lag autocorrelation */
const SKP_int D /* I order */
);
/* Copy and multiply a vector by a constant */
void SKP_Silk_scale_copy_vector16(
SKP_int16 *data_out,
const SKP_int16 *data_in,
SKP_int32 gain_Q16, /* I: gain in Q16 */
const SKP_int dataSize /* I: length */
);
/* Some for the LTP related function requires Q26 to work.*/
void SKP_Silk_scale_vector32_Q26_lshift_18(
SKP_int32 *data1, /* I/O: Q0/Q18 */
SKP_int32 gain_Q26, /* I: Q26 */
SKP_int dataSize /* I: length */
);
/********************************************************************/
/* INLINE ARM MATH */
/********************************************************************/
/* return sum(inVec1[i]*inVec2[i]) */
/* inVec1 and inVec2 should be increasing ordered, and starting address should be 4 byte aligned. (a factor of 4)*/
SKP_int32 SKP_Silk_inner_prod_aligned(
const SKP_int16* const inVec1, /* I input vector 1 */
const SKP_int16* const inVec2, /* I input vector 2 */
const SKP_int len /* I vector lengths */
);
SKP_int64 SKP_Silk_inner_prod16_aligned_64(
const SKP_int16 *inVec1, /* I input vector 1 */
const SKP_int16 *inVec2, /* I input vector 2 */
const SKP_int len /* I vector lengths */
);
/********************************************************************/
/* MACROS */
/********************************************************************/
/* Rotate a32 right by 'rot' bits. Negative rot values result in rotating
left. Output is 32bit int.
Note: contemporary compilers recognize the C expressions below and
compile them into 'ror' instructions if available. No need for inline ASM! */
#if defined(EMBEDDED_MIPS)
/* For MIPS (and most likely for ARM! and >=i486) we don't have to handle
negative rot's as only 5 bits of rot are encoded into ROR instructions. */
SKP_INLINE SKP_int32 SKP_ROR32(SKP_int32 a32, SKP_int rot)
{
SKP_uint32 _x = (SKP_uint32) a32;
SKP_uint32 _r = (SKP_uint32) rot;
return (SKP_int32) ((_x << (32 - _r)) | (_x >> _r));
}
#else
/* PPC must use this generic implementation. */
SKP_INLINE SKP_int32 SKP_ROR32( SKP_int32 a32, SKP_int rot )
{
SKP_uint32 x = (SKP_uint32) a32;
SKP_uint32 r = (SKP_uint32) rot;
SKP_uint32 m = (SKP_uint32) -rot;
if(rot <= 0)
return (SKP_int32) ((x << m) | (x >> (32 - m)));
else
return (SKP_int32) ((x << (32 - r)) | (x >> r));
}
#endif
/* Allocate SKP_int16 alligned to 4-byte memory address */
#if EMBEDDED_ARM
#if defined(_WIN32) && defined(_M_ARM)
#define SKP_DWORD_ALIGN __declspec(align(4))
#else
#define SKP_DWORD_ALIGN __attribute__((aligned(4)))
#endif
#else
#define SKP_DWORD_ALIGN
#endif
/* Useful Macros that can be adjusted to other platforms */
#define SKP_memcpy(a, b, c) memcpy((a), (b), (c)) /* Dest, Src, ByteCount */
#define SKP_memset(a, b, c) memset((a), (b), (c)) /* Dest, value, ByteCount */
#define SKP_memmove(a, b, c) memmove((a), (b), (c)) /* Dest, Src, ByteCount */
/* fixed point macros */
// (a32 * b32) output have to be 32bit int
#define SKP_MUL(a32, b32) ((a32) * (b32))
// (a32 * b32) output have to be 32bit uint
#define SKP_MUL_uint(a32, b32) SKP_MUL(a32, b32)
// a32 + (b32 * c32) output have to be 32bit int
#define SKP_MLA(a32, b32, c32) SKP_ADD32((a32),((b32) * (c32)))
/* ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */
#define SKP_SMULTT(a32, b32) (((a32) >> 16) * ((b32) >> 16))
/* a32 + ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */
#define SKP_SMLATT(a32, b32, c32) SKP_ADD32((a32),((b32) >> 16) * ((c32) >> 16))
#define SKP_SMLALBB(a64, b16, c16) SKP_ADD64((a64),(SKP_int64)((SKP_int32)(b16) * (SKP_int32)(c16)))
// (a32 * b32)
#define SKP_SMULL(a32, b32) ((SKP_int64)(a32) * /*(SKP_int64)*/(b32))
/* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
(just standard two's complement implementation-specific behaviour) */
#define SKP_ADD32_ovflw(a, b) ((SKP_int32)((SKP_uint32)(a) + (SKP_uint32)(b)))
/* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
(just standard two's complement implementation-specific behaviour) */
#define SKP_SUB32_ovflw(a, b) ((SKP_int32)((SKP_uint32)(a) - (SKP_uint32)(b)))
/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */
#define SKP_MLA_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), (SKP_uint32)(b32) * (SKP_uint32)(c32))
#ifndef SKP_SMLABB_ovflw
#define SKP_SMLABB_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULBB((b32),(c32)))
#endif
#define SKP_SMLATT_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULTT((b32),(c32)))
#define SKP_SMLAWB_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULWB((b32),(c32)))
#define SKP_SMLAWT_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULWT((b32),(c32)))
#define SKP_DIV32_16(a32, b16) ((SKP_int32)((a32) / (b16)))
#define SKP_DIV32(a32, b32) ((SKP_int32)((a32) / (b32)))
#define SKP_ADD32(a, b) ((a) + (b))
#define SKP_ADD64(a, b) ((a) + (b))
#define SKP_SUB32(a, b) ((a) - (b))
#define SKP_SAT16(a) ((a) > SKP_int16_MAX ? SKP_int16_MAX : \
((a) < SKP_int16_MIN ? SKP_int16_MIN : (a)))
#define SKP_SAT32(a) ((a) > SKP_int32_MAX ? SKP_int32_MAX : \
((a) < SKP_int32_MIN ? SKP_int32_MIN : (a)))
#define SKP_CHECK_FIT16(a) (a)
#define SKP_CHECK_FIT32(a) (a)
#define SKP_ADD_SAT16(a, b) (SKP_int16)SKP_SAT16( SKP_ADD32( (SKP_int32)(a), (b) ) )
/* Add with saturation for positive input values */
#define SKP_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? SKP_int32_MAX : ((a)+(b)))
#define SKP_LSHIFT32(a, shift) ((a)<<(shift)) // shift >= 0, shift < 32
#define SKP_LSHIFT64(a, shift) ((a)<<(shift)) // shift >= 0, shift < 64
#define SKP_LSHIFT(a, shift) SKP_LSHIFT32(a, shift) // shift >= 0, shift < 32
#define SKP_RSHIFT32(a, shift) ((a)>>(shift)) // shift >= 0, shift < 32
#define SKP_RSHIFT64(a, shift) ((a)>>(shift)) // shift >= 0, shift < 64
#define SKP_RSHIFT(a, shift) SKP_RSHIFT32(a, shift) // shift >= 0, shift < 32
/* saturates before shifting */
#define SKP_LSHIFT_SAT32(a, shift) (SKP_LSHIFT32( SKP_LIMIT_32( (a), SKP_RSHIFT32( SKP_int32_MIN, (shift) ), \
SKP_RSHIFT32( SKP_int32_MAX, (shift) ) ), (shift) ))
#define SKP_LSHIFT_ovflw(a, shift) ((a)<<(shift)) // shift >= 0, allowed to overflow
#define SKP_LSHIFT_uint(a, shift) ((a)<<(shift)) // shift >= 0
#define SKP_RSHIFT_uint(a, shift) ((a)>>(shift)) // shift >= 0
#define SKP_ADD_LSHIFT(a, b, shift) ((a) + SKP_LSHIFT((b), (shift))) // shift >= 0
#define SKP_ADD_LSHIFT32(a, b, shift) SKP_ADD32((a), SKP_LSHIFT32((b), (shift))) // shift >= 0
#define SKP_ADD_RSHIFT(a, b, shift) ((a) + SKP_RSHIFT((b), (shift))) // shift >= 0
#define SKP_ADD_RSHIFT32(a, b, shift) SKP_ADD32((a), SKP_RSHIFT32((b), (shift))) // shift >= 0
#define SKP_ADD_RSHIFT_uint(a, b, shift) ((a) + SKP_RSHIFT_uint((b), (shift))) // shift >= 0
#define SKP_SUB_LSHIFT32(a, b, shift) SKP_SUB32((a), SKP_LSHIFT32((b), (shift))) // shift >= 0
#define SKP_SUB_RSHIFT32(a, b, shift) SKP_SUB32((a), SKP_RSHIFT32((b), (shift))) // shift >= 0
/* Requires that shift > 0 */
#define SKP_RSHIFT_ROUND(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)
#define SKP_RSHIFT_ROUND64(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)
/* Number of rightshift required to fit the multiplication */
#define SKP_NSHIFT_MUL_32_32(a, b) ( -(31- (32-SKP_Silk_CLZ32(SKP_abs(a)) + (32-SKP_Silk_CLZ32(SKP_abs(b))))) )
#define SKP_min(a, b) (((a) < (b)) ? (a) : (b))
#define SKP_max(a, b) (((a) > (b)) ? (a) : (b))
/* Macro to convert floating-point constants to fixed-point */
#define SKP_FIX_CONST( C, Q ) ((SKP_int32)((C) * ((SKP_int64)1 << (Q)) + 0.5))
/* SKP_min() versions with typecast in the function call */
SKP_INLINE SKP_int SKP_min_int(SKP_int a, SKP_int b)
{
return (((a) < (b)) ? (a) : (b));
}
SKP_INLINE SKP_int32 SKP_min_32(SKP_int32 a, SKP_int32 b)
{
return (((a) < (b)) ? (a) : (b));
}
/* SKP_min() versions with typecast in the function call */
SKP_INLINE SKP_int SKP_max_int(SKP_int a, SKP_int b)
{
return (((a) > (b)) ? (a) : (b));
}
SKP_INLINE SKP_int16 SKP_max_16(SKP_int16 a, SKP_int16 b)
{
return (((a) > (b)) ? (a) : (b));
}
SKP_INLINE SKP_int32 SKP_max_32(SKP_int32 a, SKP_int32 b)
{
return (((a) > (b)) ? (a) : (b));
}
#define SKP_LIMIT( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \
: ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))))
#define SKP_LIMIT_int SKP_LIMIT
#define SKP_LIMIT_32 SKP_LIMIT
//#define SKP_non_neg(a) ((a) & ((-(a)) >> (8 * sizeof(a) - 1))) /* doesn't seem faster than SKP_max(0, a);
#define SKP_abs(a) (((a) > 0) ? (a) : -(a)) // Be careful, SKP_abs returns wrong when input equals to SKP_intXX_MIN
#define SKP_abs_int32(a) (((a) ^ ((a) >> 31)) - ((a) >> 31))
/* PSEUDO-RANDOM GENERATOR */
/* Make sure to store the result as the seed for the next call (also in between */
/* frames), otherwise result won't be random at all. When only using some of the */
/* bits, take the most significant bits by right-shifting. Do not just mask off */
/* the lowest bits. */
#define SKP_RAND(seed) (SKP_MLA_ovflw(907633515, (seed), 196314165))
// Add some multiplication functions that can be easily mapped to ARM.
// SKP_SMMUL: Signed top word multiply.
// ARMv6 2 instruction cycles.
// ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)
//#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT(SKP_SMLAL(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16)), 16)
// the following seems faster on x86
//#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32)
#include "SKP_Silk_Inlines.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,254 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef _SKP_SILK_SIGPROC_FLP_H_
#define _SKP_SILK_SIGPROC_FLP_H_
#include "SKP_Silk_SigProc_FIX.h"
#include <math.h>
#ifdef __cplusplus
extern "C"
{
#endif
/********************************************************************/
/* SIGNAL PROCESSING FUNCTIONS */
/********************************************************************/
/* first-order allpass filter */
void SKP_Silk_allpass_int_FLP(
const SKP_float *in, /* I: input signal [len] */
SKP_float *S, /* I/O: state [1] */
SKP_float A, /* I: coefficient (0 <= A < 1) */
SKP_float *out, /* O: output signal [len] */
const SKP_int32 len /* I: number of samples */
);
/* downsample by a factor 2, coarser */
void SKP_Silk_decimate2_coarse_FLP(
const SKP_float *in, /* I: signal [2*len] */
SKP_float *S, /* I/O: state vector [2] */
SKP_float *out, /* O: decimated signal [len] */
SKP_float *scratch, /* I: scratch memory [3*len] */
const SKP_int32 len /* I: number of OUTPUT samples */
);
/* downsample by a factor 2, coarsest */
void SKP_Silk_decimate2_coarsest_FLP(
const SKP_float *in, /* I: signal [2*len] */
SKP_float *S, /* I/O: state vector [2] */
SKP_float *out, /* O: decimated signal [len] */
SKP_float *scratch, /* I: scratch memory [3*len] */
const SKP_int32 len /* I: number of OUTPUT samples */
);
/* Chirp (bw expand) LP AR filter */
void SKP_Silk_bwexpander_FLP(
SKP_float *ar, /* io AR filter to be expanded (without leading 1) */
const SKP_int d, /* i length of ar */
const SKP_float chirp /* i chirp factor (typically in range (0..1) ) */
);
/* compute inverse of LPC prediction gain, and */
/* test if LPC coefficients are stable (all poles within unit circle) */
/* this code is based on SKP_Silk_FLP_a2k() */
SKP_int SKP_Silk_LPC_inverse_pred_gain_FLP( /* O: returns 1 if unstable, otherwise 0 */
SKP_float *invGain, /* O: inverse prediction gain, energy domain */
const SKP_float *A, /* I: prediction coefficients [order] */
SKP_int32 order /* I: prediction order */
);
SKP_float SKP_Silk_schur_FLP( /* O returns residual energy */
SKP_float refl_coef[], /* O reflection coefficients (length order) */
const SKP_float auto_corr[], /* I autotcorrelation sequence (length order+1) */
SKP_int order /* I order */
);
void SKP_Silk_k2a_FLP(
SKP_float *A, /* O: prediction coefficients [order] */
const SKP_float *rc, /* I: reflection coefficients [order] */
SKP_int32 order /* I: prediction order */
);
/* Solve the normal equations using the Levinson-Durbin recursion */
SKP_float SKP_Silk_levinsondurbin_FLP( /* O prediction error energy */
SKP_float A[], /* O prediction coefficients [order] */
const SKP_float corr[], /* I input auto-correlations [order + 1] */
const SKP_int order /* I prediction order */
);
/* compute autocorrelation */
void SKP_Silk_autocorrelation_FLP(
SKP_float *results, /* o result (length correlationCount) */
const SKP_float *inputData, /* i input data to correlate */
SKP_int inputDataSize, /* i length of input */
SKP_int correlationCount /* i number of correlation taps to compute */
);
/* Pitch estimator */
#define SigProc_PITCH_EST_MIN_COMPLEX 0
#define SigProc_PITCH_EST_MID_COMPLEX 1
#define SigProc_PITCH_EST_MAX_COMPLEX 2
SKP_int SKP_Silk_pitch_analysis_core_FLP( /* O voicing estimate: 0 voiced, 1 unvoiced */
const SKP_float *signal, /* I signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz */
SKP_int *pitch_out, /* O 4 pitch lag values */
SKP_int *lagIndex, /* O lag Index */
SKP_int *contourIndex, /* O pitch contour Index */
SKP_float *LTPCorr, /* I/O normalized correlation; input: value from previous frame */
SKP_int prevLag, /* I last lag of previous frame; set to zero is unvoiced */
const SKP_float search_thres1, /* I first stage threshold for lag candidates 0 - 1 */
const SKP_float search_thres2, /* I final threshold for lag candidates 0 - 1 */
const SKP_int Fs_kHz, /* I sample frequency (kHz) */
const SKP_int complexity /* I Complexity setting, 0-2, where 2 is highest */
);
#define PI (3.1415926536f)
void SKP_Silk_insertion_sort_decreasing_FLP(
SKP_float *a, /* I/O: Unsorted / Sorted vector */
SKP_int *index, /* O: Index vector for the sorted elements */
const SKP_int L, /* I: Vector length */
const SKP_int K /* I: Number of correctly sorted positions */
);
void SKP_Silk_insertion_sort_increasing_FLP(
SKP_float *a, /* I/O: Unsorted / Sorted vector */
SKP_int *index, /* O: Index vector for the sorted elements */
const SKP_int L, /* I: Vector length */
const SKP_int K /* I: Number of correctly sorted positions */
);
/* Laroia low complexity NLSF weights */
void SKP_Silk_NLSF_VQ_weights_laroia_FLP(
SKP_float *pXW, /* 0: Pointer to input vector weights [D x 1] */
const SKP_float *pX, /* I: Pointer to input vector [D x 1] */
const SKP_int D /* I: Input vector dimension */
);
/* Compute reflection coefficients from input signal */
SKP_float SKP_Silk_burg_modified_FLP( /* O returns residual energy */
SKP_float A[], /* O prediction coefficients (length order) */
const SKP_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
const SKP_int subfr_length, /* I input signal subframe length (including D preceeding samples) */
const SKP_int nb_subfr, /* I number of subframes stacked in x */
const SKP_float WhiteNoiseFrac, /* I fraction added to zero-lag autocorrelation */
const SKP_int D /* I order */
);
/* multiply a vector by a constant */
void SKP_Silk_scale_vector_FLP(
SKP_float *data1,
SKP_float gain,
SKP_int dataSize
);
/* copy and multiply a vector by a constant */
void SKP_Silk_scale_copy_vector_FLP(
SKP_float *data_out,
const SKP_float *data_in,
SKP_float gain,
SKP_int dataSize
);
/* inner product of two SKP_float arrays, with result as double */
double SKP_Silk_inner_product_FLP(
const SKP_float *data1,
const SKP_float *data2,
SKP_int dataSize
);
/* sum of squares of a SKP_float array, with result as double */
double SKP_Silk_energy_FLP(
const SKP_float *data,
SKP_int dataSize
);
/********************************************************************/
/* MACROS */
/********************************************************************/
#define SKP_min_float(a, b) (((a) < (b)) ? (a) : (b))
#define SKP_max_float(a, b) (((a) > (b)) ? (a) : (b))
#define SKP_abs_float(a) ((SKP_float)fabs(a))
#define SKP_LIMIT_float( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \
: ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))))
/* sigmoid function */
SKP_INLINE SKP_float SKP_sigmoid(SKP_float x)
{
return (SKP_float)(1.0 / (1.0 + exp(-x)));
}
/* floating-point to integer conversion (rounding) */
SKP_INLINE void SKP_float2short_array(
SKP_int16 *out,
const SKP_float *in,
SKP_int32 length
)
{
SKP_int32 k;
for (k = length-1; k >= 0; k--) {
#if defined( _WIN32 ) && !defined( _WIN64 )
double t = in[k] + 6755399441055744.0;
out[k] = (SKP_int16)SKP_SAT16(*(( SKP_int32 * )( &t )));
#else
double x = in[k];
out[k] = (SKP_int16)SKP_SAT16( ( x > 0 ) ? x + 0.5 : x - 0.5 );
#endif
}
}
/* floating-point to integer conversion (rounding) */
SKP_INLINE SKP_int32 SKP_float2int(double x)
{
return (SKP_int32)( ( x > 0 ) ? x + 0.5 : x - 0.5 );
}
/* integer to floating-point conversion */
SKP_INLINE void SKP_short2float_array(
SKP_float *out,
const SKP_int16 *in,
SKP_int32 length
)
{
SKP_int32 k;
for (k = length-1; k >= 0; k--) {
out[k] = (SKP_float)in[k];
}
}
#define SKP_round(x) (SKP_float)((x)>=0 ? (SKP_int64)((x)+0.5) : (SKP_int64)((x)-0.5))
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,320 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/*
* File Name: SKP_Silk_VAD.c
* Description: Silk VAD.
*/
#include <stdlib.h>
#include "SKP_Silk_main.h"
/**********************************/
/* Initialization of the Silk VAD */
/**********************************/
SKP_int SKP_Silk_VAD_Init( /* O Return value, 0 if success */
SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
)
{
SKP_int b, ret = 0;
/* reset state memory */
SKP_memset( psSilk_VAD, 0, sizeof( SKP_Silk_VAD_state ) );
/* init noise levels */
/* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */
for( b = 0; b < VAD_N_BANDS; b++ ) {
psSilk_VAD->NoiseLevelBias[ b ] = SKP_max_32( SKP_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 );
}
/* Initialize state */
for( b = 0; b < VAD_N_BANDS; b++ ) {
psSilk_VAD->NL[ b ] = SKP_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] );
psSilk_VAD->inv_NL[ b ] = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->NL[ b ] );
}
psSilk_VAD->counter = 15;
/* init smoothed energy-to-noise ratio*/
for( b = 0; b < VAD_N_BANDS; b++ ) {
psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */
}
return( ret );
}
/* Weighting factors for tilt measure */
const static SKP_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };
/***************************************/
/* Get the speech activity level in Q8 */
/***************************************/
SKP_int SKP_Silk_VAD_GetSA_Q8( /* O Return value, 0 if success */
SKP_Silk_VAD_state *psSilk_VAD, /* I/O Silk VAD state */
SKP_int *pSA_Q8, /* O Speech activity level in Q8 */
SKP_int *pSNR_dB_Q7, /* O SNR for current frame in Q7 */
SKP_int pQuality_Q15[ VAD_N_BANDS ], /* O Smoothed SNR for each band */
SKP_int *pTilt_Q15, /* O current frame's frequency tilt */
const SKP_int16 pIn[], /* I PCM input [framelength] */
const SKP_int framelength /* I Input frame length */
)
{
SKP_int SA_Q15, input_tilt;
SKP_int32 scratch[ 3 * MAX_FRAME_LENGTH / 2 ];
SKP_int decimated_framelength, dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
SKP_int32 sumSquared, smooth_coef_Q16;
SKP_int16 HPstateTmp;
SKP_int16 X[ VAD_N_BANDS ][ MAX_FRAME_LENGTH / 2 ];
SKP_int32 Xnrg[ VAD_N_BANDS ];
SKP_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
SKP_int32 speech_nrg, x_tmp;
SKP_int ret = 0;
/* Safety checks */
SKP_assert( VAD_N_BANDS == 4 );
SKP_assert( MAX_FRAME_LENGTH >= framelength );
SKP_assert( framelength <= 512 );
/***********************/
/* Filter and Decimate */
/***********************/
/* 0-8 kHz to 0-4 kHz and 4-8 kHz */
SKP_Silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], &X[ 0 ][ 0 ], &X[ 3 ][ 0 ], &scratch[ 0 ], framelength );
/* 0-4 kHz to 0-2 kHz and 2-4 kHz */
SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState1[ 0 ], &X[ 0 ][ 0 ], &X[ 2 ][ 0 ], &scratch[ 0 ], SKP_RSHIFT( framelength, 1 ) );
/* 0-2 kHz to 0-1 kHz and 1-2 kHz */
SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState2[ 0 ], &X[ 0 ][ 0 ], &X[ 1 ][ 0 ], &scratch[ 0 ], SKP_RSHIFT( framelength, 2 ) );
/*********************************************/
/* HP filter on lowest band (differentiator) */
/*********************************************/
decimated_framelength = SKP_RSHIFT( framelength, 3 );
X[ 0 ][ decimated_framelength - 1 ] = SKP_RSHIFT( X[ 0 ][ decimated_framelength - 1 ], 1 );
HPstateTmp = X[ 0 ][ decimated_framelength - 1 ];
for( i = decimated_framelength - 1; i > 0; i-- ) {
X[ 0 ][ i - 1 ] = SKP_RSHIFT( X[ 0 ][ i - 1 ], 1 );
X[ 0 ][ i ] -= X[ 0 ][ i - 1 ];
}
X[ 0 ][ 0 ] -= psSilk_VAD->HPstate;
psSilk_VAD->HPstate = HPstateTmp;
/*************************************/
/* Calculate the energy in each band */
/*************************************/
for( b = 0; b < VAD_N_BANDS; b++ ) {
/* Find the decimated framelength in the non-uniformly divided bands */
decimated_framelength = SKP_RSHIFT( framelength, SKP_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
/* Split length into subframe lengths */
dec_subframe_length = SKP_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
dec_subframe_offset = 0;
/* Compute energy per sub-frame */
/* initialize with summed energy of last subframe */
Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
sumSquared = 0;
for( i = 0; i < dec_subframe_length; i++ ) {
/* The energy will be less than dec_subframe_length * ( SKP_int16_MIN / 8 ) ^ 2. */
/* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */
x_tmp = SKP_RSHIFT( X[ b ][ i + dec_subframe_offset ], 3 );
sumSquared = SKP_SMLABB( sumSquared, x_tmp, x_tmp );
/* Safety check */
SKP_assert( sumSquared >= 0 );
}
/* Add/saturate summed energy of current subframe */
if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
} else {
/* Look-ahead subframe */
Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], SKP_RSHIFT( sumSquared, 1 ) );
}
dec_subframe_offset += dec_subframe_length;
}
psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
}
/********************/
/* Noise estimation */
/********************/
SKP_Silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
/***********************************************/
/* Signal-plus-noise to noise ratio estimation */
/***********************************************/
sumSquared = 0;
input_tilt = 0;
for( b = 0; b < VAD_N_BANDS; b++ ) {
speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
if( speech_nrg > 0 ) {
/* Divide, with sufficient resolution */
if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( SKP_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
} else {
NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( Xnrg[ b ], SKP_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
}
/* Convert to log domain */
SNR_Q7 = SKP_Silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
/* Sum-of-squares */
sumSquared = SKP_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */
/* Tilt measure */
if( speech_nrg < ( 1 << 20 ) ) {
/* Scale down SNR value for small subband speech energies */
SNR_Q7 = SKP_SMULWB( SKP_LSHIFT( SKP_Silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
}
input_tilt = SKP_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
} else {
NrgToNoiseRatio_Q8[ b ] = 256;
}
}
/* Mean-of-squares */
sumSquared = SKP_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
/* Root-mean-square approximation, scale to dBs, and write to output pointer */
*pSNR_dB_Q7 = ( SKP_int16 )( 3 * SKP_Silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
/*********************************/
/* Speech Probability Estimation */
/*********************************/
SA_Q15 = SKP_Silk_sigm_Q15( SKP_SMULWB( VAD_SNR_FACTOR_Q16, *pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
/**************************/
/* Frequency Tilt Measure */
/**************************/
*pTilt_Q15 = SKP_LSHIFT( SKP_Silk_sigm_Q15( input_tilt ) - 16384, 1 );
/**************************************************/
/* Scale the sigmoid output based on power levels */
/**************************************************/
speech_nrg = 0;
for( b = 0; b < VAD_N_BANDS; b++ ) {
/* Accumulate signal-without-noise energies, higher frequency bands have more weight */
speech_nrg += ( b + 1 ) * SKP_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
}
/* Power scaling */
if( speech_nrg <= 0 ) {
SA_Q15 = SKP_RSHIFT( SA_Q15, 1 );
} else if( speech_nrg < 32768 ) {
/* square-root */
speech_nrg = SKP_Silk_SQRT_APPROX( SKP_LSHIFT( speech_nrg, 15 ) );
SA_Q15 = SKP_SMULWB( 32768 + speech_nrg, SA_Q15 );
}
/* Copy the resulting speech activity in Q8 to *pSA_Q8 */
*pSA_Q8 = SKP_min_int( SKP_RSHIFT( SA_Q15, 7 ), SKP_uint8_MAX );
/***********************************/
/* Energy Level and SNR estimation */
/***********************************/
/* Smoothing coefficient */
smooth_coef_Q16 = SKP_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, SKP_SMULWB( SA_Q15, SA_Q15 ) );
for( b = 0; b < VAD_N_BANDS; b++ ) {
/* compute smoothed energy-to-noise ratio per band */
psSilk_VAD->NrgRatioSmth_Q8[ b ] = SKP_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
/* signal to noise ratio in dB per band */
SNR_Q7 = 3 * ( SKP_Silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
/* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
pQuality_Q15[ b ] = SKP_Silk_sigm_Q15( SKP_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
}
return( ret );
}
/**************************/
/* Noise level estimation */
/**************************/
void SKP_Silk_VAD_GetNoiseLevels(
const SKP_int32 pX[ VAD_N_BANDS ], /* I subband energies */
SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
)
{
SKP_int k;
SKP_int32 nl, nrg, inv_nrg;
SKP_int coef, min_coef;
/* Initially faster smoothing */
if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */
min_coef = SKP_DIV32_16( SKP_int16_MAX, SKP_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );
} else {
min_coef = 0;
}
for( k = 0; k < VAD_N_BANDS; k++ ) {
/* Get old noise level estimate for current band */
nl = psSilk_VAD->NL[ k ];
SKP_assert( nl >= 0 );
/* Add bias */
nrg = SKP_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] );
SKP_assert( nrg > 0 );
/* Invert energies */
inv_nrg = SKP_DIV32( SKP_int32_MAX, nrg );
SKP_assert( inv_nrg >= 0 );
/* Less update when subband energy is high */
if( nrg > SKP_LSHIFT( nl, 3 ) ) {
coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3;
} else if( nrg < nl ) {
coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16;
} else {
coef = SKP_SMULWB( SKP_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 );
}
/* Initially faster smoothing */
coef = SKP_max_int( coef, min_coef );
/* Smooth inverse energies */
psSilk_VAD->inv_NL[ k ] = SKP_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef );
SKP_assert( psSilk_VAD->inv_NL[ k ] >= 0 );
/* Compute noise level by inverting again */
nl = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->inv_NL[ k ] );
SKP_assert( nl >= 0 );
/* Limit noise levels (guarantee 7 bits of head room) */
nl = SKP_min( nl, 0x00FFFFFF );
/* Store as part of state */
psSilk_VAD->NL[ k ] = nl;
}
/* Increment frame counter */
psSilk_VAD->counter++;
}

View File

@ -0,0 +1,102 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
#define Q14_CONVERSION_FAC 6.1035e-005f // 1 / 2^14
/* entropy constrained MATRIX-weighted VQ, for a single input data vector */
void SKP_Silk_VQ_WMat_EC_FLP(
SKP_int *ind, /* O Index of best codebook vector */
SKP_float *rate_dist, /* O Best weighted quant. error + mu * rate */
const SKP_float *in, /* I Input vector to be quantized */
const SKP_float *W, /* I Weighting matrix */
const SKP_int16 *cb, /* I Codebook */
const SKP_int16 *cl_Q6, /* I Code length for each codebook vector */
const SKP_float mu, /* I Tradeoff between WSSE and rate */
const SKP_int L /* I Number of vectors in codebook */
)
{
SKP_int k;
SKP_float sum1;
SKP_float diff[ 5 ];
const SKP_int16 *cb_row;
/* Loop over codebook */
*rate_dist = SKP_float_MAX;
*ind = 0;
cb_row = cb;
for( k = 0; k < L; k++ ) {
/* Calc difference between in vector and cbk vector */
diff[ 0 ] = in[ 0 ] - ( SKP_float )cb_row[ 0 ] * Q14_CONVERSION_FAC;
diff[ 1 ] = in[ 1 ] - ( SKP_float )cb_row[ 1 ] * Q14_CONVERSION_FAC;
diff[ 2 ] = in[ 2 ] - ( SKP_float )cb_row[ 2 ] * Q14_CONVERSION_FAC;
diff[ 3 ] = in[ 3 ] - ( SKP_float )cb_row[ 3 ] * Q14_CONVERSION_FAC;
diff[ 4 ] = in[ 4 ] - ( SKP_float )cb_row[ 4 ] * Q14_CONVERSION_FAC;
/* Weighted rate */
sum1 = mu * cl_Q6[ k ] / 64.0f;
/* Add weighted quantization error, assuming W is symmetric */
/* first row of W */
sum1 += diff[ 0 ] * ( W[ 0 ] * diff[ 0 ] +
2.0f * ( W[ 1 ] * diff[ 1 ] +
W[ 2 ] * diff[ 2 ] +
W[ 3 ] * diff[ 3 ] +
W[ 4 ] * diff[ 4 ] ) );
/* second row of W */
sum1 += diff[ 1 ] * ( W[ 6 ] * diff[ 1 ] +
2.0f * ( W[ 7 ] * diff[ 2 ] +
W[ 8 ] * diff[ 3 ] +
W[ 9 ] * diff[ 4 ] ) );
/* third row of W */
sum1 += diff[ 2 ] * ( W[ 12 ] * diff[ 2 ] +
2.0f * ( W[ 13 ] * diff[ 3 ] +
W[ 14 ] * diff[ 4 ] ) );
/* fourth row of W */
sum1 += diff[ 3 ] * ( W[ 18 ] * diff[ 3 ] +
2.0f * ( W[ 19 ] * diff[ 4 ] ) );
/* last row of W */
sum1 += diff[ 4 ] * ( W[ 24 ] * diff[ 4 ] );
/* find best */
if( sum1 < *rate_dist ) {
*rate_dist = sum1;
*ind = k;
}
/* Go to next cbk vector */
cb_row += LTP_ORDER;
}
/* If this breaks, we had a floating point wrap-around or similar */
SKP_assert( ( *rate_dist ) < SKP_float_MAX );
}

View File

@ -0,0 +1,69 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_allpass_int.c *
* *
* First-order allpass filter with *
* transfer function: *
* *
* A + Z^(-1) *
* H(z) = ------------ *
* 1 + A*Z^(-1) *
* *
* Implemented using minimum multiplier filter design. *
* *
* Reference: http://www.univ.trieste.it/~ramponi/teaching/ *
* DSP/materiale/Ch6(2).pdf *
* *
* Copyright 2007 (c), Skype Limited *
* Date: 070525 *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* First-order allpass filter */
void SKP_Silk_allpass_int(
const SKP_int32 *in, /* I: Q25 input signal [len] */
SKP_int32 *S, /* I/O: Q25 state [1] */
SKP_int A, /* I: Q15 coefficient (0 <= A < 32768) */
SKP_int32 *out, /* O: Q25 output signal [len] */
const SKP_int32 len /* I: Number of samples */
)
{
SKP_int32 Y2, X2, S0;
SKP_int k;
S0 = S[ 0 ];
for( k = len - 1; k >= 0; k-- ) {
Y2 = *in - S0;
X2 = ( Y2 >> 15 ) * A + ( ( ( Y2 & 0x00007FFF ) * A ) >> 15 );
( *out++ ) = S0 + X2;
S0 = ( *in++ ) + X2;
}
S[ 0 ] = S0;
}

View File

@ -0,0 +1,68 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_allpass_int.c *
* *
* First-order allpass filter with * *
* transfer function: *
* *
* A + Z^(-1) *
* H(z) = ------------ *
* 1 + A*Z^(-1) *
* *
* Implemented using minimum multiplier filter design. *
* *
* Reference: http://www.univ.trieste.it/~ramponi/teaching/ *
* DSP/materiale/Ch6(2).pdf *
* *
* Copyright 2007 (c), Skype Limited *
* Date: 070525 *
* */
#include "SKP_Silk_SigProc_FLP.h"
/* first-order allpass filter */
void SKP_Silk_allpass_int_FLP(
const SKP_float *in, /* I: input signal [len] */
SKP_float *S, /* I/O: state [1] */
SKP_float A, /* I: coefficient (0 <= A < 1) */
SKP_float *out, /* O: output signal [len] */
const SKP_int32 len /* I: number of samples */
)
{
SKP_float Y2, X2, S0;
SKP_int32 k;
S0 = S[ 0 ];
for ( k = len-1; k >= 0; k-- ) {
Y2 = *in - S0;
X2 = Y2 * A;
(*out++) = S0 + X2;
S0 = (*in++) + X2;
}
S[ 0 ] = S0;
}

View File

@ -0,0 +1,80 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_ana_filt_bank_1.c *
* *
* Split signal into two decimated bands using first-order allpass filters *
* *
* Copyright 2006 (c), Skype Limited *
* Date: 060221 *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* Coefficients for 2-band filter bank based on first-order allpass filters */
// old
static SKP_int16 A_fb1_20[ 1 ] = { 5394 << 1 };
static SKP_int16 A_fb1_21[ 1 ] = { 20623 << 1 }; /* wrap-around to negative number is intentional */
/* Split signal into two decimated bands using first-order allpass filters */
void SKP_Silk_ana_filt_bank_1(
const SKP_int16 *in, /* I: Input signal [N] */
SKP_int32 *S, /* I/O: State vector [2] */
SKP_int16 *outL, /* O: Low band [N/2] */
SKP_int16 *outH, /* O: High band [N/2] */
SKP_int32 *scratch, /* I: Scratch memory [3*N/2] */ // todo: remove - no longer used
const SKP_int32 N /* I: Number of input samples */
)
{
SKP_int k, N2 = SKP_RSHIFT( N, 1 );
SKP_int32 in32, X, Y, out_1, out_2;
/* Internal variables and state are in Q10 format */
for( k = 0; k < N2; k++ ) {
/* Convert to Q10 */
in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k ], 10 );
/* All-pass section for even input sample */
Y = SKP_SUB32( in32, S[ 0 ] );
X = SKP_SMLAWB( Y, Y, A_fb1_21[ 0 ] );
out_1 = SKP_ADD32( S[ 0 ], X );
S[ 0 ] = SKP_ADD32( in32, X );
/* Convert to Q10 */
in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k + 1 ], 10 );
/* All-pass section for odd input sample */
Y = SKP_SUB32( in32, S[ 1 ] );
X = SKP_SMULWB( Y, A_fb1_20[ 0 ] );
out_2 = SKP_ADD32( S[ 1 ], X );
S[ 1 ] = SKP_ADD32( in32, X );
/* Add/subtract, convert back to int16 and store to output */
outL[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( SKP_ADD32( out_2, out_1 ), 11 ) );
outH[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( out_2, out_1 ), 11 ) );
}
}

View File

@ -0,0 +1,77 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
/* Apply sine window to signal vector. */
/* Window types: */
/* 1 -> sine window from 0 to pi/2 */
/* 2 -> sine window from pi/2 to pi */
void SKP_Silk_apply_sine_window_FLP(
SKP_float px_win[], /* O Pointer to windowed signal */
const SKP_float px[], /* I Pointer to input signal */
const SKP_int win_type, /* I Selects a window type */
const SKP_int length /* I Window length, multiple of 4 */
)
{
SKP_int k;
SKP_float freq, c, S0, S1;
SKP_assert( win_type == 1 || win_type == 2 );
/* Length must be multiple of 4 */
SKP_assert( ( length & 3 ) == 0 );
freq = PI / ( length + 1 );
/* Approximation of 2 * cos(f) */
c = 2.0f - freq * freq;
/* Initialize state */
if( win_type < 2 ) {
/* Start from 0 */
S0 = 0.0f;
/* Approximation of sin(f) */
S1 = freq;
} else {
/* Start from 1 */
S0 = 1.0f;
/* Approximation of cos(f) */
S1 = 0.5f * c;
}
/* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
/* 4 samples at a time */
for( k = 0; k < length; k += 4 ) {
px_win[ k + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 );
px_win[ k + 1 ] = px[ k + 1 ] * S1;
S0 = c * S1 - S0;
px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 );
px_win[ k + 3 ] = px[ k + 3 ] * S0;
S1 = c * S0 - S1;
}
}

View File

@ -0,0 +1,48 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_typedef.h"
#include "SKP_Silk_SigProc_FLP.h"
/* compute autocorrelation */
void SKP_Silk_autocorrelation_FLP(
SKP_float *results, /* O result (length correlationCount) */
const SKP_float *inputData, /* I input data to correlate */
SKP_int inputDataSize, /* I length of input */
SKP_int correlationCount /* I number of correlation taps to compute */
)
{
SKP_int i;
if ( correlationCount > inputDataSize ) {
correlationCount = inputDataSize;
}
for( i = 0; i < correlationCount; i++ ) {
results[ i ] = (SKP_float)SKP_Silk_inner_product_FLP( inputData, inputData + i, inputDataSize - i );
}
}

View File

@ -0,0 +1,72 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_biquad.c *
* *
* Second order ARMA filter *
* Can handle slowly varying filter coefficients *
* *
* Copyright 2006 (c), Skype Limited *
* Date: 060221 *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* Second order ARMA filter */
/* Can handle slowly varying filter coefficients */
void SKP_Silk_biquad(
const SKP_int16 *in, /* I: input signal */
const SKP_int16 *B, /* I: MA coefficients, Q13 [3] */
const SKP_int16 *A, /* I: AR coefficients, Q13 [2] */
SKP_int32 *S, /* I/O: state vector [2] */
SKP_int16 *out, /* O: output signal */
const SKP_int32 len /* I: signal length */
)
{
SKP_int k, in16;
SKP_int32 A0_neg, A1_neg, S0, S1, out32, tmp32;
S0 = S[ 0 ];
S1 = S[ 1 ];
A0_neg = -A[ 0 ];
A1_neg = -A[ 1 ];
for( k = 0; k < len; k++ ) {
/* S[ 0 ], S[ 1 ]: Q13 */
in16 = in[ k ];
out32 = SKP_SMLABB( S0, in16, B[ 0 ] );
S0 = SKP_SMLABB( S1, in16, B[ 1 ] );
S0 += SKP_LSHIFT( SKP_SMULWB( out32, A0_neg ), 3 );
S1 = SKP_LSHIFT( SKP_SMULWB( out32, A1_neg ), 3 );
S1 = SKP_SMLABB( S1, in16, B[ 2 ] );
tmp32 = SKP_RSHIFT_ROUND( out32, 13 ) + 1;
out[ k ] = (SKP_int16)SKP_SAT16( tmp32 );
}
S[ 0 ] = S0;
S[ 1 ] = S1;
}

View File

@ -0,0 +1,73 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_biquad_alt.c *
* *
* Second order ARMA filter *
* Can handle slowly varying filter coefficients *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* Second order ARMA filter, alternative implementation */
void SKP_Silk_biquad_alt(
const SKP_int16 *in, /* I: Input signal */
const SKP_int32 *B_Q28, /* I: MA coefficients [3] */
const SKP_int32 *A_Q28, /* I: AR coefficients [2] */
SKP_int32 *S, /* I/O: State vector [2] */
SKP_int16 *out, /* O: Output signal */
const SKP_int32 len /* I: Signal length (must be even) */
)
{
/* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
SKP_int k;
SKP_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14;
/* Negate A_Q28 values and split in two parts */
A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */
A0_U_Q28 = SKP_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */
A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */
A1_U_Q28 = SKP_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */
for( k = 0; k < len; k++ ) {
/* S[ 0 ], S[ 1 ]: Q12 */
inval = in[ k ];
out32_Q14 = SKP_LSHIFT( SKP_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 );
S[ 0 ] = S[1] + SKP_RSHIFT_ROUND( SKP_SMULWB( out32_Q14, A0_L_Q28 ), 14 );
S[ 0 ] = SKP_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 );
S[ 0 ] = SKP_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval);
S[ 1 ] = SKP_RSHIFT_ROUND( SKP_SMULWB( out32_Q14, A1_L_Q28 ), 14 );
S[ 1 ] = SKP_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 );
S[ 1 ] = SKP_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval );
/* Scale back to Q0 and saturate */
out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );
}
}

View File

@ -0,0 +1,156 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_burg_modified.c *
* *
* Calculates the reflection coefficients from the input vector *
* Input vector contains nb_subfr sub vectors of length L_sub + D *
* *
* Copyright 2009 (c), Skype Limited *
* Date: 091130 *
*/
#include "SKP_Silk_SigProc_FLP.h"
#define MAX_FRAME_SIZE 544 // subfr_length * nb_subfr = ( 0.005 * 24000 + 16 ) * 4 = 544
#define MAX_NB_SUBFR 4
/* Compute reflection coefficients from input signal */
SKP_float SKP_Silk_burg_modified_FLP( /* O returns residual energy */
SKP_float A[], /* O prediction coefficients (length order) */
const SKP_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
const SKP_int subfr_length, /* I input signal subframe length (including D preceeding samples) */
const SKP_int nb_subfr, /* I number of subframes stacked in x */
const SKP_float WhiteNoiseFrac, /* I fraction added to zero-lag autocorrelation */
const SKP_int D /* I order */
)
{
SKP_int k, n, s;
double C0, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2;
const SKP_float *x_ptr;
double C_first_row[ SKP_Silk_MAX_ORDER_LPC ], C_last_row[ SKP_Silk_MAX_ORDER_LPC ];
double CAf[ SKP_Silk_MAX_ORDER_LPC + 1 ], CAb[ SKP_Silk_MAX_ORDER_LPC + 1 ];
double Af[ SKP_Silk_MAX_ORDER_LPC ];
SKP_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
SKP_assert( nb_subfr <= MAX_NB_SUBFR );
/* Compute autocorrelations, added over subframes */
C0 = SKP_Silk_energy_FLP( x, nb_subfr * subfr_length );
SKP_memset( C_first_row, 0, SKP_Silk_MAX_ORDER_LPC * sizeof( double ) );
for( s = 0; s < nb_subfr; s++ ) {
x_ptr = x + s * subfr_length;
for( n = 1; n < D + 1; n++ ) {
C_first_row[ n - 1 ] += SKP_Silk_inner_product_FLP( x_ptr, x_ptr + n, subfr_length - n );
}
}
SKP_memcpy( C_last_row, C_first_row, SKP_Silk_MAX_ORDER_LPC * sizeof( double ) );
/* Initialize */
CAb[ 0 ] = CAf[ 0 ] = C0 + WhiteNoiseFrac * C0 + 1e-9f;
for( n = 0; n < D; n++ ) {
/* Update first row of correlation matrix (without first element) */
/* Update last row of correlation matrix (without last element, stored in reversed order) */
/* Update C * Af */
/* Update C * flipud(Af) (stored in reversed order) */
for( s = 0; s < nb_subfr; s++ ) {
x_ptr = x + s * subfr_length;
tmp1 = x_ptr[ n ];
tmp2 = x_ptr[ subfr_length - n - 1 ];
for( k = 0; k < n; k++ ) {
C_first_row[ k ] -= x_ptr[ n ] * x_ptr[ n - k - 1 ];
C_last_row[ k ] -= x_ptr[ subfr_length - n - 1 ] * x_ptr[ subfr_length - n + k ];
Atmp = Af[ k ];
SKP_assert( subfr_length - n + k + s * subfr_length >= 0 );
SKP_assert( subfr_length - n + k + s * subfr_length < nb_subfr * subfr_length );
tmp1 += x_ptr[ n - k - 1 ] * Atmp;
tmp2 += x_ptr[ subfr_length - n + k ] * Atmp;
}
for( k = 0; k <= n; k++ ) {
CAf[ k ] -= tmp1 * x_ptr[ n - k ];
CAb[ k ] -= tmp2 * x_ptr[ subfr_length - n + k - 1 ];
}
}
tmp1 = C_first_row[ n ];
tmp2 = C_last_row[ n ];
for( k = 0; k < n; k++ ) {
Atmp = Af[ k ];
tmp1 += C_last_row[ n - k - 1 ] * Atmp;
tmp2 += C_first_row[ n - k - 1 ] * Atmp;
}
CAf[ n + 1 ] = tmp1;
CAb[ n + 1 ] = tmp2;
/* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
num = CAb[ n + 1 ];
nrg_b = CAb[ 0 ];
nrg_f = CAf[ 0 ];
for( k = 0; k < n; k++ ) {
Atmp = Af[ k ];
num += CAb[ n - k ] * Atmp;
nrg_b += CAb[ k + 1 ] * Atmp;
nrg_f += CAf[ k + 1 ] * Atmp;
}
SKP_assert( nrg_f > 0.0 );
SKP_assert( nrg_b > 0.0 );
/* Calculate the next order reflection (parcor) coefficient */
rc = -2.0 * num / ( nrg_f + nrg_b );
SKP_assert( rc > -1.0 && rc < 1.0 );
/* Update the AR coefficients */
for( k = 0; k < (n + 1) >> 1; k++ ) {
tmp1 = Af[ k ];
tmp2 = Af[ n - k - 1 ];
Af[ k ] = tmp1 + rc * tmp2;
Af[ n - k - 1 ] = tmp2 + rc * tmp1;
}
Af[ n ] = rc;
/* Update C * Af and C * Ab */
for( k = 0; k <= n + 1; k++ ) {
tmp1 = CAf[ k ];
CAf[ k ] += rc * CAb[ n - k + 1 ];
CAb[ n - k + 1 ] += rc * tmp1;
}
}
/* Return residual energy */
nrg_f = CAf[ 0 ];
tmp1 = 1.0;
for( k = 0; k < D; k++ ) {
Atmp = Af[ k ];
nrg_f += CAf[ k + 1 ] * Atmp;
tmp1 += Atmp * Atmp;
A[ k ] = (SKP_float)(-Atmp);
}
nrg_f -= WhiteNoiseFrac * C0 * tmp1;
return (SKP_float)nrg_f;
}

View File

@ -0,0 +1,49 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_SigProc_FIX.h"
/* Chirp (bandwidth expand) LP AR filter */
void SKP_Silk_bwexpander(
SKP_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */
const SKP_int d, /* I Length of ar */
SKP_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */
)
{
SKP_int i;
SKP_int32 chirp_minus_one_Q16;
chirp_minus_one_Q16 = chirp_Q16 - 65536;
/* NB: Dont use SKP_SMULWB, instead of SKP_RSHIFT_ROUND( SKP_MUL() , 16 ), below. */
/* Bias in SKP_SMULWB can lead to unstable filters */
for( i = 0; i < d - 1; i++ ) {
ar[ i ] = (SKP_int16)SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, ar[ i ] ), 16 );
chirp_Q16 += SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
}
ar[ d - 1 ] = (SKP_int16)SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, ar[ d - 1 ] ), 16 );
}

View File

@ -0,0 +1,46 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_SigProc_FIX.h"
/* Chirp (bandwidth expand) LP AR filter */
void SKP_Silk_bwexpander_32(
SKP_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */
const SKP_int d, /* I Length of ar */
SKP_int32 chirp_Q16 /* I Chirp factor in Q16 */
)
{
SKP_int i;
SKP_int32 tmp_chirp_Q16;
tmp_chirp_Q16 = chirp_Q16;
for( i = 0; i < d - 1; i++ ) {
ar[ i ] = SKP_SMULWW( ar[ i ], tmp_chirp_Q16 );
tmp_chirp_Q16 = SKP_SMULWW( chirp_Q16, tmp_chirp_Q16 );
}
ar[ d - 1 ] = SKP_SMULWW( ar[ d - 1 ], tmp_chirp_Q16 );
}

View File

@ -0,0 +1,47 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_SigProc_FLP.h"
/* Chirp (bw expand) LP AR filter */
void SKP_Silk_bwexpander_FLP(
SKP_float *ar, /* I/O AR filter to be expanded (without leading 1) */
const SKP_int d, /* I length of ar */
const SKP_float chirp /* I chirp factor (typically in range (0..1) ) */
)
{
SKP_int i;
SKP_float cfac = chirp;
for( i = 0; i < d - 1; i++ ) {
ar[ i ] *= cfac;
cfac *= chirp;
}
ar[ d - 1 ] *= cfac;
}

View File

@ -0,0 +1,91 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
//#define SKP_enc_map(a) ((a) > 0 ? 1 : 0)
//#define SKP_dec_map(a) ((a) > 0 ? 1 : -1)
/* shifting avoids if-statement */
#define SKP_enc_map(a) ( SKP_RSHIFT( (a), 15 ) + 1 )
#define SKP_dec_map(a) ( SKP_LSHIFT( (a), 1 ) - 1 )
/* Encodes signs of excitation */
void SKP_Silk_encode_signs(
SKP_Silk_range_coder_state *sRC, /* I/O Range coder state */
const SKP_int8 q[], /* I Pulse signal */
const SKP_int length, /* I Length of input */
const SKP_int sigtype, /* I Signal type */
const SKP_int QuantOffsetType, /* I Quantization offset type */
const SKP_int RateLevelIndex /* I Rate level index */
)
{
SKP_int i;
SKP_int inData;
SKP_uint16 cdf[ 3 ];
i = SKP_SMULBB( N_RATE_LEVELS - 1, SKP_LSHIFT( sigtype, 1 ) + QuantOffsetType ) + RateLevelIndex;
cdf[ 0 ] = 0;
cdf[ 1 ] = SKP_Silk_sign_CDF[ i ];
cdf[ 2 ] = 65535;
for( i = 0; i < length; i++ ) {
if( q[ i ] != 0 ) {
inData = SKP_enc_map( q[ i ] ); /* - = 0, + = 1 */
SKP_Silk_range_encoder( sRC, inData, cdf );
}
}
}
/* Decodes signs of excitation */
void SKP_Silk_decode_signs(
SKP_Silk_range_coder_state *sRC, /* I/O Range coder state */
SKP_int q[], /* I/O pulse signal */
const SKP_int length, /* I length of output */
const SKP_int sigtype, /* I Signal type */
const SKP_int QuantOffsetType, /* I Quantization offset type */
const SKP_int RateLevelIndex /* I Rate Level Index */
)
{
SKP_int i;
SKP_int data;
SKP_uint16 cdf[ 3 ];
i = SKP_SMULBB( N_RATE_LEVELS - 1, SKP_LSHIFT( sigtype, 1 ) + QuantOffsetType ) + RateLevelIndex;
cdf[ 0 ] = 0;
cdf[ 1 ] = SKP_Silk_sign_CDF[ i ];
cdf[ 2 ] = 65535;
for( i = 0; i < length; i++ ) {
if( q[ i ] > 0 ) {
SKP_Silk_range_decoder( &data, sRC, cdf, 1 );
/* attach sign */
/* implementation with shift, subtraction, multiplication */
q[ i ] *= SKP_dec_map( data );
}
}
}

View File

@ -0,0 +1,76 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef SIGPROC_COMMON_PITCH_EST_DEFINES_H
#define SIGPROC_COMMON_PITCH_EST_DEFINES_H
#include "SKP_Silk_SigProc_FIX.h"
/************************************************************/
/* Definitions For Fix pitch estimator */
/************************************************************/
#define PITCH_EST_MAX_FS_KHZ 24 /* Maximum sampling frequency used */
#define PITCH_EST_FRAME_LENGTH_MS 40 /* 40 ms */
#define PITCH_EST_MAX_FRAME_LENGTH (PITCH_EST_FRAME_LENGTH_MS * PITCH_EST_MAX_FS_KHZ)
#define PITCH_EST_MAX_FRAME_LENGTH_ST_1 (PITCH_EST_MAX_FRAME_LENGTH >> 2)
#define PITCH_EST_MAX_FRAME_LENGTH_ST_2 (PITCH_EST_MAX_FRAME_LENGTH >> 1)
#define PITCH_EST_MAX_SF_FRAME_LENGTH (PITCH_EST_SUB_FRAME * PITCH_EST_MAX_FS_KHZ)
#define PITCH_EST_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */
#define PITCH_EST_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */
#define PITCH_EST_MAX_LAG (PITCH_EST_MAX_LAG_MS * PITCH_EST_MAX_FS_KHZ)
#define PITCH_EST_MIN_LAG (PITCH_EST_MIN_LAG_MS * PITCH_EST_MAX_FS_KHZ)
#define PITCH_EST_NB_SUBFR 4
#define PITCH_EST_D_SRCH_LENGTH 24
#define PITCH_EST_MAX_DECIMATE_STATE_LENGTH 7
#define PITCH_EST_NB_STAGE3_LAGS 5
#define PITCH_EST_NB_CBKS_STAGE2 3
#define PITCH_EST_NB_CBKS_STAGE2_EXT 11
#define PITCH_EST_CB_mn2 1
#define PITCH_EST_CB_mx2 2
#define PITCH_EST_NB_CBKS_STAGE3_MAX 34
#define PITCH_EST_NB_CBKS_STAGE3_MID 24
#define PITCH_EST_NB_CBKS_STAGE3_MIN 16
extern const SKP_int16 SKP_Silk_CB_lags_stage2[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE2_EXT];
extern const SKP_int16 SKP_Silk_CB_lags_stage3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX];
extern const SKP_int16 SKP_Silk_Lag_range_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ] [ PITCH_EST_NB_SUBFR ][ 2 ];
extern const SKP_int16 SKP_Silk_cbk_sizes_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ];
extern const SKP_int16 SKP_Silk_cbk_offsets_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ];
#endif

View File

@ -0,0 +1,137 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/* Control internal sampling rate */
SKP_int SKP_Silk_control_audio_bandwidth(
SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */
)
{
SKP_int fs_kHz;
fs_kHz = psEncC->fs_kHz;
if( fs_kHz == 0 ) {
/* Encoder has just been initialized */
if( TargetRate_bps >= SWB2WB_BITRATE_BPS ) {
fs_kHz = 24;
} else if( TargetRate_bps >= WB2MB_BITRATE_BPS ) {
fs_kHz = 16;
} else if( TargetRate_bps >= MB2NB_BITRATE_BPS ) {
fs_kHz = 12;
} else {
fs_kHz = 8;
}
/* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */
fs_kHz = SKP_min( fs_kHz, SKP_DIV32_16( psEncC->API_fs_Hz, 1000 ) );
fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz );
} else if( SKP_SMULBB( fs_kHz, 1000 ) > psEncC->API_fs_Hz || fs_kHz > psEncC->maxInternal_fs_kHz ) {
/* Make sure internal rate is not higher than external rate or maximum allowed */
fs_kHz = SKP_DIV32_16( psEncC->API_fs_Hz, 1000 );
fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz );
} else {
/* State machine for the internal sampling rate switching */
if( psEncC->API_fs_Hz > 8000 ) {
/* Accumulate the difference between the target rate and limit for switching down */
psEncC->bitrateDiff += SKP_MUL( psEncC->PacketSize_ms, TargetRate_bps - psEncC->bitrate_threshold_down );
psEncC->bitrateDiff = SKP_min( psEncC->bitrateDiff, 0 );
if( psEncC->vadFlag == NO_VOICE_ACTIVITY ) { /* Low speech activity */
/* Check if we should switch down */
#if SWITCH_TRANSITION_FILTERING
if( ( psEncC->sLP.transition_frame_no == 0 ) && /* Transition phase not active */
( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || /* Bitrate threshold is met */
( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz == 24 ) ) ) { /* Forced down-switching due to WB input */
psEncC->sLP.transition_frame_no = 1; /* Begin transition phase */
psEncC->sLP.mode = 0; /* Switch down */
} else if(
( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && /* Transition phase complete */
( psEncC->sLP.mode == 0 ) ) { /* Ready to switch down */
psEncC->sLP.transition_frame_no = 0; /* Ready for new transition phase */
#else
if( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) { /* Bitrate threshold is met */
#endif
psEncC->bitrateDiff = 0;
/* Switch to a lower sample frequency */
if( psEncC->fs_kHz == 24 ) {
fs_kHz = 16;
} else if( psEncC->fs_kHz == 16 ) {
fs_kHz = 12;
} else {
SKP_assert( psEncC->fs_kHz == 12 );
fs_kHz = 8;
}
}
/* Check if we should switch up */
if( ( ( psEncC->fs_kHz * 1000 < psEncC->API_fs_Hz ) &&
( TargetRate_bps >= psEncC->bitrate_threshold_up ) &&
( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz < 16 ) ) &&
( ( ( psEncC->fs_kHz == 16 ) && ( psEncC->maxInternal_fs_kHz >= 24 ) ) ||
( ( psEncC->fs_kHz == 12 ) && ( psEncC->maxInternal_fs_kHz >= 16 ) ) ||
( ( psEncC->fs_kHz == 8 ) && ( psEncC->maxInternal_fs_kHz >= 12 ) ) )
#if SWITCH_TRANSITION_FILTERING
&& ( psEncC->sLP.transition_frame_no == 0 ) ) { /* No transition phase running, ready to switch */
psEncC->sLP.mode = 1; /* Switch up */
#else
) {
#endif
psEncC->bitrateDiff = 0;
/* Switch to a higher sample frequency */
if( psEncC->fs_kHz == 8 ) {
fs_kHz = 12;
} else if( psEncC->fs_kHz == 12 ) {
fs_kHz = 16;
} else {
SKP_assert( psEncC->fs_kHz == 16 );
fs_kHz = 24;
}
}
}
}
#if SWITCH_TRANSITION_FILTERING
/* After switching up, stop transition filter during speech inactivity */
if( ( psEncC->sLP.mode == 1 ) &&
( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_UP ) &&
( psEncC->vadFlag == NO_VOICE_ACTIVITY ) ) {
psEncC->sLP.transition_frame_no = 0;
/* Reset transition filter state */
SKP_memset( psEncC->sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );
}
#endif
}
return fs_kHz;
}

View File

@ -0,0 +1,411 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
#include "SKP_Silk_setup_complexity.h"
SKP_INLINE SKP_int SKP_Silk_setup_resamplers(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
SKP_int fs_kHz /* I Internal sampling rate (kHz) */
);
SKP_INLINE SKP_int SKP_Silk_setup_packetsize(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
SKP_int PacketSize_ms /* I Packet length (ms) */
);
SKP_INLINE SKP_int SKP_Silk_setup_fs(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
SKP_int fs_kHz /* I Internal sampling rate (kHz) */
);
SKP_INLINE SKP_int SKP_Silk_setup_rate(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
SKP_int32 TargetRate_bps /* I Target max bitrate */
);
SKP_INLINE SKP_int SKP_Silk_setup_LBRR(
SKP_Silk_encoder_state_FLP *psEnc /* I/O Pointer to Silk encoder state FLP */
);
/* Control encoder */
SKP_int SKP_Silk_control_encoder_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
const SKP_int PacketSize_ms, /* I Packet length (ms) */
const SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) */
const SKP_int PacketLoss_perc, /* I Packet loss rate (in percent) */
const SKP_int DTX_enabled, /* I Enable / disable DTX */
const SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */
)
{
SKP_int fs_kHz, ret = 0;
if( psEnc->sCmn.controlled_since_last_payload != 0 ) {
if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) {
/* Change in API sampling rate in the middle of encoding a packet */
ret += SKP_Silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz );
}
return ret;
}
/* Beyond this point we know that there are no previously coded frames in the payload buffer */
/********************************************/
/* Determine internal sampling rate */
/********************************************/
fs_kHz = SKP_Silk_control_audio_bandwidth( &psEnc->sCmn, TargetRate_bps );
/********************************************/
/* Prepare resampler and buffered data */
/********************************************/
ret += SKP_Silk_setup_resamplers( psEnc, fs_kHz );
/********************************************/
/* Set packet size */
/********************************************/
ret += SKP_Silk_setup_packetsize( psEnc, PacketSize_ms );
/********************************************/
/* Set internal sampling frequency */
/********************************************/
ret += SKP_Silk_setup_fs( psEnc, fs_kHz );
/********************************************/
/* Set encoding complexity */
/********************************************/
ret += SKP_Silk_setup_complexity( &psEnc->sCmn, Complexity );
/********************************************/
/* Set bitrate/coding quality */
/********************************************/
ret += SKP_Silk_setup_rate( psEnc, TargetRate_bps );
/********************************************/
/* Set packet loss rate measured by farend */
/********************************************/
if( ( PacketLoss_perc < 0 ) || ( PacketLoss_perc > 100 ) ) {
ret = SKP_SILK_ENC_INVALID_LOSS_RATE;
}
psEnc->sCmn.PacketLoss_perc = PacketLoss_perc;
/********************************************/
/* Set LBRR usage */
/********************************************/
ret += SKP_Silk_setup_LBRR( psEnc );
/********************************************/
/* Set DTX mode */
/********************************************/
if( DTX_enabled < 0 || DTX_enabled > 1 ) {
ret = SKP_SILK_ENC_INVALID_DTX_SETTING;
}
psEnc->sCmn.useDTX = DTX_enabled;
psEnc->sCmn.controlled_since_last_payload = 1;
return ret;
}
/* Control low bitrate redundancy usage */
void SKP_Silk_LBRR_ctrl_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I Encoder state FLP */
SKP_Silk_encoder_control *psEncCtrl /* I/O Encoder control */
)
{
SKP_int LBRR_usage;
if( psEnc->sCmn.LBRR_enabled ) {
/* Control LBRR */
/* Usage Control based on sensitivity and packet loss caracteristics */
/* For now only enable adding to next for active frames. Make more complex later */
LBRR_usage = SKP_SILK_NO_LBRR;
if( psEnc->speech_activity > LBRR_SPEECH_ACTIVITY_THRES && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) { // nb! maybe multiply loss prob and speech activity
LBRR_usage = SKP_SILK_ADD_LBRR_TO_PLUS1;
}
psEncCtrl->LBRR_usage = LBRR_usage;
} else {
psEncCtrl->LBRR_usage = SKP_SILK_NO_LBRR;
}
}
SKP_INLINE SKP_int SKP_Silk_setup_resamplers(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
SKP_int fs_kHz /* I Internal sampling rate (kHz) */
)
{
SKP_int ret = SKP_SILK_NO_ERROR;
if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz ) {
if( psEnc->sCmn.fs_kHz == 0 ) {
/* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
ret += SKP_Silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000 );
} else {
/* Allocate space for worst case temporary upsampling, 8 to 48 kHz, so a factor 6 */
SKP_int16 x_buf_API_fs_Hz[ ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * ( MAX_API_FS_KHZ / 8 ) ];
SKP_int16 x_bufFIX[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];
SKP_int32 nSamples_temp = 2 * psEnc->sCmn.frame_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz;
SKP_float2short_array( x_bufFIX, psEnc->x_buf, nSamples_temp );
if( fs_kHz * 1000 < psEnc->sCmn.API_fs_Hz && psEnc->sCmn.fs_kHz != 0 ) {
/* Resample buffered data in x_buf to API_fs_Hz */
SKP_Silk_resampler_state_struct temp_resampler_state;
/* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */
ret += SKP_Silk_resampler_init( &temp_resampler_state, psEnc->sCmn.fs_kHz * 1000, psEnc->sCmn.API_fs_Hz );
/* Temporary resampling of x_buf data to API_fs_Hz */
ret += SKP_Silk_resampler( &temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, nSamples_temp );
/* Calculate number of samples that has been temporarily upsampled */
nSamples_temp = SKP_DIV32_16( nSamples_temp * psEnc->sCmn.API_fs_Hz, psEnc->sCmn.fs_kHz * 1000 );
/* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
ret += SKP_Silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000 );
} else {
/* Copy data */
SKP_memcpy( x_buf_API_fs_Hz, x_bufFIX, nSamples_temp * sizeof( SKP_int16 ) );
}
if( 1000 * fs_kHz != psEnc->sCmn.API_fs_Hz ) {
/* Correct resampler state (unless resampling by a factor 1) by resampling buffered data from API_fs_Hz to fs_kHz */
ret += SKP_Silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, nSamples_temp );
}
SKP_short2float_array( psEnc->x_buf, x_bufFIX, ( 2 * FRAME_LENGTH_MS + LA_SHAPE_MS ) * fs_kHz );
}
}
psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz;
return ret;
}
SKP_INLINE SKP_int SKP_Silk_setup_packetsize(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
SKP_int PacketSize_ms /* I Packet length (ms) */
)
{
SKP_int ret = SKP_SILK_NO_ERROR;
/* Set packet size */
if( ( PacketSize_ms != 20 ) &&
( PacketSize_ms != 40 ) &&
( PacketSize_ms != 60 ) &&
( PacketSize_ms != 80 ) &&
( PacketSize_ms != 100 ) ) {
ret = SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
} else {
if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) {
psEnc->sCmn.PacketSize_ms = PacketSize_ms;
/* Packet length changes. Reset LBRR buffer */
SKP_Silk_LBRR_reset( &psEnc->sCmn );
}
}
return(ret);
}
SKP_INLINE SKP_int SKP_Silk_setup_fs(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
SKP_int fs_kHz /* I Internal sampling rate (kHz) */
)
{
SKP_int ret = SKP_SILK_NO_ERROR;
/* Set internal sampling frequency */
if( psEnc->sCmn.fs_kHz != fs_kHz ) {
/* reset part of the state */
SKP_memset( &psEnc->sShape, 0, sizeof( SKP_Silk_shape_state_FLP ) );
SKP_memset( &psEnc->sPrefilt, 0, sizeof( SKP_Silk_prefilter_state_FLP ) );
SKP_memset( &psEnc->sPred, 0, sizeof( SKP_Silk_predict_state_FLP ) );
SKP_memset( &psEnc->sCmn.sNSQ, 0, sizeof( SKP_Silk_nsq_state ) );
SKP_memset( psEnc->sCmn.sNSQ_LBRR.xq, 0, ( 2 * MAX_FRAME_LENGTH ) * sizeof( SKP_int16 ) );
SKP_memset( psEnc->sCmn.LBRR_buffer, 0, MAX_LBRR_DELAY * sizeof( SKP_SILK_LBRR_struct ) );
#if SWITCH_TRANSITION_FILTERING
SKP_memset( psEnc->sCmn.sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );
if( psEnc->sCmn.sLP.mode == 1 ) {
/* Begin transition phase */
psEnc->sCmn.sLP.transition_frame_no = 1;
} else {
/* End transition phase */
psEnc->sCmn.sLP.transition_frame_no = 0;
}
#endif
psEnc->sCmn.inputBufIx = 0;
psEnc->sCmn.nFramesInPayloadBuf = 0;
psEnc->sCmn.nBytesInPayloadBuf = 0;
psEnc->sCmn.oldest_LBRR_idx = 0;
psEnc->sCmn.TargetRate_bps = 0; /* Ensures that psEnc->SNR_dB is recomputed */
SKP_memset( psEnc->sPred.prev_NLSFq, 0, MAX_LPC_ORDER * sizeof( SKP_float ) );
/* Initialize non-zero parameters */
psEnc->sCmn.prevLag = 100;
psEnc->sCmn.prev_sigtype = SIG_TYPE_UNVOICED;
psEnc->sCmn.first_frame_after_reset = 1;
psEnc->sPrefilt.lagPrev = 100;
psEnc->sShape.LastGainIndex = 1;
psEnc->sCmn.sNSQ.lagPrev = 100;
psEnc->sCmn.sNSQ.prev_inv_gain_Q16 = 65536;
psEnc->sCmn.sNSQ_LBRR.prev_inv_gain_Q16 = 65536;
psEnc->sCmn.fs_kHz = fs_kHz;
if( psEnc->sCmn.fs_kHz == 8 ) {
psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;
psEnc->sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_10;
psEnc->sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_10;
psEnc->psNLSF_CB_FLP[ 0 ] = &SKP_Silk_NLSF_CB0_10_FLP;
psEnc->psNLSF_CB_FLP[ 1 ] = &SKP_Silk_NLSF_CB1_10_FLP;
} else {
psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;
psEnc->sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_16;
psEnc->sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_16;
psEnc->psNLSF_CB_FLP[ 0 ] = &SKP_Silk_NLSF_CB0_16_FLP;
psEnc->psNLSF_CB_FLP[ 1 ] = &SKP_Silk_NLSF_CB1_16_FLP;
}
psEnc->sCmn.frame_length = FRAME_LENGTH_MS * fs_kHz;
psEnc->sCmn.subfr_length = psEnc->sCmn.frame_length / NB_SUBFR;
psEnc->sCmn.la_pitch = LA_PITCH_MS * fs_kHz;
psEnc->sPred.min_pitch_lag = 3 * fs_kHz;
psEnc->sPred.max_pitch_lag = 18 * fs_kHz;
psEnc->sPred.pitch_LPC_win_length = FIND_PITCH_LPC_WIN_MS * fs_kHz;
if( psEnc->sCmn.fs_kHz == 24 ) {
psEnc->mu_LTP = MU_LTP_QUANT_SWB;
psEnc->sCmn.bitrate_threshold_up = SKP_int32_MAX;
psEnc->sCmn.bitrate_threshold_down = SWB2WB_BITRATE_BPS;
} else if( psEnc->sCmn.fs_kHz == 16 ) {
psEnc->mu_LTP = MU_LTP_QUANT_WB;
psEnc->sCmn.bitrate_threshold_up = WB2SWB_BITRATE_BPS;
psEnc->sCmn.bitrate_threshold_down = WB2MB_BITRATE_BPS;
} else if( psEnc->sCmn.fs_kHz == 12 ) {
psEnc->mu_LTP = MU_LTP_QUANT_MB;
psEnc->sCmn.bitrate_threshold_up = MB2WB_BITRATE_BPS;
psEnc->sCmn.bitrate_threshold_down = MB2NB_BITRATE_BPS;
} else {
psEnc->mu_LTP = MU_LTP_QUANT_NB;
psEnc->sCmn.bitrate_threshold_up = NB2MB_BITRATE_BPS;
psEnc->sCmn.bitrate_threshold_down = 0;
}
psEnc->sCmn.fs_kHz_changed = 1;
/* Check that settings are valid */
SKP_assert( ( psEnc->sCmn.subfr_length * NB_SUBFR ) == psEnc->sCmn.frame_length );
}
return ret;
}
SKP_INLINE SKP_int SKP_Silk_setup_rate(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
SKP_int32 TargetRate_bps /* I Target max bitrate */
)
{
SKP_int k, ret = SKP_SILK_NO_ERROR;
SKP_float frac;
const SKP_int32 *rateTable;
/* Set bitrate/coding quality */
if( TargetRate_bps != psEnc->sCmn.TargetRate_bps ) {
psEnc->sCmn.TargetRate_bps = TargetRate_bps;
/* If new TargetRate_bps, translate to SNR_dB value */
if( psEnc->sCmn.fs_kHz == 8 ) {
rateTable = TargetRate_table_NB;
} else if( psEnc->sCmn.fs_kHz == 12 ) {
rateTable = TargetRate_table_MB;
} else if( psEnc->sCmn.fs_kHz == 16 ) {
rateTable = TargetRate_table_WB;
} else {
rateTable = TargetRate_table_SWB;
}
for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {
/* Find bitrate interval in table and interpolate */
if( TargetRate_bps <= rateTable[ k ] ) {
frac = (SKP_float)( TargetRate_bps - rateTable[ k - 1 ] ) /
(SKP_float)( rateTable[ k ] - rateTable[ k - 1 ] );
psEnc->SNR_dB = 0.5f * ( SNR_table_Q1[ k - 1 ] + frac * ( SNR_table_Q1[ k ] - SNR_table_Q1[ k - 1 ] ) );
break;
}
}
}
return( ret );
}
SKP_INLINE SKP_int SKP_Silk_setup_LBRR(
SKP_Silk_encoder_state_FLP *psEnc /* I/O Pointer to Silk encoder state FLP */
)
{
SKP_int ret = SKP_SILK_NO_ERROR;
#if USE_LBRR
SKP_int32 LBRRRate_thres_bps;
if( psEnc->sCmn.useInBandFEC < 0 || psEnc->sCmn.useInBandFEC > 1 ) {
ret = SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING;
}
psEnc->sCmn.LBRR_enabled = psEnc->sCmn.useInBandFEC;
if( psEnc->sCmn.fs_kHz == 8 ) {
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 9000;
} else if( psEnc->sCmn.fs_kHz == 12 ) {
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 6000;
} else if( psEnc->sCmn.fs_kHz == 16 ) {
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 3000;
} else {
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS;
}
if( psEnc->sCmn.TargetRate_bps >= LBRRRate_thres_bps ) {
/* Set gain increase / rate reduction for LBRR usage */
/* Coarsely tuned with PESQ for now. */
/* Linear regression coefs G = 8 - 0.5 * loss */
/* Meaning that at 16% loss main rate and redundant rate is the same, -> G = 0 */
psEnc->sCmn.LBRR_GainIncreases = SKP_max_int( 8 - SKP_RSHIFT( psEnc->sCmn.PacketLoss_perc, 1 ), 0 );
/* Set main stream rate compensation */
if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) {
/* Tuned to give approx same mean / weighted bitrate as no inband FEC */
psEnc->inBandFEC_SNR_comp = 6.0f - 0.5f * psEnc->sCmn.LBRR_GainIncreases;
} else {
psEnc->inBandFEC_SNR_comp = 0.0f;
psEnc->sCmn.LBRR_enabled = 0;
}
} else {
psEnc->inBandFEC_SNR_comp = 0.0f;
psEnc->sCmn.LBRR_enabled = 0;
}
#else
if( INBandFEC_enabled != 0 ) {
ret = SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING;
}
psEnc->sCmn.LBRR_enabled = 0;
#endif
return ret;
}

View File

@ -0,0 +1,89 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/**********************************************************************
* Correlation matrix computations for LS estimate.
**********************************************************************/
#include "SKP_Silk_main_FLP.h"
/* Calculates correlation vector X'*t */
void SKP_Silk_corrVector_FLP(
const SKP_float *x, /* I x vector [L+order-1] used to create X */
const SKP_float *t, /* I Target vector [L] */
const SKP_int L, /* I Length of vecors */
const SKP_int Order, /* I Max lag for correlation */
SKP_float *Xt /* O X'*t correlation vector [order] */
)
{
SKP_int lag;
const SKP_float *ptr1;
ptr1 = &x[ Order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
for( lag = 0; lag < Order; lag++ ) {
/* Calculate X[:,lag]'*t */
Xt[ lag ] = (SKP_float)SKP_Silk_inner_product_FLP( ptr1, t, L );
ptr1--; /* Next column of X */
}
}
/* Calculates correlation matrix X'*X */
void SKP_Silk_corrMatrix_FLP(
const SKP_float *x, /* I x vector [ L+order-1 ] used to create X */
const SKP_int L, /* I Length of vectors */
const SKP_int Order, /* I Max lag for correlation */
SKP_float *XX /* O X'*X correlation matrix [order x order] */
)
{
SKP_int j, lag;
double energy;
const SKP_float *ptr1, *ptr2;
ptr1 = &x[ Order - 1 ]; /* First sample of column 0 of X */
energy = SKP_Silk_energy_FLP( ptr1, L ); /* X[:,0]'*X[:,0] */
matrix_ptr( XX, 0, 0, Order ) = ( SKP_float )energy;
for( j = 1; j < Order; j++ ) {
/* Calculate X[:,j]'*X[:,j] */
energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ];
matrix_ptr( XX, j, j, Order ) = ( SKP_float )energy;
}
ptr2 = &x[ Order - 2 ]; /* First sample of column 1 of X */
for( lag = 1; lag < Order; lag++ ) {
/* Calculate X[:,0]'*X[:,lag] */
energy = SKP_Silk_inner_product_FLP( ptr1, ptr2, L );
matrix_ptr( XX, lag, 0, Order ) = ( SKP_float )energy;
matrix_ptr( XX, 0, lag, Order ) = ( SKP_float )energy;
/* Calculate X[:,j]'*X[:,j + lag] */
for( j = 1; j < ( Order - lag ); j++ ) {
energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ];
matrix_ptr( XX, lag + j, j, Order ) = ( SKP_float )energy;
matrix_ptr( XX, j, lag + j, Order ) = ( SKP_float )energy;
}
ptr2--; /* Next column of X */
}
}

View File

@ -0,0 +1,53 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/************************/
/* Init Decoder State */
/************************/
SKP_int SKP_Silk_init_decoder(
SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */
)
{
SKP_memset( psDec, 0, sizeof( SKP_Silk_decoder_state ) );
/* Set sampling rate to 24 kHz, and init non-zero values */
SKP_Silk_decoder_set_fs( psDec, 24 );
/* Used to deactivate e.g. LSF interpolation and fluctuation reduction */
psDec->first_frame_after_reset = 1;
psDec->prev_inv_gain_Q16 = 65536;
/* Reset CNG state */
SKP_Silk_CNG_Reset( psDec );
SKP_Silk_PLC_Reset( psDec );
return(0);
}

View File

@ -0,0 +1,279 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_SDK_API.h"
#include "SKP_Silk_main.h"
/*********************/
/* Decoder functions */
/*********************/
SKP_int SKP_Silk_SDK_Get_Decoder_Size( SKP_int32 *decSizeBytes )
{
SKP_int ret = 0;
*decSizeBytes = sizeof( SKP_Silk_decoder_state );
return ret;
}
/* Reset decoder state */
SKP_int SKP_Silk_SDK_InitDecoder(
void* decState /* I/O: State */
)
{
SKP_int ret = 0;
SKP_Silk_decoder_state *struc;
struc = (SKP_Silk_decoder_state *)decState;
ret = SKP_Silk_init_decoder( struc );
return ret;
}
/* Decode a frame */
SKP_int SKP_Silk_SDK_Decode(
void* decState, /* I/O: State */
SKP_SILK_SDK_DecControlStruct* decControl, /* I/O: Control structure */
SKP_int lostFlag, /* I: 0: no loss, 1 loss */
const SKP_uint8 *inData, /* I: Encoded input vector */
const SKP_int nBytesIn, /* I: Number of input Bytes */
SKP_int16 *samplesOut, /* O: Decoded output speech vector */
SKP_int16 *nSamplesOut /* I/O: Number of samples (vector/decoded) */
)
{
SKP_int ret = 0, used_bytes, prev_fs_kHz;
SKP_Silk_decoder_state *psDec;
SKP_int16 samplesOutInternal[ MAX_API_FS_KHZ * FRAME_LENGTH_MS ];
SKP_int16 *pSamplesOutInternal;
psDec = (SKP_Silk_decoder_state *)decState;
/* We need this buffer to have room for an internal frame */
pSamplesOutInternal = samplesOut;
if( psDec->fs_kHz * 1000 > decControl->API_sampleRate ) {
pSamplesOutInternal = samplesOutInternal;
}
/**********************************/
/* Test if first frame in payload */
/**********************************/
if( psDec->moreInternalDecoderFrames == 0 ) {
/* First Frame in Payload */
psDec->nFramesDecoded = 0; /* Used to count frames in packet */
}
if( psDec->moreInternalDecoderFrames == 0 && /* First frame in packet */
lostFlag == 0 && /* Not packet loss */
nBytesIn > MAX_ARITHM_BYTES ) { /* Too long payload */
/* Avoid trying to decode a too large packet */
lostFlag = 1;
ret = SKP_SILK_DEC_PAYLOAD_TOO_LARGE;
}
/* Save previous sample frequency */
prev_fs_kHz = psDec->fs_kHz;
/* Call decoder for one frame */
ret += SKP_Silk_decode_frame( psDec, pSamplesOutInternal, nSamplesOut, inData, nBytesIn,
lostFlag, &used_bytes );
if( used_bytes ) { /* Only Call if not a packet loss */
if( psDec->nBytesLeft > 0 && psDec->FrameTermination == SKP_SILK_MORE_FRAMES && psDec->nFramesDecoded < 5 ) {
/* We have more frames in the Payload */
psDec->moreInternalDecoderFrames = 1;
} else {
/* Last frame in Payload */
psDec->moreInternalDecoderFrames = 0;
psDec->nFramesInPacket = psDec->nFramesDecoded;
/* Track inband FEC usage */
if( psDec->vadFlag == VOICE_ACTIVITY ) {
if( psDec->FrameTermination == SKP_SILK_LAST_FRAME ) {
psDec->no_FEC_counter++;
if( psDec->no_FEC_counter > NO_LBRR_THRES ) {
psDec->inband_FEC_offset = 0;
}
} else if( psDec->FrameTermination == SKP_SILK_LBRR_VER1 ) {
psDec->inband_FEC_offset = 1; /* FEC info with 1 packet delay */
psDec->no_FEC_counter = 0;
} else if( psDec->FrameTermination == SKP_SILK_LBRR_VER2 ) {
psDec->inband_FEC_offset = 2; /* FEC info with 2 packets delay */
psDec->no_FEC_counter = 0;
}
}
}
}
if( MAX_API_FS_KHZ * 1000 < decControl->API_sampleRate ||
8000 > decControl->API_sampleRate ) {
ret = SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY;
return( ret );
}
/* Resample if needed */
if( psDec->fs_kHz * 1000 != decControl->API_sampleRate ) {
SKP_int16 samplesOut_tmp[ MAX_API_FS_KHZ * FRAME_LENGTH_MS ];
SKP_assert( psDec->fs_kHz <= MAX_API_FS_KHZ );
/* Copy to a tmp buffer as the resampling writes to samplesOut */
SKP_memcpy( samplesOut_tmp, pSamplesOutInternal, *nSamplesOut * sizeof( SKP_int16 ) );
/* (Re-)initialize resampler state when switching internal sampling frequency */
if( prev_fs_kHz != psDec->fs_kHz || psDec->prev_API_sampleRate != decControl->API_sampleRate ) {
ret = SKP_Silk_resampler_init( &psDec->resampler_state, SKP_SMULBB( psDec->fs_kHz, 1000 ), decControl->API_sampleRate );
}
/* Resample the output to API_sampleRate */
ret += SKP_Silk_resampler( &psDec->resampler_state, samplesOut, samplesOut_tmp, *nSamplesOut );
/* Update the number of output samples */
*nSamplesOut = SKP_DIV32( ( SKP_int32 )*nSamplesOut * decControl->API_sampleRate, psDec->fs_kHz * 1000 );
} else if( prev_fs_kHz * 1000 > decControl->API_sampleRate ) {
SKP_memcpy( samplesOut, pSamplesOutInternal, *nSamplesOut * sizeof( SKP_int16 ) );
}
psDec->prev_API_sampleRate = decControl->API_sampleRate;
/* Copy all parameters that are needed out of internal structure to the control stucture */
decControl->frameSize = (SKP_uint16)( decControl->API_sampleRate / 50 ) ;
decControl->framesPerPacket = ( SKP_int )psDec->nFramesInPacket;
decControl->inBandFECOffset = ( SKP_int )psDec->inband_FEC_offset;
decControl->moreInternalDecoderFrames = ( SKP_int )psDec->moreInternalDecoderFrames;
return ret;
}
/* Function to find LBRR information in a packet */
void SKP_Silk_SDK_search_for_LBRR(
const SKP_uint8 *inData, /* I: Encoded input vector */
const SKP_int nBytesIn, /* I: Number of input Bytes */
SKP_int lost_offset, /* I: Offset from lost packet */
SKP_uint8 *LBRRData, /* O: LBRR payload */
SKP_int16 *nLBRRBytes /* O: Number of LBRR Bytes */
)
{
SKP_Silk_decoder_state sDec; // Local decoder state to avoid interfering with running decoder */
SKP_Silk_decoder_control sDecCtrl;
SKP_int TempQ[ MAX_FRAME_LENGTH ];
if( lost_offset < 1 || lost_offset > MAX_LBRR_DELAY ) {
/* No useful FEC in this packet */
*nLBRRBytes = 0;
return;
}
sDec.nFramesDecoded = 0;
sDec.fs_kHz = 0; /* Force update parameters LPC_order etc */
sDec.lossCnt = 0; /* Avoid running bw expansion of the LPC parameters when searching for LBRR data */
SKP_memset( sDec.prevNLSF_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) );
SKP_Silk_range_dec_init( &sDec.sRC, inData, ( SKP_int32 )nBytesIn );
while(1) {
SKP_Silk_decode_parameters( &sDec, &sDecCtrl, TempQ, 0 );
if( sDec.sRC.error ) {
/* Corrupt stream */
*nLBRRBytes = 0;
return;
};
if( ( sDec.FrameTermination - 1 ) & lost_offset && sDec.FrameTermination > 0 && sDec.nBytesLeft >= 0 ) {
/* The wanted FEC is present in the packet */
*nLBRRBytes = sDec.nBytesLeft;
SKP_memcpy( LBRRData, &inData[ nBytesIn - sDec.nBytesLeft ], sDec.nBytesLeft * sizeof( SKP_uint8 ) );
break;
}
if( sDec.nBytesLeft > 0 && sDec.FrameTermination == SKP_SILK_MORE_FRAMES ) {
sDec.nFramesDecoded++;
} else {
LBRRData = NULL;
*nLBRRBytes = 0;
break;
}
}
}
/* Getting type of content for a packet */
void SKP_Silk_SDK_get_TOC(
const SKP_uint8 *inData, /* I: Encoded input vector */
const SKP_int nBytesIn, /* I: Number of input bytes */
SKP_Silk_TOC_struct *Silk_TOC /* O: Type of content */
)
{
SKP_Silk_decoder_state sDec; // Local Decoder state to avoid interfering with running decoder */
SKP_Silk_decoder_control sDecCtrl;
SKP_int TempQ[ MAX_FRAME_LENGTH ];
sDec.nFramesDecoded = 0;
sDec.fs_kHz = 0; /* Force update parameters LPC_order etc */
SKP_Silk_range_dec_init( &sDec.sRC, inData, ( SKP_int32 )nBytesIn );
Silk_TOC->corrupt = 0;
while( 1 ) {
SKP_Silk_decode_parameters( &sDec, &sDecCtrl, TempQ, 0 );
Silk_TOC->vadFlags[ sDec.nFramesDecoded ] = sDec.vadFlag;
Silk_TOC->sigtypeFlags[ sDec.nFramesDecoded ] = sDecCtrl.sigtype;
if( sDec.sRC.error ) {
/* Corrupt stream */
Silk_TOC->corrupt = 1;
break;
};
if( sDec.nBytesLeft > 0 && sDec.FrameTermination == SKP_SILK_MORE_FRAMES ) {
sDec.nFramesDecoded++;
} else {
break;
}
}
if( Silk_TOC->corrupt || sDec.FrameTermination == SKP_SILK_MORE_FRAMES ||
sDec.nFramesInPacket > SILK_MAX_FRAMES_PER_PACKET ) {
/* Corrupt packet */
SKP_memset( Silk_TOC, 0, sizeof( SKP_Silk_TOC_struct ) );
Silk_TOC->corrupt = 1;
} else {
Silk_TOC->framesInPacket = sDec.nFramesDecoded + 1;
Silk_TOC->fs_kHz = sDec.fs_kHz;
if( sDec.FrameTermination == SKP_SILK_LAST_FRAME ) {
Silk_TOC->inbandLBRR = sDec.FrameTermination;
} else {
Silk_TOC->inbandLBRR = sDec.FrameTermination - 1;
}
}
}
/**************************/
/* Get the version number */
/**************************/
/* Return a pointer to string specifying the version */
const char *SKP_Silk_SDK_get_version()
{
static const char version[] = "1.0.9";
return version;
}

View File

@ -0,0 +1,69 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_decimate2_coarse.c *
* *
* downsample by a factor 2, coarser *
* */
#include "SKP_Silk_SigProc_FLP.h"
/* coefficients for coarser 2-fold resampling */
static SKP_float A20c_FLP[ 2 ] = {0.064666748046875f, 0.508514404296875f};
static SKP_float A21c_FLP[ 2 ] = {0.245666503906250f, 0.819732666015625f};
/* downsample by a factor 2, coarser */
void SKP_Silk_decimate2_coarse_FLP(
const SKP_float *in, /* I: 16 kHz signal [2*len] */
SKP_float *S, /* I/O: state vector [4] */
SKP_float *out, /* O: 8 kHz signal [len] */
SKP_float *scratch, /* I: scratch memory [3*len] */
const SKP_int32 len /* I: number of OUTPUT samples */
)
{
SKP_int32 k;
/* de-interleave allpass inputs */
for ( k = 0; k < len; k++) {
scratch[ k ] = in[ 2 * k ];
scratch[ k + len ] = in[ 2 * k + 1 ];
}
/* allpass filters */
SKP_Silk_allpass_int_FLP( scratch, S + 0, A21c_FLP[ 0 ], scratch + 2 * len, len );
SKP_Silk_allpass_int_FLP( scratch + 2 * len, S + 1, A21c_FLP[ 1 ], scratch, len );
SKP_Silk_allpass_int_FLP( scratch + len, S + 2, A20c_FLP[ 0 ], scratch + 2 * len, len );
SKP_Silk_allpass_int_FLP( scratch + 2 * len, S + 3, A20c_FLP[ 1 ], scratch + len, len );
/* add two allpass outputs */
for ( k = 0; k < len; k++ ) {
out[ k ] = 0.5f * ( scratch[ k ] + scratch[ k + len ] );
}
}

View File

@ -0,0 +1,67 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_decimate2_coarsest.c *
* *
* downsample by a factor 2, coarsest *
* */
#include "SKP_Silk_SigProc_FLP.h"
/* coefficients for coarsest 2-fold resampling */
/* note that these differ from the interpolator with the same filter orders! */
static float A20cst_FLP[ 1 ] = {0.289001464843750f};
static float A21cst_FLP[ 1 ] = {0.780487060546875f};
/* downsample by a factor 2, coarsest */
void SKP_Silk_decimate2_coarsest_FLP(
const SKP_float *in, /* I: 16 kHz signal [2*len] */
SKP_float *S, /* I/O: state vector [2] */
SKP_float *out, /* O: 8 kHz signal [len] */
SKP_float *scratch, /* I: scratch memory [3*len] */
const SKP_int32 len /* I: number of OUTPUT samples */
)
{
SKP_int32 k;
/* de-interleave allpass inputs */
for ( k = 0; k < len; k++ ) {
scratch[ k ] = in[ 2 * k + 0 ];
scratch[ k + len ] = in[ 2 * k + 1 ];
}
/* allpass filters */
SKP_Silk_allpass_int_FLP( scratch, S + 0, A21cst_FLP[ 0 ], scratch + 2 * len, len );
SKP_Silk_allpass_int_FLP( scratch + len, S + 1, A20cst_FLP[ 0 ], scratch, len );
/* add two allpass outputs */
for ( k = 0; k < len; k++ ) {
out[ k ] = 0.5f * ( scratch[ k ] + scratch[ k + 2 * len ] );
}
}

View File

@ -0,0 +1,242 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
void SKP_Silk_decode_short_term_prediction(
SKP_int32 *vec_Q10,
SKP_int32 *pres_Q10,
SKP_int32 *sLPC_Q14,
SKP_int16 *A_Q12_tmp,
SKP_int LPC_order,
SKP_int subfr_length
);
/**********************************************************/
/* Core decoder. Performs inverse NSQ operation LTP + LPC */
/**********************************************************/
void SKP_Silk_decode_core(
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */
SKP_int16 xq[], /* O Decoded speech */
const SKP_int q[ MAX_FRAME_LENGTH ] /* I Pulse signal */
)
{
SKP_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, sigtype;
SKP_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ];
SKP_int16 sLTP[ MAX_FRAME_LENGTH ];
SKP_int32 LTP_pred_Q14, Gain_Q16, inv_gain_Q16, inv_gain_Q32, gain_adj_Q16, rand_seed, offset_Q10, dither;
SKP_int32 *pred_lag_ptr, *pexc_Q10, *pres_Q10;
SKP_int32 vec_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];
SKP_int32 FiltState[ MAX_LPC_ORDER ];
SKP_assert( psDec->prev_inv_gain_Q16 != 0 );
offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psDecCtrl->sigtype ][ psDecCtrl->QuantOffsetType ];
if( psDecCtrl->NLSFInterpCoef_Q2 < ( 1 << 2 ) ) {
NLSF_interpolation_flag = 1;
} else {
NLSF_interpolation_flag = 0;
}
/* Decode excitation */
rand_seed = psDecCtrl->Seed;
for( i = 0; i < psDec->frame_length; i++ ) {
rand_seed = SKP_RAND( rand_seed );
/* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
dither = SKP_RSHIFT( rand_seed, 31 );
psDec->exc_Q10[ i ] = SKP_LSHIFT( ( SKP_int32 )q[ i ], 10 ) + offset_Q10;
psDec->exc_Q10[ i ] = ( psDec->exc_Q10[ i ] ^ dither ) - dither;
rand_seed += q[ i ];
}
pexc_Q10 = psDec->exc_Q10;
pres_Q10 = psDec->res_Q10;
pxq = &psDec->outBuf[ psDec->frame_length ];
sLTP_buf_idx = psDec->frame_length;
/* Loop over subframes */
for( k = 0; k < NB_SUBFR; k++ ) {
A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ];
/* Preload LPC coeficients to array on stack. Gives small performance gain */
SKP_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( SKP_int16 ) );
B_Q14 = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ];
Gain_Q16 = psDecCtrl->Gains_Q16[ k ];
sigtype = psDecCtrl->sigtype;
inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gain_Q16, 1 ), 32 );
inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );
/* Calculate Gain adjustment factor */
gain_adj_Q16 = ( SKP_int32 )1 << 16;
if( inv_gain_Q16 != psDec->prev_inv_gain_Q16 ) {
gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, psDec->prev_inv_gain_Q16, 16 );
}
/* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */
if( psDec->lossCnt && psDec->prev_sigtype == SIG_TYPE_VOICED &&
psDecCtrl->sigtype == SIG_TYPE_UNVOICED && k < ( NB_SUBFR >> 1 ) ) {
SKP_memset( B_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ) );
B_Q14[ LTP_ORDER/2 ] = ( SKP_int16 )1 << 12; /* 0.25 */
sigtype = SIG_TYPE_VOICED;
psDecCtrl->pitchL[ k ] = psDec->lagPrev;
}
if( sigtype == SIG_TYPE_VOICED ) {
/* Voiced */
lag = psDecCtrl->pitchL[ k ];
/* Re-whitening */
if( ( k & ( 3 - SKP_LSHIFT( NLSF_interpolation_flag, 1 ) ) ) == 0 ) {
/* Rewhiten with new A coefs */
start_idx = psDec->frame_length - lag - psDec->LPC_order - LTP_ORDER / 2;
SKP_assert( start_idx >= 0 );
SKP_assert( start_idx <= psDec->frame_length - psDec->LPC_order );
SKP_memset( FiltState, 0, psDec->LPC_order * sizeof( SKP_int32 ) ); /* Not really necessary, but Valgrind and Coverity will complain otherwise */
SKP_Silk_MA_Prediction( &psDec->outBuf[ start_idx + k * ( psDec->frame_length >> 2 ) ],
A_Q12, FiltState, sLTP + start_idx, psDec->frame_length - start_idx, psDec->LPC_order );
/* After rewhitening the LTP state is unscaled */
inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );
if( k == 0 ) {
/* Do LTP downscaling */
inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, psDecCtrl->LTP_scale_Q14 ), 2 );
}
for( i = 0; i < (lag + LTP_ORDER/2); i++ ) {
psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] = SKP_SMULWB( inv_gain_Q32, sLTP[ psDec->frame_length - i - 1 ] );
}
} else {
/* Update LTP state when Gain changes */
if( gain_adj_Q16 != ( SKP_int32 )1 << 16 ) {
for( i = 0; i < ( lag + LTP_ORDER / 2 ); i++ ) {
psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] = SKP_SMULWW( gain_adj_Q16, psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] );
}
}
}
}
/* Scale short term state */
for( i = 0; i < MAX_LPC_ORDER; i++ ) {
psDec->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDec->sLPC_Q14[ i ] );
}
/* Save inv_gain */
SKP_assert( inv_gain_Q16 != 0 );
psDec->prev_inv_gain_Q16 = inv_gain_Q16;
/* Long-term prediction */
if( sigtype == SIG_TYPE_VOICED ) {
/* Setup pointer */
pred_lag_ptr = &psDec->sLTP_Q16[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
for( i = 0; i < psDec->subfr_length; i++ ) {
/* Unrolled loop */
LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], B_Q14[ 0 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
pred_lag_ptr++;
/* Generate LPC residual */
pres_Q10[ i ] = SKP_ADD32( pexc_Q10[ i ], SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) );
/* Update states */
psDec->sLTP_Q16[ sLTP_buf_idx ] = SKP_LSHIFT( pres_Q10[ i ], 6 );
sLTP_buf_idx++;
}
} else {
SKP_memcpy( pres_Q10, pexc_Q10, psDec->subfr_length * sizeof( SKP_int32 ) );
}
SKP_Silk_decode_short_term_prediction(vec_Q10, pres_Q10, psDec->sLPC_Q14,A_Q12_tmp,psDec->LPC_order,psDec->subfr_length);
/* Scale with Gain */
for( i = 0; i < psDec->subfr_length; i++ ) {
pxq[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( vec_Q10[ i ], Gain_Q16 ), 10 ) );
}
/* Update LPC filter state */
SKP_memcpy( psDec->sLPC_Q14, &psDec->sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) );
pexc_Q10 += psDec->subfr_length;
pres_Q10 += psDec->subfr_length;
pxq += psDec->subfr_length;
}
/* Copy to output */
SKP_memcpy( xq, &psDec->outBuf[ psDec->frame_length ], psDec->frame_length * sizeof( SKP_int16 ) );
}
void SKP_Silk_decode_short_term_prediction(
SKP_int32 *vec_Q10,
SKP_int32 *pres_Q10,
SKP_int32 *sLPC_Q14,
SKP_int16 *A_Q12_tmp,
SKP_int LPC_order,
SKP_int subfr_length
)
{
SKP_int i;
SKP_int32 LPC_pred_Q10;
SKP_int j;
for( i = 0; i < subfr_length; i++ ) {
/* Partially unrolled */
LPC_pred_Q10 = SKP_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] );
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] );
for( j = 10; j < LPC_order; j ++ ) {
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp[ j ] );
}
/* Add prediction to LPC residual */
vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 );
/* Update states */
sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT_ovflw( vec_Q10[ i ], 4 );
}
}

View File

@ -0,0 +1,155 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
#include "SKP_Silk_PLC.h"
/****************/
/* Decode frame */
/****************/
SKP_int SKP_Silk_decode_frame(
SKP_Silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */
SKP_int16 pOut[], /* O Pointer to output speech frame */
SKP_int16 *pN, /* O Pointer to size of output frame */
const SKP_uint8 pCode[], /* I Pointer to payload */
const SKP_int nBytes, /* I Payload length */
SKP_int action, /* I Action from Jitter Buffer */
SKP_int *decBytes /* O Used bytes to decode this frame */
)
{
SKP_Silk_decoder_control sDecCtrl;
SKP_int L, fs_Khz_old, ret = 0;
SKP_int Pulses[ MAX_FRAME_LENGTH ];
L = psDec->frame_length;
sDecCtrl.LTP_scale_Q14 = 0;
/* Safety checks */
SKP_assert( L > 0 && L <= MAX_FRAME_LENGTH );
/********************************************/
/* Decode Frame if packet is not lost */
/********************************************/
*decBytes = 0;
if( action == 0 ) {
/********************************************/
/* Initialize arithmetic coder */
/********************************************/
fs_Khz_old = psDec->fs_kHz;
if( psDec->nFramesDecoded == 0 ) {
/* Initialize range decoder state */
SKP_Silk_range_dec_init( &psDec->sRC, pCode, nBytes );
}
/********************************************/
/* Decode parameters and pulse signal */
/********************************************/
SKP_Silk_decode_parameters( psDec, &sDecCtrl, Pulses, 1 );
if( psDec->sRC.error ) {
psDec->nBytesLeft = 0;
action = 1; /* PLC operation */
/* revert fs if changed in decode_parameters */
SKP_Silk_decoder_set_fs( psDec, fs_Khz_old );
/* Avoid crashing */
*decBytes = psDec->sRC.bufferLength;
if( psDec->sRC.error == RANGE_CODER_DEC_PAYLOAD_TOO_LONG ) {
ret = SKP_SILK_DEC_PAYLOAD_TOO_LARGE;
} else {
ret = SKP_SILK_DEC_PAYLOAD_ERROR;
}
} else {
*decBytes = psDec->sRC.bufferLength - psDec->nBytesLeft;
psDec->nFramesDecoded++;
/* Update lengths. Sampling frequency could have changed */
L = psDec->frame_length;
/********************************************************/
/* Run inverse NSQ */
/********************************************************/
SKP_Silk_decode_core( psDec, &sDecCtrl, pOut, Pulses );
/********************************************************/
/* Update PLC state */
/********************************************************/
SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, action );
psDec->lossCnt = 0;
psDec->prev_sigtype = sDecCtrl.sigtype;
/* A frame has been decoded without errors */
psDec->first_frame_after_reset = 0;
}
}
/*************************************************************/
/* Generate Concealment frame if packet is lost, or corrupt */
/*************************************************************/
if( action == 1 ) {
/* Handle packet loss by extrapolation */
SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, action );
}
/*************************/
/* Update output buffer. */
/*************************/
SKP_memcpy( psDec->outBuf, pOut, L * sizeof( SKP_int16 ) );
/****************************************************************/
/* Ensure smooth connection of extrapolated and good frames */
/****************************************************************/
SKP_Silk_PLC_glue_frames( psDec, &sDecCtrl, pOut, L );
/************************************************/
/* Comfort noise generation / estimation */
/************************************************/
SKP_Silk_CNG( psDec, &sDecCtrl, pOut , L );
/********************************************/
/* HP filter output */
/********************************************/
SKP_assert( ( ( psDec->fs_kHz == 12 ) && ( L % 3 ) == 0 ) ||
( ( psDec->fs_kHz != 12 ) && ( L % 2 ) == 0 ) );
SKP_Silk_biquad( pOut, psDec->HP_B, psDec->HP_A, psDec->HPState, pOut, L );
/********************************************/
/* set output frame length */
/********************************************/
*pN = ( SKP_int16 )L;
/* Update some decoder state variables */
psDec->lagPrev = sDecCtrl.pitchL[ NB_SUBFR - 1 ];
return ret;
}

View File

@ -0,0 +1,244 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/* Decode parameters from payload */
void SKP_Silk_decode_parameters(
SKP_Silk_decoder_state *psDec, /* I/O State */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int q[], /* O Excitation signal */
const SKP_int fullDecoding /* I Flag to tell if only arithmetic decoding */
)
{
SKP_int i, k, Ix, fs_kHz_dec, nBytesUsed;
SKP_int Ixs[ NB_SUBFR ];
SKP_int GainsIndices[ NB_SUBFR ];
SKP_int NLSFIndices[ NLSF_MSVQ_MAX_CB_STAGES ];
SKP_int pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ];
const SKP_int16 *cbk_ptr_Q14;
const SKP_Silk_NLSF_CB_struct *psNLSF_CB = NULL;
SKP_Silk_range_coder_state *psRC = &psDec->sRC;
/************************/
/* Decode sampling rate */
/************************/
/* only done for first frame of packet */
if( psDec->nFramesDecoded == 0 ) {
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_SamplingRates_CDF, SKP_Silk_SamplingRates_offset );
/* check that sampling rate is supported */
if( Ix < 0 || Ix > 3 ) {
psRC->error = RANGE_CODER_ILLEGAL_SAMPLING_RATE;
return;
}
fs_kHz_dec = SKP_Silk_SamplingRates_table[ Ix ];
SKP_Silk_decoder_set_fs( psDec, fs_kHz_dec );
}
/*******************************************/
/* Decode signal type and quantizer offset */
/*******************************************/
if( psDec->nFramesDecoded == 0 ) {
/* first frame in packet: independent coding */
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_type_offset_CDF, SKP_Silk_type_offset_CDF_offset );
} else {
/* condidtional coding */
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_type_offset_joint_CDF[ psDec->typeOffsetPrev ],
SKP_Silk_type_offset_CDF_offset );
}
psDecCtrl->sigtype = SKP_RSHIFT( Ix, 1 );
psDecCtrl->QuantOffsetType = Ix & 1;
psDec->typeOffsetPrev = Ix;
/****************/
/* Decode gains */
/****************/
/* first subframe */
if( psDec->nFramesDecoded == 0 ) {
/* first frame in packet: independent coding */
SKP_Silk_range_decoder( &GainsIndices[ 0 ], psRC, SKP_Silk_gain_CDF[ psDecCtrl->sigtype ], SKP_Silk_gain_CDF_offset );
} else {
/* condidtional coding */
SKP_Silk_range_decoder( &GainsIndices[ 0 ], psRC, SKP_Silk_delta_gain_CDF, SKP_Silk_delta_gain_CDF_offset );
}
/* remaining subframes */
for( i = 1; i < NB_SUBFR; i++ ) {
SKP_Silk_range_decoder( &GainsIndices[ i ], psRC, SKP_Silk_delta_gain_CDF, SKP_Silk_delta_gain_CDF_offset );
}
/* Dequant Gains */
SKP_Silk_gains_dequant( psDecCtrl->Gains_Q16, GainsIndices, &psDec->LastGainIndex, psDec->nFramesDecoded );
/****************/
/* Decode NLSFs */
/****************/
/* Set pointer to NLSF VQ CB for the current signal type */
psNLSF_CB = psDec->psNLSF_CB[ psDecCtrl->sigtype ];
/* Range decode NLSF path */
SKP_Silk_range_decoder_multi( NLSFIndices, psRC, psNLSF_CB->StartPtr, psNLSF_CB->MiddleIx, psNLSF_CB->nStages );
/* From the NLSF path, decode an NLSF vector */
SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, NLSFIndices, psDec->LPC_order );
/************************************/
/* Decode NLSF interpolation factor */
/************************************/
SKP_Silk_range_decoder( &psDecCtrl->NLSFInterpCoef_Q2, psRC, SKP_Silk_NLSF_interpolation_factor_CDF,
SKP_Silk_NLSF_interpolation_factor_offset );
/* If just reset, e.g., because internal Fs changed, do not allow interpolation */
/* improves the case of packet loss in the first frame after a switch */
if( psDec->first_frame_after_reset == 1 ) {
psDecCtrl->NLSFInterpCoef_Q2 = 4;
}
if( fullDecoding ) {
/* Convert NLSF parameters to AR prediction filter coefficients */
SKP_Silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order );
if( psDecCtrl->NLSFInterpCoef_Q2 < 4 ) {
/* Calculation of the interpolated NLSF0 vector from the interpolation factor, */
/* the previous NLSF1, and the current NLSF1 */
for( i = 0; i < psDec->LPC_order; i++ ) {
pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + SKP_RSHIFT( SKP_MUL( psDecCtrl->NLSFInterpCoef_Q2,
( pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ) ), 2 );
}
/* Convert NLSF parameters to AR prediction filter coefficients */
SKP_Silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );
} else {
/* Copy LPC coefficients for first half from second half */
SKP_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ],
psDec->LPC_order * sizeof( SKP_int16 ) );
}
}
SKP_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( SKP_int ) );
/* After a packet loss do BWE of LPC coefs */
if( psDec->lossCnt ) {
SKP_Silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 );
SKP_Silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 );
}
if( psDecCtrl->sigtype == SIG_TYPE_VOICED ) {
/*********************/
/* Decode pitch lags */
/*********************/
/* Get lag index */
if( psDec->fs_kHz == 8 ) {
SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_NB_CDF, SKP_Silk_pitch_lag_NB_CDF_offset );
} else if( psDec->fs_kHz == 12 ) {
SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_MB_CDF, SKP_Silk_pitch_lag_MB_CDF_offset );
} else if( psDec->fs_kHz == 16 ) {
SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_WB_CDF, SKP_Silk_pitch_lag_WB_CDF_offset );
} else {
SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_SWB_CDF, SKP_Silk_pitch_lag_SWB_CDF_offset );
}
/* Get countour index */
if( psDec->fs_kHz == 8 ) {
/* Less codevectors used in 8 khz mode */
SKP_Silk_range_decoder( &Ixs[ 1 ], psRC, SKP_Silk_pitch_contour_NB_CDF, SKP_Silk_pitch_contour_NB_CDF_offset );
} else {
/* Joint for 12, 16, and 24 khz */
SKP_Silk_range_decoder( &Ixs[ 1 ], psRC, SKP_Silk_pitch_contour_CDF, SKP_Silk_pitch_contour_CDF_offset );
}
/* Decode pitch values */
SKP_Silk_decode_pitch( Ixs[ 0 ], Ixs[ 1 ], psDecCtrl->pitchL, psDec->fs_kHz );
/********************/
/* Decode LTP gains */
/********************/
/* Decode PERIndex value */
SKP_Silk_range_decoder( &psDecCtrl->PERIndex, psRC, SKP_Silk_LTP_per_index_CDF,
SKP_Silk_LTP_per_index_CDF_offset );
/* Decode Codebook Index */
cbk_ptr_Q14 = SKP_Silk_LTP_vq_ptrs_Q14[ psDecCtrl->PERIndex ]; /* set pointer to start of codebook */
for( k = 0; k < NB_SUBFR; k++ ) {
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_LTP_gain_CDF_ptrs[ psDecCtrl->PERIndex ],
SKP_Silk_LTP_gain_CDF_offsets[ psDecCtrl->PERIndex ] );
for( i = 0; i < LTP_ORDER; i++ ) {
psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = cbk_ptr_Q14[ Ix * LTP_ORDER + i ];
}
}
/**********************/
/* Decode LTP scaling */
/**********************/
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_LTPscale_CDF, SKP_Silk_LTPscale_offset );
psDecCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ Ix ];
} else {
SKP_assert( psDecCtrl->sigtype == SIG_TYPE_UNVOICED );
SKP_memset( psDecCtrl->pitchL, 0, NB_SUBFR * sizeof( SKP_int ) );
SKP_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * NB_SUBFR * sizeof( SKP_int16 ) );
psDecCtrl->PERIndex = 0;
psDecCtrl->LTP_scale_Q14 = 0;
}
/***************/
/* Decode seed */
/***************/
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_Seed_CDF, SKP_Silk_Seed_offset );
psDecCtrl->Seed = ( SKP_int32 )Ix;
/*********************************************/
/* Decode quantization indices of excitation */
/*********************************************/
SKP_Silk_decode_pulses( psRC, psDecCtrl, q, psDec->frame_length );
/*********************************************/
/* Decode VAD flag */
/*********************************************/
SKP_Silk_range_decoder( &psDec->vadFlag, psRC, SKP_Silk_vadflag_CDF, SKP_Silk_vadflag_offset );
/**************************************/
/* Decode Frame termination indicator */
/**************************************/
SKP_Silk_range_decoder( &psDec->FrameTermination, psRC, SKP_Silk_FrameTermination_CDF, SKP_Silk_FrameTermination_offset );
/****************************************/
/* get number of bytes used so far */
/****************************************/
SKP_Silk_range_coder_get_length( psRC, &nBytesUsed );
psDec->nBytesLeft = psRC->bufferLength - nBytesUsed;
if( psDec->nBytesLeft < 0 ) {
psRC->error = RANGE_CODER_READ_BEYOND_BUFFER;
}
/****************************************/
/* check remaining bits in last byte */
/****************************************/
if( psDec->nBytesLeft == 0 ) {
SKP_Silk_range_coder_check_after_decoding( psRC );
}
}

View File

@ -0,0 +1,57 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/***********************************************************
* Pitch analyser function
********************************************************** */
#include "SKP_Silk_SigProc_FIX.h"
#include "SKP_Silk_common_pitch_est_defines.h"
void SKP_Silk_decode_pitch(
SKP_int lagIndex, /* I */
SKP_int contourIndex, /* O */
SKP_int pitch_lags[], /* O 4 pitch values */
SKP_int Fs_kHz /* I sampling frequency (kHz) */
)
{
SKP_int lag, i, min_lag;
min_lag = SKP_SMULBB( PITCH_EST_MIN_LAG_MS, Fs_kHz );
/* Only for 24 / 16 kHz version for now */
lag = min_lag + lagIndex;
if( Fs_kHz == 8 ) {
/* Only a small codebook for 8 khz */
for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) {
pitch_lags[ i ] = lag + SKP_Silk_CB_lags_stage2[ i ][ contourIndex ];
}
} else {
for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) {
pitch_lags[ i ] = lag + SKP_Silk_CB_lags_stage3[ i ][ contourIndex ];
}
}
}

View File

@ -0,0 +1,105 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/*********************************************/
/* Decode quantization indices of excitation */
/*********************************************/
void SKP_Silk_decode_pulses(
SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int q[], /* O Excitation signal */
const SKP_int frame_length /* I Frame length (preliminary) */
)
{
SKP_int i, j, k, iter, abs_q, nLS, bit;
SKP_int sum_pulses[ MAX_NB_SHELL_BLOCKS ], nLshifts[ MAX_NB_SHELL_BLOCKS ];
SKP_int *pulses_ptr;
const SKP_uint16 *cdf_ptr;
/*********************/
/* Decode rate level */
/*********************/
SKP_Silk_range_decoder( &psDecCtrl->RateLevelIndex, psRC,
SKP_Silk_rate_levels_CDF[ psDecCtrl->sigtype ], SKP_Silk_rate_levels_CDF_offset );
/* Calculate number of shell blocks */
iter = frame_length / SHELL_CODEC_FRAME_LENGTH;
/***************************************************/
/* Sum-Weighted-Pulses Decoding */
/***************************************************/
cdf_ptr = SKP_Silk_pulses_per_block_CDF[ psDecCtrl->RateLevelIndex ];
for( i = 0; i < iter; i++ ) {
nLshifts[ i ] = 0;
SKP_Silk_range_decoder( &sum_pulses[ i ], psRC, cdf_ptr, SKP_Silk_pulses_per_block_CDF_offset );
/* LSB indication */
while( sum_pulses[ i ] == ( MAX_PULSES + 1 ) ) {
nLshifts[ i ]++;
SKP_Silk_range_decoder( &sum_pulses[ i ], psRC,
SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ], SKP_Silk_pulses_per_block_CDF_offset );
}
}
/***************************************************/
/* Shell decoding */
/***************************************************/
for( i = 0; i < iter; i++ ) {
if( sum_pulses[ i ] > 0 ) {
SKP_Silk_shell_decoder( &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], psRC, sum_pulses[ i ] );
} else {
SKP_memset( &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof( SKP_int ) );
}
}
/***************************************************/
/* LSB Decoding */
/***************************************************/
for( i = 0; i < iter; i++ ) {
if( nLshifts[ i ] > 0 ) {
nLS = nLshifts[ i ];
pulses_ptr = &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ];
for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
abs_q = pulses_ptr[ k ];
for( j = 0; j < nLS; j++ ) {
abs_q = SKP_LSHIFT( abs_q, 1 );
SKP_Silk_range_decoder( &bit, psRC, SKP_Silk_lsb_CDF, 1 );
abs_q += bit;
}
pulses_ptr[ k ] = abs_q;
}
}
}
/****************************************/
/* Decode and add signs to pulse signal */
/****************************************/
SKP_Silk_decode_signs( psRC, q, frame_length, psDecCtrl->sigtype,
psDecCtrl->QuantOffsetType, psDecCtrl->RateLevelIndex);
}

View File

@ -0,0 +1,80 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/* Set decoder sampling rate */
void SKP_Silk_decoder_set_fs(
SKP_Silk_decoder_state *psDec, /* I/O Decoder state pointer */
SKP_int fs_kHz /* I Sampling frequency (kHz) */
)
{
if( psDec->fs_kHz != fs_kHz ) {
psDec->fs_kHz = fs_kHz;
psDec->frame_length = SKP_SMULBB( FRAME_LENGTH_MS, fs_kHz );
psDec->subfr_length = SKP_SMULBB( FRAME_LENGTH_MS / NB_SUBFR, fs_kHz );
if( psDec->fs_kHz == 8 ) {
psDec->LPC_order = MIN_LPC_ORDER;
psDec->psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_10;
psDec->psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_10;
} else {
psDec->LPC_order = MAX_LPC_ORDER;
psDec->psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_16;
psDec->psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_16;
}
/* Reset part of the decoder state */
SKP_memset( psDec->sLPC_Q14, 0, MAX_LPC_ORDER * sizeof( SKP_int32 ) );
SKP_memset( psDec->outBuf, 0, MAX_FRAME_LENGTH * sizeof( SKP_int16 ) );
SKP_memset( psDec->prevNLSF_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) );
psDec->lagPrev = 100;
psDec->LastGainIndex = 1;
psDec->prev_sigtype = 0;
psDec->first_frame_after_reset = 1;
if( fs_kHz == 24 ) {
psDec->HP_A = SKP_Silk_Dec_A_HP_24;
psDec->HP_B = SKP_Silk_Dec_B_HP_24;
} else if( fs_kHz == 16 ) {
psDec->HP_A = SKP_Silk_Dec_A_HP_16;
psDec->HP_B = SKP_Silk_Dec_B_HP_16;
} else if( fs_kHz == 12 ) {
psDec->HP_A = SKP_Silk_Dec_A_HP_12;
psDec->HP_B = SKP_Silk_Dec_B_HP_12;
} else if( fs_kHz == 8 ) {
psDec->HP_A = SKP_Silk_Dec_A_HP_8;
psDec->HP_B = SKP_Silk_Dec_B_HP_8;
} else {
/* unsupported sampling rate */
SKP_assert( 0 );
}
}
/* Check that settings are valid */
SKP_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );
}

View File

@ -0,0 +1,306 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef SKP_SILK_DEFINE_H
#define SKP_SILK_DEFINE_H
#include "SKP_Silk_errors.h"
#include "SKP_Silk_typedef.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define MAX_FRAMES_PER_PACKET 5
/* Limits on bitrate */
#define MIN_TARGET_RATE_BPS 5000
#define MAX_TARGET_RATE_BPS 100000
/* Transition bitrates between modes */
#define SWB2WB_BITRATE_BPS 25000
#define WB2SWB_BITRATE_BPS 30000
#define WB2MB_BITRATE_BPS 14000
#define MB2WB_BITRATE_BPS 18000
#define MB2NB_BITRATE_BPS 10000
#define NB2MB_BITRATE_BPS 14000
/* Integration/hysteresis threshold for lowering internal sample frequency */
/* 30000000 -> 6 sec if bitrate is 5000 bps below limit; 3 sec if bitrate is 10000 bps below limit */
#define ACCUM_BITS_DIFF_THRESHOLD 30000000
#define TARGET_RATE_TAB_SZ 8
/* DTX settings */
#define NO_SPEECH_FRAMES_BEFORE_DTX 5 /* eq 100 ms */
#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */
#define USE_LBRR 1
/* Amount of concecutive no FEC packets before telling JB */
#define NO_LBRR_THRES 10
/* Maximum delay between real packet and LBRR packet */
#define MAX_LBRR_DELAY 2
#define LBRR_IDX_MASK 1
#define INBAND_FEC_MIN_RATE_BPS 18000 /* Dont use inband FEC below this total target rate */
#define LBRR_LOSS_THRES 1 /* Start adding LBRR at this loss rate */
/* LBRR usage defines */
#define SKP_SILK_NO_LBRR 0 /* No LBRR information for this packet */
#define SKP_SILK_ADD_LBRR_TO_PLUS1 1 /* Add LBRR for this packet to packet n + 1 */
#define SKP_SILK_ADD_LBRR_TO_PLUS2 2 /* Add LBRR for this packet to packet n + 2 */
/* Frame termination indicator defines */
#define SKP_SILK_LAST_FRAME 0 /* Last frames in packet */
#define SKP_SILK_MORE_FRAMES 1 /* More frames to follow this one */
#define SKP_SILK_LBRR_VER1 2 /* LBRR information from packet n - 1 */
#define SKP_SILK_LBRR_VER2 3 /* LBRR information from packet n - 2 */
#define SKP_SILK_EXT_LAYER 4 /* Extension layers added */
/* Number of Second order Sections for SWB detection HP filter */
#define NB_SOS 3
#define HP_8_KHZ_THRES 10 /* average energy per sample, above 8 kHz */
#define CONCEC_SWB_SMPLS_THRES 480 * 15 /* 300 ms */
#define WB_DETECT_ACTIVE_SPEECH_MS_THRES 15000 /* ms of active speech needed for WB detection */
/* Low complexity setting */
#define LOW_COMPLEXITY_ONLY 0
/* Activate bandwidth transition filtering for mode switching */
#define SWITCH_TRANSITION_FILTERING 1
/* Decoder Parameters */
#define DEC_HP_ORDER 2
/* Maximum sampling frequency, should be 16 for some embedded platforms */
#define MAX_FS_KHZ 24
#define MAX_API_FS_KHZ 48
/* Signal Types used by silk */
#define SIG_TYPE_VOICED 0
#define SIG_TYPE_UNVOICED 1
/* VAD Types used by silk */
#define NO_VOICE_ACTIVITY 0
#define VOICE_ACTIVITY 1
/* Number of samples per frame */
#define FRAME_LENGTH_MS 20
#define MAX_FRAME_LENGTH ( FRAME_LENGTH_MS * MAX_FS_KHZ )
/* Milliseconds of lookahead for pitch analysis */
#define LA_PITCH_MS 2
#define LA_PITCH_MAX ( LA_PITCH_MS * MAX_FS_KHZ )
/* Length of LPC window used in find pitch */
#define FIND_PITCH_LPC_WIN_MS ( 20 + (LA_PITCH_MS << 1) )
#define FIND_PITCH_LPC_WIN_MAX ( FIND_PITCH_LPC_WIN_MS * MAX_FS_KHZ )
/* Order of LPC used in find pitch */
#define MAX_FIND_PITCH_LPC_ORDER 16
#define PITCH_EST_COMPLEXITY_HC_MODE SKP_Silk_PITCH_EST_MAX_COMPLEX
#define PITCH_EST_COMPLEXITY_MC_MODE SKP_Silk_PITCH_EST_MID_COMPLEX
#define PITCH_EST_COMPLEXITY_LC_MODE SKP_Silk_PITCH_EST_MIN_COMPLEX
/* Milliseconds of lookahead for noise shape analysis */
#define LA_SHAPE_MS 5
#define LA_SHAPE_MAX ( LA_SHAPE_MS * MAX_FS_KHZ )
/* Max length of LPC window used in noise shape analysis */
#define SHAPE_LPC_WIN_MAX ( 15 * MAX_FS_KHZ )
/* Max number of bytes in payload output buffer (may contain multiple frames) */
#define MAX_ARITHM_BYTES 1024
#define RANGE_CODER_WRITE_BEYOND_BUFFER -1
#define RANGE_CODER_CDF_OUT_OF_RANGE -2
#define RANGE_CODER_NORMALIZATION_FAILED -3
#define RANGE_CODER_ZERO_INTERVAL_WIDTH -4
#define RANGE_CODER_DECODER_CHECK_FAILED -5
#define RANGE_CODER_READ_BEYOND_BUFFER -6
#define RANGE_CODER_ILLEGAL_SAMPLING_RATE -7
#define RANGE_CODER_DEC_PAYLOAD_TOO_LONG -8
/* dB level of lowest gain quantization level */
#define MIN_QGAIN_DB 6
/* dB level of highest gain quantization level */
#define MAX_QGAIN_DB 86
/* Number of gain quantization levels */
#define N_LEVELS_QGAIN 64
/* Max increase in gain quantization index */
#define MAX_DELTA_GAIN_QUANT 40
/* Max decrease in gain quantization index */
#define MIN_DELTA_GAIN_QUANT -4
/* Quantization offsets (multiples of 4) */
#define OFFSET_VL_Q10 32
#define OFFSET_VH_Q10 100
#define OFFSET_UVL_Q10 100
#define OFFSET_UVH_Q10 256
/* Maximum numbers of iterations used to stabilize a LPC vector */
#define MAX_LPC_STABILIZE_ITERATIONS 20
#define MAX_LPC_ORDER 16
#define MIN_LPC_ORDER 10
/* Find Pred Coef defines */
#define LTP_ORDER 5
/* LTP quantization settings */
#define NB_LTP_CBKS 3
/* Number of subframes */
#define NB_SUBFR 4
/* Flag to use harmonic noise shaping */
#define USE_HARM_SHAPING 1
/* Max LPC order of noise shaping filters */
#define MAX_SHAPE_LPC_ORDER 16
#define HARM_SHAPE_FIR_TAPS 3
/* Maximum number of delayed decision states */
#define MAX_DEL_DEC_STATES 4
#define LTP_BUF_LENGTH 512
#define LTP_MASK (LTP_BUF_LENGTH - 1)
#define DECISION_DELAY 32
#define DECISION_DELAY_MASK (DECISION_DELAY - 1)
/* number of subframes for excitation entropy coding */
#define SHELL_CODEC_FRAME_LENGTH 16
#define MAX_NB_SHELL_BLOCKS (MAX_FRAME_LENGTH / SHELL_CODEC_FRAME_LENGTH)
/* number of rate levels, for entropy coding of excitation */
#define N_RATE_LEVELS 10
/* maximum sum of pulses per shell coding frame */
#define MAX_PULSES 18
#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */
#if( MAX_LPC_ORDER > DECISION_DELAY )
# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER
#else
# define NSQ_LPC_BUF_LENGTH DECISION_DELAY
#endif
/***********************/
/* High pass filtering */
/***********************/
#define HIGH_PASS_INPUT 1
/***************************/
/* Voice activity detector */
/***************************/
#define VAD_N_BANDS 4
#define VAD_INTERNAL_SUBFRAMES_LOG2 2
#define VAD_INTERNAL_SUBFRAMES (1 << VAD_INTERNAL_SUBFRAMES_LOG2)
#define VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 1024 /* Must be < 4096 */
#define VAD_NOISE_LEVELS_BIAS 50
/* Sigmoid settings */
#define VAD_NEGATIVE_OFFSET_Q5 128 /* sigmoid is 0 at -128 */
#define VAD_SNR_FACTOR_Q16 45000
/* smoothing for SNR measurement */
#define VAD_SNR_SMOOTH_COEF_Q18 4096
/******************/
/* NLSF quantizer */
/******************/
# define NLSF_MSVQ_MAX_CB_STAGES 10 /* Update manually when changing codebooks */
# define NLSF_MSVQ_MAX_VECTORS_IN_STAGE 128 /* Update manually when changing codebooks */
# define NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END 16 /* Update manually when changing codebooks */
#define NLSF_MSVQ_FLUCTUATION_REDUCTION 1
#define MAX_NLSF_MSVQ_SURVIVORS 16
#define MAX_NLSF_MSVQ_SURVIVORS_LC_MODE 2
#define MAX_NLSF_MSVQ_SURVIVORS_MC_MODE 4
/* Based on above defines, calculate how much memory is necessary to allocate */
#if( NLSF_MSVQ_MAX_VECTORS_IN_STAGE > ( MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END ) )
# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE NLSF_MSVQ_MAX_VECTORS_IN_STAGE
#else
# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END
#endif
#if( NLSF_MSVQ_MAX_VECTORS_IN_STAGE > ( MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END ) )
# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED NLSF_MSVQ_MAX_VECTORS_IN_STAGE
#else
# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END
#endif
#define NLSF_MSVQ_SURV_MAX_REL_RD 0.1f /* Must be < 0.5 */
/* Transition filtering for mode switching */
#if SWITCH_TRANSITION_FILTERING
# define TRANSITION_TIME_UP_MS 5120 // 5120 = 64 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 64*(20*4)
# define TRANSITION_TIME_DOWN_MS 2560 // 2560 = 32 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 32*(20*4)
# define TRANSITION_NB 3 /* Hardcoded in tables */
# define TRANSITION_NA 2 /* Hardcoded in tables */
# define TRANSITION_INT_NUM 5 /* Hardcoded in tables */
# define TRANSITION_FRAMES_UP ( TRANSITION_TIME_UP_MS / FRAME_LENGTH_MS )
# define TRANSITION_FRAMES_DOWN ( TRANSITION_TIME_DOWN_MS / FRAME_LENGTH_MS )
# define TRANSITION_INT_STEPS_UP ( TRANSITION_FRAMES_UP / ( TRANSITION_INT_NUM - 1 ) )
# define TRANSITION_INT_STEPS_DOWN ( TRANSITION_FRAMES_DOWN / ( TRANSITION_INT_NUM - 1 ) )
#endif
/* Row based */
#define matrix_ptr(Matrix_base_adr, row, column, N) *(Matrix_base_adr + ((row)*(N)+(column)))
#define matrix_adr(Matrix_base_adr, row, column, N) (Matrix_base_adr + ((row)*(N)+(column)))
/* Column based */
#ifndef matrix_c_ptr
# define matrix_c_ptr(Matrix_base_adr, row, column, M) *(Matrix_base_adr + ((row)+(M)*(column)))
#endif
#define matrix_c_adr(Matrix_base_adr, row, column, M) (Matrix_base_adr + ((row)+(M)*(column)))
/* BWE factors to apply after packet loss */
#define BWE_AFTER_LOSS_Q16 63570
/* Defines for CN generation */
#define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */
#define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */
#define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,76 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/*
* Detect SWB input by measuring energy above 8 kHz.
*/
#include "SKP_Silk_main.h"
void SKP_Silk_detect_SWB_input(
SKP_Silk_detect_SWB_state *psSWBdetect, /* (I/O) encoder state */
const SKP_int16 samplesIn[], /* (I) input to encoder */
SKP_int nSamplesIn /* (I) length of input */
)
{
SKP_int HP_8_kHz_len, i, shift;
SKP_int16 in_HP_8_kHz[ MAX_FRAME_LENGTH ];
SKP_int32 energy_32;
/* High pass filter with cutoff at 8 khz */
HP_8_kHz_len = SKP_min_int( nSamplesIn, MAX_FRAME_LENGTH );
HP_8_kHz_len = SKP_max_int( HP_8_kHz_len, 0 );
/* Cutoff around 9 khz */
/* A = conv(conv([8192,14613, 6868], [8192,12883, 7337]), [8192,11586, 7911]); */
/* B = conv(conv([575, -948, 575], [575, -221, 575]), [575, 104, 575]); */
SKP_Silk_biquad( samplesIn, SKP_Silk_SWB_detect_B_HP_Q13[ 0 ], SKP_Silk_SWB_detect_A_HP_Q13[ 0 ],
psSWBdetect->S_HP_8_kHz[ 0 ], in_HP_8_kHz, HP_8_kHz_len );
for( i = 1; i < NB_SOS; i++ ) {
SKP_Silk_biquad( in_HP_8_kHz, SKP_Silk_SWB_detect_B_HP_Q13[ i ], SKP_Silk_SWB_detect_A_HP_Q13[ i ],
psSWBdetect->S_HP_8_kHz[ i ], in_HP_8_kHz, HP_8_kHz_len );
}
/* Calculate energy in HP signal */
SKP_Silk_sum_sqr_shift( &energy_32, &shift, in_HP_8_kHz, HP_8_kHz_len );
/* Count concecutive samples above threshold, after adjusting threshold for number of input samples and shift */
if( energy_32 > SKP_RSHIFT( SKP_SMULBB( HP_8_KHZ_THRES, HP_8_kHz_len ), shift ) ) {
psSWBdetect->ConsecSmplsAboveThres += nSamplesIn;
if( psSWBdetect->ConsecSmplsAboveThres > CONCEC_SWB_SMPLS_THRES ) {
psSWBdetect->SWB_detected = 1;
}
} else {
psSWBdetect->ConsecSmplsAboveThres -= nSamplesIn;
psSWBdetect->ConsecSmplsAboveThres = SKP_max( psSWBdetect->ConsecSmplsAboveThres, 0 );
}
/* If sufficient speech activity and no SWB detected, we detect the signal as being WB */
if( ( psSWBdetect->ActiveSpeech_ms > WB_DETECT_ACTIVE_SPEECH_MS_THRES ) && ( psSWBdetect->SWB_detected == 0 ) ) {
psSWBdetect->WB_detected = 1;
}
}

View File

@ -0,0 +1,247 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_define.h"
#include "SKP_Silk_main_FLP.h"
#include "SKP_Silk_SDK_API.h"
#include "SKP_Silk_control.h"
#include "SKP_Silk_typedef.h"
#include "SKP_Silk_structs.h"
#define SKP_Silk_EncodeControlStruct SKP_SILK_SDK_EncControlStruct
/****************************************/
/* Encoder functions */
/****************************************/
SKP_int SKP_Silk_SDK_Get_Encoder_Size( SKP_int32 *encSizeBytes )
{
SKP_int ret = 0;
*encSizeBytes = sizeof( SKP_Silk_encoder_state_FLP );
return ret;
}
/***************************************/
/* Read control structure from encoder */
/***************************************/
SKP_int SKP_Silk_SDK_QueryEncoder(
const void *encState, /* I: State Vector */
SKP_Silk_EncodeControlStruct *encStatus /* O: Control Structure */
)
{
SKP_Silk_encoder_state_FLP *psEnc;
SKP_int ret = 0;
psEnc = ( SKP_Silk_encoder_state_FLP* )encState;
encStatus->API_sampleRate = psEnc->sCmn.API_fs_Hz;
encStatus->maxInternalSampleRate = SKP_SMULBB( psEnc->sCmn.maxInternal_fs_kHz, 1000 );
encStatus->packetSize = ( SKP_int )SKP_DIV32_16( psEnc->sCmn.API_fs_Hz * psEnc->sCmn.PacketSize_ms, 1000 ); /* convert samples -> ms */
encStatus->bitRate = psEnc->sCmn.TargetRate_bps;
encStatus->packetLossPercentage = psEnc->sCmn.PacketLoss_perc;
encStatus->complexity = psEnc->sCmn.Complexity;
encStatus->useInBandFEC = psEnc->sCmn.useInBandFEC;
encStatus->useDTX = psEnc->sCmn.useDTX;
return ret;
}
/*************************/
/* Init or Reset encoder */
/*************************/
SKP_int SKP_Silk_SDK_InitEncoder(
void *encState, /* I/O: State */
SKP_Silk_EncodeControlStruct *encStatus /* O: Control structure */
)
{
SKP_Silk_encoder_state_FLP *psEnc;
SKP_int ret = 0;
psEnc = ( SKP_Silk_encoder_state_FLP* )encState;
/* Reset Encoder */
if( ret += SKP_Silk_init_encoder_FLP( psEnc ) ) {
SKP_assert( 0 );
}
/* Read control structure */
if( ret += SKP_Silk_SDK_QueryEncoder( encState, encStatus ) ) {
SKP_assert( 0 );
}
return ret;
}
/**************************/
/* Encode frame with Silk */
/**************************/
SKP_int SKP_Silk_SDK_Encode(
void *encState, /* I/O: State */
const SKP_Silk_EncodeControlStruct *encControl, /* I: Control structure */
const SKP_int16 *samplesIn, /* I: Speech sample input vector */
SKP_int nSamplesIn, /* I: Number of samples in input vector */
SKP_uint8 *outData, /* O: Encoded output vector */
SKP_int16 *nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */
)
{
SKP_int max_internal_fs_kHz, PacketSize_ms, PacketLoss_perc, UseInBandFEC, UseDTX, ret = 0;
SKP_int nSamplesToBuffer, Complexity, input_10ms, nSamplesFromInput = 0;
SKP_int32 TargetRate_bps, API_fs_Hz;
SKP_int16 MaxBytesOut;
SKP_Silk_encoder_state_FLP *psEnc = ( SKP_Silk_encoder_state_FLP* )encState;
SKP_assert( encControl != NULL );
/* Check sampling frequency first, to avoid divide by zero later */
if( ( ( encControl->API_sampleRate != 8000 ) &&
( encControl->API_sampleRate != 12000 ) &&
( encControl->API_sampleRate != 16000 ) &&
( encControl->API_sampleRate != 24000 ) &&
( encControl->API_sampleRate != 32000 ) &&
( encControl->API_sampleRate != 44100 ) &&
( encControl->API_sampleRate != 48000 ) ) ||
( ( encControl->maxInternalSampleRate != 8000 ) &&
( encControl->maxInternalSampleRate != 12000 ) &&
( encControl->maxInternalSampleRate != 16000 ) &&
( encControl->maxInternalSampleRate != 24000 ) ) ) {
ret = SKP_SILK_ENC_FS_NOT_SUPPORTED;
SKP_assert( 0 );
return( ret );
}
/* Set encoder parameters from control structure */
API_fs_Hz = encControl->API_sampleRate;
max_internal_fs_kHz = (SKP_int)( encControl->maxInternalSampleRate >> 10 ) + 1; /* convert Hz -> kHz */
PacketSize_ms = SKP_DIV32( 1000 * (SKP_int)encControl->packetSize, API_fs_Hz );
TargetRate_bps = encControl->bitRate;
PacketLoss_perc = encControl->packetLossPercentage;
UseInBandFEC = encControl->useInBandFEC;
Complexity = encControl->complexity;
UseDTX = encControl->useDTX;
/* Save values in state */
psEnc->sCmn.API_fs_Hz = API_fs_Hz;
psEnc->sCmn.maxInternal_fs_kHz = max_internal_fs_kHz;
psEnc->sCmn.useInBandFEC = UseInBandFEC;
/* Only accept input lengths that are a multiple of 10 ms */
input_10ms = SKP_DIV32( 100 * nSamplesIn, API_fs_Hz );
if( input_10ms * API_fs_Hz != 100 * nSamplesIn || nSamplesIn < 0 ) {
ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
SKP_assert( 0 );
return( ret );
}
TargetRate_bps = SKP_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS );
if( ( ret = SKP_Silk_control_encoder_FLP( psEnc, PacketSize_ms, TargetRate_bps,
PacketLoss_perc, UseDTX, Complexity) ) != 0 ) {
SKP_assert( 0 );
return( ret );
}
/* Make sure no more than one packet can be produced */
if( 1000 * (SKP_int32)nSamplesIn > psEnc->sCmn.PacketSize_ms * API_fs_Hz ) {
ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
SKP_assert( 0 );
return( ret );
}
#if MAX_FS_KHZ > 16
/* Detect energy above 8 kHz */
if( SKP_min( API_fs_Hz, 1000 * max_internal_fs_kHz ) == 24000 &&
psEnc->sCmn.sSWBdetect.SWB_detected == 0 &&
psEnc->sCmn.sSWBdetect.WB_detected == 0 ) {
SKP_Silk_detect_SWB_input( &psEnc->sCmn.sSWBdetect, samplesIn, ( SKP_int )nSamplesIn );
}
#endif
/* Input buffering/resampling and encoding */
MaxBytesOut = 0; /* return 0 output bytes if no encoder called */
while( 1 ) {
nSamplesToBuffer = psEnc->sCmn.frame_length - psEnc->sCmn.inputBufIx;
if( API_fs_Hz == SKP_SMULBB( 1000, psEnc->sCmn.fs_kHz ) ) {
nSamplesToBuffer = SKP_min_int( nSamplesToBuffer, nSamplesIn );
nSamplesFromInput = nSamplesToBuffer;
/* Copy to buffer */
SKP_memcpy( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, nSamplesFromInput * sizeof( SKP_int16 ) );
} else {
nSamplesToBuffer = SKP_min( nSamplesToBuffer, 10 * input_10ms * psEnc->sCmn.fs_kHz );
nSamplesFromInput = SKP_DIV32_16( nSamplesToBuffer * API_fs_Hz, psEnc->sCmn.fs_kHz * 1000 );
/* Resample and write to buffer */
ret += SKP_Silk_resampler( &psEnc->sCmn.resampler_state,
&psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, nSamplesFromInput );
}
samplesIn += nSamplesFromInput;
nSamplesIn -= nSamplesFromInput;
psEnc->sCmn.inputBufIx += nSamplesToBuffer;
/* Silk encoder */
if( psEnc->sCmn.inputBufIx >= psEnc->sCmn.frame_length ) {
SKP_assert( psEnc->sCmn.inputBufIx == psEnc->sCmn.frame_length );
/* Enough data in input buffer, so encode */
if( MaxBytesOut == 0 ) {
/* No payload obtained so far */
MaxBytesOut = *nBytesOut;
if( ( ret = SKP_Silk_encode_frame_FLP( psEnc, outData, &MaxBytesOut, psEnc->sCmn.inputBuf ) ) != 0 ) {
SKP_assert( 0 );
}
} else {
/* outData already contains a payload */
if( ( ret = SKP_Silk_encode_frame_FLP( psEnc, outData, nBytesOut, psEnc->sCmn.inputBuf ) ) != 0 ) {
SKP_assert( 0 );
}
/* Check that no second payload was created */
SKP_assert( *nBytesOut == 0 );
}
psEnc->sCmn.inputBufIx = 0;
psEnc->sCmn.controlled_since_last_payload = 0;
if( nSamplesIn == 0 ) {
break;
}
} else {
break;
}
}
*nBytesOut = MaxBytesOut;
if( psEnc->sCmn.useDTX && psEnc->sCmn.inDTX ) {
/* DTX simulation */
*nBytesOut = 0;
}
return ret;
}

View File

@ -0,0 +1,398 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
#include "SKP_Silk_tuning_parameters.h"
/****************/
/* Encode frame */
/****************/
SKP_int SKP_Silk_encode_frame_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_uint8 *pCode, /* O Payload */
SKP_int16 *pnBytesOut, /* I/O Number of payload bytes; */
/* input: max length; output: used */
const SKP_int16 *pIn /* I Input speech frame */
)
{
SKP_Silk_encoder_control_FLP sEncCtrl;
SKP_int k, nBytes, ret = 0;
SKP_float *x_frame, *res_pitch_frame;
SKP_int16 pIn_HP[ MAX_FRAME_LENGTH ];
SKP_int16 pIn_HP_LP[ MAX_FRAME_LENGTH ];
SKP_float xfw[ MAX_FRAME_LENGTH ];
SKP_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
SKP_int LBRR_idx, frame_terminator;
/* Low bitrate redundancy parameters */
SKP_uint8 LBRRpayload[ MAX_ARITHM_BYTES ];
SKP_int16 nBytesLBRR;
const SKP_uint16 *FrameTermination_CDF;
sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3;
/**************************************************************/
/* Setup Input Pointers, and insert frame in input buffer */
/*************************************************************/
/* pointers aligned with start of frame to encode */
x_frame = psEnc->x_buf + psEnc->sCmn.frame_length; // start of frame to encode
res_pitch_frame = res_pitch + psEnc->sCmn.frame_length; // start of pitch LPC residual frame
/****************************/
/* Voice Activity Detection */
/****************************/
SKP_Silk_VAD_FLP( psEnc, &sEncCtrl, pIn );
/*******************************************/
/* High-pass filtering of the input signal */
/*******************************************/
#if HIGH_PASS_INPUT
/* Variable high-pass filter */
SKP_Silk_HP_variable_cutoff_FLP( psEnc, &sEncCtrl, pIn_HP, pIn );
#else
SKP_memcpy( pIn_HP, pIn, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );
#endif
#if SWITCH_TRANSITION_FILTERING
/* Ensure smooth bandwidth transitions */
SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, pIn_HP_LP, pIn_HP, psEnc->sCmn.frame_length );
#else
SKP_memcpy( pIn_HP_LP, pIn_HP, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );
#endif
/*******************************************/
/* Copy new frame to front of input buffer */
/*******************************************/
SKP_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP_LP, psEnc->sCmn.frame_length );
/* Add tiny signal to avoid high CPU load from denormalized floating point numbers */
for( k = 0; k < 8; k++ ) {
x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + k * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( k & 2 ) ) * 1e-6f;
}
/*****************************************/
/* Find pitch lags, initial LPC analysis */
/*****************************************/
SKP_Silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame );
/************************/
/* Noise shape analysis */
/************************/
SKP_Silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
/*****************************************/
/* Prefiltering for noise shaper */
/*****************************************/
SKP_Silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame );
/***************************************************/
/* Find linear prediction coefficients (LPC + LTP) */
/***************************************************/
SKP_Silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch );
/****************************************/
/* Process gains */
/****************************************/
SKP_Silk_process_gains_FLP( psEnc, &sEncCtrl );
/****************************************/
/* Low Bitrate Redundant Encoding */
/****************************************/
nBytesLBRR = MAX_ARITHM_BYTES;
SKP_Silk_LBRR_encode_FLP( psEnc, &sEncCtrl, LBRRpayload, &nBytesLBRR, xfw );
/*****************************************/
/* Noise shaping quantization */
/*****************************************/
SKP_Silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, xfw, psEnc->sCmn.q, 0 );
/**************************************************/
/* Convert speech activity into VAD and DTX flags */
/**************************************************/
if( psEnc->speech_activity < SPEECH_ACTIVITY_DTX_THRES ) {
psEnc->sCmn.vadFlag = NO_VOICE_ACTIVITY;
psEnc->sCmn.noSpeechCounter++;
if( psEnc->sCmn.noSpeechCounter > NO_SPEECH_FRAMES_BEFORE_DTX ) {
psEnc->sCmn.inDTX = 1;
}
if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NO_SPEECH_FRAMES_BEFORE_DTX ) {
psEnc->sCmn.noSpeechCounter = NO_SPEECH_FRAMES_BEFORE_DTX;
psEnc->sCmn.inDTX = 0;
}
} else {
psEnc->sCmn.noSpeechCounter = 0;
psEnc->sCmn.inDTX = 0;
psEnc->sCmn.vadFlag = VOICE_ACTIVITY;
}
/****************************************/
/* Initialize range coder */
/****************************************/
if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
SKP_Silk_range_enc_init( &psEnc->sCmn.sRC );
psEnc->sCmn.nBytesInPayloadBuf = 0;
}
/****************************************/
/* Encode Parameters */
/****************************************/
SKP_Silk_encode_parameters( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC, psEnc->sCmn.q );
FrameTermination_CDF = SKP_Silk_FrameTermination_CDF;
/****************************************/
/* Update Buffers and State */
/****************************************/
/* Update input buffer */
SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
( psEnc->sCmn.frame_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_float ) );
/* Parameters needed for next frame */
psEnc->sCmn.prev_sigtype = sEncCtrl.sCmn.sigtype;
psEnc->sCmn.prevLag = sEncCtrl.sCmn.pitchL[ NB_SUBFR - 1];
psEnc->sCmn.first_frame_after_reset = 0;
if( psEnc->sCmn.sRC.error ) {
/* Encoder returned error: Clear payload buffer */
psEnc->sCmn.nFramesInPayloadBuf = 0;
} else {
psEnc->sCmn.nFramesInPayloadBuf++;
}
/****************************************/
/* Finalize payload and copy to output */
/****************************************/
if( psEnc->sCmn.nFramesInPayloadBuf * FRAME_LENGTH_MS >= psEnc->sCmn.PacketSize_ms ) {
LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;
/* Check if FEC information should be added */
frame_terminator = SKP_SILK_LAST_FRAME;
if( psEnc->sCmn.LBRR_buffer[ LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS1 ) {
frame_terminator = SKP_SILK_LBRR_VER1;
}
if( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS2 ) {
frame_terminator = SKP_SILK_LBRR_VER2;
LBRR_idx = psEnc->sCmn.oldest_LBRR_idx;
}
/* Add the frame termination info to stream */
SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );
/* Payload length so far */
SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC, &nBytes );
/* Check that there is enough space in external output buffer, and move data */
if( *pnBytesOut >= nBytes ) {
SKP_Silk_range_enc_wrap_up( &psEnc->sCmn.sRC );
SKP_memcpy( pCode, psEnc->sCmn.sRC.buffer, nBytes * sizeof( SKP_uint8 ) );
if( frame_terminator > SKP_SILK_MORE_FRAMES &&
*pnBytesOut >= nBytes + psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes ) {
/* Get old packet and add to payload. */
SKP_memcpy( &pCode[ nBytes ],
psEnc->sCmn.LBRR_buffer[ LBRR_idx ].payload,
psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes * sizeof( SKP_uint8 ) );
nBytes += psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes;
}
*pnBytesOut = nBytes;
/* Update FEC buffer */
SKP_memcpy( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].payload, LBRRpayload,
nBytesLBRR * sizeof( SKP_uint8 ) );
psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].nBytes = nBytesLBRR;
/* The line below describes how FEC should be used */
psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage = sEncCtrl.sCmn.LBRR_usage;
psEnc->sCmn.oldest_LBRR_idx = ( ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK );
} else {
/* Not enough space: Payload will be discarded */
*pnBytesOut = 0;
nBytes = 0;
ret = SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT;
}
/* Reset the number of frames in payload buffer */
psEnc->sCmn.nFramesInPayloadBuf = 0;
} else {
/* No payload this time */
*pnBytesOut = 0;
/* Encode that more frames follows */
frame_terminator = SKP_SILK_MORE_FRAMES;
SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );
/* Payload length so far */
SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC, &nBytes );
}
/* Check for arithmetic coder errors */
if( psEnc->sCmn.sRC.error ) {
ret = SKP_SILK_ENC_INTERNAL_ERROR;
}
/* Simulate number of ms buffered in channel because of exceeding TargetRate */
psEnc->BufferedInChannel_ms += ( 8.0f * 1000.0f * ( nBytes - psEnc->sCmn.nBytesInPayloadBuf ) ) / psEnc->sCmn.TargetRate_bps;
psEnc->BufferedInChannel_ms -= FRAME_LENGTH_MS;
psEnc->BufferedInChannel_ms = SKP_LIMIT_float( psEnc->BufferedInChannel_ms, 0.0f, 100.0f );
psEnc->sCmn.nBytesInPayloadBuf = nBytes;
if( psEnc->speech_activity > WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES ) {
psEnc->sCmn.sSWBdetect.ActiveSpeech_ms = SKP_ADD_POS_SAT32( psEnc->sCmn.sSWBdetect.ActiveSpeech_ms, FRAME_LENGTH_MS );
}
return( ret );
}
/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */
void SKP_Silk_LBRR_encode_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
SKP_uint8 *pCode, /* O Payload */
SKP_int16 *pnBytesOut, /* I/O Payload bytes; in: max; out: used */
const SKP_float xfw[] /* I Input signal */
)
{
SKP_int32 Gains_Q16[ NB_SUBFR ];
SKP_int k, TempGainsIndices[ NB_SUBFR ], frame_terminator;
SKP_int nBytes, nFramesInPayloadBuf;
SKP_float TempGains[ NB_SUBFR ];
SKP_int typeOffset, LTP_scaleIndex, Rate_only_parameters = 0;
/* Control use of inband LBRR */
SKP_Silk_LBRR_ctrl_FLP( psEnc, &psEncCtrl->sCmn );
if( psEnc->sCmn.LBRR_enabled ) {
/* Save original gains */
SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, NB_SUBFR * sizeof( SKP_int ) );
SKP_memcpy( TempGains, psEncCtrl->Gains, NB_SUBFR * sizeof( SKP_float ) );
typeOffset = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten
LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex;
/* Set max rate where quant signal is encoded */
if( psEnc->sCmn.fs_kHz == 8 ) {
Rate_only_parameters = 13500;
} else if( psEnc->sCmn.fs_kHz == 12 ) {
Rate_only_parameters = 15500;
} else if( psEnc->sCmn.fs_kHz == 16 ) {
Rate_only_parameters = 17500;
} else if( psEnc->sCmn.fs_kHz == 24 ) {
Rate_only_parameters = 19500;
} else {
SKP_assert( 0 );
}
if( psEnc->sCmn.Complexity > 0 && psEnc->sCmn.TargetRate_bps > Rate_only_parameters ) {
if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
/* First frame in packet copy everything */
SKP_memcpy( &psEnc->sCmn.sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( SKP_Silk_nsq_state ) );
psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
/* Increase Gains to get target LBRR rate */
psEncCtrl->sCmn.GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases;
psEncCtrl->sCmn.GainsIndices[ 0 ] = SKP_LIMIT_int( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 );
}
/* Decode to get gains in sync with decoder */
SKP_Silk_gains_dequant( Gains_Q16, psEncCtrl->sCmn.GainsIndices,
&psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf );
/* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
for( k = 0; k < NB_SUBFR; k++ ) {
psEncCtrl->Gains[ k ] = Gains_Q16[ k ] / 65536.0f;
}
/*****************************************/
/* Noise shaping quantization */
/*****************************************/
SKP_Silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, xfw, psEnc->sCmn.q_LBRR, 1 );
} else {
SKP_memset( psEnc->sCmn.q_LBRR, 0, psEnc->sCmn.frame_length * sizeof( SKP_int8 ) );
psEncCtrl->sCmn.LTP_scaleIndex = 0;
}
/****************************************/
/* Initialize arithmetic coder */
/****************************************/
if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
SKP_Silk_range_enc_init( &psEnc->sCmn.sRC_LBRR );
psEnc->sCmn.nBytesInPayloadBuf = 0;
}
/****************************************/
/* Encode Parameters */
/****************************************/
SKP_Silk_encode_parameters( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sRC_LBRR, psEnc->sCmn.q_LBRR );
if( psEnc->sCmn.sRC_LBRR.error ) {
/* Encoder returned error: Clear payload buffer */
nFramesInPayloadBuf = 0;
} else {
nFramesInPayloadBuf = psEnc->sCmn.nFramesInPayloadBuf + 1;
}
/****************************************/
/* Finalize payload and copy to output */
/****************************************/
if( nFramesInPayloadBuf * FRAME_LENGTH_MS >= psEnc->sCmn.PacketSize_ms ) {
/* Check if FEC information should be added */
frame_terminator = SKP_SILK_LAST_FRAME;
/* Add the frame termination info to stream */
SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF );
/* Payload length so far */
SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC_LBRR, &nBytes );
/* Check that there is enough space in external output buffer and move data */
if( *pnBytesOut >= nBytes ) {
SKP_Silk_range_enc_wrap_up( &psEnc->sCmn.sRC_LBRR );
SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.buffer, nBytes * sizeof( SKP_uint8 ) );
*pnBytesOut = nBytes;
} else {
/* Not enough space: Payload will be discarded */
*pnBytesOut = 0;
SKP_assert( 0 );
}
} else {
/* No payload this time */
*pnBytesOut = 0;
/* Encode that more frames follows */
frame_terminator = SKP_SILK_MORE_FRAMES;
SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF );
}
/* Restore original Gains */
SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices, NB_SUBFR * sizeof( SKP_int ) );
SKP_memcpy( psEncCtrl->Gains, TempGains, NB_SUBFR * sizeof( SKP_float ) );
/* Restore LTP scale index and typeoffset */
psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex;
psEnc->sCmn.typeOffsetPrev = typeOffset;
}
}

View File

@ -0,0 +1,162 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/*******************************************/
/* Encode parameters to create the payload */
/*******************************************/
void SKP_Silk_encode_parameters(
SKP_Silk_encoder_state *psEncC, /* I/O Encoder state */
SKP_Silk_encoder_control *psEncCtrlC, /* I/O Encoder control */
SKP_Silk_range_coder_state *psRC, /* I/O Range encoder state */
const SKP_int8 *q /* I Quantization indices */
)
{
SKP_int i, k, typeOffset;
const SKP_Silk_NLSF_CB_struct *psNLSF_CB;
/************************/
/* Encode sampling rate */
/************************/
/* only done for first frame in packet */
if( psEncC->nFramesInPayloadBuf == 0 ) {
/* get sampling rate index */
for( i = 0; i < 3; i++ ) {
if( SKP_Silk_SamplingRates_table[ i ] == psEncC->fs_kHz ) {
break;
}
}
SKP_Silk_range_encoder( psRC, i, SKP_Silk_SamplingRates_CDF );
}
/*******************************************/
/* Encode signal type and quantizer offset */
/*******************************************/
typeOffset = 2 * psEncCtrlC->sigtype + psEncCtrlC->QuantOffsetType;
if( psEncC->nFramesInPayloadBuf == 0 ) {
/* first frame in packet: independent coding */
SKP_Silk_range_encoder( psRC, typeOffset, SKP_Silk_type_offset_CDF );
} else {
/* condidtional coding */
SKP_Silk_range_encoder( psRC, typeOffset, SKP_Silk_type_offset_joint_CDF[ psEncC->typeOffsetPrev ] );
}
psEncC->typeOffsetPrev = typeOffset;
/****************/
/* Encode gains */
/****************/
/* first subframe */
if( psEncC->nFramesInPayloadBuf == 0 ) {
/* first frame in packet: independent coding */
SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ 0 ], SKP_Silk_gain_CDF[ psEncCtrlC->sigtype ] );
} else {
/* condidtional coding */
SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ 0 ], SKP_Silk_delta_gain_CDF );
}
/* remaining subframes */
for( i = 1; i < NB_SUBFR; i++ ) {
SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ i ], SKP_Silk_delta_gain_CDF );
}
/****************/
/* Encode NLSFs */
/****************/
/* Range encoding of the NLSF path */
psNLSF_CB = psEncC->psNLSF_CB[ psEncCtrlC->sigtype ];
SKP_Silk_range_encoder_multi( psRC, psEncCtrlC->NLSFIndices, psNLSF_CB->StartPtr, psNLSF_CB->nStages );
/* Encode NLSF interpolation factor */
SKP_assert( psEncC->useInterpolatedNLSFs == 1 || psEncCtrlC->NLSFInterpCoef_Q2 == ( 1 << 2 ) );
SKP_Silk_range_encoder( psRC, psEncCtrlC->NLSFInterpCoef_Q2, SKP_Silk_NLSF_interpolation_factor_CDF );
if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
/*********************/
/* Encode pitch lags */
/*********************/
/* lag index */
if( psEncC->fs_kHz == 8 ) {
SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_NB_CDF );
} else if( psEncC->fs_kHz == 12 ) {
SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_MB_CDF );
} else if( psEncC->fs_kHz == 16 ) {
SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_WB_CDF );
} else {
SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_SWB_CDF );
}
/* countour index */
if( psEncC->fs_kHz == 8 ) {
/* Less codevectors used in 8 khz mode */
SKP_Silk_range_encoder( psRC, psEncCtrlC->contourIndex, SKP_Silk_pitch_contour_NB_CDF );
} else {
/* Joint for 12, 16, 24 khz */
SKP_Silk_range_encoder( psRC, psEncCtrlC->contourIndex, SKP_Silk_pitch_contour_CDF );
}
/********************/
/* Encode LTP gains */
/********************/
/* PERIndex value */
SKP_Silk_range_encoder( psRC, psEncCtrlC->PERIndex, SKP_Silk_LTP_per_index_CDF );
/* Codebook Indices */
for( k = 0; k < NB_SUBFR; k++ ) {
SKP_Silk_range_encoder( psRC, psEncCtrlC->LTPIndex[ k ], SKP_Silk_LTP_gain_CDF_ptrs[ psEncCtrlC->PERIndex ] );
}
/**********************/
/* Encode LTP scaling */
/**********************/
SKP_Silk_range_encoder( psRC, psEncCtrlC->LTP_scaleIndex, SKP_Silk_LTPscale_CDF );
}
/***************/
/* Encode seed */
/***************/
SKP_Silk_range_encoder( psRC, psEncCtrlC->Seed, SKP_Silk_Seed_CDF );
/*********************************************/
/* Encode quantization indices of excitation */
/*********************************************/
SKP_Silk_encode_pulses( psRC, psEncCtrlC->sigtype, psEncCtrlC->QuantOffsetType, q, psEncC->frame_length );
/*********************************************/
/* Encode VAD flag */
/*********************************************/
SKP_Silk_range_encoder( psRC, psEncC->vadFlag, SKP_Silk_vadflag_CDF );
}

View File

@ -0,0 +1,195 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/*********************************************/
/* Encode quantization indices of excitation */
/*********************************************/
SKP_INLINE SKP_int combine_and_check( /* return ok */
SKP_int *pulses_comb, /* O */
const SKP_int *pulses_in, /* I */
SKP_int max_pulses, /* I max value for sum of pulses */
SKP_int len /* I number of output values */
)
{
SKP_int k, sum;
for( k = 0; k < len; k++ ) {
sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ];
if( sum > max_pulses ) {
return 1;
}
pulses_comb[ k ] = sum;
}
return 0;
}
/* Encode quantization indices of excitation */
void SKP_Silk_encode_pulses(
SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
const SKP_int sigtype, /* I Sigtype */
const SKP_int QuantOffsetType,/* I QuantOffsetType */
const SKP_int8 q[], /* I quantization indices */
const SKP_int frame_length /* I Frame length */
)
{
SKP_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0;
SKP_int32 abs_q, minSumBits_Q6, sumBits_Q6;
SKP_int abs_pulses[ MAX_FRAME_LENGTH ];
SKP_int sum_pulses[ MAX_NB_SHELL_BLOCKS ];
SKP_int nRshifts[ MAX_NB_SHELL_BLOCKS ];
SKP_int pulses_comb[ 8 ];
SKP_int *abs_pulses_ptr;
const SKP_int8 *pulses_ptr;
const SKP_uint16 *cdf_ptr;
const SKP_int16 *nBits_ptr;
SKP_memset( pulses_comb, 0, 8 * sizeof( SKP_int ) ); // Fixing Valgrind reported problem
/****************************/
/* Prepare for shell coding */
/****************************/
/* Calculate number of shell blocks */
iter = frame_length / SHELL_CODEC_FRAME_LENGTH;
/* Take the absolute value of the pulses */
for( i = 0; i < frame_length; i+=4 ) {
abs_pulses[i+0] = ( SKP_int )SKP_abs( q[ i + 0 ] );
abs_pulses[i+1] = ( SKP_int )SKP_abs( q[ i + 1 ] );
abs_pulses[i+2] = ( SKP_int )SKP_abs( q[ i + 2 ] );
abs_pulses[i+3] = ( SKP_int )SKP_abs( q[ i + 3 ] );
}
/* Calc sum pulses per shell code frame */
abs_pulses_ptr = abs_pulses;
for( i = 0; i < iter; i++ ) {
nRshifts[ i ] = 0;
while( 1 ) {
/* 1+1 -> 2 */
scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, SKP_Silk_max_pulses_table[ 0 ], 8 );
/* 2+2 -> 4 */
scale_down += combine_and_check( pulses_comb, pulses_comb, SKP_Silk_max_pulses_table[ 1 ], 4 );
/* 4+4 -> 8 */
scale_down += combine_and_check( pulses_comb, pulses_comb, SKP_Silk_max_pulses_table[ 2 ], 2 );
/* 8+8 -> 16 */
sum_pulses[ i ] = pulses_comb[ 0 ] + pulses_comb[ 1 ];
if( sum_pulses[ i ] > SKP_Silk_max_pulses_table[ 3 ] ) {
scale_down++;
}
if( scale_down ) {
/* We need to down scale the quantization signal */
nRshifts[ i ]++;
for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
abs_pulses_ptr[ k ] = SKP_RSHIFT( abs_pulses_ptr[ k ], 1 );
}
} else {
/* Jump out of while(1) loop and go to next shell coding frame */
break;
}
}
abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH;
}
/**************/
/* Rate level */
/**************/
/* find rate level that leads to fewest bits for coding of pulses per block info */
minSumBits_Q6 = SKP_int32_MAX;
for( k = 0; k < N_RATE_LEVELS - 1; k++ ) {
nBits_ptr = SKP_Silk_pulses_per_block_BITS_Q6[ k ];
sumBits_Q6 = SKP_Silk_rate_levels_BITS_Q6[sigtype][ k ];
for( i = 0; i < iter; i++ ) {
if( nRshifts[ i ] > 0 ) {
sumBits_Q6 += nBits_ptr[ MAX_PULSES + 1 ];
} else {
sumBits_Q6 += nBits_ptr[ sum_pulses[ i ] ];
}
}
if( sumBits_Q6 < minSumBits_Q6 ) {
minSumBits_Q6 = sumBits_Q6;
RateLevelIndex = k;
}
}
SKP_Silk_range_encoder( psRC, RateLevelIndex, SKP_Silk_rate_levels_CDF[ sigtype ] );
/***************************************************/
/* Sum-Weighted-Pulses Encoding */
/***************************************************/
cdf_ptr = SKP_Silk_pulses_per_block_CDF[ RateLevelIndex ];
for( i = 0; i < iter; i++ ) {
if( nRshifts[ i ] == 0 ) {
SKP_Silk_range_encoder( psRC, sum_pulses[ i ], cdf_ptr );
} else {
SKP_Silk_range_encoder( psRC, MAX_PULSES + 1, cdf_ptr );
for( k = 0; k < nRshifts[ i ] - 1; k++ ) {
SKP_Silk_range_encoder( psRC, MAX_PULSES + 1, SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ] );
}
SKP_Silk_range_encoder( psRC, sum_pulses[ i ], SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ] );
}
}
/******************/
/* Shell Encoding */
/******************/
for( i = 0; i < iter; i++ ) {
if( sum_pulses[ i ] > 0 ) {
SKP_Silk_shell_encoder( psRC, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] );
}
}
/****************/
/* LSB Encoding */
/****************/
for( i = 0; i < iter; i++ ) {
if( nRshifts[ i ] > 0 ) {
pulses_ptr = &q[ i * SHELL_CODEC_FRAME_LENGTH ];
nLS = nRshifts[ i ] - 1;
for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
abs_q = (SKP_int8)SKP_abs( pulses_ptr[ k ] );
for( j = nLS; j > 0; j-- ) {
bit = SKP_RSHIFT( abs_q, j ) & 1;
SKP_Silk_range_encoder( psRC, bit, SKP_Silk_lsb_CDF );
}
bit = abs_q & 1;
SKP_Silk_range_encoder( psRC, bit, SKP_Silk_lsb_CDF );
}
}
}
/****************/
/* Encode signs */
/****************/
SKP_Silk_encode_signs( psRC, q, frame_length, sigtype, QuantOffsetType, RateLevelIndex );
}

View File

@ -0,0 +1,56 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_SigProc_FLP.h"
/* sum of squares of a SKP_float array, with result as double */
double SKP_Silk_energy_FLP(
const SKP_float *data,
SKP_int dataSize
)
{
SKP_int i, dataSize4;
double result;
/* 4x unrolled loop */
result = 0.0f;
dataSize4 = dataSize & 0xFFFC;
for( i = 0; i < dataSize4; i += 4 ) {
result += data[ i + 0 ] * data[ i + 0 ] +
data[ i + 1 ] * data[ i + 1 ] +
data[ i + 2 ] * data[ i + 2 ] +
data[ i + 3 ] * data[ i + 3 ];
}
/* add any remaining products */
for( ; i < dataSize; i++ ) {
result += data[ i ] * data[ i ];
}
SKP_assert( result >= 0.0 );
return result;
}

View File

@ -0,0 +1,102 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
#include "SKP_Silk_tuning_parameters.h"
void SKP_Silk_find_LPC_FLP(
SKP_float NLSF[], /* O NLSFs */
SKP_int *interpIndex, /* O NLSF interp. index for NLSF interp. */
const SKP_float prev_NLSFq[], /* I Previous NLSFs, for NLSF interpolation */
const SKP_int useInterpNLSFs, /* I Flag */
const SKP_int LPC_order, /* I LPC order */
const SKP_float x[], /* I Input signal */
const SKP_int subfr_length /* I Subframe length incl preceeding samples */
)
{
SKP_int k;
SKP_float a[ MAX_LPC_ORDER ];
/* Used only for NLSF interpolation */
double res_nrg, res_nrg_2nd, res_nrg_interp;
SKP_float a_tmp[ MAX_LPC_ORDER ], NLSF0[ MAX_LPC_ORDER ];
SKP_float LPC_res[ ( MAX_FRAME_LENGTH + NB_SUBFR * MAX_LPC_ORDER ) / 2 ];
/* Default: No interpolation */
*interpIndex = 4;
/* Burg AR analysis for the full frame */
res_nrg = SKP_Silk_burg_modified_FLP( a, x, subfr_length, NB_SUBFR, FIND_LPC_COND_FAC, LPC_order );
SKP_Silk_bwexpander_FLP( a, LPC_order, FIND_LPC_CHIRP );
if( useInterpNLSFs == 1 ) {
/* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */
/* adding it to the residual energy of the first 10 ms in each iteration of the search below */
res_nrg -= SKP_Silk_burg_modified_FLP( a_tmp, x + ( NB_SUBFR / 2 ) * subfr_length,
subfr_length, NB_SUBFR / 2, FIND_LPC_COND_FAC, LPC_order );
SKP_Silk_bwexpander_FLP( a_tmp, LPC_order, FIND_LPC_CHIRP );
/* Convert to NLSFs */
SKP_Silk_A2NLSF_FLP( NLSF, a_tmp, LPC_order );
/* Search over interpolation indices to find the one with lowest residual energy */
res_nrg_2nd = SKP_float_MAX;
for( k = 3; k >= 0; k-- ) {
/* Interpolate NLSFs for first half */
SKP_Silk_interpolate_wrapper_FLP( NLSF0, prev_NLSFq, NLSF, 0.25f * k, LPC_order );
/* Convert to LPC for residual energy evaluation */
SKP_Silk_NLSF2A_stable_FLP( a_tmp, NLSF0, LPC_order );
/* Calculate residual energy with LSF interpolation */
SKP_Silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, LPC_order );
res_nrg_interp =
SKP_Silk_energy_FLP( LPC_res + LPC_order, subfr_length - LPC_order ) +
SKP_Silk_energy_FLP( LPC_res + LPC_order + subfr_length, subfr_length - LPC_order );
/* Determine whether current interpolated NLSFs are best so far */
if( res_nrg_interp < res_nrg ) {
/* Interpolation has lower residual energy */
res_nrg = res_nrg_interp;
*interpIndex = k;
} else if( res_nrg_interp > res_nrg_2nd ) {
/* No reason to continue iterating - residual energies will continue to climb */
break;
}
res_nrg_2nd = res_nrg_interp;
}
}
if( *interpIndex == 4 ) {
/* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
SKP_Silk_A2NLSF_FLP( NLSF, a, LPC_order );
}
}

View File

@ -0,0 +1,131 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
#include "SKP_Silk_tuning_parameters.h"
void SKP_Silk_find_LTP_FLP(
SKP_float b[ NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
SKP_float WLTP[NB_SUBFR*LTP_ORDER*LTP_ORDER], /* O Weight for LTP quantization */
SKP_float *LTPredCodGain, /* O LTP coding gain */
const SKP_float r_first[], /* I LPC residual, signal + state for 10 ms */
const SKP_float r_last[], /* I LPC residual, signal + state for 10 ms */
const SKP_int lag[ NB_SUBFR ], /* I LTP lags */
const SKP_float Wght[ NB_SUBFR ], /* I Weights */
const SKP_int subfr_length, /* I Subframe length */
const SKP_int mem_offset /* I Number of samples in LTP memory */
)
{
SKP_int i, k;
SKP_float *b_ptr, temp, *WLTP_ptr;
SKP_float LPC_res_nrg, LPC_LTP_res_nrg;
SKP_float d[ NB_SUBFR ], m, g, delta_b[ LTP_ORDER ];
SKP_float w[ NB_SUBFR ], nrg[ NB_SUBFR ], regu;
SKP_float Rr[ LTP_ORDER ], rr[ NB_SUBFR ];
const SKP_float *r_ptr, *lag_ptr;
b_ptr = b;
WLTP_ptr = WLTP;
r_ptr = &r_first[ mem_offset ];
for( k = 0; k < NB_SUBFR; k++ ) {
if( k == ( NB_SUBFR >> 1 ) ) { /* Shift residual for last 10 ms */
r_ptr = &r_last[ mem_offset ];
}
lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
SKP_Silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, WLTP_ptr );
SKP_Silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr );
rr[ k ] = ( SKP_float )SKP_Silk_energy_FLP( r_ptr, subfr_length );
regu = 1.0f + rr[ k ] +
matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ) +
matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER );
regu *= LTP_DAMPING / 3;
SKP_Silk_regularize_correlations_FLP( WLTP_ptr, &rr[ k ], regu, LTP_ORDER );
SKP_Silk_solve_LDL_FLP( WLTP_ptr, LTP_ORDER, Rr, b_ptr );
/* Calculate residual energy */
nrg[ k ] = SKP_Silk_residual_energy_covar_FLP( b_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER );
temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length );
SKP_Silk_scale_vector_FLP( WLTP_ptr, temp, LTP_ORDER * LTP_ORDER );
w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER / 2, LTP_ORDER / 2, LTP_ORDER );
r_ptr += subfr_length;
b_ptr += LTP_ORDER;
WLTP_ptr += LTP_ORDER * LTP_ORDER;
}
/* Compute LTP coding gain */
if( LTPredCodGain != NULL ) {
LPC_LTP_res_nrg = 1e-6f;
LPC_res_nrg = 0.0f;
for( k = 0; k < NB_SUBFR; k++ ) {
LPC_res_nrg += rr[ k ] * Wght[ k ];
LPC_LTP_res_nrg += nrg[ k ] * Wght[ k ];
}
SKP_assert( LPC_LTP_res_nrg > 0 );
*LTPredCodGain = 3.0f * SKP_Silk_log2( LPC_res_nrg / LPC_LTP_res_nrg );
}
/* Smoothing */
/* d = sum( B, 1 ); */
b_ptr = b;
for( k = 0; k < NB_SUBFR; k++ ) {
d[ k ] = 0;
for( i = 0; i < LTP_ORDER; i++ ) {
d[ k ] += b_ptr[ i ];
}
b_ptr += LTP_ORDER;
}
/* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */
temp = 1e-3f;
for( k = 0; k < NB_SUBFR; k++ ) {
temp += w[ k ];
}
m = 0;
for( k = 0; k < NB_SUBFR; k++ ) {
m += d[ k ] * w[ k ];
}
m = m / temp;
b_ptr = b;
for( k = 0; k < NB_SUBFR; k++ ) {
g = LTP_SMOOTHING / ( LTP_SMOOTHING + w[ k ] ) * ( m - d[ k ] );
temp = 0;
for( i = 0; i < LTP_ORDER; i++ ) {
delta_b[ i ] = SKP_max_float( b_ptr[ i ], 0.1f );
temp += delta_b[ i ];
}
temp = g / temp;
for( i = 0; i < LTP_ORDER; i++ ) {
b_ptr[ i ] = b_ptr[ i ] + delta_b[ i ] * temp;
}
b_ptr += LTP_ORDER;
}
}

View File

@ -0,0 +1,116 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
#include "SKP_Silk_tuning_parameters.h"
void SKP_Silk_find_pitch_lags_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
SKP_float res[], /* O Residual */
const SKP_float x[] /* I Speech signal */
)
{
SKP_Silk_predict_state_FLP *psPredSt = &psEnc->sPred;
SKP_int buf_len;
SKP_float thrhld, res_nrg;
const SKP_float *x_buf_ptr, *x_buf;
SKP_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
SKP_float A[ MAX_FIND_PITCH_LPC_ORDER ];
SKP_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ];
SKP_float Wsig[ FIND_PITCH_LPC_WIN_MAX ];
SKP_float *Wsig_ptr;
/******************************************/
/* Setup buffer lengths etc based on Fs */
/******************************************/
buf_len = 2 * psEnc->sCmn.frame_length + psEnc->sCmn.la_pitch;
/* Safty check */
SKP_assert( buf_len >= psPredSt->pitch_LPC_win_length );
x_buf = x - psEnc->sCmn.frame_length;
/******************************************/
/* Estimate LPC AR coeficients */
/******************************************/
/* Calculate windowed signal */
/* First LA_LTP samples */
x_buf_ptr = x_buf + buf_len - psPredSt->pitch_LPC_win_length;
Wsig_ptr = Wsig;
SKP_Silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );
/* Middle non-windowed samples */
Wsig_ptr += psEnc->sCmn.la_pitch;
x_buf_ptr += psEnc->sCmn.la_pitch;
SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psPredSt->pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( SKP_float ) );
/* Last LA_LTP samples */
Wsig_ptr += psPredSt->pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 );
x_buf_ptr += psPredSt->pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 );
SKP_Silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );
/* Calculate autocorrelation sequence */
SKP_Silk_autocorrelation_FLP( auto_corr, Wsig, psPredSt->pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 );
/* Add white noise, as a fraction of the energy */
auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION;
/* Calculate the reflection coefficients using Schur */
res_nrg = SKP_Silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );
/* Prediction gain */
psEncCtrl->predGain = auto_corr[ 0 ] / SKP_max_float( res_nrg, 1.0f );
/* Convert reflection coefficients to prediction coefficients */
SKP_Silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder );
/* Bandwidth expansion */
SKP_Silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWITH_EXPANSION );
/*****************************************/
/* LPC analysis filtering */
/*****************************************/
SKP_Silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder );
SKP_memset( res, 0, psEnc->sCmn.pitchEstimationLPCOrder * sizeof( SKP_float ) );
/* Threshold for pitch estimator */
thrhld = 0.45f;
thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder;
thrhld -= 0.1f * psEnc->speech_activity;
thrhld += 0.15f * psEnc->sCmn.prev_sigtype;
thrhld -= 0.1f * psEncCtrl->input_tilt;
/*****************************************/
/* Call Pitch estimator */
/*****************************************/
psEncCtrl->sCmn.sigtype = SKP_Silk_pitch_analysis_core_FLP( res, psEncCtrl->sCmn.pitchL, &psEncCtrl->sCmn.lagIndex,
&psEncCtrl->sCmn.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f,
thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity );
}

View File

@ -0,0 +1,111 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
void SKP_Silk_find_pred_coefs_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
const SKP_float res_pitch[] /* I Residual from pitch analysis */
)
{
SKP_int i;
SKP_float WLTP[ NB_SUBFR * LTP_ORDER * LTP_ORDER ];
SKP_float invGains[ NB_SUBFR ], Wght[ NB_SUBFR ];
SKP_float NLSF[ MAX_LPC_ORDER ];
const SKP_float *x_ptr;
SKP_float *x_pre_ptr, LPC_in_pre[ NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
/* Weighting for weighted least squares */
for( i = 0; i < NB_SUBFR; i++ ) {
SKP_assert( psEncCtrl->Gains[ i ] > 0.0f );
invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ];
Wght[ i ] = invGains[ i ] * invGains[ i ];
}
if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
/**********/
/* VOICED */
/**********/
SKP_assert( psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->sCmn.pitchL[ 0 ] + LTP_ORDER / 2 );
/* LTP analysis */
SKP_Silk_find_LTP_FLP( psEncCtrl->LTPCoef, WLTP, &psEncCtrl->LTPredCodGain, res_pitch,
res_pitch + ( psEnc->sCmn.frame_length >> 1 ), psEncCtrl->sCmn.pitchL, Wght,
psEnc->sCmn.subfr_length, psEnc->sCmn.frame_length );
/* Quantize LTP gain parameters */
SKP_Silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEncCtrl->sCmn.LTPIndex, &psEncCtrl->sCmn.PERIndex,
WLTP, psEnc->mu_LTP, psEnc->sCmn.LTPQuantLowComplexity );
/* Control LTP scaling */
SKP_Silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl );
/* Create LTP residual */
SKP_Silk_LTP_analysis_filter_FLP( LPC_in_pre, psEnc->x_buf + psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder,
psEncCtrl->LTPCoef, psEncCtrl->sCmn.pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.predictLPCOrder );
} else {
/************/
/* UNVOICED */
/************/
/* Create signal with prepended subframes, scaled by inverse gains */
x_ptr = psEnc->x_buf + psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder;
x_pre_ptr = LPC_in_pre;
for( i = 0; i < NB_SUBFR; i++ ) {
SKP_Silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ],
psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
x_ptr += psEnc->sCmn.subfr_length;
}
SKP_memset( psEncCtrl->LTPCoef, 0, NB_SUBFR * LTP_ORDER * sizeof( SKP_float ) );
psEncCtrl->LTPredCodGain = 0.0f;
}
/* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
SKP_Silk_find_LPC_FLP( NLSF, &psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEnc->sPred.prev_NLSFq,
psEnc->sCmn.useInterpolatedNLSFs * ( 1 - psEnc->sCmn.first_frame_after_reset ), psEnc->sCmn.predictLPCOrder,
LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
/* Quantize LSFs */
SKP_Silk_process_NLSFs_FLP( psEnc, psEncCtrl, NLSF );
/* Calculate residual energy using quantized LPC coefficients */
SKP_Silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains,
psEnc->sCmn.subfr_length, psEnc->sCmn.predictLPCOrder );
/* Copy to prediction struct for use in next frame for fluctuation reduction */
SKP_memcpy( psEnc->sPred.prev_NLSFq, NLSF, psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );
}

View File

@ -0,0 +1,94 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
#define OFFSET ( ( MIN_QGAIN_DB * 128 ) / 6 + 16 * 128 )
#define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) )
#define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) )
/* Gain scalar quantization with hysteresis, uniform on log scale */
void SKP_Silk_gains_quant(
SKP_int ind[ NB_SUBFR ], /* O gain indices */
SKP_int32 gain_Q16[ NB_SUBFR ], /* I/O gains (quantized out) */
SKP_int *prev_ind, /* I/O last index in previous frame */
const SKP_int conditional /* I first gain is delta coded if 1 */
)
{
SKP_int k;
for( k = 0; k < NB_SUBFR; k++ ) {
/* Add half of previous quantization error, convert to log scale, scale, floor() */
ind[ k ] = SKP_SMULWB( SCALE_Q16, SKP_Silk_lin2log( gain_Q16[ k ] ) - OFFSET );
/* Round towards previous quantized gain (hysteresis) */
if( ind[ k ] < *prev_ind ) {
ind[ k ]++;
}
/* Compute delta indices and limit */
if( k == 0 && conditional == 0 ) {
/* Full index */
ind[ k ] = SKP_LIMIT_int( ind[ k ], 0, N_LEVELS_QGAIN - 1 );
ind[ k ] = SKP_max_int( ind[ k ], *prev_ind + MIN_DELTA_GAIN_QUANT );
*prev_ind = ind[ k ];
} else {
/* Delta index */
ind[ k ] = SKP_LIMIT_int( ind[ k ] - *prev_ind, MIN_DELTA_GAIN_QUANT, MAX_DELTA_GAIN_QUANT );
/* Accumulate deltas */
*prev_ind += ind[ k ];
/* Shift to make non-negative */
ind[ k ] -= MIN_DELTA_GAIN_QUANT;
}
/* Convert to linear scale and scale */
gain_Q16[ k ] = SKP_Silk_log2lin( SKP_min_32( SKP_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3968 = 31 in Q7 */
}
}
/* Gains scalar dequantization, uniform on log scale */
void SKP_Silk_gains_dequant(
SKP_int32 gain_Q16[ NB_SUBFR ], /* O quantized gains */
const SKP_int ind[ NB_SUBFR ], /* I gain indices */
SKP_int *prev_ind, /* I/O last index in previous frame */
const SKP_int conditional /* I first gain is delta coded if 1 */
)
{
SKP_int k;
for( k = 0; k < NB_SUBFR; k++ ) {
if( k == 0 && conditional == 0 ) {
*prev_ind = ind[ k ];
} else {
/* Delta index */
*prev_ind += ind[ k ] + MIN_DELTA_GAIN_QUANT;
}
/* Convert to linear scale and scale */
gain_Q16[ k ] = SKP_Silk_log2lin( SKP_min_32( SKP_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3968 = 31 in Q7 */
}
}

View File

@ -0,0 +1,58 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include <stdlib.h>
#include "SKP_Silk_main_FLP.h"
/*********************************/
/* Initialize Silk Encoder state */
/*********************************/
SKP_int SKP_Silk_init_encoder_FLP(
SKP_Silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */
) {
SKP_int ret = 0;
/* Clear the entire encoder state */
SKP_memset( psEnc, 0, sizeof( SKP_Silk_encoder_state_FLP ) );
#if HIGH_PASS_INPUT
psEnc->variable_HP_smth1 = SKP_Silk_log2( 70.0 );
psEnc->variable_HP_smth2 = SKP_Silk_log2( 70.0 );
#endif
/* Used to deactivate e.g. LSF interpolation and fluctuation reduction */
psEnc->sCmn.first_frame_after_reset = 1;
/* Initialize Silk VAD */
ret += SKP_Silk_VAD_Init( &psEnc->sCmn.sVAD );
/* Initialize NSQ */
psEnc->sCmn.sNSQ.prev_inv_gain_Q16 = 65536;
psEnc->sCmn.sNSQ_LBRR.prev_inv_gain_Q16 = 65536;
return( ret );
}

View File

@ -0,0 +1,56 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_SigProc_FLP.h"
/* inner product of two SKP_float arrays, with result as double */
double SKP_Silk_inner_product_FLP( /* O result */
const SKP_float *data1, /* I vector 1 */
const SKP_float *data2, /* I vector 2 */
SKP_int dataSize /* I length of vectors */
)
{
SKP_int i, dataSize4;
double result;
/* 4x unrolled loop */
result = 0.0f;
dataSize4 = dataSize & 0xFFFC;
for( i = 0; i < dataSize4; i += 4 ) {
result += data1[ i + 0 ] * data2[ i + 0 ] +
data1[ i + 1 ] * data2[ i + 1 ] +
data1[ i + 2 ] * data2[ i + 2 ] +
data1[ i + 3 ] * data2[ i + 3 ];
}
/* add any remaining products */
for( ; i < dataSize; i++ ) {
result += data1[ i ] * data2[ i ];
}
return result;
}

View File

@ -0,0 +1,47 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main.h"
/* Interpolate two vectors */
void SKP_Silk_interpolate(
SKP_int xi[ MAX_LPC_ORDER ], /* O interpolated vector */
const SKP_int x0[ MAX_LPC_ORDER ], /* I first vector */
const SKP_int x1[ MAX_LPC_ORDER ], /* I second vector */
const SKP_int ifact_Q2, /* I interp. factor, weight on 2nd vector */
const SKP_int d /* I number of parameters */
)
{
SKP_int i;
SKP_assert( ifact_Q2 >= 0 );
SKP_assert( ifact_Q2 <= ( 1 << 2 ) );
for( i = 0; i < d; i++ ) {
xi[ i ] = ( SKP_int )( ( SKP_int32 )x0[ i ] + SKP_RSHIFT( SKP_MUL( ( SKP_int32 )x1[ i ] - ( SKP_int32 )x0[ i ], ifact_Q2 ), 2 ) );
}
}

View File

@ -0,0 +1,58 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_k2a.c *
* *
* step up function, converts reflection coefficients to prediction *
* coefficients *
* *
* Copyright 2008 (c), Skype Limited *
* Date: 080103 *
* */
#include "SKP_Silk_SigProc_FLP.h"
/* step up function, converts reflection coefficients to prediction coefficients */
void SKP_Silk_k2a_FLP(
SKP_float *A, /* O: prediction coefficients [order] */
const SKP_float *rc, /* I: reflection coefficients [order] */
SKP_int32 order /* I: prediction order */
)
{
SKP_int k, n;
SKP_float Atmp[ SKP_Silk_MAX_ORDER_LPC ];
for( k = 0; k < order; k++ ){
for( n = 0; n < k; n++ ){
Atmp[ n ] = A[ n ];
}
for( n = 0; n < k; n++ ) {
A[ n ] += Atmp[ k - n - 1 ] * rc[ k ];
}
A[ k ] = -rc[ k ];
}
}

View File

@ -0,0 +1,77 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_SigProc_FLP.h"
/* Solve the normal equations using the Levinson-Durbin recursion */
SKP_float SKP_Silk_levinsondurbin_FLP( /* O prediction error energy */
SKP_float A[], /* O prediction coefficients [order] */
const SKP_float corr[], /* I input auto-correlations [order + 1] */
const SKP_int order /* I prediction order */
)
{
SKP_int i, mHalf, m;
SKP_float min_nrg, nrg, t, km, Atmp1, Atmp2;
min_nrg = 1e-12f * corr[ 0 ] + 1e-9f;
nrg = corr[ 0 ];
nrg = SKP_max_float(min_nrg, nrg);
A[ 0 ] = corr[ 1 ] / nrg;
nrg -= A[ 0 ] * corr[ 1 ];
nrg = SKP_max_float(min_nrg, nrg);
for( m = 1; m < order; m++ )
{
t = corr[ m + 1 ];
for( i = 0; i < m; i++ ) {
t -= A[ i ] * corr[ m - i ];
}
/* reflection coefficient */
km = t / nrg;
/* residual energy */
nrg -= km * t;
nrg = SKP_max_float(min_nrg, nrg);
mHalf = m >> 1;
for( i = 0; i < mHalf; i++ ) {
Atmp1 = A[ i ];
Atmp2 = A[ m - i - 1 ];
A[ m - i - 1 ] -= km * Atmp1;
A[ i ] -= km * Atmp2;
}
if( m & 1 ) {
A[ mHalf ] -= km * A[ mHalf ];
}
A[ m ] = km;
}
/* return the residual energy */
return nrg;
}

View File

@ -0,0 +1,49 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_lin2log.c *
* *
* Convert input to a log scale *
* Approximation of 128 * log2() *
* *
* Copyright 2006 (c), Skype Limited *
* Date: 060221 *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* Approximation of 128 * log2() (very close inverse of approx 2^() below) */
/* Convert input to a log scale */
SKP_int32 SKP_Silk_lin2log( const SKP_int32 inLin ) /* I: Input in linear scale */
{
SKP_int32 lz, frac_Q7;
SKP_Silk_CLZ_FRAC( inLin, &lz, &frac_Q7 );
/* Piece-wise parabolic approximation */
return( SKP_LSHIFT( 31 - lz, 7 ) + SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), 179 ) );
}

View File

@ -0,0 +1,61 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_log2lin.c *
* *
* Convert input to a linear scale *
* *
* Copyright 2006 (c), Skype Limited *
* Date: 060221 *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* Approximation of 2^() (very close inverse of SKP_Silk_lin2log()) */
/* Convert input to a linear scale */
SKP_int32 SKP_Silk_log2lin( const SKP_int32 inLog_Q7 ) /* I: Input on log scale */
{
SKP_int32 out, frac_Q7;
if( inLog_Q7 < 0 ) {
return( 0 );
} else if( inLog_Q7 >= ( 31 << 7 ) ) {
/* Saturate, and prevent wrap-around */
return( SKP_int32_MAX );
}
out = SKP_LSHIFT( 1, SKP_RSHIFT( inLog_Q7, 7 ) );
frac_Q7 = inLog_Q7 & 0x7F;
if( inLog_Q7 < 2048 ) {
/* Piece-wise parabolic approximation */
out = SKP_ADD_RSHIFT( out, SKP_MUL( out, SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 );
} else {
/* Piece-wise parabolic approximation */
out = SKP_MLA( out, SKP_RSHIFT( out, 7 ), SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), -174 ) );
}
return out;
}

View File

@ -0,0 +1,61 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_lowpass_int.c *
* *
* First order low-pass filter, with input as SKP_int32, running at *
* 48 kHz *
* *
* Copyright 2006 (c), Skype Limited *
* Date: 060221 *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* First order low-pass filter, with input as SKP_int32, running at 48 kHz */
void SKP_Silk_lowpass_int(
const SKP_int32 *in, /* I: Q25 48 kHz signal; length = len */
SKP_int32 *S, /* I/O: Q25 state; length = 1 */
SKP_int32 *out, /* O: Q25 48 kHz signal; length = len */
const SKP_int32 len /* I: Number of samples */
)
{
SKP_int k;
SKP_int32 in_tmp, out_tmp, state;
state = S[ 0 ];
for( k = len; k > 0; k-- ) {
in_tmp = *in++;
in_tmp -= SKP_RSHIFT( in_tmp, 2 ); /* multiply by 0.75 */
out_tmp = state + in_tmp; /* zero at nyquist */
state = in_tmp - SKP_RSHIFT( out_tmp, 1 ); /* pole */
*out++ = out_tmp;
}
S[ 0 ] = state;
}

View File

@ -0,0 +1,61 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/* *
* SKP_Silk_lowpass_short.c *
* *
* First order low-pass filter, with input as SKP_int16, running at *
* 48 kHz *
* *
* Copyright 2006 (c), Skype Limited *
* Date: 060221 *
* */
#include "SKP_Silk_SigProc_FIX.h"
/* First order low-pass filter, with input as SKP_int16, running at 48 kHz */
void SKP_Silk_lowpass_short(
const SKP_int16 *in, /* I: Q15 48 kHz signal; [len] */
SKP_int32 *S, /* I/O: Q25 state; length = 1 */
SKP_int32 *out, /* O: Q25 48 kHz signal; [len] */
const SKP_int32 len /* O: Signal length */
)
{
SKP_int k;
SKP_int32 in_tmp, out_tmp, state;
state = S[ 0 ];
for( k = 0; k < len; k++ ) {
in_tmp = SKP_MUL( 768, (SKP_int32)in[k] ); /* multiply by 0.75, going from Q15 to Q25 */
out_tmp = state + in_tmp; /* zero at nyquist */
state = in_tmp - SKP_RSHIFT( out_tmp, 1 ); /* pole */
out[ k ] = out_tmp;
}
S[ 0 ] = state;
}

View File

@ -0,0 +1,125 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef _SKP_SILK_API_C_H_
#define _SKP_SILK_API_C_H_
// This is an inline header file for general platform.
// (a32 * (SKP_int32)((SKP_int16)(b32))) >> 16 output have to be 32bit int
#define SKP_SMULWB(a32, b32) ((((a32) >> 16) * (SKP_int32)((SKP_int16)(b32))) + ((((a32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(b32))) >> 16))
// a32 + (b32 * (SKP_int32)((SKP_int16)(c32))) >> 16 output have to be 32bit int
#define SKP_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (SKP_int32)((SKP_int16)(c32))) + ((((b32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(c32))) >> 16)))
// (a32 * (b32 >> 16)) >> 16
#define SKP_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16))
// a32 + (b32 * (c32 >> 16)) >> 16
#define SKP_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16))
// (SKP_int32)((SKP_int16)(a3))) * (SKP_int32)((SKP_int16)(b32)) output have to be 32bit int
#define SKP_SMULBB(a32, b32) ((SKP_int32)((SKP_int16)(a32)) * (SKP_int32)((SKP_int16)(b32)))
// a32 + (SKP_int32)((SKP_int16)(b32)) * (SKP_int32)((SKP_int16)(c32)) output have to be 32bit int
#define SKP_SMLABB(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * (SKP_int32)((SKP_int16)(c32)))
// (SKP_int32)((SKP_int16)(a32)) * (b32 >> 16)
#define SKP_SMULBT(a32, b32) ((SKP_int32)((SKP_int16)(a32)) * ((b32) >> 16))
// a32 + (SKP_int32)((SKP_int16)(b32)) * (c32 >> 16)
#define SKP_SMLABT(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * ((c32) >> 16))
// a64 + (b32 * c32)
#define SKP_SMLAL(a64, b32, c32) (SKP_ADD64((a64), ((SKP_int64)(b32) * (SKP_int64)(c32))))
// (a32 * b32) >> 16
#define SKP_SMULWW(a32, b32) SKP_MLA(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16))
// a32 + ((b32 * c32) >> 16)
#define SKP_SMLAWW(a32, b32, c32) SKP_MLA(SKP_SMLAWB((a32), (b32), (c32)), (b32), SKP_RSHIFT_ROUND((c32), 16))
// (SKP_int32)(((SKP_int64)a32 * b32) >> 32)
#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32)
/* add/subtract with output saturated */
#define SKP_ADD_SAT32(a, b) ((((a) + (b)) & 0x80000000) == 0 ? \
((((a) & (b)) & 0x80000000) != 0 ? SKP_int32_MIN : (a)+(b)) : \
((((a) | (b)) & 0x80000000) == 0 ? SKP_int32_MAX : (a)+(b)) )
#define SKP_SUB_SAT32(a, b) ((((a)-(b)) & 0x80000000) == 0 ? \
(( (a) & ((b)^0x80000000) & 0x80000000) ? SKP_int32_MIN : (a)-(b)) : \
((((a)^0x80000000) & (b) & 0x80000000) ? SKP_int32_MAX : (a)-(b)) )
SKP_INLINE SKP_int32 SKP_Silk_CLZ16(SKP_int16 in16)
{
SKP_int32 out32 = 0;
if( in16 == 0 ) {
return 16;
}
/* test nibbles */
if( in16 & 0xFF00 ) {
if( in16 & 0xF000 ) {
in16 >>= 12;
} else {
out32 += 4;
in16 >>= 8;
}
} else {
if( in16 & 0xFFF0 ) {
out32 += 8;
in16 >>= 4;
} else {
out32 += 12;
}
}
/* test bits and return */
if( in16 & 0xC ) {
if( in16 & 0x8 )
return out32 + 0;
else
return out32 + 1;
} else {
if( in16 & 0xE )
return out32 + 2;
else
return out32 + 3;
}
}
SKP_INLINE SKP_int32 SKP_Silk_CLZ32(SKP_int32 in32)
{
/* test highest 16 bits and convert to SKP_int16 */
if( in32 & 0xFFFF0000 ) {
return SKP_Silk_CLZ16((SKP_int16)(in32 >> 16));
} else {
return SKP_Silk_CLZ16((SKP_int16)in32) + 16;
}
}
#endif //_SKP_SILK_API_C_H_

View File

@ -0,0 +1,388 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef SKP_SILK_MAIN_H
#define SKP_SILK_MAIN_H
#include "SKP_Silk_SigProc_FIX.h"
#ifdef __cplusplus
extern "C"
{
#endif
#include "SKP_Silk_define.h"
#include "SKP_Silk_structs.h"
#include "SKP_Silk_tables.h"
#include "SKP_Silk_PLC.h"
/* Encodes signs of excitation */
void SKP_Silk_encode_signs(
SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
const SKP_int8 q[], /* I pulse signal */
const SKP_int length, /* I length of input */
const SKP_int sigtype, /* I Signal type */
const SKP_int QuantOffsetType, /* I Quantization offset type */
const SKP_int RateLevelIndex /* I Rate Level Index */
);
/* Decodes signs of excitation */
void SKP_Silk_decode_signs(
SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
SKP_int q[], /* I/O pulse signal */
const SKP_int length, /* I length of output */
const SKP_int sigtype, /* I Signal type */
const SKP_int QuantOffsetType, /* I Quantization offset type */
const SKP_int RateLevelIndex /* I Rate Level Index */
);
/* Control internal sampling rate */
SKP_int SKP_Silk_control_audio_bandwidth(
SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */
);
/***************/
/* Shell coder */
/***************/
/* Encode quantization indices of excitation */
void SKP_Silk_encode_pulses(
SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
const SKP_int sigtype, /* I Sigtype */
const SKP_int QuantOffsetType, /* I QuantOffsetType */
const SKP_int8 q[], /* I quantization indices */
const SKP_int frame_length /* I Frame length */
);
/* Shell encoder, operates on one shell code frame of 16 pulses */
void SKP_Silk_shell_encoder(
SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
const SKP_int *pulses0 /* I data: nonnegative pulse amplitudes */
);
/* Shell decoder, operates on one shell code frame of 16 pulses */
void SKP_Silk_shell_decoder(
SKP_int *pulses0, /* O data: nonnegative pulse amplitudes */
SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
const SKP_int pulses4 /* I number of pulses per pulse-subframe */
);
/***************/
/* Range coder */
/***************/
/* Range encoder for one symbol */
void SKP_Silk_range_encoder(
SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
const SKP_int data, /* I uncompressed data */
const SKP_uint16 prob[] /* I cumulative density functions */
);
/* Range encoder for multiple symbols */
void SKP_Silk_range_encoder_multi(
SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
const SKP_int data[], /* I uncompressed data [nSymbols] */
const SKP_uint16 * const prob[], /* I cumulative density functions */
const SKP_int nSymbols /* I number of data symbols */
);
/* Range decoder for one symbol */
void SKP_Silk_range_decoder(
SKP_int data[], /* O uncompressed data */
SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
const SKP_uint16 prob[], /* I cumulative density function */
SKP_int probIx /* I initial (middle) entry of cdf */
);
/* Range decoder for multiple symbols */
void SKP_Silk_range_decoder_multi(
SKP_int data[], /* O uncompressed data [nSymbols] */
SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
const SKP_uint16 * const prob[], /* I cumulative density functions */
const SKP_int probStartIx[], /* I initial (middle) entries of cdfs [nSymbols] */
const SKP_int nSymbols /* I number of data symbols */
);
/* Initialize range coder structure for encoder */
void SKP_Silk_range_enc_init(
SKP_Silk_range_coder_state *psRC /* O compressor data structure */
);
/* Initialize range coder structure for decoder */
void SKP_Silk_range_dec_init(
SKP_Silk_range_coder_state *psRC, /* O compressor data structure */
const SKP_uint8 buffer[], /* I buffer for compressed data [bufferLength] */
const SKP_int32 bufferLength /* I buffer length (in bytes) */
);
/* Determine length of bitstream */
SKP_int SKP_Silk_range_coder_get_length( /* O returns number of BITS in stream */
const SKP_Silk_range_coder_state *psRC, /* I compressed data structure */
SKP_int *nBytes /* O number of BYTES in stream */
);
/* Write decodable stream to buffer, and determine its length */
void SKP_Silk_range_enc_wrap_up(
SKP_Silk_range_coder_state *psRC /* I/O compressed data structure */
);
/* Check that any remaining bits in the last byte are set to 1 */
void SKP_Silk_range_coder_check_after_decoding(
SKP_Silk_range_coder_state *psRC /* I/O compressed data structure */
);
/* Gain scalar quantization with hysteresis, uniform on log scale */
void SKP_Silk_gains_quant(
SKP_int ind[ NB_SUBFR ], /* O gain indices */
SKP_int32 gain_Q16[ NB_SUBFR ], /* I/O gains (quantized out) */
SKP_int *prev_ind, /* I/O last index in previous frame */
const SKP_int conditional /* I first gain is delta coded if 1 */
);
/* Gains scalar dequantization, uniform on log scale */
void SKP_Silk_gains_dequant(
SKP_int32 gain_Q16[ NB_SUBFR ], /* O quantized gains */
const SKP_int ind[ NB_SUBFR ], /* I gain indices */
SKP_int *prev_ind, /* I/O last index in previous frame */
const SKP_int conditional /* I first gain is delta coded if 1 */
);
/* Convert NLSF parameters to stable AR prediction filter coefficients */
void SKP_Silk_NLSF2A_stable(
SKP_int16 pAR_Q12[ MAX_LPC_ORDER ], /* O Stabilized AR coefs [LPC_order] */
const SKP_int pNLSF[ MAX_LPC_ORDER ], /* I NLSF vector [LPC_order] */
const SKP_int LPC_order /* I LPC/LSF order */
);
/* Interpolate two vectors */
void SKP_Silk_interpolate(
SKP_int xi[ MAX_LPC_ORDER ], /* O interpolated vector */
const SKP_int x0[ MAX_LPC_ORDER ], /* I first vector */
const SKP_int x1[ MAX_LPC_ORDER ], /* I second vector */
const SKP_int ifact_Q2, /* I interp. factor, weight on 2nd vector */
const SKP_int d /* I number of parameters */
);
/***********************************/
/* Noise shaping quantization (NSQ)*/
/***********************************/
void SKP_Silk_NSQ(
SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */
SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
const SKP_int16 x[], /* I prefiltered input signal */
SKP_int8 q[], /* O quantized qulse signal */
const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */
const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefficients */
const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I Long term prediction coefficients */
const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */
const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */
const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */
const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
const SKP_int Lambda_Q10, /* I */
const SKP_int LTP_scale_Q14 /* I LTP state scaling */
);
/* Noise shaping using delayed decision */
void SKP_Silk_NSQ_del_dec(
SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */
SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
const SKP_int16 x[], /* I Prefiltered input signal */
SKP_int8 q[], /* O Quantized pulse signal */
const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */
const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Prediction coefs */
const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I LT prediction coefs */
const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */
const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */
const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */
const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
const SKP_int Lambda_Q10, /* I */
const SKP_int LTP_scale_Q14 /* I LTP state scaling */
);
/************/
/* Silk VAD */
/************/
/* Initialize the Silk VAD */
SKP_int SKP_Silk_VAD_Init( /* O Return value, 0 if success */
SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
);
/* Silk VAD noise level estimation */
void SKP_Silk_VAD_GetNoiseLevels(
const SKP_int32 pX[ VAD_N_BANDS ], /* I subband energies */
SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
);
/* Get speech activity level in Q8 */
SKP_int SKP_Silk_VAD_GetSA_Q8( /* O Return value, 0 if success */
SKP_Silk_VAD_state *psSilk_VAD, /* I/O Silk VAD state */
SKP_int *pSA_Q8, /* O Speech activity level in Q8 */
SKP_int *pSNR_dB_Q7, /* O SNR for current frame in Q7 */
SKP_int pQuality_Q15[ VAD_N_BANDS ], /* O Smoothed SNR for each band */
SKP_int *pTilt_Q15, /* O current frame's frequency tilt */
const SKP_int16 pIn[], /* I PCM input [framelength] */
const SKP_int framelength /* I Input frame length */
);
/* Detect signal in 8 - 12 khz range */
void SKP_Silk_detect_SWB_input(
SKP_Silk_detect_SWB_state *psSWBdetect, /* I/O Encoder state */
const SKP_int16 samplesIn[], /* I Input to encoder */
SKP_int nSamplesIn /* I Length of input */
);
#if SWITCH_TRANSITION_FILTERING
/* Low-pass filter with variable cutoff frequency based on */
/* piece-wise linear interpolation between elliptic filters */
/* Start by setting transition_frame_no = 1; */
void SKP_Silk_LP_variable_cutoff(
SKP_Silk_LP_state *psLP, /* I/O LP filter state */
SKP_int16 *out, /* O Low-pass filtered output signal */
const SKP_int16 *in, /* I Input signal */
const SKP_int frame_length /* I Frame length */
);
#endif
/****************************************************/
/* Decoder Functions */
/****************************************************/
SKP_int SKP_Silk_create_decoder(
SKP_Silk_decoder_state **ppsDec /* I/O Decoder state pointer pointer */
);
SKP_int SKP_Silk_free_decoder(
SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */
);
SKP_int SKP_Silk_init_decoder(
SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */
);
/* Set decoder sampling rate */
void SKP_Silk_decoder_set_fs(
SKP_Silk_decoder_state *psDec, /* I/O Decoder state pointer */
SKP_int fs_kHz /* I Sampling frequency (kHz) */
);
/****************/
/* Decode frame */
/****************/
SKP_int SKP_Silk_decode_frame(
SKP_Silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */
SKP_int16 pOut[], /* O Pointer to output speech frame */
SKP_int16 *pN, /* O Pointer to size of output frame */
const SKP_uint8 pCode[], /* I Pointer to payload */
const SKP_int nBytes, /* I Payload length */
SKP_int action, /* I Action from Jitter Buffer */
SKP_int *decBytes /* O Used bytes to decode this frame */
);
/* Decode parameters from payload */
void SKP_Silk_decode_parameters(
SKP_Silk_decoder_state *psDec, /* I/O State */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int q[], /* O Excitation signal */
const SKP_int fullDecoding /* I Flag to tell if only arithmetic decoding */
);
/* Core decoder. Performs inverse NSQ operation LTP + LPC */
void SKP_Silk_decode_core(
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */
SKP_int16 xq[], /* O Decoded speech */
const SKP_int q[ MAX_FRAME_LENGTH ] /* I Pulse signal */
);
/* NLSF vector decoder */
void SKP_Silk_NLSF_MSVQ_decode(
SKP_int *pNLSF_Q15, /* O Pointer to decoded output [LPC_ORDER x 1] */
const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Pointer to NLSF codebook struct */
const SKP_int *NLSFIndices, /* I Pointer to NLSF indices [nStages x 1] */
const SKP_int LPC_order /* I LPC order */
);
/**********************/
/* Arithmetic coding */
/*********************/
/* Decode quantization indices of excitation (Shell coding) */
void SKP_Silk_decode_pulses(
SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int q[], /* O Excitation signal */
const SKP_int frame_length /* I Frame length (preliminary) */
);
/******************/
/* CNG */
/******************/
/* Reset CNG */
void SKP_Silk_CNG_Reset(
SKP_Silk_decoder_state *psDec /* I/O Decoder state */
);
/* Updates CNG estimate, and applies the CNG when packet was lost */
void SKP_Silk_CNG(
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
SKP_int16 signal[], /* I/O Signal */
SKP_int length /* I Length of residual */
);
/* Encoding of various parameters */
void SKP_Silk_encode_parameters(
SKP_Silk_encoder_state *psEncC, /* I/O Encoder state */
SKP_Silk_encoder_control *psEncCtrlC, /* I/O Encoder control */
SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
const SKP_int8 *q /* I Quantization indices */
);
/* Extract lowest layer encoding */
void SKP_Silk_get_low_layer_internal(
const SKP_uint8 *indata, /* I: Encoded input vector */
const SKP_int16 nBytesIn, /* I: Number of input Bytes */
SKP_uint8 *Layer0data, /* O: Layer0 payload */
SKP_int16 *nLayer0Bytes /* O: Number of FEC Bytes */
);
/* Resets LBRR buffer, used if packet size changes */
void SKP_Silk_LBRR_reset(
SKP_Silk_encoder_state *psEncC /* I/O Pointer to Silk encoder state */
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,433 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef SKP_SILK_MAIN_FLP_H
#define SKP_SILK_MAIN_FLP_H
#include "SKP_Silk_SigProc_FLP.h"
#include "SKP_Silk_SigProc_FIX.h"
#include "SKP_Silk_structs_FLP.h"
#include "SKP_Silk_tables_FLP.h"
#include "SKP_Silk_main.h"
/* uncomment to compile without SSE optimizations */
//#undef SKP_USE_SSE
#ifdef __cplusplus
extern "C"
{
#endif
void SKP_Silk_LBRR_ctrl_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I Encoder state FLP */
SKP_Silk_encoder_control *psEncCtrl /* I/O Encoder control */
);
void SKP_Silk_LTP_scale_ctrl_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl /* I/O Encoder control FLP */
);
void SKP_Silk_quant_LTP_gains_FLP(
SKP_float B[ NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */
SKP_int cbk_index[ NB_SUBFR ], /* O Codebook index */
SKP_int *periodicity_index, /* O Periodicity index */
const SKP_float W[ NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error weights */
const SKP_float mu, /* I Mu value (R/D tradeoff) */
const SKP_int lowComplexity /* I Flag for low complexity */
);
/*********************/
/* Encoder Functions */
/*********************/
/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
void SKP_Silk_HP_variable_cutoff_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
SKP_int16 *out, /* O High-pass filtered output signal */
const SKP_int16 *in /* I Input signal */
);
/* Encoder main function */
SKP_int SKP_Silk_encode_frame_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_uint8 *pCode, /* O Payload */
SKP_int16 *pnBytesOut, /* I/O Number of payload bytes; */
/* input: max length; output: used */
const SKP_int16 *pIn /* I Input speech frame */
);
/* Limit, stabilize, and quantize NLSFs */
void SKP_Silk_process_NLSFs_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
SKP_float *pNLSF /* I/O NLSFs (quantized output) */
);
/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */
void SKP_Silk_LBRR_encode_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
SKP_uint8 *pCode, /* O Payload */
SKP_int16 *pnBytesOut, /* I/O Payload bytes; in: max; out: used */
const SKP_float xfw[] /* I Input signal */
);
/* Initializes the Silk encoder state */
SKP_int SKP_Silk_init_encoder_FLP(
SKP_Silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */
);
/* Control the Silk encoder */
SKP_int SKP_Silk_control_encoder_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
const SKP_int PacketSize_ms, /* I Packet length (ms) */
const SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) */
const SKP_int PacketLoss_perc, /* I Packet loss rate (in percent) */
const SKP_int DTX_enabled, /* I Enable / disable DTX */
const SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */
);
/****************/
/* Prefiltering */
/****************/
void SKP_Silk_prefilter_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
const SKP_Silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */
SKP_float xw[], /* O Weighted signal */
const SKP_float x[] /* I Speech signal */
);
/**************************/
/* Noise shaping analysis */
/**************************/
/* Compute noise shaping coefficients and initial gain values */
void SKP_Silk_noise_shape_analysis_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
const SKP_float *pitch_res, /* I LPC residual from pitch analysis */
const SKP_float *x /* I Input signal [frame_length + la_shape] */
);
/* Autocorrelations for a warped frequency axis */
void SKP_Silk_warped_autocorrelation_FLP(
SKP_float *corr, /* O Result [order + 1] */
const SKP_float *input, /* I Input data to correlate */
const SKP_float warping, /* I Warping coefficient */
const SKP_int length, /* I Length of input */
const SKP_int order /* I Correlation order (even) */
);
/**************/
/* Find pitch */
/**************/
void SKP_Silk_find_pitch_lags_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
SKP_float res[], /* O Residual */
const SKP_float x[] /* I Speech signal */
);
/******************/
/* NLSF Quantizer */
/******************/
/* NLSF vector encoder */
void SKP_Silk_NLSF_MSVQ_encode_FLP(
SKP_int *NLSFIndices, /* O Codebook path vector [ CB_STAGES ] */
SKP_float *pNLSF, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
const SKP_Silk_NLSF_CB_FLP *psNLSF_CB_FLP, /* I Codebook object */
const SKP_float *pNLSF_q_prev, /* I Prev. quantized NLSF vector [LPC_ORDER] */
const SKP_float *pW, /* I NLSF weight vector [ LPC_ORDER ] */
const SKP_float NLSF_mu, /* I Rate weight for the RD optimization */
const SKP_float NLSF_mu_fluc_red, /* I Fluctuation reduction error weight */
const SKP_int NLSF_MSVQ_Survivors,/* I Max survivors from each stage */
const SKP_int LPC_order, /* I LPC order */
const SKP_int deactivate_fluc_red /* I Deactivate fluctuation reduction */
);
/* NLSF vector decoder */
void SKP_Silk_NLSF_MSVQ_decode_FLP(
SKP_float *pNLSF, /* O Decoded output vector [ LPC_ORDER ] */
const SKP_Silk_NLSF_CB_FLP *psNLSF_CB_FLP, /* I NLSF codebook struct */
const SKP_int *NLSFIndices, /* I NLSF indices [ nStages ] */
const SKP_int LPC_order /* I LPC order used */
);
/* Rate-Distortion calculations for multiple input data vectors */
void SKP_Silk_NLSF_VQ_rate_distortion_FLP(
SKP_float *pRD, /* O Rate-distortion values [psNLSF_CBS_FLP->nVectors*N] */
const SKP_Silk_NLSF_CBS_FLP *psNLSF_CBS_FLP, /* I NLSF codebook stage struct */
const SKP_float *in, /* I Input vectors to be quantized */
const SKP_float *w, /* I Weight vector */
const SKP_float *rate_acc, /* I Accumulated rates from previous stage */
const SKP_float mu, /* I Weight between weighted error and rate */
const SKP_int N, /* I Number of input vectors to be quantized */
const SKP_int LPC_order /* I LPC order */
);
/* compute weighted quantization errors for LPC_order element input vectors, over one codebook stage */
void SKP_Silk_NLSF_VQ_sum_error_FLP(
SKP_float *err, /* O Weighted quantization errors [ N * K ] */
const SKP_float *in, /* I Input vectors [ N * LPC_order ] */
const SKP_float *w, /* I Weighting vectors [ N * LPC_order ] */
const SKP_float *pCB, /* I Codebook vectors [ K * LPC_order ] */
const SKP_int N, /* I Number of input vectors */
const SKP_int K, /* I Number of codebook vectors */
const SKP_int LPC_order /* I LPC order */
);
/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
SKP_float SKP_Silk_residual_energy_covar_FLP( /* O Weighted residual energy */
const SKP_float *c, /* I Filter coefficients */
SKP_float *wXX, /* I/O Weighted correlation matrix, reg. out */
const SKP_float *wXx, /* I Weighted correlation vector */
const SKP_float wxx, /* I Weighted correlation value */
const SKP_int D /* I Dimension */
);
/* Entropy constrained MATRIX-weighted VQ, for a single input data vector */
void SKP_Silk_VQ_WMat_EC_FLP(
SKP_int *ind, /* O Index of best codebook vector */
SKP_float *rate_dist, /* O Best weighted quant. error + mu * rate */
const SKP_float *in, /* I Input vector to be quantized */
const SKP_float *W, /* I Weighting matrix */
const SKP_int16 *cb, /* I Codebook */
const SKP_int16 *cl_Q6, /* I Code length for each codebook vector */
const SKP_float mu, /* I Tradeoff between WSSE and rate */
const SKP_int L /* I Number of vectors in codebook */
);
/* Processing of gains */
void SKP_Silk_process_gains_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl /* I/O Encoder control FLP */
);
void SKP_Silk_find_LTP_FLP(
SKP_float b[ NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
SKP_float WLTP[NB_SUBFR*LTP_ORDER*LTP_ORDER], /* O Weight for LTP quantization */
SKP_float *LTPredCodGain, /* O LTP coding gain */
const SKP_float r_first[], /* I LPC residual, signal + state for 10 ms */
const SKP_float r_last[], /* I LPC residual, signal + state for 10 ms */
const SKP_int lag[ NB_SUBFR ], /* I LTP lags */
const SKP_float Wght[ NB_SUBFR ], /* I Weights */
const SKP_int subfr_length, /* I Subframe length */
const SKP_int mem_offset /* I Number of samples in LTP memory */
);
void SKP_Silk_find_LPC_FLP(
SKP_float NLSF[], /* O NLSFs */
SKP_int *interpIndex, /* O NLSF interp. index for NLSF interp. */
const SKP_float prev_NLSFq[], /* I Previous NLSFs, for NLSF interpolation */
const SKP_int useInterpNLSFs, /* I Flag */
const SKP_int LPC_order, /* I LPC order */
const SKP_float x[], /* I Input signal */
const SKP_int subfr_length /* I Subframe length incl preceeding samples */
);
void SKP_Silk_LTP_analysis_filter_FLP(
SKP_float *LTP_res, /* O LTP res NB_SUBFR*(pre_lgth+subfr_lngth) */
const SKP_float *x, /* I Input signal, with preceeding samples */
const SKP_float B[ LTP_ORDER * NB_SUBFR ], /* I LTP coefficients for each subframe */
const SKP_int pitchL[ NB_SUBFR ], /* I Pitch lags */
const SKP_float invGains[ NB_SUBFR ], /* I Inverse quantization gains */
const SKP_int subfr_length, /* I Length of each subframe */
const SKP_int pre_length /* I Preceeding samples for each subframe */
);
void SKP_Silk_residual_energy_FLP(
SKP_float nrgs[ NB_SUBFR ], /* O Residual energy per subframe */
const SKP_float x[], /* I Input signal */
SKP_float a[ 2 ][ MAX_LPC_ORDER ],/* I AR coefs for each frame half */
const SKP_float gains[], /* I Quantization gains */
const SKP_int subfr_length, /* I Subframe length */
const SKP_int LPC_order /* I LPC order */
);
void SKP_Silk_find_pred_coefs_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
const SKP_float res_pitch[] /* I Residual from pitch analysis */
);
/* 16th order LPC analysis filter */
void SKP_Silk_LPC_analysis_filter_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length, /* I Length of input signal */
const SKP_int Order /* I LPC order */
);
/* 16th order LPC analysis filter, does not write first 16 samples */
void SKP_Silk_LPC_analysis_filter16_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length /* I Length of input signal */
);
/* 12th order LPC analysis filter, does not write first 12 samples */
void SKP_Silk_LPC_analysis_filter12_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length /* I Length of input signal */
);
/* 10th order LPC analysis filter, does not write first 10 samples */
void SKP_Silk_LPC_analysis_filter10_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length /* I Length of input signal */
);
/* 8th order LPC analysis filter, does not write first 8 samples */
void SKP_Silk_LPC_analysis_filter8_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length /* I Length of input signal */
);
/* 6th order LPC analysis filter, does not write first 6 samples */
void SKP_Silk_LPC_analysis_filter6_FLP(
SKP_float r_LPC[], /* O LPC residual signal */
const SKP_float PredCoef[], /* I LPC coefficients */
const SKP_float s[], /* I Input signal */
const SKP_int length /* I Length of input signal */
);
/******************/
/* Linear Algebra */
/******************/
/* Calculates correlation matrix X'*X */
void SKP_Silk_corrMatrix_FLP(
const SKP_float *x, /* I x vector [ L+order-1 ] used to create X */
const SKP_int L, /* I Length of vectors */
const SKP_int Order, /* I Max lag for correlation */
SKP_float *XX /* O X'*X correlation matrix [order x order] */
);
/* Calculates correlation vector X'*t */
void SKP_Silk_corrVector_FLP(
const SKP_float *x, /* I x vector [L+order-1] used to create X */
const SKP_float *t, /* I Target vector [L] */
const SKP_int L, /* I Length of vecors */
const SKP_int Order, /* I Max lag for correlation */
SKP_float *Xt /* O X'*t correlation vector [order] */
);
/* Add noise to matrix diagonal */
void SKP_Silk_regularize_correlations_FLP(
SKP_float *XX, /* I/O Correlation matrices */
SKP_float *xx, /* I/O Correlation values */
const SKP_float noise, /* I Noise energy to add */
const SKP_int D /* I Dimension of XX */
);
/* Function to solve linear equation Ax = b, when A is an MxM symmetric square matrix */
void SKP_Silk_solve_LDL_FLP(
SKP_float *A, /* I/O Symmetric square matrix, out: reg. */
const SKP_int M, /* I Size of matrix */
const SKP_float *b, /* I Pointer to b vector */
SKP_float *x /* O Pointer to x solution vector */
);
/* Apply sine window to signal vector. */
/* Window types: */
/* 1 -> sine window from 0 to pi/2 */
/* 2 -> sine window from pi/2 to pi */
void SKP_Silk_apply_sine_window_FLP(
SKP_float px_win[], /* O Pointer to windowed signal */
const SKP_float px[], /* I Pointer to input signal */
const SKP_int win_type, /* I Selects a window type */
const SKP_int length /* I Window length, multiple of 4 */
);
/* Wrappers. Calls flp / fix code */
/* Convert AR filter coefficients to NLSF parameters */
void SKP_Silk_A2NLSF_FLP(
SKP_float *pNLSF, /* O NLSF vector [ LPC_order ] */
const SKP_float *pAR, /* I LPC coefficients [ LPC_order ] */
const SKP_int LPC_order /* I LPC order */
);
/* Convert NLSF parameters to AR prediction filter coefficients */
void SKP_Silk_NLSF2A_stable_FLP(
SKP_float *pAR, /* O LPC coefficients [ LPC_order ] */
const SKP_float *pNLSF, /* I NLSF vector [ LPC_order ] */
const SKP_int LPC_order /* I LPC order */
);
/* NLSF stabilizer, for a single input data vector */
void SKP_Silk_NLSF_stabilize_FLP(
SKP_float *pNLSF, /* I/O (Un)stable NLSF vector [ LPC_order ] */
const SKP_float *pNDelta_min, /* I Normalized delta min vector[LPC_order+1]*/
const SKP_int LPC_order /* I LPC order */
);
/* Interpolation function with fixed point rounding */
void SKP_Silk_interpolate_wrapper_FLP(
SKP_float xi[], /* O Interpolated vector */
const SKP_float x0[], /* I First vector */
const SKP_float x1[], /* I Second vector */
const SKP_float ifact, /* I Interp. factor, weight on second vector */
const SKP_int d /* I Number of parameters */
);
/****************************************/
/* Floating-point Silk VAD wrapper */
/****************************************/
SKP_int SKP_Silk_VAD_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
const SKP_int16 *pIn /* I Input signal */
);
/****************************************/
/* Floating-point Silk NSQ wrapper */
/****************************************/
void SKP_Silk_NSQ_wrapper_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
const SKP_float x[], /* I Prefiltered input signal */
SKP_int8 q[], /* O Quantized pulse signal */
const SKP_int useLBRR /* I LBRR flag */
);
/* using log2() helps the fixed-point conversion */
SKP_INLINE SKP_float SKP_Silk_log2( double x ) { return ( SKP_float )( 3.32192809488736 * log10( x ) ); }
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,382 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
#include "SKP_Silk_tuning_parameters.h"
/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */
/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */
SKP_INLINE SKP_float warped_gain(
const SKP_float *coefs,
SKP_float lambda,
SKP_int order
) {
SKP_int i;
SKP_float gain;
lambda = -lambda;
gain = coefs[ order - 1 ];
for( i = order - 2; i >= 0; i-- ) {
gain = lambda * gain + coefs[ i ];
}
return (SKP_float)( 1.0f / ( 1.0f - lambda * gain ) );
}
/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
SKP_INLINE void warped_true2monic_coefs(
SKP_float *coefs_syn,
SKP_float *coefs_ana,
SKP_float lambda,
SKP_float limit,
SKP_int order
) {
SKP_int i, iter, ind = 0;
SKP_float tmp, maxabs, chirp, gain_syn, gain_ana;
/* Convert to monic coefficients */
for( i = order - 1; i > 0; i-- ) {
coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];
coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];
}
gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );
gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );
for( i = 0; i < order; i++ ) {
coefs_syn[ i ] *= gain_syn;
coefs_ana[ i ] *= gain_ana;
}
/* Limit */
for( iter = 0; iter < 10; iter++ ) {
/* Find maximum absolute value */
maxabs = -1.0f;
for( i = 0; i < order; i++ ) {
tmp = SKP_max( SKP_abs_float( coefs_syn[ i ] ), SKP_abs_float( coefs_ana[ i ] ) );
if( tmp > maxabs ) {
maxabs = tmp;
ind = i;
}
}
if( maxabs <= limit ) {
/* Coefficients are within range - done */
return;
}
/* Convert back to true warped coefficients */
for( i = 1; i < order; i++ ) {
coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ];
coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ];
}
gain_syn = 1.0f / gain_syn;
gain_ana = 1.0f / gain_ana;
for( i = 0; i < order; i++ ) {
coefs_syn[ i ] *= gain_syn;
coefs_ana[ i ] *= gain_ana;
}
/* Apply bandwidth expansion */
chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
SKP_Silk_bwexpander_FLP( coefs_syn, order, chirp );
SKP_Silk_bwexpander_FLP( coefs_ana, order, chirp );
/* Convert to monic warped coefficients */
for( i = order - 1; i > 0; i-- ) {
coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];
coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];
}
gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );
gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );
for( i = 0; i < order; i++ ) {
coefs_syn[ i ] *= gain_syn;
coefs_ana[ i ] *= gain_ana;
}
}
SKP_assert( 0 );
}
/* Compute noise shaping coefficients and initial gain values */
void SKP_Silk_noise_shape_analysis_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
const SKP_float *pitch_res, /* I LPC residual from pitch analysis */
const SKP_float *x /* I Input signal [frame_length + la_shape] */
)
{
SKP_Silk_shape_state_FLP *psShapeSt = &psEnc->sShape;
SKP_int k, nSamples;
SKP_float SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt;
SKP_float nrg, pre_nrg, log_energy, log_energy_prev, energy_variation;
SKP_float delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping;
SKP_float x_windowed[ SHAPE_LPC_WIN_MAX ];
SKP_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
const SKP_float *x_ptr, *pitch_res_ptr;
/* Point to start of first LPC analysis block */
x_ptr = x - psEnc->sCmn.la_shape;
/****************/
/* CONTROL SNR */
/****************/
/* Reduce SNR_dB values if recent bitstream has exceeded TargetRate */
psEncCtrl->current_SNR_dB = psEnc->SNR_dB - 0.05f * psEnc->BufferedInChannel_ms;
/* Reduce SNR_dB if inband FEC used */
if( psEnc->speech_activity > LBRR_SPEECH_ACTIVITY_THRES ) {
psEncCtrl->current_SNR_dB -= psEnc->inBandFEC_SNR_comp;
}
/****************/
/* GAIN CONTROL */
/****************/
/* Input quality is the average of the quality in the lowest two VAD bands */
psEncCtrl->input_quality = 0.5f * ( psEncCtrl->input_quality_bands[ 0 ] + psEncCtrl->input_quality_bands[ 1 ] );
/* Coding quality level, between 0.0 and 1.0 */
psEncCtrl->coding_quality = SKP_sigmoid( 0.25f * ( psEncCtrl->current_SNR_dB - 18.0f ) );
/* Reduce coding SNR during low speech activity */
b = 1.0f - psEnc->speech_activity;
SNR_adj_dB = psEncCtrl->current_SNR_dB -
BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b;
if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
/* Reduce gains for periodic signals */
SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr;
} else {
/* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
SNR_adj_dB += ( -0.4f * psEncCtrl->current_SNR_dB + 6.0f ) * ( 1.0f - psEncCtrl->input_quality );
}
/*************************/
/* SPARSENESS PROCESSING */
/*************************/
/* Set quantizer offset */
if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
/* Initally set to 0; may be overruled in process_gains(..) */
psEncCtrl->sCmn.QuantOffsetType = 0;
psEncCtrl->sparseness = 0.0f;
} else {
/* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
nSamples = 2 * psEnc->sCmn.fs_kHz;
energy_variation = 0.0f;
log_energy_prev = 0.0f;
pitch_res_ptr = pitch_res;
for( k = 0; k < FRAME_LENGTH_MS / 2; k++ ) {
nrg = ( SKP_float )nSamples + ( SKP_float )SKP_Silk_energy_FLP( pitch_res_ptr, nSamples );
log_energy = SKP_Silk_log2( nrg );
if( k > 0 ) {
energy_variation += SKP_abs_float( log_energy - log_energy_prev );
}
log_energy_prev = log_energy;
pitch_res_ptr += nSamples;
}
psEncCtrl->sparseness = SKP_sigmoid( 0.4f * ( energy_variation - 5.0f ) );
/* Set quantization offset depending on sparseness measure */
if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) {
psEncCtrl->sCmn.QuantOffsetType = 0;
} else {
psEncCtrl->sCmn.QuantOffsetType = 1;
}
/* Increase coding SNR for sparse signals */
SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f );
}
/*******************************/
/* Control bandwidth expansion */
/*******************************/
/* More BWE for signals with high prediction gain */
strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */
BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );
delta = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality );
BWExp1 -= delta;
BWExp2 += delta;
/* BWExp1 will be applied after BWExp2, so make it relative */
BWExp1 /= BWExp2;
if( psEnc->sCmn.warping_Q16 > 0 ) {
/* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
warping = (SKP_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;
} else {
warping = 0.0f;
}
/********************************************/
/* Compute noise shaping AR coefs and gains */
/********************************************/
for( k = 0; k < NB_SUBFR; k++ ) {
/* Apply window: sine slope followed by flat part followed by cosine slope */
SKP_int shift, slope_part, flat_part;
flat_part = psEnc->sCmn.fs_kHz * 5;
slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2;
SKP_Silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part );
shift = slope_part;
SKP_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(SKP_float) );
shift += flat_part;
SKP_Silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part );
/* Update pointer: next LPC analysis block */
x_ptr += psEnc->sCmn.subfr_length;
if( psEnc->sCmn.warping_Q16 > 0 ) {
/* Calculate warped auto correlation */
SKP_Silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping,
psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
} else {
/* Calculate regular auto correlation */
SKP_Silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 );
}
/* Add white noise, as a fraction of energy */
auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION;
/* Convert correlations to prediction coefficients, and compute residual energy */
nrg = SKP_Silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder );
psEncCtrl->Gains[ k ] = ( SKP_float )sqrt( nrg );
if( psEnc->sCmn.warping_Q16 > 0 ) {
/* Adjust gain for warping */
psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );
}
/* Bandwidth expansion for synthesis filter shaping */
SKP_Silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 );
/* Compute noise shaping filter coefficients */
SKP_memcpy(
&psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],
&psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ],
psEnc->sCmn.shapingLPCOrder * sizeof( SKP_float ) );
/* Bandwidth expansion for analysis filter shaping */
SKP_Silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 );
/* Ratio of prediction gains, in energy domain */
SKP_Silk_LPC_inverse_pred_gain_FLP( &pre_nrg, &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
SKP_Silk_LPC_inverse_pred_gain_FLP( &nrg, &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg );
/* Convert to monic warped prediction coefficients and limit absolute values */
warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],
warping, 3.999f, psEnc->sCmn.shapingLPCOrder );
}
/*****************/
/* Gain tweaking */
/*****************/
/* Increase gains during low speech activity and put lower limit on gains */
gain_mult = ( SKP_float )pow( 2.0f, -0.16f * SNR_adj_dB );
gain_add = ( SKP_float )pow( 2.0f, 0.16f * NOISE_FLOOR_dB ) +
( SKP_float )pow( 2.0f, 0.16f * RELATIVE_MIN_GAIN_dB ) * psEnc->avgGain;
for( k = 0; k < NB_SUBFR; k++ ) {
psEncCtrl->Gains[ k ] *= gain_mult;
psEncCtrl->Gains[ k ] += gain_add;
psEnc->avgGain += psEnc->speech_activity * GAIN_SMOOTHING_COEF * ( psEncCtrl->Gains[ k ] - psEnc->avgGain );
}
/************************************************/
/* Decrease level during fricatives (de-essing) */
/************************************************/
gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT;
if( psEncCtrl->input_tilt <= 0.0f && psEncCtrl->sCmn.sigtype == SIG_TYPE_UNVOICED ) {
SKP_float essStrength = -psEncCtrl->input_tilt * psEnc->speech_activity * ( 1.0f - psEncCtrl->sparseness );
if( psEnc->sCmn.fs_kHz == 24 ) {
gain_mult *= ( SKP_float )pow( 2.0f, -0.16f * DE_ESSER_COEF_SWB_dB * essStrength );
} else if( psEnc->sCmn.fs_kHz == 16 ) {
gain_mult *= (SKP_float)pow( 2.0f, -0.16f * DE_ESSER_COEF_WB_dB * essStrength );
} else {
SKP_assert( psEnc->sCmn.fs_kHz == 12 || psEnc->sCmn.fs_kHz == 8 );
}
}
for( k = 0; k < NB_SUBFR; k++ ) {
psEncCtrl->GainsPre[ k ] *= gain_mult;
}
/************************************************/
/* Control low-frequency shaping and noise tilt */
/************************************************/
/* Less low frequency shaping for noisy inputs */
strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEncCtrl->input_quality_bands[ 0 ] - 1.0f ) );
if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
/* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
/*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
for( k = 0; k < NB_SUBFR; k++ ) {
b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->sCmn.pitchL[ k ];
psEncCtrl->LF_MA_shp[ k ] = -1.0f + b;
psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength;
}
Tilt = - HP_NOISE_COEF -
(1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->speech_activity;
} else {
b = 1.3f / psEnc->sCmn.fs_kHz;
psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b;
psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f;
for( k = 1; k < NB_SUBFR; k++ ) {
psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ];
psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ];
}
Tilt = -HP_NOISE_COEF;
}
/****************************/
/* HARMONIC SHAPING CONTROL */
/****************************/
/* Control boosting of harmonic frequencies */
HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr;
/* More harmonic boost for noisy input signals */
HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality );
if( USE_HARM_SHAPING && psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
/* Harmonic noise shaping */
HarmShapeGain = HARMONIC_SHAPING;
/* More harmonic noise shaping for high bitrates or noisy input */
HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING *
( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality );
/* Less harmonic noise shaping for less periodic signals */
HarmShapeGain *= ( SKP_float )sqrt( psEnc->LTPCorr );
} else {
HarmShapeGain = 0.0f;
}
/*************************/
/* Smooth over subframes */
/*************************/
for( k = 0; k < NB_SUBFR; k++ ) {
psShapeSt->HarmBoost_smth += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth );
psEncCtrl->HarmBoost[ k ] = psShapeSt->HarmBoost_smth;
psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth );
psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth;
psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth );
psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth;
}
}

View File

@ -0,0 +1,625 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. 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.
***********************************************************************/
/*****************************************************************************
*
* Pitch analyser function
*
******************************************************************************/
#include "SKP_Silk_SigProc_FLP.h"
#include "SKP_Silk_SigProc_FIX.h"
#include "./SKP_Silk_pitch_est_defines_FLP.h"
#include "SKP_Silk_common_pitch_est_defines.h"
#define SCRATCH_SIZE 22
/************************************************************/
/* Definitions */
/************************************************************/
#define eps 1.192092896e-07f
/* using log2() helps the fixed-point conversion */
SKP_INLINE SKP_float SKP_P_log2(double x) { return (SKP_float)(3.32192809488736 * log10(x)); }
/************************************************************/
/* Internally used functions */
/************************************************************/
static void SKP_P_Ana_calc_corr_st3(
SKP_float cross_corr_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
const SKP_float signal[], /* I vector to correlate */
SKP_int start_lag, /* I start lag */
SKP_int sf_length, /* I sub frame length */
SKP_int complexity /* I Complexity setting */
);
static void SKP_P_Ana_calc_energy_st3(
SKP_float energies_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
const SKP_float signal[], /* I vector to correlate */
SKP_int start_lag, /* I start lag */
SKP_int sf_length, /* I sub frame length */
SKP_int complexity /* I Complexity setting */
);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//% CORE PITCH ANALYSIS FUNCTION %
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SKP_int SKP_Silk_pitch_analysis_core_FLP( /* O voicing estimate: 0 voiced, 1 unvoiced */
const SKP_float *signal, /* I signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz */
SKP_int *pitch_out, /* O 4 pitch lag values */
SKP_int *lagIndex, /* O lag Index */
SKP_int *contourIndex, /* O pitch contour Index */
SKP_float *LTPCorr, /* I/O normalized correlation; input: value from previous frame */
SKP_int prevLag, /* I last lag of previous frame; set to zero is unvoiced */
const SKP_float search_thres1, /* I first stage threshold for lag candidates 0 - 1 */
const SKP_float search_thres2, /* I final threshold for lag candidates 0 - 1 */
const SKP_int Fs_kHz, /* I sample frequency (kHz) */
const SKP_int complexity /* I Complexity setting, 0-2, where 2 is highest */
)
{
SKP_float signal_8kHz[ PITCH_EST_FRAME_LENGTH_MS * 8 ];
SKP_float signal_4kHz[ PITCH_EST_FRAME_LENGTH_MS * 4 ];
SKP_float scratch_mem[ PITCH_EST_MAX_FRAME_LENGTH * 3 ];
SKP_float filt_state[ PITCH_EST_MAX_DECIMATE_STATE_LENGTH ];
SKP_int i, k, d, j;
SKP_float threshold, contour_bias;
SKP_float C[PITCH_EST_NB_SUBFR][(PITCH_EST_MAX_LAG >> 1) + 5]; /* use to be +2 but then valgrind reported errors for SWB */
SKP_float CC[PITCH_EST_NB_CBKS_STAGE2_EXT];
const SKP_float *target_ptr, *basis_ptr;
double cross_corr, normalizer, energy, energy_tmp;
SKP_int d_srch[PITCH_EST_D_SRCH_LENGTH];
SKP_int16 d_comp[(PITCH_EST_MAX_LAG >> 1) + 5];
SKP_int length_d_srch, length_d_comp;
SKP_float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new;
SKP_int CBimax, CBimax_new, lag, start_lag, end_lag, lag_new;
SKP_int cbk_offset, cbk_size;
SKP_float lag_log2, prevLag_log2, delta_lag_log2_sqr;
SKP_float energies_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ];
SKP_float cross_corr_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ];
SKP_int diff, lag_counter;
SKP_int frame_length, frame_length_8kHz, frame_length_4kHz;
SKP_int sf_length, sf_length_8kHz;
SKP_int min_lag, min_lag_8kHz, min_lag_4kHz;
SKP_int max_lag, max_lag_8kHz, max_lag_4kHz;
SKP_int nb_cbks_stage2;
/* Check for valid sampling frequency */
SKP_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 || Fs_kHz == 24 );
/* Check for valid complexity setting */
SKP_assert( complexity >= SKP_Silk_PITCH_EST_MIN_COMPLEX );
SKP_assert( complexity <= SKP_Silk_PITCH_EST_MAX_COMPLEX );
SKP_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f );
SKP_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f );
/* Setup frame lengths max / min lag for the sampling frequency */
frame_length = PITCH_EST_FRAME_LENGTH_MS * Fs_kHz;
frame_length_4kHz = PITCH_EST_FRAME_LENGTH_MS * 4;
frame_length_8kHz = PITCH_EST_FRAME_LENGTH_MS * 8;
sf_length = SKP_RSHIFT( frame_length, 3 );
sf_length_8kHz = SKP_RSHIFT( frame_length_8kHz, 3 );
min_lag = PITCH_EST_MIN_LAG_MS * Fs_kHz;
min_lag_4kHz = PITCH_EST_MIN_LAG_MS * 4;
min_lag_8kHz = PITCH_EST_MIN_LAG_MS * 8;
max_lag = PITCH_EST_MAX_LAG_MS * Fs_kHz;
max_lag_4kHz = PITCH_EST_MAX_LAG_MS * 4;
max_lag_8kHz = PITCH_EST_MAX_LAG_MS * 8;
SKP_memset(C, 0, sizeof(SKP_float) * PITCH_EST_NB_SUBFR * ((PITCH_EST_MAX_LAG >> 1) + 5));
/* Resample from input sampled at Fs_kHz to 8 kHz */
if( Fs_kHz == 12 ) {
SKP_int16 signal_12[ 12 * PITCH_EST_FRAME_LENGTH_MS ];
SKP_int16 signal_8[ 8 * PITCH_EST_FRAME_LENGTH_MS ];
SKP_int32 R23[ 6 ];
/* Resample to 12 -> 8 khz */
SKP_memset( R23, 0, 6 * sizeof( SKP_int32 ) );
SKP_float2short_array( signal_12, signal, PITCH_EST_FRAME_LENGTH_MS * 12);
SKP_Silk_resampler_down2_3( R23, signal_8, signal_12, PITCH_EST_FRAME_LENGTH_MS * 12 );
SKP_short2float_array( signal_8kHz, signal_8, frame_length_8kHz );
} else if( Fs_kHz == 16 ) {
if( complexity == SKP_Silk_PITCH_EST_MAX_COMPLEX ) {
SKP_assert( 4 <= PITCH_EST_MAX_DECIMATE_STATE_LENGTH );
SKP_memset( filt_state, 0, 4 * sizeof(SKP_float) );
SKP_Silk_decimate2_coarse_FLP( signal, filt_state, signal_8kHz,
scratch_mem, frame_length_8kHz );
} else {
SKP_assert( 2 <= PITCH_EST_MAX_DECIMATE_STATE_LENGTH );
SKP_memset( filt_state, 0, 2 * sizeof(SKP_float) );
SKP_Silk_decimate2_coarsest_FLP( signal, filt_state, signal_8kHz,
scratch_mem, frame_length_8kHz );
}
} else if( Fs_kHz == 24 ) {
SKP_int16 signal_24[ PITCH_EST_MAX_FRAME_LENGTH ];
SKP_int16 signal_8[ 8 * PITCH_EST_FRAME_LENGTH_MS ];
SKP_int32 filt_state_fix[ 8 ];
/* Resample to 24 -> 8 khz */
SKP_float2short_array( signal_24, signal, 24 * PITCH_EST_FRAME_LENGTH_MS );
SKP_memset( filt_state_fix, 0, 8 * sizeof(SKP_int32) );
SKP_Silk_resampler_down3( filt_state_fix, signal_8, signal_24, 24 * PITCH_EST_FRAME_LENGTH_MS );
SKP_short2float_array( signal_8kHz, signal_8, frame_length_8kHz );
} else {
SKP_assert( Fs_kHz == 8 );
SKP_memcpy( signal_8kHz, signal, frame_length_8kHz * sizeof(SKP_float) );
}
/* Decimate again to 4 kHz. Set mem to zero */
if( complexity == SKP_Silk_PITCH_EST_MAX_COMPLEX ) {
SKP_assert( 4 <= PITCH_EST_MAX_DECIMATE_STATE_LENGTH );
SKP_memset( filt_state, 0, 4 * sizeof(SKP_float) );
SKP_Silk_decimate2_coarse_FLP( signal_8kHz, filt_state,
signal_4kHz, scratch_mem, frame_length_4kHz );
} else {
SKP_assert( 2 <= PITCH_EST_MAX_DECIMATE_STATE_LENGTH );
SKP_memset( filt_state, 0, 2 * sizeof(SKP_float) );
SKP_Silk_decimate2_coarsest_FLP( signal_8kHz, filt_state,
signal_4kHz, scratch_mem, frame_length_4kHz );
}
/* Low-pass filter */
for( i = frame_length_4kHz - 1; i > 0; i-- ) {
signal_4kHz[ i ] += signal_4kHz[ i - 1 ];
}
/******************************************************************************
* FIRST STAGE, operating in 4 khz
******************************************************************************/
target_ptr = &signal_4kHz[ SKP_RSHIFT( frame_length_4kHz, 1 ) ];
for( k = 0; k < 2; k++ ) {
/* Check that we are within range of the array */
SKP_assert( target_ptr >= signal_4kHz );
SKP_assert( target_ptr + sf_length_8kHz <= signal_4kHz + frame_length_4kHz );
basis_ptr = target_ptr - min_lag_4kHz;
/* Check that we are within range of the array */
SKP_assert( basis_ptr >= signal_4kHz );
SKP_assert( basis_ptr + sf_length_8kHz <= signal_4kHz + frame_length_4kHz );
/* Calculate first vector products before loop */
cross_corr = SKP_Silk_inner_product_FLP( target_ptr, basis_ptr, sf_length_8kHz );
normalizer = SKP_Silk_energy_FLP( basis_ptr, sf_length_8kHz ) + sf_length_8kHz * 4000.0f;
C[ 0 ][ min_lag_4kHz ] += (SKP_float)(cross_corr / sqrt(normalizer));
/* From now on normalizer is computed recursively */
for(d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++) {
basis_ptr--;
/* Check that we are within range of the array */
SKP_assert( basis_ptr >= signal_4kHz );
SKP_assert( basis_ptr + sf_length_8kHz <= signal_4kHz + frame_length_4kHz );
cross_corr = SKP_Silk_inner_product_FLP(target_ptr, basis_ptr, sf_length_8kHz);
/* Add contribution of new sample and remove contribution from oldest sample */
normalizer +=
basis_ptr[ 0 ] * basis_ptr[ 0 ] -
basis_ptr[ sf_length_8kHz ] * basis_ptr[ sf_length_8kHz ];
C[ 0 ][ d ] += (SKP_float)(cross_corr / sqrt( normalizer ));
}
/* Update target pointer */
target_ptr += sf_length_8kHz;
}
/* Apply short-lag bias */
for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f;
}
/* Sort */
length_d_srch = 4 + 2 * complexity;
SKP_assert( 3 * length_d_srch <= PITCH_EST_D_SRCH_LENGTH );
SKP_Silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
/* Escape if correlation is very low already here */
Cmax = C[ 0 ][ min_lag_4kHz ];
target_ptr = &signal_4kHz[ SKP_RSHIFT( frame_length_4kHz, 1 ) ];
energy = 1000.0f;
for( i = 0; i < SKP_RSHIFT( frame_length_4kHz, 1 ); i++ ) {
energy += target_ptr[i] * target_ptr[i];
}
threshold = Cmax * Cmax;
if( energy / 16.0f > threshold ) {
SKP_memset(pitch_out, 0, PITCH_EST_NB_SUBFR * sizeof(SKP_int));
*LTPCorr = 0.0f;
*lagIndex = 0;
*contourIndex = 0;
return 1;
}
threshold = search_thres1 * Cmax;
for( i = 0; i < length_d_srch; i++ ) {
/* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) {
d_srch[ i ] = SKP_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 );
} else {
length_d_srch = i;
break;
}
}
SKP_assert( length_d_srch > 0 );
for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
d_comp[ i ] = 0;
}
for( i = 0; i < length_d_srch; i++ ) {
d_comp[ d_srch[ i ] ] = 1;
}
/* Convolution */
for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ];
}
length_d_srch = 0;
for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) {
if( d_comp[ i + 1 ] > 0 ) {
d_srch[ length_d_srch ] = i;
length_d_srch++;
}
}
/* Convolution */
for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ];
}
length_d_comp = 0;
for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) {
if( d_comp[ i ] > 0 ) {
d_comp[ length_d_comp ] = i - 2;
length_d_comp++;
}
}
/**********************************************************************************
** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
*************************************************************************************/
/*********************************************************************************
* Find energy of each subframe projected onto its history, for a range of delays
*********************************************************************************/
SKP_memset( C, 0, PITCH_EST_NB_SUBFR*((PITCH_EST_MAX_LAG >> 1) + 5) * sizeof(SKP_float)); // Is this needed?
target_ptr = &signal_8kHz[ frame_length_4kHz ]; /* point to middle of frame */
for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ){
/* Check that we are within range of the array */
SKP_assert( target_ptr >= signal_8kHz );
SKP_assert( target_ptr + sf_length_8kHz <= signal_8kHz + frame_length_8kHz );
energy_tmp = SKP_Silk_energy_FLP( target_ptr, sf_length_8kHz );
for( j = 0; j < length_d_comp; j++ ) {
d = d_comp[ j ];
basis_ptr = target_ptr - d;
/* Check that we are within range of the array */
SKP_assert( basis_ptr >= signal_8kHz );
SKP_assert( basis_ptr + sf_length_8kHz <= signal_8kHz + frame_length_8kHz );
cross_corr = SKP_Silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz );
energy = SKP_Silk_energy_FLP( basis_ptr, sf_length_8kHz );
if (cross_corr > 0.0f) {
C[ k ][ d ] = (SKP_float)(cross_corr * cross_corr / (energy * energy_tmp + eps));
} else {
C[ k ][ d ] = 0.0f;
}
}
target_ptr += sf_length_8kHz;
}
/* search over lag range and lags codebook */
/* scale factor for lag codebook, as a function of center lag */
CCmax = 0.0f; /* This value doesn't matter */
CCmax_b = -1000.0f;
CBimax = 0; /* To avoid returning undefined lag values */
lag = -1; /* To check if lag with strong enough correlation has been found */
if( prevLag > 0 ) {
if( Fs_kHz == 12 ) {
prevLag = SKP_LSHIFT( prevLag, 1 ) / 3;
} else if( Fs_kHz == 16 ) {
prevLag = SKP_RSHIFT( prevLag, 1 );
} else if( Fs_kHz == 24 ) {
prevLag = prevLag / 3;
}
prevLag_log2 = SKP_P_log2((double)prevLag);
} else {
prevLag_log2 = 0;
}
/* If input is 8 khz use a larger codebook here because it is last stage */
if( Fs_kHz == 8 && complexity > SKP_Silk_PITCH_EST_MIN_COMPLEX ) {
nb_cbks_stage2 = PITCH_EST_NB_CBKS_STAGE2_EXT;
} else {
nb_cbks_stage2 = PITCH_EST_NB_CBKS_STAGE2;
}
for( k = 0; k < length_d_srch; k++ ) {
d = d_srch[ k ];
for( j = 0; j < nb_cbks_stage2; j++ ) {
CC[j] = 0.0f;
for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) {
/* Try all codebooks */
CC[ j ] += C[ i ][ d + SKP_Silk_CB_lags_stage2[ i ][ j ] ];
}
}
/* Find best codebook */
CCmax_new = -1000.0f;
CBimax_new = 0;
for( i = 0; i < nb_cbks_stage2; i++ ) {
if( CC[ i ] > CCmax_new ) {
CCmax_new = CC[ i ];
CBimax_new = i;
}
}
CCmax_new = SKP_max_float(CCmax_new, 0.0f); /* To avoid taking square root of negative number later */
CCmax_new_b = CCmax_new;
/* Bias towards shorter lags */
lag_log2 = SKP_P_log2((double)d);
CCmax_new_b -= PITCH_EST_FLP_SHORTLAG_BIAS * PITCH_EST_NB_SUBFR * lag_log2;
/* Bias towards previous lag */
if ( prevLag > 0 ) {
delta_lag_log2_sqr = lag_log2 - prevLag_log2;
delta_lag_log2_sqr *= delta_lag_log2_sqr;
CCmax_new_b -= PITCH_EST_FLP_PREVLAG_BIAS * PITCH_EST_NB_SUBFR * (*LTPCorr) * delta_lag_log2_sqr / (delta_lag_log2_sqr + 0.5f);
}
if ( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
CCmax_new > PITCH_EST_NB_SUBFR * search_thres2 * search_thres2 && /* Correlation needs to be high enough to be voiced */
SKP_Silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= min_lag_8kHz /* Lag must be in range */
) {
CCmax_b = CCmax_new_b;
CCmax = CCmax_new;
lag = d;
CBimax = CBimax_new;
}
}
if( lag == -1 ) {
/* No suitable candidate found */
SKP_memset( pitch_out, 0, PITCH_EST_NB_SUBFR * sizeof(SKP_int) );
*LTPCorr = 0.0f;
*lagIndex = 0;
*contourIndex = 0;
return 1;
}
if( Fs_kHz > 8 ) {
/* Search in original signal */
/* Compensate for decimation */
SKP_assert( lag == SKP_SAT16( lag ) );
if( Fs_kHz == 12 ) {
lag = SKP_RSHIFT_ROUND( SKP_SMULBB( lag, 3 ), 1 );
} else if( Fs_kHz == 16 ) {
lag = SKP_LSHIFT( lag, 1 );
} else {
lag = SKP_SMULBB( lag, 3 );
}
lag = SKP_LIMIT_int( lag, min_lag, max_lag );
start_lag = SKP_max_int( lag - 2, min_lag );
end_lag = SKP_min_int( lag + 2, max_lag );
lag_new = lag; /* to avoid undefined lag */
CBimax = 0; /* to avoid undefined lag */
SKP_assert( CCmax >= 0.0f );
*LTPCorr = (SKP_float)sqrt( CCmax / PITCH_EST_NB_SUBFR ); // Output normalized correlation
CCmax = -1000.0f;
/* Calculate the correlations and energies needed in stage 3 */
SKP_P_Ana_calc_corr_st3( cross_corr_st3, signal, start_lag, sf_length, complexity );
SKP_P_Ana_calc_energy_st3( energies_st3, signal, start_lag, sf_length, complexity );
lag_counter = 0;
SKP_assert( lag == SKP_SAT16( lag ) );
contour_bias = PITCH_EST_FLP_FLATCONTOUR_BIAS / lag;
/* Setup cbk parameters acording to complexity setting */
cbk_size = (SKP_int)SKP_Silk_cbk_sizes_stage3[ complexity ];
cbk_offset = (SKP_int)SKP_Silk_cbk_offsets_stage3[ complexity ];
for( d = start_lag; d <= end_lag; d++ ) {
for( j = cbk_offset; j < ( cbk_offset + cbk_size ); j++ ) {
cross_corr = 0.0;
energy = eps;
for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
energy += energies_st3[ k ][ j ][ lag_counter ];
cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ];
}
if( cross_corr > 0.0 ) {
CCmax_new = (SKP_float)(cross_corr * cross_corr / energy);
/* Reduce depending on flatness of contour */
diff = j - ( PITCH_EST_NB_CBKS_STAGE3_MAX >> 1 );
CCmax_new *= ( 1.0f - contour_bias * diff * diff );
} else {
CCmax_new = 0.0f;
}
if( CCmax_new > CCmax &&
( d + (SKP_int)SKP_Silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag
) {
CCmax = CCmax_new;
lag_new = d;
CBimax = j;
}
}
lag_counter++;
}
for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
pitch_out[k] = lag_new + (SKP_int)SKP_Silk_CB_lags_stage3[ k ][ CBimax ];
}
*lagIndex = lag_new - min_lag;
*contourIndex = CBimax;
} else {
/* Save Lags and correlation */
SKP_assert( CCmax >= 0.0f );
*LTPCorr = (SKP_float)sqrt(CCmax / PITCH_EST_NB_SUBFR); /* Output normalized correlation */
for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
pitch_out[ k ] = lag + SKP_Silk_CB_lags_stage2[ k ][ CBimax ];
}
*lagIndex = lag - min_lag;
*contourIndex = CBimax;
}
SKP_assert( *lagIndex >= 0 );
/* return as voiced */
return 0;
}
static void SKP_P_Ana_calc_corr_st3(
SKP_float cross_corr_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
const SKP_float signal[], /* I vector to correlate */
SKP_int start_lag, /* I start lag */
SKP_int sf_length, /* I sub frame length */
SKP_int complexity /* I Complexity setting */
)
/***********************************************************************
Calculates the correlations used in stage 3 search. In order to cover
the whole lag codebook for all the searched offset lags (lag +- 2),
the following correlations are needed in each sub frame:
sf1: lag range [-8,...,7] total 16 correlations
sf2: lag range [-4,...,4] total 9 correlations
sf3: lag range [-3,....4] total 8 correltions
sf4: lag range [-6,....8] total 15 correlations
In total 48 correlations. The direct implementation computed in worst case
4*12*5 = 240 correlations, but more likely around 120.
**********************************************************************/
{
const SKP_float *target_ptr, *basis_ptr;
SKP_int i, j, k, lag_counter;
SKP_int cbk_offset, cbk_size, delta, idx;
SKP_float scratch_mem[ SCRATCH_SIZE ];
SKP_assert( complexity >= SKP_Silk_PITCH_EST_MIN_COMPLEX );
SKP_assert( complexity <= SKP_Silk_PITCH_EST_MAX_COMPLEX );
cbk_offset = SKP_Silk_cbk_offsets_stage3[ complexity ];
cbk_size = SKP_Silk_cbk_sizes_stage3[ complexity ];
target_ptr = &signal[ SKP_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
lag_counter = 0;
/* Calculate the correlations for each subframe */
for( j = SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ]; j <= SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 1 ]; j++ ) {
basis_ptr = target_ptr - ( start_lag + j );
SKP_assert( lag_counter < SCRATCH_SIZE );
scratch_mem[ lag_counter ] = (SKP_float)SKP_Silk_inner_product_FLP( target_ptr, basis_ptr, sf_length );
lag_counter++;
}
delta = SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ];
for( i = cbk_offset; i < ( cbk_offset + cbk_size ); i++ ) {
/* Fill out the 3 dim array that stores the correlations for */
/* each code_book vector for each start lag */
idx = SKP_Silk_CB_lags_stage3[ k ][ i ] - delta;
for( j = 0; j < PITCH_EST_NB_STAGE3_LAGS; j++ ) {
SKP_assert( idx + j < SCRATCH_SIZE );
SKP_assert( idx + j < lag_counter );
cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
}
}
target_ptr += sf_length;
}
}
static void SKP_P_Ana_calc_energy_st3(
SKP_float energies_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
const SKP_float signal[], /* I vector to correlate */
SKP_int start_lag, /* I start lag */
SKP_int sf_length, /* I sub frame length */
SKP_int complexity /* I Complexity setting */
)
/****************************************************************
Calculate the energies for first two subframes. The energies are
calculated recursively.
****************************************************************/
{
const SKP_float *target_ptr, *basis_ptr;
double energy;
SKP_int k, i, j, lag_counter;
SKP_int cbk_offset, cbk_size, delta, idx;
SKP_float scratch_mem[ SCRATCH_SIZE ];
SKP_assert( complexity >= SKP_Silk_PITCH_EST_MIN_COMPLEX );
SKP_assert( complexity <= SKP_Silk_PITCH_EST_MAX_COMPLEX );
cbk_offset = SKP_Silk_cbk_offsets_stage3[ complexity ];
cbk_size = SKP_Silk_cbk_sizes_stage3[ complexity ];
target_ptr = &signal[ SKP_LSHIFT( sf_length, 2 ) ];
for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
lag_counter = 0;
/* Calculate the energy for first lag */
basis_ptr = target_ptr - ( start_lag + SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ] );
energy = SKP_Silk_energy_FLP( basis_ptr, sf_length ) + 1e-3;
SKP_assert( energy >= 0.0 );
scratch_mem[lag_counter] = (SKP_float)energy;
lag_counter++;
for( i = 1; i < ( SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 1 ] - SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ] + 1 ); i++ ) {
/* remove part outside new window */
energy -= basis_ptr[sf_length - i] * basis_ptr[sf_length - i];
/* add part that comes into window */
energy += basis_ptr[ -i ] * basis_ptr[ -i ];
SKP_assert( lag_counter < SCRATCH_SIZE );
scratch_mem[lag_counter] = ( SKP_float )SKP_max_float( energy, 1e-3 );
lag_counter++;
}
delta = SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ];
for( i = cbk_offset; i < ( cbk_offset + cbk_size ); i++ ) {
/* Fill out the 3 dim array that stores the correlations for */
/* each code_book vector for each start lag */
idx = SKP_Silk_CB_lags_stage3[ k ][ i ] - delta;
for(j = 0; j < PITCH_EST_NB_STAGE3_LAGS; j++){
SKP_assert( idx + j < SCRATCH_SIZE );
SKP_assert( idx + j < lag_counter );
energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
SKP_assert( energies_st3[ k ][ i ][ j ] >= 0.0f );
}
}
target_ptr += sf_length;
}
}

View File

@ -0,0 +1,40 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef SIGPROCFIX_PITCH_EST_DEFINES_H
#define SIGPROCFIX_PITCH_EST_DEFINES_H
/************************************************************/
/* Definitions For Fix pitch estimator */
/************************************************************/
#define PITCH_EST_SHORTLAG_BIAS_Q15 6554 /* 0.2f. for logarithmic weighting */
#define PITCH_EST_PREVLAG_BIAS_Q15 6554 /* Prev lag bias */
#define PITCH_EST_FLATCONTOUR_BIAS_Q20 52429 /* 0.05f */
#endif

View File

@ -0,0 +1,40 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifndef SIGPROCFLP_PITCH_EST_DEFINES_H
#define SIGPROCFLP_PITCH_EST_DEFINES_H
/************************************************************/
/* Definitions For FLP pitch estimator */
/************************************************************/
#define PITCH_EST_FLP_SHORTLAG_BIAS 0.2f /* for logarithmic weighting */
#define PITCH_EST_FLP_PREVLAG_BIAS 0.2f /* for logarithmic weighting */
#define PITCH_EST_FLP_FLATCONTOUR_BIAS 0.05f
#endif

View File

@ -0,0 +1,89 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_typedef.h"
#include "SKP_Silk_common_pitch_est_defines.h"
/********************************************************/
/* Auto Generated File from generate_pitch_est_tables.m */
/********************************************************/
const SKP_int16 SKP_Silk_CB_lags_stage2[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE2_EXT] =
{
{0, 2,-1,-1,-1, 0, 0, 1, 1, 0, 1},
{0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0},
{0,-1, 2, 1, 0, 1, 1, 0, 0,-1,-1}
};
const SKP_int16 SKP_Silk_CB_lags_stage3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX] =
{
{-9,-7,-6,-5,-5,-4,-4,-3,-3,-2,-2,-2,-1,-1,-1, 0, 0, 0, 1, 1, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 5, 6, 8},
{-3,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 2, 1, 2, 2, 2, 2, 3},
{ 3, 3, 2, 2, 2, 2, 1, 2, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,-1, 0, 0,-1,-1,-1,-1,-1,-2,-2,-2},
{ 9, 8, 6, 5, 6, 5, 4, 4, 3, 3, 2, 2, 2, 1, 0, 1, 1, 0, 0, 0,-1,-1,-1,-2,-2,-2,-3,-3,-4,-4,-5,-5,-6,-7}
};
const SKP_int16 SKP_Silk_Lag_range_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ] [ PITCH_EST_NB_SUBFR ][ 2 ] =
{
/* Lags to search for low number of stage3 cbks */
{
{-2,6},
{-1,5},
{-1,5},
{-2,7}
},
/* Lags to search for middle number of stage3 cbks */
{
{-4,8},
{-1,6},
{-1,6},
{-4,9}
},
/* Lags to search for max number of stage3 cbks */
{
{-9,12},
{-3,7},
{-2,7},
{-7,13}
}
};
const SKP_int16 SKP_Silk_cbk_sizes_stage3[SKP_Silk_PITCH_EST_MAX_COMPLEX + 1] =
{
PITCH_EST_NB_CBKS_STAGE3_MIN,
PITCH_EST_NB_CBKS_STAGE3_MID,
PITCH_EST_NB_CBKS_STAGE3_MAX
};
const SKP_int16 SKP_Silk_cbk_offsets_stage3[SKP_Silk_PITCH_EST_MAX_COMPLEX + 1] =
{
((PITCH_EST_NB_CBKS_STAGE3_MAX - PITCH_EST_NB_CBKS_STAGE3_MIN) >> 1),
((PITCH_EST_NB_CBKS_STAGE3_MAX - PITCH_EST_NB_CBKS_STAGE3_MID) >> 1),
0
};

View File

@ -0,0 +1,202 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include "SKP_Silk_main_FLP.h"
#include "SKP_Silk_tuning_parameters.h"
/*
* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal
*/
SKP_INLINE void SKP_Silk_prefilt_FLP(
SKP_Silk_prefilter_state_FLP *P,/* I/O state */
SKP_float st_res[], /* I */
SKP_float xw[], /* O */
SKP_float *HarmShapeFIR, /* I */
SKP_float Tilt, /* I */
SKP_float LF_MA_shp, /* I */
SKP_float LF_AR_shp, /* I */
SKP_int lag, /* I */
SKP_int length /* I */
);
void SKP_Silk_warped_LPC_analysis_filter_FLP(
SKP_float state[], /* I/O State [order + 1] */
SKP_float res[], /* O Residual signal [length] */
const SKP_float coef[], /* I Coefficients [order] */
const SKP_float input[], /* I Input signal [length] */
const SKP_float lambda, /* I Warping factor */
const SKP_int length, /* I Length of input signal */
const SKP_int order /* I Filter order (even) */
)
{
SKP_int n, i;
SKP_float acc, tmp1, tmp2;
/* Order must be even */
SKP_assert( ( order & 1 ) == 0 );
for( n = 0; n < length; n++ ) {
/* Output of lowpass section */
tmp2 = state[ 0 ] + lambda * state[ 1 ];
state[ 0 ] = input[ n ];
/* Output of allpass section */
tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 );
state[ 1 ] = tmp2;
acc = coef[ 0 ] * tmp2;
/* Loop over allpass sections */
for( i = 2; i < order; i += 2 ) {
/* Output of allpass section */
tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 );
state[ i ] = tmp1;
acc += coef[ i - 1 ] * tmp1;
/* Output of allpass section */
tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 );
state[ i + 1 ] = tmp2;
acc += coef[ i ] * tmp2;
}
state[ order ] = tmp1;
acc += coef[ order - 1 ] * tmp1;
res[ n ] = input[ n ] - acc;
}
}
/*
* SKP_Silk_prefilter. Main prefilter function
*/
void SKP_Silk_prefilter_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
const SKP_Silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */
SKP_float xw[], /* O Weighted signal */
const SKP_float x[] /* I Speech signal */
)
{
SKP_Silk_prefilter_state_FLP *P = &psEnc->sPrefilt;
SKP_int j, k, lag;
SKP_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp;
SKP_float B[ 2 ];
const SKP_float *AR1_shp;
const SKP_float *px;
SKP_float *pxw;
SKP_float HarmShapeFIR[ 3 ];
SKP_float st_res[ MAX_FRAME_LENGTH / NB_SUBFR + MAX_SHAPE_LPC_ORDER ];
/* Set up pointers */
px = x;
pxw = xw;
lag = P->lagPrev;
for( k = 0; k < NB_SUBFR; k++ ) {
/* Update Variables that change per sub frame */
if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
lag = psEncCtrl->sCmn.pitchL[ k ];
}
/* Noise shape parameters */
HarmShapeGain = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] );
HarmShapeFIR[ 0 ] = SKP_Silk_HarmShapeFIR_FLP[ 0 ] * HarmShapeGain;
HarmShapeFIR[ 1 ] = SKP_Silk_HarmShapeFIR_FLP[ 1 ] * HarmShapeGain;
HarmShapeFIR[ 2 ] = SKP_Silk_HarmShapeFIR_FLP[ 2 ] * HarmShapeGain;
Tilt = psEncCtrl->Tilt[ k ];
LF_MA_shp = psEncCtrl->LF_MA_shp[ k ];
LF_AR_shp = psEncCtrl->LF_AR_shp[ k ];
AR1_shp = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ];
/* Short term FIR filtering */
SKP_Silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px,
(SKP_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );
/* Reduce (mainly) low frequencies during harmonic emphasis */
B[ 0 ] = psEncCtrl->GainsPre[ k ];
B[ 1 ] = -psEncCtrl->GainsPre[ k ] *
( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT );
pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP;
for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ];
}
P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ];
SKP_Silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length );
px += psEnc->sCmn.subfr_length;
pxw += psEnc->sCmn.subfr_length;
}
P->lagPrev = psEncCtrl->sCmn.pitchL[ NB_SUBFR - 1 ];
}
/*
* Prefilter for finding Quantizer input signal
*/
SKP_INLINE void SKP_Silk_prefilt_FLP(
SKP_Silk_prefilter_state_FLP *P,/* I/O state */
SKP_float st_res[], /* I */
SKP_float xw[], /* O */
SKP_float *HarmShapeFIR, /* I */
SKP_float Tilt, /* I */
SKP_float LF_MA_shp, /* I */
SKP_float LF_AR_shp, /* I */
SKP_int lag, /* I */
SKP_int length /* I */
)
{
SKP_int i;
SKP_int idx, LTP_shp_buf_idx;
SKP_float n_Tilt, n_LF, n_LTP;
SKP_float sLF_AR_shp, sLF_MA_shp;
SKP_float *LTP_shp_buf;
/* To speed up use temp variables instead of using the struct */
LTP_shp_buf = P->sLTP_shp;
LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
sLF_AR_shp = P->sLF_AR_shp;
sLF_MA_shp = P->sLF_MA_shp;
for( i = 0; i < length; i++ ) {
if( lag > 0 ) {
SKP_assert( HARM_SHAPE_FIR_TAPS == 3 );
idx = lag + LTP_shp_buf_idx;
n_LTP = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ];
n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ] * HarmShapeFIR[ 1 ];
n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ];
} else {
n_LTP = 0;
}
n_Tilt = sLF_AR_shp * Tilt;
n_LF = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp;
sLF_AR_shp = st_res[ i ] - n_Tilt;
sLF_MA_shp = sLF_AR_shp - n_LF;
LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp;
xw[ i ] = sLF_MA_shp - n_LTP;
}
/* Copy temp variable back to state */
P->sLF_AR_shp = sLF_AR_shp;
P->sLF_MA_shp = sLF_MA_shp;
P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
}

View File

@ -0,0 +1,106 @@
/***********************************************************************
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, (subject to the limitations in the disclaimer below)
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 Skype Limited, nor the names of specific
contributors, may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#include <stdlib.h>
#include "SKP_Silk_main_FLP.h"
/* Limit, stabilize, convert and quantize NLSFs */
void SKP_Silk_process_NLSFs_FLP(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
SKP_float *pNLSF /* I/O NLSFs (quantized output) */
)
{
SKP_int doInterpolate;
SKP_float pNLSFW[ MAX_LPC_ORDER ];
SKP_float NLSF_mu, NLSF_mu_fluc_red, i_sqr, NLSF_interpolation_factor = 0.0f;
const SKP_Silk_NLSF_CB_FLP *psNLSF_CB_FLP;
/* Used only for NLSF interpolation */
SKP_float pNLSF0_temp[ MAX_LPC_ORDER ];
SKP_float pNLSFW0_temp[ MAX_LPC_ORDER ];
SKP_int i;
SKP_assert( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED || psEncCtrl->sCmn.sigtype == SIG_TYPE_UNVOICED );
/***********************/
/* Calculate mu values */
/***********************/
if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
NLSF_mu = 0.002f - 0.001f * psEnc->speech_activity;
NLSF_mu_fluc_red = 0.1f - 0.05f * psEnc->speech_activity;
} else {
NLSF_mu = 0.005f - 0.004f * psEnc->speech_activity;
NLSF_mu_fluc_red = 0.2f - 0.1f * ( psEnc->speech_activity + psEncCtrl->sparseness );
}
/* Calculate NLSF weights */
SKP_Silk_NLSF_VQ_weights_laroia_FLP( pNLSFW, pNLSF, psEnc->sCmn.predictLPCOrder );
/* Update NLSF weights for interpolated NLSFs */
doInterpolate = ( psEnc->sCmn.useInterpolatedNLSFs == 1 ) && ( psEncCtrl->sCmn.NLSFInterpCoef_Q2 < ( 1 << 2 ) );
if( doInterpolate ) {
/* Calculate the interpolated NLSF vector for the first half */
NLSF_interpolation_factor = 0.25f * psEncCtrl->sCmn.NLSFInterpCoef_Q2;
SKP_Silk_interpolate_wrapper_FLP( pNLSF0_temp, psEnc->sPred.prev_NLSFq, pNLSF,
NLSF_interpolation_factor, psEnc->sCmn.predictLPCOrder );
/* Calculate first half NLSF weights for the interpolated NLSFs */
SKP_Silk_NLSF_VQ_weights_laroia_FLP( pNLSFW0_temp, pNLSF0_temp, psEnc->sCmn.predictLPCOrder );
/* Update NLSF weights with contribution from first half */
i_sqr = NLSF_interpolation_factor * NLSF_interpolation_factor;
for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) {
pNLSFW[ i ] = 0.5f * ( pNLSFW[ i ] + i_sqr * pNLSFW0_temp[ i ] );
}
}
/* Set pointer to the NLSF codebook for the current signal type and LPC order */
psNLSF_CB_FLP = psEnc->psNLSF_CB_FLP[ psEncCtrl->sCmn.sigtype ];
/* Quantize NLSF parameters given the trained NLSF codebooks */
SKP_Silk_NLSF_MSVQ_encode_FLP( psEncCtrl->sCmn.NLSFIndices, pNLSF, psNLSF_CB_FLP, psEnc->sPred.prev_NLSFq, pNLSFW, NLSF_mu,
NLSF_mu_fluc_red, psEnc->sCmn.NLSF_MSVQ_Survivors, psEnc->sCmn.predictLPCOrder, psEnc->sCmn.first_frame_after_reset );
/* Convert quantized NLSFs back to LPC coefficients */
SKP_Silk_NLSF2A_stable_FLP( psEncCtrl->PredCoef[ 1 ], pNLSF, psEnc->sCmn.predictLPCOrder );
if( doInterpolate ) {
/* Calculate the interpolated, quantized NLSF vector for the first half */
SKP_Silk_interpolate_wrapper_FLP( pNLSF0_temp, psEnc->sPred.prev_NLSFq, pNLSF,
NLSF_interpolation_factor, psEnc->sCmn.predictLPCOrder );
/* Convert back to LPC coefficients */
SKP_Silk_NLSF2A_stable_FLP( psEncCtrl->PredCoef[ 0 ], pNLSF0_temp, psEnc->sCmn.predictLPCOrder );
} else {
/* Copy LPC coefficients for first half from second half */
SKP_memcpy( psEncCtrl->PredCoef[ 0 ], psEncCtrl->PredCoef[ 1 ], psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );
}
}

Some files were not shown because too many files have changed in this diff Show More