mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-27 19:07:31 +09:00
parent
b188579bb6
commit
a8b1099a1e
228 changed files with 10990 additions and 5670 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2014, Cisco Systems, INC
|
||||
Written by XiangMingZhu WeiZhou MinPeng YanWang
|
||||
/* Copyright (c) 2014-2020, Cisco Systems, INC
|
||||
Written by XiangMingZhu WeiZhou MinPeng YanWang FrancisQuiers
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
|
||||
|
||||
#define QA 25
|
||||
#define N_BITS_HEAD_ROOM 2
|
||||
#define N_BITS_HEAD_ROOM 3
|
||||
#define MIN_RSHIFTS -16
|
||||
#define MAX_RSHIFTS (32 - QA)
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ void silk_burg_modified_sse4_1(
|
|||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain;
|
||||
opus_int k, n, s, lz, rshifts, reached_max_gain;
|
||||
opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
|
||||
const opus_int16 *x_ptr;
|
||||
opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
|
||||
|
|
@ -68,30 +68,26 @@ void silk_burg_modified_sse4_1(
|
|||
opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
|
||||
opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
|
||||
opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int64 C0_64;
|
||||
|
||||
__m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210;
|
||||
__m128i CONST1 = _mm_set1_epi32(1);
|
||||
|
||||
silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||
celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||
|
||||
/* Compute autocorrelations, added over subframes */
|
||||
silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
|
||||
if( rshifts > MAX_RSHIFTS ) {
|
||||
C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS );
|
||||
silk_assert( C0 > 0 );
|
||||
rshifts = MAX_RSHIFTS;
|
||||
C0_64 = silk_inner_prod16( x, x, subfr_length*nb_subfr, arch );
|
||||
lz = silk_CLZ64(C0_64);
|
||||
rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz;
|
||||
if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS;
|
||||
if (rshifts < MIN_RSHIFTS) rshifts = MIN_RSHIFTS;
|
||||
|
||||
if (rshifts > 0) {
|
||||
C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts );
|
||||
} else {
|
||||
lz = silk_CLZ32( C0 ) - 1;
|
||||
rshifts_extra = N_BITS_HEAD_ROOM - lz;
|
||||
if( rshifts_extra > 0 ) {
|
||||
rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts );
|
||||
C0 = silk_RSHIFT32( C0, rshifts_extra );
|
||||
} else {
|
||||
rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts );
|
||||
C0 = silk_LSHIFT32( C0, -rshifts_extra );
|
||||
}
|
||||
rshifts += rshifts_extra;
|
||||
C0 = silk_LSHIFT32((opus_int32)C0_64, -rshifts );
|
||||
}
|
||||
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||
silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
||||
if( rshifts > 0 ) {
|
||||
|
|
@ -99,7 +95,7 @@ void silk_burg_modified_sse4_1(
|
|||
x_ptr = x + s * subfr_length;
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(
|
||||
silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );
|
||||
silk_inner_prod16( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -203,8 +199,11 @@ void silk_burg_modified_sse4_1(
|
|||
C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
|
||||
C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
|
||||
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */
|
||||
tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
|
||||
tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
|
||||
/* We sometimes get overflows in the multiplications (even beyond +/- 2^32),
|
||||
but they cancel each other and the real result seems to always fit in a 32-bit
|
||||
signed integer. This was determined experimentally, not theoretically (unfortunately). */
|
||||
tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
|
||||
tmp2 = silk_MLA_ovflw( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
|
||||
}
|
||||
|
||||
tmp1 = -tmp1; /* Q17 */
|
||||
|
|
@ -350,7 +349,7 @@ void silk_burg_modified_sse4_1(
|
|||
if( rshifts > 0 ) {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );
|
||||
C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16( x_ptr, x_ptr, D, arch ), rshifts );
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
|
|
@ -374,4 +373,28 @@ void silk_burg_modified_sse4_1(
|
|||
*res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
|
||||
*res_nrg_Q = -rshifts;
|
||||
}
|
||||
|
||||
#ifdef OPUS_CHECK_ASM
|
||||
{
|
||||
opus_int32 res_nrg_c = 0;
|
||||
opus_int res_nrg_Q_c = 0;
|
||||
opus_int32 A_Q16_c[ MAX_LPC_ORDER ] = {0};
|
||||
|
||||
silk_burg_modified_c(
|
||||
&res_nrg_c,
|
||||
&res_nrg_Q_c,
|
||||
A_Q16_c,
|
||||
x,
|
||||
minInvGain_Q30,
|
||||
subfr_length,
|
||||
nb_subfr,
|
||||
D,
|
||||
0
|
||||
);
|
||||
|
||||
silk_assert( *res_nrg == res_nrg_c );
|
||||
silk_assert( *res_nrg_Q == res_nrg_Q_c );
|
||||
silk_assert( !memcmp( A_Q16, A_Q16_c, D * sizeof( *A_Q16 ) ) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
/* Copyright (c) 2014, Cisco Systems, INC
|
||||
Written by XiangMingZhu WeiZhou MinPeng YanWang
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <smmintrin.h>
|
||||
#include "main.h"
|
||||
#include "celt/x86/x86cpu.h"
|
||||
|
||||
void silk_warped_LPC_analysis_filter_FIX_sse4_1(
|
||||
opus_int32 state[], /* I/O State [order + 1] */
|
||||
opus_int32 res_Q2[], /* O Residual signal [length] */
|
||||
const opus_int16 coef_Q13[], /* I Coefficients [order] */
|
||||
const opus_int16 input[], /* I Input signal [length] */
|
||||
const opus_int16 lambda_Q16, /* I Warping factor */
|
||||
const opus_int length, /* I Length of input signal */
|
||||
const opus_int order /* I Filter order (even) */
|
||||
)
|
||||
{
|
||||
opus_int n, i;
|
||||
opus_int32 acc_Q11, tmp1, tmp2;
|
||||
|
||||
/* Order must be even */
|
||||
silk_assert( ( order & 1 ) == 0 );
|
||||
|
||||
if (order == 10)
|
||||
{
|
||||
if (0 == lambda_Q16)
|
||||
{
|
||||
__m128i coef_Q13_3210, coef_Q13_7654;
|
||||
__m128i coef_Q13_0123, coef_Q13_4567;
|
||||
__m128i state_0123, state_4567;
|
||||
__m128i xmm_product1, xmm_product2;
|
||||
__m128i xmm_tempa, xmm_tempb;
|
||||
|
||||
register opus_int32 sum;
|
||||
register opus_int32 state_8, state_9, state_a;
|
||||
register opus_int64 coef_Q13_8, coef_Q13_9;
|
||||
|
||||
silk_assert( length > 0 );
|
||||
|
||||
coef_Q13_3210 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 0 ] );
|
||||
coef_Q13_7654 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 4 ] );
|
||||
|
||||
coef_Q13_0123 = _mm_shuffle_epi32( coef_Q13_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
coef_Q13_4567 = _mm_shuffle_epi32( coef_Q13_7654, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
|
||||
coef_Q13_8 = (opus_int64) coef_Q13[ 8 ];
|
||||
coef_Q13_9 = (opus_int64) coef_Q13[ 9 ];
|
||||
|
||||
state_0123 = _mm_loadu_si128( (__m128i *)(&state[ 0 ] ) );
|
||||
state_4567 = _mm_loadu_si128( (__m128i *)(&state[ 4 ] ) );
|
||||
|
||||
state_0123 = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
state_4567 = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
|
||||
state_8 = state[ 8 ];
|
||||
state_9 = state[ 9 ];
|
||||
state_a = 0;
|
||||
|
||||
for( n = 0; n < length; n++ )
|
||||
{
|
||||
xmm_product1 = _mm_mul_epi32( coef_Q13_0123, state_0123 ); /* 64-bit multiply, only 2 pairs */
|
||||
xmm_product2 = _mm_mul_epi32( coef_Q13_4567, state_4567 );
|
||||
|
||||
xmm_tempa = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
xmm_tempb = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
|
||||
xmm_product1 = _mm_srli_epi64( xmm_product1, 16 ); /* >> 16, zero extending works */
|
||||
xmm_product2 = _mm_srli_epi64( xmm_product2, 16 );
|
||||
|
||||
xmm_tempa = _mm_mul_epi32( coef_Q13_3210, xmm_tempa );
|
||||
xmm_tempb = _mm_mul_epi32( coef_Q13_7654, xmm_tempb );
|
||||
|
||||
xmm_tempa = _mm_srli_epi64( xmm_tempa, 16 );
|
||||
xmm_tempb = _mm_srli_epi64( xmm_tempb, 16 );
|
||||
|
||||
xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_product1 );
|
||||
xmm_tempb = _mm_add_epi32( xmm_tempb, xmm_product2 );
|
||||
xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_tempb );
|
||||
|
||||
sum = (coef_Q13_8 * state_8) >> 16;
|
||||
sum += (coef_Q13_9 * state_9) >> 16;
|
||||
|
||||
xmm_tempa = _mm_add_epi32( xmm_tempa, _mm_shuffle_epi32( xmm_tempa, _MM_SHUFFLE( 0, 0, 0, 2 ) ) );
|
||||
sum += _mm_cvtsi128_si32( xmm_tempa);
|
||||
res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( ( 5 + sum ), 9);
|
||||
|
||||
/* move right */
|
||||
state_a = state_9;
|
||||
state_9 = state_8;
|
||||
state_8 = _mm_cvtsi128_si32( state_4567 );
|
||||
state_4567 = _mm_alignr_epi8( state_0123, state_4567, 4 );
|
||||
|
||||
state_0123 = _mm_alignr_epi8( _mm_cvtsi32_si128( silk_LSHIFT( input[ n ], 14 ) ), state_0123, 4 );
|
||||
}
|
||||
|
||||
_mm_storeu_si128( (__m128i *)( &state[ 0 ] ), _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );
|
||||
_mm_storeu_si128( (__m128i *)( &state[ 4 ] ), _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );
|
||||
state[ 8 ] = state_8;
|
||||
state[ 9 ] = state_9;
|
||||
state[ 10 ] = state_a;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for( n = 0; n < length; n++ ) {
|
||||
/* Output of lowpass section */
|
||||
tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
|
||||
state[ 0 ] = silk_LSHIFT( input[ n ], 14 );
|
||||
/* Output of allpass section */
|
||||
tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
|
||||
state[ 1 ] = tmp2;
|
||||
acc_Q11 = silk_RSHIFT( order, 1 );
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
|
||||
/* Loop over allpass sections */
|
||||
for( i = 2; i < order; i += 2 ) {
|
||||
/* Output of allpass section */
|
||||
tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
|
||||
state[ i ] = tmp1;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
|
||||
/* Output of allpass section */
|
||||
tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
|
||||
state[ i + 1 ] = tmp2;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
|
||||
}
|
||||
state[ order ] = tmp1;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
|
||||
res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
|
||||
}
|
||||
}
|
||||
|
|
@ -37,39 +37,36 @@
|
|||
#include "SigProc_FIX.h"
|
||||
#include "pitch.h"
|
||||
|
||||
opus_int64 silk_inner_prod16_aligned_64_sse4_1(
|
||||
opus_int64 silk_inner_prod16_sse4_1(
|
||||
const opus_int16 *inVec1, /* I input vector 1 */
|
||||
const opus_int16 *inVec2, /* I input vector 2 */
|
||||
const opus_int len /* I vector lengths */
|
||||
)
|
||||
{
|
||||
opus_int i, dataSize8;
|
||||
opus_int i, dataSize4;
|
||||
opus_int64 sum;
|
||||
|
||||
__m128i xmm_tempa;
|
||||
__m128i inVec1_76543210, acc1;
|
||||
__m128i inVec2_76543210, acc2;
|
||||
__m128i xmm_prod_20, xmm_prod_31;
|
||||
__m128i inVec1_3210, acc1;
|
||||
__m128i inVec2_3210, acc2;
|
||||
|
||||
sum = 0;
|
||||
dataSize8 = len & ~7;
|
||||
dataSize4 = len & ~3;
|
||||
|
||||
acc1 = _mm_setzero_si128();
|
||||
acc2 = _mm_setzero_si128();
|
||||
|
||||
for( i = 0; i < dataSize8; i += 8 ) {
|
||||
inVec1_76543210 = _mm_loadu_si128( (__m128i *)(&inVec1[i + 0] ) );
|
||||
inVec2_76543210 = _mm_loadu_si128( (__m128i *)(&inVec2[i + 0] ) );
|
||||
for( i = 0; i < dataSize4; i += 4 ) {
|
||||
inVec1_3210 = OP_CVTEPI16_EPI32_M64( &inVec1[i + 0] );
|
||||
inVec2_3210 = OP_CVTEPI16_EPI32_M64( &inVec2[i + 0] );
|
||||
xmm_prod_20 = _mm_mul_epi32( inVec1_3210, inVec2_3210 );
|
||||
|
||||
/* only when all 4 operands are -32768 (0x8000), this results in wrap around */
|
||||
inVec1_76543210 = _mm_madd_epi16( inVec1_76543210, inVec2_76543210 );
|
||||
inVec1_3210 = _mm_shuffle_epi32( inVec1_3210, _MM_SHUFFLE( 0, 3, 2, 1 ) );
|
||||
inVec2_3210 = _mm_shuffle_epi32( inVec2_3210, _MM_SHUFFLE( 0, 3, 2, 1 ) );
|
||||
xmm_prod_31 = _mm_mul_epi32( inVec1_3210, inVec2_3210 );
|
||||
|
||||
xmm_tempa = _mm_cvtepi32_epi64( inVec1_76543210 );
|
||||
/* equal shift right 8 bytes */
|
||||
inVec1_76543210 = _mm_shuffle_epi32( inVec1_76543210, _MM_SHUFFLE( 0, 0, 3, 2 ) );
|
||||
inVec1_76543210 = _mm_cvtepi32_epi64( inVec1_76543210 );
|
||||
|
||||
acc1 = _mm_add_epi64( acc1, xmm_tempa );
|
||||
acc2 = _mm_add_epi64( acc2, inVec1_76543210 );
|
||||
acc1 = _mm_add_epi64( acc1, xmm_prod_20 );
|
||||
acc2 = _mm_add_epi64( acc2, xmm_prod_31 );
|
||||
}
|
||||
|
||||
acc1 = _mm_add_epi64( acc1, acc2 );
|
||||
|
|
@ -84,5 +81,12 @@ opus_int64 silk_inner_prod16_aligned_64_sse4_1(
|
|||
sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
|
||||
}
|
||||
|
||||
#ifdef OPUS_CHECK_ASM
|
||||
{
|
||||
opus_int64 sum_c = silk_inner_prod16_c( inVec1, inVec2, len );
|
||||
silk_assert( sum == sum_c );
|
||||
}
|
||||
#endif
|
||||
|
||||
return sum;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue