summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/amrwbenc/src
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2010-05-14 15:45:22 -0700
committerJames Dong <jdong@google.com>2010-05-19 07:21:25 -0700
commit956c553ab0ce72f8074ad0fda2ffd66a0305700c (patch)
treefe111ecd29e01c270246f5f338c56806d6d5b136 /media/libstagefright/codecs/amrwbenc/src
parente1f61055b4abb96a86d1ff24b5a7777dfe40fe5f (diff)
downloadframeworks_av-956c553ab0ce72f8074ad0fda2ffd66a0305700c.zip
frameworks_av-956c553ab0ce72f8074ad0fda2ffd66a0305700c.tar.gz
frameworks_av-956c553ab0ce72f8074ad0fda2ffd66a0305700c.tar.bz2
Initial software encoder checkins
Change-Id: I27f387db23594e46384c4eb3a0093ce220bb6b60
Diffstat (limited to 'media/libstagefright/codecs/amrwbenc/src')
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s104
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s80
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s185
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s231
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s226
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s186
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s151
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s460
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s228
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s75
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s238
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s102
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s127
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s228
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s270
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s133
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s178
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s151
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s100
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s127
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s138
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s106
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/autocorr.c127
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/az_isp.c268
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/bits.c210
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/c2t64fx.c297
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/c4t64fx.c1043
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/cmnMemory.c73
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/convolve.c109
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/cor_h_x.c127
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/decim54.c146
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/deemph.c117
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/dtx.c605
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/g_pitch.c79
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/gpclip.c110
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/homing.c46
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/hp400.c106
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/hp50.c106
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/hp6k.c93
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/hp_wsp.c148
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/int_lpc.c66
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/isp_az.c247
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/isp_isf.c91
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/lag_wind.c49
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/levinson.c250
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/log2.c111
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/lp_dec2.c70
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/math_op.c219
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/mem_align.c107
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/oper_32b.c223
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/p_med_ol.c256
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/pit_shrp.c49
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/pitch_f4.c324
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/pred_lt4.c120
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/preemph.c88
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/q_gain2.c346
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/q_pulse.c400
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/qisf_ns.c111
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c542
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/random.c33
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/residu.c67
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/scale.c57
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/stream.c58
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/syn_filt.c160
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/updt_tar.c49
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/util.c74
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c1941
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/voicefac.c92
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/wb_vad.c808
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/weight_a.c48
70 files changed, 14690 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
new file mode 100644
index 0000000..0eb5e9f
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
@@ -0,0 +1,104 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+
+@void Deemph_32(
+@ Word16 x_hi[], /* (i) : input signal (bit31..16) */
+@ Word16 x_lo[], /* (i) : input signal (bit15..4) */
+@ Word16 y[], /* (o) : output signal (x16) */
+@ Word16 mu, /* (i) Q15 : deemphasis factor */
+@ Word16 L, /* (i) : vector size */
+@ Word16 * mem /* (i/o) : memory (y[-1]) */
+@ )
+
+@x_hi RN R0
+@x_lo RN R1
+@y[] RN R2
+@*mem RN R3
+
+ .section .text
+ .global Deemph_32_asm
+
+Deemph_32_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ MOV r4, #2 @i=0
+ LDRSH r6, [r0], #2 @load x_hi[0]
+ LDRSH r7, [r1], #2 @load x_lo[0]
+ LDR r5, =22282 @r5---mu
+ MOV r11, #0x8000
+
+ @y[0]
+ MOV r10, r6, LSL #16 @L_tmp = x_hi[0]<<16
+ MOV r8, r5, ASR #1 @fac = mu >> 1
+ LDR r5, [r3]
+ ADD r12, r10, r7, LSL #4 @L_tmp += x_lo[0] << 4
+ MOV r10, r12, LSL #3 @L_tmp <<= 3
+ MUL r9, r5, r8
+ LDRSH r6, [r0], #2 @load x_hi[1]
+ QDADD r10, r10, r9
+ LDRSH r7, [r1], #2 @load x_lo[1]
+ MOV r12, r10, LSL #1 @L_tmp = L_mac(L_tmp, *mem, fac)
+ QADD r10, r12, r11
+ MOV r14, r10, ASR #16 @y[0] = round(L_tmp)
+
+
+ MOV r10, r6, LSL #16
+ ADD r12, r10, r7, LSL #4
+ STRH r14, [r2], #2 @update y[0]
+ MOV r10, r12, LSL #3
+ MUL r9, r14, r8
+ QDADD r10, r10, r9
+ MOV r12, r10, LSL #1
+ QADD r10, r12, r11
+ MOV r14, r10, ASR #16 @y[1] = round(L_tmp)
+
+LOOP:
+ LDRSH r6, [r0], #2 @load x_hi[]
+ LDRSH r7, [r1], #2
+ STRH r14, [r2], #2
+ MOV r10, r6, LSL #16
+ ADD r12, r10, r7, LSL #4
+ MUL r9, r14, r8
+ MOV r10, r12, LSL #3
+ QDADD r10, r10, r9
+ LDRSH r6, [r0], #2 @load x_hi[]
+ MOV r12, r10, LSL #1
+ QADD r10, r12, r11
+ LDRSH r7, [r1], #2
+ MOV r14, r10, ASR #16
+
+ MOV r10, r6, LSL #16
+ ADD r12, r10, r7, LSL #4
+ STRH r14, [r2], #2
+ MUL r9, r14, r8
+ MOV r10, r12, LSL #3
+ QDADD r10, r10, r9
+ ADD r4, r4, #2
+ MOV r12, r10, LSL #1
+ QADD r10, r12, r11
+ CMP r4, #64
+ MOV r14, r10, ASR #16
+
+ BLT LOOP
+ STR r14, [r3]
+ STRH r14, [r2]
+
+ LDMFD r13!, {r4 - r12, r15}
+
+ @ENDP
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
new file mode 100644
index 0000000..0383269
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
@@ -0,0 +1,80 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */
+@ Word16 x[], /* (i) 12bits: x vector */
+@ Word16 y[], /* (i) 12bits: y vector */
+@ Word16 lg, /* (i) : vector length */
+@ Word16 * exp /* (o) : exponent of result (0..+30) */
+@)
+@****************************************************************
+@ x[] --- r0
+@ y[] --- r1
+@ lg --- r2
+@ *exp --- r3
+
+ .section .text
+ .global Dot_product12_asm
+
+Dot_product12_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ MOV r4, #0 @ L_sum = 0
+ MOV r5, #0 @ i = 0
+
+LOOP:
+ LDR r6, [r0], #4
+ LDR r7, [r1], #4
+ LDR r8, [r0], #4
+ SMLABB r4, r6, r7, r4
+ LDR r9, [r1], #4
+ SMLATT r4, r6, r7, r4
+
+ LDR r6, [r0], #4
+ SMLABB r4, r8, r9, r4
+
+ LDR r7, [r1], #4
+ SMLATT r4, r8, r9, r4
+ LDR r8, [r0], #4
+
+ SMLABB r4, r6, r7, r4
+ LDR r9, [r1], #4
+ SMLATT r4, r6, r7, r4
+ ADD r5, r5, #8
+ SMLABB r4, r8, r9, r4
+ CMP r5, r2
+ SMLATT r4, r8, r9, r4
+ BLT LOOP
+
+ MOV r12, r4, LSL #1
+ ADD r12, r12, #1 @ L_sum = (L_sum << 1) + 1
+ MOV r4, r12
+
+ CMP r12, #0
+ RSBLT r4, r12, #0
+ CLZ r10, r4
+ SUB r10, r10, #1 @ sft = norm_l(L_sum)
+ MOV r0, r12, LSL r10 @ L_sum = L_sum << sft
+ RSB r11, r10, #30 @ *exp = 30 - sft
+ STRH r11, [r3]
+
+Dot_product12_end:
+
+ LDMFD r13!, {r4 - r12, r15}
+ @ENDFUNC
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
new file mode 100644
index 0000000..e6ebd73
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
@@ -0,0 +1,185 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+
+@**********************************************************************/
+@void Filt_6k_7k(
+@ Word16 signal[], /* input: signal */
+@ Word16 lg, /* input: length of input */
+@ Word16 mem[] /* in/out: memory (size=30) */
+@)
+@******************************************************************
+@ r0 --- signal[]
+@ r1 --- lg
+@ r2 --- mem[]
+
+ .section .text
+ .global Filt_6k_7k_asm
+ .extern voAWB_Copy
+ .extern fir_6k_7k
+
+Filt_6k_7k_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ SUB r13, r13, #240 @ x[L_SUBFR16k + (L_FIR - 1)]
+ MOV r8, r0 @ copy signal[] address
+ MOV r4, r1 @ copy lg address
+ MOV r5, r2 @ copy mem[] address
+
+ MOV r1, r13
+ MOV r0, r2
+ MOV r2, #30 @ L_FIR - 1
+ BL voAWB_Copy @ memcpy(x, mem, (L_FIR - 1)<<1)
+
+ LDR r10, Lable1 @ get fir_7k address
+
+ MOV r14, #0
+ MOV r3, r8 @ change myMemCopy to Copy, due to Copy will change r3 content
+ ADD r6, r13, #60 @ get x[L_FIR - 1] address
+ MOV r7, r3 @ get signal[i]
+LOOP1:
+ LDRSH r8, [r7], #2
+ LDRSH r9, [r7], #2
+ MOV r8, r8, ASR #2
+ MOV r9, r9, ASR #2
+ LDRSH r11, [r7], #2
+ LDRSH r12, [r7], #2
+ MOV r11, r11, ASR #2
+ MOV r12, r12, ASR #2
+ STRH r8, [r6], #2
+ STRH r9, [r6], #2
+ STRH r11, [r6], #2
+ STRH r12, [r6], #2
+ LDRSH r8, [r7], #2
+ LDRSH r9, [r7], #2
+ MOV r8, r8, ASR #2
+ MOV r9, r9, ASR #2
+ LDRSH r11, [r7], #2
+ LDRSH r12, [r7], #2
+ MOV r11, r11, ASR #2
+ MOV r12, r12, ASR #2
+ STRH r8, [r6], #2
+ STRH r9, [r6], #2
+ STRH r11, [r6], #2
+ STRH r12, [r6], #2
+ ADD r14, r14, #8
+ CMP r14, #80
+ BLT LOOP1
+
+
+ STR r5, [sp, #-4] @ PUSH r5 to stack
+
+ @ not use registers: r4, r10, r12, r14, r5
+ MOV r4, r13
+ MOV r5, #0 @ i = 0
+LOOP2:
+ LDR r0, [r10]
+
+ LDRSH r1, [r4] @ load x[i]
+ LDRSH r2, [r4, #60] @ load x[i + 30]
+ LDRSH r6, [r4, #2] @ load x[i + 1]
+ LDRSH r7, [r4, #58] @ load x[i + 29]
+ ADD r1, r1, r2 @ x[i] + x[i + 30]
+ ADD r6, r6, r7 @ x[i + 1] + x[i + 29]
+ LDRSH r8, [r4, #4] @ load x[i + 2]
+ LDRSH r9, [r4, #56] @ load x[i + 28]
+
+ SMULBB r14, r1, r0 @ (x[i] + x[i + 30]) * fir_7k[0]
+ ADD r8, r8, r9 @ x[i + 2] + x[i + 28]
+ SMLABT r14, r6, r0, r14 @ (x[i + 1] + x[i + 29]) * fir_7k[1]
+
+ LDR r0, [r10, #4]
+ LDRSH r1, [r4, #6] @ load x[i+3]
+ LDRSH r2, [r4, #54] @ load x[i+27]
+ LDRSH r6, [r4, #8] @ load x[i+4]
+ LDRSH r7, [r4, #52] @ load x[i+26]
+ ADD r1, r1, r2 @ x[i+3] + x[i+27]
+ ADD r6, r6, r7 @ x[i+4] + x[i+26]
+ SMLABB r14, r8, r0, r14 @ (x[i + 2] + x[i + 28]) * fir_7k[2]
+ LDRSH r8, [r4, #10] @ load x[i+5]
+ LDRSH r9, [r4, #50] @ load x[i+25]
+ SMLABT r14, r1, r0, r14 @ (x[i+3] + x[i+27]) * fir_7k[3]
+ ADD r8, r8, r9 @ x[i+5] + x[i+25]
+
+ LDR r0, [r10, #8]
+ LDRSH r1, [r4, #12] @ x[i+6]
+ LDRSH r2, [r4, #48] @ x[i+24]
+ SMLABB r14, r6, r0, r14 @ (x[i+4] + x[i+26]) * fir_7k[4]
+ LDRSH r6, [r4, #14] @ x[i+7]
+ LDRSH r7, [r4, #46] @ x[i+23]
+ SMLABT r14, r8, r0, r14 @ (x[i+5] + x[i+25]) * fir_7k[5]
+ LDR r0, [r10, #12]
+ ADD r1, r1, r2 @ (x[i+6] + x[i+24])
+ ADD r6, r6, r7 @ (x[i+7] + x[i+23])
+ SMLABB r14, r1, r0, r14 @ (x[i+6] + x[i+24]) * fir_7k[6]
+ LDRSH r8, [r4, #16] @ x[i+8]
+ LDRSH r9, [r4, #44] @ x[i+22]
+ SMLABT r14, r6, r0, r14 @ (x[i+7] + x[i+23]) * fir_7k[7]
+ LDR r0, [r10, #16]
+ LDRSH r1, [r4, #18] @ x[i+9]
+ LDRSH r2, [r4, #42] @ x[i+21]
+ LDRSH r6, [r4, #20] @ x[i+10]
+ LDRSH r7, [r4, #40] @ x[i+20]
+ ADD r8, r8, r9 @ (x[i+8] + x[i+22])
+ ADD r1, r1, r2 @ (x[i+9] + x[i+21])
+ ADD r6, r6, r7 @ (x[i+10] + x[i+20])
+ SMLABB r14, r8, r0, r14 @ (x[i+8] + x[i+22]) * fir_7k[8]
+ LDRSH r8, [r4, #22] @ x[i+11]
+ LDRSH r9, [r4, #38] @ x[i+19]
+ SMLABT r14, r1, r0, r14 @ (x[i+9] + x[i+21]) * fir_7k[9]
+ LDR r0, [r10, #20]
+ LDRSH r1, [r4, #24] @ x[i+12]
+ LDRSH r2, [r4, #36] @ x[i+18]
+ SMLABB r14, r6, r0, r14 @ (x[i+10] + x[i+20]) * fir_7k[10]
+ LDRSH r6, [r4, #26] @ x[i+13]
+ ADD r8, r8, r9 @ (x[i+11] + x[i+19])
+ LDRSH r7, [r4, #34] @ x[i+17]
+ SMLABT r14, r8, r0, r14 @ (x[i+11] + x[i+19]) * fir_7k[11]
+ LDR r0, [r10, #24]
+ ADD r1, r1, r2 @ x[i+12] + x[i+18]
+ LDRSH r8, [r4, #28] @ x[i+14]
+ SMLABB r14, r1, r0, r14 @ (x[i+12] + x[i+18]) * fir_7k[12]
+ ADD r6, r6, r7 @ (x[i+13] + x[i+17])
+ LDRSH r9, [r4, #32] @ x[i+16]
+ SMLABT r14, r6, r0, r14 @ (x[i+13] + x[i+17]) * fir_7k[13]
+ LDR r0, [r10, #28]
+ ADD r8, r8, r9 @ (x[i+14] + x[i+16])
+ LDRSH r1, [r4, #30] @ x[i+15]
+ SMLABB r14, r8, r0, r14 @ (x[i+14] + x[i+16]) * fir_7k[14]
+ SMLABT r14, r1, r0, r14 @ x[i+15] * fir_7k[15]
+
+ ADD r5, r5, #1
+ ADD r14, r14, #0x4000
+ ADD r4, r4, #2
+ MOV r1, r14, ASR #15
+ CMP r5, #80
+ STRH r1, [r3], #2 @signal[i] = (L_tmp + 0x4000) >> 15
+ BLT LOOP2
+
+ LDR r1, [sp, #-4] @mem address
+ ADD r0, r13, #160 @x + lg
+ MOV r2, #30
+ BL voAWB_Copy
+
+Filt_6k_7k_end:
+ ADD r13, r13, #240
+ LDMFD r13!, {r4 - r12, r15}
+
+Lable1:
+ .word fir_6k_7k
+ @ENDFUNC
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
new file mode 100644
index 0000000..b440a31
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
@@ -0,0 +1,231 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+
+@static void Norm_Corr (Word16 exc[], /* (i) : excitation buffer */
+@ Word16 xn[], /* (i) : target vector */
+@ Word16 h[], /* (i) Q15 : impulse response of synth/wgt filters */
+@ Word16 L_subfr, /* (i) : sub-frame length */
+@ Word16 t_min, /* (i) : minimum value of pitch lag. */
+@ Word16 t_max, /* (i) : maximum value of pitch lag. */
+@ Word16 corr_norm[]) /* (o) Q15 : normalized correlation */
+@
+
+@ r0 --- exc[]
+@ r1 --- xn[]
+@ r2 --- h[]
+@ r3 --- L_subfr
+@ r4 --- t_min
+@ r5 --- t_max
+@ r6 --- corr_norm[]
+
+
+ .section .text
+ .global Norm_corr_asm
+ .extern Convolve_asm
+ .extern Isqrt_n
+@******************************
+@ constant
+@******************************
+.equ EXC , 0
+.equ XN , 4
+.equ H , 8
+.equ L_SUBFR , 12
+.equ voSTACK , 172
+.equ T_MIN , 212
+.equ T_MAX , 216
+.equ CORR_NORM , 220
+
+Norm_corr_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ SUB r13, r13, #voSTACK
+
+ ADD r8, r13, #20 @get the excf[L_SUBFR]
+ LDR r4, [r13, #T_MIN] @get t_min
+ RSB r11, r4, #0 @k = -t_min
+ ADD r5, r0, r11, LSL #1 @get the &exc[k]
+
+ @transfer Convolve function
+ STMFD sp!, {r0 - r3}
+ MOV r0, r5
+ MOV r1, r2
+ MOV r2, r8 @r2 --- excf[]
+ BL Convolve_asm
+ LDMFD sp!, {r0 - r3}
+
+ @ r8 --- excf[]
+
+ MOV r14, r1 @copy xn[] address
+ MOV r5, #64
+ MOV r6, #0 @L_tmp = 0
+ MOV r7, #1
+
+LOOP1:
+ LDR r9, [r14], #4
+ LDR r10, [r14], #4
+ LDR r11, [r14], #4
+ LDR r12, [r14], #4
+ SMLABB r6, r9, r9, r6 @L_tmp += (xn[i] * xn[i])
+ SMLATT r6, r9, r9, r6 @L_tmp += (xn[i+1] * xn[i+1])
+ SMLABB r6, r10, r10, r6
+ SMLATT r6, r10, r10, r6
+ SMLABB r6, r11, r11, r6
+ SMLATT r6, r11, r11, r6
+ SMLABB r6, r12, r12, r6
+ SMLATT r6, r12, r12, r6
+ SUBS r5, r5, #8
+ BNE LOOP1
+
+ ADD r9, r7, r6, LSL #1 @L_tmp = (L_tmp << 1) + 1
+ CLZ r7, r9
+ SUB r6, r7, #1 @exp = norm_l(L_tmp)
+ RSB r7, r6, #32 @exp = 32 - exp
+ MOV r6, r7, ASR #1
+ RSB r7, r6, #0 @scale = -(exp >> 1)
+
+ @loop for every possible period
+ @for(t = t_min@ t <= t_max@ t++)
+ @r7 --- scale r4 --- t_min r8 --- excf[]
+
+LOOPFOR:
+ MOV r5, #0 @L_tmp = 0
+ MOV r6, #0 @L_tmp1 = 0
+ MOV r9, #64
+ MOV r12, r1 @copy of xn[]
+ ADD r14, r13, #20 @copy of excf[]
+ MOV r8, #0x8000
+
+LOOPi:
+ LDR r11, [r14], #4 @load excf[i], excf[i+1]
+ LDR r10, [r12], #4 @load xn[i], xn[i+1]
+ SMLABB r6, r11, r11, r6 @L_tmp1 += excf[i] * excf[i]
+ SMLATT r6, r11, r11, r6 @L_tmp1 += excf[i+1] * excf[i+1]
+ SMLABB r5, r10, r11, r5 @L_tmp += xn[i] * excf[i]
+ SMLATT r5, r10, r11, r5 @L_tmp += xn[i+1] * excf[i+1]
+ LDR r11, [r14], #4 @load excf[i+2], excf[i+3]
+ LDR r10, [r12], #4 @load xn[i+2], xn[i+3]
+ SMLABB r6, r11, r11, r6
+ SMLATT r6, r11, r11, r6
+ SMLABB r5, r10, r11, r5
+ SMLATT r5, r10, r11, r5
+ SUBS r9, r9, #4
+ BNE LOOPi
+
+ @r5 --- L_tmp, r6 --- L_tmp1
+ MOV r10, #1
+ ADD r5, r10, r5, LSL #1 @L_tmp = (L_tmp << 1) + 1
+ ADD r6, r10, r6, LSL #1 @L_tmp1 = (L_tmp1 << 1) + 1
+
+ CLZ r10, r5
+ CMP r5, #0
+ RSBLT r11, r5, #0
+ CLZLT r10, r11
+ SUB r10, r10, #1 @exp = norm_l(L_tmp)
+
+ MOV r5, r5, LSL r10 @L_tmp = (L_tmp << exp)
+ RSB r10, r10, #30 @exp_corr = 30 - exp
+ MOV r11, r5, ASR #16 @corr = extract_h(L_tmp)
+
+ CLZ r5, r6
+ SUB r5, r5, #1
+ MOV r6, r6, LSL r5 @L_tmp = (L_tmp1 << exp)
+ RSB r5, r5, #30 @exp_norm = 30 - exp
+
+ @r10 --- exp_corr, r11 --- corr
+ @r6 --- L_tmp, r5 --- exp_norm
+
+ @Isqrt_n(&L_tmp, &exp_norm)
+
+ MOV r14, r0
+ MOV r12, r1
+
+ STMFD sp!, {r0 - r4, r7 - r12, r14}
+ ADD r1, sp, #4
+ ADD r0, sp, #0
+ STR r6, [sp]
+ STRH r5, [sp, #4]
+ BL Isqrt_n
+ LDR r6, [sp]
+ LDRSH r5, [sp, #4]
+ LDMFD sp!, {r0 - r4, r7 - r12, r14}
+ MOV r0, r14
+ MOV r1, r12
+
+
+ MOV r6, r6, ASR #16 @norm = extract_h(L_tmp)
+ MUL r12, r6, r11
+ ADD r12, r12, r12 @L_tmp = vo_L_mult(corr, norm)
+
+ ADD r6, r10, r5
+ ADD r6, r6, r7 @exp_corr + exp_norm + scale
+
+ CMP r6, #0
+ RSBLT r6, r6, #0
+ MOVLT r12, r12, ASR r6
+ MOVGT r12, r12, LSL r6 @L_tmp = L_shl(L_tmp, exp_corr + exp_norm + scale)
+
+ ADD r12, r12, r8
+ MOV r12, r12, ASR #16 @vo_round(L_tmp)
+
+ LDR r5, [r13, #CORR_NORM] @ get corr_norm address
+ LDR r6, [r13, #T_MAX] @ get t_max
+ ADD r10, r5, r4, LSL #1 @ get corr_norm[t] address
+ STRH r12, [r10] @ corr_norm[t] = vo_round(L_tmp)
+
+ CMP r4, r6
+ BEQ Norm_corr_asm_end
+
+ ADD r4, r4, #1 @ t_min ++
+
+ RSB r5, r4, #0 @ k
+
+ MOV r6, #63 @ i = 63
+ MOV r8, r0 @ exc[]
+ MOV r9, r2 @ h[]
+ ADD r10, r13, #20 @ excf[]
+
+ ADD r8, r8, r5, LSL #1 @ exc[k] address
+ ADD r9, r9, r6, LSL #1 @ h[i] address
+ ADD r10, r10, r6, LSL #1 @ excf[i] address
+ LDRSH r11, [r8] @ tmp = exc[k]
+
+LOOPK:
+ LDRSH r8, [r9], #-2 @ load h[i]
+ LDRSH r12, [r10, #-2] @ load excf[i - 1]
+ MUL r14, r11, r8
+ MOV r8, r14, ASR #15
+ ADD r14, r8, r12
+ STRH r14, [r10], #-2
+ SUBS r6, r6, #1
+ BGT LOOPK
+
+ LDRSH r8, [r9] @ load h[0]
+ MUL r14, r11, r8
+ LDR r6, [r13, #T_MAX] @ get t_max
+ MOV r8, r14, ASR #15
+ STRH r8, [r10]
+
+ CMP r4, r6
+ BLE LOOPFOR
+
+Norm_corr_asm_end:
+
+ ADD r13, r13, #voSTACK
+ LDMFD r13!, {r4 - r12, r15}
+
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
new file mode 100644
index 0000000..6416634
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
@@ -0,0 +1,226 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@void Syn_filt_32(
+@ Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients */
+@ Word16 m, /* (i) : order of LP filter */
+@ Word16 exc[], /* (i) Qnew: excitation (exc[i] >> Qnew) */
+@ Word16 Qnew, /* (i) : exc scaling = 0(min) to 8(max) */
+@ Word16 sig_hi[], /* (o) /16 : synthesis high */
+@ Word16 sig_lo[], /* (o) /16 : synthesis low */
+@ Word16 lg /* (i) : size of filtering */
+@)
+@***************************************************************
+@
+@ a[] --- r0
+@ m --- r1
+@ exc[] --- r2
+@ Qnew --- r3
+@ sig_hi[] --- r4
+@ sig_lo[] --- r5
+@ lg --- r6
+
+ .section .text
+ .global Syn_filt_32_asm
+
+Syn_filt_32_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ LDR r4, [r13, #40] @ get sig_hi[] address
+ LDR r5, [r13, #44] @ get sig_lo[] address
+
+ LDRSH r6, [r0] @ load Aq[0]
+ ADD r7, r3, #4 @ 4 + Q_new
+ MOV r3, r6, ASR r7 @ a0 = Aq[0] >> (4 + Q_new)
+
+ LDR r14, =0xffff
+ LDRSH r6, [r0, #2] @ load Aq[1]
+ LDRSH r7, [r0, #4] @ load Aq[2]
+ LDRSH r8, [r0, #6] @ load Aq[3]
+ LDRSH r9, [r0, #8] @ load Aq[4]
+ AND r6, r6, r14
+ AND r8, r8, r14
+ ORR r10, r6, r7, LSL #16 @ Aq[2] -- Aq[1]
+ ORR r11, r8, r9, LSL #16 @ Aq[4] -- Aq[3]
+ STR r10, [r13, #-4]
+ STR r11, [r13, #-8]
+
+ LDRSH r6, [r0, #10] @ load Aq[5]
+ LDRSH r7, [r0, #12] @ load Aq[6]
+ LDRSH r8, [r0, #14] @ load Aq[7]
+ LDRSH r9, [r0, #16] @ load Aq[8]
+ AND r6, r6, r14
+ AND r8, r8, r14
+ ORR r10, r6, r7, LSL #16 @ Aq[6] -- Aq[5]
+ ORR r11, r8, r9, LSL #16 @ Aq[8] -- Aq[7]
+ STR r10, [r13, #-12]
+ STR r11, [r13, #-16]
+
+ LDRSH r6, [r0, #18] @ load Aq[9]
+ LDRSH r7, [r0, #20] @ load Aq[10]
+ LDRSH r8, [r0, #22] @ load Aq[11]
+ LDRSH r9, [r0, #24] @ load Aq[12]
+ AND r6, r6, r14
+ AND r8, r8, r14
+ ORR r10, r6, r7, LSL #16 @ Aq[10] -- Aq[9]
+ ORR r11, r8, r9, LSL #16 @ Aq[12] -- Aq[11]
+ STR r10, [r13, #-20]
+ STR r11, [r13, #-24]
+
+ LDRSH r6, [r0, #26] @ load Aq[13]
+ LDRSH r7, [r0, #28] @ load Aq[14]
+ LDRSH r8, [r0, #30] @ load Aq[15]
+ LDRSH r9, [r0, #32] @ load Aq[16]
+ AND r6, r6, r14
+ AND r8, r8, r14
+ ORR r10, r6, r7, LSL #16 @ Aq[14] -- Aq[13]
+ ORR r11, r8, r9, LSL #16 @ Aq[16] -- Aq[15]
+ STR r10, [r13, #-28]
+ STR r11, [r13, #-32]
+
+ MOV r8, #0 @ i = 0
+
+LOOP:
+ LDRSH r6, [r5, #-2] @ load sig_lo[i-1]
+ LDRSH r7, [r5, #-4] @ load sig_lo[i-2]
+
+ LDR r11, [r13, #-4] @ Aq[2] -- Aq[1]
+ LDRSH r9, [r5, #-6] @ load sig_lo[i-3]
+ LDRSH r10, [r5, #-8] @ load sig_lo[i-4]
+
+ SMULBB r12, r6, r11 @ sig_lo[i-1] * Aq[1]
+
+ LDRSH r6, [r5, #-10] @ load sig_lo[i-5]
+ SMLABT r12, r7, r11, r12 @ sig_lo[i-2] * Aq[2]
+ LDR r11, [r13, #-8] @ Aq[4] -- Aq[3]
+ LDRSH r7, [r5, #-12] @ load sig_lo[i-6]
+ SMLABB r12, r9, r11, r12 @ sig_lo[i-3] * Aq[3]
+ LDRSH r9, [r5, #-14] @ load sig_lo[i-7]
+ SMLABT r12, r10, r11, r12 @ sig_lo[i-4] * Aq[4]
+ LDR r11, [r13, #-12] @ Aq[6] -- Aq[5]
+ LDRSH r10, [r5, #-16] @ load sig_lo[i-8]
+ SMLABB r12, r6, r11, r12 @ sig_lo[i-5] * Aq[5]
+ LDRSH r6, [r5, #-18] @ load sig_lo[i-9]
+ SMLABT r12, r7, r11, r12 @ sig_lo[i-6] * Aq[6]
+ LDR r11, [r13, #-16] @ Aq[8] -- Aq[7]
+ LDRSH r7, [r5, #-20] @ load sig_lo[i-10]
+ SMLABB r12, r9, r11, r12 @ sig_lo[i-7] * Aq[7]
+ LDRSH r9, [r5, #-22] @ load sig_lo[i-11]
+ SMLABT r12, r10, r11, r12 @ sig_lo[i-8] * Aq[8]
+ LDR r11, [r13, #-20] @ Aq[10] -- Aq[9]
+ LDRSH r10,[r5, #-24] @ load sig_lo[i-12]
+ SMLABB r12, r6, r11, r12 @ sig_lo[i-9] * Aq[9]
+ LDRSH r6, [r5, #-26] @ load sig_lo[i-13]
+ SMLABT r12, r7, r11, r12 @ sig_lo[i-10] * Aq[10]
+ LDR r11, [r13, #-24] @ Aq[12] -- Aq[11]
+ LDRSH r7, [r5, #-28] @ load sig_lo[i-14]
+ SMLABB r12, r9, r11, r12 @ sig_lo[i-11] * Aq[11]
+ LDRSH r9, [r5, #-30] @ load sig_lo[i-15]
+ SMLABT r12, r10, r11, r12 @ sig_lo[i-12] * Aq[12]
+
+ LDR r11, [r13, #-28] @ Aq[14] -- Aq[13]
+ LDRSH r10, [r5, #-32] @ load sig_lo[i-16]
+ SMLABB r12, r6, r11, r12 @ sig_lo[i-13] * Aq[13]
+ SMLABT r12, r7, r11, r12 @ sig_lo[i-14] * Aq[14]
+
+ LDR r11, [r13, #-32] @ Aq[16] -- Aq[15]
+ LDRSH r6, [r2],#2 @ load exc[i]
+ SMLABB r12, r9, r11, r12 @ sig_lo[i-15] * Aq[15]
+ SMLABT r12, r10, r11, r12 @ sig_lo[i-16] * Aq[16]
+ MUL r7, r6, r3 @ exc[i] * a0
+ RSB r14, r12, #0 @ L_tmp
+ MOV r14, r14, ASR #11 @ L_tmp >>= 11
+ ADD r14, r14, r7, LSL #1 @ L_tmp += (exc[i] * a0) << 1
+
+
+ LDRSH r6, [r4, #-2] @ load sig_hi[i-1]
+ LDRSH r7, [r4, #-4] @ load sig_hi[i-2]
+
+ LDR r11, [r13, #-4] @ Aq[2] -- Aq[1]
+ LDRSH r9, [r4, #-6] @ load sig_hi[i-3]
+ LDRSH r10, [r4, #-8] @ load sig_hi[i-4]
+ SMULBB r12, r6, r11 @ sig_hi[i-1] * Aq[1]
+ LDRSH r6, [r4, #-10] @ load sig_hi[i-5]
+ SMLABT r12, r7, r11, r12 @ sig_hi[i-2] * Aq[2]
+
+ LDR r11, [r13, #-8] @ Aq[4] -- Aq[3]
+ LDRSH r7, [r4, #-12] @ load sig_hi[i-6]
+
+ SMLABB r12, r9, r11, r12 @ sig_hi[i-3] * Aq[3]
+ LDRSH r9, [r4, #-14] @ load sig_hi[i-7]
+
+ SMLABT r12, r10, r11, r12 @ sig_hi[i-4] * Aq[4]
+
+ LDR r11, [r13, #-12] @ Aq[6] -- Aq[5]
+ LDRSH r10, [r4, #-16] @ load sig_hi[i-8]
+
+ SMLABB r12, r6, r11, r12 @ sig_hi[i-5] * Aq[5]
+
+ LDRSH r6, [r4, #-18] @ load sig_hi[i-9]
+ SMLABT r12, r7, r11, r12 @ sig_hi[i-6] * Aq[6]
+
+ LDR r11, [r13, #-16] @ Aq[8] -- Aq[7]
+ LDRSH r7, [r4, #-20] @ load sig_hi[i-10]
+
+ SMLABB r12, r9, r11, r12 @ sig_hi[i-7] * Aq[7]
+
+ LDRSH r9, [r4, #-22] @ load sig_hi[i-11]
+
+ SMLABT r12, r10, r11, r12 @ sig_hi[i-8] * Aq[8]
+
+ LDR r11, [r13, #-20] @ Aq[10] -- Aq[9]
+ LDRSH r10,[r4, #-24] @ load sig_hi[i-12]
+
+ SMLABB r12, r6, r11, r12 @ sig_hi[i-9] * Aq[9]
+ LDRSH r6, [r4, #-26] @ load sig_hi[i-13]
+ SMLABT r12, r7, r11, r12 @ sig_hi[i-10] * Aq[10]
+
+ LDR r11, [r13, #-24] @ Aq[12] -- Aq[11]
+ LDRSH r7, [r4, #-28] @ load sig_hi[i-14]
+ SMLABB r12, r9, r11, r12 @ sig_hi[i-11] * Aq[11]
+ LDRSH r9, [r4, #-30] @ load sig_hi[i-15]
+ SMLABT r12, r10, r11, r12 @ sig_hi[i-12] * Aq[12]
+
+ LDR r11, [r13, #-28] @ Aq[14] -- Aq[13]
+ LDRSH r10, [r4, #-32] @ load sig_hi[i-16]
+ SMLABB r12, r6, r11, r12 @ sig_hi[i-13] * Aq[13]
+ SMLABT r12, r7, r11, r12 @ sig_hi[i-14] * Aq[14]
+
+ LDR r11, [r13, #-32] @ Aq[16] -- Aq[15]
+ SMLABB r12, r9, r11, r12 @ sig_hi[i-15] * Aq[15]
+ SMLABT r12, r10, r11, r12 @ sig_hi[i-16] * Aq[16]
+ ADD r6, r12, r12 @ r12 << 1
+ SUB r14, r14, r6
+ MOV r14, r14, LSL #3 @ L_tmp <<=3
+
+ MOV r7, r14, ASR #16 @ L_tmp >> 16
+
+ MOV r14, r14, ASR #4 @ L_tmp >>=4
+ STRH r7, [r4], #2 @ sig_hi[i] = L_tmp >> 16
+ SUB r9, r14, r7, LSL #12 @ sig_lo[i] = L_tmp - (sig_hi[i] << 12)
+
+ ADD r8, r8, #1
+ STRH r9, [r5], #2
+ CMP r8, #64
+ BLT LOOP
+
+Syn_filt_32_end:
+
+ LDMFD r13!, {r4 - r12, r15}
+ @ENDFUNC
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
new file mode 100644
index 0000000..0228bda
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
@@ -0,0 +1,186 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+
+
+@*void Convolve (
+@* Word16 x[], /* (i) : input vector */
+@* Word16 h[], /* (i) : impulse response */
+@* Word16 y[], /* (o) : output vector */
+@* Word16 L /* (i) : vector size */
+@*)
+@ r0 --- x[]
+@ r1 --- h[]
+@ r2 --- y[]
+@ r3 --- L
+
+ .section .text
+ .global Convolve_asm
+
+Convolve_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ MOV r3, #0 @ n
+ MOV r11, #0x8000
+
+LOOP:
+ ADD r4, r1, r3, LSL #1 @ tmpH address
+ ADD r5, r3, #1 @ i = n + 1
+ MOV r6, r0 @ tmpX = x
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2 @ *tmpH--
+ SUB r5, r5, #1
+ MUL r8, r9, r10
+
+LOOP1:
+ CMP r5, #0
+ BLE L1
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2 @ *tmpH--
+ LDRSH r12, [r6], #2 @ *tmpX++
+ LDRSH r14, [r4], #-2 @ *tmpH--
+ MLA r8, r9, r10, r8
+ MLA r8, r12, r14, r8
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2 @ *tmpH--
+ LDRSH r12, [r6], #2 @ *tmpX++
+ LDRSH r14, [r4], #-2 @ *tmpH--
+ MLA r8, r9, r10, r8
+ SUBS r5, r5, #4
+ MLA r8, r12, r14, r8
+
+ B LOOP1
+
+L1:
+
+ ADD r5, r11, r8, LSL #1
+ MOV r5, r5, LSR #16 @extract_h(s)
+ ADD r3, r3, #1
+ STRH r5, [r2], #2 @y[n]
+
+
+ ADD r4, r1, r3, LSL #1 @tmpH address
+ ADD r5, r3, #1
+ MOV r6, r0
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2
+ LDRSH r12, [r6], #2
+ LDRSH r14, [r4], #-2
+
+ MUL r8, r9, r10
+ SUB r5, r5, #2
+ MLA r8, r12, r14, r8
+
+LOOP2:
+ CMP r5, #0
+ BLE L2
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2 @ *tmpH--
+ LDRSH r12, [r6], #2 @ *tmpX++
+ LDRSH r14, [r4], #-2 @ *tmpH--
+ MLA r8, r9, r10, r8
+ MLA r8, r12, r14, r8
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2 @ *tmpH--
+ LDRSH r12, [r6], #2 @ *tmpX++
+ LDRSH r14, [r4], #-2 @ *tmpH--
+ MLA r8, r9, r10, r8
+ SUBS r5, r5, #4
+ MLA r8, r12, r14, r8
+ B LOOP2
+
+L2:
+ ADD r8, r11, r8, LSL #1
+ MOV r8, r8, LSR #16 @extract_h(s)
+ ADD r3, r3, #1
+ STRH r8, [r2], #2 @y[n]
+
+ ADD r4, r1, r3, LSL #1
+ ADD r5, r3, #1
+ MOV r6, r0
+ LDRSH r9, [r6], #2
+ LDRSH r10, [r4], #-2
+ LDRSH r12, [r6], #2
+ LDRSH r14, [r4], #-2
+ MUL r8, r9, r10
+ LDRSH r9, [r6], #2
+ LDRSH r10, [r4], #-2
+ MLA r8, r12, r14, r8
+ SUB r5, r5, #3
+ MLA r8, r9, r10, r8
+
+LOOP3:
+ CMP r5, #0
+ BLE L3
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2 @ *tmpH--
+ LDRSH r12, [r6], #2 @ *tmpX++
+ LDRSH r14, [r4], #-2 @ *tmpH--
+ MLA r8, r9, r10, r8
+ MLA r8, r12, r14, r8
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2 @ *tmpH--
+ LDRSH r12, [r6], #2 @ *tmpX++
+ LDRSH r14, [r4], #-2 @ *tmpH--
+ MLA r8, r9, r10, r8
+ SUBS r5, r5, #4
+ MLA r8, r12, r14, r8
+ B LOOP3
+
+L3:
+ ADD r8, r11, r8, LSL #1
+ MOV r8, r8, LSR #16 @extract_h(s)
+ ADD r3, r3, #1
+ STRH r8, [r2], #2 @y[n]
+
+ ADD r5, r3, #1 @ i = n + 1
+ ADD r4, r1, r3, LSL #1 @ tmpH address
+ MOV r6, r0
+ MOV r8, #0
+
+LOOP4:
+ CMP r5, #0
+ BLE L4
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2 @ *tmpH--
+ LDRSH r12, [r6], #2 @ *tmpX++
+ LDRSH r14, [r4], #-2 @ *tmpH--
+ MLA r8, r9, r10, r8
+ MLA r8, r12, r14, r8
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2 @ *tmpH--
+ LDRSH r12, [r6], #2 @ *tmpX++
+ LDRSH r14, [r4], #-2 @ *tmpH--
+ MLA r8, r9, r10, r8
+ SUBS r5, r5, #4
+ MLA r8, r12, r14, r8
+ B LOOP4
+L4:
+ ADD r5, r11, r8, LSL #1
+ MOV r5, r5, LSR #16 @extract_h(s)
+ ADD r3, r3, #1
+ STRH r5, [r2], #2 @y[n]
+
+ CMP r3, #64
+ BLT LOOP
+
+Convolve_asm_end:
+
+ LDMFD r13!, {r4 - r12, r15}
+
+ @ENDFUNC
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
new file mode 100644
index 0000000..441b984
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
@@ -0,0 +1,151 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@static void cor_h_vec_012(
+@ Word16 h[], /* (i) scaled impulse response */
+@ Word16 vec[], /* (i) scaled vector (/8) to correlate with h[] */
+@ Word16 track, /* (i) track to use */
+@ Word16 sign[], /* (i) sign vector */
+@ Word16 rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */
+@ Word16 cor_1[], /* (o) result of correlation (NB_POS elements) */
+@ Word16 cor_2[] /* (o) result of correlation (NB_POS elements) */
+@)
+@r0 ---- h[]
+@r1 ---- vec[]
+@r2 ---- track
+@r3 ---- sign[]
+@r4 ---- rrixix[][NB_POS]
+@r5 ---- cor_1[]
+@r6 ---- cor_2[]
+
+
+ .section .text
+ .global cor_h_vec_012_asm
+
+cor_h_vec_012_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ LDR r4, [r13, #40] @load rrixix[][NB_POS]
+ ADD r7, r4, r2, LSL #5 @r7 --- p0 = rrixix[track]
+ MOV r4, #0 @i=0
+
+ @r0 --- h[], r1 --- vec[], r2 --- pos
+ @r3 --- sign[], r4 --- i, r7 --- p0
+LOOPi:
+ MOV r5, #0 @L_sum1 = 0
+ MOV r6, #0 @L_sum2 = 0
+ ADD r9, r1, r2, LSL #1 @p2 = &vec[pos]
+ MOV r10, r0 @p1 = h
+ RSB r11, r2, #62 @j=62-pos
+
+LOOPj1:
+ LDRSH r12, [r10], #2
+ LDRSH r8, [r9], #2
+ LDRSH r14, [r9]
+ SUBS r11, r11, #1
+ MLA r5, r12, r8, r5
+ MLA r6, r12, r14, r6
+ BGE LOOPj1
+
+ LDRSH r12, [r10], #2 @*p1++
+ MOV r6, r6, LSL #2 @L_sum2 = (L_sum2 << 2)
+ MLA r5, r12, r14, r5
+ MOV r14, #0x8000
+ MOV r5, r5, LSL #2 @L_sum1 = (L_sum1 << 2)
+ ADD r10, r6, r14
+ ADD r9, r5, r14
+ MOV r5, r9, ASR #16
+ MOV r6, r10, ASR #16
+ ADD r9, r3, r2, LSL #1 @address of sign[pos]
+ ADD r8, r7, #32
+ LDRSH r10, [r9], #2 @sign[pos]
+ LDRSH r11, [r9] @sign[pos + 1]
+ MUL r12, r5, r10
+ MUL r14, r6, r11
+ MOV r5, r12, ASR #15
+ MOV r6, r14, ASR #15
+ LDR r9, [r13, #44]
+ LDR r12, [r13, #48]
+ LDRSH r10, [r7], #2 @*p0++
+ LDRSH r11, [r8] @*p3++
+ ADD r9, r9, r4, LSL #1
+ ADD r12, r12, r4, LSL #1
+ ADD r5, r5, r10
+ ADD r6, r6, r11
+ STRH r5, [r9]
+ STRH r6, [r12]
+
+ ADD r2, r2, #4
+
+ MOV r5, #0 @L_sum1 = 0
+ MOV r6, #0 @L_sum2 = 0
+ ADD r9, r1, r2, LSL #1 @p2 = &vec[pos]
+ MOV r10, r0 @p1 = h
+ RSB r11, r2, #62 @j=62-pos
+ ADD r4, r4, #1 @i++
+
+LOOPj2:
+ LDRSH r12, [r10], #2
+ LDRSH r8, [r9], #2
+ LDRSH r14, [r9]
+ SUBS r11, r11, #1
+ MLA r5, r12, r8, r5
+ MLA r6, r12, r14, r6
+ BGE LOOPj2
+
+ LDRSH r12, [r10], #2 @*p1++
+ MOV r6, r6, LSL #2 @L_sum2 = (L_sum2 << 2)
+ MLA r5, r12, r14, r5
+ MOV r14, #0x8000
+ MOV r5, r5, LSL #2 @L_sum1 = (L_sum1 << 2)
+ ADD r10, r6, r14
+ ADD r9, r5, r14
+
+ MOV r5, r9, ASR #16
+ MOV r6, r10, ASR #16
+ ADD r9, r3, r2, LSL #1 @address of sign[pos]
+ ADD r8, r7, #32
+ LDRSH r10, [r9], #2 @sign[pos]
+ LDRSH r11, [r9] @sign[pos + 1]
+ MUL r12, r5, r10
+ MUL r14, r6, r11
+ MOV r5, r12, ASR #15
+ MOV r6, r14, ASR #15
+ LDR r9, [r13, #44]
+ LDR r12, [r13, #48]
+ LDRSH r10, [r7], #2 @*p0++
+ LDRSH r11, [r8] @*p3++
+ ADD r9, r9, r4, LSL #1
+ ADD r12, r12, r4, LSL #1
+ ADD r5, r5, r10
+ ADD r6, r6, r11
+ STRH r5, [r9]
+ STRH r6, [r12]
+ ADD r4, r4, #1 @i+1
+ ADD r2, r2, #4 @pos += STEP
+ CMP r4, #16
+
+ BLT LOOPi
+
+the_end:
+ LDMFD r13!, {r4 - r12, r15}
+
+ @ENDFUNC
+ .END
+
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
new file mode 100644
index 0000000..d5dd8f0
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
@@ -0,0 +1,460 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@void Pred_lt4(
+@ Word16 exc[], /* in/out: excitation buffer */
+@ Word16 T0, /* input : integer pitch lag */
+@ Word16 frac, /* input : fraction of lag */
+@ Word16 L_subfr /* input : subframe size */
+@ )
+
+@******************************
+@ ARM Register
+@******************************
+@ r0 --- exc[]
+@ r1 --- T0
+@ r2 --- frac
+@ r3 --- L_subfr
+
+ .section .text
+ .global pred_lt4_asm
+ .extern inter4_2
+
+pred_lt4_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ RSB r4, r1, #0 @-T0
+ RSB r2, r2, #0 @frac = -frac
+ ADD r5, r0, r4, LSL #1 @x = exc - T0
+ CMP r2, #0
+ ADDLT r2, r2, #4 @frac += UP_SAMP
+ SUBLT r5, r5, #2 @x--
+ SUB r5, r5, #30 @x -= 15
+ RSB r4, r2, #3 @k = 3 - frac
+ LDR r6, Table
+ MOV r8, r4, LSL #6
+ @MOV r7, #0 @j = 0
+ ADD r8, r6, r8 @ptr2 = &(inter4_2[k][0])
+
+ MOV r1, r5
+ MOV r5, #0x8000
+ MOV r14, #21
+@ used register
+ @r0 --- exc[] r1 --- x r7 --- j r8 --- ptr2 r5 --- 0x8000
+THREE_LOOP:
+
+ @MOV r1, r5 @ptr1 = x
+ MOV r2, r8 @ptr = ptr2
+ LDR r3, [r2], #4 @h[0], h[1]
+ LDRSH r4, [r1], #2 @x[0]
+ LDRSH r6, [r1], #2 @x[1]
+ LDRSH r9, [r1], #2 @x[2]
+
+ SMULBB r10, r4, r3 @x[0] * h[0]
+ SMULBB r11, r6, r3 @x[1] * h[0]
+ SMULBB r12, r9, r3 @x[2] * h[0]
+
+ LDRSH r4, [r1], #2 @x[3]
+ SMLABT r10, r6, r3, r10 @x[1] * h[1]
+ SMLABT r11, r9, r3, r11 @x[2] * h[1]
+ SMLABT r12, r4, r3, r12 @x[3] * h[1]
+
+ LDR r3, [r2], #4 @h[2], h[3]
+ LDRSH r6, [r1], #2 @x[4]
+ SMLABB r10, r9, r3, r10 @x[2] * h[2]
+ SMLABB r11, r4, r3, r11 @x[3] * h[2]
+ SMLABB r12, r6, r3, r12 @x[4] * h[2]
+
+ LDRSH r9, [r1], #2 @x[5]
+ SMLABT r10, r4, r3, r10 @x[3] * h[3]
+ SMLABT r11, r6, r3, r11 @x[4] * h[3]
+ SMLABT r12, r9, r3, r12 @x[5] * h[3]
+
+ LDR r3, [r2], #4 @h[4], h[5]
+ LDRSH r4, [r1], #2 @x[6]
+ SMLABB r10, r6, r3, r10 @x[4] * h[4]
+ SMLABB r11, r9, r3, r11 @x[5] * h[4]
+ SMLABB r12, r4, r3, r12 @x[6] * h[4]
+
+ LDRSH r6, [r1], #2 @x[7]
+ SMLABT r10, r9, r3, r10 @x[5] * h[5]
+ SMLABT r11, r4, r3, r11 @x[6] * h[5]
+ SMLABT r12, r6, r3, r12 @x[7] * h[5]
+
+ LDR r3, [r2], #4 @h[6], h[7]
+ LDRSH r9, [r1], #2 @x[8]
+ SMLABB r10, r4, r3, r10 @x[6] * h[6]
+ SMLABB r11, r6, r3, r11 @x[7] * h[6]
+ SMLABB r12, r9, r3, r12 @x[8] * h[6]
+
+ LDRSH r4, [r1], #2 @x[9]
+ SMLABT r10, r6, r3, r10 @x[7] * h[7]
+ SMLABT r11, r9, r3, r11 @x[8] * h[7]
+ SMLABT r12, r4, r3, r12 @x[9] * h[7]
+
+ LDR r3, [r2], #4 @h[8], h[9]
+ LDRSH r6, [r1], #2 @x[10]
+ SMLABB r10, r9, r3, r10 @x[8] * h[8]
+ SMLABB r11, r4, r3, r11 @x[9] * h[8]
+ SMLABB r12, r6, r3, r12 @x[10] * h[8]
+
+ LDRSH r9, [r1], #2 @x[11]
+ SMLABT r10, r4, r3, r10 @x[9] * h[9]
+ SMLABT r11, r6, r3, r11 @x[10] * h[9]
+ SMLABT r12, r9, r3, r12 @x[11] * h[9]
+
+ LDR r3, [r2], #4 @h[10], h[11]
+ LDRSH r4, [r1], #2 @x[12]
+ SMLABB r10, r6, r3, r10 @x[10] * h[10]
+ SMLABB r11, r9, r3, r11 @x[11] * h[10]
+ SMLABB r12, r4, r3, r12 @x[12] * h[10]
+
+ LDRSH r6, [r1], #2 @x[13]
+ SMLABT r10, r9, r3, r10 @x[11] * h[11]
+ SMLABT r11, r4, r3, r11 @x[12] * h[11]
+ SMLABT r12, r6, r3, r12 @x[13] * h[11]
+
+ LDR r3, [r2], #4 @h[12], h[13]
+ LDRSH r9, [r1], #2 @x[14]
+ SMLABB r10, r4, r3, r10 @x[12] * h[12]
+ SMLABB r11, r6, r3, r11 @x[13] * h[12]
+ SMLABB r12, r9, r3, r12 @x[14] * h[12]
+
+ LDRSH r4, [r1], #2 @x[15]
+ SMLABT r10, r6, r3, r10 @x[13] * h[13]
+ SMLABT r11, r9, r3, r11 @x[14] * h[13]
+ SMLABT r12, r4, r3, r12 @x[15] * h[13]
+
+ LDR r3, [r2], #4 @h[14], h[15]
+ LDRSH r6, [r1], #2 @x[16]
+ SMLABB r10, r9, r3, r10 @x[14] * h[14]
+ SMLABB r11, r4, r3, r11 @x[15] * h[14]
+ SMLABB r12, r6, r3, r12 @x[16] * h[14]
+
+ LDRSH r9, [r1], #2 @x[17]
+ SMLABT r10, r4, r3, r10 @x[15] * h[15]
+ SMLABT r11, r6, r3, r11 @x[16] * h[15]
+ SMLABT r12, r9, r3, r12 @x[17] * h[15]
+
+ LDR r3, [r2], #4 @h[16], h[17]
+ LDRSH r4, [r1], #2 @x[18]
+ SMLABB r10, r6, r3, r10 @x[16] * h[16]
+ SMLABB r11, r9, r3, r11 @x[17] * h[16]
+ SMLABB r12, r4, r3, r12 @x[18] * h[16]
+
+ LDRSH r6, [r1], #2 @x[19]
+ SMLABT r10, r9, r3, r10 @x[17] * h[17]
+ SMLABT r11, r4, r3, r11 @x[18] * h[17]
+ SMLABT r12, r6, r3, r12 @x[19] * h[17]
+
+ LDR r3, [r2], #4 @h[18], h[19]
+ LDRSH r9, [r1], #2 @x[20]
+ SMLABB r10, r4, r3, r10 @x[18] * h[18]
+ SMLABB r11, r6, r3, r11 @x[19] * h[18]
+ SMLABB r12, r9, r3, r12 @x[20] * h[18]
+
+ LDRSH r4, [r1], #2 @x[21]
+ SMLABT r10, r6, r3, r10 @x[19] * h[19]
+ SMLABT r11, r9, r3, r11 @x[20] * h[19]
+ SMLABT r12, r4, r3, r12 @x[21] * h[19]
+
+ LDR r3, [r2], #4 @h[20], h[21]
+ LDRSH r6, [r1], #2 @x[22]
+ SMLABB r10, r9, r3, r10 @x[20] * h[20]
+ SMLABB r11, r4, r3, r11 @x[21] * h[20]
+ SMLABB r12, r6, r3, r12 @x[22] * h[20]
+
+ LDRSH r9, [r1], #2 @x[23]
+ SMLABT r10, r4, r3, r10 @x[21] * h[21]
+ SMLABT r11, r6, r3, r11 @x[22] * h[21]
+ SMLABT r12, r9, r3, r12 @x[23] * h[21]
+
+ LDR r3, [r2], #4 @h[22], h[23]
+ LDRSH r4, [r1], #2 @x[24]
+ SMLABB r10, r6, r3, r10 @x[22] * h[22]
+ SMLABB r11, r9, r3, r11 @x[23] * h[22]
+ SMLABB r12, r4, r3, r12 @x[24] * h[22]
+
+ LDRSH r6, [r1], #2 @x[25]
+ SMLABT r10, r9, r3, r10 @x[23] * h[23]
+ SMLABT r11, r4, r3, r11 @x[24] * h[23]
+ SMLABT r12, r6, r3, r12 @x[25] * h[23]
+
+ LDR r3, [r2], #4 @h[24], h[25]
+ LDRSH r9, [r1], #2 @x[26]
+ SMLABB r10, r4, r3, r10 @x[24] * h[24]
+ SMLABB r11, r6, r3, r11 @x[25] * h[24]
+ SMLABB r12, r9, r3, r12 @x[26] * h[24]
+
+ LDRSH r4, [r1], #2 @x[27]
+ SMLABT r10, r6, r3, r10 @x[25] * h[25]
+ SMLABT r11, r9, r3, r11 @x[26] * h[25]
+ SMLABT r12, r4, r3, r12 @x[27] * h[25]
+
+ LDR r3, [r2], #4 @h[26], h[27]
+ LDRSH r6, [r1], #2 @x[28]
+ SMLABB r10, r9, r3, r10 @x[26] * h[26]
+ SMLABB r11, r4, r3, r11 @x[27] * h[26]
+ SMLABB r12, r6, r3, r12 @x[28] * h[26]
+
+ LDRSH r9, [r1], #2 @x[29]
+ SMLABT r10, r4, r3, r10 @x[27] * h[27]
+ SMLABT r11, r6, r3, r11 @x[28] * h[27]
+ SMLABT r12, r9, r3, r12 @x[29] * h[27]
+
+ LDR r3, [r2], #4 @h[28], h[29]
+ LDRSH r4, [r1], #2 @x[30]
+ SMLABB r10, r6, r3, r10 @x[28] * h[28]
+ SMLABB r11, r9, r3, r11 @x[29] * h[28]
+ SMLABB r12, r4, r3, r12 @x[30] * h[28]
+
+ LDRSH r6, [r1], #2 @x[31]
+ SMLABT r10, r9, r3, r10 @x[29] * h[29]
+ SMLABT r11, r4, r3, r11 @x[30] * h[29]
+ SMLABT r12, r6, r3, r12 @x[31] * h[29]
+
+ LDR r3, [r2], #4 @h[30], h[31]
+ LDRSH r9, [r1], #2 @x[32]
+ SMLABB r10, r4, r3, r10 @x[30] * h[30]
+ SMLABB r11, r6, r3, r11 @x[31] * h[30]
+ SMLABB r12, r9, r3, r12 @x[32] * h[30]
+
+ LDRSH r4, [r1], #-60 @x[33]
+ SMLABT r10, r6, r3, r10 @x[31] * h[31]
+ SMLABT r11, r9, r3, r11 @x[32] * h[31]
+ SMLABT r12, r4, r3, r12 @x[33] * h[31]
+
+ @SSAT r10, #32, r10, LSL #2
+ @SSAT r11, #32, r11, LSL #2
+ @SSAT r12, #32, r12, LSL #2
+
+ MOV r10, r10, LSL #1
+ MOV r11, r11, LSL #1
+ MOV r12, r12, LSL #1
+
+ QADD r10, r10, r10
+ QADD r11, r11, r11
+ QADD r12, r12, r12
+
+ QADD r10, r10, r5
+ QADD r11, r11, r5
+ QADD r12, r12, r5
+
+ SUBS r14, r14, #1
+
+ MOV r10, r10, ASR #16
+ MOV r11, r11, ASR #16
+ MOV r12, r12, ASR #16
+
+ STRH r10, [r0], #2
+ STRH r11, [r0], #2
+ STRH r12, [r0], #2
+ BNE THREE_LOOP
+
+ MOV r2, r8 @ptr = ptr2
+
+Last2LOOP:
+
+ LDR r3, [r2], #4 @h[0], h[1]
+ LDRSH r4, [r1], #2 @x[0]
+ LDRSH r6, [r1], #2 @x[1]
+ LDRSH r9, [r1], #2 @x[2]
+
+ SMULBB r10, r4, r3 @x[0] * h[0]
+ SMULBB r11, r6, r3 @x[1] * h[0]
+
+ SMLABT r10, r6, r3, r10 @x[1] * h[1]
+ SMLABT r11, r9, r3, r11 @x[2] * h[1]
+
+ LDR r3, [r2], #4 @h[2], h[3]
+ LDRSH r4, [r1], #2 @x[3]
+ LDRSH r6, [r1], #2 @x[4]
+
+ SMLABB r10, r9, r3, r10 @x[2] * h[2]
+ SMLABB r11, r4, r3, r11 @x[3] * h[2]
+
+ SMLABT r10, r4, r3, r10 @x[3] * h[3]
+ SMLABT r11, r6, r3, r11 @x[4] * h[3]
+
+ LDR r3, [r2], #4 @h[4], h[5]
+ LDRSH r9, [r1], #2 @x[5]
+ LDRSH r4, [r1], #2 @x[6]
+
+ SMLABB r10, r6, r3, r10 @x[4] * h[4]
+ SMLABB r11, r9, r3, r11 @x[5] * h[4]
+
+ SMLABT r10, r9, r3, r10 @x[5] * h[5]
+ SMLABT r11, r4, r3, r11 @x[6] * h[5]
+
+ LDR r3, [r2], #4 @h[6], h[7]
+ LDRSH r6, [r1], #2 @x[7]
+ LDRSH r9, [r1], #2 @x[8]
+
+ SMLABB r10, r4, r3, r10 @x[6] * h[6]
+ SMLABB r11, r6, r3, r11 @x[7] * h[6]
+
+ SMLABT r10, r6, r3, r10 @x[7] * h[7]
+ SMLABT r11, r9, r3, r11 @x[8] * h[7]
+
+ LDR r3, [r2], #4 @h[8], h[9]
+ LDRSH r4, [r1], #2 @x[9]
+ LDRSH r6, [r1], #2 @x[10]
+
+ SMLABB r10, r9, r3, r10 @x[8] * h[8]
+ SMLABB r11, r4, r3, r11 @x[9] * h[8]
+
+ SMLABT r10, r4, r3, r10 @x[9] * h[9]
+ SMLABT r11, r6, r3, r11 @x[10] * h[9]
+
+ LDR r3, [r2], #4 @h[10], h[11]
+ LDRSH r9, [r1], #2 @x[11]
+ LDRSH r4, [r1], #2 @x[12]
+
+ SMLABB r10, r6, r3, r10 @x[10] * h[10]
+ SMLABB r11, r9, r3, r11 @x[11] * h[10]
+
+ SMLABT r10, r9, r3, r10 @x[11] * h[11]
+ SMLABT r11, r4, r3, r11 @x[12] * h[11]
+
+ LDR r3, [r2], #4 @h[12], h[13]
+ LDRSH r6, [r1], #2 @x[13]
+ LDRSH r9, [r1], #2 @x[14]
+
+ SMLABB r10, r4, r3, r10 @x[12] * h[12]
+ SMLABB r11, r6, r3, r11 @x[13] * h[12]
+
+ SMLABT r10, r6, r3, r10 @x[13] * h[13]
+ SMLABT r11, r9, r3, r11 @x[14] * h[13]
+
+ LDR r3, [r2], #4 @h[14], h[15]
+ LDRSH r4, [r1], #2 @x[15]
+ LDRSH r6, [r1], #2 @x[16]
+
+ SMLABB r10, r9, r3, r10 @x[14] * h[14]
+ SMLABB r11, r4, r3, r11 @x[15] * h[14]
+
+ SMLABT r10, r4, r3, r10 @x[15] * h[15]
+ SMLABT r11, r6, r3, r11 @x[16] * h[15]
+
+ LDR r3, [r2], #4 @h[16], h[17]
+ LDRSH r9, [r1], #2 @x[17]
+ LDRSH r4, [r1], #2 @x[18]
+
+ SMLABB r10, r6, r3, r10 @x[16] * h[16]
+ SMLABB r11, r9, r3, r11 @x[17] * h[16]
+
+ SMLABT r10, r9, r3, r10 @x[17] * h[17]
+ SMLABT r11, r4, r3, r11 @x[18] * h[17]
+
+ LDR r3, [r2], #4 @h[18], h[19]
+ LDRSH r6, [r1], #2 @x[19]
+ LDRSH r9, [r1], #2 @x[20]
+
+ SMLABB r10, r4, r3, r10 @x[18] * h[18]
+ SMLABB r11, r6, r3, r11 @x[19] * h[18]
+
+ SMLABT r10, r6, r3, r10 @x[19] * h[19]
+ SMLABT r11, r9, r3, r11 @x[20] * h[19]
+
+ LDR r3, [r2], #4 @h[20], h[21]
+ LDRSH r4, [r1], #2 @x[21]
+ LDRSH r6, [r1], #2 @x[22]
+
+ SMLABB r10, r9, r3, r10 @x[20] * h[20]
+ SMLABB r11, r4, r3, r11 @x[21] * h[20]
+
+ SMLABT r10, r4, r3, r10 @x[21] * h[21]
+ SMLABT r11, r6, r3, r11 @x[22] * h[21]
+
+ LDR r3, [r2], #4 @h[22], h[23]
+ LDRSH r9, [r1], #2 @x[23]
+ LDRSH r4, [r1], #2 @x[24]
+
+ SMLABB r10, r6, r3, r10 @x[22] * h[22]
+ SMLABB r11, r9, r3, r11 @x[23] * h[22]
+
+ SMLABT r10, r9, r3, r10 @x[23] * h[23]
+ SMLABT r11, r4, r3, r11 @x[24] * h[23]
+
+ LDR r3, [r2], #4 @h[24], h[25]
+ LDRSH r6, [r1], #2 @x[25]
+ LDRSH r9, [r1], #2 @x[26]
+
+ SMLABB r10, r4, r3, r10 @x[24] * h[24]
+ SMLABB r11, r6, r3, r11 @x[25] * h[24]
+
+ SMLABT r10, r6, r3, r10 @x[25] * h[25]
+ SMLABT r11, r9, r3, r11 @x[26] * h[25]
+
+ LDR r3, [r2], #4 @h[26], h[27]
+ LDRSH r4, [r1], #2 @x[27]
+ LDRSH r6, [r1], #2 @x[28]
+
+ SMLABB r10, r9, r3, r10 @x[26] * h[26]
+ SMLABB r11, r4, r3, r11 @x[27] * h[26]
+
+ SMLABT r10, r4, r3, r10 @x[27] * h[27]
+ SMLABT r11, r6, r3, r11 @x[28] * h[27]
+
+ LDR r3, [r2], #4 @h[28], h[29]
+ LDRSH r9, [r1], #2 @x[29]
+ LDRSH r4, [r1], #2 @x[30]
+
+ SMLABB r10, r6, r3, r10 @x[28] * h[28]
+ SMLABB r11, r9, r3, r11 @x[29] * h[28]
+
+ SMLABT r10, r9, r3, r10 @x[29] * h[29]
+ SMLABT r11, r4, r3, r11 @x[30] * h[29]
+
+ LDR r3, [r2], #4 @h[30], h[31]
+ LDRSH r6, [r1], #2 @x[31]
+ LDRSH r9, [r1], #2 @x[32]
+
+ SMLABB r10, r4, r3, r10 @x[30] * h[30]
+ SMLABB r11, r6, r3, r11 @x[31] * h[30]
+
+ SMLABT r10, r6, r3, r10 @x[31] * h[31]
+ SMLABT r11, r9, r3, r11 @x[32] * h[31]
+
+ @SSAT r10, #32, r10, LSL #2
+ @SSAT r11, #32, r11, LSL #2
+ MOV r10, r10, LSL #1
+ MOV r11, r11, LSL #1
+
+ QADD r10, r10, r10
+ QADD r11, r11, r11
+
+ QADD r10, r10, r5
+ QADD r11, r11, r5
+
+ MOV r10, r10, ASR #16
+ MOV r11, r11, ASR #16
+
+ STRH r10, [r0], #2
+ STRH r11, [r0], #2
+
+
+pred_lt4_end:
+ LDMFD r13!, {r4 - r12, r15}
+
+Table:
+ .word inter4_2
+ @ENDFUNC
+ .END
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
new file mode 100644
index 0000000..060d9c7
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
@@ -0,0 +1,228 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@void Residu(
+@ Word16 a[], /* (i) Q12 : prediction coefficients */
+@ Word16 x[], /* (i) : speech (values x[-m..-1] are needed */
+@ Word16 y[], /* (o) x2 : residual signal */
+@ Word16 lg /* (i) : size of filtering */
+@ )
+@a[] --- r0
+@x[] --- r1
+@y[] --- r2
+@lg --- r3
+
+ .section .text
+ .global Residu_opt
+
+Residu_opt:
+
+ STMFD r13!, {r4 - r12, r14}
+
+ LDRH r5, [r0], #2
+ LDRH r6, [r0], #2
+ ORR r5, r6, r5, LSL #16 @r5 --- a0, a1
+
+ LDRH r6, [r0], #2
+ LDRH r7, [r0], #2
+ ORR r6, r7, r6, LSL #16 @r6 --- a2, a3
+
+ LDRH r7, [r0], #2
+ LDRH r8, [r0], #2
+ ORR r7, r8, r7, LSL #16 @r7 --- a4, a5
+
+ LDRH r8, [r0], #2
+ LDRH r9, [r0], #2
+ ORR r8, r9, r8, LSL #16 @r8 --- a6, a7
+
+ LDRH r9, [r0], #2
+ LDRH r10, [r0], #2
+ ORR r9, r10, r9, LSL #16 @r9 --- a8, a9
+
+ LDRH r10, [r0], #2
+ LDRH r11, [r0], #2
+ ORR r10, r11, r10, LSL #16 @r10 --- a10, a11
+
+ LDRH r11, [r0], #2
+ LDRH r12, [r0], #2
+ ORR r11, r12, r11, LSL #16 @r11 --- a12, a13
+
+ LDRH r12, [r0], #2
+ LDRH r4, [r0], #2
+ ORR r12, r4, r12, LSL #16 @r12 --- a14, a15
+
+
+ STMFD r13!, {r8 - r12} @store r8-r12
+ LDRH r4, [r0], #2 @load a16
+ MOV r14, r3, ASR #2 @one loop get 4 outputs
+ ADD r1, r1, #4
+ MOV r0, r2
+ ORR r14, r4, r14, LSL #16 @r14 --- loopnum, a16
+
+residu_loop:
+
+ LDR r10, [r1], #-4 @r10 --- x[3], x[2]
+ LDR r2, [r1], #-4 @r2 --- x[1], x[0]
+
+ SMULTB r3, r5, r2 @i1(0) --- r3 = x[0] * a0
+ SMULTT r4, r5, r2 @i2(0) --- r4 = x[1] * a0
+ SMULTB r11, r5, r10 @i3(0) --- r11 = x[2] * a0
+ SMULTT r12, r5, r10 @i4(0) --- r12 = x[3] * a0
+
+ SMLABB r4, r5, r2, r4 @i2(1) --- r4 += x[0] * a1
+ SMLABT r11, r5, r2, r11 @i3(1) --- r11 += x[1] * a0
+ SMLABB r12, r5, r10, r12 @i4(1) --- r12 += x[2] * a1
+
+ SMLATB r11, r6, r2, r11 @i3(2) --- r11 += x[0] * a2
+ SMLATT r12, r6, r2, r12 @i4(2) --- r12 += x[1] * a2
+ SMLABB r12, r6, r2, r12 @i4(3) --- r12 += x[0] * a3
+
+ LDR r2, [r1], #-4 @r2 ---- x[-1], x[-2]
+
+ SMLABT r3, r5, r2, r3 @i1(1) --- r3 += x[-1] * a1
+ SMLATT r4, r6, r2, r4 @i2(2) --- r4 += x[-1] * a2
+ SMLABT r11, r6, r2, r11 @i3(3) --- r11 += x[-1] * a3
+ SMLATT r12, r7, r2, r12 @i4(4) --- r12 += x[-1] * a4
+ SMLATB r3, r6, r2, r3 @i1(2) --- r3 += x[-2] * a2
+
+ SMLABB r4, r6, r2, r4 @ i2 (3)
+ SMLATB r11,r7, r2, r11 @ i3 (4)
+ SMLABB r12,r7, r2, r12 @ i4 (5)
+
+ LDR r2,[r1],#-4
+ SMLABT r3, r6, r2, r3 @ i1 (3)
+ SMLATT r4, r7, r2, r4 @ i2 (4)
+ SMLABT r11,r7, r2, r11 @ i3 (5)
+ SMLATT r12,r8, r2, r12 @ i4 (6)
+ SMLATB r3, r7, r2, r3 @ i1 (4)
+ SMLABB r4, r7, r2, r4 @ i2 (5)
+ SMLATB r11,r8, r2, r11 @ i3 (6)
+ SMLABB r12,r8, r2, r12 @ i4 (7)
+
+ LDR r2,[r1],#-4
+ SMLABT r3, r7, r2, r3 @ i1 (5)
+ SMLATT r4, r8, r2, r4 @ i2 (6)
+ SMLABT r11,r8, r2, r11 @ i3 (7)
+ SMLATT r12,r9, r2, r12 @ i4 (8)
+ SMLATB r3, r8, r2, r3 @ i1 (6)
+ SMLABB r4, r8, r2, r4 @ i2 (7)
+ SMLATB r11,r9, r2, r11 @ i3 (8)
+ SMLABB r12,r9, r2, r12 @ i4 (9)
+ LDR r10, [r13, #8] @ [ a10 | a11]
+
+ LDR r2,[r1],#-4
+ SMLABT r3, r8, r2, r3 @ i1 (7)
+ SMLATT r4, r9, r2, r4 @ i2 (8)
+ SMLABT r11,r9, r2, r11 @ i3 (9)
+ SMLATT r12,r10, r2, r12 @ i4 (10)
+ SMLATB r3, r9, r2, r3 @ i1 (8)
+ SMLABB r4, r9, r2, r4 @ i2 (9)
+ SMLATB r11,r10, r2, r11 @ i3 (10)
+ SMLABB r12,r10, r2, r12 @ i4 (11)
+ LDR r8, [r13, #12] @ [ a12 | a13 ]
+
+ LDR r2,[r1],#-4
+ SMLABT r3, r9, r2, r3 @ i1 (9)
+ SMLATT r4, r10, r2, r4 @ i2 (10)
+ SMLABT r11,r10, r2, r11 @ i3 (11)
+ SMLATT r12,r8, r2, r12 @ i4 (12)
+ SMLATB r3, r10, r2, r3 @ i1 (10)
+ SMLABB r4, r10, r2, r4 @ i2 (11)
+ SMLATB r11,r8, r2, r11 @ i3 (12)
+ SMLABB r12,r8, r2, r12 @ i4 (13)
+ LDR r9, [r13, #16] @ [ a14 | a15 ]
+
+ LDR r2,[r1],#-4
+ SMLABT r3, r10, r2, r3 @ i1 (11)
+ SMLATT r4, r8, r2, r4 @ i2 (12)
+ SMLABT r11,r8, r2, r11 @ i3 (13)
+ SMLATT r12,r9, r2, r12 @ i4 (14)
+ SMLATB r3, r8, r2, r3 @ i1 (12)
+ SMLABB r4, r8, r2, r4 @ i2 (13)
+ SMLATB r11,r9, r2, r11 @ i3 (14)
+ SMLABB r12,r9, r2, r12 @ i4 (15)
+
+
+ LDR r2,[r1],#-4
+ SMLABT r3, r8, r2, r3 @ i1 (13)
+ SMLATT r4, r9, r2, r4 @ i2 (14)
+ SMLABT r11,r9, r2, r11 @ i3 (15)
+ SMLABT r12,r14, r2, r12 @ i4 (16)
+ SMLATB r3, r9, r2, r3 @ i1 (14)
+ SMLABB r4, r9, r2, r4 @ i2 (15)
+ SMLABB r11,r14, r2, r11 @ i3 (16)
+ LDR r8, [r13] @ [ a6 | a7 ]
+
+ LDR r2,[r1],#44 @ Change
+ SMLABT r3, r9, r2, r3
+ SMLABB r3, r14, r2, r3
+ SMLABT r4, r14, r2, r4
+ LDR r9, [r13, #4] @ [ a8 | a9 ]
+
+
+ QADD r3,r3,r3
+ QADD r4,r4,r4
+ QADD r11,r11,r11
+ QADD r12,r12,r12
+
+ QADD r3,r3,r3
+ QADD r4,r4,r4
+ QADD r11,r11,r11
+ QADD r12,r12,r12
+
+ QADD r3,r3,r3
+ QADD r4,r4,r4
+ QADD r11,r11,r11
+ QADD r12,r12,r12
+
+ QADD r3,r3,r3
+ QADD r4,r4,r4
+ QADD r11,r11,r11
+ QADD r12,r12,r12
+
+ MOV r2,#32768
+
+ QDADD r3,r2,r3
+ QDADD r4,r2,r4
+ QDADD r11,r2,r11
+ QDADD r12,r2,r12
+
+
+ MOV r3,r3,asr #16
+ MOV r4,r4,asr #16
+ MOV r11,r11,asr #16
+ MOV r12,r12,asr #16
+
+ STRH r3,[r0],#2
+ STRH r4,[r0],#2
+ STRH r11,[r0],#2
+ STRH r12,[r0],#2
+
+ MOV r2,r14,asr #16
+ SUB r14, r14, #0x10000
+ SUBS r2,r2,#1
+ BNE residu_loop
+end:
+ LDMFD r13!, {r8 -r12}
+ LDMFD r13!, {r4 -r12,pc}
+
+ @ENDFUNC
+ .END
+
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
new file mode 100644
index 0000000..aa9f464
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
@@ -0,0 +1,75 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@void Scale_sig(
+@ Word16 x[], /* (i/o) : signal to scale */
+@ Word16 lg, /* (i) : size of x[] */
+@ Word16 exp /* (i) : exponent: x = round(x << exp) */
+@ )
+@
+@r0 --- x[]
+@r1 --- lg
+@r2 --- exp
+
+ .section .text
+ .global Scale_sig_opt
+
+Scale_sig_opt:
+
+ STMFD r13!, {r4 - r12, r14}
+ SUB r3, r1, #1 @i = lg - 1
+ CMP r2, #0 @Compare exp and 0
+ RSB r7, r2, #0 @exp = -exp
+ ADD r10, r2, #16 @16 + exp
+ ADD r4, r0, r3, LSL #1 @x[i] address
+ MOV r8, #0x7fffffff
+ MOV r9, #0x8000
+ BLE LOOP2
+
+LOOP1:
+
+ LDRSH r5, [r4] @load x[i]
+ MOV r12, r5, LSL r10
+ TEQ r5, r12, ASR r10
+ EORNE r12, r8, r5, ASR #31
+ SUBS r3, r3, #1
+ QADD r11, r12, r9
+ MOV r12, r11, ASR #16
+ STRH r12, [r4], #-2
+ BGE LOOP1
+ BL The_end
+
+LOOP2:
+
+ LDRSH r5, [r4] @load x[i]
+ MOV r6, r5, LSL #16 @L_tmp = x[i] << 16
+ MOV r5, r6, ASR r7 @L_tmp >>= exp
+ QADD r11, r5, r9
+ MOV r12, r11, ASR #16
+ SUBS r3, r3, #1
+ STRH r12, [r4], #-2
+ BGE LOOP2
+
+The_end:
+ LDMFD r13!, {r4 - r12, r15}
+
+ @ENDFUNC
+ .END
+
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
new file mode 100644
index 0000000..e05e9e0
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
@@ -0,0 +1,238 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@**********************************************************************/
+@void Syn_filt(
+@ Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients */
+@ Word16 x[], /* (i) : input signal */
+@ Word16 y[], /* (o) : output signal */
+@ Word16 mem[], /* (i/o) : memory associated with this filtering. */
+@)
+@***********************************************************************
+@ a[] --- r0
+@ x[] --- r1
+@ y[] --- r2
+@ mem[] --- r3
+@ m --- 16 lg --- 80 update --- 1
+
+ .section .text
+ .global Syn_filt_asm
+ .extern voAWB_Copy
+
+Syn_filt_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ SUB r13, r13, #700 @ y_buf[L_FRAME16k + M16k]
+
+ MOV r4, r3 @ copy mem[] address
+ MOV r5, r13 @ copy yy = y_buf address
+
+ @ for(i = 0@ i < m@ i++)
+ @{
+ @ *yy++ = mem[i]@
+ @}
+
+ LDRH r6, [r4], #2
+ LDRH r7, [r4], #2
+ LDRH r8, [r4], #2
+ LDRH r9, [r4], #2
+ LDRH r10, [r4], #2
+ LDRH r11, [r4], #2
+ LDRH r12, [r4], #2
+ LDRH r14, [r4], #2
+
+ STRH r6, [r5], #2
+ STRH r7, [r5], #2
+ STRH r8, [r5], #2
+ STRH r9, [r5], #2
+ STRH r10, [r5], #2
+ STRH r11, [r5], #2
+ STRH r12, [r5], #2
+ STRH r14, [r5], #2
+
+ LDRH r6, [r4], #2
+ LDRH r7, [r4], #2
+ LDRH r8, [r4], #2
+ LDRH r9, [r4], #2
+ LDRH r10, [r4], #2
+ LDRH r11, [r4], #2
+ LDRH r12, [r4], #2
+ LDRH r14, [r4], #2
+
+ STRH r6, [r5], #2
+ STRH r7, [r5], #2
+ STRH r8, [r5], #2
+ STRH r9, [r5], #2
+ STRH r10, [r5], #2
+ STRH r11, [r5], #2
+ STRH r12, [r5], #2
+ STRH r14, [r5], #2
+
+ LDRSH r5, [r0] @ load a[0]
+ MOV r8, #0 @ i = 0
+ MOV r5, r5, ASR #1 @ a0 = a[0] >> 1
+ @MOV r4, r13
+ @ load all a[]
+
+ LDR r14, =0xffff
+ LDRSH r6, [r0, #2] @ load a[1]
+ LDRSH r7, [r0, #4] @ load a[2]
+ LDRSH r9, [r0, #6] @ load a[3]
+ LDRSH r11,[r0, #8] @ load a[4]
+ AND r6, r6, r14
+ AND r9, r9, r14
+ ORR r10, r6, r7, LSL #16 @ -a[2] -- -a[1]
+ ORR r12, r9, r11, LSL #16 @ -a[4] -- -a[3]
+ STR r10, [r13, #-4]
+ STR r12, [r13, #-8]
+
+ LDRSH r6, [r0, #10] @ load a[5]
+ LDRSH r7, [r0, #12] @ load a[6]
+ LDRSH r9, [r0, #14] @ load a[7]
+ LDRSH r11,[r0, #16] @ load a[8]
+ AND r6, r6, r14
+ AND r9, r9, r14
+ ORR r10, r6, r7, LSL #16 @ -a[6] -- -a[5]
+ ORR r12, r9, r11, LSL #16 @ -a[8] -- -a[7]
+ STR r10, [r13, #-12]
+ STR r12, [r13, #-16]
+
+ LDRSH r6, [r0, #18] @ load a[9]
+ LDRSH r7, [r0, #20] @ load a[10]
+ LDRSH r9, [r0, #22] @ load a[11]
+ LDRSH r11,[r0, #24] @ load a[12]
+ AND r6, r6, r14
+ AND r9, r9, r14
+ ORR r10, r6, r7, LSL #16 @ -a[10] -- -a[9]
+ ORR r12, r9, r11, LSL #16 @ -a[12] -- -a[11]
+ STR r10, [r13, #-20]
+ STR r12, [r13, #-24]
+
+ LDRSH r6, [r0, #26] @ load a[13]
+ LDRSH r7, [r0, #28] @ load a[14]
+ LDRSH r9, [r0, #30] @ load a[15]
+ LDRSH r11,[r0, #32] @ load a[16]
+ AND r6, r6, r14
+ AND r9, r9, r14
+ ORR r10, r6, r7, LSL #16 @ -a[14] -- -a[13]
+ ORR r12, r9, r11, LSL #16 @ -a[16] -- -a[15]
+ STR r10, [r13, #-28]
+ STR r12, [r13, #-32]
+
+ ADD r4, r13, #32
+LOOP:
+ LDRSH r6, [r1], #2 @ load x[i]
+ ADD r10, r4, r8, LSL #1 @ temp_p = yy + i
+
+ MUL r0, r5, r6 @ L_tmp = x[i] * a0
+ @ for(j = 1@ j <= m, j+=8)
+ LDR r7, [r13, #-4] @ -a[2] -a[1]
+ LDRSH r9, [r10, #-2] @ *(temp_p - 1)
+ LDRSH r12, [r10, #-4] @ *(temp_p - 2)
+
+
+ SMULBB r14, r9, r7 @ -a[1] * (*(temp_p -1))
+
+ LDRSH r6, [r10, #-6] @ *(temp_p - 3)
+
+ SMLABT r14, r12, r7, r14 @ -a[2] * (*(temp_p - 2))
+
+ LDR r7, [r13, #-8] @ -a[4] -a[3]
+ LDRSH r11, [r10, #-8] @ *(temp_p - 4)
+
+ SMLABB r14, r6, r7, r14 @ -a[3] * (*(temp_p -3))
+
+ LDRSH r9, [r10, #-10] @ *(temp_p - 5)
+
+ SMLABT r14, r11, r7, r14 @ -a[4] * (*(temp_p -4))
+
+ LDR r7, [r13, #-12] @ -a[6] -a[5]
+ LDRSH r12, [r10, #-12] @ *(temp_p - 6)
+
+ SMLABB r14, r9, r7, r14 @ -a[5] * (*(temp_p -5))
+
+ LDRSH r6, [r10, #-14] @ *(temp_p - 7)
+
+ SMLABT r14, r12, r7, r14 @ -a[6] * (*(temp_p - 6))
+
+ LDR r7, [r13, #-16] @ -a[8] -a[7]
+ LDRSH r11, [r10, #-16] @ *(temp_p - 8)
+
+ SMLABB r14, r6, r7, r14 @ -a[7] * (*(temp_p -7))
+
+ LDRSH r9, [r10, #-18] @ *(temp_p - 9)
+
+ SMLABT r14, r11, r7, r14 @ -a[8] * (*(temp_p -8))
+
+ LDR r7, [r13, #-20] @ -a[10] -a[9]
+ LDRSH r12, [r10, #-20] @ *(temp_p - 10)
+
+ SMLABB r14, r9, r7, r14 @ -a[9] * (*(temp_p -9))
+
+ LDRSH r6, [r10, #-22] @ *(temp_p - 11)
+
+ SMLABT r14, r12, r7, r14 @ -a[10] * (*(temp_p - 10))
+
+ LDR r7, [r13, #-24] @ -a[12] -a[11]
+ LDRSH r11, [r10, #-24] @ *(temp_p - 12)
+
+ SMLABB r14, r6, r7, r14 @ -a[11] * (*(temp_p -11))
+
+ LDRSH r9, [r10, #-26] @ *(temp_p - 13)
+
+ SMLABT r14, r11, r7, r14 @ -a[12] * (*(temp_p -12))
+
+ LDR r7, [r13, #-28] @ -a[14] -a[13]
+ LDRSH r12, [r10, #-28] @ *(temp_p - 14)
+
+ SMLABB r14, r9, r7, r14 @ -a[13] * (*(temp_p -13))
+
+ LDRSH r6, [r10, #-30] @ *(temp_p - 15)
+
+ SMLABT r14, r12, r7, r14 @ -a[14] * (*(temp_p - 14))
+
+ LDR r7, [r13, #-32] @ -a[16] -a[15]
+ LDRSH r11, [r10, #-32] @ *(temp_p - 16)
+
+ SMLABB r14, r6, r7, r14 @ -a[15] * (*(temp_p -15))
+
+ SMLABT r14, r11, r7, r14 @ -a[16] * (*(temp_p -16))
+
+ RSB r14, r14, r0
+
+ MOV r7, r14, LSL #4 @ L_tmp <<=4
+ ADD r8, r8, #1
+ ADD r14, r7, #0x8000
+ MOV r7, r14, ASR #16 @ (L_tmp + 0x8000) >> 16
+ CMP r8, #80
+ STRH r7, [r10] @ yy[i]
+ STRH r7, [r2], #2 @ y[i]
+ BLT LOOP
+
+ @ update mem[]
+ ADD r5, r13, #160 @ yy[64] address
+ MOV r1, r3
+ MOV r0, r5
+ MOV r2, #16
+ BL voAWB_Copy
+
+Syn_filt_asm_end:
+
+ ADD r13, r13, #700
+ LDMFD r13!, {r4 - r12, r15}
+ @ENDFUNC
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
new file mode 100644
index 0000000..acb60c3
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
@@ -0,0 +1,102 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@void Deemph_32(
+@ Word16 x_hi[], /* (i) : input signal (bit31..16) */
+@ Word16 x_lo[], /* (i) : input signal (bit15..4) */
+@ Word16 y[], /* (o) : output signal (x16) */
+@ Word16 mu, /* (i) Q15 : deemphasis factor */
+@ Word16 L, /* (i) : vector size */
+@ Word16 * mem /* (i/o) : memory (y[-1]) */
+@ )
+
+@x_hi RN R0
+@x_lo RN R1
+@y[] RN R2
+@*mem RN R3
+
+ .section .text
+ .global Deemph_32_asm
+
+Deemph_32_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ MOV r4, #2 @i=0
+ LDRSH r6, [r0], #2 @load x_hi[0]
+ LDRSH r7, [r1], #2 @load x_lo[0]
+ LDR r5, =22282 @r5---mu
+ MOV r11, #0x8000
+
+ @y[0]
+ MOV r10, r6, LSL #16 @L_tmp = x_hi[0]<<16
+ MOV r8, r5, ASR #1 @fac = mu >> 1
+ LDR r5, [r3]
+ ADD r12, r10, r7, LSL #4 @L_tmp += x_lo[0] << 4
+ MOV r10, r12, LSL #3 @L_tmp <<= 3
+ MUL r9, r5, r8
+ LDRSH r6, [r0], #2 @load x_hi[1]
+ QDADD r10, r10, r9
+ LDRSH r7, [r1], #2 @load x_lo[1]
+ MOV r12, r10, LSL #1 @L_tmp = L_mac(L_tmp, *mem, fac)
+ QADD r10, r12, r11
+ MOV r14, r10, ASR #16 @y[0] = round(L_tmp)
+
+
+ MOV r10, r6, LSL #16
+ ADD r12, r10, r7, LSL #4
+ STRH r14, [r2], #2 @update y[0]
+ MOV r10, r12, LSL #3
+ MUL r9, r14, r8
+ QDADD r10, r10, r9
+ MOV r12, r10, LSL #1
+ QADD r10, r12, r11
+ MOV r14, r10, ASR #16 @y[1] = round(L_tmp)
+
+LOOP:
+ LDRSH r6, [r0], #2 @load x_hi[]
+ LDRSH r7, [r1], #2
+ STRH r14, [r2], #2
+ MOV r10, r6, LSL #16
+ ADD r12, r10, r7, LSL #4
+ MUL r9, r14, r8
+ MOV r10, r12, LSL #3
+ QDADD r10, r10, r9
+ LDRSH r6, [r0], #2 @load x_hi[]
+ MOV r12, r10, LSL #1
+ QADD r10, r12, r11
+ LDRSH r7, [r1], #2
+ MOV r14, r10, ASR #16
+
+ MOV r10, r6, LSL #16
+ ADD r12, r10, r7, LSL #4
+ STRH r14, [r2], #2
+ MUL r9, r14, r8
+ MOV r10, r12, LSL #3
+ QDADD r10, r10, r9
+ ADD r4, r4, #2
+ MOV r12, r10, LSL #1
+ QADD r10, r12, r11
+ CMP r4, #64
+ MOV r14, r10, ASR #16
+
+ BLT LOOP
+ STR r14, [r3]
+ STRH r14, [r2]
+
+ LDMFD r13!, {r4 - r12, r15}
+
+ .END
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
new file mode 100644
index 0000000..07ca344
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
@@ -0,0 +1,127 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@**********************************************************************/
+@Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */
+@ Word16 x[], /* (i) 12bits: x vector */
+@ Word16 y[], /* (i) 12bits: y vector */
+@ Word16 lg, /* (i) : vector length */
+@ Word16 * exp /* (o) : exponent of result (0..+30) */
+@)
+@************************************************************************
+@ x[] --- r0
+@ y[] --- r1
+@ lg --- r2
+@ *exp --- r3
+
+ .section .text
+ .global Dot_product12_asm
+
+Dot_product12_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ CMP r0, r1
+ BEQ LOOP_EQ
+
+ VLD1.S16 {Q0, Q1}, [r0]! @load 16 Word16 x[]
+ VLD1.S16 {Q2, Q3}, [r0]! @load 16 Word16 x[]
+ VLD1.S16 {Q4, Q5}, [r0]! @load 16 Word16 x[]
+ VLD1.S16 {Q6, Q7}, [r0]! @load 16 Word16 x[]
+ VLD1.S16 {Q8, Q9}, [r1]! @load 16 Word16 y[]
+ VLD1.S16 {Q10, Q11}, [r1]! @load 16 Word16 y[]
+ VLD1.S16 {Q12, Q13}, [r1]! @load 16 Word16 y[]
+
+ VMULL.S16 Q15, D16, D0
+ VMLAL.S16 Q15, D17, D1
+ VMLAL.S16 Q15, D18, D2
+ VMLAL.S16 Q15, D19, D3
+ VLD1.S16 {Q0, Q1}, [r1]! @load 16 Word16 y[]
+ VMLAL.S16 Q15, D20, D4
+ VMLAL.S16 Q15, D21, D5
+ VMLAL.S16 Q15, D22, D6
+ VMLAL.S16 Q15, D23, D7
+ VMLAL.S16 Q15, D24, D8
+ VMLAL.S16 Q15, D25, D9
+ VMLAL.S16 Q15, D26, D10
+ VMLAL.S16 Q15, D27, D11
+ VMLAL.S16 Q15, D0, D12
+ VMLAL.S16 Q15, D1, D13
+ VMLAL.S16 Q15, D2, D14
+ VMLAL.S16 Q15, D3, D15
+
+ CMP r2, #64
+ BEQ Lable1
+ VLD1.S16 {Q0, Q1}, [r0]! @load 16 Word16 x[]
+ VLD1.S16 {Q2, Q3}, [r1]!
+ VMLAL.S16 Q15, D4, D0
+ VMLAL.S16 Q15, D5, D1
+ VMLAL.S16 Q15, D6, D2
+ VMLAL.S16 Q15, D7, D3
+ BL Lable1
+
+LOOP_EQ:
+ VLD1.S16 {Q0, Q1}, [r0]!
+ VLD1.S16 {Q2, Q3}, [r0]!
+ VLD1.S16 {Q4, Q5}, [r0]!
+ VLD1.S16 {Q6, Q7}, [r0]!
+ VMULL.S16 Q15, D0, D0
+ VMLAL.S16 Q15, D1, D1
+ VMLAL.S16 Q15, D2, D2
+ VMLAL.S16 Q15, D3, D3
+ VMLAL.S16 Q15, D4, D4
+ VMLAL.S16 Q15, D5, D5
+ VMLAL.S16 Q15, D6, D6
+ VMLAL.S16 Q15, D7, D7
+ VMLAL.S16 Q15, D8, D8
+ VMLAL.S16 Q15, D9, D9
+ VMLAL.S16 Q15, D10, D10
+ VMLAL.S16 Q15, D11, D11
+ VMLAL.S16 Q15, D12, D12
+ VMLAL.S16 Q15, D13, D13
+ VMLAL.S16 Q15, D14, D14
+ VMLAL.S16 Q15, D15, D15
+
+ CMP r2, #64
+ BEQ Lable1
+ VLD1.S16 {Q0, Q1}, [r0]!
+ VMLAL.S16 Q15, D0, D0
+ VMLAL.S16 Q15, D1, D1
+ VMLAL.S16 Q15, D2, D2
+ VMLAL.S16 Q15, D3, D3
+
+Lable1:
+
+ VQADD.S32 D30, D30, D31
+ VPADD.S32 D30, D30, D30
+ VMOV.S32 r12, D30[0]
+
+ ADD r12, r12, r12
+ ADD r12, r12, #1 @ L_sum = (L_sum << 1) + 1
+ MOV r4, r12
+ CMP r12, #0
+ RSBLT r4, r12, #0
+ CLZ r10, r4
+ SUB r10, r10, #1 @ sft = norm_l(L_sum)
+ MOV r0, r12, LSL r10 @ L_sum = L_sum << sft
+ RSB r11, r10, #30 @ *exp = 30 - sft
+ STRH r11, [r3]
+
+Dot_product12_end:
+
+ LDMFD r13!, {r4 - r12, r15}
+
+ .END
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
new file mode 100644
index 0000000..1880024
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
@@ -0,0 +1,228 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@**********************************************************************/
+@void Filt_6k_7k(
+@ Word16 signal[], /* input: signal */
+@ Word16 lg, /* input: length of input */
+@ Word16 mem[] /* in/out: memory (size=30) */
+@)
+@***********************************************************************
+@ r0 --- signal[]
+@ r1 --- lg
+@ r2 --- mem[]
+
+ .section .text
+ .global Filt_6k_7k_asm
+ .extern fir_6k_7k
+
+Filt_6k_7k_asm:
+
+ STMFD r13!, {r0 - r12, r14}
+ SUB r13, r13, #240 @ x[L_SUBFR16k + (L_FIR - 1)]
+ MOV r8, r0 @ copy signal[] address
+ MOV r5, r2 @ copy mem[] address
+
+ MOV r0, r2
+ MOV r1, r13
+
+ VLD1.S16 {D0, D1, D2, D3}, [r0]!
+ VLD1.S16 {D4, D5, D6, D7}, [r0]!
+
+ VST1.S16 {D0, D1, D2, D3}, [r1]!
+ VST1.S16 {D4, D5, D6}, [r1]!
+ VST1.S16 D7[0], [r1]!
+ VST1.S16 D7[1], [r1]!
+
+
+
+ LDR r10, Lable1 @ get fir_7k address
+ MOV r3, r8 @ change myMemCopy to Copy, due to Copy will change r3 content
+ ADD r6, r13, #60 @ get x[L_FIR - 1] address
+ MOV r7, r3 @ get signal[i]
+ @for (i = lg - 1@ i >= 0@ i--)
+ @{
+ @ x[i + L_FIR - 1] = signal[i] >> 2@
+ @}
+ VLD1.S16 {Q0, Q1}, [r7]! @ signal[0] ~ signal[15]
+ VLD1.S16 {Q2, Q3}, [r7]! @ signal[16] ~ signal[31]
+ VLD1.S16 {Q4, Q5}, [r7]! @ signal[32] ~ signal[47]
+ VLD1.S16 {Q6, Q7}, [r7]! @ signal[48] ~ signal[63]
+ VLD1.S16 {Q8, Q9}, [r7]! @ signal[64] ~ signal[79]
+ VSHR.S16 Q10, Q0, #2
+ VSHR.S16 Q11, Q1, #2
+ VSHR.S16 Q12, Q2, #2
+ VSHR.S16 Q13, Q3, #2
+ VST1.S16 {Q10, Q11}, [r6]!
+ VSHR.S16 Q0, Q4, #2
+ VSHR.S16 Q1, Q5, #2
+ VSHR.S16 Q10, Q6, #2
+ VSHR.S16 Q11, Q7, #2
+ VSHR.S16 Q2, Q8, #2
+ VSHR.S16 Q3, Q9, #2
+ VST1.S16 {Q12, Q13}, [r6]!
+ VST1.S16 {Q0, Q1}, [r6]!
+ VST1.S16 {Q10, Q11}, [r6]!
+ VST1.S16 {Q2, Q3}, [r6]!
+
+ MOV r12, r5
+ @STR r5, [sp, #-4] @ PUSH r5 to stack
+ @ not use registers: r4, r10, r12, r14, r5
+ MOV r4, r13
+ MOV r5, #0 @ i = 0
+
+ @ r4 --- x[i], r10 ---- fir_6k_7k
+ VLD1.S16 {Q0, Q1}, [r10]! @fir_6k_7k[0] ~ fir_6k_7k[15]
+ VLD1.S16 {Q2, Q3}, [r10]! @fir_6k_7k[16] ~ fir_6k_7k[31]
+ VMOV.S16 D7[3], r5 @set fir_6k_7K = 0
+
+ VLD1.S16 {Q4, Q5}, [r4]! @x[0] ~ x[15]
+ VLD1.S16 {Q6, Q7}, [r4]! @x[16] ~ X[31]
+ VLD1.S16 {Q8}, [r4]!
+ VMOV.S16 Q15, #0
+
+LOOP_6K7K:
+
+ VMULL.S16 Q9,D8,D0[0]
+ VMULL.S16 Q10,D9,D1[0]
+ VMULL.S16 Q11,D9,D0[0]
+ VMULL.S16 Q12,D10,D1[0]
+ VEXT.8 Q4,Q4,Q5,#2
+ VMLAL.S16 Q9,D10,D2[0]
+ VMLAL.S16 Q10,D11,D3[0]
+ VMLAL.S16 Q11,D11,D2[0]
+ VMLAL.S16 Q12,D12,D3[0]
+ VEXT.8 Q5,Q5,Q6,#2
+ VMLAL.S16 Q9,D12,D4[0]
+ VMLAL.S16 Q10,D13,D5[0]
+ VMLAL.S16 Q11,D13,D4[0]
+ VMLAL.S16 Q12,D14,D5[0]
+ VEXT.8 Q6,Q6,Q7,#2
+ VMLAL.S16 Q9,D14,D6[0]
+ VMLAL.S16 Q10,D15,D7[0]
+ VMLAL.S16 Q11,D15,D6[0]
+ VMLAL.S16 Q12,D16,D7[0]
+ VEXT.8 Q7,Q7,Q8,#2
+
+ VMLAL.S16 Q9,D8,D0[1]
+ VMLAL.S16 Q10,D9,D1[1]
+ VEXT.8 Q8,Q8,Q15,#2
+ VMLAL.S16 Q11,D9,D0[1]
+ VMLAL.S16 Q12,D10,D1[1]
+ VEXT.8 Q4,Q4,Q5,#2
+ VMLAL.S16 Q9,D10,D2[1]
+ VMLAL.S16 Q10,D11,D3[1]
+ VMLAL.S16 Q11,D11,D2[1]
+ VMLAL.S16 Q12,D12,D3[1]
+ VEXT.8 Q5,Q5,Q6,#2
+ VMLAL.S16 Q9,D12,D4[1]
+ VMLAL.S16 Q10,D13,D5[1]
+ VMLAL.S16 Q11,D13,D4[1]
+ VMLAL.S16 Q12,D14,D5[1]
+ VEXT.8 Q6,Q6,Q7,#2
+ VMLAL.S16 Q9,D14,D6[1]
+ VMLAL.S16 Q10,D15,D7[1]
+ VMLAL.S16 Q11,D15,D6[1]
+ VMLAL.S16 Q12,D16,D7[1]
+ VEXT.8 Q7,Q7,Q8,#2
+
+ VMLAL.S16 Q9,D8,D0[2]
+ VMLAL.S16 Q10,D9,D1[2]
+ VEXT.8 Q8,Q8,Q15,#2
+ VMLAL.S16 Q11,D9,D0[2]
+ VMLAL.S16 Q12,D10,D1[2]
+ VEXT.8 Q4,Q4,Q5,#2
+ VMLAL.S16 Q9,D10,D2[2]
+ VMLAL.S16 Q10,D11,D3[2]
+ VMLAL.S16 Q11,D11,D2[2]
+ VMLAL.S16 Q12,D12,D3[2]
+ VEXT.8 Q5,Q5,Q6,#2
+ VMLAL.S16 Q9,D12,D4[2]
+ VMLAL.S16 Q10,D13,D5[2]
+ VMLAL.S16 Q11,D13,D4[2]
+ VMLAL.S16 Q12,D14,D5[2]
+ VEXT.8 Q6,Q6,Q7,#2
+ VMLAL.S16 Q9,D14,D6[2]
+ VMLAL.S16 Q10,D15,D7[2]
+ VMLAL.S16 Q11,D15,D6[2]
+ VMLAL.S16 Q12,D16,D7[2]
+ VEXT.8 Q7,Q7,Q8,#2
+
+ VMLAL.S16 Q9,D8,D0[3]
+ VMLAL.S16 Q10,D9,D1[3]
+ VEXT.8 Q8,Q8,Q15,#2
+ VMLAL.S16 Q11,D9,D0[3]
+ VMLAL.S16 Q12,D10,D1[3]
+ VEXT.8 Q4,Q4,Q5,#2
+ VMLAL.S16 Q9,D10,D2[3]
+ VMLAL.S16 Q10,D11,D3[3]
+ VMLAL.S16 Q11,D11,D2[3]
+ VMLAL.S16 Q12,D12,D3[3]
+ VEXT.8 Q5,Q5,Q6,#2
+ VMLAL.S16 Q9,D12,D4[3]
+ VMLAL.S16 Q10,D13,D5[3]
+ VMLAL.S16 Q11,D13,D4[3]
+ VMLAL.S16 Q12,D14,D5[3]
+ VEXT.8 Q6,Q6,Q7,#2
+ VMLAL.S16 Q9,D14,D6[3]
+ VMLAL.S16 Q10,D15,D7[3]
+ VMLAL.S16 Q11,D15,D6[3]
+ VMLAL.S16 Q12,D16,D7[3]
+ VEXT.8 Q7,Q7,Q8,#2
+
+ VMOV.S16 D8,D9
+ VEXT.8 Q8,Q8,Q15,#2
+ VMOV.S16 D9,D10
+ VADD.S32 Q9,Q9,Q10
+ VMOV.S16 D10,D11
+ VMOV.S16 D11,D12
+ VADD.S32 Q11,Q11,Q12
+ VMOV.S16 D12,D13
+ VQRSHRN.S32 D28,Q9,#15
+ VMOV.S16 D13,D14
+ VMOV.S16 D14,D15
+ VQRSHRN.S32 D29,Q11,#15
+ VMOV.S16 D15,D16
+
+ VLD1.S16 {Q8},[r4]!
+ ADD r5, r5, #8
+ CMP r5, #80
+ VST1.S16 {D28,D29},[r3]!
+ BLT LOOP_6K7K
+
+ ADD r0, r13, #160 @x + lg
+ MOV r1, r12
+ @LDR r1, [sp, #-4] @mem address
+
+ VLD1.S16 {D0, D1, D2, D3}, [r0]!
+ VLD1.S16 {D4, D5, D6, D7}, [r0]!
+
+ VST1.S16 {D0, D1, D2, D3}, [r1]!
+ VST1.S16 {D4, D5, D6}, [r1]!
+ VST1.S16 D7[0], [r1]!
+ VST1.S16 D7[1], [r1]!
+
+Filt_6k_7k_end:
+
+ ADD r13, r13, #240
+ LDMFD r13!, {r0 - r12, r15}
+
+Lable1:
+ .word fir_6k_7k
+ @ENDFUNC
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
new file mode 100644
index 0000000..60e9ade
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
@@ -0,0 +1,270 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@static void Norm_Corr (Word16 exc[], /* (i) : excitation buffer */
+@ Word16 xn[], /* (i) : target vector */
+@ Word16 h[], /* (i) Q15 : impulse response of synth/wgt filters */
+@ Word16 L_subfr, /* (i) : sub-frame length */
+@ Word16 t_min, /* (i) : minimum value of pitch lag. */
+@ Word16 t_max, /* (i) : maximum value of pitch lag. */
+@ Word16 corr_norm[]) /* (o) Q15 : normalized correlation */
+@
+
+@ r0 --- exc[]
+@ r1 --- xn[]
+@ r2 --- h[]
+@ r3 --- L_subfr
+@ r4 --- t_min
+@ r5 --- t_max
+@ r6 --- corr_norm[]
+
+
+ .section .text
+ .global Norm_corr_asm
+ .extern Convolve_asm
+ .extern Isqrt_n
+@******************************
+@ constant
+@******************************
+.equ EXC , 0
+.equ XN , 4
+.equ H , 8
+.equ L_SUBFR , 12
+.equ voSTACK , 172
+.equ T_MIN , 212
+.equ T_MAX , 216
+.equ CORR_NORM , 220
+
+Norm_corr_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ SUB r13, r13, #voSTACK
+
+ ADD r8, r13, #20 @get the excf[L_SUBFR]
+ LDR r4, [r13, #T_MIN] @get t_min
+ RSB r11, r4, #0 @k = -t_min
+ ADD r5, r0, r11, LSL #1 @get the &exc[k]
+
+ @transfer Convolve function
+ STMFD sp!, {r0 - r3}
+ MOV r0, r5
+ MOV r1, r2
+ MOV r2, r8 @r2 --- excf[]
+ BL Convolve_asm
+ LDMFD sp!, {r0 - r3}
+
+ @ r8 --- excf[]
+
+ MOV r14, r1 @copy xn[] address
+ MOV r7, #1
+ VLD1.S16 {Q0, Q1}, [r14]!
+ VLD1.S16 {Q2, Q3}, [r14]!
+ VLD1.S16 {Q4, Q5}, [r14]!
+ VLD1.S16 {Q6, Q7}, [r14]!
+
+ VMULL.S16 Q10, D0, D0
+ VMLAL.S16 Q10, D1, D1
+ VMLAL.S16 Q10, D2, D2
+ VMLAL.S16 Q10, D3, D3
+ VMLAL.S16 Q10, D4, D4
+ VMLAL.S16 Q10, D5, D5
+ VMLAL.S16 Q10, D6, D6
+ VMLAL.S16 Q10, D7, D7
+ VMLAL.S16 Q10, D8, D8
+ VMLAL.S16 Q10, D9, D9
+ VMLAL.S16 Q10, D10, D10
+ VMLAL.S16 Q10, D11, D11
+ VMLAL.S16 Q10, D12, D12
+ VMLAL.S16 Q10, D13, D13
+ VMLAL.S16 Q10, D14, D14
+ VMLAL.S16 Q10, D15, D15
+
+ VQADD.S32 D20, D20, D21
+ VMOV.S32 r9, D20[0]
+ VMOV.S32 r10, D20[1]
+ QADD r6, r9, r10
+ QADD r6, r6, r6
+ QADD r9, r6, r7 @L_tmp = (L_tmp << 1) + 1;
+ CLZ r7, r9
+ SUB r6, r7, #1 @exp = norm_l(L_tmp)
+ RSB r7, r6, #32 @exp = 32 - exp
+ MOV r6, r7, ASR #1
+ RSB r7, r6, #0 @scale = -(exp >> 1)
+
+ @loop for every possible period
+ @for(t = t_min@ t <= t_max@ t++)
+ @r7 --- scale r4 --- t_min r8 --- excf[]
+
+LOOPFOR:
+ ADD r14, r13, #20 @copy of excf[]
+ MOV r12, r1 @copy of xn[]
+ MOV r8, #0x8000
+
+ VLD1.S16 {Q0, Q1}, [r14]! @ load 16 excf[]
+ VLD1.S16 {Q2, Q3}, [r14]! @ load 16 excf[]
+ VLD1.S16 {Q4, Q5}, [r12]! @ load 16 x[]
+ VLD1.S16 {Q6, Q7}, [r12]! @ load 16 x[]
+ VMULL.S16 Q10, D0, D0 @L_tmp1 += excf[] * excf[]
+ VMULL.S16 Q11, D0, D8 @L_tmp += x[] * excf[]
+ VMLAL.S16 Q10, D1, D1
+ VMLAL.S16 Q11, D1, D9
+ VMLAL.S16 Q10, D2, D2
+ VMLAL.S16 Q11, D2, D10
+ VMLAL.S16 Q10, D3, D3
+ VMLAL.S16 Q11, D3, D11
+ VMLAL.S16 Q10, D4, D4
+ VMLAL.S16 Q11, D4, D12
+ VMLAL.S16 Q10, D5, D5
+ VMLAL.S16 Q11, D5, D13
+ VMLAL.S16 Q10, D6, D6
+ VMLAL.S16 Q11, D6, D14
+ VMLAL.S16 Q10, D7, D7
+ VMLAL.S16 Q11, D7, D15
+
+ VLD1.S16 {Q0, Q1}, [r14]! @ load 16 excf[]
+ VLD1.S16 {Q2, Q3}, [r14]! @ load 16 excf[]
+ VLD1.S16 {Q4, Q5}, [r12]! @ load 16 x[]
+ VLD1.S16 {Q6, Q7}, [r12]! @ load 16 x[]
+ VMLAL.S16 Q10, D0, D0
+ VMLAL.S16 Q11, D0, D8
+ VMLAL.S16 Q10, D1, D1
+ VMLAL.S16 Q11, D1, D9
+ VMLAL.S16 Q10, D2, D2
+ VMLAL.S16 Q11, D2, D10
+ VMLAL.S16 Q10, D3, D3
+ VMLAL.S16 Q11, D3, D11
+ VMLAL.S16 Q10, D4, D4
+ VMLAL.S16 Q11, D4, D12
+ VMLAL.S16 Q10, D5, D5
+ VMLAL.S16 Q11, D5, D13
+ VMLAL.S16 Q10, D6, D6
+ VMLAL.S16 Q11, D6, D14
+ VMLAL.S16 Q10, D7, D7
+ VMLAL.S16 Q11, D7, D15
+
+ VQADD.S32 D20, D20, D21
+ VQADD.S32 D22, D22, D23
+
+ VPADD.S32 D20, D20, D20 @D20[0] --- L_tmp1 << 1
+ VPADD.S32 D22, D22, D22 @D22[0] --- L_tmp << 1
+
+ VMOV.S32 r6, D20[0]
+ VMOV.S32 r5, D22[0]
+
+ @r5 --- L_tmp, r6 --- L_tmp1
+ MOV r10, #1
+ ADD r5, r10, r5, LSL #1 @L_tmp = (L_tmp << 1) + 1
+ ADD r6, r10, r6, LSL #1 @L_tmp1 = (L_tmp1 << 1) + 1
+
+ CLZ r10, r5
+ CMP r5, #0
+ RSBLT r11, r5, #0
+ CLZLT r10, r11
+ SUB r10, r10, #1 @exp = norm_l(L_tmp)
+
+ MOV r5, r5, LSL r10 @L_tmp = (L_tmp << exp)
+ RSB r10, r10, #30 @exp_corr = 30 - exp
+ MOV r11, r5, ASR #16 @corr = extract_h(L_tmp)
+
+ CLZ r5, r6
+ SUB r5, r5, #1
+ MOV r6, r6, LSL r5 @L_tmp = (L_tmp1 << exp)
+ RSB r5, r5, #30 @exp_norm = 30 - exp
+
+ @r10 --- exp_corr, r11 --- corr
+ @r6 --- L_tmp, r5 --- exp_norm
+
+ @Isqrt_n(&L_tmp, &exp_norm)
+
+ MOV r14, r0
+ MOV r12, r1
+
+ STMFD sp!, {r0 - r4, r7 - r12, r14}
+ ADD r1, sp, #4
+ ADD r0, sp, #0
+ STR r6, [sp]
+ STRH r5, [sp, #4]
+ BL Isqrt_n
+ LDR r6, [sp]
+ LDRSH r5, [sp, #4]
+ LDMFD sp!, {r0 - r4, r7 - r12, r14}
+ MOV r0, r14
+ MOV r1, r12
+
+
+ MOV r6, r6, ASR #16 @norm = extract_h(L_tmp)
+ MUL r12, r6, r11
+ ADD r12, r12, r12 @L_tmp = vo_L_mult(corr, norm)
+
+ ADD r6, r10, r5
+ ADD r6, r6, r7 @exp_corr + exp_norm + scale
+
+ CMP r6, #0
+ RSBLT r6, r6, #0
+ MOVLT r12, r12, ASR r6
+ MOVGT r12, r12, LSL r6 @L_tmp = L_shl(L_tmp, exp_corr + exp_norm + scale)
+
+ ADD r12, r12, r8
+ MOV r12, r12, ASR #16 @vo_round(L_tmp)
+
+ LDR r5, [r13, #CORR_NORM] @ get corr_norm address
+ LDR r6, [r13, #T_MAX] @ get t_max
+ ADD r10, r5, r4, LSL #1 @ get corr_norm[t] address
+ STRH r12, [r10] @ corr_norm[t] = vo_round(L_tmp)
+
+ CMP r4, r6
+ BEQ Norm_corr_asm_end
+
+ ADD r4, r4, #1 @ t_min ++
+ RSB r5, r4, #0 @ k
+
+ MOV r6, #63 @ i = 63
+ MOV r8, r0 @ exc[]
+ MOV r9, r2 @ h[]
+ ADD r10, r13, #20 @ excf[]
+
+ ADD r8, r8, r5, LSL #1 @ exc[k] address
+ ADD r9, r9, r6, LSL #1 @ h[i] address
+ ADD r10, r10, r6, LSL #1 @ excf[i] address
+ LDRSH r11, [r8] @ tmp = exc[k]
+
+LOOPK:
+ LDRSH r8, [r9], #-2 @ load h[i]
+ LDRSH r12, [r10, #-2] @ load excf[i - 1]
+ MUL r14, r11, r8
+ MOV r8, r14, ASR #15
+ ADD r14, r8, r12
+ STRH r14, [r10], #-2
+ SUBS r6, r6, #1
+ BGT LOOPK
+
+ LDRSH r8, [r9] @ load h[0]
+ MUL r14, r11, r8
+ LDR r6, [r13, #T_MAX] @ get t_max
+ MOV r8, r14, ASR #15
+ STRH r8, [r10]
+
+ CMP r4, r6
+ BLE LOOPFOR
+
+Norm_corr_asm_end:
+
+ ADD r13, r13, #voSTACK
+ LDMFD r13!, {r4 - r12, r15}
+
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
new file mode 100644
index 0000000..cb1764f
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
@@ -0,0 +1,133 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@**********************************************************************/
+@void Syn_filt_32(
+@ Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients */
+@ Word16 m, /* (i) : order of LP filter */
+@ Word16 exc[], /* (i) Qnew: excitation (exc[i] >> Qnew) */
+@ Word16 Qnew, /* (i) : exc scaling = 0(min) to 8(max) */
+@ Word16 sig_hi[], /* (o) /16 : synthesis high */
+@ Word16 sig_lo[], /* (o) /16 : synthesis low */
+@ Word16 lg /* (i) : size of filtering */
+@)
+@***********************************************************************
+@ a[] --- r0
+@ m --- r1
+@ exc[] --- r2
+@ Qnew --- r3
+@ sig_hi[] --- r4
+@ sig_lo[] --- r5
+@ lg --- r6
+
+ .section .text
+ .global Syn_filt_32_asm
+
+Syn_filt_32_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ LDR r4, [r13, #40] @ get sig_hi[] address
+ LDR r5, [r13, #44] @ get sig_lo[] address
+
+ LDRSH r6, [r0], #2 @ load Aq[0]
+ ADD r7, r3, #4 @ 4 + Q_new
+ MOV r3, r6, ASR r7 @ a0 = Aq[0] >> (4 + Q_new)
+
+ SUB r10, r4, #32 @ sig_hi[-16] address
+ SUB r11, r5, #32 @ sig_lo[-16] address
+
+ VLD1.S16 {D0, D1, D2, D3}, [r0]! @a[1] ~ a[16]
+
+ MOV r8, #0 @ i = 0
+
+ VLD1.S16 {D4, D5, D6, D7}, [r10]! @ sig_hi[-16] ~ sig_hi[-1]
+ VREV64.16 D0, D0
+ VREV64.16 D1, D1
+ VLD1.S16 {D8, D9, D10, D11}, [r11]! @ sig_lo[-16] ~ sig_lo[-1]
+ VREV64.16 D2, D2
+ VREV64.16 D3, D3
+ VDUP.S32 Q15, r8
+
+SYN_LOOP:
+
+ LDRSH r6, [r2], #2 @exc[i]
+ @L_tmp = L_msu(L_tmp, sig_lo[i - j], a[j])@
+ VMULL.S16 Q10, D8, D3
+ VEXT.8 D8, D8, D9, #2
+ VMLAL.S16 Q10, D9, D2
+ VMLAL.S16 Q10, D10, D1
+ VMLAL.S16 Q10, D11, D0
+
+ VEXT.8 D9, D9, D10, #2
+ VEXT.8 D10, D10, D11, #2
+
+ VPADD.S32 D28, D20, D21
+ MUL r12, r6, r3 @exc[i] * a0
+ VPADD.S32 D29, D28, D28
+ VDUP.S32 Q10, D29[0] @result1
+
+ VMULL.S16 Q11, D4, D3
+ VMLAL.S16 Q11, D5, D2
+ VSUB.S32 Q10, Q15, Q10
+ @L_tmp = L_msu(L_tmp, sig_hi[i - j], a[j])@
+
+ VMLAL.S16 Q11, D6, D1
+ VEXT.8 D4, D4, D5, #2
+ VMLAL.S16 Q11, D7, D0
+
+
+ VEXT.8 D5, D5, D6, #2
+ VEXT.8 D6, D6, D7, #2
+
+ VPADD.S32 D28, D22, D23
+ VPADD.S32 D29, D28, D28
+ MOV r14, r12, LSL #1 @exc[i] * a0 << 1
+ VDUP.S32 Q11, D29[0] @result2
+
+
+
+ VSHR.S32 Q10, Q10, #11 @result1 >>= 11
+ VSHL.S32 Q11, Q11, #1 @result2 <<= 1
+ VDUP.S32 Q12, r14
+ VADD.S32 Q12, Q12, Q10 @L_tmp = L_tmp - (result1 >>= 11) - (result2 <<= 1)
+ VSUB.S32 Q12, Q12, Q11
+
+ VSHL.S32 Q12, Q12, #3 @L_tmp <<= 3
+
+
+ VSHRN.S32 D20, Q12, #16 @sig_hi[i] = L_tmp >> 16@
+ VMOV.S16 r10, D20[0]
+ VSHR.S32 Q12, Q12, #4 @L_tmp >>= 4
+ VEXT.8 D7, D7, D20, #2
+ STRH r10, [r4], #2 @store sig_hi[i]
+ VMOV.S32 r11, D24[0] @r11 --- L_tmp >>= 4
+ ADD r8, r8, #1
+ SUB r12, r11, r10, LSL #12
+ @MOV r11, r12, ASR #16 @sig_lo[i]
+ VDUP.S16 D21, r12
+ VEXT.8 D11, D11, D21, #2
+ STRH r12, [r5], #2 @stroe sig_lo[i]
+
+ CMP r8, #64
+ BLT SYN_LOOP
+
+Syn_filt_32_end:
+
+ LDMFD r13!, {r4 - r12, r15}
+ @ENDFUNC
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
new file mode 100644
index 0000000..189e33b
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
@@ -0,0 +1,178 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@*void Convolve (
+@* Word16 x[], /* (i) : input vector */
+@* Word16 h[], /* (i) : impulse response */
+@* Word16 y[], /* (o) : output vector */
+@* Word16 L /* (i) : vector size */
+@*)
+@
+@ r0 --- x[]
+@ r1 --- h[]
+@ r2 --- y[]
+@ r3 --- L
+
+ .section .text
+ .global Convolve_asm
+
+Convolve_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ MOV r3, #0
+ MOV r11, #0x8000
+
+LOOP:
+ @MOV r8, #0 @ s = 0
+ ADD r4, r1, r3, LSL #1 @ tmpH address
+ ADD r5, r3, #1 @ i = n + 1
+ MOV r6, r0
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4] @ *tmpH--
+ SUB r5, r5, #1
+ VMOV.S32 Q10, #0
+ MUL r8, r9, r10
+
+LOOP1:
+ CMP r5, #0
+ BLE L1
+ SUB r4, r4, #8
+ MOV r9, r4
+ VLD1.S16 D0, [r6]!
+ VLD1.S16 D1, [r9]!
+ VREV64.16 D1, D1
+ SUBS r5, r5, #4
+ VMLAL.S16 Q10, D0, D1
+ B LOOP1
+L1:
+ VADD.S32 D20, D20, D21
+ VPADD.S32 D20, D20, D20
+ VMOV.S32 r5, D20[0]
+ ADD r5, r5, r8
+ ADD r5, r11, r5, LSL #1
+ MOV r5, r5, LSR #16 @extract_h(s)
+ ADD r3, r3, #1
+ STRH r5, [r2], #2 @y[n]
+
+
+ @MOV r8, #0
+ ADD r4, r1, r3, LSL #1 @tmpH address
+ ADD r5, r3, #1
+ MOV r6, r0
+ LDRSH r9, [r6], #2 @ *tmpX++
+ LDRSH r10, [r4], #-2
+ LDRSH r12, [r6], #2
+ LDRSH r14, [r4]
+
+ MUL r8, r9, r10
+ SUB r5, r5, #2
+ MLA r8, r12, r14, r8
+
+ VMOV.S32 Q10, #0
+LOOP2:
+ CMP r5, #0
+ BLE L2
+ SUB r4, r4, #8
+ MOV r9, r4
+ VLD1.S16 D0, [r6]!
+ VLD1.S16 D1, [r9]!
+ SUBS r5, r5, #4
+ VREV64.16 D1, D1
+ VMLAL.S16 Q10, D0, D1
+ B LOOP2
+L2:
+ VADD.S32 D20, D20, D21
+ VPADD.S32 D20, D20, D20
+ VMOV.S32 r5, D20[0]
+ ADD r8, r8, r5
+ ADD r8, r11, r8, LSL #1
+ MOV r8, r8, LSR #16 @extract_h(s)
+ ADD r3, r3, #1
+ STRH r8, [r2], #2 @y[n]
+
+
+ @MOV r8, #0
+ ADD r4, r1, r3, LSL #1
+ ADD r5, r3, #1
+ MOV r6, r0
+ LDRSH r9, [r6], #2
+ LDRSH r10, [r4], #-2
+ LDRSH r12, [r6], #2
+ LDRSH r14, [r4], #-2
+ MUL r8, r9, r10
+ LDRSH r9, [r6], #2
+ LDRSH r10, [r4]
+ MLA r8, r12, r14, r8
+ SUB r5, r5, #3
+ MLA r8, r9, r10, r8
+
+ VMOV.S32 Q10, #0
+LOOP3:
+ CMP r5, #0
+ BLE L3
+ SUB r4, r4, #8
+ MOV r9, r4
+ VLD1.S16 D0, [r6]!
+ VLD1.S16 D1, [r9]!
+ VREV64.16 D1, D1
+ SUBS r5, r5, #4
+ VMLAL.S16 Q10, D0, D1
+ B LOOP3
+
+L3:
+ VADD.S32 D20, D20, D21
+ VPADD.S32 D20, D20, D20
+ VMOV.S32 r5, D20[0]
+ ADD r8, r8, r5
+ ADD r8, r11, r8, LSL #1
+ MOV r8, r8, LSR #16 @extract_h(s)
+ ADD r3, r3, #1
+ STRH r8, [r2], #2 @y[n]
+
+ ADD r5, r3, #1 @ i = n + 1
+ ADD r4, r1, r5, LSL #1 @ tmpH address
+ MOV r6, r0
+ VMOV.S32 Q10, #0
+LOOP4:
+ CMP r5, #0
+ BLE L4
+ SUB r4, r4, #8
+ MOV r9, r4
+ VLD1.S16 D0, [r6]!
+ VLD1.S16 D1, [r9]!
+ VREV64.16 D1, D1
+ SUBS r5, r5, #4
+ VMLAL.S16 Q10, D0, D1
+ B LOOP4
+L4:
+ VADD.S32 D20, D20, D21
+ VPADD.S32 D20, D20, D20
+ VMOV.S32 r5, D20[0]
+ ADD r5, r11, r5, LSL #1
+ MOV r5, r5, LSR #16 @extract_h(s)
+ ADD r3, r3, #1
+ STRH r5, [r2], #2 @y[n]
+
+ CMP r3, #64
+ BLT LOOP
+
+Convolve_asm_end:
+
+ LDMFD r13!, {r4 - r12, r15}
+
+ @ENDFUNC
+ .END
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
new file mode 100644
index 0000000..2e339db
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
@@ -0,0 +1,151 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@static void cor_h_vec_012(
+@ Word16 h[], /* (i) scaled impulse response */
+@ Word16 vec[], /* (i) scaled vector (/8) to correlate with h[] */
+@ Word16 track, /* (i) track to use */
+@ Word16 sign[], /* (i) sign vector */
+@ Word16 rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */
+@ Word16 cor_1[], /* (o) result of correlation (NB_POS elements) */
+@ Word16 cor_2[] /* (o) result of correlation (NB_POS elements) */
+@)
+@r0 ---- h[]
+@r1 ---- vec[]
+@r2 ---- track
+@r3 ---- sign[]
+@r4 ---- rrixix[][NB_POS]
+@r5 ---- cor_1[]
+@r6 ---- cor_2[]
+
+ .section .text
+ .global cor_h_vec_012_asm
+
+cor_h_vec_012_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ LDR r4, [r13, #40] @load rrixix[][NB_POS]
+ ADD r7, r4, r2, LSL #5 @r7 --- p0 = rrixix[track]
+ MOV r4, #0 @i=0
+
+ @r0 --- h[], r1 --- vec[], r2 --- pos
+ @r3 --- sign[], r4 --- i, r7 --- p0
+
+LOOPi:
+ MOV r5, #0 @L_sum1 = 0
+ MOV r6, #0 @L_sum2 = 0
+ ADD r9, r1, r2, LSL #1 @p2 = &vec[pos]
+ MOV r10, r0 @p1 = h
+ RSB r11, r2, #62 @j=62-pos
+
+LOOPj1:
+ LDRSH r12, [r10], #2
+ LDRSH r8, [r9], #2
+ LDRSH r14, [r9]
+ SUBS r11, r11, #1
+ MLA r5, r12, r8, r5
+ MLA r6, r12, r14, r6
+ BGE LOOPj1
+
+ LDRSH r12, [r10], #2 @*p1++
+ MOV r6, r6, LSL #2 @L_sum2 = (L_sum2 << 2)
+ MLA r5, r12, r14, r5
+ MOV r14, #0x8000
+ MOV r5, r5, LSL #2 @L_sum1 = (L_sum1 << 2)
+ ADD r10, r6, r14
+ ADD r9, r5, r14
+ MOV r5, r9, ASR #16
+ MOV r6, r10, ASR #16
+ ADD r9, r3, r2, LSL #1 @address of sign[pos]
+ ADD r8, r7, #32
+ LDRSH r10, [r9], #2 @sign[pos]
+ LDRSH r11, [r9] @sign[pos + 1]
+ MUL r12, r5, r10
+ MUL r14, r6, r11
+ MOV r5, r12, ASR #15
+ MOV r6, r14, ASR #15
+ LDR r9, [r13, #44]
+ LDR r12, [r13, #48]
+ LDRSH r10, [r7], #2 @*p0++
+ LDRSH r11, [r8] @*p3++
+ ADD r9, r9, r4, LSL #1
+ ADD r12, r12, r4, LSL #1
+ ADD r5, r5, r10
+ ADD r6, r6, r11
+ STRH r5, [r9]
+ STRH r6, [r12]
+
+ ADD r2, r2, #4
+
+ MOV r5, #0 @L_sum1 = 0
+ MOV r6, #0 @L_sum2 = 0
+ ADD r9, r1, r2, LSL #1 @p2 = &vec[pos]
+ MOV r10, r0 @p1 = h
+ RSB r11, r2, #62 @j=62-pos
+ ADD r4, r4, #1 @i++
+
+LOOPj2:
+ LDRSH r12, [r10], #2
+ LDRSH r8, [r9], #2
+ LDRSH r14, [r9]
+ SUBS r11, r11, #1
+ MLA r5, r12, r8, r5
+ MLA r6, r12, r14, r6
+ BGE LOOPj2
+
+ LDRSH r12, [r10], #2 @*p1++
+ MOV r6, r6, LSL #2 @L_sum2 = (L_sum2 << 2)
+ MLA r5, r12, r14, r5
+ MOV r14, #0x8000
+ MOV r5, r5, LSL #2 @L_sum1 = (L_sum1 << 2)
+ ADD r10, r6, r14
+ ADD r9, r5, r14
+
+ MOV r5, r9, ASR #16
+ MOV r6, r10, ASR #16
+ ADD r9, r3, r2, LSL #1 @address of sign[pos]
+ ADD r8, r7, #32
+ LDRSH r10, [r9], #2 @sign[pos]
+ LDRSH r11, [r9] @sign[pos + 1]
+ MUL r12, r5, r10
+ MUL r14, r6, r11
+ MOV r5, r12, ASR #15
+ MOV r6, r14, ASR #15
+ LDR r9, [r13, #44]
+ LDR r12, [r13, #48]
+ LDRSH r10, [r7], #2 @*p0++
+ LDRSH r11, [r8] @*p3++
+ ADD r9, r9, r4, LSL #1
+ ADD r12, r12, r4, LSL #1
+ ADD r5, r5, r10
+ ADD r6, r6, r11
+ STRH r5, [r9]
+ STRH r6, [r12]
+ ADD r4, r4, #1 @i+1
+ ADD r2, r2, #4 @pos += STEP
+ CMP r4, #16
+
+ BLT LOOPi
+
+the_end:
+ LDMFD r13!, {r4 - r12, r15}
+
+ .END
+
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
new file mode 100644
index 0000000..3b8853f
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
@@ -0,0 +1,100 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@void Pred_lt4(
+@ Word16 exc[], /* in/out: excitation buffer */
+@ Word16 T0, /* input : integer pitch lag */
+@ Word16 frac, /* input : fraction of lag */
+@ Word16 L_subfr /* input : subframe size */
+@)
+@***********************************************************************
+@ r0 --- exc[]
+@ r1 --- T0
+@ r2 --- frac
+@ r3 --- L_subfr
+
+ .section .text
+ .global pred_lt4_asm
+ .extern inter4_2
+
+pred_lt4_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ SUB r4, r0, r1, LSL #1 @ x = exc - T0
+ RSB r2, r2, #0 @ frac = - frac
+ SUB r4, r4, #30 @ x -= L_INTERPOL2 - 1
+ CMP r2, #0
+ ADDLT r2, r2, #4 @ frac += UP_SAMP
+ SUBLT r4, r4, #2 @ x--
+
+ LDR r11, Lable1
+ RSB r2, r2, #3 @ k = UP_SAMP - 1 - frac
+ MOV r8, #0 @ j = 0
+ ADD r11, r11, r2, LSL #6 @ get inter4_2[k][]
+
+ VLD1.S16 {Q0, Q1}, [r11]!
+ VLD1.S16 {Q2, Q3}, [r11]!
+
+ MOV r6, #0x8000
+
+ VLD1.S16 {Q4, Q5}, [r4]! @load 16 x[]
+ VLD1.S16 {Q6, Q7}, [r4]! @load 16 x[]
+
+LOOP:
+ VQDMULL.S16 Q15, D8, D0
+ VQDMLAL.S16 Q15, D9, D1
+ VQDMLAL.S16 Q15, D10, D2
+ VQDMLAL.S16 Q15, D11, D3
+
+ VQDMLAL.S16 Q15, D12, D4
+ VQDMLAL.S16 Q15, D13, D5
+ VQDMLAL.S16 Q15, D14, D6
+ VQDMLAL.S16 Q15, D15, D7
+
+ LDRSH r12, [r4], #2
+
+ VEXT.S16 D8, D8, D9, #1
+ VEXT.S16 D9, D9, D10, #1
+ VEXT.S16 D10, D10, D11, #1
+ VEXT.S16 D11, D11, D12, #1
+ VDUP.S16 D24, r12
+ VEXT.S16 D12, D12, D13, #1
+ VEXT.S16 D13, D13, D14, #1
+
+ VQADD.S32 D30, D30, D31
+ MOV r11, #0x8000
+ VPADD.S32 D30, D30, D30
+ ADD r8, r8, #1
+ VMOV.S32 r12, D30[0]
+ VEXT.S16 D14, D14, D15, #1
+
+ QADD r1, r12, r12 @ L_sum = (L_sum << 2)
+ VEXT.S16 D15, D15, D24, #1
+ QADD r5, r1, r6
+ MOV r1, r5, ASR #16
+ CMP r8, r3
+ STRH r1, [r0], #2 @ exc[j] = (L_sum + 0x8000) >> 16
+ BLT LOOP
+
+pred_lt4_end:
+
+ LDMFD r13!, {r4 - r12, r15}
+
+Lable1:
+ .word inter4_2
+ @ENDFUNC
+ .END
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
new file mode 100644
index 0000000..b9e6b23
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
@@ -0,0 +1,127 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@void Residu (
+@ Word16 a[], /* (i) : prediction coefficients */
+@ Word16 x[], /* (i) : speech signal */
+@ Word16 y[], /* (o) : residual signal */
+@ Word16 lg /* (i) : size of filtering */
+@)
+@a[] RN r0
+@x[] RN r1
+@y[] RN r2
+@lg RN r3
+
+ .section .text
+ .global Residu_opt
+
+Residu_opt:
+
+ STMFD r13!, {r4 - r12, r14}
+ SUB r7, r3, #4 @i = lg - 4
+
+ VLD1.S16 {D0, D1, D2, D3}, [r0]! @get all a[]
+ VLD1.S16 {D4}, [r0]!
+ VMOV.S32 Q8, #0x8000
+
+LOOP1:
+ ADD r9, r1, r7, LSL #1 @copy the address
+ ADD r10, r2, r7, LSL #1
+ MOV r8, r9
+ VLD1.S16 D5, [r8]! @get x[i], x[i+1], x[i+2], x[i+3]
+ VQDMULL.S16 Q10, D5, D0[0] @finish the first L_mult
+
+ SUB r8, r9, #2 @get the x[i-1] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D0[1]
+
+ SUB r8, r9, #4 @load the x[i-2] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D0[2]
+
+ SUB r8, r9, #6 @load the x[i-3] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D0[3]
+
+ SUB r8, r9, #8 @load the x[i-4] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D1[0]
+
+ SUB r8, r9, #10 @load the x[i-5] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D1[1]
+
+ SUB r8, r9, #12 @load the x[i-6] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D1[2]
+
+ SUB r8, r9, #14 @load the x[i-7] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D1[3]
+
+ SUB r8, r9, #16 @load the x[i-8] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D2[0]
+
+ SUB r8, r9, #18 @load the x[i-9] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D2[1]
+
+ SUB r8, r9, #20 @load the x[i-10] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D2[2]
+
+ SUB r8, r9, #22 @load the x[i-11] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D2[3]
+
+ SUB r8, r9, #24 @load the x[i-12] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D3[0]
+
+ SUB r8, r9, #26 @load the x[i-13] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D3[1]
+
+ SUB r8, r9, #28 @load the x[i-14] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D3[2]
+
+ SUB r8, r9, #30 @load the x[i-15] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D3[3]
+
+ SUB r8, r9, #32 @load the x[i-16] address
+ VLD1.S16 D5, [r8]!
+ VQDMLAL.S16 Q10, D5, D4[0]
+
+ SUB r7, r7, #4 @i-=4
+ VQSHL.S32 Q10, Q10, #4
+ VQADD.S32 Q10, Q10, Q8
+ VSHRN.S32 D5, Q10, #16
+ VST1.S16 D5, [r10]!
+ CMP r7, #0
+
+ BGE LOOP1
+
+Residu_asm_end:
+
+ LDMFD r13!, {r4 - r12, r15}
+
+ @ENDFUNC
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
new file mode 100644
index 0000000..14957d8
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
@@ -0,0 +1,138 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@**********************************************************************/
+@void Scale_sig(
+@ Word16 x[], /* (i/o) : signal to scale */
+@ Word16 lg, /* (i) : size of x[] */
+@ Word16 exp /* (i) : exponent: x = round(x << exp) */
+@)
+@***********************************************************************
+@ x[] --- r0
+@ lg --- r1
+@ exp --- r2
+
+ .section .text
+ .global Scale_sig_opt
+
+Scale_sig_opt:
+
+ STMFD r13!, {r4 - r12, r14}
+ MOV r4, #4
+ VMOV.S32 Q15, #0x8000
+ VDUP.S32 Q14, r2
+ MOV r5, r0 @ copy x[] address
+ CMP r1, #64
+ MOVEQ r4, #1
+ BEQ LOOP
+ CMP r1, #128
+ MOVEQ r4, #2
+ BEQ LOOP
+ CMP r1, #256
+ BEQ LOOP
+ CMP r1, #80
+ MOVEQ r4, #1
+ BEQ LOOP1
+
+LOOP1:
+ VLD1.S16 {Q0, Q1}, [r5]! @load 16 Word16 x[]
+ VSHLL.S16 Q10, D0, #16
+ VSHLL.S16 Q11, D1, #16
+ VSHLL.S16 Q12, D2, #16
+ VSHLL.S16 Q13, D3, #16
+ VSHL.S32 Q10, Q10, Q14
+ VSHL.S32 Q11, Q11, Q14
+ VSHL.S32 Q12, Q12, Q14
+ VSHL.S32 Q13, Q13, Q14
+ VADDHN.S32 D16, Q10, Q15
+ VADDHN.S32 D17, Q11, Q15
+ VADDHN.S32 D18, Q12, Q15
+ VADDHN.S32 D19, Q13, Q15
+ VST1.S16 {Q8, Q9}, [r0]! @store 16 Word16 x[]
+
+LOOP:
+ VLD1.S16 {Q0, Q1}, [r5]! @load 16 Word16 x[]
+ VLD1.S16 {Q2, Q3}, [r5]! @load 16 Word16 x[]
+ VLD1.S16 {Q4, Q5}, [r5]! @load 16 Word16 x[]
+ VLD1.S16 {Q6, Q7}, [r5]! @load 16 Word16 x[]
+
+ VSHLL.S16 Q8, D0, #16
+ VSHLL.S16 Q9, D1, #16
+ VSHLL.S16 Q10, D2, #16
+ VSHLL.S16 Q11, D3, #16
+ VSHL.S32 Q8, Q8, Q14
+ VSHL.S32 Q9, Q9, Q14
+ VSHL.S32 Q10, Q10, Q14
+ VSHL.S32 Q11, Q11, Q14
+ VADDHN.S32 D16, Q8, Q15
+ VADDHN.S32 D17, Q9, Q15
+ VADDHN.S32 D18, Q10, Q15
+ VADDHN.S32 D19, Q11, Q15
+ VST1.S16 {Q8, Q9}, [r0]! @store 16 Word16 x[]
+
+
+ VSHLL.S16 Q12, D4, #16
+ VSHLL.S16 Q13, D5, #16
+ VSHLL.S16 Q10, D6, #16
+ VSHLL.S16 Q11, D7, #16
+ VSHL.S32 Q12, Q12, Q14
+ VSHL.S32 Q13, Q13, Q14
+ VSHL.S32 Q10, Q10, Q14
+ VSHL.S32 Q11, Q11, Q14
+ VADDHN.S32 D16, Q12, Q15
+ VADDHN.S32 D17, Q13, Q15
+ VADDHN.S32 D18, Q10, Q15
+ VADDHN.S32 D19, Q11, Q15
+ VST1.S16 {Q8, Q9}, [r0]! @store 16 Word16 x[]
+
+ VSHLL.S16 Q10, D8, #16
+ VSHLL.S16 Q11, D9, #16
+ VSHLL.S16 Q12, D10, #16
+ VSHLL.S16 Q13, D11, #16
+ VSHL.S32 Q10, Q10, Q14
+ VSHL.S32 Q11, Q11, Q14
+ VSHL.S32 Q12, Q12, Q14
+ VSHL.S32 Q13, Q13, Q14
+ VADDHN.S32 D16, Q10, Q15
+ VADDHN.S32 D17, Q11, Q15
+ VADDHN.S32 D18, Q12, Q15
+ VADDHN.S32 D19, Q13, Q15
+ VST1.S16 {Q8, Q9}, [r0]! @store 16 Word16 x[]
+
+ VSHLL.S16 Q10, D12, #16
+ VSHLL.S16 Q11, D13, #16
+ VSHLL.S16 Q12, D14, #16
+ VSHLL.S16 Q13, D15, #16
+ VSHL.S32 Q10, Q10, Q14
+ VSHL.S32 Q11, Q11, Q14
+ VSHL.S32 Q12, Q12, Q14
+ VSHL.S32 Q13, Q13, Q14
+ VADDHN.S32 D16, Q10, Q15
+ VADDHN.S32 D17, Q11, Q15
+ VADDHN.S32 D18, Q12, Q15
+ VADDHN.S32 D19, Q13, Q15
+ VST1.S16 {Q8, Q9}, [r0]! @store 16 Word16 x[]
+ SUBS r4, r4, #1
+ BGT LOOP
+
+
+Scale_sig_asm_end:
+
+ LDMFD r13!, {r4 - r12, r15}
+ @ENDFUNC
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
new file mode 100644
index 0000000..dc3d4a8
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
@@ -0,0 +1,106 @@
+@/*
+@ ** Copyright 2003-2010, VisualOn, Inc.
+@ **
+@ ** Licensed under the Apache License, Version 2.0 (the "License");
+@ ** you may not use this file except in compliance with the License.
+@ ** You may obtain a copy of the License at
+@ **
+@ ** http://www.apache.org/licenses/LICENSE-2.0
+@ **
+@ ** Unless required by applicable law or agreed to in writing, software
+@ ** distributed under the License is distributed on an "AS IS" BASIS,
+@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@ ** See the License for the specific language governing permissions and
+@ ** limitations under the License.
+@ */
+@
+@void Syn_filt(
+@ Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients */
+@ Word16 x[], /* (i) : input signal */
+@ Word16 y[], /* (o) : output signal */
+@ Word16 mem[], /* (i/o) : memory associated with this filtering. */
+@)
+@***********************************************************************
+@ a[] --- r0
+@ x[] --- r1
+@ y[] --- r2
+@ mem[] --- r3
+@ m --- 16 lg --- 80 update --- 1
+
+ .section .text
+ .global Syn_filt_asm
+
+Syn_filt_asm:
+
+ STMFD r13!, {r4 - r12, r14}
+ SUB r13, r13, #700 @ y_buf[L_FRAME16k + M16k]
+
+ MOV r4, r3 @ copy mem[] address
+ MOV r5, r13 @ copy yy = y_buf address
+
+ @ for(i = 0@ i < m@ i++)
+ @{
+ @ *yy++ = mem[i]@
+ @}
+ VLD1.S16 {D0, D1, D2, D3}, [r4]! @load 16 mems
+ VST1.S16 {D0, D1, D2, D3}, [r5]! @store 16 mem[] to *yy
+
+ LDRSH r5, [r0], #2 @ load a[0]
+ MOV r8, #0 @ i = 0
+ MOV r5, r5, ASR #1 @ a0 = a[0] >> 1
+ VMOV.S16 D8[0], r5
+ @ load all a[]
+ VLD1.S16 {D0, D1, D2, D3}, [r0]! @ load a[1] ~ a[16]
+ VREV64.16 D0, D0
+ VREV64.16 D1, D1
+ VREV64.16 D2, D2
+ VREV64.16 D3, D3
+ MOV r8, #0 @ loop times
+ MOV r10, r13 @ temp = y_buf
+ ADD r4, r13, #32 @ yy[i] address
+
+ VLD1.S16 {D4, D5, D6, D7}, [r10]! @ first 16 temp_p
+
+SYN_LOOP:
+
+ LDRSH r6, [r1], #2 @ load x[i]
+ MUL r12, r6, r5 @ L_tmp = x[i] * a0
+ ADD r10, r4, r8, LSL #1 @ y[i], yy[i] address
+
+ VDUP.S32 Q10, r12
+ VMULL.S16 Q5, D3, D4
+ VMLAL.S16 Q5, D2, D5
+ VMLAL.S16 Q5, D1, D6
+ VMLAL.S16 Q5, D0, D7
+ VEXT.8 D4, D4, D5, #2
+ VEXT.8 D5, D5, D6, #2
+ VEXT.8 D6, D6, D7, #2
+ VPADD.S32 D12, D10, D11
+ ADD r8, r8, #1
+ VPADD.S32 D10, D12, D12
+
+ VDUP.S32 Q7, D10[0]
+
+ VSUB.S32 Q9, Q10, Q7
+ VQRSHRN.S32 D20, Q9, #12
+ VMOV.S16 r9, D20[0]
+ VEXT.8 D7, D7, D20, #2
+ CMP r8, #80
+ STRH r9, [r10] @ yy[i]
+ STRH r9, [r2], #2 @ y[i]
+
+ BLT SYN_LOOP
+
+ @ update mem[]
+ ADD r5, r13, #160 @ yy[64] address
+ VLD1.S16 {D0, D1, D2, D3}, [r5]!
+ VST1.S16 {D0, D1, D2, D3}, [r3]!
+
+Syn_filt_asm_end:
+
+ ADD r13, r13, #700
+ LDMFD r13!, {r4 - r12, r15}
+ @ENDFUNC
+ .END
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/autocorr.c b/media/libstagefright/codecs/amrwbenc/src/autocorr.c
new file mode 100644
index 0000000..33ed670
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/autocorr.c
@@ -0,0 +1,127 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+
+/***********************************************************************
+* File: autocorr.c *
+* *
+* Description:Compute autocorrelations of signal with windowing *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "acelp.h"
+#include "ham_wind.tab"
+
+void Autocorr(
+ Word16 x[], /* (i) : Input signal */
+ Word16 m, /* (i) : LPC order */
+ Word16 r_h[], /* (o) Q15: Autocorrelations (msb) */
+ Word16 r_l[] /* (o) : Autocorrelations (lsb) */
+ )
+{
+ Word32 i, norm, shift;
+ Word16 y[L_WINDOW];
+ Word32 L_sum, L_sum1, L_tmp, F_LEN;
+ Word16 *p1,*p2,*p3;
+ const Word16 *p4;
+ /* Windowing of signal */
+ p1 = x;
+ p4 = vo_window;
+ p3 = y;
+
+ for (i = 0; i < L_WINDOW; i+=4)
+ {
+ *p3++ = vo_mult_r((*p1++), (*p4++));
+ *p3++ = vo_mult_r((*p1++), (*p4++));
+ *p3++ = vo_mult_r((*p1++), (*p4++));
+ *p3++ = vo_mult_r((*p1++), (*p4++));
+ }
+
+ /* calculate energy of signal */
+ L_sum = vo_L_deposit_h(16); /* sqrt(256), avoid overflow after rounding */
+ for (i = 0; i < L_WINDOW; i++)
+ {
+ L_tmp = vo_L_mult(y[i], y[i]);
+ L_tmp = (L_tmp >> 8);
+ L_sum += L_tmp;
+ }
+
+ /* scale signal to avoid overflow in autocorrelation */
+ norm = norm_l(L_sum);
+ shift = 4 - (norm >> 1);
+ if(shift > 0)
+ {
+ p1 = y;
+ for (i = 0; i < L_WINDOW; i+=4)
+ {
+ *p1 = vo_shr_r(*p1, shift);
+ p1++;
+ *p1 = vo_shr_r(*p1, shift);
+ p1++;
+ *p1 = vo_shr_r(*p1, shift);
+ p1++;
+ *p1 = vo_shr_r(*p1, shift);
+ p1++;
+ }
+ }
+
+ /* Compute and normalize r[0] */
+ L_sum = 1;
+ for (i = 0; i < L_WINDOW; i+=4)
+ {
+ L_sum += vo_L_mult(y[i], y[i]);
+ L_sum += vo_L_mult(y[i+1], y[i+1]);
+ L_sum += vo_L_mult(y[i+2], y[i+2]);
+ L_sum += vo_L_mult(y[i+3], y[i+3]);
+ }
+
+ norm = norm_l(L_sum);
+ L_sum = (L_sum << norm);
+
+ r_h[0] = L_sum >> 16;
+ r_l[0] = (L_sum & 0xffff)>>1;
+
+ /* Compute r[1] to r[m] */
+ for (i = 1; i <= 8; i++)
+ {
+ L_sum1 = 0;
+ L_sum = 0;
+ F_LEN = (Word32)(L_WINDOW - 2*i);
+ p1 = y;
+ p2 = y + (2*i)-1;
+ do{
+ L_sum1 += *p1 * *p2++;
+ L_sum += *p1++ * *p2;
+ }while(--F_LEN!=0);
+
+ L_sum1 += *p1 * *p2++;
+
+ L_sum1 = L_sum1<<norm;
+ L_sum = L_sum<<norm;
+
+ r_h[(2*i)-1] = L_sum1 >> 15;
+ r_l[(2*i)-1] = L_sum1 & 0x00007fff;
+ r_h[(2*i)] = L_sum >> 15;
+ r_l[(2*i)] = L_sum & 0x00007fff;
+ }
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/az_isp.c b/media/libstagefright/codecs/amrwbenc/src/az_isp.c
new file mode 100644
index 0000000..8259f91
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/az_isp.c
@@ -0,0 +1,268 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: az_isp.c
+*
+* Description:
+*-----------------------------------------------------------------------*
+* Compute the ISPs from the LPC coefficients (order=M) *
+*-----------------------------------------------------------------------*
+* *
+* The ISPs are the roots of the two polynomials F1(z) and F2(z) *
+* defined as *
+* F1(z) = A(z) + z^-m A(z^-1) *
+* and F2(z) = A(z) - z^-m A(z^-1) *
+* *
+* For a even order m=2n, F1(z) has M/2 conjugate roots on the unit *
+* circle and F2(z) has M/2-1 conjugate roots on the unit circle in *
+* addition to two roots at 0 and pi. *
+* *
+* For a 16th order LP analysis, F1(z) and F2(z) can be written as *
+* *
+* F1(z) = (1 + a[M]) PRODUCT (1 - 2 cos(w_i) z^-1 + z^-2 ) *
+* i=0,2,4,6,8,10,12,14 *
+* *
+* F2(z) = (1 - a[M]) (1 - z^-2) PRODUCT (1 - 2 cos(w_i) z^-1 + z^-2 ) *
+* i=1,3,5,7,9,11,13 *
+* *
+* The ISPs are the M-1 frequencies w_i, i=0...M-2 plus the last *
+* predictor coefficient a[M]. *
+*-----------------------------------------------------------------------*
+
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "stdio.h"
+#include "grid100.tab"
+
+#define M 16
+#define NC (M/2)
+
+/* local function */
+static __inline Word16 Chebps2(Word16 x, Word16 f[], Word32 n);
+
+void Az_isp(
+ Word16 a[], /* (i) Q12 : predictor coefficients */
+ Word16 isp[], /* (o) Q15 : Immittance spectral pairs */
+ Word16 old_isp[] /* (i) : old isp[] (in case not found M roots) */
+ )
+{
+ Word32 i, j, nf, ip, order;
+ Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
+ Word16 x, y, sign, exp;
+ Word16 *coef;
+ Word16 f1[NC + 1], f2[NC];
+ Word32 t0;
+ /*-------------------------------------------------------------*
+ * find the sum and diff polynomials F1(z) and F2(z) *
+ * F1(z) = [A(z) + z^M A(z^-1)] *
+ * F2(z) = [A(z) - z^M A(z^-1)]/(1-z^-2) *
+ * *
+ * for (i=0; i<NC; i++) *
+ * { *
+ * f1[i] = a[i] + a[M-i]; *
+ * f2[i] = a[i] - a[M-i]; *
+ * } *
+ * f1[NC] = 2.0*a[NC]; *
+ * *
+ * for (i=2; i<NC; i++) Divide by (1-z^-2) *
+ * f2[i] += f2[i-2]; *
+ *-------------------------------------------------------------*/
+ for (i = 0; i < NC; i++)
+ {
+ t0 = a[i] << 15;
+ f1[i] = vo_round(t0 + (a[M - i] << 15)); /* =(a[i]+a[M-i])/2 */
+ f2[i] = vo_round(t0 - (a[M - i] << 15)); /* =(a[i]-a[M-i])/2 */
+ }
+ f1[NC] = a[NC];
+ for (i = 2; i < NC; i++) /* Divide by (1-z^-2) */
+ f2[i] = add1(f2[i], f2[i - 2]);
+
+ /*---------------------------------------------------------------------*
+ * Find the ISPs (roots of F1(z) and F2(z) ) using the *
+ * Chebyshev polynomial evaluation. *
+ * The roots of F1(z) and F2(z) are alternatively searched. *
+ * We start by finding the first root of F1(z) then we switch *
+ * to F2(z) then back to F1(z) and so on until all roots are found. *
+ * *
+ * - Evaluate Chebyshev pol. at grid points and check for sign change.*
+ * - If sign change track the root by subdividing the interval *
+ * 2 times and ckecking sign change. *
+ *---------------------------------------------------------------------*/
+ nf = 0; /* number of found frequencies */
+ ip = 0; /* indicator for f1 or f2 */
+ coef = f1;
+ order = NC;
+ xlow = vogrid[0];
+ ylow = Chebps2(xlow, coef, order);
+ j = 0;
+ while ((nf < M - 1) && (j < GRID_POINTS))
+ {
+ j ++;
+ xhigh = xlow;
+ yhigh = ylow;
+ xlow = vogrid[j];
+ ylow = Chebps2(xlow, coef, order);
+ if ((ylow * yhigh) <= (Word32) 0)
+ {
+ /* divide 2 times the interval */
+ for (i = 0; i < 2; i++)
+ {
+ xmid = (xlow >> 1) + (xhigh >> 1); /* xmid = (xlow + xhigh)/2 */
+ ymid = Chebps2(xmid, coef, order);
+ if ((ylow * ymid) <= (Word32) 0)
+ {
+ yhigh = ymid;
+ xhigh = xmid;
+ } else
+ {
+ ylow = ymid;
+ xlow = xmid;
+ }
+ }
+ /*-------------------------------------------------------------*
+ * Linear interpolation *
+ * xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow); *
+ *-------------------------------------------------------------*/
+ x = xhigh - xlow;
+ y = yhigh - ylow;
+ if (y == 0)
+ {
+ xint = xlow;
+ } else
+ {
+ sign = y;
+ y = abs_s(y);
+ exp = norm_s(y);
+ y = y << exp;
+ y = div_s((Word16) 16383, y);
+ t0 = x * y;
+ t0 = (t0 >> (19 - exp));
+ y = vo_extract_l(t0); /* y= (xhigh-xlow)/(yhigh-ylow) in Q11 */
+ if (sign < 0)
+ y = -y;
+ t0 = ylow * y; /* result in Q26 */
+ t0 = (t0 >> 10); /* result in Q15 */
+ xint = vo_sub(xlow, vo_extract_l(t0)); /* xint = xlow - ylow*y */
+ }
+ isp[nf] = xint;
+ xlow = xint;
+ nf++;
+ if (ip == 0)
+ {
+ ip = 1;
+ coef = f2;
+ order = NC - 1;
+ } else
+ {
+ ip = 0;
+ coef = f1;
+ order = NC;
+ }
+ ylow = Chebps2(xlow, coef, order);
+ }
+ }
+ /* Check if M-1 roots found */
+ if(nf < M - 1)
+ {
+ for (i = 0; i < M; i++)
+ {
+ isp[i] = old_isp[i];
+ }
+ } else
+ {
+ isp[M - 1] = a[M] << 3; /* From Q12 to Q15 with saturation */
+ }
+ return;
+}
+
+/*--------------------------------------------------------------*
+* function Chebps2: *
+* ~~~~~~~ *
+* Evaluates the Chebishev polynomial series *
+*--------------------------------------------------------------*
+* *
+* The polynomial order is *
+* n = M/2 (M is the prediction order) *
+* The polynomial is given by *
+* C(x) = f(0)T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2 *
+* Arguments: *
+* x: input value of evaluation; x = cos(frequency) in Q15 *
+* f[]: coefficients of the pol. in Q11 *
+* n: order of the pol. *
+* *
+* The value of C(x) is returned. (Satured to +-1.99 in Q14) *
+* *
+*--------------------------------------------------------------*/
+
+static __inline Word16 Chebps2(Word16 x, Word16 f[], Word32 n)
+{
+ Word32 i, cheb;
+ Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l;
+ Word32 t0;
+
+ /* Note: All computation are done in Q24. */
+
+ t0 = f[0] << 13;
+ b2_h = t0 >> 16;
+ b2_l = (t0 & 0xffff)>>1;
+
+ t0 = ((b2_h * x)<<1) + (((b2_l * x)>>15)<<1);
+ t0 <<= 1;
+ t0 += (f[1] << 13); /* + f[1] in Q24 */
+
+ b1_h = t0 >> 16;
+ b1_l = (t0 & 0xffff) >> 1;
+
+ for (i = 2; i < n; i++)
+ {
+ t0 = ((b1_h * x)<<1) + (((b1_l * x)>>15)<<1);
+
+ t0 += (b2_h * (-16384))<<1;
+ t0 += (f[i] << 12);
+ t0 <<= 1;
+ t0 -= (b2_l << 1); /* t0 = 2.0*x*b1 - b2 + f[i]; */
+
+ b0_h = t0 >> 16;
+ b0_l = (t0 & 0xffff) >> 1;
+
+ b2_l = b1_l; /* b2 = b1; */
+ b2_h = b1_h;
+ b1_l = b0_l; /* b1 = b0; */
+ b1_h = b0_h;
+ }
+
+ t0 = ((b1_h * x)<<1) + (((b1_l * x)>>15)<<1);
+ t0 += (b2_h * (-32768))<<1; /* t0 = x*b1 - b2 */
+ t0 -= (b2_l << 1);
+ t0 += (f[n] << 12); /* t0 = x*b1 - b2 + f[i]/2 */
+
+ t0 = L_shl2(t0, 6); /* Q24 to Q30 with saturation */
+
+ cheb = extract_h(t0); /* Result in Q14 */
+
+ if (cheb == -32768)
+ {
+ cheb = -32767; /* to avoid saturation in Az_isp */
+ }
+ return (cheb);
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/bits.c b/media/libstagefright/codecs/amrwbenc/src/bits.c
new file mode 100644
index 0000000..90d1a00
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/bits.c
@@ -0,0 +1,210 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+ File: bits.c
+
+ Description: Performs bit stream manipulation
+
+************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "typedef.h"
+#include "basic_op.h"
+#include "cnst.h"
+#include "bits.h"
+#include "acelp.h"
+#include "dtx.h"
+#include "mime_io.tab"
+
+
+int PackBits(Word16 prms[], /* i: analysis parameters */
+ Word16 coding_mode, /* i: coding bit-stream ratio mode */
+ Word16 mode, /* i: coding bit-stream ratio mode*/
+ Coder_State *st /*i/o: coder global parameters struct */
+ )
+{
+ Word16 i, frame_type;
+ UWord8 temp;
+ UWord8 *stream_ptr;
+ Word16 bitstreamformat = st->frameType;
+
+ unsigned short* dataOut = st->outputStream;
+
+ if (coding_mode == MRDTX)
+ {
+ st->sid_update_counter--;
+
+ if (st->prev_ft == TX_SPEECH)
+ {
+ frame_type = TX_SID_FIRST;
+ st->sid_update_counter = 3;
+ } else
+ {
+ if ((st->sid_handover_debt > 0) && (st->sid_update_counter > 2))
+ {
+ /* ensure extra updates are properly delayed after a possible SID_FIRST */
+ frame_type = TX_SID_UPDATE;
+ st->sid_handover_debt--;
+ } else
+ {
+ if (st->sid_update_counter == 0)
+ {
+ frame_type = TX_SID_UPDATE;
+ st->sid_update_counter = 8;
+ } else
+ {
+ frame_type = TX_NO_DATA;
+ }
+ }
+ }
+ } else
+ {
+ st->sid_update_counter = 8;
+ frame_type = TX_SPEECH;
+ }
+ st->prev_ft = frame_type;
+
+ if(bitstreamformat == 0) /* default file format */
+ {
+ *(dataOut) = TX_FRAME_TYPE;
+ *(dataOut + 1) = frame_type;
+ *(dataOut + 2) = mode;
+ for (i = 0; i < nb_of_bits[coding_mode]; i++)
+ {
+ *(dataOut + 3 + i) = prms[i];
+ }
+ return (3 + nb_of_bits[coding_mode])<<1;
+ } else
+ {
+ if (bitstreamformat == 1) /* ITU file format */
+ {
+ *(dataOut) = 0x6b21;
+ if(frame_type != TX_NO_DATA && frame_type != TX_SID_FIRST)
+ {
+ *(dataOut + 1) = nb_of_bits[coding_mode];
+ for (i = 0; i < nb_of_bits[coding_mode]; i++)
+ {
+ if(prms[i] == BIT_0){
+ *(dataOut + 2 + i) = BIT_0_ITU;
+ }
+ else{
+ *(dataOut + 2 + i) = BIT_1_ITU;
+ }
+ }
+ return (2 + nb_of_bits[coding_mode])<<1;
+ } else
+ {
+ *(dataOut + 1) = 0;
+ return 2<<1;
+ }
+ } else /* MIME/storage file format */
+ {
+#define MRSID 9
+ /* change mode index in case of SID frame */
+ if (coding_mode == MRDTX)
+ {
+ coding_mode = MRSID;
+ if (frame_type == TX_SID_FIRST)
+ {
+ for (i = 0; i < NBBITS_SID; i++) prms[i] = BIT_0;
+ }
+ }
+ /* -> force NO_DATA frame */
+ if (coding_mode < 0 || coding_mode > 15 || (coding_mode > MRSID && coding_mode < 14))
+ {
+ coding_mode = 15;
+ }
+ /* mark empty frames between SID updates as NO_DATA frames */
+ if (coding_mode == MRSID && frame_type == TX_NO_DATA)
+ {
+ coding_mode = 15;
+ }
+ /* set pointer for packed frame, note that we handle data as bytes */
+ stream_ptr = (UWord8*)dataOut;
+ /* insert table of contents (ToC) byte at the beginning of the packet */
+ *stream_ptr = toc_byte[coding_mode];
+ stream_ptr++;
+ temp = 0;
+ /* sort and pack AMR-WB speech or SID bits */
+ for (i = 1; i < unpacked_size[coding_mode] + 1; i++)
+ {
+ if (prms[sort_ptr[coding_mode][i-1]] == BIT_1)
+ {
+ temp++;
+ }
+ if (i&0x7)
+ {
+ temp <<= 1;
+ }
+ else
+ {
+ *stream_ptr = temp;
+ stream_ptr++;
+ temp = 0;
+ }
+ }
+ /* insert SID type indication and speech mode in case of SID frame */
+ if (coding_mode == MRSID)
+ {
+ if (frame_type == TX_SID_UPDATE)
+ {
+ temp++;
+ }
+ temp <<= 4;
+ temp += mode & 0x000F;
+ }
+ /* insert unused bits (zeros) at the tail of the last byte */
+ if (unused_size[coding_mode])
+ {
+ temp <<= (unused_size[coding_mode] - 1);
+ }
+ *stream_ptr = temp;
+ /* write packed frame into file (1 byte added to cover ToC entry) */
+ return (1 + packed_size[coding_mode]);
+ }
+ }
+}
+
+/*-----------------------------------------------------*
+* Parm_serial -> convert parameters to serial stream *
+*-----------------------------------------------------*/
+
+void Parm_serial(
+ Word16 value, /* input : parameter value */
+ Word16 no_of_bits, /* input : number of bits */
+ Word16 ** prms
+ )
+{
+ Word16 i, bit;
+ *prms += no_of_bits;
+ for (i = 0; i < no_of_bits; i++)
+ {
+ bit = (Word16) (value & 0x0001); /* get lsb */
+ if (bit == 0)
+ *--(*prms) = BIT_0;
+ else
+ *--(*prms) = BIT_1;
+ value >>= 1;
+ }
+ *prms += no_of_bits;
+ return;
+}
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c b/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c
new file mode 100644
index 0000000..39fc4c5
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c
@@ -0,0 +1,297 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/************************************************************************
+* File: c2t64fx.c *
+* *
+* Description:Performs algebraic codebook search for 6.60kbits mode*
+* *
+*************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "acelp.h"
+#include "cnst.h"
+
+#define NB_TRACK 2
+#define STEP 2
+#define NB_POS 32
+#define MSIZE 1024
+
+/*************************************************************************
+* Function: ACELP_2t64_fx() *
+* *
+* 12 bits algebraic codebook. *
+* 2 tracks x 32 positions per track = 64 samples. *
+* *
+* 12 bits --> 2 pulses in a frame of 64 samples. *
+* *
+* All pulses can have two (2) possible amplitudes: +1 or -1. *
+* Each pulse can have 32 possible positions. *
+**************************************************************************/
+
+void ACELP_2t64_fx(
+ Word16 dn[], /* (i) <12b : correlation between target x[] and H[] */
+ Word16 cn[], /* (i) <12b : residual after long term prediction */
+ Word16 H[], /* (i) Q12: impulse response of weighted synthesis filter */
+ Word16 code[], /* (o) Q9 : algebraic (fixed) codebook excitation */
+ Word16 y[], /* (o) Q9 : filtered fixed codebook excitation */
+ Word16 * index /* (o) : index (12): 5+1+5+1 = 11 bits. */
+ )
+{
+ Word32 i, j, k, i0, i1, ix, iy, pos, pos2;
+ Word16 ps, psk, ps1, ps2, alpk, alp1, alp2, sq;
+ Word16 alp, val, exp, k_cn, k_dn;
+ Word16 *p0, *p1, *p2, *psign;
+ Word16 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf;
+
+ Word16 sign[L_SUBFR], vec[L_SUBFR], dn2[L_SUBFR];
+ Word16 h_buf[4 * L_SUBFR] = {0};
+ Word16 rrixix[NB_TRACK][NB_POS];
+ Word16 rrixiy[MSIZE];
+ Word32 s, cor;
+
+ /*----------------------------------------------------------------*
+ * Find sign for each pulse position. *
+ *----------------------------------------------------------------*/
+ alp = 8192; /* alp = 2.0 (Q12) */
+
+ /* calculate energy for normalization of cn[] and dn[] */
+ /* set k_cn = 32..32767 (ener_cn = 2^30..256-0) */
+#ifdef ASM_OPT /* asm optimization branch */
+ s = Dot_product12_asm(cn, cn, L_SUBFR, &exp);
+#else
+ s = Dot_product12(cn, cn, L_SUBFR, &exp);
+#endif
+
+ Isqrt_n(&s, &exp);
+ s = L_shl(s, add1(exp, 5));
+ k_cn = vo_round(s);
+
+ /* set k_dn = 32..512 (ener_dn = 2^30..2^22) */
+#ifdef ASM_OPT /* asm optimization branch */
+ s = Dot_product12_asm(dn, dn, L_SUBFR, &exp);
+#else
+ s = Dot_product12(dn, dn, L_SUBFR, &exp);
+#endif
+
+ Isqrt_n(&s, &exp);
+ k_dn = vo_round(L_shl(s, (exp + 8))); /* k_dn = 256..4096 */
+ k_dn = vo_mult_r(alp, k_dn); /* alp in Q12 */
+
+ /* mix normalized cn[] and dn[] */
+ p0 = cn;
+ p1 = dn;
+ p2 = dn2;
+
+ for (i = 0; i < L_SUBFR/4; i++)
+ {
+ s = (k_cn* (*p0++))+(k_dn * (*p1++));
+ *p2++ = s >> 7;
+ s = (k_cn* (*p0++))+(k_dn * (*p1++));
+ *p2++ = s >> 7;
+ s = (k_cn* (*p0++))+(k_dn * (*p1++));
+ *p2++ = s >> 7;
+ s = (k_cn* (*p0++))+(k_dn * (*p1++));
+ *p2++ = s >> 7;
+ }
+
+ /* set sign according to dn2[] = k_cn*cn[] + k_dn*dn[] */
+ for (i = 0; i < L_SUBFR; i ++)
+ {
+ val = dn[i];
+ ps = dn2[i];
+ if (ps >= 0)
+ {
+ sign[i] = 32767; /* sign = +1 (Q12) */
+ vec[i] = -32768;
+ } else
+ {
+ sign[i] = -32768; /* sign = -1 (Q12) */
+ vec[i] = 32767;
+ dn[i] = -val;
+ }
+ }
+ /*------------------------------------------------------------*
+ * Compute h_inv[i]. *
+ *------------------------------------------------------------*/
+ /* impulse response buffer for fast computation */
+ h = h_buf + L_SUBFR;
+ h_inv = h + (L_SUBFR<<1);
+
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ h[i] = H[i];
+ h_inv[i] = vo_negate(h[i]);
+ }
+
+ /*------------------------------------------------------------*
+ * Compute rrixix[][] needed for the codebook search. *
+ * Result is multiplied by 0.5 *
+ *------------------------------------------------------------*/
+ /* Init pointers to last position of rrixix[] */
+ p0 = &rrixix[0][NB_POS - 1];
+ p1 = &rrixix[1][NB_POS - 1];
+
+ ptr_h1 = h;
+ cor = 0x00010000L; /* for rounding */
+ for (i = 0; i < NB_POS; i++)
+ {
+ cor += ((*ptr_h1) * (*ptr_h1) << 1);
+ ptr_h1++;
+ *p1-- = (extract_h(cor) >> 1);
+ cor += ((*ptr_h1) * (*ptr_h1) << 1);
+ ptr_h1++;
+ *p0-- = (extract_h(cor) >> 1);
+ }
+
+ /*------------------------------------------------------------*
+ * Compute rrixiy[][] needed for the codebook search. *
+ *------------------------------------------------------------*/
+ pos = MSIZE - 1;
+ pos2 = MSIZE - 2;
+ ptr_hf = h + 1;
+
+ for (k = 0; k < NB_POS; k++)
+ {
+ p1 = &rrixiy[pos];
+ p0 = &rrixiy[pos2];
+ cor = 0x00008000L; /* for rounding */
+ ptr_h1 = h;
+ ptr_h2 = ptr_hf;
+
+ for (i = (k + 1); i < NB_POS; i++)
+ {
+ cor += ((*ptr_h1) * (*ptr_h2))<<1;
+ ptr_h1++;
+ ptr_h2++;
+ *p1 = extract_h(cor);
+ cor += ((*ptr_h1) * (*ptr_h2))<<1;
+ ptr_h1++;
+ ptr_h2++;
+ *p0 = extract_h(cor);
+
+ p1 -= (NB_POS + 1);
+ p0 -= (NB_POS + 1);
+ }
+ cor += ((*ptr_h1) * (*ptr_h2))<<1;
+ ptr_h1++;
+ ptr_h2++;
+ *p1 = extract_h(cor);
+
+ pos -= NB_POS;
+ pos2--;
+ ptr_hf += STEP;
+ }
+
+ /*------------------------------------------------------------*
+ * Modification of rrixiy[][] to take signs into account. *
+ *------------------------------------------------------------*/
+ p0 = rrixiy;
+ for (i = 0; i < L_SUBFR; i += STEP)
+ {
+ psign = sign;
+ if (psign[i] < 0)
+ {
+ psign = vec;
+ }
+ for (j = 1; j < L_SUBFR; j += STEP)
+ {
+ *p0 = vo_mult(*p0, psign[j]);
+ p0++;
+ }
+ }
+ /*-------------------------------------------------------------------*
+ * search 2 pulses: *
+ * ~@~~~~~~~~~~~~~~ *
+ * 32 pos x 32 pos = 1024 tests (all combinaisons is tested) *
+ *-------------------------------------------------------------------*/
+ p0 = rrixix[0];
+ p1 = rrixix[1];
+ p2 = rrixiy;
+
+ psk = -1;
+ alpk = 1;
+ ix = 0;
+ iy = 1;
+
+ for (i0 = 0; i0 < L_SUBFR; i0 += STEP)
+ {
+ ps1 = dn[i0];
+ alp1 = (*p0++);
+ pos = -1;
+ for (i1 = 1; i1 < L_SUBFR; i1 += STEP)
+ {
+ ps2 = add1(ps1, dn[i1]);
+ alp2 = add1(alp1, add1(*p1++, *p2++));
+ sq = vo_mult(ps2, ps2);
+ s = vo_L_mult(alpk, sq) - ((psk * alp2)<<1);
+ if (s > 0)
+ {
+ psk = sq;
+ alpk = alp2;
+ pos = i1;
+ }
+ }
+ p1 -= NB_POS;
+ if (pos >= 0)
+ {
+ ix = i0;
+ iy = pos;
+ }
+ }
+ /*-------------------------------------------------------------------*
+ * Build the codeword, the filtered codeword and index of codevector.*
+ *-------------------------------------------------------------------*/
+
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ code[i] = 0;
+ }
+
+ i0 = (ix >> 1); /* pos of pulse 1 (0..31) */
+ i1 = (iy >> 1); /* pos of pulse 2 (0..31) */
+ if (sign[ix] > 0)
+ {
+ code[ix] = 512; /* codeword in Q9 format */
+ p0 = h - ix;
+ } else
+ {
+ code[ix] = -512;
+ i0 += NB_POS;
+ p0 = h_inv - ix;
+ }
+ if (sign[iy] > 0)
+ {
+ code[iy] = 512;
+ p1 = h - iy;
+ } else
+ {
+ code[iy] = -512;
+ i1 += NB_POS;
+ p1 = h_inv - iy;
+ }
+ *index = add1((i0 << 6), i1);
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ y[i] = vo_shr_r(add1((*p0++), (*p1++)), 3);
+ }
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
new file mode 100644
index 0000000..27ba95d
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
@@ -0,0 +1,1043 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: c4t64fx.c *
+* *
+* Description:Performs algebraic codebook search for higher modes *
+* *
+************************************************************************/
+
+/************************************************************************
+* Function: ACELP_4t64_fx() *
+* *
+* 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook. *
+* 4 tracks x 16 positions per track = 64 samples. *
+* *
+* 20 bits --> 4 pulses in a frame of 64 samples. *
+* 36 bits --> 8 pulses in a frame of 64 samples. *
+* 44 bits --> 10 pulses in a frame of 64 samples. *
+* 52 bits --> 12 pulses in a frame of 64 samples. *
+* 64 bits --> 16 pulses in a frame of 64 samples. *
+* 72 bits --> 18 pulses in a frame of 64 samples. *
+* 88 bits --> 24 pulses in a frame of 64 samples. *
+* *
+* All pulses can have two (2) possible amplitudes: +1 or -1. *
+* Each pulse can have sixteen (16) possible positions. *
+*************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "acelp.h"
+#include "cnst.h"
+
+#include "q_pulse.h"
+
+static Word16 tipos[36] = {
+ 0, 1, 2, 3, /* starting point &ipos[0], 1st iter */
+ 1, 2, 3, 0, /* starting point &ipos[4], 2nd iter */
+ 2, 3, 0, 1, /* starting point &ipos[8], 3rd iter */
+ 3, 0, 1, 2, /* starting point &ipos[12], 4th iter */
+ 0, 1, 2, 3,
+ 1, 2, 3, 0,
+ 2, 3, 0, 1,
+ 3, 0, 1, 2,
+ 0, 1, 2, 3}; /* end point for 24 pulses &ipos[35], 4th iter */
+
+#define NB_PULSE_MAX 24
+
+#define L_SUBFR 64
+#define NB_TRACK 4
+#define STEP 4
+#define NB_POS 16
+#define MSIZE 256
+#define NB_MAX 8
+#define NPMAXPT ((NB_PULSE_MAX+NB_TRACK-1)/NB_TRACK)
+
+/* Private functions */
+void cor_h_vec_012(
+ Word16 h[], /* (i) scaled impulse response */
+ Word16 vec[], /* (i) scaled vector (/8) to correlate with h[] */
+ Word16 track, /* (i) track to use */
+ Word16 sign[], /* (i) sign vector */
+ Word16 rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */
+ Word16 cor_1[], /* (o) result of correlation (NB_POS elements) */
+ Word16 cor_2[] /* (o) result of correlation (NB_POS elements) */
+ );
+
+void cor_h_vec_012_asm(
+ Word16 h[], /* (i) scaled impulse response */
+ Word16 vec[], /* (i) scaled vector (/8) to correlate with h[] */
+ Word16 track, /* (i) track to use */
+ Word16 sign[], /* (i) sign vector */
+ Word16 rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */
+ Word16 cor_1[], /* (o) result of correlation (NB_POS elements) */
+ Word16 cor_2[] /* (o) result of correlation (NB_POS elements) */
+ );
+
+void cor_h_vec_30(
+ Word16 h[], /* (i) scaled impulse response */
+ Word16 vec[], /* (i) scaled vector (/8) to correlate with h[] */
+ Word16 track, /* (i) track to use */
+ Word16 sign[], /* (i) sign vector */
+ Word16 rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */
+ Word16 cor_1[], /* (o) result of correlation (NB_POS elements) */
+ Word16 cor_2[] /* (o) result of correlation (NB_POS elements) */
+ );
+
+void search_ixiy(
+ Word16 nb_pos_ix, /* (i) nb of pos for pulse 1 (1..8) */
+ Word16 track_x, /* (i) track of pulse 1 */
+ Word16 track_y, /* (i) track of pulse 2 */
+ Word16 * ps, /* (i/o) correlation of all fixed pulses */
+ Word16 * alp, /* (i/o) energy of all fixed pulses */
+ Word16 * ix, /* (o) position of pulse 1 */
+ Word16 * iy, /* (o) position of pulse 2 */
+ Word16 dn[], /* (i) corr. between target and h[] */
+ Word16 dn2[], /* (i) vector of selected positions */
+ Word16 cor_x[], /* (i) corr. of pulse 1 with fixed pulses */
+ Word16 cor_y[], /* (i) corr. of pulse 2 with fixed pulses */
+ Word16 rrixiy[][MSIZE] /* (i) corr. of pulse 1 with pulse 2 */
+ );
+
+
+void ACELP_4t64_fx(
+ Word16 dn[], /* (i) <12b : correlation between target x[] and H[] */
+ Word16 cn[], /* (i) <12b : residual after long term prediction */
+ Word16 H[], /* (i) Q12: impulse response of weighted synthesis filter */
+ Word16 code[], /* (o) Q9 : algebraic (fixed) codebook excitation */
+ Word16 y[], /* (o) Q9 : filtered fixed codebook excitation */
+ Word16 nbbits, /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits */
+ Word16 ser_size, /* (i) : bit rate */
+ Word16 _index[] /* (o) : index (20): 5+5+5+5 = 20 bits. */
+ /* (o) : index (36): 9+9+9+9 = 36 bits. */
+ /* (o) : index (44): 13+9+13+9 = 44 bits. */
+ /* (o) : index (52): 13+13+13+13 = 52 bits. */
+ /* (o) : index (64): 2+2+2+2+14+14+14+14 = 64 bits. */
+ /* (o) : index (72): 10+2+10+2+10+14+10+14 = 72 bits. */
+ /* (o) : index (88): 11+11+11+11+11+11+11+11 = 88 bits. */
+ )
+{
+ Word32 i, j, k;
+ Word16 st, ix, iy, pos, index, track, nb_pulse, nbiter, j_temp;
+ Word16 psk, ps, alpk, alp, val, k_cn, k_dn, exp;
+ Word16 *p0, *p1, *p2, *p3, *psign;
+ Word16 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf, h_shift;
+ Word32 s, cor, L_tmp, L_index;
+ Word16 dn2[L_SUBFR], sign[L_SUBFR], vec[L_SUBFR];
+ Word16 ind[NPMAXPT * NB_TRACK];
+ Word16 codvec[NB_PULSE_MAX], nbpos[10];
+ Word16 cor_x[NB_POS], cor_y[NB_POS], pos_max[NB_TRACK];
+ Word16 h_buf[4 * L_SUBFR];
+ Word16 rrixix[NB_TRACK][NB_POS], rrixiy[NB_TRACK][MSIZE];
+ Word16 ipos[NB_PULSE_MAX];
+
+ switch (nbbits)
+ {
+ case 20: /* 20 bits, 4 pulses, 4 tracks */
+ nbiter = 4; /* 4x16x16=1024 loop */
+ alp = 8192; /* alp = 2.0 (Q12) */
+ nb_pulse = 4;
+ nbpos[0] = 4;
+ nbpos[1] = 8;
+ break;
+ case 36: /* 36 bits, 8 pulses, 4 tracks */
+ nbiter = 4; /* 4x20x16=1280 loop */
+ alp = 4096; /* alp = 1.0 (Q12) */
+ nb_pulse = 8;
+ nbpos[0] = 4;
+ nbpos[1] = 8;
+ nbpos[2] = 8;
+ break;
+ case 44: /* 44 bits, 10 pulses, 4 tracks */
+ nbiter = 4; /* 4x26x16=1664 loop */
+ alp = 4096; /* alp = 1.0 (Q12) */
+ nb_pulse = 10;
+ nbpos[0] = 4;
+ nbpos[1] = 6;
+ nbpos[2] = 8;
+ nbpos[3] = 8;
+ break;
+ case 52: /* 52 bits, 12 pulses, 4 tracks */
+ nbiter = 4; /* 4x26x16=1664 loop */
+ alp = 4096; /* alp = 1.0 (Q12) */
+ nb_pulse = 12;
+ nbpos[0] = 4;
+ nbpos[1] = 6;
+ nbpos[2] = 8;
+ nbpos[3] = 8;
+ break;
+ case 64: /* 64 bits, 16 pulses, 4 tracks */
+ nbiter = 3; /* 3x36x16=1728 loop */
+ alp = 3277; /* alp = 0.8 (Q12) */
+ nb_pulse = 16;
+ nbpos[0] = 4;
+ nbpos[1] = 4;
+ nbpos[2] = 6;
+ nbpos[3] = 6;
+ nbpos[4] = 8;
+ nbpos[5] = 8;
+ break;
+ case 72: /* 72 bits, 18 pulses, 4 tracks */
+ nbiter = 3; /* 3x35x16=1680 loop */
+ alp = 3072; /* alp = 0.75 (Q12) */
+ nb_pulse = 18;
+ nbpos[0] = 2;
+ nbpos[1] = 3;
+ nbpos[2] = 4;
+ nbpos[3] = 5;
+ nbpos[4] = 6;
+ nbpos[5] = 7;
+ nbpos[6] = 8;
+ break;
+ case 88: /* 88 bits, 24 pulses, 4 tracks */
+ if(ser_size > 462)
+ nbiter = 1;
+ else
+ nbiter = 2; /* 2x53x16=1696 loop */
+
+ alp = 2048; /* alp = 0.5 (Q12) */
+ nb_pulse = 24;
+ nbpos[0] = 2;
+ nbpos[1] = 2;
+ nbpos[2] = 3;
+ nbpos[3] = 4;
+ nbpos[4] = 5;
+ nbpos[5] = 6;
+ nbpos[6] = 7;
+ nbpos[7] = 8;
+ nbpos[8] = 8;
+ nbpos[9] = 8;
+ break;
+ default:
+ nbiter = 0;
+ alp = 0;
+ nb_pulse = 0;
+ }
+
+ for (i = 0; i < nb_pulse; i++)
+ {
+ codvec[i] = i;
+ }
+
+ /*----------------------------------------------------------------*
+ * Find sign for each pulse position. *
+ *----------------------------------------------------------------*/
+ /* calculate energy for normalization of cn[] and dn[] */
+ /* set k_cn = 32..32767 (ener_cn = 2^30..256-0) */
+#ifdef ASM_OPT /* asm optimization branch */
+ s = Dot_product12_asm(cn, cn, L_SUBFR, &exp);
+#else
+ s = Dot_product12(cn, cn, L_SUBFR, &exp);
+#endif
+
+ Isqrt_n(&s, &exp);
+ s = L_shl(s, (exp + 5));
+ k_cn = extract_h(L_add(s, 0x8000));
+
+ /* set k_dn = 32..512 (ener_dn = 2^30..2^22) */
+#ifdef ASM_OPT /* asm optimization branch */
+ s = Dot_product12_asm(dn, dn, L_SUBFR, &exp);
+#else
+ s = Dot_product12(dn, dn, L_SUBFR, &exp);
+#endif
+
+ Isqrt_n(&s, &exp);
+ k_dn = (L_shl(s, (exp + 5 + 3)) + 0x8000) >> 16; /* k_dn = 256..4096 */
+ k_dn = vo_mult_r(alp, k_dn); /* alp in Q12 */
+
+ /* mix normalized cn[] and dn[] */
+ p0 = cn;
+ p1 = dn;
+ p2 = dn2;
+
+ for (i = 0; i < L_SUBFR/4; i++)
+ {
+ s = (k_cn* (*p0++))+(k_dn * (*p1++));
+ *p2++ = s >> 7;
+ s = (k_cn* (*p0++))+(k_dn * (*p1++));
+ *p2++ = s >> 7;
+ s = (k_cn* (*p0++))+(k_dn * (*p1++));
+ *p2++ = s >> 7;
+ s = (k_cn* (*p0++))+(k_dn * (*p1++));
+ *p2++ = s >> 7;
+ }
+
+ /* set sign according to dn2[] = k_cn*cn[] + k_dn*dn[] */
+ for(i = 0; i < L_SUBFR; i++)
+ {
+ val = dn[i];
+ ps = dn2[i];
+ if (ps >= 0)
+ {
+ sign[i] = 32767; /* sign = +1 (Q12) */
+ vec[i] = -32768;
+ } else
+ {
+ sign[i] = -32768; /* sign = -1 (Q12) */
+ vec[i] = 32767;
+ dn[i] = -val;
+ dn2[i] = -ps;
+ }
+ }
+ /*----------------------------------------------------------------*
+ * Select NB_MAX position per track according to max of dn2[]. *
+ *----------------------------------------------------------------*/
+ pos = 0;
+ for (i = 0; i < NB_TRACK; i++)
+ {
+ for (k = 0; k < NB_MAX; k++)
+ {
+ ps = -1;
+ for (j = i; j < L_SUBFR; j += STEP)
+ {
+ if(dn2[j] > ps)
+ {
+ ps = dn2[j];
+ pos = j;
+ }
+ }
+ dn2[pos] = (k - NB_MAX); /* dn2 < 0 when position is selected */
+ if (k == 0)
+ {
+ pos_max[i] = pos;
+ }
+ }
+ }
+
+ /*--------------------------------------------------------------*
+ * Scale h[] to avoid overflow and to get maximum of precision *
+ * on correlation. *
+ * *
+ * Maximum of h[] (h[0]) is fixed to 2048 (MAX16 / 16). *
+ * ==> This allow addition of 16 pulses without saturation. *
+ * *
+ * Energy worst case (on resonant impulse response), *
+ * - energy of h[] is approximately MAX/16. *
+ * - During search, the energy is divided by 8 to avoid *
+ * overflow on "alp". (energy of h[] = MAX/128). *
+ * ==> "alp" worst case detected is 22854 on sinusoidal wave. *
+ *--------------------------------------------------------------*/
+
+ /* impulse response buffer for fast computation */
+
+ h = h_buf;
+ h_inv = h_buf + (2 * L_SUBFR);
+ L_tmp = 0;
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ *h++ = 0;
+ *h_inv++ = 0;
+ L_tmp += (H[i] * H[i]) << 1;
+ }
+ /* scale h[] down (/2) when energy of h[] is high with many pulses used */
+ val = extract_h(L_tmp);
+ h_shift = 0;
+
+ if ((nb_pulse >= 12) && (val > 1024))
+ {
+ h_shift = 1;
+ }
+ p0 = H;
+ p1 = h;
+ p2 = h_inv;
+
+ for (i = 0; i < L_SUBFR/4; i++)
+ {
+ *p1 = *p0++ >> h_shift;
+ *p2++ = -(*p1++);
+ *p1 = *p0++ >> h_shift;
+ *p2++ = -(*p1++);
+ *p1 = *p0++ >> h_shift;
+ *p2++ = -(*p1++);
+ *p1 = *p0++ >> h_shift;
+ *p2++ = -(*p1++);
+ }
+
+ /*------------------------------------------------------------*
+ * Compute rrixix[][] needed for the codebook search. *
+ * This algorithm compute impulse response energy of all *
+ * positions (16) in each track (4). Total = 4x16 = 64. *
+ *------------------------------------------------------------*/
+
+ /* storage order --> i3i3, i2i2, i1i1, i0i0 */
+
+ /* Init pointers to last position of rrixix[] */
+ p0 = &rrixix[0][NB_POS - 1];
+ p1 = &rrixix[1][NB_POS - 1];
+ p2 = &rrixix[2][NB_POS - 1];
+ p3 = &rrixix[3][NB_POS - 1];
+
+ ptr_h1 = h;
+ cor = 0x00008000L; /* for rounding */
+ for (i = 0; i < NB_POS; i++)
+ {
+ cor += vo_L_mult((*ptr_h1), (*ptr_h1));
+ ptr_h1++;
+ *p3-- = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h1));
+ ptr_h1++;
+ *p2-- = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h1));
+ ptr_h1++;
+ *p1-- = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h1));
+ ptr_h1++;
+ *p0-- = extract_h(cor);
+ }
+
+ /*------------------------------------------------------------*
+ * Compute rrixiy[][] needed for the codebook search. *
+ * This algorithm compute correlation between 2 pulses *
+ * (2 impulses responses) in 4 possible adjacents tracks. *
+ * (track 0-1, 1-2, 2-3 and 3-0). Total = 4x16x16 = 1024. *
+ *------------------------------------------------------------*/
+
+ /* storage order --> i2i3, i1i2, i0i1, i3i0 */
+
+ pos = MSIZE - 1;
+ ptr_hf = h + 1;
+
+ for (k = 0; k < NB_POS; k++)
+ {
+ p3 = &rrixiy[2][pos];
+ p2 = &rrixiy[1][pos];
+ p1 = &rrixiy[0][pos];
+ p0 = &rrixiy[3][pos - NB_POS];
+
+ cor = 0x00008000L; /* for rounding */
+ ptr_h1 = h;
+ ptr_h2 = ptr_hf;
+
+ for (i = k + 1; i < NB_POS; i++)
+ {
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p3 = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p2 = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p1 = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p0 = extract_h(cor);
+
+ p3 -= (NB_POS + 1);
+ p2 -= (NB_POS + 1);
+ p1 -= (NB_POS + 1);
+ p0 -= (NB_POS + 1);
+ }
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p3 = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p2 = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p1 = extract_h(cor);
+
+ pos -= NB_POS;
+ ptr_hf += STEP;
+ }
+
+ /* storage order --> i3i0, i2i3, i1i2, i0i1 */
+
+ pos = MSIZE - 1;
+ ptr_hf = h + 3;
+
+ for (k = 0; k < NB_POS; k++)
+ {
+ p3 = &rrixiy[3][pos];
+ p2 = &rrixiy[2][pos - 1];
+ p1 = &rrixiy[1][pos - 1];
+ p0 = &rrixiy[0][pos - 1];
+
+ cor = 0x00008000L; /* for rounding */
+ ptr_h1 = h;
+ ptr_h2 = ptr_hf;
+
+ for (i = k + 1; i < NB_POS; i++)
+ {
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p3 = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p2 = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p1 = extract_h(cor);
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p0 = extract_h(cor);
+
+ p3 -= (NB_POS + 1);
+ p2 -= (NB_POS + 1);
+ p1 -= (NB_POS + 1);
+ p0 -= (NB_POS + 1);
+ }
+ cor += vo_L_mult((*ptr_h1), (*ptr_h2));
+ ptr_h1++;
+ ptr_h2++;
+ *p3 = extract_h(cor);
+
+ pos--;
+ ptr_hf += STEP;
+ }
+
+ /*------------------------------------------------------------*
+ * Modification of rrixiy[][] to take signs into account. *
+ *------------------------------------------------------------*/
+
+ p0 = &rrixiy[0][0];
+
+ for (k = 0; k < NB_TRACK; k++)
+ {
+ j_temp = (k + 1)&0x03;
+ for (i = k; i < L_SUBFR; i += STEP)
+ {
+ psign = sign;
+ if (psign[i] < 0)
+ {
+ psign = vec;
+ }
+ j = j_temp;
+ for (; j < L_SUBFR; j += STEP)
+ {
+ *p0 = vo_mult(*p0, psign[j]);
+ p0++;
+ }
+ }
+ }
+
+ /*-------------------------------------------------------------------*
+ * Deep first search *
+ *-------------------------------------------------------------------*/
+
+ psk = -1;
+ alpk = 1;
+
+ for (k = 0; k < nbiter; k++)
+ {
+ j_temp = k<<2;
+ for (i = 0; i < nb_pulse; i++)
+ ipos[i] = tipos[j_temp + i];
+
+ if(nbbits == 20)
+ {
+ pos = 0;
+ ps = 0;
+ alp = 0;
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ vec[i] = 0;
+ }
+ } else if ((nbbits == 36) || (nbbits == 44))
+ {
+ /* first stage: fix 2 pulses */
+ pos = 2;
+
+ ix = ind[0] = pos_max[ipos[0]];
+ iy = ind[1] = pos_max[ipos[1]];
+ ps = dn[ix] + dn[iy];
+ i = ix >> 2; /* ix / STEP */
+ j = iy >> 2; /* iy / STEP */
+ s = rrixix[ipos[0]][i] << 13;
+ s += rrixix[ipos[1]][j] << 13;
+ i = (i << 4) + j; /* (ix/STEP)*NB_POS + (iy/STEP) */
+ s += rrixiy[ipos[0]][i] << 14;
+ alp = (s + 0x8000) >> 16;
+ if (sign[ix] < 0)
+ p0 = h_inv - ix;
+ else
+ p0 = h - ix;
+ if (sign[iy] < 0)
+ p1 = h_inv - iy;
+ else
+ p1 = h - iy;
+
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ vec[i] = (*p0++) + (*p1++);
+ }
+
+ if(nbbits == 44)
+ {
+ ipos[8] = 0;
+ ipos[9] = 1;
+ }
+ } else
+ {
+ /* first stage: fix 4 pulses */
+ pos = 4;
+
+ ix = ind[0] = pos_max[ipos[0]];
+ iy = ind[1] = pos_max[ipos[1]];
+ i = ind[2] = pos_max[ipos[2]];
+ j = ind[3] = pos_max[ipos[3]];
+ ps = add1(add1(add1(dn[ix], dn[iy]), dn[i]), dn[j]);
+
+ if (sign[ix] < 0)
+ p0 = h_inv - ix;
+ else
+ p0 = h - ix;
+
+ if (sign[iy] < 0)
+ p1 = h_inv - iy;
+ else
+ p1 = h - iy;
+
+ if (sign[i] < 0)
+ p2 = h_inv - i;
+ else
+ p2 = h - i;
+
+ if (sign[j] < 0)
+ p3 = h_inv - j;
+ else
+ p3 = h - j;
+
+ L_tmp = 0L;
+ for(i = 0; i < L_SUBFR; i++)
+ {
+ vec[i] = add1(add1(add1(*p0++, *p1++), *p2++), *p3++);
+ L_tmp += (vec[i] * vec[i]) << 1;
+ }
+
+ alp = ((L_tmp >> 3) + 0x8000) >> 16;
+
+ if(nbbits == 72)
+ {
+ ipos[16] = 0;
+ ipos[17] = 1;
+ }
+ }
+
+ /* other stages of 2 pulses */
+
+ for (j = pos, st = 0; j < nb_pulse; j += 2, st++)
+ {
+ /*--------------------------------------------------*
+ * Calculate correlation of all possible positions *
+ * of the next 2 pulses with previous fixed pulses. *
+ * Each pulse can have 16 possible positions. *
+ *--------------------------------------------------*/
+ if(ipos[j] == 3)
+ {
+ cor_h_vec_30(h, vec, ipos[j], sign, rrixix, cor_x, cor_y);
+ }
+ else
+ {
+#ifdef ASM_OPT /* asm optimization branch */
+ cor_h_vec_012_asm(h, vec, ipos[j], sign, rrixix, cor_x, cor_y);
+#else
+ cor_h_vec_012(h, vec, ipos[j], sign, rrixix, cor_x, cor_y);
+#endif
+ }
+ /*--------------------------------------------------*
+ * Find best positions of 2 pulses. *
+ *--------------------------------------------------*/
+ search_ixiy(nbpos[st], ipos[j], ipos[j + 1], &ps, &alp,
+ &ix, &iy, dn, dn2, cor_x, cor_y, rrixiy);
+
+ ind[j] = ix;
+ ind[j + 1] = iy;
+
+ if (sign[ix] < 0)
+ p0 = h_inv - ix;
+ else
+ p0 = h - ix;
+ if (sign[iy] < 0)
+ p1 = h_inv - iy;
+ else
+ p1 = h - iy;
+
+ for (i = 0; i < L_SUBFR; i+=4)
+ {
+ vec[i] += add1((*p0++), (*p1++));
+ vec[i+1] += add1((*p0++), (*p1++));
+ vec[i+2] += add1((*p0++), (*p1++));
+ vec[i+3] += add1((*p0++), (*p1++));
+ }
+ }
+ /* memorise the best codevector */
+ ps = vo_mult(ps, ps);
+ s = vo_L_msu(vo_L_mult(alpk, ps), psk, alp);
+ if (s > 0)
+ {
+ psk = ps;
+ alpk = alp;
+ for (i = 0; i < nb_pulse; i++)
+ {
+ codvec[i] = ind[i];
+ }
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ y[i] = vec[i];
+ }
+ }
+ }
+ /*-------------------------------------------------------------------*
+ * Build the codeword, the filtered codeword and index of codevector.*
+ *-------------------------------------------------------------------*/
+ for (i = 0; i < NPMAXPT * NB_TRACK; i++)
+ {
+ ind[i] = -1;
+ }
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ code[i] = 0;
+ y[i] = vo_shr_r(y[i], 3); /* Q12 to Q9 */
+ }
+ val = (512 >> h_shift); /* codeword in Q9 format */
+ for (k = 0; k < nb_pulse; k++)
+ {
+ i = codvec[k]; /* read pulse position */
+ j = sign[i]; /* read sign */
+ index = i >> 2; /* index = pos of pulse (0..15) */
+ track = (Word16) (i & 0x03); /* track = i % NB_TRACK (0..3) */
+
+ if (j > 0)
+ {
+ code[i] += val;
+ codvec[k] += 128;
+ } else
+ {
+ code[i] -= val;
+ index += NB_POS;
+ }
+
+ i = (Word16)((vo_L_mult(track, NPMAXPT) >> 1));
+
+ while (ind[i] >= 0)
+ {
+ i += 1;
+ }
+ ind[i] = index;
+ }
+
+ k = 0;
+ /* Build index of codevector */
+ if(nbbits == 20)
+ {
+ for (track = 0; track < NB_TRACK; track++)
+ {
+ _index[track] = (Word16)(quant_1p_N1(ind[k], 4));
+ k += NPMAXPT;
+ }
+ } else if(nbbits == 36)
+ {
+ for (track = 0; track < NB_TRACK; track++)
+ {
+ _index[track] = (Word16)(quant_2p_2N1(ind[k], ind[k + 1], 4));
+ k += NPMAXPT;
+ }
+ } else if(nbbits == 44)
+ {
+ for (track = 0; track < NB_TRACK - 2; track++)
+ {
+ _index[track] = (Word16)(quant_3p_3N1(ind[k], ind[k + 1], ind[k + 2], 4));
+ k += NPMAXPT;
+ }
+ for (track = 2; track < NB_TRACK; track++)
+ {
+ _index[track] = (Word16)(quant_2p_2N1(ind[k], ind[k + 1], 4));
+ k += NPMAXPT;
+ }
+ } else if(nbbits == 52)
+ {
+ for (track = 0; track < NB_TRACK; track++)
+ {
+ _index[track] = (Word16)(quant_3p_3N1(ind[k], ind[k + 1], ind[k + 2], 4));
+ k += NPMAXPT;
+ }
+ } else if(nbbits == 64)
+ {
+ for (track = 0; track < NB_TRACK; track++)
+ {
+ L_index = quant_4p_4N(&ind[k], 4);
+ _index[track] = (Word16)((L_index >> 14) & 3);
+ _index[track + NB_TRACK] = (Word16)(L_index & 0x3FFF);
+ k += NPMAXPT;
+ }
+ } else if(nbbits == 72)
+ {
+ for (track = 0; track < NB_TRACK - 2; track++)
+ {
+ L_index = quant_5p_5N(&ind[k], 4);
+ _index[track] = (Word16)((L_index >> 10) & 0x03FF);
+ _index[track + NB_TRACK] = (Word16)(L_index & 0x03FF);
+ k += NPMAXPT;
+ }
+ for (track = 2; track < NB_TRACK; track++)
+ {
+ L_index = quant_4p_4N(&ind[k], 4);
+ _index[track] = (Word16)((L_index >> 14) & 3);
+ _index[track + NB_TRACK] = (Word16)(L_index & 0x3FFF);
+ k += NPMAXPT;
+ }
+ } else if(nbbits == 88)
+ {
+ for (track = 0; track < NB_TRACK; track++)
+ {
+ L_index = quant_6p_6N_2(&ind[k], 4);
+ _index[track] = (Word16)((L_index >> 11) & 0x07FF);
+ _index[track + NB_TRACK] = (Word16)(L_index & 0x07FF);
+ k += NPMAXPT;
+ }
+ }
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function cor_h_vec() *
+ * ~~~~~~~~~~~~~~~~~~~~~ *
+ * Compute correlations of h[] with vec[] for the specified track. *
+ *-------------------------------------------------------------------*/
+void cor_h_vec_30(
+ Word16 h[], /* (i) scaled impulse response */
+ Word16 vec[], /* (i) scaled vector (/8) to correlate with h[] */
+ Word16 track, /* (i) track to use */
+ Word16 sign[], /* (i) sign vector */
+ Word16 rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */
+ Word16 cor_1[], /* (o) result of correlation (NB_POS elements) */
+ Word16 cor_2[] /* (o) result of correlation (NB_POS elements) */
+ )
+{
+ Word32 i, j, pos, corr;
+ Word16 *p0, *p1, *p2,*p3,*cor_x,*cor_y;
+ Word32 L_sum1,L_sum2;
+ cor_x = cor_1;
+ cor_y = cor_2;
+ p0 = rrixix[track];
+ p3 = rrixix[0];
+ pos = track;
+
+ for (i = 0; i < NB_POS; i+=2)
+ {
+ L_sum1 = L_sum2 = 0L;
+ p1 = h;
+ p2 = &vec[pos];
+ for (j=pos;j < L_SUBFR; j++)
+ {
+ L_sum1 += *p1 * *p2;
+ p2-=3;
+ L_sum2 += *p1++ * *p2;
+ p2+=4;
+ }
+ p2-=3;
+ L_sum2 += *p1++ * *p2++;
+ L_sum2 += *p1++ * *p2++;
+ L_sum2 += *p1++ * *p2++;
+
+ L_sum1 = (L_sum1 << 2);
+ L_sum2 = (L_sum2 << 2);
+
+ corr = vo_round(L_sum1);
+ *cor_x++ = vo_mult(corr, sign[pos]) + (*p0++);
+ corr = vo_round(L_sum2);
+ *cor_y++ = vo_mult(corr, sign[pos-3]) + (*p3++);
+ pos += STEP;
+
+ L_sum1 = L_sum2 = 0L;
+ p1 = h;
+ p2 = &vec[pos];
+ for (j=pos;j < L_SUBFR; j++)
+ {
+ L_sum1 += *p1 * *p2;
+ p2-=3;
+ L_sum2 += *p1++ * *p2;
+ p2+=4;
+ }
+ p2-=3;
+ L_sum2 += *p1++ * *p2++;
+ L_sum2 += *p1++ * *p2++;
+ L_sum2 += *p1++ * *p2++;
+
+ L_sum1 = (L_sum1 << 2);
+ L_sum2 = (L_sum2 << 2);
+
+ corr = vo_round(L_sum1);
+ *cor_x++ = vo_mult(corr, sign[pos]) + (*p0++);
+ corr = vo_round(L_sum2);
+ *cor_y++ = vo_mult(corr, sign[pos-3]) + (*p3++);
+ pos += STEP;
+ }
+ return;
+}
+
+void cor_h_vec_012(
+ Word16 h[], /* (i) scaled impulse response */
+ Word16 vec[], /* (i) scaled vector (/8) to correlate with h[] */
+ Word16 track, /* (i) track to use */
+ Word16 sign[], /* (i) sign vector */
+ Word16 rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */
+ Word16 cor_1[], /* (o) result of correlation (NB_POS elements) */
+ Word16 cor_2[] /* (o) result of correlation (NB_POS elements) */
+ )
+{
+ Word32 i, j, pos, corr;
+ Word16 *p0, *p1, *p2,*p3,*cor_x,*cor_y;
+ Word32 L_sum1,L_sum2;
+ cor_x = cor_1;
+ cor_y = cor_2;
+ p0 = rrixix[track];
+ p3 = rrixix[track+1];
+ pos = track;
+
+ for (i = 0; i < NB_POS; i+=2)
+ {
+ L_sum1 = L_sum2 = 0L;
+ p1 = h;
+ p2 = &vec[pos];
+ for (j=62-pos ;j >= 0; j--)
+ {
+ L_sum1 += *p1 * *p2++;
+ L_sum2 += *p1++ * *p2;
+ }
+ L_sum1 += *p1 * *p2;
+ L_sum1 = (L_sum1 << 2);
+ L_sum2 = (L_sum2 << 2);
+
+ corr = (L_sum1 + 0x8000) >> 16;
+ cor_x[i] = vo_mult(corr, sign[pos]) + (*p0++);
+ corr = (L_sum2 + 0x8000) >> 16;
+ cor_y[i] = vo_mult(corr, sign[pos + 1]) + (*p3++);
+ pos += STEP;
+
+ L_sum1 = L_sum2 = 0L;
+ p1 = h;
+ p2 = &vec[pos];
+ for (j= 62-pos;j >= 0; j--)
+ {
+ L_sum1 += *p1 * *p2++;
+ L_sum2 += *p1++ * *p2;
+ }
+ L_sum1 += *p1 * *p2;
+ L_sum1 = (L_sum1 << 2);
+ L_sum2 = (L_sum2 << 2);
+
+ corr = (L_sum1 + 0x8000) >> 16;
+ cor_x[i+1] = vo_mult(corr, sign[pos]) + (*p0++);
+ corr = (L_sum2 + 0x8000) >> 16;
+ cor_y[i+1] = vo_mult(corr, sign[pos + 1]) + (*p3++);
+ pos += STEP;
+ }
+ return;
+}
+
+/*-------------------------------------------------------------------*
+ * Function search_ixiy() *
+ * ~~~~~~~~~~~~~~~~~~~~~~~ *
+ * Find the best positions of 2 pulses in a subframe. *
+ *-------------------------------------------------------------------*/
+
+void search_ixiy(
+ Word16 nb_pos_ix, /* (i) nb of pos for pulse 1 (1..8) */
+ Word16 track_x, /* (i) track of pulse 1 */
+ Word16 track_y, /* (i) track of pulse 2 */
+ Word16 * ps, /* (i/o) correlation of all fixed pulses */
+ Word16 * alp, /* (i/o) energy of all fixed pulses */
+ Word16 * ix, /* (o) position of pulse 1 */
+ Word16 * iy, /* (o) position of pulse 2 */
+ Word16 dn[], /* (i) corr. between target and h[] */
+ Word16 dn2[], /* (i) vector of selected positions */
+ Word16 cor_x[], /* (i) corr. of pulse 1 with fixed pulses */
+ Word16 cor_y[], /* (i) corr. of pulse 2 with fixed pulses */
+ Word16 rrixiy[][MSIZE] /* (i) corr. of pulse 1 with pulse 2 */
+ )
+{
+ Word32 x, y, pos, thres_ix;
+ Word16 ps1, ps2, sq, sqk;
+ Word16 alp_16, alpk;
+ Word16 *p0, *p1, *p2;
+ Word32 s, alp0, alp1, alp2;
+
+ p0 = cor_x;
+ p1 = cor_y;
+ p2 = rrixiy[track_x];
+
+ thres_ix = nb_pos_ix - NB_MAX;
+
+ alp0 = L_deposit_h(*alp);
+ alp0 = (alp0 + 0x00008000L); /* for rounding */
+
+ sqk = -1;
+ alpk = 1;
+
+ for (x = track_x; x < L_SUBFR; x += STEP)
+ {
+ ps1 = *ps + dn[x];
+ alp1 = alp0 + ((*p0++)<<13);
+
+ if (dn2[x] < thres_ix)
+ {
+ pos = -1;
+ for (y = track_y; y < L_SUBFR; y += STEP)
+ {
+ ps2 = add1(ps1, dn[y]);
+
+ alp2 = alp1 + ((*p1++)<<13);
+ alp2 = alp2 + ((*p2++)<<14);
+ alp_16 = extract_h(alp2);
+ sq = vo_mult(ps2, ps2);
+ s = vo_L_mult(alpk, sq) - ((sqk * alp_16)<<1);
+
+ if (s > 0)
+ {
+ sqk = sq;
+ alpk = alp_16;
+ pos = y;
+ }
+ }
+ p1 -= NB_POS;
+
+ if (pos >= 0)
+ {
+ *ix = x;
+ *iy = pos;
+ }
+ } else
+ {
+ p2 += NB_POS;
+ }
+ }
+
+ *ps = add1(*ps, add1(dn[*ix], dn[*iy]));
+ *alp = alpk;
+
+ return;
+}
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c b/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c
new file mode 100644
index 0000000..c17264c
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c
@@ -0,0 +1,73 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+/*******************************************************************************
+ File: cmnMemory.c
+
+ Content: sample code for memory operator implementation
+
+*******************************************************************************/
+#include "cmnMemory.h"
+
+#include <malloc.h>
+#if defined LINUX
+#include <string.h>
+#endif
+
+//VO_MEM_OPERATOR g_memOP;
+
+VO_U32 cmnMemAlloc (VO_S32 uID, VO_MEM_INFO * pMemInfo)
+{
+ if (!pMemInfo)
+ return VO_ERR_INVALID_ARG;
+
+ pMemInfo->VBuffer = malloc (pMemInfo->Size);
+ return 0;
+}
+
+VO_U32 cmnMemFree (VO_S32 uID, VO_PTR pMem)
+{
+ free (pMem);
+ return 0;
+}
+
+VO_U32 cmnMemSet (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize)
+{
+ memset (pBuff, uValue, uSize);
+ return 0;
+}
+
+VO_U32 cmnMemCopy (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
+{
+ memcpy (pDest, pSource, uSize);
+ return 0;
+}
+
+VO_U32 cmnMemCheck (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize)
+{
+ return 0;
+}
+
+VO_S32 cmnMemCompare (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize)
+{
+ return memcmp(pBuffer1, pBuffer2, uSize);
+}
+
+VO_U32 cmnMemMove (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
+{
+ memmove (pDest, pSource, uSize);
+ return 0;
+}
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/convolve.c b/media/libstagefright/codecs/amrwbenc/src/convolve.c
new file mode 100644
index 0000000..66c74d6
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/convolve.c
@@ -0,0 +1,109 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+ File: convolve.c
+
+ Description:Perform the convolution between two vectors x[] and h[]
+ and write the result in the vector y[]
+
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+
+void Convolve (
+ Word16 x[], /* (i) : input vector */
+ Word16 h[], /* (i) : impulse response */
+ Word16 y[], /* (o) : output vector */
+ Word16 L /* (i) : vector size */
+ )
+{
+ Word32 i, n;
+ Word16 *tmpH,*tmpX;
+ Word32 s;
+ for (n = 0; n < 64;)
+ {
+ tmpH = h+n;
+ tmpX = x;
+ i=n+1;
+ s = vo_mult32((*tmpX++), (*tmpH--));i--;
+ while(i>0)
+ {
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ i -= 4;
+ }
+ y[n] = ((s<<1) + 0x8000)>>16;
+ n++;
+
+ tmpH = h+n;
+ tmpX = x;
+ i=n+1;
+ s = vo_mult32((*tmpX++), (*tmpH--));i--;
+ s += vo_mult32((*tmpX++), (*tmpH--));i--;
+
+ while(i>0)
+ {
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ i -= 4;
+ }
+ y[n] = ((s<<1) + 0x8000)>>16;
+ n++;
+
+ tmpH = h+n;
+ tmpX = x;
+ i=n+1;
+ s = vo_mult32((*tmpX++), (*tmpH--));i--;
+ s += vo_mult32((*tmpX++), (*tmpH--));i--;
+ s += vo_mult32((*tmpX++), (*tmpH--));i--;
+
+ while(i>0)
+ {
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ i -= 4;
+ }
+ y[n] = ((s<<1) + 0x8000)>>16;
+ n++;
+
+ s = 0;
+ tmpH = h+n;
+ tmpX = x;
+ i=n+1;
+ while(i>0)
+ {
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ s += vo_mult32((*tmpX++), (*tmpH--));
+ i -= 4;
+ }
+ y[n] = ((s<<1) + 0x8000)>>16;
+ n++;
+ }
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c b/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c
new file mode 100644
index 0000000..3c2e9d5
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c
@@ -0,0 +1,127 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: cor_h_x.c *
+* *
+* Description:Compute correlation between target "x[]" and "h[]" *
+* Designed for codebook search (24 pulses, 4 tracks, *
+* 4 pulses per track, 16 positions in each track) to *
+* avoid saturation. *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+
+#define L_SUBFR 64
+#define NB_TRACK 4
+#define STEP 4
+
+void cor_h_x(
+ Word16 h[], /* (i) Q12 : impulse response of weighted synthesis filter */
+ Word16 x[], /* (i) Q0 : target vector */
+ Word16 dn[] /* (o) <12bit : correlation between target and h[] */
+ )
+{
+ Word32 i, j;
+ Word32 L_tmp, y32[L_SUBFR], L_tot;
+ Word16 *p1, *p2;
+ Word32 *p3;
+ Word32 L_max, L_max1, L_max2, L_max3;
+ /* first keep the result on 32 bits and find absolute maximum */
+ L_tot = 1;
+ L_max = 0;
+ L_max1 = 0;
+ L_max2 = 0;
+ L_max3 = 0;
+ for (i = 0; i < L_SUBFR; i += STEP)
+ {
+ L_tmp = 1; /* 1 -> to avoid null dn[] */
+ p1 = &x[i];
+ p2 = &h[0];
+ for (j = i; j < L_SUBFR; j++)
+ L_tmp += vo_L_mult(*p1++, *p2++);
+
+ y32[i] = L_tmp;
+ L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
+ if(L_tmp > L_max)
+ {
+ L_max = L_tmp;
+ }
+
+ L_tmp = 1L;
+ p1 = &x[i+1];
+ p2 = &h[0];
+ for (j = i+1; j < L_SUBFR; j++)
+ L_tmp += vo_L_mult(*p1++, *p2++);
+
+ y32[i+1] = L_tmp;
+ L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
+ if(L_tmp > L_max1)
+ {
+ L_max1 = L_tmp;
+ }
+
+ L_tmp = 1;
+ p1 = &x[i+2];
+ p2 = &h[0];
+ for (j = i+2; j < L_SUBFR; j++)
+ L_tmp += vo_L_mult(*p1++, *p2++);
+
+ y32[i+2] = L_tmp;
+ L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
+ if(L_tmp > L_max2)
+ {
+ L_max2 = L_tmp;
+ }
+
+ L_tmp = 1;
+ p1 = &x[i+3];
+ p2 = &h[0];
+ for (j = i+3; j < L_SUBFR; j++)
+ L_tmp += vo_L_mult(*p1++, *p2++);
+
+ y32[i+3] = L_tmp;
+ L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
+ if(L_tmp > L_max3)
+ {
+ L_max3 = L_tmp;
+ }
+ }
+ /* tot += 3*max / 8 */
+ L_max = ((L_max + L_max1 + L_max2 + L_max3) >> 2);
+ L_tot = vo_L_add(L_tot, L_max); /* +max/4 */
+ L_tot = vo_L_add(L_tot, (L_max >> 1)); /* +max/8 */
+
+ /* Find the number of right shifts to do on y32[] so that */
+ /* 6.0 x sumation of max of dn[] in each track not saturate. */
+ j = norm_l(L_tot) - 4; /* 4 -> 16 x tot */
+ p1 = dn;
+ p3 = y32;
+ for (i = 0; i < L_SUBFR; i+=4)
+ {
+ *p1++ = vo_round(L_shl(*p3++, j));
+ *p1++ = vo_round(L_shl(*p3++, j));
+ *p1++ = vo_round(L_shl(*p3++, j));
+ *p1++ = vo_round(L_shl(*p3++, j));
+ }
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/decim54.c b/media/libstagefright/codecs/amrwbenc/src/decim54.c
new file mode 100644
index 0000000..429a7d6
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/decim54.c
@@ -0,0 +1,146 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: decim54.c *
+* *
+* Description:Decimation of 16kHz signal to 12.8kHz *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "acelp.h"
+#include "cnst.h"
+
+#define FAC5 5
+#define DOWN_FAC 26215 /* 4/5 in Q15 */
+
+#define NB_COEF_DOWN 15
+
+/* Local functions */
+static void Down_samp(
+ Word16 * sig, /* input: signal to downsampling */
+ Word16 * sig_d, /* output: downsampled signal */
+ Word16 L_frame_d /* input: length of output */
+ );
+
+/* 1/5 resolution interpolation filter (in Q14) */
+/* -1.5dB @ 6kHz, -6dB @ 6.4kHz, -10dB @ 6.6kHz, -20dB @ 6.9kHz, -25dB @ 7kHz, -55dB @ 8kHz */
+
+static Word16 fir_down1[4][30] =
+{
+ {-5, 24, -50, 54, 0, -128, 294, -408, 344, 0, -647, 1505, -2379, 3034, 13107, 3034, -2379, 1505, -647, 0, 344, -408,
+ 294, -128, 0, 54, -50, 24, -5, 0},
+
+ {-6, 19, -26, 0, 77, -188, 270, -233, 0, 434, -964, 1366, -1293, 0, 12254, 6575, -2746, 1030, 0, -507, 601, -441,
+ 198, 0, -95, 99, -58, 18, 0, -1},
+
+ {-3, 9, 0, -41, 111, -170, 153, 0, -295, 649, -888, 770, 0, -1997, 9894, 9894, -1997, 0, 770, -888, 649, -295, 0,
+ 153, -170, 111, -41, 0, 9, -3},
+
+ {-1, 0, 18, -58, 99, -95, 0, 198, -441, 601, -507, 0, 1030, -2746, 6575, 12254, 0, -1293, 1366, -964, 434, 0,
+ -233, 270, -188, 77, 0, -26, 19, -6}
+};
+
+void Init_Decim_12k8(
+ Word16 mem[] /* output: memory (2*NB_COEF_DOWN) set to zeros */
+ )
+{
+ Set_zero(mem, 2 * NB_COEF_DOWN);
+ return;
+}
+
+void Decim_12k8(
+ Word16 sig16k[], /* input: signal to downsampling */
+ Word16 lg, /* input: length of input */
+ Word16 sig12k8[], /* output: decimated signal */
+ Word16 mem[] /* in/out: memory (2*NB_COEF_DOWN) */
+ )
+{
+ Word16 lg_down;
+ Word16 signal[L_FRAME16k + (2 * NB_COEF_DOWN)];
+
+ Copy(mem, signal, 2 * NB_COEF_DOWN);
+
+ Copy(sig16k, signal + (2 * NB_COEF_DOWN), lg);
+
+ lg_down = (lg * DOWN_FAC)>>15;
+
+ Down_samp(signal + NB_COEF_DOWN, sig12k8, lg_down);
+
+ Copy(signal + lg, mem, 2 * NB_COEF_DOWN);
+
+ return;
+}
+
+static void Down_samp(
+ Word16 * sig, /* input: signal to downsampling */
+ Word16 * sig_d, /* output: downsampled signal */
+ Word16 L_frame_d /* input: length of output */
+ )
+{
+ Word32 i, j, frac, pos;
+ Word16 *x, *y;
+ Word32 L_sum;
+
+ pos = 0; /* position is in Q2 -> 1/4 resolution */
+ for (j = 0; j < L_frame_d; j++)
+ {
+ i = (pos >> 2); /* integer part */
+ frac = pos & 3; /* fractional part */
+ x = sig + i - NB_COEF_DOWN + 1;
+ y = (Word16 *)(fir_down1 + frac);
+
+ L_sum = vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x++),(*y++));
+ L_sum += vo_mult32((*x),(*y));
+
+ L_sum = L_shl2(L_sum, 2);
+ sig_d[j] = extract_h(L_add(L_sum, 0x8000));
+ pos += FAC5; /* pos + 5/4 */
+ }
+ return;
+}
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/deemph.c b/media/libstagefright/codecs/amrwbenc/src/deemph.c
new file mode 100644
index 0000000..6ad528d
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/deemph.c
@@ -0,0 +1,117 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: deemph.c *
+* *
+* Description:filtering through 1/(1-mu z^ -1) *
+* Deemph2 --> signal is divided by 2 *
+* Deemph_32 --> for 32 bits signal. *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+
+void Deemph(
+ Word16 x[], /* (i/o) : input signal overwritten by the output */
+ Word16 mu, /* (i) Q15 : deemphasis factor */
+ Word16 L, /* (i) : vector size */
+ Word16 * mem /* (i/o) : memory (y[-1]) */
+ )
+{
+ Word32 i;
+ Word32 L_tmp;
+
+ L_tmp = L_deposit_h(x[0]);
+ L_tmp = L_mac(L_tmp, *mem, mu);
+ x[0] = vo_round(L_tmp);
+
+ for (i = 1; i < L; i++)
+ {
+ L_tmp = L_deposit_h(x[i]);
+ L_tmp = L_mac(L_tmp, x[i - 1], mu);
+ x[i] = voround(L_tmp);
+ }
+
+ *mem = x[L - 1];
+
+ return;
+}
+
+
+void Deemph2(
+ Word16 x[], /* (i/o) : input signal overwritten by the output */
+ Word16 mu, /* (i) Q15 : deemphasis factor */
+ Word16 L, /* (i) : vector size */
+ Word16 * mem /* (i/o) : memory (y[-1]) */
+ )
+{
+ Word32 i;
+ Word32 L_tmp;
+ L_tmp = x[0] << 15;
+ L_tmp += ((*mem) * mu)<<1;
+ x[0] = (L_tmp + 0x8000)>>16;
+ for (i = 1; i < L; i++)
+ {
+ L_tmp = x[i] << 15;
+ L_tmp += (x[i - 1] * mu)<<1;
+ x[i] = (L_tmp + 0x8000)>>16;
+ }
+ *mem = x[L - 1];
+ return;
+}
+
+
+void Deemph_32(
+ Word16 x_hi[], /* (i) : input signal (bit31..16) */
+ Word16 x_lo[], /* (i) : input signal (bit15..4) */
+ Word16 y[], /* (o) : output signal (x16) */
+ Word16 mu, /* (i) Q15 : deemphasis factor */
+ Word16 L, /* (i) : vector size */
+ Word16 * mem /* (i/o) : memory (y[-1]) */
+ )
+{
+ Word16 fac;
+ Word32 i, L_tmp;
+
+ fac = mu >> 1; /* Q15 --> Q14 */
+
+ L_tmp = L_deposit_h(x_hi[0]);
+ L_tmp += (x_lo[0] * 8)<<1;
+ L_tmp = (L_tmp << 3);
+ L_tmp += ((*mem) * fac)<<1;
+ L_tmp = (L_tmp << 1);
+ y[0] = (L_tmp + 0x8000)>>16;
+
+ for (i = 1; i < L; i++)
+ {
+ L_tmp = L_deposit_h(x_hi[i]);
+ L_tmp += (x_lo[i] * 8)<<1;
+ L_tmp = (L_tmp << 3);
+ L_tmp += (y[i - 1] * fac)<<1;
+ L_tmp = (L_tmp << 1);
+ y[i] = (L_tmp + 0x8000)>>16;
+ }
+
+ *mem = y[L - 1];
+
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/dtx.c b/media/libstagefright/codecs/amrwbenc/src/dtx.c
new file mode 100644
index 0000000..02921eb
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/dtx.c
@@ -0,0 +1,605 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: dtx.c *
+* *
+* Description:DTX functions *
+* *
+************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "math_op.h"
+#include "cnst.h"
+#include "acelp.h" /* prototype of functions */
+#include "bits.h"
+#include "dtx.h"
+#include "log2.h"
+#include "mem_align.h"
+
+static void aver_isf_history(
+ Word16 isf_old[],
+ Word16 indices[],
+ Word32 isf_aver[]
+ );
+
+static void find_frame_indices(
+ Word16 isf_old_tx[],
+ Word16 indices[],
+ dtx_encState * st
+ );
+
+static Word16 dithering_control(
+ dtx_encState * st
+ );
+
+/* excitation energy adjustment depending on speech coder mode used, Q7 */
+static Word16 en_adjust[9] =
+{
+ 230, /* mode0 = 7k : -5.4dB */
+ 179, /* mode1 = 9k : -4.2dB */
+ 141, /* mode2 = 12k : -3.3dB */
+ 128, /* mode3 = 14k : -3.0dB */
+ 122, /* mode4 = 16k : -2.85dB */
+ 115, /* mode5 = 18k : -2.7dB */
+ 115, /* mode6 = 20k : -2.7dB */
+ 115, /* mode7 = 23k : -2.7dB */
+ 115 /* mode8 = 24k : -2.7dB */
+};
+
+/**************************************************************************
+*
+* Function : dtx_enc_init
+*
+**************************************************************************/
+Word16 dtx_enc_init(dtx_encState ** st, Word16 isf_init[], VO_MEM_OPERATOR *pMemOP)
+{
+ dtx_encState *s;
+
+ if (st == (dtx_encState **) NULL)
+ {
+ fprintf(stderr, "dtx_enc_init: invalid parameter\n");
+ return -1;
+ }
+ *st = NULL;
+
+ /* allocate memory */
+ if ((s = (dtx_encState *)mem_malloc(pMemOP, sizeof(dtx_encState), 32, VO_INDEX_ENC_AMRWB)) == NULL)
+ {
+ fprintf(stderr, "dtx_enc_init: can not malloc state structure\n");
+ return -1;
+ }
+ dtx_enc_reset(s, isf_init);
+ *st = s;
+ return 0;
+}
+
+/**************************************************************************
+*
+* Function : dtx_enc_reset
+*
+**************************************************************************/
+Word16 dtx_enc_reset(dtx_encState * st, Word16 isf_init[])
+{
+ Word32 i;
+
+ if (st == (dtx_encState *) NULL)
+ {
+ fprintf(stderr, "dtx_enc_reset: invalid parameter\n");
+ return -1;
+ }
+ st->hist_ptr = 0;
+ st->log_en_index = 0;
+
+ /* Init isf_hist[] */
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ Copy(isf_init, &st->isf_hist[i * M], M);
+ }
+ st->cng_seed = RANDOM_INITSEED;
+
+ /* Reset energy history */
+ Set_zero(st->log_en_hist, DTX_HIST_SIZE);
+
+ st->dtxHangoverCount = DTX_HANG_CONST;
+ st->decAnaElapsedCount = 32767;
+
+ for (i = 0; i < 28; i++)
+ {
+ st->D[i] = 0;
+ }
+
+ for (i = 0; i < DTX_HIST_SIZE - 1; i++)
+ {
+ st->sumD[i] = 0;
+ }
+
+ return 1;
+}
+
+/**************************************************************************
+*
+* Function : dtx_enc_exit
+*
+**************************************************************************/
+void dtx_enc_exit(dtx_encState ** st, VO_MEM_OPERATOR *pMemOP)
+{
+ if (st == NULL || *st == NULL)
+ return;
+ /* deallocate memory */
+ mem_free(pMemOP, *st, VO_INDEX_ENC_AMRWB);
+ *st = NULL;
+ return;
+}
+
+
+/**************************************************************************
+*
+* Function : dtx_enc
+*
+**************************************************************************/
+Word16 dtx_enc(
+ dtx_encState * st, /* i/o : State struct */
+ Word16 isf[M], /* o : CN ISF vector */
+ Word16 * exc2, /* o : CN excitation */
+ Word16 ** prms
+ )
+{
+ Word32 i, j;
+ Word16 indice[7];
+ Word16 log_en, gain, level, exp, exp0, tmp;
+ Word16 log_en_int_e, log_en_int_m;
+ Word32 L_isf[M], ener32, level32;
+ Word16 isf_order[3];
+ Word16 CN_dith;
+
+ /* VOX mode computation of SID parameters */
+ log_en = 0;
+ for (i = 0; i < M; i++)
+ {
+ L_isf[i] = 0;
+ }
+ /* average energy and isf */
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer. log_en is in Q10 */
+ log_en = add(log_en, st->log_en_hist[i]);
+
+ }
+ find_frame_indices(st->isf_hist, isf_order, st);
+ aver_isf_history(st->isf_hist, isf_order, L_isf);
+
+ for (j = 0; j < M; j++)
+ {
+ isf[j] = (Word16)(L_isf[j] >> 3); /* divide by 8 */
+ }
+
+ /* quantize logarithmic energy to 6 bits (-6 : 66 dB) which corresponds to -2:22 in log2(E). */
+ /* st->log_en_index = (short)( (log_en + 2.0) * 2.625 ); */
+
+ /* increase dynamics to 7 bits (Q8) */
+ log_en = (log_en >> 2);
+
+ /* Add 2 in Q8 = 512 to get log2(E) between 0:24 */
+ log_en = add(log_en, 512);
+
+ /* Multiply by 2.625 to get full 6 bit range. 2.625 = 21504 in Q13. The result is in Q6 */
+ log_en = mult(log_en, 21504);
+
+ /* Quantize Energy */
+ st->log_en_index = shr(log_en, 6);
+
+ if(st->log_en_index > 63)
+ {
+ st->log_en_index = 63;
+ }
+ if (st->log_en_index < 0)
+ {
+ st->log_en_index = 0;
+ }
+ /* Quantize ISFs */
+ Qisf_ns(isf, isf, indice);
+
+
+ Parm_serial(indice[0], 6, prms);
+ Parm_serial(indice[1], 6, prms);
+ Parm_serial(indice[2], 6, prms);
+ Parm_serial(indice[3], 5, prms);
+ Parm_serial(indice[4], 5, prms);
+
+ Parm_serial((st->log_en_index), 6, prms);
+
+ CN_dith = dithering_control(st);
+ Parm_serial(CN_dith, 1, prms);
+
+ /* level = (float)( pow( 2.0f, (float)st->log_en_index / 2.625 - 2.0 ) ); */
+ /* log2(E) in Q9 (log2(E) lies in between -2:22) */
+ log_en = shl(st->log_en_index, 15 - 6);
+
+ /* Divide by 2.625; log_en will be between 0:24 */
+ log_en = mult(log_en, 12483);
+ /* the result corresponds to log2(gain) in Q10 */
+
+ /* Find integer part */
+ log_en_int_e = (log_en >> 10);
+
+ /* Find fractional part */
+ log_en_int_m = (Word16) (log_en & 0x3ff);
+ log_en_int_m = shl(log_en_int_m, 5);
+
+ /* Subtract 2 from log_en in Q9, i.e divide the gain by 2 (energy by 4) */
+ /* Add 16 in order to have the result of pow2 in Q16 */
+ log_en_int_e = add(log_en_int_e, 16 - 1);
+
+ level32 = Pow2(log_en_int_e, log_en_int_m); /* Q16 */
+ exp0 = norm_l(level32);
+ level32 = (level32 << exp0); /* level in Q31 */
+ exp0 = (15 - exp0);
+ level = extract_h(level32); /* level in Q15 */
+
+ /* generate white noise vector */
+ for (i = 0; i < L_FRAME; i++)
+ {
+ exc2[i] = (Random(&(st->cng_seed)) >> 4);
+ }
+
+ /* gain = level / sqrt(ener) * sqrt(L_FRAME) */
+
+ /* energy of generated excitation */
+ ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp);
+
+ Isqrt_n(&ener32, &exp);
+
+ gain = extract_h(ener32);
+
+ gain = mult(level, gain); /* gain in Q15 */
+
+ exp = add(exp0, exp);
+
+ /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */
+ exp += 4;
+
+ for (i = 0; i < L_FRAME; i++)
+ {
+ tmp = mult(exc2[i], gain); /* Q0 * Q15 */
+ exc2[i] = shl(tmp, exp);
+ }
+
+ return 0;
+}
+
+/**************************************************************************
+*
+* Function : dtx_buffer Purpose : handles the DTX buffer
+*
+**************************************************************************/
+Word16 dtx_buffer(
+ dtx_encState * st, /* i/o : State struct */
+ Word16 isf_new[], /* i : isf vector */
+ Word32 enr, /* i : residual energy (in L_FRAME) */
+ Word16 codec_mode
+ )
+{
+ Word16 log_en;
+
+ Word16 log_en_e;
+ Word16 log_en_m;
+ st->hist_ptr = add(st->hist_ptr, 1);
+ if(st->hist_ptr == DTX_HIST_SIZE)
+ {
+ st->hist_ptr = 0;
+ }
+ /* copy lsp vector into buffer */
+ Copy(isf_new, &st->isf_hist[st->hist_ptr * M], M);
+
+ /* log_en = (float)log10(enr*0.0059322)/(float)log10(2.0f); */
+ Log2(enr, &log_en_e, &log_en_m);
+
+ /* convert exponent and mantissa to Word16 Q7. Q7 is used to simplify averaging in dtx_enc */
+ log_en = shl(log_en_e, 7); /* Q7 */
+ log_en = add(log_en, shr(log_en_m, 15 - 7));
+
+ /* Find energy per sample by multiplying with 0.0059322, i.e subtract log2(1/0.0059322) = 7.39722 The
+ * constant 0.0059322 takes into account windowings and analysis length from autocorrelation
+ * computations; 7.39722 in Q7 = 947 */
+ /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */
+ /* log_en = sub( log_en, 947 + en_adjust[codec_mode] ); */
+
+ /* Find energy per sample (divide by L_FRAME=256), i.e subtract log2(256) = 8.0 (1024 in Q7) */
+ /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */
+
+ log_en = sub(log_en, add(1024, en_adjust[codec_mode]));
+
+ /* Insert into the buffer */
+ st->log_en_hist[st->hist_ptr] = log_en;
+ return 0;
+}
+
+/**************************************************************************
+*
+* Function : tx_dtx_handler Purpose : adds extra speech hangover
+* to analyze speech on
+* the decoding side.
+**************************************************************************/
+void tx_dtx_handler(dtx_encState * st, /* i/o : State struct */
+ Word16 vad_flag, /* i : vad decision */
+ Word16 * usedMode /* i/o : mode changed or not */
+ )
+{
+
+ /* this state machine is in synch with the GSMEFR txDtx machine */
+ st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
+
+ if (vad_flag != 0)
+ {
+ st->dtxHangoverCount = DTX_HANG_CONST;
+ } else
+ { /* non-speech */
+ if (st->dtxHangoverCount == 0)
+ { /* out of decoder analysis hangover */
+ st->decAnaElapsedCount = 0;
+ *usedMode = MRDTX;
+ } else
+ { /* in possible analysis hangover */
+ st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
+
+ /* decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH */
+ if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
+ DTX_ELAPSED_FRAMES_THRESH) < 0)
+ {
+ *usedMode = MRDTX;
+ /* if short time since decoder update, do not add extra HO */
+ }
+ /* else override VAD and stay in speech mode *usedMode and add extra hangover */
+ }
+ }
+
+ return;
+}
+
+
+
+static void aver_isf_history(
+ Word16 isf_old[],
+ Word16 indices[],
+ Word32 isf_aver[]
+ )
+{
+ Word32 i, j, k;
+ Word16 isf_tmp[2 * M];
+ Word32 L_tmp;
+
+ /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */
+ /* the median ISF vector prior to the averaging */
+ for (k = 0; k < 2; k++)
+ {
+ if ((indices[k] + 1) != 0)
+ {
+ for (i = 0; i < M; i++)
+ {
+ isf_tmp[k * M + i] = isf_old[indices[k] * M + i];
+ isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i];
+ }
+ }
+ }
+
+ /* Perform the ISF averaging */
+ for (j = 0; j < M; j++)
+ {
+ L_tmp = 0;
+
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ L_tmp = L_add(L_tmp, L_deposit_l(isf_old[i * M + j]));
+ }
+ isf_aver[j] = L_tmp;
+ }
+
+ /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */
+ for (k = 0; k < 2; k++)
+ {
+ if ((indices[k] + 1) != 0)
+ {
+ for (i = 0; i < M; i++)
+ {
+ isf_old[indices[k] * M + i] = isf_tmp[k * M + i];
+ }
+ }
+ }
+
+ return;
+}
+
+static void find_frame_indices(
+ Word16 isf_old_tx[],
+ Word16 indices[],
+ dtx_encState * st
+ )
+{
+ Word32 L_tmp, summin, summax, summax2nd;
+ Word16 i, j, tmp;
+ Word16 ptr;
+
+ /* Remove the effect of the oldest frame from the column */
+ /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is */
+ /* not updated since it will be removed later. */
+
+ tmp = DTX_HIST_SIZE_MIN_ONE;
+ j = -1;
+ for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
+ {
+ j = add(j, tmp);
+ st->sumD[i] = L_sub(st->sumD[i], st->D[j]);
+ tmp = sub(tmp, 1);
+ }
+
+ /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1] */
+ /* corresponding to the oldest frame is removed. The sum of */
+ /* the distances between the latest isf and other isfs, */
+ /* i.e. the element sumD[0], will be computed during this call. */
+ /* Hence this element is initialized to zero. */
+
+ for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--)
+ {
+ st->sumD[i] = st->sumD[i - 1];
+ }
+ st->sumD[0] = 0;
+
+ /* Remove the oldest frame from the distance matrix. */
+ /* Note that the distance matrix is replaced by a one- */
+ /* dimensional array to save static memory. */
+
+ tmp = 0;
+ for (i = 27; i >= 12; i = (Word16) (i - tmp))
+ {
+ tmp = add(tmp, 1);
+ for (j = tmp; j > 0; j--)
+ {
+ st->D[i - j + 1] = st->D[i - j - tmp];
+ }
+ }
+
+ /* Compute the first column of the distance matrix D */
+ /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */
+
+ ptr = st->hist_ptr;
+ for (i = 1; i < DTX_HIST_SIZE; i++)
+ {
+ /* Compute the distance between the latest isf and the other isfs. */
+ ptr = sub(ptr, 1);
+ if (ptr < 0)
+ {
+ ptr = DTX_HIST_SIZE_MIN_ONE;
+ }
+ L_tmp = 0;
+ for (j = 0; j < M; j++)
+ {
+ tmp = sub(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]);
+ L_tmp = L_mac(L_tmp, tmp, tmp);
+ }
+ st->D[i - 1] = L_tmp;
+
+ /* Update also the column sums. */
+ st->sumD[0] = L_add(st->sumD[0], st->D[i - 1]);
+ st->sumD[i] = L_add(st->sumD[i], st->D[i - 1]);
+ }
+
+ /* Find the minimum and maximum distances */
+ summax = st->sumD[0];
+ summin = st->sumD[0];
+ indices[0] = 0;
+ indices[2] = 0;
+ for (i = 1; i < DTX_HIST_SIZE; i++)
+ {
+ if (L_sub(st->sumD[i], summax) > 0)
+ {
+ indices[0] = i;
+ summax = st->sumD[i];
+ }
+ if (L_sub(st->sumD[i], summin) < 0)
+ {
+ indices[2] = i;
+ summin = st->sumD[i];
+ }
+ }
+
+ /* Find the second largest distance */
+ summax2nd = -2147483647L;
+ indices[1] = -1;
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ if ((L_sub(st->sumD[i], summax2nd) > 0) && (sub(i, indices[0]) != 0))
+ {
+ indices[1] = i;
+ summax2nd = st->sumD[i];
+ }
+ }
+
+ for (i = 0; i < 3; i++)
+ {
+ indices[i] = sub(st->hist_ptr, indices[i]);
+ if (indices[i] < 0)
+ {
+ indices[i] = add(indices[i], DTX_HIST_SIZE);
+ }
+ }
+
+ /* If maximum distance/MED_THRESH is smaller than minimum distance */
+ /* then the median ISF vector replacement is not performed */
+ tmp = norm_l(summax);
+ summax = (summax << tmp);
+ summin = (summin << tmp);
+ L_tmp = L_mult(voround(summax), INV_MED_THRESH);
+ if(L_tmp <= summin)
+ {
+ indices[0] = -1;
+ }
+ /* If second largest distance/MED_THRESH is smaller than */
+ /* minimum distance then the median ISF vector replacement is */
+ /* not performed */
+ summax2nd = L_shl(summax2nd, tmp);
+ L_tmp = L_mult(voround(summax2nd), INV_MED_THRESH);
+ if(L_tmp <= summin)
+ {
+ indices[1] = -1;
+ }
+ return;
+}
+
+static Word16 dithering_control(
+ dtx_encState * st
+ )
+{
+ Word16 tmp, mean, CN_dith, gain_diff;
+ Word32 i, ISF_diff;
+
+ /* determine how stationary the spectrum of background noise is */
+ ISF_diff = 0;
+ for (i = 0; i < 8; i++)
+ {
+ ISF_diff = L_add(ISF_diff, st->sumD[i]);
+ }
+ if ((ISF_diff >> 26) > 0)
+ {
+ CN_dith = 1;
+ } else
+ {
+ CN_dith = 0;
+ }
+
+ /* determine how stationary the energy of background noise is */
+ mean = 0;
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ mean = add(mean, st->log_en_hist[i]);
+ }
+ mean = (mean >> 3);
+ gain_diff = 0;
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ tmp = abs_s(sub(st->log_en_hist[i], mean));
+ gain_diff = add(gain_diff, tmp);
+ }
+ if (gain_diff > GAIN_THR)
+ {
+ CN_dith = 1;
+ }
+ return CN_dith;
+}
diff --git a/media/libstagefright/codecs/amrwbenc/src/g_pitch.c b/media/libstagefright/codecs/amrwbenc/src/g_pitch.c
new file mode 100644
index 0000000..570138e
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/g_pitch.c
@@ -0,0 +1,79 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: g_pitch.c *
+* *
+* Description:Compute the gain of pitch. Result in Q12 *
+* if(gain < 0) gain = 0 *
+* if(gain > 1.2) gain = 1.2 *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+
+Word16 G_pitch( /* (o) Q14 : Gain of pitch lag saturated to 1.2 */
+ Word16 xn[], /* (i) : Pitch target. */
+ Word16 y1[], /* (i) : filtered adaptive codebook. */
+ Word16 g_coeff[], /* : Correlations need for gain quantization. */
+ Word16 L_subfr /* : Length of subframe. */
+ )
+{
+ Word32 i;
+ Word16 xy, yy, exp_xy, exp_yy, gain;
+ /* Compute scalar product <y1[],y1[]> */
+#ifdef ASM_OPT /* asm optimization branch */
+ /* Compute scalar product <xn[],y1[]> */
+ xy = extract_h(Dot_product12_asm(xn, y1, L_subfr, &exp_xy));
+ yy = extract_h(Dot_product12_asm(y1, y1, L_subfr, &exp_yy));
+
+#else
+ /* Compute scalar product <xn[],y1[]> */
+ xy = extract_h(Dot_product12(xn, y1, L_subfr, &exp_xy));
+ yy = extract_h(Dot_product12(y1, y1, L_subfr, &exp_yy));
+
+#endif
+
+ g_coeff[0] = yy;
+ g_coeff[1] = exp_yy;
+ g_coeff[2] = xy;
+ g_coeff[3] = exp_xy;
+
+ /* If (xy < 0) gain = 0 */
+ if (xy < 0)
+ return ((Word16) 0);
+
+ /* compute gain = xy/yy */
+
+ xy >>= 1; /* Be sure xy < yy */
+ gain = div_s(xy, yy);
+
+ i = exp_xy;
+ i -= exp_yy;
+
+ gain = shl(gain, i);
+
+ /* if (gain > 1.2) gain = 1.2 in Q14 */
+ if(gain > 19661)
+ {
+ gain = 19661;
+ }
+ return (gain);
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/gpclip.c b/media/libstagefright/codecs/amrwbenc/src/gpclip.c
new file mode 100644
index 0000000..e23f2f4
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/gpclip.c
@@ -0,0 +1,110 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/**************************************************************************
+* File: gpclip.c *
+* *
+* Description:To avoid unstable synthesis on frame erasure, the gain *
+* need to be limited(gain pitch < 1.0) when the following *
+* case occurs *
+* a resonance on LPC filter(lp_disp < 60Hz) *
+* a good pitch prediction (lp_gp > 0.95) *
+* *
+***************************************************************************/
+#include "typedef.h"
+#include "basic_op.h"
+
+#define DIST_ISF_MAX 307 /* 120 Hz (6400Hz=16384) */
+#define DIST_ISF_THRES 154 /* 60 (6400Hz=16384) */
+#define GAIN_PIT_THRES 14746 /* 0.9 in Q14 */
+#define GAIN_PIT_MIN 9830 /* 0.6 in Q14 */
+#define M 16
+
+
+void Init_gp_clip(
+ Word16 mem[] /* (o) : memory of gain of pitch clipping algorithm */
+ )
+{
+ mem[0] = DIST_ISF_MAX;
+ mem[1] = GAIN_PIT_MIN;
+}
+
+
+Word16 Gp_clip(
+ Word16 mem[] /* (i/o) : memory of gain of pitch clipping algorithm */
+ )
+{
+ Word16 clip = 0;
+ if ((mem[0] < DIST_ISF_THRES) && (mem[1] > GAIN_PIT_THRES))
+ clip = 1;
+
+ return (clip);
+}
+
+
+void Gp_clip_test_isf(
+ Word16 isf[], /* (i) : isf values (in frequency domain) */
+ Word16 mem[] /* (i/o) : memory of gain of pitch clipping algorithm */
+ )
+{
+ Word16 dist, dist_min;
+ Word32 i;
+
+ dist_min = vo_sub(isf[1], isf[0]);
+
+ for (i = 2; i < M - 1; i++)
+ {
+ dist = vo_sub(isf[i], isf[i - 1]);
+ if(dist < dist_min)
+ {
+ dist_min = dist;
+ }
+ }
+
+ dist = extract_h(L_mac(vo_L_mult(26214, mem[0]), 6554, dist_min));
+
+ if (dist > DIST_ISF_MAX)
+ {
+ dist = DIST_ISF_MAX;
+ }
+ mem[0] = dist;
+
+ return;
+}
+
+
+void Gp_clip_test_gain_pit(
+ Word16 gain_pit, /* (i) Q14 : gain of quantized pitch */
+ Word16 mem[] /* (i/o) : memory of gain of pitch clipping algorithm */
+ )
+{
+ Word16 gain;
+ Word32 L_tmp;
+ L_tmp = (29491 * mem[1])<<1;
+ L_tmp += (3277 * gain_pit)<<1;
+
+ gain = extract_h(L_tmp);
+
+ if(gain < GAIN_PIT_MIN)
+ {
+ gain = GAIN_PIT_MIN;
+ }
+ mem[1] = gain;
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/homing.c b/media/libstagefright/codecs/amrwbenc/src/homing.c
new file mode 100644
index 0000000..015633f
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/homing.c
@@ -0,0 +1,46 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: homing.c *
+* *
+* Description:Performs the homing routines *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "cnst.h"
+#include "basic_op.h"
+#include "bits.h"
+#include "homing.tab"
+
+Word16 encoder_homing_frame_test(Word16 input_frame[])
+{
+ Word32 i;
+ Word16 j = 0;
+
+ /* check 320 input samples for matching EHF_MASK: defined in e_homing.h */
+ for (i = 0; i < L_FRAME16k; i++)
+ {
+ j = (Word16) (input_frame[i] ^ EHF_MASK);
+
+ if (j)
+ break;
+ }
+
+ return (Word16) (!j);
+}
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp400.c b/media/libstagefright/codecs/amrwbenc/src/hp400.c
new file mode 100644
index 0000000..463a53a
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/hp400.c
@@ -0,0 +1,106 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: hp400.c *
+* *
+* Description: *
+* 2nd order high pass filter with cut off frequency at 400 Hz. *
+* Designed with cheby2 function in MATLAB. *
+* Optimized for fixed-point to get the following frequency response: *
+* *
+* frequency: 0Hz 100Hz 200Hz 300Hz 400Hz 630Hz 1.5kHz 3kHz *
+* dB loss: -infdB -30dB -20dB -10dB -3dB +6dB +1dB 0dB *
+* *
+* Algorithm: *
+* *
+* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] *
+* + a[1]*y[i-1] + a[2]*y[i-2]; *
+* *
+* Word16 b[3] = {3660, -7320, 3660}; in Q12 *
+* Word16 a[3] = {4096, 7320, -3540}; in Q12 *
+* *
+* float --> b[3] = {0.893554687, -1.787109375, 0.893554687}; *
+* a[3] = {1.000000000, 1.787109375, -0.864257812}; *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "acelp.h"
+
+/* filter coefficients */
+static Word16 b[3] = {915, -1830, 915}; /* Q12 (/4) */
+static Word16 a[3] = {16384, 29280, -14160}; /* Q12 (x4) */
+/* Initialization of static values */
+
+void Init_HP400_12k8(Word16 mem[])
+{
+ Set_zero(mem, 6);
+}
+
+
+void HP400_12k8(
+ Word16 signal[], /* input signal / output is divided by 16 */
+ Word16 lg, /* lenght of signal */
+ Word16 mem[] /* filter memory [6] */
+ )
+{
+ Word16 x2;
+ Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1;
+ Word32 L_tmp;
+ Word32 num;
+ y2_hi = *mem++;
+ y2_lo = *mem++;
+ y1_hi = *mem++;
+ y1_lo = *mem++;
+ x0 = *mem++;
+ x1 = *mem;
+ num = (Word32)lg;
+ do
+ {
+ x2 = x1;
+ x1 = x0;
+ x0 = *signal;
+ /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2] */
+ /* + a[1]*y[i-1] + a[2] * y[i-2]; */
+ L_tmp = 8192L; /* rounding to maximise precision */
+ L_tmp += y1_lo * a[1];
+ L_tmp += y2_lo * a[2];
+ L_tmp = L_tmp >> 14;
+ L_tmp += (y1_hi * a[1] + y2_hi * a[2] + (x0 + x2)* b[0] + x1 * b[1]) << 1;
+ L_tmp <<= 1; /* coeff Q12 --> Q13 */
+ y2_hi = y1_hi;
+ y2_lo = y1_lo;
+ y1_hi = (Word16)(L_tmp>>16);
+ y1_lo = (Word16)((L_tmp & 0xffff)>>1);
+
+ /* signal is divided by 16 to avoid overflow in energy computation */
+ *signal++ = (L_tmp + 0x8000) >> 16;
+ }while(--num !=0);
+
+ *mem-- = x1;
+ *mem-- = x0;
+ *mem-- = y1_lo;
+ *mem-- = y1_hi;
+ *mem-- = y2_lo;
+ *mem = y2_hi;
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp50.c b/media/libstagefright/codecs/amrwbenc/src/hp50.c
new file mode 100644
index 0000000..53e3d7b
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/hp50.c
@@ -0,0 +1,106 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: hp50.c *
+* *
+* Description: *
+* 2nd order high pass filter with cut off frequency at 31 Hz. *
+* Designed with cheby2 function in MATLAB. *
+* Optimized for fixed-point to get the following frequency response: *
+* *
+* frequency: 0Hz 14Hz 24Hz 31Hz 37Hz 41Hz 47Hz *
+* dB loss: -infdB -15dB -6dB -3dB -1.5dB -1dB -0.5dB *
+* *
+* Algorithm: *
+* *
+* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] *
+* + a[1]*y[i-1] + a[2]*y[i-2]; *
+* *
+* Word16 b[3] = {4053, -8106, 4053}; in Q12 *
+* Word16 a[3] = {8192, 16211, -8021}; in Q12 *
+* *
+* float --> b[3] = {0.989501953, -1.979003906, 0.989501953}; *
+* a[3] = {1.000000000, 1.978881836, -0.979125977}; *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "cnst.h"
+#include "acelp.h"
+
+/* filter coefficients */
+static Word16 b[3] = {4053, -8106, 4053}; /* Q12 */
+static Word16 a[3] = {8192, 16211, -8021}; /* Q12 (x2) */
+
+/* Initialization of static values */
+
+void Init_HP50_12k8(Word16 mem[])
+{
+ Set_zero(mem, 6);
+}
+
+
+void HP50_12k8(
+ Word16 signal[], /* input/output signal */
+ Word16 lg, /* lenght of signal */
+ Word16 mem[] /* filter memory [6] */
+ )
+{
+ Word16 x2;
+ Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1;
+ Word32 L_tmp;
+ Word32 num;
+
+ y2_hi = *mem++;
+ y2_lo = *mem++;
+ y1_hi = *mem++;
+ y1_lo = *mem++;
+ x0 = *mem++;
+ x1 = *mem;
+ num = (Word32)lg;
+ do
+ {
+ x2 = x1;
+ x1 = x0;
+ x0 = *signal;
+ /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2] */
+ /* + a[1]*y[i-1] + a[2] * y[i-2]; */
+ L_tmp = 8192 ; /* rounding to maximise precision */
+ L_tmp += y1_lo * a[1];
+ L_tmp += y2_lo * a[2];
+ L_tmp = L_tmp >> 14;
+ L_tmp += (y1_hi * a[1] + y2_hi * a[2] + (x0 + x2) * b[0] + x1 * b[1]) << 1;
+ L_tmp <<= 2; /* coeff Q12 --> Q13 */
+ y2_hi = y1_hi;
+ y2_lo = y1_lo;
+ y1_hi = (Word16)(L_tmp>>16);
+ y1_lo = (Word16)((L_tmp & 0xffff)>>1);
+ *signal++ = extract_h((L_add((L_tmp<<1), 0x8000)));
+ }while(--num !=0);
+
+ *mem-- = x1;
+ *mem-- = x0;
+ *mem-- = y1_lo;
+ *mem-- = y1_hi;
+ *mem-- = y2_lo;
+ *mem-- = y2_hi;
+
+ return;
+}
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp6k.c b/media/libstagefright/codecs/amrwbenc/src/hp6k.c
new file mode 100644
index 0000000..5ee5b20
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/hp6k.c
@@ -0,0 +1,93 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: hp6k.c *
+* *
+* Description:15th order band pass 6kHz to 7kHz FIR filter *
+* frequency: 4kHz 5kHz 5.5kHz 6kHz 6.5kHz 7kHz 7.5kHz 8kHz *
+* dB loss: -60dB -45dB -13dB -3dB 0dB -3dB -13dB -45dB *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "acelp.h"
+#include "cnst.h"
+
+#define L_FIR 31
+
+/* filter coefficients (gain=4.0) */
+
+Word16 fir_6k_7k[L_FIR] =
+{
+ -32, 47, 32, -27, -369,
+ 1122, -1421, 0, 3798, -8880,
+ 12349, -10984, 3548, 7766, -18001,
+ 22118, -18001, 7766, 3548, -10984,
+ 12349, -8880, 3798, 0, -1421,
+ 1122, -369, -27, 32, 47,
+ -32
+};
+
+
+void Init_Filt_6k_7k(Word16 mem[]) /* mem[30] */
+{
+ Set_zero(mem, L_FIR - 1);
+ return;
+}
+
+void Filt_6k_7k(
+ Word16 signal[], /* input: signal */
+ Word16 lg, /* input: length of input */
+ Word16 mem[] /* in/out: memory (size=30) */
+ )
+{
+ Word16 x[L_SUBFR16k + (L_FIR - 1)];
+ Word32 i, L_tmp;
+
+ Copy(mem, x, L_FIR - 1);
+ for (i = lg - 1; i >= 0; i--)
+ {
+ x[i + L_FIR - 1] = signal[i] >> 2; /* gain of filter = 4 */
+ }
+ for (i = 0; i < lg; i++)
+ {
+ L_tmp = (x[i] + x[i+ 30]) * fir_6k_7k[0];
+ L_tmp += (x[i+1] + x[i + 29]) * fir_6k_7k[1];
+ L_tmp += (x[i+2] + x[i + 28]) * fir_6k_7k[2];
+ L_tmp += (x[i+3] + x[i + 27]) * fir_6k_7k[3];
+ L_tmp += (x[i+4] + x[i + 26]) * fir_6k_7k[4];
+ L_tmp += (x[i+5] + x[i + 25]) * fir_6k_7k[5];
+ L_tmp += (x[i+6] + x[i + 24]) * fir_6k_7k[6];
+ L_tmp += (x[i+7] + x[i + 23]) * fir_6k_7k[7];
+ L_tmp += (x[i+8] + x[i + 22]) * fir_6k_7k[8];
+ L_tmp += (x[i+9] + x[i + 21]) * fir_6k_7k[9];
+ L_tmp += (x[i+10] + x[i + 20]) * fir_6k_7k[10];
+ L_tmp += (x[i+11] + x[i + 19]) * fir_6k_7k[11];
+ L_tmp += (x[i+12] + x[i + 18]) * fir_6k_7k[12];
+ L_tmp += (x[i+13] + x[i + 17]) * fir_6k_7k[13];
+ L_tmp += (x[i+14] + x[i + 16]) * fir_6k_7k[14];
+ L_tmp += (x[i+15]) * fir_6k_7k[15];
+ signal[i] = (L_tmp + 0x4000) >> 15;
+ }
+
+ Copy(x + lg, mem, L_FIR - 1);
+
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp_wsp.c b/media/libstagefright/codecs/amrwbenc/src/hp_wsp.c
new file mode 100644
index 0000000..7fb62a4
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/hp_wsp.c
@@ -0,0 +1,148 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: hp_wsp.c *
+* Description: *
+* 3nd order high pass filter with cut off frequency at 180Hz *
+* Algorithm: *
+* *
+* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] + b[3]*x[i-3] *
+* + a[1]*y[i-1] + a[2]*y[i-2] + a[3]*y[i-3]; *
+* *
+* float a_coef[HP_ORDER]= { *
+* -2.64436711600664f, *
+* 2.35087386625360f, *
+* -0.70001156927424f}; *
+* *
+* float b_coef[HP_ORDER+1]= { *
+* -0.83787057505665f, *
+* 2.50975570071058f, *
+* -2.50975570071058f, *
+* 0.83787057505665f}; *
+* *
+*************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "acelp.h"
+
+/* filter coefficients in Q12 */
+static Word16 a[4] = {8192, 21663, -19258, 5734};
+static Word16 b[4] = {-3432, +10280, -10280, +3432};
+
+/* Initialization of static values */
+void Init_Hp_wsp(Word16 mem[])
+{
+ Set_zero(mem, 9);
+
+ return;
+}
+
+void scale_mem_Hp_wsp(Word16 mem[], Word16 exp)
+{
+ Word32 i;
+ Word32 L_tmp;
+
+ for (i = 0; i < 6; i += 2)
+ {
+ L_tmp = ((mem[i] << 16) + (mem[i + 1]<<1));
+ L_tmp = L_shl(L_tmp, exp);
+ mem[i] = L_tmp >> 16;
+ mem[i + 1] = (L_tmp & 0xffff)>>1;
+ }
+
+ for (i = 6; i < 9; i++)
+ {
+ L_tmp = L_deposit_h(mem[i]); /* x[i] */
+ L_tmp = L_shl(L_tmp, exp);
+ mem[i] = vo_round(L_tmp);
+ }
+
+ return;
+}
+
+
+void Hp_wsp(
+ Word16 wsp[], /* i : wsp[] signal */
+ Word16 hp_wsp[], /* o : hypass wsp[] */
+ Word16 lg, /* i : lenght of signal */
+ Word16 mem[] /* i/o : filter memory [9] */
+ )
+{
+ Word16 x0, x1, x2, x3;
+ Word16 y3_hi, y3_lo, y2_hi, y2_lo, y1_hi, y1_lo;
+ Word32 i, L_tmp;
+
+ y3_hi = mem[0];
+ y3_lo = mem[1];
+ y2_hi = mem[2];
+ y2_lo = mem[3];
+ y1_hi = mem[4];
+ y1_lo = mem[5];
+ x0 = mem[6];
+ x1 = mem[7];
+ x2 = mem[8];
+
+ for (i = 0; i < lg; i++)
+ {
+ x3 = x2;
+ x2 = x1;
+ x1 = x0;
+ x0 = wsp[i];
+ /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2] + b[3]*x[i-3] */
+ /* + a[1]*y[i-1] + a[2] * y[i-2] + a[3]*y[i-3] */
+
+ L_tmp = 16384L; /* rounding to maximise precision */
+ L_tmp += (y1_lo * a[1])<<1;
+ L_tmp += (y2_lo * a[2])<<1;
+ L_tmp += (y3_lo * a[3])<<1;
+ L_tmp = L_tmp >> 15;
+ L_tmp += (y1_hi * a[1])<<1;
+ L_tmp += (y2_hi * a[2])<<1;
+ L_tmp += (y3_hi * a[3])<<1;
+ L_tmp += (x0 * b[0])<<1;
+ L_tmp += (x1 * b[1])<<1;
+ L_tmp += (x2 * b[2])<<1;
+ L_tmp += (x3 * b[3])<<1;
+
+ L_tmp = L_tmp << 2;
+
+ y3_hi = y2_hi;
+ y3_lo = y2_lo;
+ y2_hi = y1_hi;
+ y2_lo = y1_lo;
+ y1_hi = L_tmp >> 16;
+ y1_lo = (L_tmp & 0xffff) >>1;
+
+ hp_wsp[i] = (L_tmp + 0x4000)>>15;
+ }
+
+ mem[0] = y3_hi;
+ mem[1] = y3_lo;
+ mem[2] = y2_hi;
+ mem[3] = y2_lo;
+ mem[4] = y1_hi;
+ mem[5] = y1_lo;
+ mem[6] = x0;
+ mem[7] = x1;
+ mem[8] = x2;
+
+ return;
+}
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/int_lpc.c b/media/libstagefright/codecs/amrwbenc/src/int_lpc.c
new file mode 100644
index 0000000..be1fd0b
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/int_lpc.c
@@ -0,0 +1,66 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: int_lpc.c *
+* *
+* Description:Interpolation of the LP parameters in 4 subframes. *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "cnst.h"
+#include "acelp.h"
+
+#define MP1 (M+1)
+
+
+void Int_isp(
+ Word16 isp_old[], /* input : isps from past frame */
+ Word16 isp_new[], /* input : isps from present frame */
+ Word16 frac[], /* input : fraction for 3 first subfr (Q15) */
+ Word16 Az[] /* output: LP coefficients in 4 subframes */
+ )
+{
+ Word32 i, k;
+ Word16 fac_old, fac_new;
+ Word16 isp[M];
+ Word32 L_tmp;
+
+ for (k = 0; k < 3; k++)
+ {
+ fac_new = frac[k];
+ fac_old = (32767 - fac_new) + 1; /* 1.0 - fac_new */
+
+ for (i = 0; i < M; i++)
+ {
+ L_tmp = (isp_old[i] * fac_old)<<1;
+ L_tmp += (isp_new[i] * fac_new)<<1;
+ isp[i] = (L_tmp + 0x8000)>>16;
+ }
+ Isp_Az(isp, Az, M, 0);
+ Az += MP1;
+ }
+
+ /* 4th subframe: isp_new (frac=1.0) */
+ Isp_Az(isp_new, Az, M, 0);
+
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/isp_az.c b/media/libstagefright/codecs/amrwbenc/src/isp_az.c
new file mode 100644
index 0000000..7b44d12
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/isp_az.c
@@ -0,0 +1,247 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: isp_az.c *
+* *
+* Description:Compute the LPC coefficients from isp (order=M) *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "cnst.h"
+
+#define NC (M/2)
+#define NC16k (M16k/2)
+
+/* local function */
+
+static void Get_isp_pol(Word16 * isp, Word32 * f, Word16 n);
+static void Get_isp_pol_16kHz(Word16 * isp, Word32 * f, Word16 n);
+
+void Isp_Az(
+ Word16 isp[], /* (i) Q15 : Immittance spectral pairs */
+ Word16 a[], /* (o) Q12 : predictor coefficients (order = M) */
+ Word16 m,
+ Word16 adaptive_scaling /* (i) 0 : adaptive scaling disabled */
+ /* 1 : adaptive scaling enabled */
+ )
+{
+ Word32 i, j;
+ Word16 hi, lo;
+ Word32 f1[NC16k + 1], f2[NC16k];
+ Word16 nc;
+ Word32 t0;
+ Word16 q, q_sug;
+ Word32 tmax;
+
+ nc = (m >> 1);
+ if(nc > 8)
+ {
+ Get_isp_pol_16kHz(&isp[0], f1, nc);
+ for (i = 0; i <= nc; i++)
+ {
+ f1[i] = f1[i] << 2;
+ }
+ } else
+ Get_isp_pol(&isp[0], f1, nc);
+
+ if (nc > 8)
+ {
+ Get_isp_pol_16kHz(&isp[1], f2, (nc - 1));
+ for (i = 0; i <= nc - 1; i++)
+ {
+ f2[i] = f2[i] << 2;
+ }
+ } else
+ Get_isp_pol(&isp[1], f2, (nc - 1));
+
+ /*-----------------------------------------------------*
+ * Multiply F2(z) by (1 - z^-2) *
+ *-----------------------------------------------------*/
+
+ for (i = (nc - 1); i > 1; i--)
+ {
+ f2[i] = vo_L_sub(f2[i], f2[i - 2]); /* f2[i] -= f2[i-2]; */
+ }
+
+ /*----------------------------------------------------------*
+ * Scale F1(z) by (1+isp[m-1]) and F2(z) by (1-isp[m-1]) *
+ *----------------------------------------------------------*/
+
+ for (i = 0; i < nc; i++)
+ {
+ /* f1[i] *= (1.0 + isp[M-1]); */
+
+ hi = f1[i] >> 16;
+ lo = (f1[i] & 0xffff)>>1;
+
+ t0 = Mpy_32_16(hi, lo, isp[m - 1]);
+ f1[i] = vo_L_add(f1[i], t0);
+
+ /* f2[i] *= (1.0 - isp[M-1]); */
+
+ hi = f2[i] >> 16;
+ lo = (f2[i] & 0xffff)>>1;
+ t0 = Mpy_32_16(hi, lo, isp[m - 1]);
+ f2[i] = vo_L_sub(f2[i], t0);
+ }
+
+ /*-----------------------------------------------------*
+ * A(z) = (F1(z)+F2(z))/2 *
+ * F1(z) is symmetric and F2(z) is antisymmetric *
+ *-----------------------------------------------------*/
+
+ /* a[0] = 1.0; */
+ a[0] = 4096;
+ tmax = 1;
+ for (i = 1, j = m - 1; i < nc; i++, j--)
+ {
+ /* a[i] = 0.5*(f1[i] + f2[i]); */
+
+ t0 = vo_L_add(f1[i], f2[i]); /* f1[i] + f2[i] */
+ tmax |= L_abs(t0);
+ a[i] = (Word16)(vo_L_shr_r(t0, 12)); /* from Q23 to Q12 and * 0.5 */
+
+ /* a[j] = 0.5*(f1[i] - f2[i]); */
+
+ t0 = vo_L_sub(f1[i], f2[i]); /* f1[i] - f2[i] */
+ tmax |= L_abs(t0);
+ a[j] = (Word16)(vo_L_shr_r(t0, 12)); /* from Q23 to Q12 and * 0.5 */
+ }
+
+ /* rescale data if overflow has occured and reprocess the loop */
+ if(adaptive_scaling == 1)
+ q = 4 - norm_l(tmax); /* adaptive scaling enabled */
+ else
+ q = 0; /* adaptive scaling disabled */
+
+ if (q > 0)
+ {
+ q_sug = (12 + q);
+ for (i = 1, j = m - 1; i < nc; i++, j--)
+ {
+ /* a[i] = 0.5*(f1[i] + f2[i]); */
+ t0 = vo_L_add(f1[i], f2[i]); /* f1[i] + f2[i] */
+ a[i] = (Word16)(vo_L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */
+
+ /* a[j] = 0.5*(f1[i] - f2[i]); */
+ t0 = vo_L_sub(f1[i], f2[i]); /* f1[i] - f2[i] */
+ a[j] = (Word16)(vo_L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */
+ }
+ a[0] = shr(a[0], q);
+ }
+ else
+ {
+ q_sug = 12;
+ q = 0;
+ }
+ /* a[NC] = 0.5*f1[NC]*(1.0 + isp[M-1]); */
+ hi = f1[nc] >> 16;
+ lo = (f1[nc] & 0xffff)>>1;
+ t0 = Mpy_32_16(hi, lo, isp[m - 1]);
+ t0 = vo_L_add(f1[nc], t0);
+ a[nc] = (Word16)(L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */
+ /* a[m] = isp[m-1]; */
+
+ a[m] = vo_shr_r(isp[m - 1], (3 + q)); /* from Q15 to Q12 */
+ return;
+}
+
+/*-----------------------------------------------------------*
+* procedure Get_isp_pol: *
+* ~~~~~~~~~~~ *
+* Find the polynomial F1(z) or F2(z) from the ISPs. *
+* This is performed by expanding the product polynomials: *
+* *
+* F1(z) = product ( 1 - 2 isp_i z^-1 + z^-2 ) *
+* i=0,2,4,6,8 *
+* F2(z) = product ( 1 - 2 isp_i z^-1 + z^-2 ) *
+* i=1,3,5,7 *
+* *
+* where isp_i are the ISPs in the cosine domain. *
+*-----------------------------------------------------------*
+* *
+* Parameters: *
+* isp[] : isp vector (cosine domaine) in Q15 *
+* f[] : the coefficients of F1 or F2 in Q23 *
+* n : == NC for F1(z); == NC-1 for F2(z) *
+*-----------------------------------------------------------*/
+
+static void Get_isp_pol(Word16 * isp, Word32 * f, Word16 n)
+{
+ Word16 hi, lo;
+ Word32 i, j, t0;
+ /* All computation in Q23 */
+
+ f[0] = vo_L_mult(4096, 1024); /* f[0] = 1.0; in Q23 */
+ f[1] = vo_L_mult(isp[0], -256); /* f[1] = -2.0*isp[0] in Q23 */
+
+ f += 2; /* Advance f pointer */
+ isp += 2; /* Advance isp pointer */
+ for (i = 2; i <= n; i++)
+ {
+ *f = f[-2];
+ for (j = 1; j < i; j++, f--)
+ {
+ hi = f[-1]>>16;
+ lo = (f[-1] & 0xffff)>>1;
+
+ t0 = Mpy_32_16(hi, lo, *isp); /* t0 = f[-1] * isp */
+ t0 = t0 << 1;
+ *f = vo_L_sub(*f, t0); /* *f -= t0 */
+ *f = vo_L_add(*f, f[-2]); /* *f += f[-2] */
+ }
+ *f -= (*isp << 9); /* *f -= isp<<8 */
+ f += i; /* Advance f pointer */
+ isp += 2; /* Advance isp pointer */
+ }
+ return;
+}
+
+static void Get_isp_pol_16kHz(Word16 * isp, Word32 * f, Word16 n)
+{
+ Word16 hi, lo;
+ Word32 i, j, t0;
+
+ /* All computation in Q23 */
+ f[0] = L_mult(4096, 256); /* f[0] = 1.0; in Q23 */
+ f[1] = L_mult(isp[0], -64); /* f[1] = -2.0*isp[0] in Q23 */
+
+ f += 2; /* Advance f pointer */
+ isp += 2; /* Advance isp pointer */
+
+ for (i = 2; i <= n; i++)
+ {
+ *f = f[-2];
+ for (j = 1; j < i; j++, f--)
+ {
+ VO_L_Extract(f[-1], &hi, &lo);
+ t0 = Mpy_32_16(hi, lo, *isp); /* t0 = f[-1] * isp */
+ t0 = L_shl2(t0, 1);
+ *f = L_sub(*f, t0); /* *f -= t0 */
+ *f = L_add(*f, f[-2]); /* *f += f[-2] */
+ }
+ *f = L_msu(*f, *isp, 64); /* *f -= isp<<8 */
+ f += i; /* Advance f pointer */
+ isp += 2; /* Advance isp pointer */
+ }
+ return;
+}
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/isp_isf.c b/media/libstagefright/codecs/amrwbenc/src/isp_isf.c
new file mode 100644
index 0000000..6c6e389
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/isp_isf.c
@@ -0,0 +1,91 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: isp_isf.c *
+* *
+* Description: *
+* Isp_isf Transformation isp to isf *
+* Isf_isp Transformation isf to isp *
+* *
+* The transformation from isp[i] to isf[i] and isf[i] to isp[i] *
+* are approximated by a look-up table and interpolation *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "isp_isf.tab" /* Look-up table for transformations */
+
+void Isp_isf(
+ Word16 isp[], /* (i) Q15 : isp[m] (range: -1<=val<1) */
+ Word16 isf[], /* (o) Q15 : isf[m] normalized (range: 0.0<=val<=0.5) */
+ Word16 m /* (i) : LPC order */
+ )
+{
+ Word32 i, ind;
+ Word32 L_tmp;
+ ind = 127; /* beging at end of table -1 */
+ for (i = (m - 1); i >= 0; i--)
+ {
+ if (i >= (m - 2))
+ { /* m-2 is a constant */
+ ind = 127; /* beging at end of table -1 */
+ }
+ /* find value in table that is just greater than isp[i] */
+ while (table[ind] < isp[i])
+ ind--;
+ /* acos(isp[i])= ind*128 + ( ( isp[i]-table[ind] ) * slope[ind] )/2048 */
+ L_tmp = vo_L_mult(vo_sub(isp[i], table[ind]), slope[ind]);
+ isf[i] = vo_round((L_tmp << 4)); /* (isp[i]-table[ind])*slope[ind])>>11 */
+ isf[i] = add1(isf[i], (ind << 7));
+ }
+ isf[m - 1] = (isf[m - 1] >> 1);
+ return;
+}
+
+
+void Isf_isp(
+ Word16 isf[], /* (i) Q15 : isf[m] normalized (range: 0.0<=val<=0.5) */
+ Word16 isp[], /* (o) Q15 : isp[m] (range: -1<=val<1) */
+ Word16 m /* (i) : LPC order */
+ )
+{
+ Word16 offset;
+ Word32 i, ind, L_tmp;
+
+ for (i = 0; i < m - 1; i++)
+ {
+ isp[i] = isf[i];
+ }
+ isp[m - 1] = (isf[m - 1] << 1);
+
+ for (i = 0; i < m; i++)
+ {
+ ind = (isp[i] >> 7); /* ind = b7-b15 of isf[i] */
+ offset = (Word16) (isp[i] & 0x007f); /* offset = b0-b6 of isf[i] */
+
+ /* isp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 128 */
+ L_tmp = vo_L_mult(vo_sub(table[ind + 1], table[ind]), offset);
+ isp[i] = add1(table[ind], (Word16)((L_tmp >> 8)));
+ }
+
+ return;
+}
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/lag_wind.c b/media/libstagefright/codecs/amrwbenc/src/lag_wind.c
new file mode 100644
index 0000000..0397704
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/lag_wind.c
@@ -0,0 +1,49 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: lag_wind.c *
+* *
+* Description: Lag_windows on autocorrelations *
+* r[i] *= lag_wind[i] *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "lag_wind.tab"
+
+
+void Lag_window(
+ Word16 r_h[], /* (i/o) : Autocorrelations (msb) */
+ Word16 r_l[] /* (i/o) : Autocorrelations (lsb) */
+ )
+{
+ Word32 i;
+ Word32 x;
+
+ for (i = 1; i <= M; i++)
+ {
+ x = Mpy_32(r_h[i], r_l[i], volag_h[i - 1], volag_l[i - 1]);
+ r_h[i] = x >> 16;
+ r_l[i] = (x & 0xffff)>>1;
+ }
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/levinson.c b/media/libstagefright/codecs/amrwbenc/src/levinson.c
new file mode 100644
index 0000000..8bc6f62
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/levinson.c
@@ -0,0 +1,250 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: levinson.c *
+* *
+* Description:LEVINSON-DURBIN algorithm in double precision *
+* *
+************************************************************************/
+/*---------------------------------------------------------------------------*
+ * LEVINSON.C *
+ *---------------------------------------------------------------------------*
+ * *
+ * LEVINSON-DURBIN algorithm in double precision *
+ * *
+ * *
+ * Algorithm *
+ * *
+ * R[i] autocorrelations. *
+ * A[i] filter coefficients. *
+ * K reflection coefficients. *
+ * Alpha prediction gain. *
+ * *
+ * Initialization: *
+ * A[0] = 1 *
+ * K = -R[1]/R[0] *
+ * A[1] = K *
+ * Alpha = R[0] * (1-K**2] *
+ * *
+ * Do for i = 2 to M *
+ * *
+ * S = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] *
+ * *
+ * K = -S / Alpha *
+ * *
+ * An[j] = A[j] + K*A[i-j] for j=1 to i-1 *
+ * where An[i] = new A[i] *
+ * An[i]=K *
+ * *
+ * Alpha=Alpha * (1-K**2) *
+ * *
+ * END *
+ * *
+ * Remarks on the dynamics of the calculations. *
+ * *
+ * The numbers used are in double precision in the following format : *
+ * A = AH <<16 + AL<<1. AH and AL are 16 bit signed integers. *
+ * Since the LSB's also contain a sign bit, this format does not *
+ * correspond to standard 32 bit integers. We use this format since *
+ * it allows fast execution of multiplications and divisions. *
+ * *
+ * "DPF" will refer to this special format in the following text. *
+ * See oper_32b.c *
+ * *
+ * The R[i] were normalized in routine AUTO (hence, R[i] < 1.0). *
+ * The K[i] and Alpha are theoretically < 1.0. *
+ * The A[i], for a sampling frequency of 8 kHz, are in practice *
+ * always inferior to 16.0. *
+ * *
+ * These characteristics allow straigthforward fixed-point *
+ * implementation. We choose to represent the parameters as *
+ * follows : *
+ * *
+ * R[i] Q31 +- .99.. *
+ * K[i] Q31 +- .99.. *
+ * Alpha Normalized -> mantissa in Q31 plus exponent *
+ * A[i] Q27 +- 15.999.. *
+ * *
+ * The additions are performed in 32 bit. For the summation used *
+ * to calculate the K[i], we multiply numbers in Q31 by numbers *
+ * in Q27, with the result of the multiplications in Q27, *
+ * resulting in a dynamic of +- 16. This is sufficient to avoid *
+ * overflow, since the final result of the summation is *
+ * necessarily < 1.0 as both the K[i] and Alpha are *
+ * theoretically < 1.0. *
+ *___________________________________________________________________________*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "acelp.h"
+
+#define M 16
+#define NC (M/2)
+
+void Init_Levinson(
+ Word16 * mem /* output :static memory (18 words) */
+ )
+{
+ Set_zero(mem, 18); /* old_A[0..M-1] = 0, old_rc[0..1] = 0 */
+ return;
+}
+
+
+void Levinson(
+ Word16 Rh[], /* (i) : Rh[M+1] Vector of autocorrelations (msb) */
+ Word16 Rl[], /* (i) : Rl[M+1] Vector of autocorrelations (lsb) */
+ Word16 A[], /* (o) Q12 : A[M] LPC coefficients (m = 16) */
+ Word16 rc[], /* (o) Q15 : rc[M] Reflection coefficients. */
+ Word16 * mem /* (i/o) :static memory (18 words) */
+ )
+{
+ Word32 i, j;
+ Word16 hi, lo;
+ Word16 Kh, Kl; /* reflection coefficient; hi and lo */
+ Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */
+ Word16 Ah[M + 1], Al[M + 1]; /* LPC coef. in double prec. */
+ Word16 Anh[M + 1], Anl[M + 1]; /* LPC coef.for next iteration in double prec. */
+ Word32 t0, t1, t2; /* temporary variable */
+ Word16 *old_A, *old_rc;
+
+ /* Last A(z) for case of unstable filter */
+ old_A = mem;
+ old_rc = mem + M;
+
+ /* K = A[1] = -R[1] / R[0] */
+
+ t1 = ((Rh[1] << 16) + (Rl[1] << 1)); /* R[1] in Q31 */
+ t2 = L_abs(t1); /* abs R[1] */
+ t0 = Div_32(t2, Rh[0], Rl[0]); /* R[1]/R[0] in Q31 */
+ if (t1 > 0)
+ t0 = -t0; /* -R[1]/R[0] */
+
+ Kh = t0 >> 16;
+ Kl = (t0 & 0xffff)>>1;
+ rc[0] = Kh;
+ t0 = (t0 >> 4); /* A[1] in Q27 */
+
+ Ah[1] = t0 >> 16;
+ Al[1] = (t0 & 0xffff)>>1;
+
+ /* Alpha = R[0] * (1-K**2) */
+ t0 = Mpy_32(Kh, Kl, Kh, Kl); /* K*K in Q31 */
+ t0 = L_abs(t0); /* Some case <0 !! */
+ t0 = vo_L_sub((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */
+
+ hi = t0 >> 16;
+ lo = (t0 & 0xffff)>>1;
+
+ t0 = Mpy_32(Rh[0], Rl[0], hi, lo); /* Alpha in Q31 */
+
+ /* Normalize Alpha */
+ alp_exp = norm_l(t0);
+ t0 = (t0 << alp_exp);
+
+ alp_h = t0 >> 16;
+ alp_l = (t0 & 0xffff)>>1;
+ /*--------------------------------------*
+ * ITERATIONS I=2 to M *
+ *--------------------------------------*/
+ for (i = 2; i <= M; i++)
+ {
+ /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */
+ t0 = 0;
+ for (j = 1; j < i; j++)
+ t0 = vo_L_add(t0, Mpy_32(Rh[j], Rl[j], Ah[i - j], Al[i - j]));
+
+ t0 = t0 << 4; /* result in Q27 -> convert to Q31 */
+ /* No overflow possible */
+ t1 = ((Rh[i] << 16) + (Rl[i] << 1));
+ t0 = vo_L_add(t0, t1); /* add R[i] in Q31 */
+
+ /* K = -t0 / Alpha */
+ t1 = L_abs(t0);
+ t2 = Div_32(t1, alp_h, alp_l); /* abs(t0)/Alpha */
+ if (t0 > 0)
+ t2 = -t2; /* K =-t0/Alpha */
+ t2 = (t2 << alp_exp); /* denormalize; compare to Alpha */
+
+ Kh = t2 >> 16;
+ Kl = (t2 & 0xffff)>>1;
+
+ rc[i - 1] = Kh;
+ /* Test for unstable filter. If unstable keep old A(z) */
+ if (abs_s(Kh) > 32750)
+ {
+ A[0] = 4096; /* Ai[0] not stored (always 1.0) */
+ for (j = 0; j < M; j++)
+ {
+ A[j + 1] = old_A[j];
+ }
+ rc[0] = old_rc[0]; /* only two rc coefficients are needed */
+ rc[1] = old_rc[1];
+ return;
+ }
+ /*------------------------------------------*
+ * Compute new LPC coeff. -> An[i] *
+ * An[j]= A[j] + K*A[i-j] , j=1 to i-1 *
+ * An[i]= K *
+ *------------------------------------------*/
+ for (j = 1; j < i; j++)
+ {
+ t0 = Mpy_32(Kh, Kl, Ah[i - j], Al[i - j]);
+ t0 = vo_L_add(t0, ((Ah[j] << 16) + (Al[j] << 1)));
+ Anh[j] = t0 >> 16;
+ Anl[j] = (t0 & 0xffff)>>1;
+ }
+ t2 = (t2 >> 4); /* t2 = K in Q31 ->convert to Q27 */
+
+ VO_L_Extract(t2, &Anh[i], &Anl[i]); /* An[i] in Q27 */
+
+ /* Alpha = Alpha * (1-K**2) */
+ t0 = Mpy_32(Kh, Kl, Kh, Kl); /* K*K in Q31 */
+ t0 = L_abs(t0); /* Some case <0 !! */
+ t0 = vo_L_sub((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */
+ hi = t0 >> 16;
+ lo = (t0 & 0xffff)>>1;
+ t0 = Mpy_32(alp_h, alp_l, hi, lo); /* Alpha in Q31 */
+
+ /* Normalize Alpha */
+ j = norm_l(t0);
+ t0 = (t0 << j);
+ alp_h = t0 >> 16;
+ alp_l = (t0 & 0xffff)>>1;
+ alp_exp += j; /* Add normalization to alp_exp */
+
+ /* A[j] = An[j] */
+ for (j = 1; j <= i; j++)
+ {
+ Ah[j] = Anh[j];
+ Al[j] = Anl[j];
+ }
+ }
+ /* Truncate A[i] in Q27 to Q12 with rounding */
+ A[0] = 4096;
+ for (i = 1; i <= M; i++)
+ {
+ t0 = (Ah[i] << 16) + (Al[i] << 1);
+ old_A[i - 1] = A[i] = vo_round((t0 << 1));
+ }
+ old_rc[0] = rc[0];
+ old_rc[1] = rc[1];
+
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/log2.c b/media/libstagefright/codecs/amrwbenc/src/log2.c
new file mode 100644
index 0000000..cd3d815
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/log2.c
@@ -0,0 +1,111 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* *
+* File : log2.c *
+* Purpose : Computes log2(L_x) *
+* *
+************************************************************************/
+
+#include "log2.h"
+/********************************************************************************
+* INCLUDE FILES
+*********************************************************************************/
+#include "typedef.h"
+#include "basic_op.h"
+
+/*********************************************************************************
+* LOCAL VARIABLES AND TABLES
+**********************************************************************************/
+#include "log2_tab.h" /* Table for Log2() */
+
+/*************************************************************************
+*
+* FUNCTION: Log2_norm()
+*
+* PURPOSE: Computes log2(L_x, exp), where L_x is positive and
+* normalized, and exp is the normalisation exponent
+* If L_x is negative or zero, the result is 0.
+*
+* DESCRIPTION:
+* The function Log2(L_x) is approximated by a table and linear
+* interpolation. The following steps are used to compute Log2(L_x)
+*
+* 1- exponent = 30-norm_exponent
+* 2- i = bit25-b31 of L_x; 32<=i<=63 (because of normalization).
+* 3- a = bit10-b24
+* 4- i -=32
+* 5- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
+*
+*************************************************************************/
+
+void Log2_norm (
+ Word32 L_x, /* (i) : input value (normalized) */
+ Word16 exp, /* (i) : norm_l (L_x) */
+ Word16 *exponent, /* (o) : Integer part of Log2. (range: 0<=val<=30) */
+ Word16 *fraction /* (o) : Fractional part of Log2. (range: 0<=val<1) */
+ )
+{
+ Word16 i, a, tmp;
+ Word32 L_y;
+ if (L_x <= (Word32) 0)
+ {
+ *exponent = 0;
+ *fraction = 0;
+ return;
+ }
+ *exponent = (30 - exp);
+ L_x = (L_x >> 9);
+ i = extract_h (L_x); /* Extract b25-b31 */
+ L_x = (L_x >> 1);
+ a = (Word16)(L_x); /* Extract b10-b24 of fraction */
+ a = (Word16)(a & (Word16)0x7fff);
+ i -= 32;
+ L_y = L_deposit_h (table[i]); /* table[i] << 16 */
+ tmp = vo_sub(table[i], table[i + 1]); /* table[i] - table[i+1] */
+ L_y = vo_L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */
+ *fraction = extract_h (L_y);
+
+ return;
+}
+
+/*************************************************************************
+*
+* FUNCTION: Log2()
+*
+* PURPOSE: Computes log2(L_x), where L_x is positive.
+* If L_x is negative or zero, the result is 0.
+*
+* DESCRIPTION:
+* normalizes L_x and then calls Log2_norm().
+*
+*************************************************************************/
+
+void Log2 (
+ Word32 L_x, /* (i) : input value */
+ Word16 *exponent, /* (o) : Integer part of Log2. (range: 0<=val<=30) */
+ Word16 *fraction /* (o) : Fractional part of Log2. (range: 0<=val<1) */
+ )
+{
+ Word16 exp;
+
+ exp = norm_l(L_x);
+ Log2_norm ((L_x << exp), exp, exponent, fraction);
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/lp_dec2.c b/media/libstagefright/codecs/amrwbenc/src/lp_dec2.c
new file mode 100644
index 0000000..63b746b
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/lp_dec2.c
@@ -0,0 +1,70 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: lp_dec2.c *
+* *
+* Description:Decimate a vector by 2 with 2nd order fir filter *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "cnst.h"
+
+#define L_FIR 5
+#define L_MEM (L_FIR-2)
+
+/* static float h_fir[L_FIR] = {0.13, 0.23, 0.28, 0.23, 0.13}; */
+/* fixed-point: sum of coef = 32767 to avoid overflow on DC */
+static Word16 h_fir[L_FIR] = {4260, 7536, 9175, 7536, 4260};
+
+void LP_Decim2(
+ Word16 x[], /* in/out: signal to process */
+ Word16 l, /* input : size of filtering */
+ Word16 mem[] /* in/out: memory (size=3) */
+ )
+{
+ Word16 *p_x, x_buf[L_FRAME + L_MEM];
+ Word32 i, j;
+ Word32 L_tmp;
+ /* copy initial filter states into buffer */
+ p_x = x_buf;
+ for (i = 0; i < L_MEM; i++)
+ {
+ *p_x++ = mem[i];
+ mem[i] = x[l - L_MEM + i];
+ }
+ for (i = 0; i < l; i++)
+ {
+ *p_x++ = x[i];
+ }
+ for (i = 0, j = 0; i < l; i += 2, j++)
+ {
+ p_x = &x_buf[i];
+ L_tmp = ((*p_x++) * h_fir[0]);
+ L_tmp += ((*p_x++) * h_fir[1]);
+ L_tmp += ((*p_x++) * h_fir[2]);
+ L_tmp += ((*p_x++) * h_fir[3]);
+ L_tmp += ((*p_x++) * h_fir[4]);
+ x[j] = (L_tmp + 0x4000)>>15;
+ }
+ return;
+}
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/math_op.c b/media/libstagefright/codecs/amrwbenc/src/math_op.c
new file mode 100644
index 0000000..1c95ed0
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/math_op.c
@@ -0,0 +1,219 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/*___________________________________________________________________________
+| |
+| This file contains mathematic operations in fixed point. |
+| |
+| Isqrt() : inverse square root (16 bits precision). |
+| Pow2() : 2^x (16 bits precision). |
+| Log2() : log2 (16 bits precision). |
+| Dot_product() : scalar product of <x[],y[]> |
+| |
+| These operations are not standard double precision operations. |
+| They are used where low complexity is important and the full 32 bits |
+| precision is not necessary. For example, the function Div_32() has a |
+| 24 bits precision which is enough for our purposes. |
+| |
+| In this file, the values use theses representations: |
+| |
+| Word32 L_32 : standard signed 32 bits format |
+| Word16 hi, lo : L_32 = hi<<16 + lo<<1 (DPF - Double Precision Format) |
+| Word32 frac, Word16 exp : L_32 = frac << exp-31 (normalised format) |
+| Word16 int, frac : L_32 = int.frac (fractional format) |
+|___________________________________________________________________________|
+*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+
+/*___________________________________________________________________________
+| |
+| Function Name : Isqrt |
+| |
+| Compute 1/sqrt(L_x). |
+| if L_x is negative or zero, result is 1 (7fffffff). |
+|---------------------------------------------------------------------------|
+| Algorithm: |
+| |
+| 1- Normalization of L_x. |
+| 2- call Isqrt_n(L_x, exponant) |
+| 3- L_y = L_x << exponant |
+|___________________________________________________________________________|
+*/
+Word32 Isqrt( /* (o) Q31 : output value (range: 0<=val<1) */
+ Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */
+ )
+{
+ Word16 exp;
+ Word32 L_y;
+ exp = norm_l(L_x);
+ L_x = (L_x << exp); /* L_x is normalized */
+ exp = (31 - exp);
+ Isqrt_n(&L_x, &exp);
+ L_y = (L_x << exp); /* denormalization */
+ return (L_y);
+}
+
+/*___________________________________________________________________________
+| |
+| Function Name : Isqrt_n |
+| |
+| Compute 1/sqrt(value). |
+| if value is negative or zero, result is 1 (frac=7fffffff, exp=0). |
+|---------------------------------------------------------------------------|
+| Algorithm: |
+| |
+| The function 1/sqrt(value) is approximated by a table and linear |
+| interpolation. |
+| |
+| 1- If exponant is odd then shift fraction right once. |
+| 2- exponant = -((exponant-1)>>1) |
+| 3- i = bit25-b30 of fraction, 16 <= i <= 63 ->because of normalization. |
+| 4- a = bit10-b24 |
+| 5- i -=16 |
+| 6- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 |
+|___________________________________________________________________________|
+*/
+static Word16 table_isqrt[49] =
+{
+ 32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214,
+ 25705, 25225, 24770, 24339, 23930, 23541, 23170, 22817, 22479, 22155,
+ 21845, 21548, 21263, 20988, 20724, 20470, 20225, 19988, 19760, 19539,
+ 19326, 19119, 18919, 18725, 18536, 18354, 18176, 18004, 17837, 17674,
+ 17515, 17361, 17211, 17064, 16921, 16782, 16646, 16514, 16384
+};
+
+void Isqrt_n(
+ Word32 * frac, /* (i/o) Q31: normalized value (1.0 < frac <= 0.5) */
+ Word16 * exp /* (i/o) : exponent (value = frac x 2^exponent) */
+ )
+{
+ Word16 i, a, tmp;
+
+ if (*frac <= (Word32) 0)
+ {
+ *exp = 0;
+ *frac = 0x7fffffffL;
+ return;
+ }
+
+ if((*exp & 1) == 1) /*If exponant odd -> shift right */
+ *frac = (*frac) >> 1;
+
+ *exp = negate((*exp - 1) >> 1);
+
+ *frac = (*frac >> 9);
+ i = extract_h(*frac); /* Extract b25-b31 */
+ *frac = (*frac >> 1);
+ a = (Word16)(*frac); /* Extract b10-b24 */
+ a = (Word16) (a & (Word16) 0x7fff);
+ i -= 16;
+ *frac = L_deposit_h(table_isqrt[i]); /* table[i] << 16 */
+ tmp = vo_sub(table_isqrt[i], table_isqrt[i + 1]); /* table[i] - table[i+1]) */
+ *frac = vo_L_msu(*frac, tmp, a); /* frac -= tmp*a*2 */
+
+ return;
+}
+
+/*___________________________________________________________________________
+| |
+| Function Name : Pow2() |
+| |
+| L_x = pow(2.0, exponant.fraction) (exponant = interger part) |
+| = pow(2.0, 0.fraction) << exponant |
+|---------------------------------------------------------------------------|
+| Algorithm: |
+| |
+| The function Pow2(L_x) is approximated by a table and linear |
+| interpolation. |
+| |
+| 1- i = bit10-b15 of fraction, 0 <= i <= 31 |
+| 2- a = bit0-b9 of fraction |
+| 3- L_x = table[i]<<16 - (table[i] - table[i+1]) * a * 2 |
+| 4- L_x = L_x >> (30-exponant) (with rounding) |
+|___________________________________________________________________________|
+*/
+static Word16 table_pow2[33] =
+{
+ 16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911,
+ 20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726,
+ 25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706,
+ 31379, 32066, 32767
+};
+
+Word32 Pow2( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */
+ Word16 exponant, /* (i) Q0 : Integer part. (range: 0<=val<=30) */
+ Word16 fraction /* (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */
+ )
+{
+ Word16 exp, i, a, tmp;
+ Word32 L_x;
+
+ L_x = vo_L_mult(fraction, 32); /* L_x = fraction<<6 */
+ i = extract_h(L_x); /* Extract b10-b16 of fraction */
+ L_x =L_x >> 1;
+ a = (Word16)(L_x); /* Extract b0-b9 of fraction */
+ a = (Word16) (a & (Word16) 0x7fff);
+
+ L_x = L_deposit_h(table_pow2[i]); /* table[i] << 16 */
+ tmp = vo_sub(table_pow2[i], table_pow2[i + 1]); /* table[i] - table[i+1] */
+ L_x -= (tmp * a)<<1; /* L_x -= tmp*a*2 */
+
+ exp = vo_sub(30, exponant);
+ L_x = vo_L_shr_r(L_x, exp);
+
+ return (L_x);
+}
+
+/*___________________________________________________________________________
+| |
+| Function Name : Dot_product12() |
+| |
+| Compute scalar product of <x[],y[]> using accumulator. |
+| |
+| The result is normalized (in Q31) with exponent (0..30). |
+|---------------------------------------------------------------------------|
+| Algorithm: |
+| |
+| dot_product = sum(x[i]*y[i]) i=0..N-1 |
+|___________________________________________________________________________|
+*/
+
+Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */
+ Word16 x[], /* (i) 12bits: x vector */
+ Word16 y[], /* (i) 12bits: y vector */
+ Word16 lg, /* (i) : vector length */
+ Word16 * exp /* (o) : exponent of result (0..+30) */
+ )
+{
+ Word16 sft;
+ Word32 i, L_sum;
+ L_sum = 0;
+ for (i = 0; i < lg; i++)
+ {
+ L_sum += x[i] * y[i];
+ }
+ L_sum = (L_sum << 1) + 1;
+ /* Normalize acc in Q31 */
+ sft = norm_l(L_sum);
+ L_sum = L_sum << sft;
+ *exp = 30 - sft; /* exponent = 0..30 */
+ return (L_sum);
+
+}
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/mem_align.c b/media/libstagefright/codecs/amrwbenc/src/mem_align.c
new file mode 100644
index 0000000..e58915a
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/mem_align.c
@@ -0,0 +1,107 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/*******************************************************************************
+ File: mem_align.c
+
+ Content: Memory alloc alignments functions
+
+*******************************************************************************/
+
+
+#include "mem_align.h"
+
+/*****************************************************************************
+*
+* function name: mem_malloc
+* description: malloc the alignments memory
+* returns: the point of the memory
+*
+**********************************************************************************/
+void *
+mem_malloc(VO_MEM_OPERATOR *pMemop, unsigned int size, unsigned char alignment, unsigned int CodecID)
+{
+ int ret;
+ unsigned char *mem_ptr;
+ VO_MEM_INFO MemInfo;
+
+ if (!alignment) {
+
+ MemInfo.Flag = 0;
+ MemInfo.Size = size + 1;
+ ret = pMemop->Alloc(CodecID, &MemInfo);
+ if(ret != 0)
+ return 0;
+ mem_ptr = (unsigned char *)MemInfo.VBuffer;
+
+ pMemop->Set(CodecID, mem_ptr, 0, size + 1);
+
+ *mem_ptr = (unsigned char)1;
+
+ return ((void *)(mem_ptr+1));
+ } else {
+ unsigned char *tmp;
+
+ MemInfo.Flag = 0;
+ MemInfo.Size = size + alignment;
+ ret = pMemop->Alloc(CodecID, &MemInfo);
+ if(ret != 0)
+ return 0;
+
+ tmp = (unsigned char *)MemInfo.VBuffer;
+
+ pMemop->Set(CodecID, tmp, 0, size + alignment);
+
+ mem_ptr =
+ (unsigned char *) ((unsigned int) (tmp + alignment - 1) &
+ (~((unsigned int) (alignment - 1))));
+
+ if (mem_ptr == tmp)
+ mem_ptr += alignment;
+
+ *(mem_ptr - 1) = (unsigned char) (mem_ptr - tmp);
+
+ return ((void *)mem_ptr);
+ }
+
+ return(0);
+}
+
+
+/*****************************************************************************
+*
+* function name: mem_free
+* description: free the memory
+*
+*******************************************************************************/
+void
+mem_free(VO_MEM_OPERATOR *pMemop, void *mem_ptr, unsigned int CodecID)
+{
+
+ unsigned char *ptr;
+
+ if (mem_ptr == 0)
+ return;
+
+ ptr = mem_ptr;
+
+ ptr -= *(ptr - 1);
+
+ pMemop->Free(CodecID, ptr);
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/oper_32b.c b/media/libstagefright/codecs/amrwbenc/src/oper_32b.c
new file mode 100644
index 0000000..5f1523e
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/oper_32b.c
@@ -0,0 +1,223 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/*****************************************************************************
+ * This file contains operations in double precision. *
+ * These operations are not standard double precision operations. *
+ * They are used where single precision is not enough but the full 32 bits *
+ * precision is not necessary. For example, the function Div_32() has a *
+ * 24 bits precision which is enough for our purposes. *
+ * *
+ * The double precision numbers use a special representation: *
+ * *
+ * L_32 = hi<<16 + lo<<1 *
+ * *
+ * L_32 is a 32 bit integer. *
+ * hi and lo are 16 bit signed integers. *
+ * As the low part also contains the sign, this allows fast multiplication. *
+ * *
+ * 0x8000 0000 <= L_32 <= 0x7fff fffe. *
+ * *
+ * We will use DPF (Double Precision Format )in this file to specify *
+ * this special format. *
+ *****************************************************************************
+*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+
+/*****************************************************************************
+ * *
+ * Function L_Extract() *
+ * *
+ * Extract from a 32 bit integer two 16 bit DPF. *
+ * *
+ * Arguments: *
+ * *
+ * L_32 : 32 bit integer. *
+ * 0x8000 0000 <= L_32 <= 0x7fff ffff. *
+ * hi : b16 to b31 of L_32 *
+ * lo : (L_32 - hi<<16)>>1 *
+ *****************************************************************************
+*/
+
+__inline void VO_L_Extract (Word32 L_32, Word16 *hi, Word16 *lo)
+{
+ *hi = (Word16)(L_32 >> 16);
+ *lo = (Word16)((L_32 & 0xffff) >> 1);
+ return;
+}
+
+/*****************************************************************************
+ * *
+ * Function L_Comp() *
+ * *
+ * Compose from two 16 bit DPF a 32 bit integer. *
+ * *
+ * L_32 = hi<<16 + lo<<1 *
+ * *
+ * Arguments: *
+ * *
+ * hi msb *
+ * lo lsf (with sign) *
+ * *
+ * Return Value : *
+ * *
+ * 32 bit long signed integer (Word32) whose value falls in the *
+ * range : 0x8000 0000 <= L_32 <= 0x7fff fff0. *
+ * *
+ *****************************************************************************
+*/
+
+Word32 L_Comp (Word16 hi, Word16 lo)
+{
+ Word32 L_32;
+
+ L_32 = L_deposit_h (hi);
+
+ return (L_mac (L_32, lo, 1)); /* = hi<<16 + lo<<1 */
+}
+
+/*****************************************************************************
+ * Function Mpy_32() *
+ * *
+ * Multiply two 32 bit integers (DPF). The result is divided by 2**31 *
+ * *
+ * L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 *
+ * *
+ * This operation can also be viewed as the multiplication of two Q31 *
+ * number and the result is also in Q31. *
+ * *
+ * Arguments: *
+ * *
+ * hi1 hi part of first number *
+ * lo1 lo part of first number *
+ * hi2 hi part of second number *
+ * lo2 lo part of second number *
+ * *
+ *****************************************************************************
+*/
+
+__inline Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
+{
+ Word32 L_32;
+ L_32 = (hi1 * hi2);
+ L_32 += (hi1 * lo2) >> 15;
+ L_32 += (lo1 * hi2) >> 15;
+ L_32 <<= 1;
+
+ return (L_32);
+}
+
+/*****************************************************************************
+ * Function Mpy_32_16() *
+ * *
+ * Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
+ * by 2**15 *
+ * *
+ * *
+ * L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
+ * *
+ * Arguments: *
+ * *
+ * hi hi part of 32 bit number. *
+ * lo lo part of 32 bit number. *
+ * n 16 bit number. *
+ * *
+ *****************************************************************************
+*/
+
+__inline Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n)
+{
+ Word32 L_32;
+
+ L_32 = (hi * n)<<1;
+ L_32 += (((lo * n)>>15)<<1);
+
+ return (L_32);
+}
+
+/*****************************************************************************
+ * *
+ * Function Name : Div_32 *
+ * *
+ * Purpose : *
+ * Fractional integer division of two 32 bit numbers. *
+ * L_num / L_denom. *
+ * L_num and L_denom must be positive and L_num < L_denom. *
+ * L_denom = denom_hi<<16 + denom_lo<<1 *
+ * denom_hi is a normalize number. *
+ * *
+ * Inputs : *
+ * *
+ * L_num *
+ * 32 bit long signed integer (Word32) whose value falls in the *
+ * range : 0x0000 0000 < L_num < L_denom *
+ * *
+ * L_denom = denom_hi<<16 + denom_lo<<1 (DPF) *
+ * *
+ * denom_hi *
+ * 16 bit positive normalized integer whose value falls in the *
+ * range : 0x4000 < hi < 0x7fff *
+ * denom_lo *
+ * 16 bit positive integer whose value falls in the *
+ * range : 0 < lo < 0x7fff *
+ * *
+ * Return Value : *
+ * *
+ * L_div *
+ * 32 bit long signed integer (Word32) whose value falls in the *
+ * range : 0x0000 0000 <= L_div <= 0x7fff ffff. *
+ * *
+ * Algorithm: *
+ * *
+ * - find = 1/L_denom. *
+ * First approximation: approx = 1 / denom_hi *
+ * 1/L_denom = approx * (2.0 - L_denom * approx ) *
+ * *
+ * - result = L_num * (1/L_denom) *
+ *****************************************************************************
+*/
+
+Word32 Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo)
+{
+ Word16 approx, hi, lo, n_hi, n_lo;
+ Word32 L_32;
+
+ /* First approximation: 1 / L_denom = 1/denom_hi */
+
+ approx = div_s ((Word16) 0x3fff, denom_hi);
+
+ /* 1/L_denom = approx * (2.0 - L_denom * approx) */
+
+ L_32 = Mpy_32_16 (denom_hi, denom_lo, approx);
+
+ L_32 = L_sub ((Word32) 0x7fffffffL, L_32);
+ hi = L_32 >> 16;
+ lo = (L_32 & 0xffff) >> 1;
+
+ L_32 = Mpy_32_16 (hi, lo, approx);
+
+ /* L_num * (1/L_denom) */
+ hi = L_32 >> 16;
+ lo = (L_32 & 0xffff) >> 1;
+ VO_L_Extract (L_num, &n_hi, &n_lo);
+ L_32 = Mpy_32 (n_hi, n_lo, hi, lo);
+ L_32 = L_shl2(L_32, 2);
+
+ return (L_32);
+}
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c b/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c
new file mode 100644
index 0000000..39ee966
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c
@@ -0,0 +1,256 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: p_med_ol.c *
+* *
+* Description: Compute the open loop pitch lag *
+* output: open loop pitch lag *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "acelp.h"
+#include "oper_32b.h"
+#include "math_op.h"
+#include "p_med_ol.tab"
+
+Word16 Pitch_med_ol(
+ Word16 wsp[], /* i: signal used to compute the open loop pitch*/
+ /* wsp[-pit_max] to wsp[-1] should be known */
+ Coder_State *st, /* i/o: codec global structure */
+ Word16 L_frame /* i: length of frame to compute pitch */
+ )
+{
+ Word16 Tm;
+ Word16 hi, lo;
+ Word16 *ww, *we, *hp_wsp;
+ Word16 exp_R0, exp_R1, exp_R2;
+ Word32 i, j, max, R0, R1, R2;
+ Word16 *p1, *p2;
+ Word16 L_min = 17; /* minimum pitch lag: PIT_MIN / OPL_DECIM */
+ Word16 L_max = 115; /* maximum pitch lag: PIT_MAX / OPL_DECIM */
+ Word16 L_0 = st->old_T0_med; /* old open-loop pitch */
+ Word16 *gain = &(st->ol_gain); /* normalize correlation of hp_wsp for the lag */
+ Word16 *hp_wsp_mem = st->hp_wsp_mem; /* memory of the hypass filter for hp_wsp[] (lg = 9)*/
+ Word16 *old_hp_wsp = st->old_hp_wsp; /* hypass wsp[] */
+ Word16 wght_flg = st->ol_wght_flg; /* is weighting function used */
+
+ ww = &corrweight[198];
+ we = &corrweight[98 + L_max - L_0];
+
+ max = MIN_32;
+ Tm = 0;
+ for (i = L_max; i > L_min; i--)
+ {
+ /* Compute the correlation */
+ R0 = 0;
+ p1 = wsp;
+ p2 = &wsp[-i];
+ for (j = 0; j < L_frame; j+=4)
+ {
+ R0 += vo_L_mult((*p1++), (*p2++));
+ R0 += vo_L_mult((*p1++), (*p2++));
+ R0 += vo_L_mult((*p1++), (*p2++));
+ R0 += vo_L_mult((*p1++), (*p2++));
+ }
+ /* Weighting of the correlation function. */
+ hi = R0>>16;
+ lo = (R0 & 0xffff)>>1;
+
+ R0 = Mpy_32_16(hi, lo, *ww);
+ ww--;
+
+ if ((L_0 > 0) && (wght_flg > 0))
+ {
+ /* Weight the neighbourhood of the old lag. */
+ hi = R0>>16;
+ lo = (R0 & 0xffff)>>1;
+ R0 = Mpy_32_16(hi, lo, *we);
+ we--;
+ }
+ if(R0 >= max)
+ {
+ max = R0;
+ Tm = i;
+ }
+ }
+
+ /* Hypass the wsp[] vector */
+ hp_wsp = old_hp_wsp + L_max;
+ Hp_wsp(wsp, hp_wsp, L_frame, hp_wsp_mem);
+
+ /* Compute normalize correlation at delay Tm */
+ R0 = 0;
+ R1 = 0;
+ R2 = 0;
+ p1 = hp_wsp;
+ p2 = hp_wsp - Tm;
+ for (j = 0; j < L_frame; j+=4)
+ {
+ R2 += vo_mult32(*p1, *p1);
+ R1 += vo_mult32(*p2, *p2);
+ R0 += vo_mult32(*p1++, *p2++);
+ R2 += vo_mult32(*p1, *p1);
+ R1 += vo_mult32(*p2, *p2);
+ R0 += vo_mult32(*p1++, *p2++);
+ R2 += vo_mult32(*p1, *p1);
+ R1 += vo_mult32(*p2, *p2);
+ R0 += vo_mult32(*p1++, *p2++);
+ R2 += vo_mult32(*p1, *p1);
+ R1 += vo_mult32(*p2, *p2);
+ R0 += vo_mult32(*p1++, *p2++);
+ }
+ R0 = R0 <<1;
+ R1 = (R1 <<1) + 1L;
+ R2 = (R2 <<1) + 1L;
+ /* gain = R0/ sqrt(R1*R2) */
+
+ exp_R0 = norm_l(R0);
+ R0 = (R0 << exp_R0);
+
+ exp_R1 = norm_l(R1);
+ R1 = (R1 << exp_R1);
+
+ exp_R2 = norm_l(R2);
+ R2 = (R2 << exp_R2);
+
+
+ R1 = vo_L_mult(vo_round(R1), vo_round(R2));
+
+ i = norm_l(R1);
+ R1 = (R1 << i);
+
+ exp_R1 += exp_R2;
+ exp_R1 += i;
+ exp_R1 = 62 - exp_R1;
+
+ Isqrt_n(&R1, &exp_R1);
+
+ R0 = vo_L_mult(voround(R0), voround(R1));
+ exp_R0 = 31 - exp_R0;
+ exp_R0 += exp_R1;
+
+ *gain = vo_round(L_shl(R0, exp_R0));
+
+ /* Shitf hp_wsp[] for next frame */
+
+ for (i = 0; i < L_max; i++)
+ {
+ old_hp_wsp[i] = old_hp_wsp[i + L_frame];
+ }
+
+ return (Tm);
+}
+
+/************************************************************************
+* Function: median5 *
+* *
+* Returns the median of the set {X[-2], X[-1],..., X[2]}, *
+* whose elements are 16-bit integers. *
+* *
+* Input: *
+* X[-2:2] 16-bit integers. *
+* *
+* Return: *
+* The median of {X[-2], X[-1],..., X[2]}. *
+************************************************************************/
+
+Word16 median5(Word16 x[])
+{
+ Word16 x1, x2, x3, x4, x5;
+ Word16 tmp;
+
+ x1 = x[-2];
+ x2 = x[-1];
+ x3 = x[0];
+ x4 = x[1];
+ x5 = x[2];
+
+ if (x2 < x1)
+ {
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ }
+ if (x3 < x1)
+ {
+ tmp = x1;
+ x1 = x3;
+ x3 = tmp;
+ }
+ if (x4 < x1)
+ {
+ tmp = x1;
+ x1 = x4;
+ x4 = tmp;
+ }
+ if (x5 < x1)
+ {
+ x5 = x1;
+ }
+ if (x3 < x2)
+ {
+ tmp = x2;
+ x2 = x3;
+ x3 = tmp;
+ }
+ if (x4 < x2)
+ {
+ tmp = x2;
+ x2 = x4;
+ x4 = tmp;
+ }
+ if (x5 < x2)
+ {
+ x5 = x2;
+ }
+ if (x4 < x3)
+ {
+ x3 = x4;
+ }
+ if (x5 < x3)
+ {
+ x3 = x5;
+ }
+ return (x3);
+}
+
+
+Word16 Med_olag( /* output : median of 5 previous open-loop lags */
+ Word16 prev_ol_lag, /* input : previous open-loop lag */
+ Word16 old_ol_lag[5]
+ )
+{
+ Word32 i;
+
+ /* Use median of 5 previous open-loop lags as old lag */
+
+ for (i = 4; i > 0; i--)
+ {
+ old_ol_lag[i] = old_ol_lag[i - 1];
+ }
+
+ old_ol_lag[0] = prev_ol_lag;
+
+ i = median5(&old_ol_lag[2]);
+
+ return i;
+
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/pit_shrp.c b/media/libstagefright/codecs/amrwbenc/src/pit_shrp.c
new file mode 100644
index 0000000..c8a227c
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/pit_shrp.c
@@ -0,0 +1,49 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: pit_shrp.c *
+* *
+* Description: Performs Pitch sharpening routine *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+
+void Pit_shrp(
+ Word16 * x, /* in/out: impulse response (or algebraic code) */
+ Word16 pit_lag, /* input : pitch lag */
+ Word16 sharp, /* input : pitch sharpening factor (Q15) */
+ Word16 L_subfr /* input : subframe size */
+ )
+{
+ Word32 i;
+ Word32 L_tmp;
+ Word16 *x_ptr = x + pit_lag;
+
+ for (i = pit_lag; i < L_subfr; i++)
+ {
+ L_tmp = (*x_ptr << 15);
+ L_tmp += *x++ * sharp;
+ *x_ptr++ = ((L_tmp + 0x4000)>>15);
+ }
+
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
new file mode 100644
index 0000000..c115b11
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
@@ -0,0 +1,324 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: pitch_f4.c *
+* *
+* Description: Find the closed loop pitch period with *
+* 1/4 subsample resolution. *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "acelp.h"
+#include "cnst.h"
+
+#define UP_SAMP 4
+#define L_INTERPOL1 4
+
+/* Local functions */
+
+#ifdef ASM_OPT
+void Norm_corr_asm(
+ Word16 exc[], /* (i) : excitation buffer */
+ Word16 xn[], /* (i) : target vector */
+ Word16 h[], /* (i) Q15 : impulse response of synth/wgt filters */
+ Word16 L_subfr,
+ Word16 t_min, /* (i) : minimum value of pitch lag. */
+ Word16 t_max, /* (i) : maximum value of pitch lag. */
+ Word16 corr_norm[] /* (o) Q15 : normalized correlation */
+ );
+#else
+static void Norm_Corr(
+ Word16 exc[], /* (i) : excitation buffer */
+ Word16 xn[], /* (i) : target vector */
+ Word16 h[], /* (i) Q15 : impulse response of synth/wgt filters */
+ Word16 L_subfr,
+ Word16 t_min, /* (i) : minimum value of pitch lag. */
+ Word16 t_max, /* (i) : maximum value of pitch lag. */
+ Word16 corr_norm[] /* (o) Q15 : normalized correlation */
+ );
+#endif
+
+static Word16 Interpol_4( /* (o) : interpolated value */
+ Word16 * x, /* (i) : input vector */
+ Word32 frac /* (i) : fraction (-4..+3) */
+ );
+
+
+Word16 Pitch_fr4( /* (o) : pitch period. */
+ Word16 exc[], /* (i) : excitation buffer */
+ Word16 xn[], /* (i) : target vector */
+ Word16 h[], /* (i) Q15 : impulse response of synth/wgt filters */
+ Word16 t0_min, /* (i) : minimum value in the searched range. */
+ Word16 t0_max, /* (i) : maximum value in the searched range. */
+ Word16 * pit_frac, /* (o) : chosen fraction (0, 1, 2 or 3). */
+ Word16 i_subfr, /* (i) : indicator for first subframe. */
+ Word16 t0_fr2, /* (i) : minimum value for resolution 1/2 */
+ Word16 t0_fr1, /* (i) : minimum value for resolution 1 */
+ Word16 L_subfr /* (i) : Length of subframe */
+ )
+{
+ Word32 fraction, i;
+ Word16 t_min, t_max;
+ Word16 max, t0, step, temp;
+ Word16 *corr;
+ Word16 corr_v[40]; /* Total length = t0_max-t0_min+1+2*L_inter */
+
+ /* Find interval to compute normalized correlation */
+
+ t_min = t0_min - L_INTERPOL1;
+ t_max = t0_max + L_INTERPOL1;
+ corr = &corr_v[-t_min];
+ /* Compute normalized correlation between target and filtered excitation */
+#ifdef ASM_OPT /* asm optimization branch */
+ Norm_corr_asm(exc, xn, h, L_subfr, t_min, t_max, corr);
+#else
+ Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr);
+#endif
+
+ /* Find integer pitch */
+
+ max = corr[t0_min];
+ t0 = t0_min;
+ for (i = t0_min + 1; i <= t0_max; i++)
+ {
+ if (corr[i] >= max)
+ {
+ max = corr[i];
+ t0 = i;
+ }
+ }
+ /* If first subframe and t0 >= t0_fr1, do not search fractionnal pitch */
+ if ((i_subfr == 0) && (t0 >= t0_fr1))
+ {
+ *pit_frac = 0;
+ return (t0);
+ }
+ /*------------------------------------------------------------------*
+ * Search fractionnal pitch with 1/4 subsample resolution. *
+ * Test the fractions around t0 and choose the one which maximizes *
+ * the interpolated normalized correlation. *
+ *------------------------------------------------------------------*/
+
+ step = 1; /* 1/4 subsample resolution */
+ fraction = -3;
+ if ((t0_fr2 == PIT_MIN)||((i_subfr == 0) && (t0 >= t0_fr2)))
+ {
+ step = 2; /* 1/2 subsample resolution */
+ fraction = -2;
+ }
+ if(t0 == t0_min)
+ {
+ fraction = 0;
+ }
+ max = Interpol_4(&corr[t0], fraction);
+
+ for (i = fraction + step; i <= 3; i += step)
+ {
+ temp = Interpol_4(&corr[t0], i);
+ if(temp > max)
+ {
+ max = temp;
+ fraction = i;
+ }
+ }
+ /* limit the fraction value in the interval [0,1,2,3] */
+ if (fraction < 0)
+ {
+ fraction += UP_SAMP;
+ t0 -= 1;
+ }
+ *pit_frac = fraction;
+ return (t0);
+}
+
+
+/***********************************************************************************
+* Function: Norm_Corr() *
+* *
+* Description: Find the normalized correlation between the target vector and the *
+* filtered past excitation. *
+* (correlation between target and filtered excitation divided by the *
+* square root of energy of target and filtered excitation). *
+************************************************************************************/
+#ifndef ASM_OPT
+static void Norm_Corr(
+ Word16 exc[], /* (i) : excitation buffer */
+ Word16 xn[], /* (i) : target vector */
+ Word16 h[], /* (i) Q15 : impulse response of synth/wgt filters */
+ Word16 L_subfr,
+ Word16 t_min, /* (i) : minimum value of pitch lag. */
+ Word16 t_max, /* (i) : maximum value of pitch lag. */
+ Word16 corr_norm[]) /* (o) Q15 : normalized correlation */
+{
+ Word32 i, k, t;
+ Word32 corr, exp_corr, norm, exp, scale;
+ Word16 exp_norm, excf[L_SUBFR], tmp;
+ Word32 L_tmp, L_tmp1, L_tmp2;
+
+ /* compute the filtered excitation for the first delay t_min */
+ k = -t_min;
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Convolve_asm(&exc[k], h, excf, 64);
+#else
+ Convolve(&exc[k], h, excf, 64);
+#endif
+
+ /* Compute rounded down 1/sqrt(energy of xn[]) */
+ L_tmp = 0;
+ for (i = 0; i < 64; i+=4)
+ {
+ L_tmp += (xn[i] * xn[i]);
+ L_tmp += (xn[i+1] * xn[i+1]);
+ L_tmp += (xn[i+2] * xn[i+2]);
+ L_tmp += (xn[i+3] * xn[i+3]);
+ }
+
+ L_tmp = (L_tmp << 1) + 1;
+ exp = norm_l(L_tmp);
+ exp = (32 - exp);
+ //exp = exp + 2; /* energy of xn[] x 2 + rounded up */
+ scale = -(exp >> 1); /* (1<<scale) < 1/sqrt(energy rounded) */
+
+ /* loop for every possible period */
+
+ for (t = t_min; t <= t_max; t++)
+ {
+ /* Compute correlation between xn[] and excf[] */
+ L_tmp = 0;
+ L_tmp1 = 0;
+ for (i = 0; i < 64; i+=4)
+ {
+ L_tmp += (xn[i] * excf[i]);
+ L_tmp1 += (excf[i] * excf[i]);
+ L_tmp += (xn[i+1] * excf[i+1]);
+ L_tmp1 += (excf[i+1] * excf[i+1]);
+ L_tmp += (xn[i+2] * excf[i+2]);
+ L_tmp1 += (excf[i+2] * excf[i+2]);
+ L_tmp += (xn[i+3] * excf[i+3]);
+ L_tmp1 += (excf[i+3] * excf[i+3]);
+ }
+
+ L_tmp = (L_tmp << 1) + 1;
+ L_tmp1 = (L_tmp1 << 1) + 1;
+
+ exp = norm_l(L_tmp);
+ L_tmp = (L_tmp << exp);
+ exp_corr = (30 - exp);
+ corr = extract_h(L_tmp);
+
+ exp = norm_l(L_tmp1);
+ L_tmp = (L_tmp1 << exp);
+ exp_norm = (30 - exp);
+
+ Isqrt_n(&L_tmp, &exp_norm);
+ norm = extract_h(L_tmp);
+
+ /* Normalize correlation = correlation * (1/sqrt(energy)) */
+
+ L_tmp = vo_L_mult(corr, norm);
+
+ L_tmp2 = exp_corr + exp_norm + scale;
+ if(L_tmp2 < 0)
+ {
+ L_tmp2 = -L_tmp2;
+ L_tmp = L_tmp >> L_tmp2;
+ }
+ else
+ {
+ L_tmp = L_tmp << L_tmp2;
+ }
+
+ corr_norm[t] = vo_round(L_tmp);
+ /* modify the filtered excitation excf[] for the next iteration */
+
+ if(t != t_max)
+ {
+ k = -(t + 1);
+ tmp = exc[k];
+ for (i = 63; i > 0; i--)
+ {
+ excf[i] = add1(vo_mult(tmp, h[i]), excf[i - 1]);
+ }
+ excf[0] = vo_mult(tmp, h[0]);
+ }
+ }
+ return;
+}
+
+#endif
+/************************************************************************************
+* Function: Interpol_4() *
+* *
+* Description: For interpolating the normalized correlation with 1/4 resolution. *
+**************************************************************************************/
+
+/* 1/4 resolution interpolation filter (-3 dB at 0.791*fs/2) in Q14 */
+static Word16 inter4_1[4][8] =
+{
+ {-12, 420, -1732, 5429, 13418, -1242, 73, 32},
+ {-26, 455, -2142, 9910, 9910, -2142, 455, -26},
+ {32, 73, -1242, 13418, 5429, -1732, 420, -12},
+ {206, -766, 1376, 14746, 1376, -766, 206, 0}
+};
+
+/*** Coefficients in floating point
+static float inter4_1[UP_SAMP*L_INTERPOL1+1] = {
+0.900000,
+0.818959, 0.604850, 0.331379, 0.083958,
+-0.075795, -0.130717, -0.105685, -0.046774,
+0.004467, 0.027789, 0.025642, 0.012571,
+0.001927, -0.001571, -0.000753, 0.000000};
+***/
+
+static Word16 Interpol_4( /* (o) : interpolated value */
+ Word16 * x, /* (i) : input vector */
+ Word32 frac /* (i) : fraction (-4..+3) */
+ )
+{
+ Word16 sum;
+ Word32 k, L_sum;
+ Word16 *ptr;
+
+ if (frac < 0)
+ {
+ frac += UP_SAMP;
+ x--;
+ }
+ x = x - L_INTERPOL1 + 1;
+ k = UP_SAMP - 1 - frac;
+ ptr = &(inter4_1[k][0]);
+
+ L_sum = vo_mult32(x[0], (*ptr++));
+ L_sum += vo_mult32(x[1], (*ptr++));
+ L_sum += vo_mult32(x[2], (*ptr++));
+ L_sum += vo_mult32(x[3], (*ptr++));
+ L_sum += vo_mult32(x[4], (*ptr++));
+ L_sum += vo_mult32(x[5], (*ptr++));
+ L_sum += vo_mult32(x[6], (*ptr++));
+ L_sum += vo_mult32(x[7], (*ptr++));
+
+ sum = extract_h(L_add(L_shl2(L_sum, 2), 0x8000));
+ return (sum);
+}
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/pred_lt4.c b/media/libstagefright/codecs/amrwbenc/src/pred_lt4.c
new file mode 100644
index 0000000..ac1ff22
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/pred_lt4.c
@@ -0,0 +1,120 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: pred_lt4.c *
+* *
+* Description: Compute the result of long term prediction with *
+* fractional interpolation of resolution 1/4 *
+* on return exc[0..L_subr-1] contains the interpolated signal *
+* (adaptive codebook excitation) *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+
+#define UP_SAMP 4
+#define L_INTERPOL2 16
+
+/* 1/4 resolution interpolation filter (-3 dB at 0.856*fs/2) in Q14 */
+
+Word16 inter4_2[4][32] =
+{
+ {0,-2,4,-2,-10,38,-88,165,-275,424,-619,871,-1207,1699,-2598,5531,14031,-2147,780,-249,
+ -16,153,-213,226,-209,175,-133,91,-55,28,-10,2},
+
+ {1,-7,19,-33,47,-52,43,-9,-60,175,-355,626,-1044,1749,-3267,10359,10359,-3267,1749,-1044,
+ 626,-355,175,-60,-9,43,-52,47,-33,19, -7, 1},
+
+ {2,-10,28,-55,91,-133,175,-209,226,-213,153,-16,-249,780,-2147,14031,5531,-2598,1699,-1207,
+ 871,-619,424,-275,165,-88,38,-10,-2,4,-2,0},
+
+ {1,-7,22,-49,92,-153,231,-325,431,-544,656,-762,853,-923,968,15401,968,-923,853,-762,
+ 656,-544,431,-325,231,-153,92,-49,22,-7, 1, 0}
+
+};
+
+void Pred_lt4(
+ Word16 exc[], /* in/out: excitation buffer */
+ Word16 T0, /* input : integer pitch lag */
+ Word16 frac, /* input : fraction of lag */
+ Word16 L_subfr /* input : subframe size */
+ )
+{
+ Word16 j, k, *x;
+ Word32 L_sum;
+ Word16 *ptr, *ptr1;
+ Word16 *ptr2;
+
+ x = exc - T0;
+ frac = -frac;
+ if (frac < 0)
+ {
+ frac += UP_SAMP;
+ x--;
+ }
+ x -= 15; /* x = L_INTERPOL2 - 1 */
+ k = 3 - frac; /* k = UP_SAMP - 1 - frac */
+
+ ptr2 = &(inter4_2[k][0]);
+ for (j = 0; j < L_subfr; j++)
+ {
+ ptr = ptr2;
+ ptr1 = x;
+ L_sum = vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+ L_sum += vo_mult32((*ptr1++), (*ptr++));
+
+ L_sum = L_shl2(L_sum, 2);
+ exc[j] = extract_h(L_add(L_sum, 0x8000));
+ x++;
+ }
+
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/preemph.c b/media/libstagefright/codecs/amrwbenc/src/preemph.c
new file mode 100644
index 0000000..f5bcd33
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/preemph.c
@@ -0,0 +1,88 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: preemph.c *
+* *
+* Description: Preemphasis: filtering through 1 - g z^-1 *
+* Preemph2 --> signal is multiplied by 2 *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+
+void Preemph(
+ Word16 x[], /* (i/o) : input signal overwritten by the output */
+ Word16 mu, /* (i) Q15 : preemphasis coefficient */
+ Word16 lg, /* (i) : lenght of filtering */
+ Word16 * mem /* (i/o) : memory (x[-1]) */
+ )
+{
+ Word16 temp;
+ Word32 i, L_tmp;
+
+ temp = x[lg - 1];
+
+ for (i = lg - 1; i > 0; i--)
+ {
+ L_tmp = L_deposit_h(x[i]);
+ L_tmp -= (x[i - 1] * mu)<<1;
+ x[i] = (L_tmp + 0x8000)>>16;
+ }
+
+ L_tmp = L_deposit_h(x[0]);
+ L_tmp -= ((*mem) * mu)<<1;
+ x[0] = (L_tmp + 0x8000)>>16;
+
+ *mem = temp;
+
+ return;
+}
+
+
+void Preemph2(
+ Word16 x[], /* (i/o) : input signal overwritten by the output */
+ Word16 mu, /* (i) Q15 : preemphasis coefficient */
+ Word16 lg, /* (i) : lenght of filtering */
+ Word16 * mem /* (i/o) : memory (x[-1]) */
+ )
+{
+ Word16 temp;
+ Word32 i, L_tmp;
+
+ temp = x[lg - 1];
+
+ for (i = (Word16) (lg - 1); i > 0; i--)
+ {
+ L_tmp = L_deposit_h(x[i]);
+ L_tmp -= (x[i - 1] * mu)<<1;
+ L_tmp = (L_tmp << 1);
+ x[i] = (L_tmp + 0x8000)>>16;
+ }
+
+ L_tmp = L_deposit_h(x[0]);
+ L_tmp -= ((*mem) * mu)<<1;
+ L_tmp = (L_tmp << 1);
+ x[0] = (L_tmp + 0x8000)>>16;
+
+ *mem = temp;
+
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/q_gain2.c b/media/libstagefright/codecs/amrwbenc/src/q_gain2.c
new file mode 100644
index 0000000..59eefe4
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/q_gain2.c
@@ -0,0 +1,346 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/**************************************************************************
+* File: q_gain2.c *
+* *
+* Description: *
+* Quantization of pitch and codebook gains. *
+* MA prediction is performed on the innovation energy (in dB with mean *
+* removed). *
+* An initial predicted gain, g_0, is first determined and the correction *
+* factor alpha = gain / g_0 is quantized. *
+* The pitch gain and the correction factor are vector quantized and the *
+* mean-squared weighted error criterion is used in the quantizer search. *
+****************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "math_op.h"
+#include "log2.h"
+#include "acelp.h"
+#include "q_gain2.tab"
+
+#define MEAN_ENER 30
+#define RANGE 64
+#define PRED_ORDER 4
+
+
+/* MA prediction coeff ={0.5, 0.4, 0.3, 0.2} in Q13 */
+static Word16 pred[PRED_ORDER] = {4096, 3277, 2458, 1638};
+
+
+void Init_Q_gain2(
+ Word16 * mem /* output :static memory (2 words) */
+ )
+{
+ Word32 i;
+
+ /* 4nd order quantizer energy predictor (init to -14.0 in Q10) */
+ for (i = 0; i < PRED_ORDER; i++)
+ {
+ mem[i] = -14336; /* past_qua_en[i] */
+ }
+
+ return;
+}
+
+Word16 Q_gain2( /* Return index of quantization. */
+ Word16 xn[], /* (i) Q_xn: Target vector. */
+ Word16 y1[], /* (i) Q_xn: Adaptive codebook. */
+ Word16 Q_xn, /* (i) : xn and y1 format */
+ Word16 y2[], /* (i) Q9 : Filtered innovative vector. */
+ Word16 code[], /* (i) Q9 : Innovative vector. */
+ Word16 g_coeff[], /* (i) : Correlations <xn y1> <y1 y1> */
+ /* Compute in G_pitch(). */
+ Word16 L_subfr, /* (i) : Subframe lenght. */
+ Word16 nbits, /* (i) : number of bits (6 or 7) */
+ Word16 * gain_pit, /* (i/o)Q14: Pitch gain. */
+ Word32 * gain_cod, /* (o) Q16 : Code gain. */
+ Word16 gp_clip, /* (i) : Gp Clipping flag */
+ Word16 * mem /* (i/o) : static memory (2 words) */
+ )
+{
+ Word16 index, *p, min_ind, size;
+ Word16 exp, frac, gcode0, exp_gcode0, e_max, exp_code, qua_ener;
+ Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
+ Word16 coeff[5], coeff_lo[5], exp_coeff[5];
+ Word16 exp_max[5];
+ Word32 i, j, L_tmp, dist_min;
+ Word16 *past_qua_en, *t_qua_gain;
+
+ past_qua_en = mem;
+
+ /*-----------------------------------------------------------------*
+ * - Find the initial quantization pitch index *
+ * - Set gains search range *
+ *-----------------------------------------------------------------*/
+ if (nbits == 6)
+ {
+ t_qua_gain = t_qua_gain6b;
+ min_ind = 0;
+ size = RANGE;
+
+ if(gp_clip == 1)
+ {
+ size = size - 16; /* limit gain pitch to 1.0 */
+ }
+ } else
+ {
+ t_qua_gain = t_qua_gain7b;
+
+ p = t_qua_gain7b + RANGE; /* pt at 1/4th of table */
+
+ j = nb_qua_gain7b - RANGE;
+
+ if (gp_clip == 1)
+ {
+ j = j - 27; /* limit gain pitch to 1.0 */
+ }
+ min_ind = 0;
+ g_pitch = *gain_pit;
+
+ for (i = 0; i < j; i++, p += 2)
+ {
+ if (g_pitch > *p)
+ {
+ min_ind = min_ind + 1;
+ }
+ }
+ size = RANGE;
+ }
+
+ /*------------------------------------------------------------------*
+ * Compute coefficient need for the quantization. *
+ * *
+ * coeff[0] = y1 y1 *
+ * coeff[1] = -2 xn y1 *
+ * coeff[2] = y2 y2 *
+ * coeff[3] = -2 xn y2 *
+ * coeff[4] = 2 y1 y2 *
+ * *
+ * Product <y1 y1> and <xn y1> have been compute in G_pitch() and *
+ * are in vector g_coeff[]. *
+ *------------------------------------------------------------------*/
+
+ coeff[0] = g_coeff[0];
+ exp_coeff[0] = g_coeff[1];
+ coeff[1] = negate(g_coeff[2]); /* coeff[1] = -2 xn y1 */
+ exp_coeff[1] = g_coeff[3] + 1;
+
+ /* Compute scalar product <y2[],y2[]> */
+#ifdef ASM_OPT /* asm optimization branch */
+ coeff[2] = extract_h(Dot_product12_asm(y2, y2, L_subfr, &exp));
+#else
+ coeff[2] = extract_h(Dot_product12(y2, y2, L_subfr, &exp));
+#endif
+ exp_coeff[2] = (exp - 18) + (Q_xn << 1); /* -18 (y2 Q9) */
+
+ /* Compute scalar product -2*<xn[],y2[]> */
+#ifdef ASM_OPT /* asm optimization branch */
+ coeff[3] = extract_h(L_negate(Dot_product12_asm(xn, y2, L_subfr, &exp)));
+#else
+ coeff[3] = extract_h(L_negate(Dot_product12(xn, y2, L_subfr, &exp)));
+#endif
+
+ exp_coeff[3] = (exp - 8) + Q_xn; /* -9 (y2 Q9), +1 (2 xn y2) */
+
+ /* Compute scalar product 2*<y1[],y2[]> */
+#ifdef ASM_OPT /* asm optimization branch */
+ coeff[4] = extract_h(Dot_product12_asm(y1, y2, L_subfr, &exp));
+#else
+ coeff[4] = extract_h(Dot_product12(y1, y2, L_subfr, &exp));
+#endif
+ exp_coeff[4] = (exp - 8) + Q_xn; /* -9 (y2 Q9), +1 (2 y1 y2) */
+
+ /*-----------------------------------------------------------------*
+ * Find energy of code and compute: *
+ * *
+ * L_tmp = MEAN_ENER - 10log10(energy of code/ L_subfr) *
+ * = MEAN_ENER - 3.0103*log2(energy of code/ L_subfr) *
+ *-----------------------------------------------------------------*/
+#ifdef ASM_OPT /* asm optimization branch */
+ L_tmp = Dot_product12_asm(code, code, L_subfr, &exp_code);
+#else
+ L_tmp = Dot_product12(code, code, L_subfr, &exp_code);
+#endif
+ /* exp_code: -18 (code in Q9), -6 (/L_subfr), -31 (L_tmp Q31->Q0) */
+ exp_code = (exp_code - (18 + 6 + 31));
+
+ Log2(L_tmp, &exp, &frac);
+ exp += exp_code;
+ L_tmp = Mpy_32_16(exp, frac, -24660); /* x -3.0103(Q13) -> Q14 */
+
+ L_tmp += (MEAN_ENER * 8192)<<1; /* + MEAN_ENER in Q14 */
+
+ /*-----------------------------------------------------------------*
+ * Compute gcode0. *
+ * = Sum(i=0,1) pred[i]*past_qua_en[i] + mean_ener - ener_code *
+ *-----------------------------------------------------------------*/
+ L_tmp = (L_tmp << 10); /* From Q14 to Q24 */
+ L_tmp += (pred[0] * past_qua_en[0])<<1; /* Q13*Q10 -> Q24 */
+ L_tmp += (pred[1] * past_qua_en[1])<<1; /* Q13*Q10 -> Q24 */
+ L_tmp += (pred[2] * past_qua_en[2])<<1; /* Q13*Q10 -> Q24 */
+ L_tmp += (pred[3] * past_qua_en[3])<<1; /* Q13*Q10 -> Q24 */
+
+ gcode0 = extract_h(L_tmp); /* From Q24 to Q8 */
+
+ /*-----------------------------------------------------------------*
+ * gcode0 = pow(10.0, gcode0/20) *
+ * = pow(2, 3.321928*gcode0/20) *
+ * = pow(2, 0.166096*gcode0) *
+ *-----------------------------------------------------------------*/
+
+ L_tmp = vo_L_mult(gcode0, 5443); /* *0.166096 in Q15 -> Q24 */
+ L_tmp = L_tmp >> 8; /* From Q24 to Q16 */
+ VO_L_Extract(L_tmp, &exp_gcode0, &frac); /* Extract exponent of gcode0 */
+
+ gcode0 = (Word16)(Pow2(14, frac)); /* Put 14 as exponent so that */
+ /* output of Pow2() will be: */
+ /* 16384 < Pow2() <= 32767 */
+ exp_gcode0 -= 14;
+
+ /*-------------------------------------------------------------------------*
+ * Find the best quantizer *
+ * ~~~~~~~~~~~~~~~~~~~~~~~ *
+ * Before doing the computation we need to aling exponents of coeff[] *
+ * to be sure to have the maximum precision. *
+ * *
+ * In the table the pitch gains are in Q14, the code gains are in Q11 and *
+ * are multiply by gcode0 which have been multiply by 2^exp_gcode0. *
+ * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code *
+ * we divide by 2^15. *
+ * Considering all the scaling above we have: *
+ * *
+ * exp_code = exp_gcode0-11+15 = exp_gcode0+4 *
+ * *
+ * g_pitch*g_pitch = -14-14+15 *
+ * g_pitch = -14 *
+ * g_code*g_code = (2*exp_code)+15 *
+ * g_code = exp_code *
+ * g_pitch*g_code = -14 + exp_code +15 *
+ * *
+ * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13 *
+ * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14 *
+ * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code) *
+ * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code *
+ * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code *
+ *-------------------------------------------------------------------------*/
+
+ exp_code = (exp_gcode0 + 4);
+ exp_max[0] = (exp_coeff[0] - 13);
+ exp_max[1] = (exp_coeff[1] - 14);
+ exp_max[2] = (exp_coeff[2] + (15 + (exp_code << 1)));
+ exp_max[3] = (exp_coeff[3] + exp_code);
+ exp_max[4] = (exp_coeff[4] + (1 + exp_code));
+
+ /* Find maximum exponant */
+
+ e_max = exp_max[0];
+ for (i = 1; i < 5; i++)
+ {
+ if(exp_max[i] > e_max)
+ {
+ e_max = exp_max[i];
+ }
+ }
+
+ /* align coeff[] and save in special 32 bit double precision */
+
+ for (i = 0; i < 5; i++)
+ {
+ j = add1(vo_sub(e_max, exp_max[i]), 2);/* /4 to avoid overflow */
+ L_tmp = L_deposit_h(coeff[i]);
+ L_tmp = L_shr(L_tmp, j);
+ VO_L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
+ coeff_lo[i] = (coeff_lo[i] >> 3); /* lo >> 3 */
+ }
+
+ /* Codebook search */
+ dist_min = MAX_32;
+ p = &t_qua_gain[min_ind << 1];
+
+ index = 0;
+ for (i = 0; i < size; i++)
+ {
+ g_pitch = *p++;
+ g_code = *p++;
+
+ g_code = ((g_code * gcode0) + 0x4000)>>15;
+ g2_pitch = ((g_pitch * g_pitch) + 0x4000)>>15;
+ g_pit_cod = ((g_code * g_pitch) + 0x4000)>>15;
+ L_tmp = (g_code * g_code)<<1;
+ VO_L_Extract(L_tmp, &g2_code, &g2_code_lo);
+
+ L_tmp = (coeff[2] * g2_code_lo)<<1;
+ L_tmp = (L_tmp >> 3);
+ L_tmp += (coeff_lo[0] * g2_pitch)<<1;
+ L_tmp += (coeff_lo[1] * g_pitch)<<1;
+ L_tmp += (coeff_lo[2] * g2_code)<<1;
+ L_tmp += (coeff_lo[3] * g_code)<<1;
+ L_tmp += (coeff_lo[4] * g_pit_cod)<<1;
+ L_tmp = (L_tmp >> 12);
+ L_tmp += (coeff[0] * g2_pitch)<<1;
+ L_tmp += (coeff[1] * g_pitch)<<1;
+ L_tmp += (coeff[2] * g2_code)<<1;
+ L_tmp += (coeff[3] * g_code)<<1;
+ L_tmp += (coeff[4] * g_pit_cod)<<1;
+
+ if(L_tmp < dist_min)
+ {
+ dist_min = L_tmp;
+ index = i;
+ }
+ }
+
+ /* Read the quantized gains */
+ index = index + min_ind;
+ p = &t_qua_gain[(index + index)];
+ *gain_pit = *p++; /* selected pitch gain in Q14 */
+ g_code = *p++; /* selected code gain in Q11 */
+
+ L_tmp = vo_L_mult(g_code, gcode0); /* Q11*Q0 -> Q12 */
+ L_tmp = L_shl(L_tmp, (exp_gcode0 + 4)); /* Q12 -> Q16 */
+
+ *gain_cod = L_tmp; /* gain of code in Q16 */
+
+ /*---------------------------------------------------*
+ * qua_ener = 20*log10(g_code) *
+ * = 6.0206*log2(g_code) *
+ * = 6.0206*(log2(g_codeQ11) - 11) *
+ *---------------------------------------------------*/
+
+ L_tmp = L_deposit_l(g_code);
+ Log2(L_tmp, &exp, &frac);
+ exp -= 11;
+ L_tmp = Mpy_32_16(exp, frac, 24660); /* x 6.0206 in Q12 */
+
+ qua_ener = (Word16)(L_tmp >> 3); /* result in Q10 */
+
+ /* update table of past quantized energies */
+
+ past_qua_en[3] = past_qua_en[2];
+ past_qua_en[2] = past_qua_en[1];
+ past_qua_en[1] = past_qua_en[0];
+ past_qua_en[0] = qua_ener;
+
+ return (index);
+}
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/q_pulse.c b/media/libstagefright/codecs/amrwbenc/src/q_pulse.c
new file mode 100644
index 0000000..a28ba40
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/q_pulse.c
@@ -0,0 +1,400 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: q_pulse.c *
+* *
+* Description: Coding and decoding of algebraic codebook *
+* *
+************************************************************************/
+
+#include <stdio.h>
+#include "typedef.h"
+#include "basic_op.h"
+#include "q_pulse.h"
+
+#define NB_POS 16 /* pos in track, mask for sign bit */
+
+Word32 quant_1p_N1( /* (o) return N+1 bits */
+ Word16 pos, /* (i) position of the pulse */
+ Word16 N) /* (i) number of bits for position */
+{
+ Word16 mask;
+ Word32 index;
+
+ mask = (1 << N) - 1; /* mask = ((1<<N)-1); */
+ /*-------------------------------------------------------*
+ * Quantization of 1 pulse with N+1 bits: *
+ *-------------------------------------------------------*/
+ index = L_deposit_l((Word16) (pos & mask));
+ if ((pos & NB_POS) != 0)
+ {
+ index = vo_L_add(index, L_deposit_l(1 << N)); /* index += 1 << N; */
+ }
+ return (index);
+}
+
+
+Word32 quant_2p_2N1( /* (o) return (2*N)+1 bits */
+ Word16 pos1, /* (i) position of the pulse 1 */
+ Word16 pos2, /* (i) position of the pulse 2 */
+ Word16 N) /* (i) number of bits for position */
+{
+ Word16 mask, tmp;
+ Word32 index;
+ mask = (1 << N) - 1; /* mask = ((1<<N)-1); */
+ /*-------------------------------------------------------*
+ * Quantization of 2 pulses with 2*N+1 bits: *
+ *-------------------------------------------------------*/
+ if (((pos2 ^ pos1) & NB_POS) == 0)
+ {
+ /* sign of 1st pulse == sign of 2th pulse */
+ if(pos1 <= pos2) /* ((pos1 - pos2) <= 0) */
+ {
+ /* index = ((pos1 & mask) << N) + (pos2 & mask); */
+ index = L_deposit_l(add1((((Word16) (pos1 & mask)) << N), ((Word16) (pos2 & mask))));
+ } else
+ {
+ /* ((pos2 & mask) << N) + (pos1 & mask); */
+ index = L_deposit_l(add1((((Word16) (pos2 & mask)) << N), ((Word16) (pos1 & mask))));
+ }
+ if ((pos1 & NB_POS) != 0)
+ {
+ tmp = (N << 1);
+ index = vo_L_add(index, (1L << tmp)); /* index += 1 << (2*N); */
+ }
+ } else
+ {
+ /* sign of 1st pulse != sign of 2th pulse */
+ if (vo_sub((Word16) (pos1 & mask), (Word16) (pos2 & mask)) <= 0)
+ {
+ /* index = ((pos2 & mask) << N) + (pos1 & mask); */
+ index = L_deposit_l(add1((((Word16) (pos2 & mask)) << N), ((Word16) (pos1 & mask))));
+ if ((pos2 & NB_POS) != 0)
+ {
+ tmp = (N << 1); /* index += 1 << (2*N); */
+ index = vo_L_add(index, (1L << tmp));
+ }
+ } else
+ {
+ /* index = ((pos1 & mask) << N) + (pos2 & mask); */
+ index = L_deposit_l(add1((((Word16) (pos1 & mask)) << N), ((Word16) (pos2 & mask))));
+ if ((pos1 & NB_POS) != 0)
+ {
+ tmp = (N << 1);
+ index = vo_L_add(index, (1 << tmp)); /* index += 1 << (2*N); */
+ }
+ }
+ }
+ return (index);
+}
+
+
+Word32 quant_3p_3N1( /* (o) return (3*N)+1 bits */
+ Word16 pos1, /* (i) position of the pulse 1 */
+ Word16 pos2, /* (i) position of the pulse 2 */
+ Word16 pos3, /* (i) position of the pulse 3 */
+ Word16 N) /* (i) number of bits for position */
+{
+ Word16 nb_pos;
+ Word32 index;
+
+ nb_pos =(1 <<(N - 1)); /* nb_pos = (1<<(N-1)); */
+ /*-------------------------------------------------------*
+ * Quantization of 3 pulses with 3*N+1 bits: *
+ *-------------------------------------------------------*/
+ if (((pos1 ^ pos2) & nb_pos) == 0)
+ {
+ index = quant_2p_2N1(pos1, pos2, sub(N, 1)); /* index = quant_2p_2N1(pos1, pos2, (N-1)); */
+ /* index += (pos1 & nb_pos) << N; */
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
+ /* index += quant_1p_N1(pos3, N) << (2*N); */
+ index = vo_L_add(index, (quant_1p_N1(pos3, N)<<(N << 1)));
+
+ } else if (((pos1 ^ pos3) & nb_pos) == 0)
+ {
+ index = quant_2p_2N1(pos1, pos3, sub(N, 1)); /* index = quant_2p_2N1(pos1, pos3, (N-1)); */
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
+ /* index += (pos1 & nb_pos) << N; */
+ index = vo_L_add(index, (quant_1p_N1(pos2, N) << (N << 1)));
+ /* index += quant_1p_N1(pos2, N) <<
+ * (2*N); */
+ } else
+ {
+ index = quant_2p_2N1(pos2, pos3, (N - 1)); /* index = quant_2p_2N1(pos2, pos3, (N-1)); */
+ /* index += (pos2 & nb_pos) << N; */
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos2 & nb_pos)) << N));
+ /* index += quant_1p_N1(pos1, N) << (2*N); */
+ index = vo_L_add(index, (quant_1p_N1(pos1, N) << (N << 1)));
+ }
+ return (index);
+}
+
+
+Word32 quant_4p_4N1( /* (o) return (4*N)+1 bits */
+ Word16 pos1, /* (i) position of the pulse 1 */
+ Word16 pos2, /* (i) position of the pulse 2 */
+ Word16 pos3, /* (i) position of the pulse 3 */
+ Word16 pos4, /* (i) position of the pulse 4 */
+ Word16 N) /* (i) number of bits for position */
+{
+ Word16 nb_pos;
+ Word32 index;
+
+ nb_pos = 1 << (N - 1); /* nb_pos = (1<<(N-1)); */
+ /*-------------------------------------------------------*
+ * Quantization of 4 pulses with 4*N+1 bits: *
+ *-------------------------------------------------------*/
+ if (((pos1 ^ pos2) & nb_pos) == 0)
+ {
+ index = quant_2p_2N1(pos1, pos2, sub(N, 1)); /* index = quant_2p_2N1(pos1, pos2, (N-1)); */
+ /* index += (pos1 & nb_pos) << N; */
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
+ /* index += quant_2p_2N1(pos3, pos4, N) << (2*N); */
+ index = vo_L_add(index, (quant_2p_2N1(pos3, pos4, N) << (N << 1)));
+ } else if (((pos1 ^ pos3) & nb_pos) == 0)
+ {
+ index = quant_2p_2N1(pos1, pos3, (N - 1));
+ /* index += (pos1 & nb_pos) << N; */
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
+ /* index += quant_2p_2N1(pos2, pos4, N) << (2*N); */
+ index = vo_L_add(index, (quant_2p_2N1(pos2, pos4, N) << (N << 1)));
+ } else
+ {
+ index = quant_2p_2N1(pos2, pos3, (N - 1));
+ /* index += (pos2 & nb_pos) << N; */
+ index = vo_L_add(index, (L_deposit_l((Word16) (pos2 & nb_pos)) << N));
+ /* index += quant_2p_2N1(pos1, pos4, N) << (2*N); */
+ index = vo_L_add(index, (quant_2p_2N1(pos1, pos4, N) << (N << 1)));
+ }
+ return (index);
+}
+
+
+Word32 quant_4p_4N( /* (o) return 4*N bits */
+ Word16 pos[], /* (i) position of the pulse 1..4 */
+ Word16 N) /* (i) number of bits for position */
+{
+ Word16 nb_pos, mask, n_1, tmp;
+ Word16 posA[4], posB[4];
+ Word32 i, j, k, index;
+
+ n_1 = (Word16) (N - 1);
+ nb_pos = (1 << n_1); /* nb_pos = (1<<n_1); */
+ mask = vo_sub((1 << N), 1); /* mask = ((1<<N)-1); */
+
+ i = 0;
+ j = 0;
+ for (k = 0; k < 4; k++)
+ {
+ if ((pos[k] & nb_pos) == 0)
+ {
+ posA[i++] = pos[k];
+ } else
+ {
+ posB[j++] = pos[k];
+ }
+ }
+
+ switch (i)
+ {
+ case 0:
+ tmp = vo_sub((N << 2), 3); /* index = 1 << ((4*N)-3); */
+ index = (1L << tmp);
+ /* index += quant_4p_4N1(posB[0], posB[1], posB[2], posB[3], n_1); */
+ index = vo_L_add(index, quant_4p_4N1(posB[0], posB[1], posB[2], posB[3], n_1));
+ break;
+ case 1:
+ /* index = quant_1p_N1(posA[0], n_1) << ((3*n_1)+1); */
+ tmp = add1((Word16)((vo_L_mult(3, n_1) >> 1)), 1);
+ index = L_shl(quant_1p_N1(posA[0], n_1), tmp);
+ /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1); */
+ index = vo_L_add(index, quant_3p_3N1(posB[0], posB[1], posB[2], n_1));
+ break;
+ case 2:
+ tmp = ((n_1 << 1) + 1); /* index = quant_2p_2N1(posA[0], posA[1], n_1) << ((2*n_1)+1); */
+ index = L_shl(quant_2p_2N1(posA[0], posA[1], n_1), tmp);
+ /* index += quant_2p_2N1(posB[0], posB[1], n_1); */
+ index = vo_L_add(index, quant_2p_2N1(posB[0], posB[1], n_1));
+ break;
+ case 3:
+ /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << N; */
+ index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), N);
+ index = vo_L_add(index, quant_1p_N1(posB[0], n_1)); /* index += quant_1p_N1(posB[0], n_1); */
+ break;
+ case 4:
+ index = quant_4p_4N1(posA[0], posA[1], posA[2], posA[3], n_1);
+ break;
+ default:
+ index = 0;
+ fprintf(stderr, "Error in function quant_4p_4N\n");
+ }
+ tmp = ((N << 2) - 2); /* index += (i & 3) << ((4*N)-2); */
+ index = vo_L_add(index, L_shl((L_deposit_l(i) & (3L)), tmp));
+
+ return (index);
+}
+
+
+
+Word32 quant_5p_5N( /* (o) return 5*N bits */
+ Word16 pos[], /* (i) position of the pulse 1..5 */
+ Word16 N) /* (i) number of bits for position */
+{
+ Word16 nb_pos, n_1, tmp;
+ Word16 posA[5], posB[5];
+ Word32 i, j, k, index, tmp2;
+
+ n_1 = (Word16) (N - 1);
+ nb_pos = (1 << n_1); /* nb_pos = (1<<n_1); */
+
+ i = 0;
+ j = 0;
+ for (k = 0; k < 5; k++)
+ {
+ if ((pos[k] & nb_pos) == 0)
+ {
+ posA[i++] = pos[k];
+ } else
+ {
+ posB[j++] = pos[k];
+ }
+ }
+
+ switch (i)
+ {
+ case 0:
+ tmp = vo_sub((Word16)((vo_L_mult(5, N) >> 1)), 1); /* ((5*N)-1)) */
+ index = L_shl(1L, tmp); /* index = 1 << ((5*N)-1); */
+ tmp = add1((N << 1), 1); /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1) << ((2*N)+1);*/
+ tmp2 = L_shl(quant_3p_3N1(posB[0], posB[1], posB[2], n_1), tmp);
+ index = vo_L_add(index, tmp2);
+ index = vo_L_add(index, quant_2p_2N1(posB[3], posB[4], N)); /* index += quant_2p_2N1(posB[3], posB[4], N); */
+ break;
+ case 1:
+ tmp = vo_sub((Word16)((vo_L_mult(5, N) >> 1)), 1); /* index = 1 << ((5*N)-1); */
+ index = L_shl(1L, tmp);
+ tmp = add1((N << 1), 1); /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1) <<((2*N)+1); */
+ tmp2 = L_shl(quant_3p_3N1(posB[0], posB[1], posB[2], n_1), tmp);
+ index = vo_L_add(index, tmp2);
+ index = vo_L_add(index, quant_2p_2N1(posB[3], posA[0], N)); /* index += quant_2p_2N1(posB[3], posA[0], N); */
+ break;
+ case 2:
+ tmp = vo_sub((Word16)((vo_L_mult(5, N) >> 1)), 1); /* ((5*N)-1)) */
+ index = L_shl(1L, tmp); /* index = 1 << ((5*N)-1); */
+ tmp = add1((N << 1), 1); /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1) << ((2*N)+1); */
+ tmp2 = L_shl(quant_3p_3N1(posB[0], posB[1], posB[2], n_1), tmp);
+ index = vo_L_add(index, tmp2);
+ index = vo_L_add(index, quant_2p_2N1(posA[0], posA[1], N)); /* index += quant_2p_2N1(posA[0], posA[1], N); */
+ break;
+ case 3:
+ tmp = add1((N << 1), 1); /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2*N)+1); */
+ index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), tmp);
+ index = vo_L_add(index, quant_2p_2N1(posB[0], posB[1], N)); /* index += quant_2p_2N1(posB[0], posB[1], N); */
+ break;
+ case 4:
+ tmp = add1((N << 1), 1); /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2*N)+1); */
+ index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), tmp);
+ index = vo_L_add(index, quant_2p_2N1(posA[3], posB[0], N)); /* index += quant_2p_2N1(posA[3], posB[0], N); */
+ break;
+ case 5:
+ tmp = add1((N << 1), 1); /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2*N)+1); */
+ index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), tmp);
+ index = vo_L_add(index, quant_2p_2N1(posA[3], posA[4], N)); /* index += quant_2p_2N1(posA[3], posA[4], N); */
+ break;
+ default:
+ index = 0;
+ fprintf(stderr, "Error in function quant_5p_5N\n");
+ }
+
+ return (index);
+}
+
+
+Word32 quant_6p_6N_2( /* (o) return (6*N)-2 bits */
+ Word16 pos[], /* (i) position of the pulse 1..6 */
+ Word16 N) /* (i) number of bits for position */
+{
+ Word16 nb_pos, n_1;
+ Word16 posA[6], posB[6];
+ Word32 i, j, k, index;
+
+ /* !! N and n_1 are constants -> it doesn't need to be operated by Basic Operators */
+ n_1 = (Word16) (N - 1);
+ nb_pos = (1 << n_1); /* nb_pos = (1<<n_1); */
+
+ i = 0;
+ j = 0;
+ for (k = 0; k < 6; k++)
+ {
+ if ((pos[k] & nb_pos) == 0)
+ {
+ posA[i++] = pos[k];
+ } else
+ {
+ posB[j++] = pos[k];
+ }
+ }
+
+ switch (i)
+ {
+ case 0:
+ index = (1 << (Word16) (6 * N - 5)); /* index = 1 << ((6*N)-5); */
+ index = vo_L_add(index, (quant_5p_5N(posB, n_1) << N)); /* index += quant_5p_5N(posB, n_1) << N; */
+ index = vo_L_add(index, quant_1p_N1(posB[5], n_1)); /* index += quant_1p_N1(posB[5], n_1); */
+ break;
+ case 1:
+ index = (1L << (Word16) (6 * N - 5)); /* index = 1 << ((6*N)-5); */
+ index = vo_L_add(index, (quant_5p_5N(posB, n_1) << N)); /* index += quant_5p_5N(posB, n_1) << N; */
+ index = vo_L_add(index, quant_1p_N1(posA[0], n_1)); /* index += quant_1p_N1(posA[0], n_1); */
+ break;
+ case 2:
+ index = (1L << (Word16) (6 * N - 5)); /* index = 1 << ((6*N)-5); */
+ /* index += quant_4p_4N(posB, n_1) << ((2*n_1)+1); */
+ index = vo_L_add(index, (quant_4p_4N(posB, n_1) << (Word16) (2 * n_1 + 1)));
+ index = vo_L_add(index, quant_2p_2N1(posA[0], posA[1], n_1)); /* index += quant_2p_2N1(posA[0], posA[1], n_1); */
+ break;
+ case 3:
+ index = (quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << (Word16) (3 * n_1 + 1));
+ /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((3*n_1)+1); */
+ index =vo_L_add(index, quant_3p_3N1(posB[0], posB[1], posB[2], n_1));
+ /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1); */
+ break;
+ case 4:
+ i = 2;
+ index = (quant_4p_4N(posA, n_1) << (Word16) (2 * n_1 + 1)); /* index = quant_4p_4N(posA, n_1) << ((2*n_1)+1); */
+ index = vo_L_add(index, quant_2p_2N1(posB[0], posB[1], n_1)); /* index += quant_2p_2N1(posB[0], posB[1], n_1); */
+ break;
+ case 5:
+ i = 1;
+ index = (quant_5p_5N(posA, n_1) << N); /* index = quant_5p_5N(posA, n_1) << N; */
+ index = vo_L_add(index, quant_1p_N1(posB[0], n_1)); /* index += quant_1p_N1(posB[0], n_1); */
+ break;
+ case 6:
+ i = 0;
+ index = (quant_5p_5N(posA, n_1) << N); /* index = quant_5p_5N(posA, n_1) << N; */
+ index = vo_L_add(index, quant_1p_N1(posA[5], n_1)); /* index += quant_1p_N1(posA[5], n_1); */
+ break;
+ default:
+ index = 0;
+ fprintf(stderr, "Error in function quant_6p_6N_2\n");
+ }
+ index = vo_L_add(index, ((L_deposit_l(i) & 3L) << (Word16) (6 * N - 4))); /* index += (i & 3) << ((6*N)-4); */
+
+ return (index);
+}
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/qisf_ns.c b/media/libstagefright/codecs/amrwbenc/src/qisf_ns.c
new file mode 100644
index 0000000..00b0a53
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/qisf_ns.c
@@ -0,0 +1,111 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***************************************************************************
+* File: qisf_ns.c *
+* *
+* Description: Coding/Decoding of ISF parameters for background noise.*
+* The ISF vector is quantized using VQ with split-by-5 *
+* *
+****************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "acelp.h"
+#include "qisf_ns.tab" /* Codebooks of ISFs */
+
+/*------------------------------------------------------------------*
+* routine: Qisf_ns() *
+* ~~~~~~~~~ *
+*------------------------------------------------------------------*/
+
+void Qisf_ns(
+ Word16 * isf1, /* input : ISF in the frequency domain (0..0.5) */
+ Word16 * isf_q, /* output: quantized ISF */
+ Word16 * indice /* output: quantization indices */
+ )
+{
+ Word16 i;
+ Word32 tmp;
+
+ for (i = 0; i < ORDER; i++)
+ {
+ isf_q[i] = sub(isf1[i], mean_isf_noise[i]);
+ }
+
+ indice[0] = Sub_VQ(&isf_q[0], dico1_isf_noise, 2, SIZE_BK_NOISE1, &tmp);
+ indice[1] = Sub_VQ(&isf_q[2], dico2_isf_noise, 3, SIZE_BK_NOISE2, &tmp);
+ indice[2] = Sub_VQ(&isf_q[5], dico3_isf_noise, 3, SIZE_BK_NOISE3, &tmp);
+ indice[3] = Sub_VQ(&isf_q[8], dico4_isf_noise, 4, SIZE_BK_NOISE4, &tmp);
+ indice[4] = Sub_VQ(&isf_q[12], dico5_isf_noise, 4, SIZE_BK_NOISE5, &tmp);
+
+ /* decoding the ISFs */
+
+ Disf_ns(indice, isf_q);
+
+ return;
+}
+
+/********************************************************************
+* Function: Disf_ns() *
+* ~~~~~~~~~ *
+* Decoding of ISF parameters *
+*-------------------------------------------------------------------*
+* Arguments: *
+* indice[] : indices of the selected codebook entries *
+* isf[] : quantized ISFs (in frequency domain) *
+*********************************************************************/
+
+void Disf_ns(
+ Word16 * indice, /* input: quantization indices */
+ Word16 * isf_q /* input : ISF in the frequency domain (0..0.5) */
+ )
+{
+ Word16 i;
+
+ for (i = 0; i < 2; i++)
+ {
+ isf_q[i] = dico1_isf_noise[indice[0] * 2 + i];
+ }
+ for (i = 0; i < 3; i++)
+ {
+ isf_q[i + 2] = dico2_isf_noise[indice[1] * 3 + i];
+ }
+ for (i = 0; i < 3; i++)
+ {
+ isf_q[i + 5] = dico3_isf_noise[indice[2] * 3 + i];
+ }
+ for (i = 0; i < 4; i++)
+ {
+ isf_q[i + 8] = dico4_isf_noise[indice[3] * 4 + i];
+ }
+ for (i = 0; i < 4; i++)
+ {
+ isf_q[i + 12] = dico5_isf_noise[indice[4] * 4 + i];
+ }
+
+ for (i = 0; i < ORDER; i++)
+ {
+ isf_q[i] = add(isf_q[i], mean_isf_noise[i]);
+ }
+
+ Reorder_isf(isf_q, ISF_GAP, ORDER);
+
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c b/media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c
new file mode 100644
index 0000000..ccedb5c
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c
@@ -0,0 +1,542 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: apisf_2s.c *
+* *
+* Description: Coding/Decodeing of ISF parameters with predication
+* The ISF vector is quantized using two-stage VQ with split-by-2 *
+* in 1st stage and split-by-5(or 3) in the second stage *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "qpisf_2s.tab" /* Codebooks of isfs */
+
+#define MU 10923 /* Prediction factor (1.0/3.0) in Q15 */
+#define N_SURV_MAX 4 /* 4 survivors max */
+#define ALPHA 29491 /* 0. 9 in Q15 */
+#define ONE_ALPHA (32768-ALPHA) /* (1.0 - ALPHA) in Q15 */
+
+/* private functions */
+static void VQ_stage1(
+ Word16 * x, /* input : ISF residual vector */
+ Word16 * dico, /* input : quantization codebook */
+ Word16 dim, /* input : dimention of vector */
+ Word16 dico_size, /* input : size of quantization codebook */
+ Word16 * index, /* output: indices of survivors */
+ Word16 surv /* input : number of survivor */
+ );
+
+/**************************************************************************
+* Function: Qpisf_2s_46B() *
+* *
+* Description: Quantization of isf parameters with prediction. (46 bits) *
+* *
+* The isf vector is quantized using two-stage VQ with split-by-2 in *
+* 1st stage and split-by-5 in the second stage. *
+***************************************************************************/
+
+void Qpisf_2s_46b(
+ Word16 * isf1, /* (i) Q15 : ISF in the frequency domain (0..0.5) */
+ Word16 * isf_q, /* (o) Q15 : quantized ISF (0..0.5) */
+ Word16 * past_isfq, /* (io)Q15 : past ISF quantizer */
+ Word16 * indice, /* (o) : quantization indices */
+ Word16 nb_surv /* (i) : number of survivor (1, 2, 3 or 4) */
+ )
+{
+ Word16 tmp_ind[5];
+ Word16 surv1[N_SURV_MAX]; /* indices of survivors from 1st stage */
+ Word32 i, k, temp, min_err, distance;
+ Word16 isf[ORDER];
+ Word16 isf_stage2[ORDER];
+
+ for (i = 0; i < ORDER; i++)
+ {
+ isf[i] = vo_sub(isf1[i], mean_isf[i]);
+ isf[i] = vo_sub(isf[i], vo_mult(MU, past_isfq[i]));
+ }
+
+ VQ_stage1(&isf[0], dico1_isf, 9, SIZE_BK1, surv1, nb_surv);
+
+ distance = MAX_32;
+
+ for (k = 0; k < nb_surv; k++)
+ {
+ for (i = 0; i < 9; i++)
+ {
+ isf_stage2[i] = vo_sub(isf[i], dico1_isf[i + surv1[k] * 9]);
+ }
+ tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico21_isf, 3, SIZE_BK21, &min_err);
+ temp = min_err;
+ tmp_ind[1] = Sub_VQ(&isf_stage2[3], dico22_isf, 3, SIZE_BK22, &min_err);
+ temp = vo_L_add(temp, min_err);
+ tmp_ind[2] = Sub_VQ(&isf_stage2[6], dico23_isf, 3, SIZE_BK23, &min_err);
+ temp = vo_L_add(temp, min_err);
+
+ if(temp < distance)
+ {
+ distance = temp;
+ indice[0] = surv1[k];
+ for (i = 0; i < 3; i++)
+ {
+ indice[i + 2] = tmp_ind[i];
+ }
+ }
+ }
+
+
+ VQ_stage1(&isf[9], dico2_isf, 7, SIZE_BK2, surv1, nb_surv);
+
+ distance = MAX_32;
+
+ for (k = 0; k < nb_surv; k++)
+ {
+ for (i = 0; i < 7; i++)
+ {
+ isf_stage2[i] = vo_sub(isf[9 + i], dico2_isf[i + surv1[k] * 7]);
+ }
+
+ tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico24_isf, 3, SIZE_BK24, &min_err);
+ temp = min_err;
+ tmp_ind[1] = Sub_VQ(&isf_stage2[3], dico25_isf, 4, SIZE_BK25, &min_err);
+ temp = vo_L_add(temp, min_err);
+
+ if(temp < distance)
+ {
+ distance = temp;
+ indice[1] = surv1[k];
+ for (i = 0; i < 2; i++)
+ {
+ indice[i + 5] = tmp_ind[i];
+ }
+ }
+ }
+
+ Dpisf_2s_46b(indice, isf_q, past_isfq, isf_q, isf_q, 0, 0);
+
+ return;
+}
+
+/*****************************************************************************
+* Function: Qpisf_2s_36B() *
+* *
+* Description: Quantization of isf parameters with prediction. (36 bits) *
+* *
+* The isf vector is quantized using two-stage VQ with split-by-2 in *
+* 1st stage and split-by-3 in the second stage. *
+******************************************************************************/
+
+void Qpisf_2s_36b(
+ Word16 * isf1, /* (i) Q15 : ISF in the frequency domain (0..0.5) */
+ Word16 * isf_q, /* (o) Q15 : quantized ISF (0..0.5) */
+ Word16 * past_isfq, /* (io)Q15 : past ISF quantizer */
+ Word16 * indice, /* (o) : quantization indices */
+ Word16 nb_surv /* (i) : number of survivor (1, 2, 3 or 4) */
+ )
+{
+ Word16 i, k, tmp_ind[5];
+ Word16 surv1[N_SURV_MAX]; /* indices of survivors from 1st stage */
+ Word32 temp, min_err, distance;
+ Word16 isf[ORDER];
+ Word16 isf_stage2[ORDER];
+
+ for (i = 0; i < ORDER; i++)
+ {
+ isf[i] = vo_sub(isf1[i], mean_isf[i]);
+ isf[i] = vo_sub(isf[i], vo_mult(MU, past_isfq[i]));
+ }
+
+ VQ_stage1(&isf[0], dico1_isf, 9, SIZE_BK1, surv1, nb_surv);
+
+ distance = MAX_32;
+
+ for (k = 0; k < nb_surv; k++)
+ {
+ for (i = 0; i < 9; i++)
+ {
+ isf_stage2[i] = vo_sub(isf[i], dico1_isf[i + surv1[k] * 9]);
+ }
+
+ tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico21_isf_36b, 5, SIZE_BK21_36b, &min_err);
+ temp = min_err;
+ tmp_ind[1] = Sub_VQ(&isf_stage2[5], dico22_isf_36b, 4, SIZE_BK22_36b, &min_err);
+ temp = vo_L_add(temp, min_err);
+
+ if(temp < distance)
+ {
+ distance = temp;
+ indice[0] = surv1[k];
+ for (i = 0; i < 2; i++)
+ {
+ indice[i + 2] = tmp_ind[i];
+ }
+ }
+ }
+
+ VQ_stage1(&isf[9], dico2_isf, 7, SIZE_BK2, surv1, nb_surv);
+ distance = MAX_32;
+
+ for (k = 0; k < nb_surv; k++)
+ {
+ for (i = 0; i < 7; i++)
+ {
+ isf_stage2[i] = vo_sub(isf[9 + i], dico2_isf[i + surv1[k] * 7]);
+ }
+
+ tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico23_isf_36b, 7, SIZE_BK23_36b, &min_err);
+ temp = min_err;
+
+ if(temp < distance)
+ {
+ distance = temp;
+ indice[1] = surv1[k];
+ indice[4] = tmp_ind[0];
+ }
+ }
+
+ Dpisf_2s_36b(indice, isf_q, past_isfq, isf_q, isf_q, 0, 0);
+
+ return;
+}
+
+/*********************************************************************
+* Function: Dpisf_2s_46b() *
+* *
+* Description: Decoding of ISF parameters *
+**********************************************************************/
+
+void Dpisf_2s_46b(
+ Word16 * indice, /* input: quantization indices */
+ Word16 * isf_q, /* output: quantized ISF in frequency domain (0..0.5) */
+ Word16 * past_isfq, /* i/0 : past ISF quantizer */
+ Word16 * isfold, /* input : past quantized ISF */
+ Word16 * isf_buf, /* input : isf buffer */
+ Word16 bfi, /* input : Bad frame indicator */
+ Word16 enc_dec
+ )
+{
+ Word16 ref_isf[M], tmp;
+ Word32 i, j, L_tmp;
+
+ if (bfi == 0) /* Good frame */
+ {
+ for (i = 0; i < 9; i++)
+ {
+ isf_q[i] = dico1_isf[indice[0] * 9 + i];
+ }
+ for (i = 0; i < 7; i++)
+ {
+ isf_q[i + 9] = dico2_isf[indice[1] * 7 + i];
+ }
+
+ for (i = 0; i < 3; i++)
+ {
+ isf_q[i] = add1(isf_q[i], dico21_isf[indice[2] * 3 + i]);
+ isf_q[i + 3] = add1(isf_q[i + 3], dico22_isf[indice[3] * 3 + i]);
+ isf_q[i + 6] = add1(isf_q[i + 6], dico23_isf[indice[4] * 3 + i]);
+ isf_q[i + 9] = add1(isf_q[i + 9], dico24_isf[indice[5] * 3 + i]);
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ isf_q[i + 12] = add1(isf_q[i + 12], dico25_isf[indice[6] * 4 + i]);
+ }
+
+ for (i = 0; i < ORDER; i++)
+ {
+ tmp = isf_q[i];
+ isf_q[i] = add1(tmp, mean_isf[i]);
+ isf_q[i] = add1(isf_q[i], vo_mult(MU, past_isfq[i]));
+ past_isfq[i] = tmp;
+ }
+
+ if (enc_dec)
+ {
+ for (i = 0; i < M; i++)
+ {
+ for (j = (L_MEANBUF - 1); j > 0; j--)
+ {
+ isf_buf[j * M + i] = isf_buf[(j - 1) * M + i];
+ }
+ isf_buf[i] = isf_q[i];
+ }
+ }
+ } else
+ { /* bad frame */
+ for (i = 0; i < M; i++)
+ {
+ L_tmp = mean_isf[i] << 14;
+ for (j = 0; j < L_MEANBUF; j++)
+ {
+ L_tmp += (isf_buf[j * M + i] << 14);
+ }
+ ref_isf[i] = vo_round(L_tmp);
+ }
+
+ /* use the past ISFs slightly shifted towards their mean */
+ for (i = 0; i < ORDER; i++)
+ {
+ isf_q[i] = add1(vo_mult(ALPHA, isfold[i]), vo_mult(ONE_ALPHA, ref_isf[i]));
+ }
+
+ /* estimate past quantized residual to be used in next frame */
+ for (i = 0; i < ORDER; i++)
+ {
+ tmp = add1(ref_isf[i], vo_mult(past_isfq[i], MU)); /* predicted ISF */
+ past_isfq[i] = vo_sub(isf_q[i], tmp);
+ past_isfq[i] = (past_isfq[i] >> 1); /* past_isfq[i] *= 0.5 */
+ }
+ }
+
+ Reorder_isf(isf_q, ISF_GAP, ORDER);
+ return;
+}
+
+/*********************************************************************
+* Function: Disf_2s_36b() *
+* *
+* Description: Decoding of ISF parameters *
+*********************************************************************/
+
+void Dpisf_2s_36b(
+ Word16 * indice, /* input: quantization indices */
+ Word16 * isf_q, /* output: quantized ISF in frequency domain (0..0.5) */
+ Word16 * past_isfq, /* i/0 : past ISF quantizer */
+ Word16 * isfold, /* input : past quantized ISF */
+ Word16 * isf_buf, /* input : isf buffer */
+ Word16 bfi, /* input : Bad frame indicator */
+ Word16 enc_dec
+ )
+{
+ Word16 ref_isf[M], tmp;
+ Word32 i, j, L_tmp;
+
+ if (bfi == 0) /* Good frame */
+ {
+ for (i = 0; i < 9; i++)
+ {
+ isf_q[i] = dico1_isf[indice[0] * 9 + i];
+ }
+ for (i = 0; i < 7; i++)
+ {
+ isf_q[i + 9] = dico2_isf[indice[1] * 7 + i];
+ }
+
+ for (i = 0; i < 5; i++)
+ {
+ isf_q[i] = add1(isf_q[i], dico21_isf_36b[indice[2] * 5 + i]);
+ }
+ for (i = 0; i < 4; i++)
+ {
+ isf_q[i + 5] = add1(isf_q[i + 5], dico22_isf_36b[indice[3] * 4 + i]);
+ }
+ for (i = 0; i < 7; i++)
+ {
+ isf_q[i + 9] = add1(isf_q[i + 9], dico23_isf_36b[indice[4] * 7 + i]);
+ }
+
+ for (i = 0; i < ORDER; i++)
+ {
+ tmp = isf_q[i];
+ isf_q[i] = add1(tmp, mean_isf[i]);
+ isf_q[i] = add1(isf_q[i], vo_mult(MU, past_isfq[i]));
+ past_isfq[i] = tmp;
+ }
+
+
+ if (enc_dec)
+ {
+ for (i = 0; i < M; i++)
+ {
+ for (j = (L_MEANBUF - 1); j > 0; j--)
+ {
+ isf_buf[j * M + i] = isf_buf[(j - 1) * M + i];
+ }
+ isf_buf[i] = isf_q[i];
+ }
+ }
+ } else
+ { /* bad frame */
+ for (i = 0; i < M; i++)
+ {
+ L_tmp = (mean_isf[i] << 14);
+ for (j = 0; j < L_MEANBUF; j++)
+ {
+ L_tmp += (isf_buf[j * M + i] << 14);
+ }
+ ref_isf[i] = vo_round(L_tmp);
+ }
+
+ /* use the past ISFs slightly shifted towards their mean */
+ for (i = 0; i < ORDER; i++)
+ {
+ isf_q[i] = add1(vo_mult(ALPHA, isfold[i]), vo_mult(ONE_ALPHA, ref_isf[i]));
+ }
+
+ /* estimate past quantized residual to be used in next frame */
+ for (i = 0; i < ORDER; i++)
+ {
+ tmp = add1(ref_isf[i], vo_mult(past_isfq[i], MU)); /* predicted ISF */
+ past_isfq[i] = vo_sub(isf_q[i], tmp);
+ past_isfq[i] = past_isfq[i] >> 1; /* past_isfq[i] *= 0.5 */
+ }
+ }
+
+ Reorder_isf(isf_q, ISF_GAP, ORDER);
+
+ return;
+}
+
+
+/***************************************************************************
+* Function: Reorder_isf() *
+* *
+* Description: To make sure that the isfs are properly order and to *
+* keep a certain minimum distance between consecutive isfs. *
+*--------------------------------------------------------------------------*
+* Argument description in/out *
+* *
+* isf[] vector of isfs i/o *
+* min_dist minimum required distance i *
+* n LPC order i *
+****************************************************************************/
+
+void Reorder_isf(
+ Word16 * isf, /* (i/o) Q15: ISF in the frequency domain (0..0.5) */
+ Word16 min_dist, /* (i) Q15 : minimum distance to keep */
+ Word16 n /* (i) : number of ISF */
+ )
+{
+ Word32 i;
+ Word16 isf_min;
+
+ isf_min = min_dist;
+ for (i = 0; i < n - 1; i++)
+ {
+ if(isf[i] < isf_min)
+ {
+ isf[i] = isf_min;
+ }
+ isf_min = (isf[i] + min_dist);
+ }
+ return;
+}
+
+
+Word16 Sub_VQ( /* output: return quantization index */
+ Word16 * x, /* input : ISF residual vector */
+ Word16 * dico, /* input : quantization codebook */
+ Word16 dim, /* input : dimention of vector */
+ Word16 dico_size, /* input : size of quantization codebook */
+ Word32 * distance /* output: error of quantization */
+ )
+{
+ Word16 temp, *p_dico;
+ Word32 i, j, index;
+ Word32 dist_min, dist;
+
+ dist_min = MAX_32;
+ p_dico = dico;
+
+ index = 0;
+ for (i = 0; i < dico_size; i++)
+ {
+ dist = 0;
+
+ for (j = 0; j < dim; j++)
+ {
+ temp = x[j] - (*p_dico++);
+ dist += (temp * temp)<<1;
+ }
+
+ if(dist < dist_min)
+ {
+ dist_min = dist;
+ index = i;
+ }
+ }
+
+ *distance = dist_min;
+
+ /* Reading the selected vector */
+ p_dico = &dico[index * dim];
+ for (j = 0; j < dim; j++)
+ {
+ x[j] = *p_dico++;
+ }
+
+ return index;
+}
+
+
+static void VQ_stage1(
+ Word16 * x, /* input : ISF residual vector */
+ Word16 * dico, /* input : quantization codebook */
+ Word16 dim, /* input : dimention of vector */
+ Word16 dico_size, /* input : size of quantization codebook */
+ Word16 * index, /* output: indices of survivors */
+ Word16 surv /* input : number of survivor */
+ )
+{
+ Word16 temp, *p_dico;
+ Word32 i, j, k, l;
+ Word32 dist_min[N_SURV_MAX], dist;
+
+ dist_min[0] = MAX_32;
+ dist_min[1] = MAX_32;
+ dist_min[2] = MAX_32;
+ dist_min[3] = MAX_32;
+ index[0] = 0;
+ index[1] = 1;
+ index[2] = 2;
+ index[3] = 3;
+
+ p_dico = dico;
+
+ for (i = 0; i < dico_size; i++)
+ {
+ dist = 0;
+ for (j = 0; j < dim; j++)
+ {
+ temp = x[j] - (*p_dico++);
+ dist += (temp * temp)<<1;
+ }
+
+ for (k = 0; k < surv; k++)
+ {
+ if(dist < dist_min[k])
+ {
+ for (l = surv - 1; l > k; l--)
+ {
+ dist_min[l] = dist_min[l - 1];
+ index[l] = index[l - 1];
+ }
+ dist_min[k] = dist;
+ index[k] = i;
+ break;
+ }
+ }
+ }
+ return;
+}
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/random.c b/media/libstagefright/codecs/amrwbenc/src/random.c
new file mode 100644
index 0000000..8baa8bf
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/random.c
@@ -0,0 +1,33 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: random.c *
+* *
+* Description: Signed 16 bits random generator *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+
+Word16 Random(Word16 * seed)
+{
+ /* static Word16 seed = 21845; */
+ *seed = (Word16)(L_add((L_mult(*seed, 31821) >> 1), 13849L));
+ return (*seed);
+}
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/residu.c b/media/libstagefright/codecs/amrwbenc/src/residu.c
new file mode 100644
index 0000000..6829882
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/residu.c
@@ -0,0 +1,67 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: residu.c *
+* *
+* Description: Compute the LPC residual by filtering *
+* the input speech through A(z) *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+
+void Residu(
+ Word16 a[], /* (i) Q12 : prediction coefficients */
+ Word16 x[], /* (i) : speech (values x[-m..-1] are needed */
+ Word16 y[], /* (o) x2 : residual signal */
+ Word16 lg /* (i) : size of filtering */
+ )
+{
+ Word16 i,*p1, *p2;
+ Word32 s;
+ for (i = 0; i < lg; i++)
+ {
+ p1 = a;
+ p2 = &x[i];
+ s = vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1++), (*p2--));
+ s += vo_mult32((*p1), (*p2));
+
+ s = L_shl2(s, 5);
+ y[i] = extract_h(L_add(s, 0x8000));
+ }
+
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/scale.c b/media/libstagefright/codecs/amrwbenc/src/scale.c
new file mode 100644
index 0000000..af40121
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/scale.c
@@ -0,0 +1,57 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: scale.c *
+* *
+* Description: Scale signal to get maximum of dynamic *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+
+void Scale_sig(
+ Word16 x[], /* (i/o) : signal to scale */
+ Word16 lg, /* (i) : size of x[] */
+ Word16 exp /* (i) : exponent: x = round(x << exp) */
+ )
+{
+ Word32 i;
+ Word32 L_tmp;
+ if(exp > 0)
+ {
+ for (i = lg - 1 ; i >= 0; i--)
+ {
+ L_tmp = L_shl2(x[i], 16 + exp);
+ x[i] = extract_h(L_add(L_tmp, 0x8000));
+ }
+ }
+ else
+ {
+ exp = -exp;
+ for (i = lg - 1; i >= 0; i--)
+ {
+ L_tmp = x[i] << 16;
+ L_tmp >>= exp;
+ x[i] = (L_tmp + 0x8000)>>16;
+ }
+ }
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/stream.c b/media/libstagefright/codecs/amrwbenc/src/stream.c
new file mode 100644
index 0000000..a708235
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/stream.c
@@ -0,0 +1,58 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: stream.c *
+* *
+* Description: VOME API Buffer Operator Implement Code *
+* *
+************************************************************************/
+
+#include "stream.h"
+
+void voAWB_InitFrameBuffer(FrameStream *stream)
+{
+ stream->set_ptr = NULL;
+ stream->frame_ptr_bk = stream->frame_ptr;
+ stream->set_len = 0;
+ stream->framebuffer_len = 0;
+ stream->frame_storelen = 0;
+}
+
+void voAWB_UpdateFrameBuffer(
+ FrameStream *stream,
+ VO_MEM_OPERATOR *pMemOP
+ )
+{
+ int len;
+ len = MIN(Frame_Maxsize - stream->frame_storelen, stream->set_len);
+ pMemOP->Copy(VO_INDEX_ENC_AMRWB, stream->frame_ptr_bk + stream->frame_storelen , stream->set_ptr, len);
+ stream->set_len -= len;
+ stream->set_ptr += len;
+ stream->framebuffer_len = stream->frame_storelen + len;
+ stream->frame_ptr = stream->frame_ptr_bk;
+ stream->used_len += len;
+}
+
+void voAWB_FlushFrameBuffer(FrameStream *stream)
+{
+ stream->set_ptr = NULL;
+ stream->frame_ptr_bk = stream->frame_ptr;
+ stream->set_len = 0;
+ stream->framebuffer_len = 0;
+ stream->frame_storelen = 0;
+}
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/syn_filt.c b/media/libstagefright/codecs/amrwbenc/src/syn_filt.c
new file mode 100644
index 0000000..6c1fb8e
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/syn_filt.c
@@ -0,0 +1,160 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: syn_filt.c *
+* *
+* Description: Do the synthesis filtering 1/A(z) *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "cnst.h"
+
+void Syn_filt(
+ Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients */
+ Word16 x[], /* (i) : input signal */
+ Word16 y[], /* (o) : output signal */
+ Word16 lg, /* (i) : size of filtering */
+ Word16 mem[], /* (i/o) : memory associated with this filtering. */
+ Word16 update /* (i) : 0=no update, 1=update of memory. */
+ )
+{
+ Word32 i, a0;
+ Word16 y_buf[L_SUBFR16k + M16k];
+ Word32 L_tmp;
+ Word16 *yy, *p1, *p2;
+ yy = &y_buf[0];
+ /* copy initial filter states into synthesis buffer */
+ for (i = 0; i < 16; i++)
+ {
+ *yy++ = mem[i];
+ }
+ a0 = (a[0] >> 1); /* input / 2 */
+ /* Do the filtering. */
+ for (i = 0; i < lg; i++)
+ {
+ p1 = &a[1];
+ p2 = &yy[i-1];
+ L_tmp = vo_mult32(a0, x[i]);
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1++), (*p2--));
+ L_tmp -= vo_mult32((*p1), (*p2));
+
+ L_tmp = L_shl2(L_tmp, 4);
+ y[i] = yy[i] = extract_h(L_add(L_tmp, 0x8000));
+ }
+ /* Update memory if required */
+ if (update)
+ for (i = 0; i < 16; i++)
+ {
+ mem[i] = yy[lg - 16 + i];
+ }
+ return;
+}
+
+
+void Syn_filt_32(
+ Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients */
+ Word16 m, /* (i) : order of LP filter */
+ Word16 exc[], /* (i) Qnew: excitation (exc[i] >> Qnew) */
+ Word16 Qnew, /* (i) : exc scaling = 0(min) to 8(max) */
+ Word16 sig_hi[], /* (o) /16 : synthesis high */
+ Word16 sig_lo[], /* (o) /16 : synthesis low */
+ Word16 lg /* (i) : size of filtering */
+ )
+{
+ Word32 i,a0;
+ Word32 L_tmp, L_tmp1;
+ Word16 *p1, *p2, *p3;
+ a0 = a[0] >> (4 + Qnew); /* input / 16 and >>Qnew */
+ /* Do the filtering. */
+ for (i = 0; i < lg; i++)
+ {
+ L_tmp = 0;
+ L_tmp1 = 0;
+ p1 = a;
+ p2 = &sig_lo[i - 1];
+ p3 = &sig_hi[i - 1];
+
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ L_tmp -= vo_mult32((*p2--), (*p1));
+ L_tmp1 -= vo_mult32((*p3--), (*p1++));
+
+ L_tmp = L_tmp >> 11;
+ L_tmp += vo_L_mult(exc[i], a0);
+
+ /* sig_hi = bit16 to bit31 of synthesis */
+ L_tmp = L_tmp - (L_tmp1<<1);
+
+ L_tmp = L_tmp >> 3; /* ai in Q12 */
+ sig_hi[i] = extract_h(L_tmp);
+
+ /* sig_lo = bit4 to bit15 of synthesis */
+ L_tmp >>= 4; /* 4 : sig_lo[i] >> 4 */
+ sig_lo[i] = (Word16)((L_tmp - (sig_hi[i] << 13)));
+ }
+
+ return;
+}
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/updt_tar.c b/media/libstagefright/codecs/amrwbenc/src/updt_tar.c
new file mode 100644
index 0000000..f3e5650
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/updt_tar.c
@@ -0,0 +1,49 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: updt_tar.c *
+* *
+* Description: Update the target vector for codebook search *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+
+void Updt_tar(
+ Word16 * x, /* (i) Q0 : old target (for pitch search) */
+ Word16 * x2, /* (o) Q0 : new target (for codebook search) */
+ Word16 * y, /* (i) Q0 : filtered adaptive codebook vector */
+ Word16 gain, /* (i) Q14 : adaptive codebook gain */
+ Word16 L /* (i) : subframe size */
+ )
+{
+ Word32 i;
+ Word32 L_tmp;
+
+ for (i = 0; i < L; i++)
+ {
+ L_tmp = x[i] << 15;
+ L_tmp -= (y[i] * gain)<<1;
+ x2[i] = extract_h(L_shl2(L_tmp, 1));
+ }
+
+ return;
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/util.c b/media/libstagefright/codecs/amrwbenc/src/util.c
new file mode 100644
index 0000000..78141dd
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/util.c
@@ -0,0 +1,74 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: util.c *
+* *
+* Description: Reset and Copy buffer *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+
+/***********************************************************************
+* Function: Set_zero() *
+* Description: Set vector x[] to zero *
+************************************************************************/
+
+void Set_zero(
+ Word16 x[], /* (o) : vector to clear */
+ Word16 L /* (i) : length of vector */
+ )
+{
+ Word32 num = (Word32)L;
+ do{
+ *x++ = 0;
+ }while(--num !=0);
+}
+
+
+/*********************************************************************
+* Function: Copy() *
+* *
+* Description: Copy vector x[] to y[] *
+*********************************************************************/
+
+void Copy(
+ Word16 x[], /* (i) : input vector */
+ Word16 y[], /* (o) : output vector */
+ Word16 L /* (i) : vector length */
+ )
+{
+ Word32 temp1,temp2,num;
+ if(L&1)
+ {
+ temp1 = *x++;
+ *y++ = temp1;
+ }
+ num = (Word32)(L>>1);
+ temp1 = *x++;
+ temp2 = *x++;
+ do{
+ *y++ = temp1;
+ *y++ = temp2;
+ temp1 = *x++;
+ temp2 = *x++;
+ }while(--num!=0);
+}
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
new file mode 100644
index 0000000..d0d99a7
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
@@ -0,0 +1,1941 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: voAMRWBEnc.c *
+* *
+* Description: Performs the main encoder routine *
+* Fixed-point C simulation of AMR WB ACELP coding *
+* algorithm with 20 msspeech frames for *
+* wideband speech signals. *
+* *
+************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "math_op.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "cod_main.h"
+#include "bits.h"
+#include "main.h"
+#include "voAMRWB.h"
+#include "mem_align.h"
+#include "cmnMemory.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* LPC interpolation coef {0.45, 0.8, 0.96, 1.0}; in Q15 */
+static Word16 interpol_frac[NB_SUBFR] = {14746, 26214, 31457, 32767};
+
+/* isp tables for initialization */
+static Word16 isp_init[M] =
+{
+ 32138, 30274, 27246, 23170, 18205, 12540, 6393, 0,
+ -6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475
+};
+
+static Word16 isf_init[M] =
+{
+ 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192,
+ 9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840
+};
+
+/* High Band encoding */
+static const Word16 HP_gain[16] =
+{
+ 3624, 4673, 5597, 6479, 7425, 8378, 9324, 10264,
+ 11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728
+};
+
+/* Private function declaration */
+static Word16 synthesis(
+ Word16 Aq[], /* A(z) : quantized Az */
+ Word16 exc[], /* (i) : excitation at 12kHz */
+ Word16 Q_new, /* (i) : scaling performed on exc */
+ Word16 synth16k[], /* (o) : 16kHz synthesis signal */
+ Coder_State * st /* (i/o) : State structure */
+ );
+
+/* Codec some parameters initialization */
+void Reset_encoder(void *st, Word16 reset_all)
+{
+ Word16 i;
+ Coder_State *cod_state;
+ cod_state = (Coder_State *) st;
+ Set_zero(cod_state->old_exc, PIT_MAX + L_INTERPOL);
+ Set_zero(cod_state->mem_syn, M);
+ Set_zero(cod_state->past_isfq, M);
+ cod_state->mem_w0 = 0;
+ cod_state->tilt_code = 0;
+ cod_state->first_frame = 1;
+ Init_gp_clip(cod_state->gp_clip);
+ cod_state->L_gc_thres = 0;
+ if (reset_all != 0)
+ {
+ /* Static vectors to zero */
+ Set_zero(cod_state->old_speech, L_TOTAL - L_FRAME);
+ Set_zero(cod_state->old_wsp, (PIT_MAX / OPL_DECIM));
+ Set_zero(cod_state->mem_decim2, 3);
+ /* routines initialization */
+ Init_Decim_12k8(cod_state->mem_decim);
+ Init_HP50_12k8(cod_state->mem_sig_in);
+ Init_Levinson(cod_state->mem_levinson);
+ Init_Q_gain2(cod_state->qua_gain);
+ Init_Hp_wsp(cod_state->hp_wsp_mem);
+ /* isp initialization */
+ Copy(isp_init, cod_state->ispold, M);
+ Copy(isp_init, cod_state->ispold_q, M);
+ /* variable initialization */
+ cod_state->mem_preemph = 0;
+ cod_state->mem_wsp = 0;
+ cod_state->Q_old = 15;
+ cod_state->Q_max[0] = 15;
+ cod_state->Q_max[1] = 15;
+ cod_state->old_wsp_max = 0;
+ cod_state->old_wsp_shift = 0;
+ /* pitch ol initialization */
+ cod_state->old_T0_med = 40;
+ cod_state->ol_gain = 0;
+ cod_state->ada_w = 0;
+ cod_state->ol_wght_flg = 0;
+ for (i = 0; i < 5; i++)
+ {
+ cod_state->old_ol_lag[i] = 40;
+ }
+ Set_zero(cod_state->old_hp_wsp, (L_FRAME / 2) / OPL_DECIM + (PIT_MAX / OPL_DECIM));
+ Set_zero(cod_state->mem_syn_hf, M);
+ Set_zero(cod_state->mem_syn_hi, M);
+ Set_zero(cod_state->mem_syn_lo, M);
+ Init_HP50_12k8(cod_state->mem_sig_out);
+ Init_Filt_6k_7k(cod_state->mem_hf);
+ Init_HP400_12k8(cod_state->mem_hp400);
+ Copy(isf_init, cod_state->isfold, M);
+ cod_state->mem_deemph = 0;
+ cod_state->seed2 = 21845;
+ Init_Filt_6k_7k(cod_state->mem_hf2);
+ cod_state->gain_alpha = 32767;
+ cod_state->vad_hist = 0;
+ wb_vad_reset(cod_state->vadSt);
+ dtx_enc_reset(cod_state->dtx_encSt, isf_init);
+ }
+ return;
+}
+
+/*-----------------------------------------------------------------*
+* Funtion coder *
+* ~~~~~ *
+* ->Main coder routine. *
+* *
+*-----------------------------------------------------------------*/
+void coder(
+ Word16 * mode, /* input : used mode */
+ Word16 speech16k[], /* input : 320 new speech samples (at 16 kHz) */
+ Word16 prms[], /* output: output parameters */
+ Word16 * ser_size, /* output: bit rate of the used mode */
+ void *spe_state, /* i/o : State structure */
+ Word16 allow_dtx /* input : DTX ON/OFF */
+ )
+{
+ /* Coder states */
+ Coder_State *st;
+ /* Speech vector */
+ Word16 old_speech[L_TOTAL];
+ Word16 *new_speech, *speech, *p_window;
+
+ /* Weighted speech vector */
+ Word16 old_wsp[L_FRAME + (PIT_MAX / OPL_DECIM)];
+ Word16 *wsp;
+
+ /* Excitation vector */
+ Word16 old_exc[(L_FRAME + 1) + PIT_MAX + L_INTERPOL];
+ Word16 *exc;
+
+ /* LPC coefficients */
+ Word16 r_h[M + 1], r_l[M + 1]; /* Autocorrelations of windowed speech */
+ Word16 rc[M]; /* Reflection coefficients. */
+ Word16 Ap[M + 1]; /* A(z) with spectral expansion */
+ Word16 ispnew[M]; /* immittance spectral pairs at 4nd sfr */
+ Word16 ispnew_q[M]; /* quantized ISPs at 4nd subframe */
+ Word16 isf[M]; /* ISF (frequency domain) at 4nd sfr */
+ Word16 *p_A, *p_Aq; /* ptr to A(z) for the 4 subframes */
+ Word16 A[NB_SUBFR * (M + 1)]; /* A(z) unquantized for the 4 subframes */
+ Word16 Aq[NB_SUBFR * (M + 1)]; /* A(z) quantized for the 4 subframes */
+
+ /* Other vectors */
+ Word16 xn[L_SUBFR]; /* Target vector for pitch search */
+ Word16 xn2[L_SUBFR]; /* Target vector for codebook search */
+ Word16 dn[L_SUBFR]; /* Correlation between xn2 and h1 */
+ Word16 cn[L_SUBFR]; /* Target vector in residual domain */
+ Word16 h1[L_SUBFR]; /* Impulse response vector */
+ Word16 h2[L_SUBFR]; /* Impulse response vector */
+ Word16 code[L_SUBFR]; /* Fixed codebook excitation */
+ Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */
+ Word16 y2[L_SUBFR]; /* Filtered adaptive excitation */
+ Word16 error[M + L_SUBFR]; /* error of quantization */
+ Word16 synth[L_SUBFR]; /* 12.8kHz synthesis vector */
+ Word16 exc2[L_FRAME]; /* excitation vector */
+ Word16 buf[L_FRAME]; /* VAD buffer */
+
+ /* Scalars */
+ Word32 i, j, i_subfr, select, pit_flag, clip_gain, vad_flag;
+ Word16 codec_mode;
+ Word16 T_op, T_op2, T0, T0_min, T0_max, T0_frac, index;
+ Word16 gain_pit, gain_code, g_coeff[4], g_coeff2[4];
+ Word16 tmp, gain1, gain2, exp, Q_new, mu, shift, max;
+ Word16 voice_fac;
+ Word16 indice[8];
+ Word32 L_tmp, L_gain_code, L_max, L_tmp1;
+ Word16 code2[L_SUBFR]; /* Fixed codebook excitation */
+ Word16 stab_fac, fac, gain_code_lo;
+
+ Word16 corr_gain;
+ Word16 *vo_p0, *vo_p1, *vo_p2, *vo_p3;
+
+ st = (Coder_State *) spe_state;
+
+ *ser_size = nb_of_bits[*mode];
+ codec_mode = *mode;
+
+ /*--------------------------------------------------------------------------*
+ * Initialize pointers to speech vector. *
+ * *
+ * *
+ * |-------|-------|-------|-------|-------|-------| *
+ * past sp sf1 sf2 sf3 sf4 L_NEXT *
+ * <------- Total speech buffer (L_TOTAL) ------> *
+ * old_speech *
+ * <------- LPC analysis window (L_WINDOW) ------> *
+ * | <-- present frame (L_FRAME) ----> *
+ * p_window | <----- new speech (L_FRAME) ----> *
+ * | | *
+ * speech | *
+ * new_speech *
+ *--------------------------------------------------------------------------*/
+
+ new_speech = old_speech + L_TOTAL - L_FRAME - L_FILT; /* New speech */
+ speech = old_speech + L_TOTAL - L_FRAME - L_NEXT; /* Present frame */
+ p_window = old_speech + L_TOTAL - L_WINDOW;
+
+ exc = old_exc + PIT_MAX + L_INTERPOL;
+ wsp = old_wsp + (PIT_MAX / OPL_DECIM);
+
+ /* copy coder memory state into working space */
+ Copy(st->old_speech, old_speech, L_TOTAL - L_FRAME);
+ Copy(st->old_wsp, old_wsp, PIT_MAX / OPL_DECIM);
+ Copy(st->old_exc, old_exc, PIT_MAX + L_INTERPOL);
+
+ /*---------------------------------------------------------------*
+ * Down sampling signal from 16kHz to 12.8kHz *
+ * -> The signal is extended by L_FILT samples (padded to zero) *
+ * to avoid additional delay (L_FILT samples) in the coder. *
+ * The last L_FILT samples are approximated after decimation and *
+ * are used (and windowed) only in autocorrelations. *
+ *---------------------------------------------------------------*/
+
+ Decim_12k8(speech16k, L_FRAME16k, new_speech, st->mem_decim);
+
+ /* last L_FILT samples for autocorrelation window */
+ Copy(st->mem_decim, code, 2 * L_FILT16k);
+ Set_zero(error, L_FILT16k); /* set next sample to zero */
+ Decim_12k8(error, L_FILT16k, new_speech + L_FRAME, code);
+
+ /*---------------------------------------------------------------*
+ * Perform 50Hz HP filtering of input signal. *
+ *---------------------------------------------------------------*/
+
+ HP50_12k8(new_speech, L_FRAME, st->mem_sig_in);
+
+ /* last L_FILT samples for autocorrelation window */
+ Copy(st->mem_sig_in, code, 6);
+ HP50_12k8(new_speech + L_FRAME, L_FILT, code);
+
+ /*---------------------------------------------------------------*
+ * Perform fixed preemphasis through 1 - g z^-1 *
+ * Scale signal to get maximum of precision in filtering *
+ *---------------------------------------------------------------*/
+
+ mu = PREEMPH_FAC >> 1; /* Q15 --> Q14 */
+
+ /* get max of new preemphased samples (L_FRAME+L_FILT) */
+ L_tmp = new_speech[0] << 15;
+ L_tmp -= (st->mem_preemph * mu)<<1;
+ L_max = L_abs(L_tmp);
+
+ for (i = 1; i < L_FRAME + L_FILT; i++)
+ {
+ L_tmp = new_speech[i] << 15;
+ L_tmp -= (new_speech[i - 1] * mu)<<1;
+ L_tmp = L_abs(L_tmp);
+ if(L_tmp > L_max)
+ {
+ L_max = L_tmp;
+ }
+ }
+
+ /* get scaling factor for new and previous samples */
+ /* limit scaling to Q_MAX to keep dynamic for ringing in low signal */
+ /* limit scaling to Q_MAX also to avoid a[0]<1 in syn_filt_32 */
+ tmp = extract_h(L_max);
+ if (tmp == 0)
+ {
+ shift = Q_MAX;
+ } else
+ {
+ shift = norm_s(tmp) - 1;
+ if (shift < 0)
+ {
+ shift = 0;
+ }
+ if (shift > Q_MAX)
+ {
+ shift = Q_MAX;
+ }
+ }
+ Q_new = shift;
+ if (Q_new > st->Q_max[0])
+ {
+ Q_new = st->Q_max[0];
+ }
+ if (Q_new > st->Q_max[1])
+ {
+ Q_new = st->Q_max[1];
+ }
+ exp = (Q_new - st->Q_old);
+ st->Q_old = Q_new;
+ st->Q_max[1] = st->Q_max[0];
+ st->Q_max[0] = shift;
+
+ /* preemphasis with scaling (L_FRAME+L_FILT) */
+ tmp = new_speech[L_FRAME - 1];
+
+ for (i = L_FRAME + L_FILT - 1; i > 0; i--)
+ {
+ L_tmp = new_speech[i] << 15;
+ L_tmp -= (new_speech[i - 1] * mu)<<1;
+ L_tmp = (L_tmp << Q_new);
+ new_speech[i] = vo_round(L_tmp);
+ }
+
+ L_tmp = new_speech[0] << 15;
+ L_tmp -= (st->mem_preemph * mu)<<1;
+ L_tmp = (L_tmp << Q_new);
+ new_speech[0] = vo_round(L_tmp);
+
+ st->mem_preemph = tmp;
+
+ /* scale previous samples and memory */
+
+ Scale_sig(old_speech, L_TOTAL - L_FRAME - L_FILT, exp);
+ Scale_sig(old_exc, PIT_MAX + L_INTERPOL, exp);
+ Scale_sig(st->mem_syn, M, exp);
+ Scale_sig(st->mem_decim2, 3, exp);
+ Scale_sig(&(st->mem_wsp), 1, exp);
+ Scale_sig(&(st->mem_w0), 1, exp);
+
+ /*------------------------------------------------------------------------*
+ * Call VAD *
+ * Preemphesis scale down signal in low frequency and keep dynamic in HF.*
+ * Vad work slightly in futur (new_speech = speech + L_NEXT - L_FILT). *
+ *------------------------------------------------------------------------*/
+ Copy(new_speech, buf, L_FRAME);
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Scale_sig_opt(buf, L_FRAME, 1 - Q_new);
+#else
+ Scale_sig(buf, L_FRAME, 1 - Q_new);
+#endif
+
+ vad_flag = wb_vad(st->vadSt, buf); /* Voice Activity Detection */
+ if (vad_flag == 0)
+ {
+ st->vad_hist = (st->vad_hist + 1);
+ } else
+ {
+ st->vad_hist = 0;
+ }
+
+ /* DTX processing */
+ if (allow_dtx != 0)
+ {
+ /* Note that mode may change here */
+ tx_dtx_handler(st->dtx_encSt, vad_flag, mode);
+ *ser_size = nb_of_bits[*mode];
+ }
+
+ if(*mode != MRDTX)
+ {
+ Parm_serial(vad_flag, 1, &prms);
+ }
+ /*------------------------------------------------------------------------*
+ * Perform LPC analysis *
+ * ~~~~~~~~~~~~~~~~~~~~ *
+ * - autocorrelation + lag windowing *
+ * - Levinson-durbin algorithm to find a[] *
+ * - convert a[] to isp[] *
+ * - convert isp[] to isf[] for quantization *
+ * - quantize and code the isf[] *
+ * - convert isf[] to isp[] for interpolation *
+ * - find the interpolated ISPs and convert to a[] for the 4 subframes *
+ *------------------------------------------------------------------------*/
+
+ /* LP analysis centered at 4nd subframe */
+ Autocorr(p_window, M, r_h, r_l); /* Autocorrelations */
+ Lag_window(r_h, r_l); /* Lag windowing */
+ Levinson(r_h, r_l, A, rc, st->mem_levinson); /* Levinson Durbin */
+ Az_isp(A, ispnew, st->ispold); /* From A(z) to ISP */
+
+ /* Find the interpolated ISPs and convert to a[] for all subframes */
+ Int_isp(st->ispold, ispnew, interpol_frac, A);
+
+ /* update ispold[] for the next frame */
+ Copy(ispnew, st->ispold, M);
+
+ /* Convert ISPs to frequency domain 0..6400 */
+ Isp_isf(ispnew, isf, M);
+
+ /* check resonance for pitch clipping algorithm */
+ Gp_clip_test_isf(isf, st->gp_clip);
+
+ /*----------------------------------------------------------------------*
+ * Perform PITCH_OL analysis *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~ *
+ * - Find the residual res[] for the whole speech frame *
+ * - Find the weighted input speech wsp[] for the whole speech frame *
+ * - scale wsp[] to avoid overflow in pitch estimation *
+ * - Find open loop pitch lag for whole speech frame *
+ *----------------------------------------------------------------------*/
+ p_A = A;
+ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+ {
+ /* Weighting of LPC coefficients */
+ Weight_a(p_A, Ap, GAMMA1, M);
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Residu_opt(Ap, &speech[i_subfr], &wsp[i_subfr], L_SUBFR);
+#else
+ Residu(Ap, &speech[i_subfr], &wsp[i_subfr], L_SUBFR);
+#endif
+
+ p_A += (M + 1);
+ }
+
+ Deemph2(wsp, TILT_FAC, L_FRAME, &(st->mem_wsp));
+
+ /* find maximum value on wsp[] for 12 bits scaling */
+ max = 0;
+ for (i = 0; i < L_FRAME; i++)
+ {
+ tmp = abs_s(wsp[i]);
+ if(tmp > max)
+ {
+ max = tmp;
+ }
+ }
+ tmp = st->old_wsp_max;
+ if(max > tmp)
+ {
+ tmp = max; /* tmp = max(wsp_max, old_wsp_max) */
+ }
+ st->old_wsp_max = max;
+
+ shift = norm_s(tmp) - 3;
+ if (shift > 0)
+ {
+ shift = 0; /* shift = 0..-3 */
+ }
+ /* decimation of wsp[] to search pitch in LF and to reduce complexity */
+ LP_Decim2(wsp, L_FRAME, st->mem_decim2);
+
+ /* scale wsp[] in 12 bits to avoid overflow */
+#ifdef ASM_OPT /* asm optimization branch */
+ Scale_sig_opt(wsp, L_FRAME / OPL_DECIM, shift);
+#else
+ Scale_sig(wsp, L_FRAME / OPL_DECIM, shift);
+#endif
+ /* scale old_wsp (warning: exp must be Q_new-Q_old) */
+ exp = exp + (shift - st->old_wsp_shift);
+ st->old_wsp_shift = shift;
+
+ Scale_sig(old_wsp, PIT_MAX / OPL_DECIM, exp);
+ Scale_sig(st->old_hp_wsp, PIT_MAX / OPL_DECIM, exp);
+
+ scale_mem_Hp_wsp(st->hp_wsp_mem, exp);
+
+ /* Find open loop pitch lag for whole speech frame */
+
+ if(*ser_size == NBBITS_7k)
+ {
+ /* Find open loop pitch lag for whole speech frame */
+ T_op = Pitch_med_ol(wsp, st, L_FRAME / OPL_DECIM);
+ } else
+ {
+ /* Find open loop pitch lag for first 1/2 frame */
+ T_op = Pitch_med_ol(wsp, st, (L_FRAME/2) / OPL_DECIM);
+ }
+
+ if(st->ol_gain > 19661) /* 0.6 in Q15 */
+ {
+ st->old_T0_med = Med_olag(T_op, st->old_ol_lag);
+ st->ada_w = 32767;
+ } else
+ {
+ st->ada_w = vo_mult(st->ada_w, 29491);
+ }
+
+ if(st->ada_w < 26214)
+ st->ol_wght_flg = 0;
+ else
+ st->ol_wght_flg = 1;
+
+ wb_vad_tone_detection(st->vadSt, st->ol_gain);
+ T_op *= OPL_DECIM;
+
+ if(*ser_size != NBBITS_7k)
+ {
+ /* Find open loop pitch lag for second 1/2 frame */
+ T_op2 = Pitch_med_ol(wsp + ((L_FRAME / 2) / OPL_DECIM), st, (L_FRAME/2) / OPL_DECIM);
+
+ if(st->ol_gain > 19661) /* 0.6 in Q15 */
+ {
+ st->old_T0_med = Med_olag(T_op2, st->old_ol_lag);
+ st->ada_w = 32767;
+ } else
+ {
+ st->ada_w = mult(st->ada_w, 29491);
+ }
+
+ if(st->ada_w < 26214)
+ st->ol_wght_flg = 0;
+ else
+ st->ol_wght_flg = 1;
+
+ wb_vad_tone_detection(st->vadSt, st->ol_gain);
+
+ T_op2 *= OPL_DECIM;
+
+ } else
+ {
+ T_op2 = T_op;
+ }
+ /*----------------------------------------------------------------------*
+ * DTX-CNG *
+ *----------------------------------------------------------------------*/
+ if(*mode == MRDTX) /* CNG mode */
+ {
+ /* Buffer isf's and energy */
+#ifdef ASM_OPT /* asm optimization branch */
+ Residu_opt(&A[3 * (M + 1)], speech, exc, L_FRAME);
+#else
+ Residu(&A[3 * (M + 1)], speech, exc, L_FRAME);
+#endif
+
+ for (i = 0; i < L_FRAME; i++)
+ {
+ exc2[i] = shr(exc[i], Q_new);
+ }
+
+ L_tmp = 0;
+ for (i = 0; i < L_FRAME; i++)
+ L_tmp += (exc2[i] * exc2[i])<<1;
+
+ L_tmp >>= 1;
+
+ dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
+
+ /* Quantize and code the ISFs */
+ dtx_enc(st->dtx_encSt, isf, exc2, &prms);
+
+ /* Convert ISFs to the cosine domain */
+ Isf_isp(isf, ispnew_q, M);
+ Isp_Az(ispnew_q, Aq, M, 0);
+
+ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+ {
+ corr_gain = synthesis(Aq, &exc2[i_subfr], 0, &speech16k[i_subfr * 5 / 4], st);
+ }
+ Copy(isf, st->isfold, M);
+
+ /* reset speech coder memories */
+ Reset_encoder(st, 0);
+
+ /*--------------------------------------------------*
+ * Update signal for next frame. *
+ * -> save past of speech[] and wsp[]. *
+ *--------------------------------------------------*/
+
+ Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
+ Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
+
+ return;
+ }
+ /*----------------------------------------------------------------------*
+ * ACELP *
+ *----------------------------------------------------------------------*/
+
+ /* Quantize and code the ISFs */
+
+ if (*ser_size <= NBBITS_7k)
+ {
+ Qpisf_2s_36b(isf, isf, st->past_isfq, indice, 4);
+
+ Parm_serial(indice[0], 8, &prms);
+ Parm_serial(indice[1], 8, &prms);
+ Parm_serial(indice[2], 7, &prms);
+ Parm_serial(indice[3], 7, &prms);
+ Parm_serial(indice[4], 6, &prms);
+ } else
+ {
+ Qpisf_2s_46b(isf, isf, st->past_isfq, indice, 4);
+
+ Parm_serial(indice[0], 8, &prms);
+ Parm_serial(indice[1], 8, &prms);
+ Parm_serial(indice[2], 6, &prms);
+ Parm_serial(indice[3], 7, &prms);
+ Parm_serial(indice[4], 7, &prms);
+ Parm_serial(indice[5], 5, &prms);
+ Parm_serial(indice[6], 5, &prms);
+ }
+
+ /* Check stability on isf : distance between old isf and current isf */
+
+ L_tmp = 0;
+ for (i = 0; i < M - 1; i++)
+ {
+ tmp = vo_sub(isf[i], st->isfold[i]);
+ L_tmp += (tmp * tmp)<<1;
+ }
+
+ tmp = extract_h(L_shl2(L_tmp, 8));
+
+ tmp = vo_mult(tmp, 26214); /* tmp = L_tmp*0.8/256 */
+ tmp = vo_sub(20480, tmp); /* 1.25 - tmp (in Q14) */
+
+ stab_fac = shl(tmp, 1);
+
+ if (stab_fac < 0)
+ {
+ stab_fac = 0;
+ }
+ Copy(isf, st->isfold, M);
+
+ /* Convert ISFs to the cosine domain */
+ Isf_isp(isf, ispnew_q, M);
+
+ if (st->first_frame != 0)
+ {
+ st->first_frame = 0;
+ Copy(ispnew_q, st->ispold_q, M);
+ }
+ /* Find the interpolated ISPs and convert to a[] for all subframes */
+
+ Int_isp(st->ispold_q, ispnew_q, interpol_frac, Aq);
+
+ /* update ispold[] for the next frame */
+ Copy(ispnew_q, st->ispold_q, M);
+
+ p_Aq = Aq;
+ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+ {
+#ifdef ASM_OPT /* asm optimization branch */
+ Residu_opt(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
+#else
+ Residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
+#endif
+ p_Aq += (M + 1);
+ }
+
+ /* Buffer isf's and energy for dtx on non-speech frame */
+ if (vad_flag == 0)
+ {
+ for (i = 0; i < L_FRAME; i++)
+ {
+ exc2[i] = exc[i] >> Q_new;
+ }
+ L_tmp = 0;
+ for (i = 0; i < L_FRAME; i++)
+ L_tmp += (exc2[i] * exc2[i])<<1;
+ L_tmp >>= 1;
+
+ dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
+ }
+ /* range for closed loop pitch search in 1st subframe */
+
+ T0_min = T_op - 8;
+ if (T0_min < PIT_MIN)
+ {
+ T0_min = PIT_MIN;
+ }
+ T0_max = (T0_min + 15);
+
+ if(T0_max > PIT_MAX)
+ {
+ T0_max = PIT_MAX;
+ T0_min = T0_max - 15;
+ }
+ /*------------------------------------------------------------------------*
+ * Loop for every subframe in the analysis frame *
+ *------------------------------------------------------------------------*
+ * To find the pitch and innovation parameters. The subframe size is *
+ * L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times. *
+ * - compute the target signal for pitch search *
+ * - compute impulse response of weighted synthesis filter (h1[]) *
+ * - find the closed-loop pitch parameters *
+ * - encode the pitch dealy *
+ * - find 2 lt prediction (with / without LP filter for lt pred) *
+ * - find 2 pitch gains and choose the best lt prediction. *
+ * - find target vector for codebook search *
+ * - update the impulse response h1[] for codebook search *
+ * - correlation between target vector and impulse response *
+ * - codebook search and encoding *
+ * - VQ of pitch and codebook gains *
+ * - find voicing factor and tilt of code for next subframe. *
+ * - update states of weighting filter *
+ * - find excitation and synthesis speech *
+ *------------------------------------------------------------------------*/
+ p_A = A;
+ p_Aq = Aq;
+ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+ {
+ pit_flag = i_subfr;
+ if ((i_subfr == 2 * L_SUBFR) && (*ser_size > NBBITS_7k))
+ {
+ pit_flag = 0;
+ /* range for closed loop pitch search in 3rd subframe */
+ T0_min = (T_op2 - 8);
+
+ if (T0_min < PIT_MIN)
+ {
+ T0_min = PIT_MIN;
+ }
+ T0_max = (T0_min + 15);
+ if (T0_max > PIT_MAX)
+ {
+ T0_max = PIT_MAX;
+ T0_min = (T0_max - 15);
+ }
+ }
+ /*-----------------------------------------------------------------------*
+ * *
+ * Find the target vector for pitch search: *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
+ * *
+ * |------| res[n] *
+ * speech[n]---| A(z) |-------- *
+ * |------| | |--------| error[n] |------| *
+ * zero -- (-)--| 1/A(z) |-----------| W(z) |-- target *
+ * exc |--------| |------| *
+ * *
+ * Instead of subtracting the zero-input response of filters from *
+ * the weighted input speech, the above configuration is used to *
+ * compute the target vector. *
+ * *
+ *-----------------------------------------------------------------------*/
+
+ for (i = 0; i < M; i++)
+ {
+ error[i] = vo_sub(speech[i + i_subfr - M], st->mem_syn[i]);
+ }
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Residu_opt(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
+#else
+ Residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
+#endif
+ Syn_filt(p_Aq, &exc[i_subfr], error + M, L_SUBFR, error, 0);
+ Weight_a(p_A, Ap, GAMMA1, M);
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Residu_opt(Ap, error + M, xn, L_SUBFR);
+#else
+ Residu(Ap, error + M, xn, L_SUBFR);
+#endif
+ Deemph2(xn, TILT_FAC, L_SUBFR, &(st->mem_w0));
+
+ /*----------------------------------------------------------------------*
+ * Find approx. target in residual domain "cn[]" for inovation search. *
+ *----------------------------------------------------------------------*/
+ /* first half: xn[] --> cn[] */
+ Set_zero(code, M);
+ Copy(xn, code + M, L_SUBFR / 2);
+ tmp = 0;
+ Preemph2(code + M, TILT_FAC, L_SUBFR / 2, &tmp);
+ Weight_a(p_A, Ap, GAMMA1, M);
+ Syn_filt(Ap,code + M, code + M, L_SUBFR / 2, code, 0);
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Residu_opt(p_Aq,code + M, cn, L_SUBFR / 2);
+#else
+ Residu(p_Aq,code + M, cn, L_SUBFR / 2);
+#endif
+
+ /* second half: res[] --> cn[] (approximated and faster) */
+ Copy(&exc[i_subfr + (L_SUBFR / 2)], cn + (L_SUBFR / 2), L_SUBFR / 2);
+
+ /*---------------------------------------------------------------*
+ * Compute impulse response, h1[], of weighted synthesis filter *
+ *---------------------------------------------------------------*/
+
+ Set_zero(error, M + L_SUBFR);
+ Weight_a(p_A, error + M, GAMMA1, M);
+
+ vo_p0 = error+M;
+ vo_p3 = h1;
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ L_tmp = *vo_p0 << 14; /* x4 (Q12 to Q14) */
+ vo_p1 = p_Aq + 1;
+ vo_p2 = vo_p0-1;
+ for (j = 1; j <= M/4; j++)
+ {
+ L_tmp -= *vo_p1++ * *vo_p2--;
+ L_tmp -= *vo_p1++ * *vo_p2--;
+ L_tmp -= *vo_p1++ * *vo_p2--;
+ L_tmp -= *vo_p1++ * *vo_p2--;
+ }
+ *vo_p3++ = *vo_p0++ = vo_round((L_tmp <<4));
+ }
+ /* deemph without division by 2 -> Q14 to Q15 */
+ tmp = 0;
+ Deemph2(h1, TILT_FAC, L_SUBFR, &tmp); /* h1 in Q14 */
+
+ /* h2 in Q12 for codebook search */
+ Copy(h1, h2, L_SUBFR);
+
+ /*---------------------------------------------------------------*
+ * scale xn[] and h1[] to avoid overflow in dot_product12() *
+ *---------------------------------------------------------------*/
+#ifdef ASM_OPT /* asm optimization branch */
+ Scale_sig_opt(h2, L_SUBFR, -2);
+ Scale_sig_opt(xn, L_SUBFR, shift); /* scaling of xn[] to limit dynamic at 12 bits */
+ Scale_sig_opt(h1, L_SUBFR, 1 + shift); /* set h1[] in Q15 with scaling for convolution */
+#else
+ Scale_sig(h2, L_SUBFR, -2);
+ Scale_sig(xn, L_SUBFR, shift); /* scaling of xn[] to limit dynamic at 12 bits */
+ Scale_sig(h1, L_SUBFR, 1 + shift); /* set h1[] in Q15 with scaling for convolution */
+#endif
+ /*----------------------------------------------------------------------*
+ * Closed-loop fractional pitch search *
+ *----------------------------------------------------------------------*/
+ /* find closed loop fractional pitch lag */
+ if(*ser_size <= NBBITS_9k)
+ {
+ T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
+ pit_flag, PIT_MIN, PIT_FR1_8b, L_SUBFR);
+
+ /* encode pitch lag */
+ if (pit_flag == 0) /* if 1st/3rd subframe */
+ {
+ /*--------------------------------------------------------------*
+ * The pitch range for the 1st/3rd subframe is encoded with *
+ * 8 bits and is divided as follows: *
+ * PIT_MIN to PIT_FR1-1 resolution 1/2 (frac = 0 or 2) *
+ * PIT_FR1 to PIT_MAX resolution 1 (frac = 0) *
+ *--------------------------------------------------------------*/
+ if (T0 < PIT_FR1_8b)
+ {
+ index = ((T0 << 1) + (T0_frac >> 1) - (PIT_MIN<<1));
+ } else
+ {
+ index = ((T0 - PIT_FR1_8b) + ((PIT_FR1_8b - PIT_MIN)*2));
+ }
+
+ Parm_serial(index, 8, &prms);
+
+ /* find T0_min and T0_max for subframe 2 and 4 */
+ T0_min = (T0 - 8);
+ if (T0_min < PIT_MIN)
+ {
+ T0_min = PIT_MIN;
+ }
+ T0_max = T0_min + 15;
+ if (T0_max > PIT_MAX)
+ {
+ T0_max = PIT_MAX;
+ T0_min = (T0_max - 15);
+ }
+ } else
+ { /* if subframe 2 or 4 */
+ /*--------------------------------------------------------------*
+ * The pitch range for subframe 2 or 4 is encoded with 5 bits: *
+ * T0_min to T0_max resolution 1/2 (frac = 0 or 2) *
+ *--------------------------------------------------------------*/
+ i = (T0 - T0_min);
+ index = (i << 1) + (T0_frac >> 1);
+
+ Parm_serial(index, 5, &prms);
+ }
+ } else
+ {
+ T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
+ pit_flag, PIT_FR2, PIT_FR1_9b, L_SUBFR);
+
+ /* encode pitch lag */
+ if (pit_flag == 0) /* if 1st/3rd subframe */
+ {
+ /*--------------------------------------------------------------*
+ * The pitch range for the 1st/3rd subframe is encoded with *
+ * 9 bits and is divided as follows: *
+ * PIT_MIN to PIT_FR2-1 resolution 1/4 (frac = 0,1,2 or 3) *
+ * PIT_FR2 to PIT_FR1-1 resolution 1/2 (frac = 0 or 1) *
+ * PIT_FR1 to PIT_MAX resolution 1 (frac = 0) *
+ *--------------------------------------------------------------*/
+
+ if (T0 < PIT_FR2)
+ {
+ index = ((T0 << 2) + T0_frac) - (PIT_MIN << 2);
+ } else if(T0 < PIT_FR1_9b)
+ {
+ index = ((((T0 << 1) + (T0_frac >> 1)) - (PIT_FR2<<1)) + ((PIT_FR2 - PIT_MIN)<<2));
+ } else
+ {
+ index = (((T0 - PIT_FR1_9b) + ((PIT_FR2 - PIT_MIN)<<2)) + ((PIT_FR1_9b - PIT_FR2)<<1));
+ }
+
+ Parm_serial(index, 9, &prms);
+
+ /* find T0_min and T0_max for subframe 2 and 4 */
+
+ T0_min = (T0 - 8);
+ if (T0_min < PIT_MIN)
+ {
+ T0_min = PIT_MIN;
+ }
+ T0_max = T0_min + 15;
+
+ if (T0_max > PIT_MAX)
+ {
+ T0_max = PIT_MAX;
+ T0_min = (T0_max - 15);
+ }
+ } else
+ { /* if subframe 2 or 4 */
+ /*--------------------------------------------------------------*
+ * The pitch range for subframe 2 or 4 is encoded with 6 bits: *
+ * T0_min to T0_max resolution 1/4 (frac = 0,1,2 or 3) *
+ *--------------------------------------------------------------*/
+ i = (T0 - T0_min);
+ index = (i << 2) + T0_frac;
+ Parm_serial(index, 6, &prms);
+ }
+ }
+
+ /*-----------------------------------------------------------------*
+ * Gain clipping test to avoid unstable synthesis on frame erasure *
+ *-----------------------------------------------------------------*/
+
+ clip_gain = 0;
+ if((st->gp_clip[0] < 154) && (st->gp_clip[1] > 14746))
+ clip_gain = 1;
+
+ /*-----------------------------------------------------------------*
+ * - find unity gain pitch excitation (adaptive codebook entry) *
+ * with fractional interpolation. *
+ * - find filtered pitch exc. y1[]=exc[] convolved with h1[]) *
+ * - compute pitch gain1 *
+ *-----------------------------------------------------------------*/
+ /* find pitch exitation */
+#ifdef ASM_OPT /* asm optimization branch */
+ pred_lt4_asm(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1);
+#else
+ Pred_lt4(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1);
+#endif
+ if (*ser_size > NBBITS_9k)
+ {
+#ifdef ASM_OPT /* asm optimization branch */
+ Convolve_asm(&exc[i_subfr], h1, y1, L_SUBFR);
+#else
+ Convolve(&exc[i_subfr], h1, y1, L_SUBFR);
+#endif
+ gain1 = G_pitch(xn, y1, g_coeff, L_SUBFR);
+ /* clip gain if necessary to avoid problem at decoder */
+ if ((clip_gain != 0) && (gain1 > GP_CLIP))
+ {
+ gain1 = GP_CLIP;
+ }
+ /* find energy of new target xn2[] */
+ Updt_tar(xn, dn, y1, gain1, L_SUBFR); /* dn used temporary */
+ } else
+ {
+ gain1 = 0;
+ }
+ /*-----------------------------------------------------------------*
+ * - find pitch excitation filtered by 1st order LP filter. *
+ * - find filtered pitch exc. y2[]=exc[] convolved with h1[]) *
+ * - compute pitch gain2 *
+ *-----------------------------------------------------------------*/
+ /* find pitch excitation with lp filter */
+ vo_p0 = exc + i_subfr-1;
+ vo_p1 = code;
+ /* find pitch excitation with lp filter */
+ for (i = 0; i < L_SUBFR/2; i++)
+ {
+ L_tmp = 5898 * *vo_p0++;
+ L_tmp1 = 5898 * *vo_p0;
+ L_tmp += 20972 * *vo_p0++;
+ L_tmp1 += 20972 * *vo_p0++;
+ L_tmp1 += 5898 * *vo_p0--;
+ L_tmp += 5898 * *vo_p0;
+ *vo_p1++ = (L_tmp + 0x4000)>>15;
+ *vo_p1++ = (L_tmp1 + 0x4000)>>15;
+ }
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Convolve_asm(code, h1, y2, L_SUBFR);
+#else
+ Convolve(code, h1, y2, L_SUBFR);
+#endif
+
+ gain2 = G_pitch(xn, y2, g_coeff2, L_SUBFR);
+
+ /* clip gain if necessary to avoid problem at decoder */
+ if ((clip_gain != 0) && (gain2 > GP_CLIP))
+ {
+ gain2 = GP_CLIP;
+ }
+ /* find energy of new target xn2[] */
+ Updt_tar(xn, xn2, y2, gain2, L_SUBFR);
+ /*-----------------------------------------------------------------*
+ * use the best prediction (minimise quadratic error). *
+ *-----------------------------------------------------------------*/
+ select = 0;
+ if(*ser_size > NBBITS_9k)
+ {
+ L_tmp = 0L;
+ vo_p0 = dn;
+ vo_p1 = xn2;
+ for (i = 0; i < L_SUBFR/2; i++)
+ {
+ L_tmp += *vo_p0 * *vo_p0;
+ vo_p0++;
+ L_tmp -= *vo_p1 * *vo_p1;
+ vo_p1++;
+ L_tmp += *vo_p0 * *vo_p0;
+ vo_p0++;
+ L_tmp -= *vo_p1 * *vo_p1;
+ vo_p1++;
+ }
+
+ if (L_tmp <= 0)
+ {
+ select = 1;
+ }
+ Parm_serial(select, 1, &prms);
+ }
+ if (select == 0)
+ {
+ /* use the lp filter for pitch excitation prediction */
+ gain_pit = gain2;
+ Copy(code, &exc[i_subfr], L_SUBFR);
+ Copy(y2, y1, L_SUBFR);
+ Copy(g_coeff2, g_coeff, 4);
+ } else
+ {
+ /* no filter used for pitch excitation prediction */
+ gain_pit = gain1;
+ Copy(dn, xn2, L_SUBFR); /* target vector for codebook search */
+ }
+ /*-----------------------------------------------------------------*
+ * - update cn[] for codebook search *
+ *-----------------------------------------------------------------*/
+ Updt_tar(cn, cn, &exc[i_subfr], gain_pit, L_SUBFR);
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Scale_sig_opt(cn, L_SUBFR, shift); /* scaling of cn[] to limit dynamic at 12 bits */
+#else
+ Scale_sig(cn, L_SUBFR, shift); /* scaling of cn[] to limit dynamic at 12 bits */
+#endif
+ /*-----------------------------------------------------------------*
+ * - include fixed-gain pitch contribution into impulse resp. h1[] *
+ *-----------------------------------------------------------------*/
+ tmp = 0;
+ Preemph(h2, st->tilt_code, L_SUBFR, &tmp);
+
+ if (T0_frac > 2)
+ T0 = (T0 + 1);
+ Pit_shrp(h2, T0, PIT_SHARP, L_SUBFR);
+ /*-----------------------------------------------------------------*
+ * - Correlation between target xn2[] and impulse response h1[] *
+ * - Innovative codebook search *
+ *-----------------------------------------------------------------*/
+ cor_h_x(h2, xn2, dn);
+ if (*ser_size <= NBBITS_7k)
+ {
+ ACELP_2t64_fx(dn, cn, h2, code, y2, indice);
+
+ Parm_serial(indice[0], 12, &prms);
+ } else if(*ser_size <= NBBITS_9k)
+ {
+ ACELP_4t64_fx(dn, cn, h2, code, y2, 20, *ser_size, indice);
+
+ Parm_serial(indice[0], 5, &prms);
+ Parm_serial(indice[1], 5, &prms);
+ Parm_serial(indice[2], 5, &prms);
+ Parm_serial(indice[3], 5, &prms);
+ } else if(*ser_size <= NBBITS_12k)
+ {
+ ACELP_4t64_fx(dn, cn, h2, code, y2, 36, *ser_size, indice);
+
+ Parm_serial(indice[0], 9, &prms);
+ Parm_serial(indice[1], 9, &prms);
+ Parm_serial(indice[2], 9, &prms);
+ Parm_serial(indice[3], 9, &prms);
+ } else if(*ser_size <= NBBITS_14k)
+ {
+ ACELP_4t64_fx(dn, cn, h2, code, y2, 44, *ser_size, indice);
+
+ Parm_serial(indice[0], 13, &prms);
+ Parm_serial(indice[1], 13, &prms);
+ Parm_serial(indice[2], 9, &prms);
+ Parm_serial(indice[3], 9, &prms);
+ } else if(*ser_size <= NBBITS_16k)
+ {
+ ACELP_4t64_fx(dn, cn, h2, code, y2, 52, *ser_size, indice);
+
+ Parm_serial(indice[0], 13, &prms);
+ Parm_serial(indice[1], 13, &prms);
+ Parm_serial(indice[2], 13, &prms);
+ Parm_serial(indice[3], 13, &prms);
+ } else if(*ser_size <= NBBITS_18k)
+ {
+ ACELP_4t64_fx(dn, cn, h2, code, y2, 64, *ser_size, indice);
+
+ Parm_serial(indice[0], 2, &prms);
+ Parm_serial(indice[1], 2, &prms);
+ Parm_serial(indice[2], 2, &prms);
+ Parm_serial(indice[3], 2, &prms);
+ Parm_serial(indice[4], 14, &prms);
+ Parm_serial(indice[5], 14, &prms);
+ Parm_serial(indice[6], 14, &prms);
+ Parm_serial(indice[7], 14, &prms);
+ } else if(*ser_size <= NBBITS_20k)
+ {
+ ACELP_4t64_fx(dn, cn, h2, code, y2, 72, *ser_size, indice);
+
+ Parm_serial(indice[0], 10, &prms);
+ Parm_serial(indice[1], 10, &prms);
+ Parm_serial(indice[2], 2, &prms);
+ Parm_serial(indice[3], 2, &prms);
+ Parm_serial(indice[4], 10, &prms);
+ Parm_serial(indice[5], 10, &prms);
+ Parm_serial(indice[6], 14, &prms);
+ Parm_serial(indice[7], 14, &prms);
+ } else
+ {
+ ACELP_4t64_fx(dn, cn, h2, code, y2, 88, *ser_size, indice);
+
+ Parm_serial(indice[0], 11, &prms);
+ Parm_serial(indice[1], 11, &prms);
+ Parm_serial(indice[2], 11, &prms);
+ Parm_serial(indice[3], 11, &prms);
+ Parm_serial(indice[4], 11, &prms);
+ Parm_serial(indice[5], 11, &prms);
+ Parm_serial(indice[6], 11, &prms);
+ Parm_serial(indice[7], 11, &prms);
+ }
+ /*-------------------------------------------------------*
+ * - Add the fixed-gain pitch contribution to code[]. *
+ *-------------------------------------------------------*/
+ tmp = 0;
+ Preemph(code, st->tilt_code, L_SUBFR, &tmp);
+ Pit_shrp(code, T0, PIT_SHARP, L_SUBFR);
+ /*----------------------------------------------------------*
+ * - Compute the fixed codebook gain *
+ * - quantize fixed codebook gain *
+ *----------------------------------------------------------*/
+ if(*ser_size <= NBBITS_9k)
+ {
+ index = Q_gain2(xn, y1, Q_new + shift, y2, code, g_coeff, L_SUBFR, 6,
+ &gain_pit, &L_gain_code, clip_gain, st->qua_gain);
+ Parm_serial(index, 6, &prms);
+ } else
+ {
+ index = Q_gain2(xn, y1, Q_new + shift, y2, code, g_coeff, L_SUBFR, 7,
+ &gain_pit, &L_gain_code, clip_gain, st->qua_gain);
+ Parm_serial(index, 7, &prms);
+ }
+ /* test quantized gain of pitch for pitch clipping algorithm */
+ Gp_clip_test_gain_pit(gain_pit, st->gp_clip);
+
+ L_tmp = L_shl(L_gain_code, Q_new);
+ gain_code = extract_h(L_add(L_tmp, 0x8000));
+
+ /*----------------------------------------------------------*
+ * Update parameters for the next subframe. *
+ * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced) *
+ *----------------------------------------------------------*/
+ /* find voice factor in Q15 (1=voiced, -1=unvoiced) */
+ Copy(&exc[i_subfr], exc2, L_SUBFR);
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Scale_sig_opt(exc2, L_SUBFR, shift);
+#else
+ Scale_sig(exc2, L_SUBFR, shift);
+#endif
+ voice_fac = voice_factor(exc2, shift, gain_pit, code, gain_code, L_SUBFR);
+ /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
+ st->tilt_code = ((voice_fac >> 2) + 8192);
+ /*------------------------------------------------------*
+ * - Update filter's memory "mem_w0" for finding the *
+ * target vector in the next subframe. *
+ * - Find the total excitation *
+ * - Find synthesis speech to update mem_syn[]. *
+ *------------------------------------------------------*/
+
+ /* y2 in Q9, gain_pit in Q14 */
+ L_tmp = (gain_code * y2[L_SUBFR - 1])<<1;
+ L_tmp = L_shl(L_tmp, (5 + shift));
+ L_tmp = L_negate(L_tmp);
+ L_tmp += (xn[L_SUBFR - 1] * 16384)<<1;
+ L_tmp -= (y1[L_SUBFR - 1] * gain_pit)<<1;
+ L_tmp = L_shl(L_tmp, (1 - shift));
+ st->mem_w0 = extract_h(L_add(L_tmp, 0x8000));
+
+ if (*ser_size >= NBBITS_24k)
+ Copy(&exc[i_subfr], exc2, L_SUBFR);
+
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ /* code in Q9, gain_pit in Q14 */
+ L_tmp = (gain_code * code[i])<<1;
+ L_tmp = (L_tmp << 5);
+ L_tmp += (exc[i + i_subfr] * gain_pit)<<1;
+ L_tmp = L_shl2(L_tmp, 1);
+ exc[i + i_subfr] = extract_h(L_add(L_tmp, 0x8000));
+ }
+
+ Syn_filt(p_Aq,&exc[i_subfr], synth, L_SUBFR, st->mem_syn, 1);
+
+ if(*ser_size >= NBBITS_24k)
+ {
+ /*------------------------------------------------------------*
+ * phase dispersion to enhance noise in low bit rate *
+ *------------------------------------------------------------*/
+ /* L_gain_code in Q16 */
+ VO_L_Extract(L_gain_code, &gain_code, &gain_code_lo);
+
+ /*------------------------------------------------------------*
+ * noise enhancer *
+ * ~~~~~~~~~~~~~~ *
+ * - Enhance excitation on noise. (modify gain of code) *
+ * If signal is noisy and LPC filter is stable, move gain *
+ * of code 1.5 dB toward gain of code threshold. *
+ * This decrease by 3 dB noise energy variation. *
+ *------------------------------------------------------------*/
+ tmp = (16384 - (voice_fac >> 1)); /* 1=unvoiced, 0=voiced */
+ fac = vo_mult(stab_fac, tmp);
+ L_tmp = L_gain_code;
+ if(L_tmp < st->L_gc_thres)
+ {
+ L_tmp = vo_L_add(L_tmp, Mpy_32_16(gain_code, gain_code_lo, 6226));
+ if(L_tmp > st->L_gc_thres)
+ {
+ L_tmp = st->L_gc_thres;
+ }
+ } else
+ {
+ L_tmp = Mpy_32_16(gain_code, gain_code_lo, 27536);
+ if(L_tmp < st->L_gc_thres)
+ {
+ L_tmp = st->L_gc_thres;
+ }
+ }
+ st->L_gc_thres = L_tmp;
+
+ L_gain_code = Mpy_32_16(gain_code, gain_code_lo, (32767 - fac));
+ VO_L_Extract(L_tmp, &gain_code, &gain_code_lo);
+ L_gain_code = vo_L_add(L_gain_code, Mpy_32_16(gain_code, gain_code_lo, fac));
+
+ /*------------------------------------------------------------*
+ * pitch enhancer *
+ * ~~~~~~~~~~~~~~ *
+ * - Enhance excitation on voice. (HP filtering of code) *
+ * On voiced signal, filtering of code by a smooth fir HP *
+ * filter to decrease energy of code in low frequency. *
+ *------------------------------------------------------------*/
+
+ tmp = ((voice_fac >> 3) + 4096); /* 0.25=voiced, 0=unvoiced */
+
+ L_tmp = L_deposit_h(code[0]);
+ L_tmp -= (code[1] * tmp)<<1;
+ code2[0] = vo_round(L_tmp);
+
+ for (i = 1; i < L_SUBFR - 1; i++)
+ {
+ L_tmp = L_deposit_h(code[i]);
+ L_tmp -= (code[i + 1] * tmp)<<1;
+ L_tmp -= (code[i - 1] * tmp)<<1;
+ code2[i] = vo_round(L_tmp);
+ }
+
+ L_tmp = L_deposit_h(code[L_SUBFR - 1]);
+ L_tmp -= (code[L_SUBFR - 2] * tmp)<<1;
+ code2[L_SUBFR - 1] = vo_round(L_tmp);
+
+ /* build excitation */
+ gain_code = vo_round(L_shl(L_gain_code, Q_new));
+
+ for (i = 0; i < L_SUBFR; i++)
+ {
+ L_tmp = (code2[i] * gain_code)<<1;
+ L_tmp = (L_tmp << 5);
+ L_tmp += (exc2[i] * gain_pit)<<1;
+ L_tmp = (L_tmp << 1);
+ exc2[i] = vo_round(L_tmp);
+ }
+
+ corr_gain = synthesis(p_Aq, exc2, Q_new, &speech16k[i_subfr * 5 / 4], st);
+ Parm_serial(corr_gain, 4, &prms);
+ }
+ p_A += (M + 1);
+ p_Aq += (M + 1);
+ } /* end of subframe loop */
+
+ /*--------------------------------------------------*
+ * Update signal for next frame. *
+ * -> save past of speech[], wsp[] and exc[]. *
+ *--------------------------------------------------*/
+ Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
+ Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
+ Copy(&old_exc[L_FRAME], st->old_exc, PIT_MAX + L_INTERPOL);
+ return;
+}
+
+/*-----------------------------------------------------*
+* Function synthesis() *
+* *
+* Synthesis of signal at 16kHz with HF extension. *
+* *
+*-----------------------------------------------------*/
+
+static Word16 synthesis(
+ Word16 Aq[], /* A(z) : quantized Az */
+ Word16 exc[], /* (i) : excitation at 12kHz */
+ Word16 Q_new, /* (i) : scaling performed on exc */
+ Word16 synth16k[], /* (o) : 16kHz synthesis signal */
+ Coder_State * st /* (i/o) : State structure */
+ )
+{
+ Word16 fac, tmp, exp;
+ Word16 ener, exp_ener;
+ Word32 L_tmp, i;
+
+ Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR];
+ Word16 synth[L_SUBFR];
+ Word16 HF[L_SUBFR16k]; /* High Frequency vector */
+ Word16 Ap[M + 1];
+
+ Word16 HF_SP[L_SUBFR16k]; /* High Frequency vector (from original signal) */
+
+ Word16 HP_est_gain, HP_calc_gain, HP_corr_gain;
+ Word16 dist_min, dist;
+ Word16 HP_gain_ind = 0;
+ Word16 gain1, gain2;
+ Word16 weight1, weight2;
+
+ /*------------------------------------------------------------*
+ * speech synthesis *
+ * ~~~~~~~~~~~~~~~~ *
+ * - Find synthesis speech corresponding to exc2[]. *
+ * - Perform fixed deemphasis and hp 50hz filtering. *
+ * - Oversampling from 12.8kHz to 16kHz. *
+ *------------------------------------------------------------*/
+ Copy(st->mem_syn_hi, synth_hi, M);
+ Copy(st->mem_syn_lo, synth_lo, M);
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Syn_filt_32_asm(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
+#else
+ Syn_filt_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
+#endif
+
+ Copy(synth_hi + L_SUBFR, st->mem_syn_hi, M);
+ Copy(synth_lo + L_SUBFR, st->mem_syn_lo, M);
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Deemph_32_asm(synth_hi + M, synth_lo + M, synth, &(st->mem_deemph));
+#else
+ Deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR, &(st->mem_deemph));
+#endif
+
+ HP50_12k8(synth, L_SUBFR, st->mem_sig_out);
+
+ /* Original speech signal as reference for high band gain quantisation */
+ for (i = 0; i < L_SUBFR16k; i++)
+ {
+ HF_SP[i] = synth16k[i];
+ }
+
+ /*------------------------------------------------------*
+ * HF noise synthesis *
+ * ~~~~~~~~~~~~~~~~~~ *
+ * - Generate HF noise between 5.5 and 7.5 kHz. *
+ * - Set energy of noise according to synthesis tilt. *
+ * tilt > 0.8 ==> - 14 dB (voiced) *
+ * tilt 0.5 ==> - 6 dB (voiced or noise) *
+ * tilt < 0.0 ==> 0 dB (noise) *
+ *------------------------------------------------------*/
+ /* generate white noise vector */
+ for (i = 0; i < L_SUBFR16k; i++)
+ {
+ HF[i] = Random(&(st->seed2))>>3;
+ }
+ /* energy of excitation */
+#ifdef ASM_OPT /* asm optimization branch */
+ Scale_sig_opt(exc, L_SUBFR, -3);
+ Q_new = Q_new - 3;
+ ener = extract_h(Dot_product12_asm(exc, exc, L_SUBFR, &exp_ener));
+#else
+ Scale_sig(exc, L_SUBFR, -3);
+ Q_new = Q_new - 3;
+ ener = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp_ener));
+#endif
+
+ exp_ener = exp_ener - (Q_new + Q_new);
+ /* set energy of white noise to energy of excitation */
+#ifdef ASM_OPT /* asm optimization branch */
+ tmp = extract_h(Dot_product12_asm(HF, HF, L_SUBFR16k, &exp));
+#else
+ tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
+#endif
+
+ if(tmp > ener)
+ {
+ tmp = (tmp >> 1); /* Be sure tmp < ener */
+ exp = (exp + 1);
+ }
+ L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
+ exp = (exp - exp_ener);
+ Isqrt_n(&L_tmp, &exp);
+ L_tmp = L_shl(L_tmp, (exp + 1)); /* L_tmp x 2, L_tmp in Q31 */
+ tmp = extract_h(L_tmp); /* tmp = 2 x sqrt(ener_exc/ener_hf) */
+
+ for (i = 0; i < L_SUBFR16k; i++)
+ {
+ HF[i] = vo_mult(HF[i], tmp);
+ }
+
+ /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */
+ HP400_12k8(synth, L_SUBFR, st->mem_hp400);
+
+ L_tmp = 1L;
+ for (i = 0; i < L_SUBFR; i++)
+ L_tmp += (synth[i] * synth[i])<<1;
+
+ exp = norm_l(L_tmp);
+ ener = extract_h(L_tmp << exp); /* ener = r[0] */
+
+ L_tmp = 1L;
+ for (i = 1; i < L_SUBFR; i++)
+ L_tmp +=(synth[i] * synth[i - 1])<<1;
+
+ tmp = extract_h(L_tmp << exp); /* tmp = r[1] */
+
+ if (tmp > 0)
+ {
+ fac = div_s(tmp, ener);
+ } else
+ {
+ fac = 0;
+ }
+
+ /* modify energy of white noise according to synthesis tilt */
+ gain1 = 32767 - fac;
+ gain2 = vo_mult(gain1, 20480);
+ gain2 = shl(gain2, 1);
+
+ if (st->vad_hist > 0)
+ {
+ weight1 = 0;
+ weight2 = 32767;
+ } else
+ {
+ weight1 = 32767;
+ weight2 = 0;
+ }
+ tmp = vo_mult(weight1, gain1);
+ tmp = add1(tmp, vo_mult(weight2, gain2));
+
+ if (tmp != 0)
+ {
+ tmp = (tmp + 1);
+ }
+ HP_est_gain = tmp;
+
+ if(HP_est_gain < 3277)
+ {
+ HP_est_gain = 3277; /* 0.1 in Q15 */
+ }
+ /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
+ Weight_a(Aq, Ap, 19661, M); /* fac=0.6 */
+
+#ifdef ASM_OPT /* asm optimization branch */
+ Syn_filt_asm(Ap, HF, HF, st->mem_syn_hf);
+ /* noise High Pass filtering (1ms of delay) */
+ Filt_6k_7k_asm(HF, L_SUBFR16k, st->mem_hf);
+ /* filtering of the original signal */
+ Filt_6k_7k_asm(HF_SP, L_SUBFR16k, st->mem_hf2);
+
+ /* check the gain difference */
+ Scale_sig_opt(HF_SP, L_SUBFR16k, -1);
+ ener = extract_h(Dot_product12_asm(HF_SP, HF_SP, L_SUBFR16k, &exp_ener));
+ /* set energy of white noise to energy of excitation */
+ tmp = extract_h(Dot_product12_asm(HF, HF, L_SUBFR16k, &exp));
+#else
+ Syn_filt(Ap, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
+ /* noise High Pass filtering (1ms of delay) */
+ Filt_6k_7k(HF, L_SUBFR16k, st->mem_hf);
+ /* filtering of the original signal */
+ Filt_6k_7k(HF_SP, L_SUBFR16k, st->mem_hf2);
+ /* check the gain difference */
+ Scale_sig(HF_SP, L_SUBFR16k, -1);
+ ener = extract_h(Dot_product12(HF_SP, HF_SP, L_SUBFR16k, &exp_ener));
+ /* set energy of white noise to energy of excitation */
+ tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
+#endif
+
+ if (tmp > ener)
+ {
+ tmp = (tmp >> 1); /* Be sure tmp < ener */
+ exp = (exp + 1);
+ }
+ L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
+ exp = vo_sub(exp, exp_ener);
+ Isqrt_n(&L_tmp, &exp);
+ L_tmp = L_shl(L_tmp, exp); /* L_tmp, L_tmp in Q31 */
+ HP_calc_gain = extract_h(L_tmp); /* tmp = sqrt(ener_input/ener_hf) */
+
+ /* st->gain_alpha *= st->dtx_encSt->dtxHangoverCount/7 */
+ L_tmp = (vo_L_mult(st->dtx_encSt->dtxHangoverCount, 4681) << 15);
+ st->gain_alpha = vo_mult(st->gain_alpha, extract_h(L_tmp));
+
+ if(st->dtx_encSt->dtxHangoverCount > 6)
+ st->gain_alpha = 32767;
+ HP_est_gain = HP_est_gain >> 1; /* From Q15 to Q14 */
+ HP_corr_gain = add1(vo_mult(HP_calc_gain, st->gain_alpha), vo_mult((32767 - st->gain_alpha), HP_est_gain));
+
+ /* Quantise the correction gain */
+ dist_min = 32767;
+ for (i = 0; i < 16; i++)
+ {
+ dist = vo_mult((HP_corr_gain - HP_gain[i]), (HP_corr_gain - HP_gain[i]));
+ if (dist_min > dist)
+ {
+ dist_min = dist;
+ HP_gain_ind = i;
+ }
+ }
+ HP_corr_gain = HP_gain[HP_gain_ind];
+ /* return the quantised gain index when using the highest mode, otherwise zero */
+ return (HP_gain_ind);
+}
+
+/*************************************************
+*
+* Breif: Codec main function
+*
+**************************************************/
+
+int AMR_Enc_Encode(HAMRENC hCodec)
+{
+ Word32 i;
+ Coder_State *gData = (Coder_State*)hCodec;
+ Word16 *signal;
+ Word16 packed_size = 0;
+ Word16 prms[NB_BITS_MAX];
+ Word16 coding_mode = 0, nb_bits, allow_dtx, mode, reset_flag;
+ mode = gData->mode;
+ coding_mode = gData->mode;
+ nb_bits = nb_of_bits[mode];
+ signal = (Word16 *)gData->inputStream;
+ allow_dtx = gData->allow_dtx;
+
+ /* check for homing frame */
+ reset_flag = encoder_homing_frame_test(signal);
+
+ for (i = 0; i < L_FRAME16k; i++) /* Delete the 2 LSBs (14-bit input) */
+ {
+ *(signal + i) = (Word16) (*(signal + i) & 0xfffC);
+ }
+
+ coder(&coding_mode, signal, prms, &nb_bits, gData, allow_dtx);
+ packed_size = PackBits(prms, coding_mode, mode, gData);
+ if (reset_flag != 0)
+ {
+ Reset_encoder(gData, 1);
+ }
+ return packed_size;
+}
+
+/***************************************************************************
+*
+*Brief: Codec API function --- Initialize the codec and return a codec handle
+*
+***************************************************************************/
+
+VO_U32 VO_API voAMRWB_Init(VO_HANDLE * phCodec, /* o: the audio codec handle */
+ VO_AUDIO_CODINGTYPE vType, /* i: Codec Type ID */
+ VO_CODEC_INIT_USERDATA * pUserData /* i: init Parameters */
+ )
+{
+ Coder_State *st;
+ FrameStream *stream;
+#ifdef USE_DEAULT_MEM
+ VO_MEM_OPERATOR voMemoprator;
+#endif
+ VO_MEM_OPERATOR *pMemOP;
+ int interMem = 0;
+
+ if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL )
+ {
+#ifdef USE_DEAULT_MEM
+ voMemoprator.Alloc = cmnMemAlloc;
+ voMemoprator.Copy = cmnMemCopy;
+ voMemoprator.Free = cmnMemFree;
+ voMemoprator.Set = cmnMemSet;
+ voMemoprator.Check = cmnMemCheck;
+ interMem = 1;
+ pMemOP = &voMemoprator;
+#else
+ *phCodec = NULL;
+ return VO_ERR_INVALID_ARG;
+#endif
+ }
+ else
+ {
+ pMemOP = (VO_MEM_OPERATOR *)pUserData->memData;
+ }
+ /*-------------------------------------------------------------------------*
+ * Memory allocation for coder state. *
+ *-------------------------------------------------------------------------*/
+ if ((st = (Coder_State *)mem_malloc(pMemOP, sizeof(Coder_State), 32, VO_INDEX_ENC_AMRWB)) == NULL)
+ {
+ return VO_ERR_OUTOF_MEMORY;
+ }
+
+ st->vadSt = NULL;
+ st->dtx_encSt = NULL;
+ st->sid_update_counter = 3;
+ st->sid_handover_debt = 0;
+ st->prev_ft = TX_SPEECH;
+ st->inputStream = NULL;
+ st->inputSize = 0;
+
+ /* Default setting */
+ st->mode = VOAMRWB_MD2385; /* bit rate 23.85kbps */
+ st->frameType = VOAMRWB_RFC3267; /* frame type: RFC3267 */
+ st->allow_dtx = 0; /* disable DTX mode */
+
+ st->outputStream = NULL;
+ st->outputSize = 0;
+
+ st->stream = (FrameStream *)mem_malloc(pMemOP, sizeof(FrameStream), 32, VO_INDEX_ENC_AMRWB);
+ if(st->stream == NULL)
+ return VO_ERR_OUTOF_MEMORY;
+
+ st->stream->frame_ptr = (unsigned char *)mem_malloc(pMemOP, Frame_Maxsize, 32, VO_INDEX_ENC_AMRWB);
+ if(st->stream->frame_ptr == NULL)
+ return VO_ERR_OUTOF_MEMORY;
+
+ stream = st->stream;
+ voAWB_InitFrameBuffer(stream);
+
+ wb_vad_init(&(st->vadSt), pMemOP);
+ dtx_enc_init(&(st->dtx_encSt), isf_init, pMemOP);
+
+ Reset_encoder((void *) st, 1);
+
+ if(interMem)
+ {
+ st->voMemoprator.Alloc = cmnMemAlloc;
+ st->voMemoprator.Copy = cmnMemCopy;
+ st->voMemoprator.Free = cmnMemFree;
+ st->voMemoprator.Set = cmnMemSet;
+ st->voMemoprator.Check = cmnMemCheck;
+ pMemOP = &st->voMemoprator;
+ }
+
+ st->pvoMemop = pMemOP;
+
+ *phCodec = (void *) st;
+
+ return VO_ERR_NONE;
+}
+
+/**********************************************************************************
+*
+* Brief: Codec API function: Input PCM data
+*
+***********************************************************************************/
+
+VO_U32 VO_API voAMRWB_SetInputData(
+ VO_HANDLE hCodec, /* i/o: The codec handle which was created by Init function */
+ VO_CODECBUFFER * pInput /* i: The input buffer parameter */
+ )
+{
+ Coder_State *gData;
+ FrameStream *stream;
+
+ if(NULL == hCodec)
+ {
+ return VO_ERR_INVALID_ARG;
+ }
+
+ gData = (Coder_State *)hCodec;
+ stream = gData->stream;
+
+ if(NULL == pInput || NULL == pInput->Buffer || 0 > pInput->Length)
+ {
+ return VO_ERR_INVALID_ARG;
+ }
+
+ stream->set_ptr = pInput->Buffer;
+ stream->set_len = pInput->Length;
+ stream->frame_ptr = stream->frame_ptr_bk;
+ stream->used_len = 0;
+
+ return VO_ERR_NONE;
+}
+
+/**************************************************************************************
+*
+* Brief: Codec API function: Get the compression audio data frame by frame
+*
+***************************************************************************************/
+
+VO_U32 VO_API voAMRWB_GetOutputData(
+ VO_HANDLE hCodec, /* i: The Codec Handle which was created by Init function*/
+ VO_CODECBUFFER * pOutput, /* o: The output audio data */
+ VO_AUDIO_OUTPUTINFO * pAudioFormat /* o: The encoder module filled audio format and used the input size*/
+ )
+{
+ Coder_State* gData = (Coder_State*)hCodec;
+ VO_MEM_OPERATOR *pMemOP;
+ FrameStream *stream = (FrameStream *)gData->stream;
+ pMemOP = (VO_MEM_OPERATOR *)gData->pvoMemop;
+
+ if(stream->framebuffer_len < Frame_MaxByte) /* check the work buffer len */
+ {
+ stream->frame_storelen = stream->framebuffer_len;
+ if(stream->frame_storelen)
+ {
+ pMemOP->Copy(VO_INDEX_ENC_AMRWB, stream->frame_ptr_bk , stream->frame_ptr , stream->frame_storelen);
+ }
+ if(stream->set_len > 0)
+ {
+ voAWB_UpdateFrameBuffer(stream, pMemOP);
+ }
+ if(stream->framebuffer_len < Frame_MaxByte)
+ {
+ if(pAudioFormat)
+ pAudioFormat->InputUsed = stream->used_len;
+ return VO_ERR_INPUT_BUFFER_SMALL;
+ }
+ }
+
+ gData->inputStream = stream->frame_ptr;
+ gData->outputStream = (unsigned short*)pOutput->Buffer;
+
+ gData->outputSize = AMR_Enc_Encode(gData); /* encoder main function */
+
+ pOutput->Length = gData->outputSize; /* get the output buffer length */
+ stream->frame_ptr += 640; /* update the work buffer ptr */
+ stream->framebuffer_len -= 640;
+
+ if(pAudioFormat) /* return output audio information */
+ {
+ pAudioFormat->Format.Channels = 1;
+ pAudioFormat->Format.SampleRate = 8000;
+ pAudioFormat->Format.SampleBits = 16;
+ pAudioFormat->InputUsed = stream->used_len;
+ }
+ return VO_ERR_NONE;
+}
+
+/*************************************************************************
+*
+* Brief: Codec API function---set the data by specified parameter ID
+*
+*************************************************************************/
+
+
+VO_U32 VO_API voAMRWB_SetParam(
+ VO_HANDLE hCodec, /* i/o: The Codec Handle which was created by Init function */
+ VO_S32 uParamID, /* i: The param ID */
+ VO_PTR pData /* i: The param value depend on the ID */
+ )
+{
+ Coder_State* gData = (Coder_State*)hCodec;
+ FrameStream *stream = (FrameStream *)(gData->stream);
+ int *lValue = (int*)pData;
+
+ switch(uParamID)
+ {
+ /* setting AMR-WB frame type*/
+ case VO_PID_AMRWB_FRAMETYPE:
+ if(*lValue < VOAMRWB_DEFAULT || *lValue > VOAMRWB_RFC3267)
+ return VO_ERR_WRONG_PARAM_ID;
+ gData->frameType = *lValue;
+ break;
+ /* setting AMR-WB bit rate */
+ case VO_PID_AMRWB_MODE:
+ {
+ if(*lValue < VOAMRWB_MD66 || *lValue > VOAMRWB_MD2385)
+ return VO_ERR_WRONG_PARAM_ID;
+ gData->mode = *lValue;
+ }
+ break;
+ /* enable or disable DTX mode */
+ case VO_PID_AMRWB_DTX:
+ gData->allow_dtx = (Word16)(*lValue);
+ break;
+
+ case VO_PID_COMMON_HEADDATA:
+ break;
+ /* flush the work buffer */
+ case VO_PID_COMMON_FLUSH:
+ stream->set_ptr = NULL;
+ stream->frame_storelen = 0;
+ stream->framebuffer_len = 0;
+ stream->set_len = 0;
+ break;
+
+ default:
+ return VO_ERR_WRONG_PARAM_ID;
+ }
+ return VO_ERR_NONE;
+}
+
+/**************************************************************************
+*
+*Brief: Codec API function---Get the data by specified parameter ID
+*
+***************************************************************************/
+
+VO_U32 VO_API voAMRWB_GetParam(
+ VO_HANDLE hCodec, /* i: The Codec Handle which was created by Init function */
+ VO_S32 uParamID, /* i: The param ID */
+ VO_PTR pData /* o: The param value depend on the ID */
+ )
+{
+ int temp;
+ Coder_State* gData = (Coder_State*)hCodec;
+
+ if (gData==NULL)
+ return VO_ERR_INVALID_ARG;
+ switch(uParamID)
+ {
+ /* output audio format */
+ case VO_PID_AMRWB_FORMAT:
+ {
+ VO_AUDIO_FORMAT* fmt = (VO_AUDIO_FORMAT*)pData;
+ fmt->Channels = 1;
+ fmt->SampleRate = 16000;
+ fmt->SampleBits = 16;
+ break;
+ }
+ /* output audio channel number */
+ case VO_PID_AMRWB_CHANNELS:
+ temp = 1;
+ pData = (void *)(&temp);
+ break;
+ /* output audio sample rate */
+ case VO_PID_AMRWB_SAMPLERATE:
+ temp = 16000;
+ pData = (void *)(&temp);
+ break;
+ /* output audio frame type */
+ case VO_PID_AMRWB_FRAMETYPE:
+ temp = gData->frameType;
+ pData = (void *)(&temp);
+ break;
+ /* output audio bit rate */
+ case VO_PID_AMRWB_MODE:
+ temp = gData->mode;
+ pData = (void *)(&temp);
+ break;
+ default:
+ return VO_ERR_WRONG_PARAM_ID;
+ }
+
+ return VO_ERR_NONE;
+}
+
+/***********************************************************************************
+*
+* Brief: Codec API function---Release the codec after all encoder operations are done
+*
+*************************************************************************************/
+
+VO_U32 VO_API voAMRWB_Uninit(VO_HANDLE hCodec /* i/o: Codec handle pointer */
+ )
+{
+ Coder_State* gData = (Coder_State*)hCodec;
+ VO_MEM_OPERATOR *pMemOP;
+ pMemOP = gData->pvoMemop;
+
+ if(hCodec)
+ {
+ if(gData->stream)
+ {
+ if(gData->stream->frame_ptr_bk)
+ {
+ mem_free(pMemOP, gData->stream->frame_ptr_bk, VO_INDEX_ENC_AMRWB);
+ gData->stream->frame_ptr_bk = NULL;
+ }
+ mem_free(pMemOP, gData->stream, VO_INDEX_ENC_AMRWB);
+ gData->stream = NULL;
+ }
+ wb_vad_exit(&(((Coder_State *) gData)->vadSt), pMemOP);
+ dtx_enc_exit(&(((Coder_State *) gData)->dtx_encSt), pMemOP);
+
+ mem_free(pMemOP, hCodec, VO_INDEX_ENC_AMRWB);
+ hCodec = NULL;
+ }
+
+ return VO_ERR_NONE;
+}
+
+/********************************************************************************
+*
+* Brief: voGetAMRWBEncAPI gets the API handle of the codec
+*
+********************************************************************************/
+
+VO_S32 VO_API voGetAMRWBEncAPI(
+ VO_AUDIO_CODECAPI * pEncHandle /* i/o: Codec handle pointer */
+ )
+{
+ if(NULL == pEncHandle)
+ return VO_ERR_INVALID_ARG;
+ pEncHandle->Init = voAMRWB_Init;
+ pEncHandle->SetInputData = voAMRWB_SetInputData;
+ pEncHandle->GetOutputData = voAMRWB_GetOutputData;
+ pEncHandle->SetParam = voAMRWB_SetParam;
+ pEncHandle->GetParam = voAMRWB_GetParam;
+ pEncHandle->Uninit = voAMRWB_Uninit;
+
+ return VO_ERR_NONE;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/media/libstagefright/codecs/amrwbenc/src/voicefac.c b/media/libstagefright/codecs/amrwbenc/src/voicefac.c
new file mode 100644
index 0000000..187d774
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/voicefac.c
@@ -0,0 +1,92 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: voicefac.c *
+* *
+* Description: Find the voicing factors (1 = voice to -1 = unvoiced) *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+
+Word16 voice_factor( /* (o) Q15 : factor (-1=unvoiced to 1=voiced) */
+ Word16 exc[], /* (i) Q_exc : pitch excitation */
+ Word16 Q_exc, /* (i) : exc format */
+ Word16 gain_pit, /* (i) Q14 : gain of pitch */
+ Word16 code[], /* (i) Q9 : Fixed codebook excitation */
+ Word16 gain_code, /* (i) Q0 : gain of code */
+ Word16 L_subfr /* (i) : subframe length */
+ )
+{
+ Word16 tmp, exp, ener1, exp1, ener2, exp2;
+ Word32 i, L_tmp;
+
+#ifdef ASM_OPT /* asm optimization branch */
+ ener1 = extract_h(Dot_product12_asm(exc, exc, L_subfr, &exp1));
+#else
+ ener1 = extract_h(Dot_product12(exc, exc, L_subfr, &exp1));
+#endif
+ exp1 = exp1 - (Q_exc + Q_exc);
+ L_tmp = vo_L_mult(gain_pit, gain_pit);
+ exp = norm_l(L_tmp);
+ tmp = extract_h(L_tmp << exp);
+ ener1 = vo_mult(ener1, tmp);
+ exp1 = exp1 - exp - 10; /* 10 -> gain_pit Q14 to Q9 */
+
+#ifdef ASM_OPT /* asm optimization branch */
+ ener2 = extract_h(Dot_product12_asm(code, code, L_subfr, &exp2));
+#else
+ ener2 = extract_h(Dot_product12(code, code, L_subfr, &exp2));
+#endif
+
+ exp = norm_s(gain_code);
+ tmp = gain_code << exp;
+ tmp = vo_mult(tmp, tmp);
+ ener2 = vo_mult(ener2, tmp);
+ exp2 = exp2 - (exp + exp);
+
+ i = exp1 - exp2;
+
+ if (i >= 0)
+ {
+ ener1 = ener1 >> 1;
+ ener2 = ener2 >> (i + 1);
+ } else
+ {
+ ener1 = ener1 >> (1 - i);
+ ener2 = ener2 >> 1;
+ }
+
+ tmp = vo_sub(ener1, ener2);
+ ener1 = add1(add1(ener1, ener2), 1);
+
+ if (tmp >= 0)
+ {
+ tmp = div_s(tmp, ener1);
+ } else
+ {
+ tmp = vo_negate(div_s(vo_negate(tmp), ener1));
+ }
+
+ return (tmp);
+}
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/wb_vad.c b/media/libstagefright/codecs/amrwbenc/src/wb_vad.c
new file mode 100644
index 0000000..0126853
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/wb_vad.c
@@ -0,0 +1,808 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: wb_vad.c *
+* *
+* Description: Voice Activity Detection *
+* *
+************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "cnst.h"
+#include "wb_vad.h"
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "wb_vad_c.h"
+#include "mem_align.h"
+
+/******************************************************************************
+* Calculate Log2 and scale the signal:
+*
+* ilog2(Word32 in) = -1024*log10(in * 2^-31)/log10(2), where in = [1, 2^31-1]
+*
+* input output
+* 32768 16384
+* 1 31744
+*
+* When input is in the range of [1,2^16], max error is 0.0380%.
+*********************************************************************************/
+
+static Word16 ilog2( /* return: output value of the log2 */
+ Word16 mant /* i: value to be converted */
+ )
+{
+ Word16 ex, ex2, res;
+ Word32 i, l_temp;
+
+ if (mant <= 0)
+ {
+ mant = 1;
+ }
+ ex = norm_s(mant);
+ mant = mant << ex;
+
+ for (i = 0; i < 3; i++)
+ mant = vo_mult(mant, mant);
+ l_temp = vo_L_mult(mant, mant);
+
+ ex2 = norm_l(l_temp);
+ mant = extract_h(l_temp << ex2);
+
+ res = (ex + 16) << 10;
+ res = add1(res, (ex2 << 6));
+ res = vo_sub(add1(res, 127), (mant >> 8));
+ return (res);
+}
+
+/******************************************************************************
+*
+* Function : filter5
+* Purpose : Fifth-order half-band lowpass/highpass filter pair with
+* decimation.
+*
+*******************************************************************************/
+
+static void filter5(
+ Word16 * in0, /* i/o : input values; output low-pass part */
+ Word16 * in1, /* i/o : input values; output high-pass part */
+ Word16 data[] /* i/o : filter memory */
+ )
+{
+ Word16 temp0, temp1, temp2;
+
+ temp0 = vo_sub(*in0, vo_mult(COEFF5_1, data[0]));
+ temp1 = add1(data[0], vo_mult(COEFF5_1, temp0));
+ data[0] = temp0;
+
+ temp0 = vo_sub(*in1, vo_mult(COEFF5_2, data[1]));
+ temp2 = add1(data[1], vo_mult(COEFF5_2, temp0));
+ data[1] = temp0;
+
+ *in0 = extract_h((vo_L_add(temp1, temp2) << 15));
+ *in1 = extract_h((vo_L_sub(temp1, temp2) << 15));
+}
+
+/******************************************************************************
+*
+* Function : filter3
+* Purpose : Third-order half-band lowpass/highpass filter pair with
+* decimation.
+*
+*******************************************************************************/
+
+static void filter3(
+ Word16 * in0, /* i/o : input values; output low-pass part */
+ Word16 * in1, /* i/o : input values; output high-pass part */
+ Word16 * data /* i/o : filter memory */
+ )
+{
+ Word16 temp1, temp2;
+
+ temp1 = vo_sub(*in1, vo_mult(COEFF3, *data));
+ temp2 = add1(*data, vo_mult(COEFF3, temp1));
+ *data = temp1;
+
+ *in1 = extract_h((vo_L_sub(*in0, temp2) << 15));
+ *in0 = extract_h((vo_L_add(*in0, temp2) << 15));
+}
+
+/******************************************************************************
+*
+* Function : level_calculation
+* Purpose : Calculate signal level in a sub-band. Level is calculated
+* by summing absolute values of the input data.
+*
+* Signal level calculated from of the end of the frame
+* (data[count1 - count2]) is stored to (*sub_level)
+* and added to the level of the next frame.
+*
+******************************************************************************/
+
+static Word16 level_calculation( /* return: signal level */
+ Word16 data[], /* i : signal buffer */
+ Word16 * sub_level, /* i : level calculated at the end of the previous frame*/
+ /* o : level of signal calculated from the last */
+ /* (count2 - count1) samples */
+ Word16 count1, /* i : number of samples to be counted */
+ Word16 count2, /* i : number of samples to be counted */
+ Word16 ind_m, /* i : step size for the index of the data buffer */
+ Word16 ind_a, /* i : starting index of the data buffer */
+ Word16 scale /* i : scaling for the level calculation */
+ )
+{
+ Word32 i, l_temp1, l_temp2;
+ Word16 level;
+
+ l_temp1 = 0L;
+ for (i = count1; i < count2; i++)
+ {
+ l_temp1 += (abs_s(data[ind_m * i + ind_a])<<1);
+ }
+
+ l_temp2 = vo_L_add(l_temp1, L_shl(*sub_level, 16 - scale));
+ *sub_level = extract_h(L_shl(l_temp1, scale));
+
+ for (i = 0; i < count1; i++)
+ {
+ l_temp2 += (abs_s(data[ind_m * i + ind_a])<<1);
+ }
+ level = extract_h(L_shl2(l_temp2, scale));
+
+ return level;
+}
+
+/******************************************************************************
+*
+* Function : filter_bank
+* Purpose : Divide input signal into bands and calculate level of
+* the signal in each band
+*
+*******************************************************************************/
+
+static void filter_bank(
+ VadVars * st, /* i/o : State struct */
+ Word16 in[], /* i : input frame */
+ Word16 level[] /* o : signal levels at each band */
+ )
+{
+ Word32 i;
+ Word16 tmp_buf[FRAME_LEN];
+
+ /* shift input 1 bit down for safe scaling */
+ for (i = 0; i < FRAME_LEN; i++)
+ {
+ tmp_buf[i] = in[i] >> 1;
+ }
+
+ /* run the filter bank */
+ for (i = 0; i < 128; i++)
+ {
+ filter5(&tmp_buf[2 * i], &tmp_buf[2 * i + 1], st->a_data5[0]);
+ }
+ for (i = 0; i < 64; i++)
+ {
+ filter5(&tmp_buf[4 * i], &tmp_buf[4 * i + 2], st->a_data5[1]);
+ filter5(&tmp_buf[4 * i + 1], &tmp_buf[4 * i + 3], st->a_data5[2]);
+ }
+ for (i = 0; i < 32; i++)
+ {
+ filter5(&tmp_buf[8 * i], &tmp_buf[8 * i + 4], st->a_data5[3]);
+ filter5(&tmp_buf[8 * i + 2], &tmp_buf[8 * i + 6], st->a_data5[4]);
+ filter3(&tmp_buf[8 * i + 3], &tmp_buf[8 * i + 7], &st->a_data3[0]);
+ }
+ for (i = 0; i < 16; i++)
+ {
+ filter3(&tmp_buf[16 * i + 0], &tmp_buf[16 * i + 8], &st->a_data3[1]);
+ filter3(&tmp_buf[16 * i + 4], &tmp_buf[16 * i + 12], &st->a_data3[2]);
+ filter3(&tmp_buf[16 * i + 6], &tmp_buf[16 * i + 14], &st->a_data3[3]);
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ filter3(&tmp_buf[32 * i + 0], &tmp_buf[32 * i + 16], &st->a_data3[4]);
+ filter3(&tmp_buf[32 * i + 8], &tmp_buf[32 * i + 24], &st->a_data3[5]);
+ }
+
+ /* calculate levels in each frequency band */
+
+ /* 4800 - 6400 Hz */
+ level[11] = level_calculation(tmp_buf, &st->sub_level[11], 16, 64, 4, 1, 14);
+ /* 4000 - 4800 Hz */
+ level[10] = level_calculation(tmp_buf, &st->sub_level[10], 8, 32, 8, 7, 15);
+ /* 3200 - 4000 Hz */
+ level[9] = level_calculation(tmp_buf, &st->sub_level[9],8, 32, 8, 3, 15);
+ /* 2400 - 3200 Hz */
+ level[8] = level_calculation(tmp_buf, &st->sub_level[8],8, 32, 8, 2, 15);
+ /* 2000 - 2400 Hz */
+ level[7] = level_calculation(tmp_buf, &st->sub_level[7],4, 16, 16, 14, 16);
+ /* 1600 - 2000 Hz */
+ level[6] = level_calculation(tmp_buf, &st->sub_level[6],4, 16, 16, 6, 16);
+ /* 1200 - 1600 Hz */
+ level[5] = level_calculation(tmp_buf, &st->sub_level[5],4, 16, 16, 4, 16);
+ /* 800 - 1200 Hz */
+ level[4] = level_calculation(tmp_buf, &st->sub_level[4],4, 16, 16, 12, 16);
+ /* 600 - 800 Hz */
+ level[3] = level_calculation(tmp_buf, &st->sub_level[3],2, 8, 32, 8, 17);
+ /* 400 - 600 Hz */
+ level[2] = level_calculation(tmp_buf, &st->sub_level[2],2, 8, 32, 24, 17);
+ /* 200 - 400 Hz */
+ level[1] = level_calculation(tmp_buf, &st->sub_level[1],2, 8, 32, 16, 17);
+ /* 0 - 200 Hz */
+ level[0] = level_calculation(tmp_buf, &st->sub_level[0],2, 8, 32, 0, 17);
+}
+
+/******************************************************************************
+*
+* Function : update_cntrl
+* Purpose : Control update of the background noise estimate.
+*
+*******************************************************************************/
+
+static void update_cntrl(
+ VadVars * st, /* i/o : State structure */
+ Word16 level[] /* i : sub-band levels of the input frame */
+ )
+{
+ Word32 i;
+ Word16 num, temp, stat_rat, exp, denom;
+ Word16 alpha;
+
+ /* if a tone has been detected for a while, initialize stat_count */
+ if (sub((Word16) (st->tone_flag & 0x7c00), 0x7c00) == 0)
+ {
+ st->stat_count = STAT_COUNT;
+ } else
+ {
+ /* if 8 last vad-decisions have been "0", reinitialize stat_count */
+ if ((st->vadreg & 0x7f80) == 0)
+ {
+ st->stat_count = STAT_COUNT;
+ } else
+ {
+ stat_rat = 0;
+ for (i = 0; i < COMPLEN; i++)
+ {
+ if(level[i] > st->ave_level[i])
+ {
+ num = level[i];
+ denom = st->ave_level[i];
+ } else
+ {
+ num = st->ave_level[i];
+ denom = level[i];
+ }
+ /* Limit nimimum value of num and denom to STAT_THR_LEVEL */
+ if(num < STAT_THR_LEVEL)
+ {
+ num = STAT_THR_LEVEL;
+ }
+ if(denom < STAT_THR_LEVEL)
+ {
+ denom = STAT_THR_LEVEL;
+ }
+ exp = norm_s(denom);
+ denom = denom << exp;
+
+ /* stat_rat = num/denom * 64 */
+ temp = div_s(num >> 1, denom);
+ stat_rat = add1(stat_rat, shr(temp, (8 - exp)));
+ }
+
+ /* compare stat_rat with a threshold and update stat_count */
+ if(stat_rat > STAT_THR)
+ {
+ st->stat_count = STAT_COUNT;
+ } else
+ {
+ if ((st->vadreg & 0x4000) != 0)
+ {
+
+ if (st->stat_count != 0)
+ {
+ st->stat_count = st->stat_count - 1;
+ }
+ }
+ }
+ }
+ }
+
+ /* Update average amplitude estimate for stationarity estimation */
+ alpha = ALPHA4;
+ if(st->stat_count == STAT_COUNT)
+ {
+ alpha = 32767;
+ } else if ((st->vadreg & 0x4000) == 0)
+ {
+ alpha = ALPHA5;
+ }
+ for (i = 0; i < COMPLEN; i++)
+ {
+ st->ave_level[i] = add1(st->ave_level[i], vo_mult_r(alpha, vo_sub(level[i], st->ave_level[i])));
+ }
+}
+
+/******************************************************************************
+*
+* Function : hangover_addition
+* Purpose : Add hangover after speech bursts
+*
+*******************************************************************************/
+
+static Word16 hangover_addition( /* return: VAD_flag indicating final VAD decision */
+ VadVars * st, /* i/o : State structure */
+ Word16 low_power, /* i : flag power of the input frame */
+ Word16 hang_len, /* i : hangover length */
+ Word16 burst_len /* i : minimum burst length for hangover addition */
+ )
+{
+ /* if the input power (pow_sum) is lower than a threshold, clear counters and set VAD_flag to "0" */
+ if (low_power != 0)
+ {
+ st->burst_count = 0;
+ st->hang_count = 0;
+ return 0;
+ }
+ /* update the counters (hang_count, burst_count) */
+ if ((st->vadreg & 0x4000) != 0)
+ {
+ st->burst_count = st->burst_count + 1;
+ if(st->burst_count >= burst_len)
+ {
+ st->hang_count = hang_len;
+ }
+ return 1;
+ } else
+ {
+ st->burst_count = 0;
+ if (st->hang_count > 0)
+ {
+ st->hang_count = st->hang_count - 1;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/******************************************************************************
+*
+* Function : noise_estimate_update
+* Purpose : Update of background noise estimate
+*
+*******************************************************************************/
+
+static void noise_estimate_update(
+ VadVars * st, /* i/o : State structure */
+ Word16 level[] /* i : sub-band levels of the input frame */
+ )
+{
+ Word32 i;
+ Word16 alpha_up, alpha_down, bckr_add = 2;
+
+ /* Control update of bckr_est[] */
+ update_cntrl(st, level);
+
+ /* Choose update speed */
+ if ((0x7800 & st->vadreg) == 0)
+ {
+ alpha_up = ALPHA_UP1;
+ alpha_down = ALPHA_DOWN1;
+ } else
+ {
+ if ((st->stat_count == 0))
+ {
+ alpha_up = ALPHA_UP2;
+ alpha_down = ALPHA_DOWN2;
+ } else
+ {
+ alpha_up = 0;
+ alpha_down = ALPHA3;
+ bckr_add = 0;
+ }
+ }
+
+ /* Update noise estimate (bckr_est) */
+ for (i = 0; i < COMPLEN; i++)
+ {
+ Word16 temp;
+ temp = (st->old_level[i] - st->bckr_est[i]);
+
+ if (temp < 0)
+ { /* update downwards */
+ st->bckr_est[i] = add1(-2, add(st->bckr_est[i],vo_mult_r(alpha_down, temp)));
+ /* limit minimum value of the noise estimate to NOISE_MIN */
+ if(st->bckr_est[i] < NOISE_MIN)
+ {
+ st->bckr_est[i] = NOISE_MIN;
+ }
+ } else
+ { /* update upwards */
+ st->bckr_est[i] = add1(bckr_add, add1(st->bckr_est[i],vo_mult_r(alpha_up, temp)));
+
+ /* limit maximum value of the noise estimate to NOISE_MAX */
+ if(st->bckr_est[i] > NOISE_MAX)
+ {
+ st->bckr_est[i] = NOISE_MAX;
+ }
+ }
+ }
+
+ /* Update signal levels of the previous frame (old_level) */
+ for (i = 0; i < COMPLEN; i++)
+ {
+ st->old_level[i] = level[i];
+ }
+}
+
+/******************************************************************************
+*
+* Function : vad_decision
+* Purpose : Calculates VAD_flag
+*
+*******************************************************************************/
+
+static Word16 vad_decision( /* return value : VAD_flag */
+ VadVars * st, /* i/o : State structure */
+ Word16 level[COMPLEN], /* i : sub-band levels of the input frame */
+ Word32 pow_sum /* i : power of the input frame */
+ )
+{
+ Word32 i;
+ Word32 L_snr_sum;
+ Word32 L_temp;
+ Word16 vad_thr, temp, noise_level;
+ Word16 low_power_flag;
+ Word16 hang_len, burst_len;
+ Word16 ilog2_speech_level, ilog2_noise_level;
+ Word16 temp2;
+
+ /* Calculate squared sum of the input levels (level) divided by the background noise components
+ * (bckr_est). */
+ L_snr_sum = 0;
+ for (i = 0; i < COMPLEN; i++)
+ {
+ Word16 exp;
+
+ exp = norm_s(st->bckr_est[i]);
+ temp = (st->bckr_est[i] << exp);
+ temp = div_s((level[i] >> 1), temp);
+ temp = shl(temp, (exp - (UNIRSHFT - 1)));
+ L_snr_sum = L_mac(L_snr_sum, temp, temp);
+ }
+
+ /* Calculate average level of estimated background noise */
+ L_temp = 0;
+ for (i = 1; i < COMPLEN; i++) /* ignore lowest band */
+ {
+ L_temp = vo_L_add(L_temp, st->bckr_est[i]);
+ }
+
+ noise_level = extract_h((L_temp << 12));
+ /* if SNR is lower than a threshold (MIN_SPEECH_SNR), and increase speech_level */
+ temp = vo_mult(noise_level, MIN_SPEECH_SNR) << 3;
+
+ if(st->speech_level < temp)
+ {
+ st->speech_level = temp;
+ }
+ ilog2_noise_level = ilog2(noise_level);
+
+ /* If SNR is very poor, speech_level is probably corrupted by noise level. This is correctred by
+ * subtracting MIN_SPEECH_SNR*noise_level from speech level */
+ ilog2_speech_level = ilog2(st->speech_level - temp);
+
+ temp = add1(vo_mult(NO_SLOPE, (ilog2_noise_level - NO_P1)), THR_HIGH);
+
+ temp2 = add1(SP_CH_MIN, vo_mult(SP_SLOPE, (ilog2_speech_level - SP_P1)));
+ if (temp2 < SP_CH_MIN)
+ {
+ temp2 = SP_CH_MIN;
+ }
+ if (temp2 > SP_CH_MAX)
+ {
+ temp2 = SP_CH_MAX;
+ }
+ vad_thr = temp + temp2;
+
+ if(vad_thr < THR_MIN)
+ {
+ vad_thr = THR_MIN;
+ }
+ /* Shift VAD decision register */
+ st->vadreg = (st->vadreg >> 1);
+
+ /* Make intermediate VAD decision */
+ if(L_snr_sum > vo_L_mult(vad_thr, (512 * COMPLEN)))
+ {
+ st->vadreg = (Word16) (st->vadreg | 0x4000);
+ }
+ /* check if the input power (pow_sum) is lower than a threshold" */
+ if(pow_sum < VAD_POW_LOW)
+ {
+ low_power_flag = 1;
+ } else
+ {
+ low_power_flag = 0;
+ }
+ /* Update background noise estimates */
+ noise_estimate_update(st, level);
+
+ /* Calculate values for hang_len and burst_len based on vad_thr */
+ hang_len = add1(vo_mult(HANG_SLOPE, (vad_thr - HANG_P1)), HANG_HIGH);
+ if(hang_len < HANG_LOW)
+ {
+ hang_len = HANG_LOW;
+ }
+ burst_len = add1(vo_mult(BURST_SLOPE, (vad_thr - BURST_P1)), BURST_HIGH);
+
+ return (hangover_addition(st, low_power_flag, hang_len, burst_len));
+}
+
+/******************************************************************************
+*
+* Function : Estimate_Speech()
+* Purpose : Estimate speech level
+*
+* Maximum signal level is searched and stored to the variable sp_max.
+* The speech frames must locate within SP_EST_COUNT number of frames.
+* Thus, noisy frames having occasional VAD = "1" decisions will not
+* affect to the estimated speech_level.
+*
+*******************************************************************************/
+
+static void Estimate_Speech(
+ VadVars * st, /* i/o : State structure */
+ Word16 in_level /* level of the input frame */
+ )
+{
+ Word16 alpha;
+
+ /* if the required activity count cannot be achieved, reset counters */
+ if((st->sp_est_cnt - st->sp_max_cnt) > (SP_EST_COUNT - SP_ACTIVITY_COUNT))
+ {
+ st->sp_est_cnt = 0;
+ st->sp_max = 0;
+ st->sp_max_cnt = 0;
+ }
+ st->sp_est_cnt += 1;
+
+ if (((st->vadreg & 0x4000)||(in_level > st->speech_level)) && (in_level > MIN_SPEECH_LEVEL1))
+ {
+ /* update sp_max */
+ if(in_level > st->sp_max)
+ {
+ st->sp_max = in_level;
+ }
+ st->sp_max_cnt += 1;
+
+ if(st->sp_max_cnt >= SP_ACTIVITY_COUNT)
+ {
+ Word16 tmp;
+ /* update speech estimate */
+ tmp = (st->sp_max >> 1); /* scale to get "average" speech level */
+
+ /* select update speed */
+ if(tmp > st->speech_level)
+ {
+ alpha = ALPHA_SP_UP;
+ } else
+ {
+ alpha = ALPHA_SP_DOWN;
+ }
+ if(tmp > MIN_SPEECH_LEVEL2)
+ {
+ st->speech_level = add1(st->speech_level, vo_mult_r(alpha, vo_sub(tmp, st->speech_level)));
+ }
+ /* clear all counters used for speech estimation */
+ st->sp_max = 0;
+ st->sp_max_cnt = 0;
+ st->sp_est_cnt = 0;
+ }
+ }
+}
+
+/******************************************************************************
+*
+* Function: wb_vad_init
+* Purpose: Allocates state memory and initializes state memory
+*
+*******************************************************************************/
+
+Word16 wb_vad_init( /* return: non-zero with error, zero for ok. */
+ VadVars ** state, /* i/o : State structure */
+ VO_MEM_OPERATOR *pMemOP
+ )
+{
+ VadVars *s;
+
+ if (state == (VadVars **) NULL)
+ {
+ fprintf(stderr, "vad_init: invalid parameter\n");
+ return -1;
+ }
+ *state = NULL;
+
+ /* allocate memory */
+ if ((s = (VadVars *) mem_malloc(pMemOP, sizeof(VadVars), 32, VO_INDEX_ENC_AMRWB)) == NULL)
+ {
+ fprintf(stderr, "vad_init: can not malloc state structure\n");
+ return -1;
+ }
+ wb_vad_reset(s);
+
+ *state = s;
+
+ return 0;
+}
+
+/******************************************************************************
+*
+* Function: wb_vad_reset
+* Purpose: Initializes state memory
+*
+*******************************************************************************/
+
+Word16 wb_vad_reset( /* return: non-zero with error, zero for ok. */
+ VadVars * state /* i/o : State structure */
+ )
+{
+ Word32 i, j;
+
+ if (state == (VadVars *) NULL)
+ {
+ fprintf(stderr, "vad_reset: invalid parameter\n");
+ return -1;
+ }
+ state->tone_flag = 0;
+ state->vadreg = 0;
+ state->hang_count = 0;
+ state->burst_count = 0;
+ state->hang_count = 0;
+
+ /* initialize memory used by the filter bank */
+ for (i = 0; i < F_5TH_CNT; i++)
+ {
+ for (j = 0; j < 2; j++)
+ {
+ state->a_data5[i][j] = 0;
+ }
+ }
+
+ for (i = 0; i < F_3TH_CNT; i++)
+ {
+ state->a_data3[i] = 0;
+ }
+
+ /* initialize the rest of the memory */
+ for (i = 0; i < COMPLEN; i++)
+ {
+ state->bckr_est[i] = NOISE_INIT;
+ state->old_level[i] = NOISE_INIT;
+ state->ave_level[i] = NOISE_INIT;
+ state->sub_level[i] = 0;
+ }
+
+ state->sp_est_cnt = 0;
+ state->sp_max = 0;
+ state->sp_max_cnt = 0;
+ state->speech_level = SPEECH_LEVEL_INIT;
+ state->prev_pow_sum = 0;
+ return 0;
+}
+
+/******************************************************************************
+*
+* Function: wb_vad_exit
+* Purpose: The memory used for state memory is freed
+*
+*******************************************************************************/
+
+void wb_vad_exit(
+ VadVars ** state, /* i/o : State structure */
+ VO_MEM_OPERATOR *pMemOP
+ )
+{
+ if (state == NULL || *state == NULL)
+ return;
+ /* deallocate memory */
+ mem_free(pMemOP, *state, VO_INDEX_ENC_AMRWB);
+ *state = NULL;
+ return;
+}
+
+/******************************************************************************
+*
+* Function : wb_vad_tone_detection
+* Purpose : Search maximum pitch gain from a frame. Set tone flag if
+* pitch gain is high. This is used to detect
+* signaling tones and other signals with high pitch gain.
+*
+*******************************************************************************/
+
+void wb_vad_tone_detection(
+ VadVars * st, /* i/o : State struct */
+ Word16 p_gain /* pitch gain */
+ )
+{
+ /* update tone flag */
+ st->tone_flag = (st->tone_flag >> 1);
+
+ /* if (pitch_gain > TONE_THR) set tone flag */
+ if (p_gain > TONE_THR)
+ {
+ st->tone_flag = (Word16) (st->tone_flag | 0x4000);
+ }
+}
+
+/******************************************************************************
+*
+* Function : wb_vad
+* Purpose : Main program for Voice Activity Detection (VAD) for AMR
+*
+*******************************************************************************/
+
+Word16 wb_vad( /* Return value : VAD Decision, 1 = speech, 0 = noise */
+ VadVars * st, /* i/o : State structure */
+ Word16 in_buf[] /* i : samples of the input frame */
+ )
+{
+ Word16 level[COMPLEN];
+ Word32 i;
+ Word16 VAD_flag, temp;
+ Word32 L_temp, pow_sum;
+
+ /* Calculate power of the input frame. */
+ L_temp = 0L;
+ for (i = 0; i < FRAME_LEN; i++)
+ {
+ L_temp = L_mac(L_temp, in_buf[i], in_buf[i]);
+ }
+
+ /* pow_sum = power of current frame and previous frame */
+ pow_sum = L_add(L_temp, st->prev_pow_sum);
+
+ /* save power of current frame for next call */
+ st->prev_pow_sum = L_temp;
+
+ /* If input power is very low, clear tone flag */
+ if (pow_sum < POW_TONE_THR)
+ {
+ st->tone_flag = (Word16) (st->tone_flag & 0x1fff);
+ }
+ /* Run the filter bank and calculate signal levels at each band */
+ filter_bank(st, in_buf, level);
+
+ /* compute VAD decision */
+ VAD_flag = vad_decision(st, level, pow_sum);
+
+ /* Calculate input level */
+ L_temp = 0;
+ for (i = 1; i < COMPLEN; i++) /* ignore lowest band */
+ {
+ L_temp = vo_L_add(L_temp, level[i]);
+ }
+
+ temp = extract_h(L_temp << 12);
+
+ Estimate_Speech(st, temp); /* Estimate speech level */
+ return (VAD_flag);
+}
+
+
+
+
diff --git a/media/libstagefright/codecs/amrwbenc/src/weight_a.c b/media/libstagefright/codecs/amrwbenc/src/weight_a.c
new file mode 100644
index 0000000..d47be97
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/src/weight_a.c
@@ -0,0 +1,48 @@
+/*
+ ** Copyright 2003-2010, VisualOn, Inc.
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+/***********************************************************************
+* File: weight_a.c *
+* *
+* Description:Weighting of LPC coefficients *
+* ap[i] = a[i] * (gamma ** i) *
+* *
+************************************************************************/
+
+#include "typedef.h"
+#include "basic_op.h"
+
+void Weight_a(
+ Word16 a[], /* (i) Q12 : a[m+1] LPC coefficients */
+ Word16 ap[], /* (o) Q12 : Spectral expanded LPC coefficients */
+ Word16 gamma, /* (i) Q15 : Spectral expansion factor. */
+ Word16 m /* (i) : LPC order. */
+ )
+{
+ Word32 num = m - 1, fac;
+ *ap++ = *a++;
+ fac = gamma;
+ do{
+ *ap++ =(Word16)(((vo_L_mult((*a++), fac)) + 0x8000) >> 16);
+ fac = (vo_L_mult(fac, gamma) + 0x8000) >> 16;
+ }while(--num != 0);
+
+ *ap++ = (Word16)(((vo_L_mult((*a++), fac)) + 0x8000) >> 16);
+ return;
+}
+
+
+