Added isac WebRtcIsacfix_CalculateResidualEnergy() into dynamic Neon detection for
Android NDK platform. Review URL: https://webrtc-codereview.appspot.com/722009 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2621 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
fd80070aa7
commit
a15ea4965e
@ -46,7 +46,7 @@ int WebRtcIsacfix_EncodeStoredData(ISACFIX_EncInst_t *ISACenc_obj,
|
||||
int BWnumber,
|
||||
float scale);
|
||||
|
||||
/************************** initialization functions *************************/
|
||||
/* initialization functions */
|
||||
|
||||
void WebRtcIsacfix_InitMaskingEnc(MaskFiltstr_enc *maskdata);
|
||||
void WebRtcIsacfix_InitMaskingDec(MaskFiltstr_dec *maskdata);
|
||||
@ -62,7 +62,7 @@ void WebRtcIsacfix_InitPitchAnalysis(PitchAnalysisStruct *State);
|
||||
void WebRtcIsacfix_InitPlc( PLCstr *State );
|
||||
|
||||
|
||||
/**************************** transform functions ****************************/
|
||||
/* transform functions */
|
||||
|
||||
void WebRtcIsacfix_InitTransform();
|
||||
|
||||
@ -82,9 +82,7 @@ void WebRtcIsacfix_Spec2Time(WebRtc_Word16 *inreQ7,
|
||||
|
||||
|
||||
|
||||
/***************************** filterbank functions **************************/
|
||||
|
||||
|
||||
/* filterbank functions */
|
||||
|
||||
void WebRtcIsacfix_SplitAndFilter1(WebRtc_Word16 *in,
|
||||
WebRtc_Word16 *LP16,
|
||||
@ -111,8 +109,7 @@ void WebRtcIsacfix_FilterAndCombine2(WebRtc_Word16 *tempin_ch1,
|
||||
|
||||
#endif
|
||||
|
||||
/************************* normalized lattice filters ************************/
|
||||
|
||||
/* normalized lattice filters */
|
||||
|
||||
void WebRtcIsacfix_NormLatticeFilterMa(WebRtc_Word16 orderCoef,
|
||||
WebRtc_Word32 *stateGQ15,
|
||||
@ -130,6 +127,10 @@ void WebRtcIsacfix_NormLatticeFilterAr(WebRtc_Word16 orderCoef,
|
||||
WebRtc_Word16 lo_hi,
|
||||
WebRtc_Word16 *lat_outQ0);
|
||||
|
||||
/* TODO(kma): Remove the following functions into individual header files. */
|
||||
|
||||
/* Internal functions in both C and ARM Neon versions */
|
||||
|
||||
int WebRtcIsacfix_AutocorrC(WebRtc_Word32* __restrict r,
|
||||
const WebRtc_Word16* __restrict x,
|
||||
WebRtc_Word16 N,
|
||||
@ -143,7 +144,6 @@ void WebRtcIsacfix_FilterMaLoopC(int16_t input0,
|
||||
int32_t* ptr1,
|
||||
int32_t* ptr2);
|
||||
|
||||
// Functions for ARM-Neon platforms, in place of the above two generic C ones.
|
||||
#if (defined WEBRTC_DETECT_ARM_NEON) || (defined WEBRTC_ARCH_ARM_NEON)
|
||||
int WebRtcIsacfix_AutocorrNeon(WebRtc_Word32* __restrict r,
|
||||
const WebRtc_Word16* __restrict x,
|
||||
@ -159,10 +159,7 @@ void WebRtcIsacfix_FilterMaLoopNeon(int16_t input0,
|
||||
int32_t* ptr2);
|
||||
#endif
|
||||
|
||||
/**** Function pointers associated with
|
||||
**** WebRtcIsacfix_AutocorrC() / WebRtcIsacfix_AutocorrNeon()
|
||||
**** and WebRtcIsacfix_FilterMaLoopC() / WebRtcIsacfix_FilterMaLoopNeon().
|
||||
****/
|
||||
/* Function pointers associated with the above functions. */
|
||||
|
||||
typedef int (*AutocorrFix)(WebRtc_Word32* __restrict r,
|
||||
const WebRtc_Word16* __restrict x,
|
||||
@ -179,5 +176,4 @@ typedef void (*FilterMaLoopFix)(int16_t input0,
|
||||
int32_t* ptr2);
|
||||
extern FilterMaLoopFix WebRtcIsacfix_FilterMaLoopFix;
|
||||
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_CODEC_H_ */
|
||||
|
@ -15,15 +15,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isacfix.h"
|
||||
#include "modules/audio_coding/codecs/isac/fix/interface/isacfix.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bandwidth_estimator.h"
|
||||
#include "codec.h"
|
||||
#include "modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h"
|
||||
#include "modules/audio_coding/codecs/isac/fix/source/codec.h"
|
||||
#include "modules/audio_coding/codecs/isac/fix/source/entropy_coding.h"
|
||||
#include "modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
|
||||
#include "modules/audio_coding/codecs/isac/fix/source/structs.h"
|
||||
#include "system_wrappers/interface/cpu_features_wrapper.h"
|
||||
#include "entropy_coding.h"
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
@ -179,6 +180,8 @@ WebRtc_Word16 WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst)
|
||||
static void WebRtcIsacfix_InitNeon(void) {
|
||||
WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrNeon;
|
||||
WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopNeon;
|
||||
WebRtcIsacfix_CalculateResidualEnergy =
|
||||
WebRtcIsacfix_CalculateResidualEnergyNeon;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -263,6 +266,8 @@ WebRtc_Word16 WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
// Initiaze function pointers.
|
||||
WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrC;
|
||||
WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopC;
|
||||
WebRtcIsacfix_CalculateResidualEnergy =
|
||||
WebRtcIsacfix_CalculateResidualEnergyC;
|
||||
|
||||
#ifdef WEBRTC_DETECT_ARM_NEON
|
||||
if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
|
||||
|
@ -97,8 +97,9 @@
|
||||
'<(webrtc_root)/common_audio/common_audio.gyp:signal_processing',
|
||||
],
|
||||
'sources': [
|
||||
'lattice_neon.S',
|
||||
'filters_neon.c',
|
||||
'lattice_neon.S',
|
||||
'lpc_masking_model_neon.S',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -464,19 +464,19 @@ static __inline WebRtc_Word16 exp2_Q10_T(WebRtc_Word16 x) { // Both in and out
|
||||
}
|
||||
|
||||
|
||||
// Declare a function pointer.
|
||||
// Declare function pointers.
|
||||
AutocorrFix WebRtcIsacfix_AutocorrFix;
|
||||
CalculateResidualEnergy WebRtcIsacfix_CalculateResidualEnergy;
|
||||
|
||||
#ifndef WEBRTC_ARCH_ARM_NEON
|
||||
/* This routine calculates the residual energy for LPC.
|
||||
* Formula as shown in comments inside.
|
||||
*/
|
||||
int32_t WebRtcIsacfix_CalculateResidualEnergy(int lpc_order,
|
||||
int32_t q_val_corr,
|
||||
int q_val_polynomial,
|
||||
int16_t* a_polynomial,
|
||||
int32_t* corr_coeffs,
|
||||
int* q_val_residual_energy) {
|
||||
int32_t WebRtcIsacfix_CalculateResidualEnergyC(int lpc_order,
|
||||
int32_t q_val_corr,
|
||||
int q_val_polynomial,
|
||||
int16_t* a_polynomial,
|
||||
int32_t* corr_coeffs,
|
||||
int* q_val_residual_energy) {
|
||||
int i = 0, j = 0;
|
||||
int shift_internal = 0, shift_norm = 0;
|
||||
int32_t tmp32 = 0, word32_high = 0, word32_low = 0, residual_energy = 0;
|
||||
@ -537,7 +537,6 @@ int32_t WebRtcIsacfix_CalculateResidualEnergy(int lpc_order,
|
||||
|
||||
return residual_energy;
|
||||
}
|
||||
#endif
|
||||
|
||||
void WebRtcIsacfix_GetLpcCoef(WebRtc_Word16 *inLoQ0,
|
||||
WebRtc_Word16 *inHiQ0,
|
||||
|
@ -24,13 +24,6 @@ extern "C" {
|
||||
|
||||
#include "structs.h"
|
||||
|
||||
int32_t WebRtcIsacfix_CalculateResidualEnergy(int lpc_order,
|
||||
int32_t q_val_corr,
|
||||
int q_offset,
|
||||
int16_t* a_polynomial,
|
||||
int32_t* corr_coeffs,
|
||||
int* q_val_residual_energy);
|
||||
|
||||
void WebRtcIsacfix_GetVars(const WebRtc_Word16 *input,
|
||||
const WebRtc_Word16 *pitchGains_Q12,
|
||||
WebRtc_UWord32 *oldEnergy,
|
||||
@ -45,6 +38,30 @@ void WebRtcIsacfix_GetLpcCoef(WebRtc_Word16 *inLoQ0,
|
||||
WebRtc_Word16 *lo_coeffQ15,
|
||||
WebRtc_Word16 *hi_coeffQ15);
|
||||
|
||||
typedef int32_t (*CalculateResidualEnergy)(int lpc_order,
|
||||
int32_t q_val_corr,
|
||||
int q_val_polynomial,
|
||||
int16_t* a_polynomial,
|
||||
int32_t* corr_coeffs,
|
||||
int* q_val_residual_energy);
|
||||
extern CalculateResidualEnergy WebRtcIsacfix_CalculateResidualEnergy;
|
||||
|
||||
int32_t WebRtcIsacfix_CalculateResidualEnergyC(int lpc_order,
|
||||
int32_t q_val_corr,
|
||||
int q_val_polynomial,
|
||||
int16_t* a_polynomial,
|
||||
int32_t* corr_coeffs,
|
||||
int* q_val_residual_energy);
|
||||
|
||||
#if (defined WEBRTC_DETECT_ARM_NEON) || (defined WEBRTC_ARCH_ARM_NEON)
|
||||
int32_t WebRtcIsacfix_CalculateResidualEnergyNeon(int lpc_order,
|
||||
int32_t q_val_corr,
|
||||
int q_val_polynomial,
|
||||
int16_t* a_polynomial,
|
||||
int32_t* corr_coeffs,
|
||||
int* q_val_residual_energy);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -8,23 +8,23 @@
|
||||
@ be found in the AUTHORS file in the root of the source tree.
|
||||
@
|
||||
|
||||
@ Contains a function for WebRtcIsacfix_CalculateResidualEnergy() in
|
||||
@ Contains a function for WebRtcIsacfix_CalculateResidualEnergyNeon() in
|
||||
@ iSAC codec, optimized for ARM Neon platform. Reference code in
|
||||
@ lpc_masking_model.c.
|
||||
|
||||
.arch armv7-a
|
||||
.fpu neon
|
||||
.global WebRtcIsacfix_CalculateResidualEnergy
|
||||
.global WebRtcIsacfix_CalculateResidualEnergyNeon
|
||||
.align 2
|
||||
|
||||
@ int32_t WebRtcIsacfix_CalculateResidualEnergy(int lpc_order,
|
||||
@ int32_t q_val_corr,
|
||||
@ int q_val_polynomial,
|
||||
@ int16_t* a_polynomial,
|
||||
@ int32_t* corr_coeffs,
|
||||
@ int* q_val_residual_energy);
|
||||
@ int32_t WebRtcIsacfix_CalculateResidualEnergyNeon(int lpc_order,
|
||||
@ int32_t q_val_corr,
|
||||
@ int q_val_polynomial,
|
||||
@ int16_t* a_polynomial,
|
||||
@ int32_t* corr_coeffs,
|
||||
@ int* q_val_residual_energy);
|
||||
|
||||
WebRtcIsacfix_CalculateResidualEnergy:
|
||||
WebRtcIsacfix_CalculateResidualEnergyNeon:
|
||||
.fnstart
|
||||
.save {r4-r11}
|
||||
push {r4-r11}
|
||||
|
@ -11,44 +11,58 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
|
||||
#include "system_wrappers/interface/cpu_features_wrapper.h"
|
||||
|
||||
class IsacUnitTest : public testing::Test {
|
||||
protected:
|
||||
// Pass a function pointer to the Tester function.
|
||||
void CalculateResidualEnergyTester(CalculateResidualEnergy
|
||||
CalculateResidualEnergyFunction) {
|
||||
const int kIntOrder = 10;
|
||||
const int32_t kInt32QDomain = 5;
|
||||
const int kIntShift = 11;
|
||||
int16_t a[kIntOrder + 1] = {32760, 122, 7, 0, -32760, -3958,
|
||||
-48, 18745, 498, 9, 23456};
|
||||
int32_t corr[kIntOrder + 1] = {11443647, -27495, 0,
|
||||
98745, -11443600, 1, 1, 498, 9, 888, 23456};
|
||||
int q_shift_residual = 0;
|
||||
int32_t residual_energy = 0;
|
||||
|
||||
// Test the code path where (residual_energy >= 0x10000).
|
||||
residual_energy = CalculateResidualEnergyFunction(kIntOrder,
|
||||
kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
|
||||
EXPECT_EQ(1789023310, residual_energy);
|
||||
EXPECT_EQ(2, q_shift_residual);
|
||||
|
||||
// Test the code path where (residual_energy < 0x10000)
|
||||
// and ((energy & 0x8000) != 0).
|
||||
for(int i = 0; i < kIntOrder + 1; i++) {
|
||||
a[i] = 24575 >> i;
|
||||
corr[i] = i;
|
||||
}
|
||||
residual_energy = CalculateResidualEnergyFunction(kIntOrder,
|
||||
kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
|
||||
EXPECT_EQ(1595279092, residual_energy);
|
||||
EXPECT_EQ(26, q_shift_residual);
|
||||
|
||||
// Test the code path where (residual_energy <= 0x7fff).
|
||||
for(int i = 0; i < kIntOrder + 1; i++) {
|
||||
a[i] = 2457 >> i;
|
||||
}
|
||||
residual_energy = CalculateResidualEnergyFunction(kIntOrder,
|
||||
kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
|
||||
EXPECT_EQ(2029266944, residual_energy);
|
||||
EXPECT_EQ(33, q_shift_residual);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(IsacUnitTest, CalculateResidualEnergyTest) {
|
||||
const int kIntOrder = 10;
|
||||
const int32_t kInt32QDomain = 5;
|
||||
const int kIntShift = 11;
|
||||
int16_t a[kIntOrder + 1] = {32760, 122, 7, 0, -32760, -3958,
|
||||
-48, 18745, 498, 9, 23456};
|
||||
int32_t corr[kIntOrder + 1] = {11443647, -27495, 0,
|
||||
98745, -11443600, 1, 1, 498, 9, 888, 23456};
|
||||
int q_shift_residual = 0;
|
||||
int32_t residual_energy = 0;
|
||||
|
||||
// Test the code path where (residual_energy >= 0x10000).
|
||||
residual_energy = WebRtcIsacfix_CalculateResidualEnergy(kIntOrder,
|
||||
kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
|
||||
EXPECT_EQ(1789023310, residual_energy);
|
||||
EXPECT_EQ(2, q_shift_residual);
|
||||
|
||||
// Test the code path where (residual_energy < 0x10000)
|
||||
// and ((energy & 0x8000) != 0).
|
||||
for(int i = 0; i < kIntOrder + 1; i++) {
|
||||
a[i] = 24575 >> i;
|
||||
corr[i] = i;
|
||||
CalculateResidualEnergyTester(WebRtcIsacfix_CalculateResidualEnergyC);
|
||||
#ifdef WEBRTC_DETECT_ARM_NEON
|
||||
if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
|
||||
CalculateResidualEnergyTester(WebRtcIsacfix_CalculateResidualEnergyNeon);
|
||||
}
|
||||
residual_energy = WebRtcIsacfix_CalculateResidualEnergy(kIntOrder,
|
||||
kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
|
||||
EXPECT_EQ(1595279092, residual_energy);
|
||||
EXPECT_EQ(26, q_shift_residual);
|
||||
|
||||
// Test the code path where (residual_energy <= 0x7fff).
|
||||
for(int i = 0; i < kIntOrder + 1; i++) {
|
||||
a[i] = 2457 >> i;
|
||||
}
|
||||
residual_energy = WebRtcIsacfix_CalculateResidualEnergy(kIntOrder,
|
||||
kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
|
||||
EXPECT_EQ(2029266944, residual_energy);
|
||||
EXPECT_EQ(33, q_shift_residual);
|
||||
#elif defined(WEBRTC_ARCH_ARM_NEON)
|
||||
CalculateResidualEnergyTester(WebRtcIsacfix_CalculateResidualEnergyNeon);
|
||||
#endif
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user