mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-28 04:25:18 +00:00
d83a3d71bc
Merge in RedPhone // FREEBIE
170 lines
9.9 KiB
C
170 lines
9.9 KiB
C
/*
|
|
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
|
|
|
// Version of WebRtcSpl_DownsampleFast() for MIPS platforms.
|
|
int WebRtcSpl_DownsampleFast_mips(const int16_t* data_in,
|
|
int data_in_length,
|
|
int16_t* data_out,
|
|
int data_out_length,
|
|
const int16_t* __restrict coefficients,
|
|
int coefficients_length,
|
|
int factor,
|
|
int delay) {
|
|
int i;
|
|
int j;
|
|
int k;
|
|
int32_t out_s32 = 0;
|
|
int endpos = delay + factor * (data_out_length - 1) + 1;
|
|
|
|
int32_t tmp1, tmp2, tmp3, tmp4, factor_2;
|
|
int16_t* p_coefficients;
|
|
int16_t* p_data_in;
|
|
int16_t* p_data_in_0 = (int16_t*)&data_in[delay];
|
|
int16_t* p_coefficients_0 = (int16_t*)&coefficients[0];
|
|
#if !defined(MIPS_DSP_R1_LE)
|
|
int32_t max_16 = 0x7FFF;
|
|
int32_t min_16 = 0xFFFF8000;
|
|
#endif // #if !defined(MIPS_DSP_R1_LE)
|
|
|
|
// Return error if any of the running conditions doesn't meet.
|
|
if (data_out_length <= 0 || coefficients_length <= 0
|
|
|| data_in_length < endpos) {
|
|
return -1;
|
|
}
|
|
#if defined(MIPS_DSP_R2_LE)
|
|
__asm __volatile (
|
|
".set push \n\t"
|
|
".set noreorder \n\t"
|
|
"subu %[i], %[endpos], %[delay] \n\t"
|
|
"sll %[factor_2], %[factor], 1 \n\t"
|
|
"1: \n\t"
|
|
"move %[p_data_in], %[p_data_in_0] \n\t"
|
|
"mult $zero, $zero \n\t"
|
|
"move %[p_coefs], %[p_coefs_0] \n\t"
|
|
"sra %[j], %[coef_length], 2 \n\t"
|
|
"beq %[j], $zero, 3f \n\t"
|
|
" andi %[k], %[coef_length], 3 \n\t"
|
|
"2: \n\t"
|
|
"lwl %[tmp1], 1(%[p_data_in]) \n\t"
|
|
"lwl %[tmp2], 3(%[p_coefs]) \n\t"
|
|
"lwl %[tmp3], -3(%[p_data_in]) \n\t"
|
|
"lwl %[tmp4], 7(%[p_coefs]) \n\t"
|
|
"lwr %[tmp1], -2(%[p_data_in]) \n\t"
|
|
"lwr %[tmp2], 0(%[p_coefs]) \n\t"
|
|
"lwr %[tmp3], -6(%[p_data_in]) \n\t"
|
|
"lwr %[tmp4], 4(%[p_coefs]) \n\t"
|
|
"packrl.ph %[tmp1], %[tmp1], %[tmp1] \n\t"
|
|
"packrl.ph %[tmp3], %[tmp3], %[tmp3] \n\t"
|
|
"dpa.w.ph $ac0, %[tmp1], %[tmp2] \n\t"
|
|
"dpa.w.ph $ac0, %[tmp3], %[tmp4] \n\t"
|
|
"addiu %[j], %[j], -1 \n\t"
|
|
"addiu %[p_data_in], %[p_data_in], -8 \n\t"
|
|
"bgtz %[j], 2b \n\t"
|
|
" addiu %[p_coefs], %[p_coefs], 8 \n\t"
|
|
"3: \n\t"
|
|
"beq %[k], $zero, 5f \n\t"
|
|
" nop \n\t"
|
|
"4: \n\t"
|
|
"lhu %[tmp1], 0(%[p_data_in]) \n\t"
|
|
"lhu %[tmp2], 0(%[p_coefs]) \n\t"
|
|
"addiu %[p_data_in], %[p_data_in], -2 \n\t"
|
|
"addiu %[k], %[k], -1 \n\t"
|
|
"dpa.w.ph $ac0, %[tmp1], %[tmp2] \n\t"
|
|
"bgtz %[k], 4b \n\t"
|
|
" addiu %[p_coefs], %[p_coefs], 2 \n\t"
|
|
"5: \n\t"
|
|
"extr_r.w %[out_s32], $ac0, 12 \n\t"
|
|
"addu %[p_data_in_0], %[p_data_in_0], %[factor_2] \n\t"
|
|
"subu %[i], %[i], %[factor] \n\t"
|
|
"shll_s.w %[out_s32], %[out_s32], 16 \n\t"
|
|
"sra %[out_s32], %[out_s32], 16 \n\t"
|
|
"sh %[out_s32], 0(%[data_out]) \n\t"
|
|
"bgtz %[i], 1b \n\t"
|
|
" addiu %[data_out], %[data_out], 2 \n\t"
|
|
".set pop \n\t"
|
|
: [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
|
|
[tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in),
|
|
[p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients),
|
|
[j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2),
|
|
[i] "=&r" (i), [k] "=&r" (k)
|
|
: [coef_length] "r" (coefficients_length), [data_out] "r" (data_out),
|
|
[p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos),
|
|
[delay] "r" (delay), [factor] "r" (factor)
|
|
: "memory", "hi", "lo"
|
|
);
|
|
#else // #if defined(MIPS_DSP_R2_LE)
|
|
__asm __volatile (
|
|
".set push \n\t"
|
|
".set noreorder \n\t"
|
|
"sll %[factor_2], %[factor], 1 \n\t"
|
|
"subu %[i], %[endpos], %[delay] \n\t"
|
|
"1: \n\t"
|
|
"move %[p_data_in], %[p_data_in_0] \n\t"
|
|
"addiu %[out_s32], $zero, 2048 \n\t"
|
|
"move %[p_coefs], %[p_coefs_0] \n\t"
|
|
"sra %[j], %[coef_length], 1 \n\t"
|
|
"beq %[j], $zero, 3f \n\t"
|
|
" andi %[k], %[coef_length], 1 \n\t"
|
|
"2: \n\t"
|
|
"lh %[tmp1], 0(%[p_data_in]) \n\t"
|
|
"lh %[tmp2], 0(%[p_coefs]) \n\t"
|
|
"lh %[tmp3], -2(%[p_data_in]) \n\t"
|
|
"lh %[tmp4], 2(%[p_coefs]) \n\t"
|
|
"mul %[tmp1], %[tmp1], %[tmp2] \n\t"
|
|
"addiu %[p_coefs], %[p_coefs], 4 \n\t"
|
|
"mul %[tmp3], %[tmp3], %[tmp4] \n\t"
|
|
"addiu %[j], %[j], -1 \n\t"
|
|
"addiu %[p_data_in], %[p_data_in], -4 \n\t"
|
|
"addu %[tmp1], %[tmp1], %[tmp3] \n\t"
|
|
"bgtz %[j], 2b \n\t"
|
|
" addu %[out_s32], %[out_s32], %[tmp1] \n\t"
|
|
"3: \n\t"
|
|
"beq %[k], $zero, 4f \n\t"
|
|
" nop \n\t"
|
|
"lh %[tmp1], 0(%[p_data_in]) \n\t"
|
|
"lh %[tmp2], 0(%[p_coefs]) \n\t"
|
|
"mul %[tmp1], %[tmp1], %[tmp2] \n\t"
|
|
"addu %[out_s32], %[out_s32], %[tmp1] \n\t"
|
|
"4: \n\t"
|
|
"sra %[out_s32], %[out_s32], 12 \n\t"
|
|
"addu %[p_data_in_0], %[p_data_in_0], %[factor_2] \n\t"
|
|
#if defined(MIPS_DSP_R1_LE)
|
|
"shll_s.w %[out_s32], %[out_s32], 16 \n\t"
|
|
"sra %[out_s32], %[out_s32], 16 \n\t"
|
|
#else // #if defined(MIPS_DSP_R1_LE)
|
|
"slt %[tmp1], %[max_16], %[out_s32] \n\t"
|
|
"movn %[out_s32], %[max_16], %[tmp1] \n\t"
|
|
"slt %[tmp1], %[out_s32], %[min_16] \n\t"
|
|
"movn %[out_s32], %[min_16], %[tmp1] \n\t"
|
|
#endif // #if defined(MIPS_DSP_R1_LE)
|
|
"subu %[i], %[i], %[factor] \n\t"
|
|
"sh %[out_s32], 0(%[data_out]) \n\t"
|
|
"bgtz %[i], 1b \n\t"
|
|
" addiu %[data_out], %[data_out], 2 \n\t"
|
|
".set pop \n\t"
|
|
: [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
|
|
[tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in), [k] "=&r" (k),
|
|
[p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients),
|
|
[j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2),
|
|
[i] "=&r" (i)
|
|
: [coef_length] "r" (coefficients_length), [data_out] "r" (data_out),
|
|
[p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos),
|
|
#if !defined(MIPS_DSP_R1_LE)
|
|
[max_16] "r" (max_16), [min_16] "r" (min_16),
|
|
#endif // #if !defined(MIPS_DSP_R1_LE)
|
|
[delay] "r" (delay), [factor] "r" (factor)
|
|
: "memory", "hi", "lo"
|
|
);
|
|
#endif // #if defined(MIPS_DSP_R2_LE)
|
|
return 0;
|
|
}
|