diff options
author | Mans Rullgard <mans@mansr.com> | 2011-04-22 09:22:33 +0300 |
---|---|---|
committer | James Dong <jdong@google.com> | 2011-05-21 09:39:22 -0700 |
commit | e2e838afcf03e603a41a0455846eaf9614537c16 (patch) | |
tree | b6c2eedacc690a2c5514ac33dea7267cb38744bf /media/libstagefright/codecs/amrwbenc/src | |
parent | 8294aac281863e584027c3f2c7d2007c4140bf24 (diff) | |
download | frameworks_av-e2e838afcf03e603a41a0455846eaf9614537c16.zip frameworks_av-e2e838afcf03e603a41a0455846eaf9614537c16.tar.gz frameworks_av-e2e838afcf03e603a41a0455846eaf9614537c16.tar.bz2 |
Convert line breaks to Unix style
Change-Id: I6219725a9fbd72432bad71a176c14f26fabdbd5f
Diffstat (limited to 'media/libstagefright/codecs/amrwbenc/src')
64 files changed, 13591 insertions, 13591 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 index 0eb5e9f..c1c74e6 100644 --- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s +++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s @@ -1,104 +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
-
-
+@/* +@ ** 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 index 0383269..02bdcab 100644 --- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s +++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s @@ -1,80 +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
-
-
+@/* +@ ** 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 index e6ebd73..1ce2a85 100644 --- 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 @@ -1,185 +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
-
-
+@/* +@ ** 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/Syn_filt_32_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s index 6416634..70464e4 100644 --- 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 @@ -1,226 +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
-
-
+@/* +@ ** 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/cor_h_vec_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s index 441b984..8f32733 100644 --- 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 @@ -1,151 +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
-
-
-
-
-
+@/* +@ ** 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 index d5dd8f0..d7b4509 100644 --- 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 @@ -1,460 +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
-
-
-
-
+@/* +@ ** 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 index 060d9c7..86b3bd6 100644 --- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s +++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s @@ -1,228 +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
-
-
-
-
-
+@/* +@ ** 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 index aa9f464..f83e688 100644 --- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s +++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s @@ -1,75 +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
-
-
-
-
-
+@/* +@ ** 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 index e05e9e0..f4700cd 100644 --- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s +++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s @@ -1,238 +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
-
-
+@/* +@ ** 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 index acb60c3..2afc146 100644 --- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s +++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s @@ -1,102 +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
-
+@/* +@ ** 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 index 07ca344..678f1d0 100644 --- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s +++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s @@ -1,127 +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
-
+@/* +@ ** 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 index 1880024..5389a1c 100644 --- 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 @@ -1,228 +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
-
-
+@/* +@ ** 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/Syn_filt_32_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s index cb1764f..1e65efa 100644 --- 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 @@ -1,133 +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
-
-
+@/* +@ ** 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/cor_h_vec_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s index 2e339db..c314a88 100644 --- 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 @@ -1,151 +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
-
-
-
-
-
+@/* +@ ** 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 index 3b8853f..dffb750 100644 --- 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 @@ -1,100 +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
-
+@/* +@ ** 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/scale_sig_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s index 14957d8..bbd354d 100644 --- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s +++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s @@ -1,138 +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
-
-
+@/* +@ ** 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 index dc3d4a8..db4559c 100644 --- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s +++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s @@ -1,106 +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
-
-
+@/* +@ ** 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 index 33ed670..9baa937 100644 --- a/media/libstagefright/codecs/amrwbenc/src/autocorr.c +++ b/media/libstagefright/codecs/amrwbenc/src/autocorr.c @@ -1,127 +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;
-}
-
-
-
+/* + ** 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 index 8259f91..9333d19 100644 --- a/media/libstagefright/codecs/amrwbenc/src/az_isp.c +++ b/media/libstagefright/codecs/amrwbenc/src/az_isp.c @@ -1,268 +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);
-}
-
-
-
+/* + ** 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 index 90d1a00..61cac3d 100644 --- a/media/libstagefright/codecs/amrwbenc/src/bits.c +++ b/media/libstagefright/codecs/amrwbenc/src/bits.c @@ -1,210 +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;
-}
-
-
-
-
+/* + ** 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 index 39fc4c5..80990d9 100644 --- a/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c +++ b/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c @@ -1,297 +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;
-}
-
-
-
+/* + ** 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 index 27ba95d..17f3d47 100644 --- a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c +++ b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c @@ -1,1043 +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;
-}
-
-
-
-
+/* + ** 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 index c17264c..dd7c26d 100644 --- a/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c +++ b/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c @@ -1,73 +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;
-}
-
+/* + ** 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 index 66c74d6..4f7fd8a 100644 --- a/media/libstagefright/codecs/amrwbenc/src/convolve.c +++ b/media/libstagefright/codecs/amrwbenc/src/convolve.c @@ -1,109 +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;
-}
-
-
-
+/* + ** 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 index 3c2e9d5..b645fa3 100644 --- a/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c +++ b/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c @@ -1,127 +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;
-}
-
-
-
+/* + ** 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 index 429a7d6..7bc5576 100644 --- a/media/libstagefright/codecs/amrwbenc/src/decim54.c +++ b/media/libstagefright/codecs/amrwbenc/src/decim54.c @@ -1,146 +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;
-}
-
-
+/* + ** 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 index 6ad528d..4ee1449 100644 --- a/media/libstagefright/codecs/amrwbenc/src/deemph.c +++ b/media/libstagefright/codecs/amrwbenc/src/deemph.c @@ -1,117 +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;
-}
-
-
-
+/* + ** 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 index 02921eb..df53131 100644 --- a/media/libstagefright/codecs/amrwbenc/src/dtx.c +++ b/media/libstagefright/codecs/amrwbenc/src/dtx.c @@ -1,605 +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;
-}
+/* + ** 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 index 570138e..f5112c5 100644 --- a/media/libstagefright/codecs/amrwbenc/src/g_pitch.c +++ b/media/libstagefright/codecs/amrwbenc/src/g_pitch.c @@ -1,79 +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);
-}
-
-
-
+/* + ** 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 index e23f2f4..24158e3 100644 --- a/media/libstagefright/codecs/amrwbenc/src/gpclip.c +++ b/media/libstagefright/codecs/amrwbenc/src/gpclip.c @@ -1,110 +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;
-}
-
-
-
+/* + ** 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 index 015633f..565040f 100644 --- a/media/libstagefright/codecs/amrwbenc/src/homing.c +++ b/media/libstagefright/codecs/amrwbenc/src/homing.c @@ -1,46 +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);
-}
-
+/* + ** 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 index 463a53a..fa66f1a 100644 --- a/media/libstagefright/codecs/amrwbenc/src/hp400.c +++ b/media/libstagefright/codecs/amrwbenc/src/hp400.c @@ -1,106 +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;
-}
-
-
-
+/* + ** 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 index 53e3d7b..36dd1f1 100644 --- a/media/libstagefright/codecs/amrwbenc/src/hp50.c +++ b/media/libstagefright/codecs/amrwbenc/src/hp50.c @@ -1,106 +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;
-}
-
-
+/* + ** 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 index 5ee5b20..578633a 100644 --- a/media/libstagefright/codecs/amrwbenc/src/hp6k.c +++ b/media/libstagefright/codecs/amrwbenc/src/hp6k.c @@ -1,93 +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);
-
-}
-
-
-
+/* + ** 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 index 7fb62a4..3510272 100644 --- a/media/libstagefright/codecs/amrwbenc/src/hp_wsp.c +++ b/media/libstagefright/codecs/amrwbenc/src/hp_wsp.c @@ -1,148 +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;
-}
-
-
+/* + ** 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 index be1fd0b..88285e8 100644 --- a/media/libstagefright/codecs/amrwbenc/src/int_lpc.c +++ b/media/libstagefright/codecs/amrwbenc/src/int_lpc.c @@ -1,66 +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;
-}
-
-
-
+/* + ** 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 index 7b44d12..c235c5d 100644 --- a/media/libstagefright/codecs/amrwbenc/src/isp_az.c +++ b/media/libstagefright/codecs/amrwbenc/src/isp_az.c @@ -1,247 +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;
-}
-
-
+/* + ** 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 index 6c6e389..fbe80eb 100644 --- a/media/libstagefright/codecs/amrwbenc/src/isp_isf.c +++ b/media/libstagefright/codecs/amrwbenc/src/isp_isf.c @@ -1,91 +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;
-}
-
-
-
-
+/* + ** 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 index 0397704..49c622c 100644 --- a/media/libstagefright/codecs/amrwbenc/src/lag_wind.c +++ b/media/libstagefright/codecs/amrwbenc/src/lag_wind.c @@ -1,49 +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;
-}
-
-
-
+/* + ** 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 index 8bc6f62..a68845f 100644 --- a/media/libstagefright/codecs/amrwbenc/src/levinson.c +++ b/media/libstagefright/codecs/amrwbenc/src/levinson.c @@ -1,250 +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;
-}
-
-
-
+/* + ** 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 index cd3d815..646d6af 100644 --- a/media/libstagefright/codecs/amrwbenc/src/log2.c +++ b/media/libstagefright/codecs/amrwbenc/src/log2.c @@ -1,111 +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);
-}
-
-
-
+/* + ** 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 index 63b746b..29bd46b 100644 --- a/media/libstagefright/codecs/amrwbenc/src/lp_dec2.c +++ b/media/libstagefright/codecs/amrwbenc/src/lp_dec2.c @@ -1,70 +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;
-}
-
-
-
-
+/* + ** 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 index 1c95ed0..1a7b513 100644 --- a/media/libstagefright/codecs/amrwbenc/src/math_op.c +++ b/media/libstagefright/codecs/amrwbenc/src/math_op.c @@ -1,219 +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);
-
-}
-
-
+/* + ** 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/oper_32b.c b/media/libstagefright/codecs/amrwbenc/src/oper_32b.c index 5f1523e..27cad76 100644 --- a/media/libstagefright/codecs/amrwbenc/src/oper_32b.c +++ b/media/libstagefright/codecs/amrwbenc/src/oper_32b.c @@ -1,223 +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);
-}
-
+/* + ** 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 index 39ee966..08f430f 100644 --- a/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c +++ b/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c @@ -1,256 +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;
-
-}
-
-
-
+/* + ** 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 index c8a227c..6f55b8f 100644 --- a/media/libstagefright/codecs/amrwbenc/src/pit_shrp.c +++ b/media/libstagefright/codecs/amrwbenc/src/pit_shrp.c @@ -1,49 +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;
-}
-
-
-
+/* + ** 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 index c115b11..41d7413 100644 --- a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c +++ b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c @@ -1,324 +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);
-}
-
-
-
-
+/* + ** 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 index ac1ff22..b359651 100644 --- a/media/libstagefright/codecs/amrwbenc/src/pred_lt4.c +++ b/media/libstagefright/codecs/amrwbenc/src/pred_lt4.c @@ -1,120 +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;
-}
-
-
-
+/* + ** 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 index f5bcd33..5408617 100644 --- a/media/libstagefright/codecs/amrwbenc/src/preemph.c +++ b/media/libstagefright/codecs/amrwbenc/src/preemph.c @@ -1,88 +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;
-}
-
-
-
+/* + ** 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 index 59eefe4..7bc299f 100644 --- a/media/libstagefright/codecs/amrwbenc/src/q_gain2.c +++ b/media/libstagefright/codecs/amrwbenc/src/q_gain2.c @@ -1,346 +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);
-}
-
-
-
-
+/* + ** 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 index a28ba40..496ca80 100644 --- a/media/libstagefright/codecs/amrwbenc/src/q_pulse.c +++ b/media/libstagefright/codecs/amrwbenc/src/q_pulse.c @@ -1,400 +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);
-}
-
-
+/* + ** 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 index 00b0a53..f6d53de 100644 --- a/media/libstagefright/codecs/amrwbenc/src/qisf_ns.c +++ b/media/libstagefright/codecs/amrwbenc/src/qisf_ns.c @@ -1,111 +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;
-}
-
-
-
+/* + ** 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 index ccedb5c..ac13a67 100644 --- a/media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c +++ b/media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c @@ -1,542 +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;
-}
-
-
-
-
+/* + ** 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 index 8baa8bf..b896863 100644 --- a/media/libstagefright/codecs/amrwbenc/src/random.c +++ b/media/libstagefright/codecs/amrwbenc/src/random.c @@ -1,33 +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);
-}
-
+/* + ** 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 index 6829882..328aed2 100644 --- a/media/libstagefright/codecs/amrwbenc/src/residu.c +++ b/media/libstagefright/codecs/amrwbenc/src/residu.c @@ -1,67 +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;
-}
-
-
-
+/* + ** 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 index af40121..b203bec 100644 --- a/media/libstagefright/codecs/amrwbenc/src/scale.c +++ b/media/libstagefright/codecs/amrwbenc/src/scale.c @@ -1,57 +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;
-}
-
-
-
+/* + ** 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 index a708235..bdf0d46 100644 --- a/media/libstagefright/codecs/amrwbenc/src/stream.c +++ b/media/libstagefright/codecs/amrwbenc/src/stream.c @@ -1,58 +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;
-}
-
+/* + ** 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 index 6c1fb8e..90fafb0 100644 --- a/media/libstagefright/codecs/amrwbenc/src/syn_filt.c +++ b/media/libstagefright/codecs/amrwbenc/src/syn_filt.c @@ -1,160 +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;
-}
-
-
-
-
+/* + ** 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 index f3e5650..eda2b1c 100644 --- a/media/libstagefright/codecs/amrwbenc/src/updt_tar.c +++ b/media/libstagefright/codecs/amrwbenc/src/updt_tar.c @@ -1,49 +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;
-}
-
-
-
+/* + ** 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 index 78141dd..76ab1b1 100644 --- a/media/libstagefright/codecs/amrwbenc/src/util.c +++ b/media/libstagefright/codecs/amrwbenc/src/util.c @@ -1,74 +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);
-}
-
-
-
+/* + ** 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 index d0d99a7..bac00dd 100644 --- a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c +++ b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c @@ -1,1941 +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
+/* + ** 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 index 187d774..17e4e55 100644 --- a/media/libstagefright/codecs/amrwbenc/src/voicefac.c +++ b/media/libstagefright/codecs/amrwbenc/src/voicefac.c @@ -1,92 +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);
-}
-
-
-
-
+/* + ** 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 index 0126853..7e1d673 100644 --- a/media/libstagefright/codecs/amrwbenc/src/wb_vad.c +++ b/media/libstagefright/codecs/amrwbenc/src/wb_vad.c @@ -1,808 +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);
-}
-
-
-
-
+/* + ** 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 index d47be97..8f0fb39 100644 --- a/media/libstagefright/codecs/amrwbenc/src/weight_a.c +++ b/media/libstagefright/codecs/amrwbenc/src/weight_a.c @@ -1,48 +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;
-}
-
-
-
+/* + ** 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; +} + + + |