mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-30 21:45:20 +00:00
d83a3d71bc
Merge in RedPhone // FREEBIE
323 lines
19 KiB
C
323 lines
19 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/complex_fft_tables.h"
|
|
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
|
|
|
#define CFFTSFT 14
|
|
#define CFFTRND 1
|
|
#define CFFTRND2 16384
|
|
|
|
#define CIFFTSFT 14
|
|
#define CIFFTRND 1
|
|
|
|
int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode) {
|
|
int i = 0;
|
|
int l = 0;
|
|
int k = 0;
|
|
int istep = 0;
|
|
int n = 0;
|
|
int m = 0;
|
|
int32_t wr = 0, wi = 0;
|
|
int32_t tmp1 = 0;
|
|
int32_t tmp2 = 0;
|
|
int32_t tmp3 = 0;
|
|
int32_t tmp4 = 0;
|
|
int32_t tmp5 = 0;
|
|
int32_t tmp6 = 0;
|
|
int32_t tmp = 0;
|
|
int16_t* ptr_j = NULL;
|
|
int16_t* ptr_i = NULL;
|
|
|
|
n = 1 << stages;
|
|
if (n > 1024) {
|
|
return -1;
|
|
}
|
|
|
|
__asm __volatile (
|
|
".set push \n\t"
|
|
".set noreorder \n\t"
|
|
|
|
"addiu %[k], $zero, 10 \n\t"
|
|
"addiu %[l], $zero, 1 \n\t"
|
|
"3: \n\t"
|
|
"sll %[istep], %[l], 1 \n\t"
|
|
"move %[m], $zero \n\t"
|
|
"sll %[tmp], %[l], 2 \n\t"
|
|
"move %[i], $zero \n\t"
|
|
"2: \n\t"
|
|
#if defined(MIPS_DSP_R1_LE)
|
|
"sllv %[tmp3], %[m], %[k] \n\t"
|
|
"addiu %[tmp2], %[tmp3], 512 \n\t"
|
|
"addiu %[m], %[m], 1 \n\t"
|
|
"lhx %[wi], %[tmp3](%[kSinTable1024]) \n\t"
|
|
"lhx %[wr], %[tmp2](%[kSinTable1024]) \n\t"
|
|
#else // #if defined(MIPS_DSP_R1_LE)
|
|
"sllv %[tmp3], %[m], %[k] \n\t"
|
|
"addu %[ptr_j], %[tmp3], %[kSinTable1024] \n\t"
|
|
"addiu %[ptr_i], %[ptr_j], 512 \n\t"
|
|
"addiu %[m], %[m], 1 \n\t"
|
|
"lh %[wi], 0(%[ptr_j]) \n\t"
|
|
"lh %[wr], 0(%[ptr_i]) \n\t"
|
|
#endif // #if defined(MIPS_DSP_R1_LE)
|
|
"1: \n\t"
|
|
"sll %[tmp1], %[i], 2 \n\t"
|
|
"addu %[ptr_i], %[frfi], %[tmp1] \n\t"
|
|
"addu %[ptr_j], %[ptr_i], %[tmp] \n\t"
|
|
"lh %[tmp6], 0(%[ptr_i]) \n\t"
|
|
"lh %[tmp5], 2(%[ptr_i]) \n\t"
|
|
"lh %[tmp3], 0(%[ptr_j]) \n\t"
|
|
"lh %[tmp4], 2(%[ptr_j]) \n\t"
|
|
"addu %[i], %[i], %[istep] \n\t"
|
|
#if defined(MIPS_DSP_R2_LE)
|
|
"mult %[wr], %[tmp3] \n\t"
|
|
"madd %[wi], %[tmp4] \n\t"
|
|
"mult $ac1, %[wr], %[tmp4] \n\t"
|
|
"msub $ac1, %[wi], %[tmp3] \n\t"
|
|
"mflo %[tmp1] \n\t"
|
|
"mflo %[tmp2], $ac1 \n\t"
|
|
"sll %[tmp6], %[tmp6], 14 \n\t"
|
|
"sll %[tmp5], %[tmp5], 14 \n\t"
|
|
"shra_r.w %[tmp1], %[tmp1], 1 \n\t"
|
|
"shra_r.w %[tmp2], %[tmp2], 1 \n\t"
|
|
"subu %[tmp4], %[tmp6], %[tmp1] \n\t"
|
|
"addu %[tmp1], %[tmp6], %[tmp1] \n\t"
|
|
"addu %[tmp6], %[tmp5], %[tmp2] \n\t"
|
|
"subu %[tmp5], %[tmp5], %[tmp2] \n\t"
|
|
"shra_r.w %[tmp1], %[tmp1], 15 \n\t"
|
|
"shra_r.w %[tmp6], %[tmp6], 15 \n\t"
|
|
"shra_r.w %[tmp4], %[tmp4], 15 \n\t"
|
|
"shra_r.w %[tmp5], %[tmp5], 15 \n\t"
|
|
#else // #if defined(MIPS_DSP_R2_LE)
|
|
"mul %[tmp2], %[wr], %[tmp4] \n\t"
|
|
"mul %[tmp1], %[wr], %[tmp3] \n\t"
|
|
"mul %[tmp4], %[wi], %[tmp4] \n\t"
|
|
"mul %[tmp3], %[wi], %[tmp3] \n\t"
|
|
"sll %[tmp6], %[tmp6], 14 \n\t"
|
|
"sll %[tmp5], %[tmp5], 14 \n\t"
|
|
"addiu %[tmp6], %[tmp6], 16384 \n\t"
|
|
"addiu %[tmp5], %[tmp5], 16384 \n\t"
|
|
"addu %[tmp1], %[tmp1], %[tmp4] \n\t"
|
|
"subu %[tmp2], %[tmp2], %[tmp3] \n\t"
|
|
"addiu %[tmp1], %[tmp1], 1 \n\t"
|
|
"addiu %[tmp2], %[tmp2], 1 \n\t"
|
|
"sra %[tmp1], %[tmp1], 1 \n\t"
|
|
"sra %[tmp2], %[tmp2], 1 \n\t"
|
|
"subu %[tmp4], %[tmp6], %[tmp1] \n\t"
|
|
"addu %[tmp1], %[tmp6], %[tmp1] \n\t"
|
|
"addu %[tmp6], %[tmp5], %[tmp2] \n\t"
|
|
"subu %[tmp5], %[tmp5], %[tmp2] \n\t"
|
|
"sra %[tmp4], %[tmp4], 15 \n\t"
|
|
"sra %[tmp1], %[tmp1], 15 \n\t"
|
|
"sra %[tmp6], %[tmp6], 15 \n\t"
|
|
"sra %[tmp5], %[tmp5], 15 \n\t"
|
|
#endif // #if defined(MIPS_DSP_R2_LE)
|
|
"sh %[tmp1], 0(%[ptr_i]) \n\t"
|
|
"sh %[tmp6], 2(%[ptr_i]) \n\t"
|
|
"sh %[tmp4], 0(%[ptr_j]) \n\t"
|
|
"blt %[i], %[n], 1b \n\t"
|
|
" sh %[tmp5], 2(%[ptr_j]) \n\t"
|
|
"blt %[m], %[l], 2b \n\t"
|
|
" addu %[i], $zero, %[m] \n\t"
|
|
"move %[l], %[istep] \n\t"
|
|
"blt %[l], %[n], 3b \n\t"
|
|
" addiu %[k], %[k], -1 \n\t"
|
|
|
|
".set pop \n\t"
|
|
|
|
: [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
|
|
[tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6),
|
|
[ptr_i] "=&r" (ptr_i), [i] "=&r" (i), [wi] "=&r" (wi), [wr] "=&r" (wr),
|
|
[m] "=&r" (m), [istep] "=&r" (istep), [l] "=&r" (l), [k] "=&r" (k),
|
|
[ptr_j] "=&r" (ptr_j), [tmp] "=&r" (tmp)
|
|
: [n] "r" (n), [frfi] "r" (frfi), [kSinTable1024] "r" (kSinTable1024)
|
|
: "hi", "lo", "$ac1hi", "$ac1lo", "memory"
|
|
);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode) {
|
|
int i = 0, l = 0, k = 0;
|
|
int istep = 0, n = 0, m = 0;
|
|
int scale = 0, shift = 0;
|
|
int32_t wr = 0, wi = 0;
|
|
int32_t tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
|
|
int32_t tmp5 = 0, tmp6 = 0, tmp = 0, tempMax = 0, round2 = 0;
|
|
int16_t* ptr_j = NULL;
|
|
int16_t* ptr_i = NULL;
|
|
|
|
n = 1 << stages;
|
|
if (n > 1024) {
|
|
return -1;
|
|
}
|
|
|
|
__asm __volatile (
|
|
".set push \n\t"
|
|
".set noreorder \n\t"
|
|
|
|
"addiu %[k], $zero, 10 \n\t"
|
|
"addiu %[l], $zero, 1 \n\t"
|
|
"move %[scale], $zero \n\t"
|
|
"3: \n\t"
|
|
"addiu %[shift], $zero, 14 \n\t"
|
|
"addiu %[round2], $zero, 8192 \n\t"
|
|
"move %[ptr_i], %[frfi] \n\t"
|
|
"move %[tempMax], $zero \n\t"
|
|
"addu %[i], %[n], %[n] \n\t"
|
|
"5: \n\t"
|
|
"lh %[tmp1], 0(%[ptr_i]) \n\t"
|
|
"lh %[tmp2], 2(%[ptr_i]) \n\t"
|
|
"lh %[tmp3], 4(%[ptr_i]) \n\t"
|
|
"lh %[tmp4], 6(%[ptr_i]) \n\t"
|
|
#if defined(MIPS_DSP_R1_LE)
|
|
"absq_s.w %[tmp1], %[tmp1] \n\t"
|
|
"absq_s.w %[tmp2], %[tmp2] \n\t"
|
|
"absq_s.w %[tmp3], %[tmp3] \n\t"
|
|
"absq_s.w %[tmp4], %[tmp4] \n\t"
|
|
#else // #if defined(MIPS_DSP_R1_LE)
|
|
"slt %[tmp5], %[tmp1], $zero \n\t"
|
|
"subu %[tmp6], $zero, %[tmp1] \n\t"
|
|
"movn %[tmp1], %[tmp6], %[tmp5] \n\t"
|
|
"slt %[tmp5], %[tmp2], $zero \n\t"
|
|
"subu %[tmp6], $zero, %[tmp2] \n\t"
|
|
"movn %[tmp2], %[tmp6], %[tmp5] \n\t"
|
|
"slt %[tmp5], %[tmp3], $zero \n\t"
|
|
"subu %[tmp6], $zero, %[tmp3] \n\t"
|
|
"movn %[tmp3], %[tmp6], %[tmp5] \n\t"
|
|
"slt %[tmp5], %[tmp4], $zero \n\t"
|
|
"subu %[tmp6], $zero, %[tmp4] \n\t"
|
|
"movn %[tmp4], %[tmp6], %[tmp5] \n\t"
|
|
#endif // #if defined(MIPS_DSP_R1_LE)
|
|
"slt %[tmp5], %[tempMax], %[tmp1] \n\t"
|
|
"movn %[tempMax], %[tmp1], %[tmp5] \n\t"
|
|
"addiu %[i], %[i], -4 \n\t"
|
|
"slt %[tmp5], %[tempMax], %[tmp2] \n\t"
|
|
"movn %[tempMax], %[tmp2], %[tmp5] \n\t"
|
|
"slt %[tmp5], %[tempMax], %[tmp3] \n\t"
|
|
"movn %[tempMax], %[tmp3], %[tmp5] \n\t"
|
|
"slt %[tmp5], %[tempMax], %[tmp4] \n\t"
|
|
"movn %[tempMax], %[tmp4], %[tmp5] \n\t"
|
|
"bgtz %[i], 5b \n\t"
|
|
" addiu %[ptr_i], %[ptr_i], 8 \n\t"
|
|
"addiu %[tmp1], $zero, 13573 \n\t"
|
|
"addiu %[tmp2], $zero, 27146 \n\t"
|
|
#if !defined(MIPS32_R2_LE)
|
|
"sll %[tempMax], %[tempMax], 16 \n\t"
|
|
"sra %[tempMax], %[tempMax], 16 \n\t"
|
|
#else // #if !defined(MIPS32_R2_LE)
|
|
"seh %[tempMax] \n\t"
|
|
#endif // #if !defined(MIPS32_R2_LE)
|
|
"slt %[tmp1], %[tmp1], %[tempMax] \n\t"
|
|
"slt %[tmp2], %[tmp2], %[tempMax] \n\t"
|
|
"addu %[tmp1], %[tmp1], %[tmp2] \n\t"
|
|
"addu %[shift], %[shift], %[tmp1] \n\t"
|
|
"addu %[scale], %[scale], %[tmp1] \n\t"
|
|
"sllv %[round2], %[round2], %[tmp1] \n\t"
|
|
"sll %[istep], %[l], 1 \n\t"
|
|
"move %[m], $zero \n\t"
|
|
"sll %[tmp], %[l], 2 \n\t"
|
|
"2: \n\t"
|
|
#if defined(MIPS_DSP_R1_LE)
|
|
"sllv %[tmp3], %[m], %[k] \n\t"
|
|
"addiu %[tmp2], %[tmp3], 512 \n\t"
|
|
"addiu %[m], %[m], 1 \n\t"
|
|
"lhx %[wi], %[tmp3](%[kSinTable1024]) \n\t"
|
|
"lhx %[wr], %[tmp2](%[kSinTable1024]) \n\t"
|
|
#else // #if defined(MIPS_DSP_R1_LE)
|
|
"sllv %[tmp3], %[m], %[k] \n\t"
|
|
"addu %[ptr_j], %[tmp3], %[kSinTable1024] \n\t"
|
|
"addiu %[ptr_i], %[ptr_j], 512 \n\t"
|
|
"addiu %[m], %[m], 1 \n\t"
|
|
"lh %[wi], 0(%[ptr_j]) \n\t"
|
|
"lh %[wr], 0(%[ptr_i]) \n\t"
|
|
#endif // #if defined(MIPS_DSP_R1_LE)
|
|
"1: \n\t"
|
|
"sll %[tmp1], %[i], 2 \n\t"
|
|
"addu %[ptr_i], %[frfi], %[tmp1] \n\t"
|
|
"addu %[ptr_j], %[ptr_i], %[tmp] \n\t"
|
|
"lh %[tmp3], 0(%[ptr_j]) \n\t"
|
|
"lh %[tmp4], 2(%[ptr_j]) \n\t"
|
|
"lh %[tmp6], 0(%[ptr_i]) \n\t"
|
|
"lh %[tmp5], 2(%[ptr_i]) \n\t"
|
|
"addu %[i], %[i], %[istep] \n\t"
|
|
#if defined(MIPS_DSP_R2_LE)
|
|
"mult %[wr], %[tmp3] \n\t"
|
|
"msub %[wi], %[tmp4] \n\t"
|
|
"mult $ac1, %[wr], %[tmp4] \n\t"
|
|
"madd $ac1, %[wi], %[tmp3] \n\t"
|
|
"mflo %[tmp1] \n\t"
|
|
"mflo %[tmp2], $ac1 \n\t"
|
|
"sll %[tmp6], %[tmp6], 14 \n\t"
|
|
"sll %[tmp5], %[tmp5], 14 \n\t"
|
|
"shra_r.w %[tmp1], %[tmp1], 1 \n\t"
|
|
"shra_r.w %[tmp2], %[tmp2], 1 \n\t"
|
|
"addu %[tmp6], %[tmp6], %[round2] \n\t"
|
|
"addu %[tmp5], %[tmp5], %[round2] \n\t"
|
|
"subu %[tmp4], %[tmp6], %[tmp1] \n\t"
|
|
"addu %[tmp1], %[tmp6], %[tmp1] \n\t"
|
|
"addu %[tmp6], %[tmp5], %[tmp2] \n\t"
|
|
"subu %[tmp5], %[tmp5], %[tmp2] \n\t"
|
|
"srav %[tmp4], %[tmp4], %[shift] \n\t"
|
|
"srav %[tmp1], %[tmp1], %[shift] \n\t"
|
|
"srav %[tmp6], %[tmp6], %[shift] \n\t"
|
|
"srav %[tmp5], %[tmp5], %[shift] \n\t"
|
|
#else // #if defined(MIPS_DSP_R2_LE)
|
|
"mul %[tmp1], %[wr], %[tmp3] \n\t"
|
|
"mul %[tmp2], %[wr], %[tmp4] \n\t"
|
|
"mul %[tmp4], %[wi], %[tmp4] \n\t"
|
|
"mul %[tmp3], %[wi], %[tmp3] \n\t"
|
|
"sll %[tmp6], %[tmp6], 14 \n\t"
|
|
"sll %[tmp5], %[tmp5], 14 \n\t"
|
|
"sub %[tmp1], %[tmp1], %[tmp4] \n\t"
|
|
"addu %[tmp2], %[tmp2], %[tmp3] \n\t"
|
|
"addiu %[tmp1], %[tmp1], 1 \n\t"
|
|
"addiu %[tmp2], %[tmp2], 1 \n\t"
|
|
"sra %[tmp2], %[tmp2], 1 \n\t"
|
|
"sra %[tmp1], %[tmp1], 1 \n\t"
|
|
"addu %[tmp6], %[tmp6], %[round2] \n\t"
|
|
"addu %[tmp5], %[tmp5], %[round2] \n\t"
|
|
"subu %[tmp4], %[tmp6], %[tmp1] \n\t"
|
|
"addu %[tmp1], %[tmp6], %[tmp1] \n\t"
|
|
"addu %[tmp6], %[tmp5], %[tmp2] \n\t"
|
|
"subu %[tmp5], %[tmp5], %[tmp2] \n\t"
|
|
"sra %[tmp4], %[tmp4], %[shift] \n\t"
|
|
"sra %[tmp1], %[tmp1], %[shift] \n\t"
|
|
"sra %[tmp6], %[tmp6], %[shift] \n\t"
|
|
"sra %[tmp5], %[tmp5], %[shift] \n\t"
|
|
#endif // #if defined(MIPS_DSP_R2_LE)
|
|
"sh %[tmp1], 0(%[ptr_i]) \n\t"
|
|
"sh %[tmp6], 2(%[ptr_i]) \n\t"
|
|
"sh %[tmp4], 0(%[ptr_j]) \n\t"
|
|
"blt %[i], %[n], 1b \n\t"
|
|
" sh %[tmp5], 2(%[ptr_j]) \n\t"
|
|
"blt %[m], %[l], 2b \n\t"
|
|
" addu %[i], $zero, %[m] \n\t"
|
|
"move %[l], %[istep] \n\t"
|
|
"blt %[l], %[n], 3b \n\t"
|
|
" addiu %[k], %[k], -1 \n\t"
|
|
|
|
".set pop \n\t"
|
|
|
|
: [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
|
|
[tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6),
|
|
[ptr_i] "=&r" (ptr_i), [i] "=&r" (i), [m] "=&r" (m), [tmp] "=&r" (tmp),
|
|
[istep] "=&r" (istep), [wi] "=&r" (wi), [wr] "=&r" (wr), [l] "=&r" (l),
|
|
[k] "=&r" (k), [round2] "=&r" (round2), [ptr_j] "=&r" (ptr_j),
|
|
[shift] "=&r" (shift), [scale] "=&r" (scale), [tempMax] "=&r" (tempMax)
|
|
: [n] "r" (n), [frfi] "r" (frfi), [kSinTable1024] "r" (kSinTable1024)
|
|
: "hi", "lo", "$ac1hi", "$ac1lo", "memory"
|
|
);
|
|
|
|
return scale;
|
|
|
|
}
|