mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 06:08:35 +00:00
82c98e9803
AUDIO: Add support for sample rates >65kHz.
693 lines
29 KiB
ArmAsm
693 lines
29 KiB
ArmAsm
@ ScummVM - Graphic Adventure Engine
|
|
@
|
|
@ ScummVM is the legal property of its developers, whose names
|
|
@ are too numerous to list here. Please refer to the COPYRIGHT
|
|
@ file distributed with this source distribution.
|
|
@
|
|
@ This program is free software@ you can redistribute it and/or
|
|
@ modify it under the terms of the GNU General Public License
|
|
@ as published by the Free Software Foundation@ either version 2
|
|
@ of the License, or (at your option) any later version.
|
|
@
|
|
@ This program is distributed in the hope that it will be useful,
|
|
@ but WITHOUT ANY WARRANTY@ without even the implied warranty of
|
|
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
@ GNU General Public License for more details.
|
|
@
|
|
@ You should have received a copy of the GNU General Public License
|
|
@ along with this program@ if not, write to the Free Software
|
|
@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
@
|
|
@ @author Robin Watts (robin@wss.co.uk)
|
|
@
|
|
@ This file, together with rate_arm.cpp, provides an ARM optimised version
|
|
@ of rate.cpp. The algorithm is essentially the same as that within rate.cpp
|
|
@ so to understand this file you should understand rate.cpp first.
|
|
|
|
.text
|
|
|
|
.global _ARM_CopyRate_M
|
|
.global _ARM_CopyRate_S
|
|
.global _ARM_CopyRate_R
|
|
.global _ARM_SimpleRate_M
|
|
.global _ARM_SimpleRate_S
|
|
.global _ARM_SimpleRate_R
|
|
.global _ARM_LinearRate_M
|
|
.global _ARM_LinearRate_S
|
|
.global _ARM_LinearRate_R
|
|
|
|
.align 2
|
|
_ARM_CopyRate_M:
|
|
@ r0 = len
|
|
@ r1 = obuf
|
|
@ r2 = vol_l
|
|
@ r3 = vol_r
|
|
@ <> = ptr
|
|
LDR r12,[r13]
|
|
STMFD r13!,{r4-r7,r14}
|
|
|
|
MOV r14,#0 @ r14= 0
|
|
ORR r2, r2, r2, LSL #8 @ r2 = vol_l as 16 bits
|
|
ORR r3, r3, r3, LSL #8 @ r3 = vol_r as 16 bits
|
|
CopyRate_M_loop:
|
|
LDRSH r5, [r12], #2 @ r5 = tmp0 = tmp1 = *ptr++
|
|
LDRSH r6, [r1] @ r6 = obuf[0]
|
|
LDRSH r7, [r1, #2] @ r7 = obuf[1]
|
|
MUL r4, r2, r5 @ r4 = tmp0*vol_l
|
|
MUL r5, r3, r5 @ r5 = tmp1*vol_r
|
|
|
|
ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
|
|
RSCVS r6, r14,#0x80000000 @ Clamp r6
|
|
ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
|
|
RSCVS r7, r14,#0x80000000 @ Clamp r7
|
|
|
|
MOV r6, r6, LSR #16 @ Shift back to halfword
|
|
MOV r7, r7, LSR #16 @ Shift back to halfword
|
|
|
|
STRH r6, [r1], #2 @ Store output value
|
|
STRH r7, [r1], #2 @ Store output value
|
|
|
|
SUBS r0,r0,#1 @ len--
|
|
BGT CopyRate_M_loop @ and loop
|
|
|
|
MOV r0, r1 @ return obuf
|
|
|
|
LDMFD r13!,{r4-r7,PC}
|
|
|
|
.align 2
|
|
_ARM_CopyRate_S:
|
|
@ r0 = len
|
|
@ r1 = obuf
|
|
@ r2 = vol_l
|
|
@ r3 = vol_r
|
|
@ <> = ptr
|
|
LDR r12,[r13]
|
|
STMFD r13!,{r4-r7,r14}
|
|
|
|
MOV r14,#0 @ r14= 0
|
|
ORR r2, r2, r2, LSL #8 @ r2 = vol_l as 16 bits
|
|
ORR r3, r3, r3, LSL #8 @ r3 = vol_r as 16 bits
|
|
CopyRate_S_loop:
|
|
LDRSH r4, [r12],#2 @ r4 = tmp0 = *ptr++
|
|
LDRSH r5, [r12],#2 @ r5 = tmp1 = *ptr++
|
|
LDRSH r6, [r1] @ r6 = obuf[0]
|
|
LDRSH r7, [r1,#2] @ r7 = obuf[1]
|
|
MUL r4, r2, r4 @ r4 = tmp0*vol_l
|
|
MUL r5, r3, r5 @ r5 = tmp1*vol_r
|
|
|
|
ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
|
|
RSCVS r6, r14,#0x80000000 @ Clamp r6
|
|
ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
|
|
RSCVS r7, r14,#0x80000000 @ Clamp r7
|
|
|
|
MOV r6, r6, LSR #16 @ Shift back to halfword
|
|
MOV r7, r7, LSR #16 @ Shift back to halfword
|
|
|
|
STRH r6, [r1],#2 @ Store output value
|
|
STRH r7, [r1],#2 @ Store output value
|
|
|
|
SUBS r0,r0,#2 @ len -= 2
|
|
BGT CopyRate_S_loop @ and loop
|
|
|
|
MOV r0, r1 @ return obuf
|
|
|
|
LDMFD r13!,{r4-r7,PC}
|
|
|
|
.align 2
|
|
_ARM_CopyRate_R:
|
|
@ r0 = len
|
|
@ r1 = obuf
|
|
@ r2 = vol_l
|
|
@ r3 = vol_r
|
|
@ <> = ptr
|
|
LDR r12,[r13]
|
|
STMFD r13!,{r4-r7,r14}
|
|
|
|
MOV r14,#0 @ r14= 0
|
|
ORR r2, r2, r2, LSL #8 @ r2 = vol_l as 16 bits
|
|
ORR r3, r3, r3, LSL #8 @ r3 = vol_r as 16 bits
|
|
CopyRate_R_loop:
|
|
LDRSH r4, [r12],#2 @ r4 = tmp0 = *ptr++
|
|
LDRSH r5, [r12],#2 @ r5 = tmp1 = *ptr++
|
|
LDRSH r6, [r1] @ r6 = obuf[0]
|
|
LDRSH r7, [r1,#2] @ r7 = obuf[1]
|
|
MUL r4, r2, r4 @ r4 = tmp0*vol_l
|
|
MUL r5, r3, r5 @ r5 = tmp1*vol_r
|
|
|
|
ADDS r6, r5, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp1*vol_r
|
|
RSCVS r6, r14,#0x80000000 @ Clamp r6
|
|
ADDS r7, r4, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp0*vol_l
|
|
RSCVS r7, r14,#0x80000000 @ Clamp r7
|
|
|
|
MOV r6, r6, LSR #16 @ Shift back to halfword
|
|
MOV r7, r7, LSR #16 @ Shift back to halfword
|
|
|
|
STRH r6, [r1],#2 @ Store output value
|
|
STRH r7, [r1],#2 @ Store output value
|
|
|
|
SUBS r0,r0,#2 @ len -= 2
|
|
BGT CopyRate_R_loop @ and loop
|
|
|
|
MOV r0, r1 @ return obuf
|
|
|
|
LDMFD r13!,{r4-r7,PC}
|
|
|
|
.align 2
|
|
_ARM_SimpleRate_M:
|
|
@ r0 = AudioStream &input
|
|
@ r1 = input.readBuffer
|
|
@ r2 = input->sr
|
|
@ r3 = obuf
|
|
@ <> = osamp
|
|
@ <> = vol_l
|
|
@ <> = vol_r
|
|
MOV r12,r13
|
|
STMFD r13!,{r0-r2,r4-r8,r10-r11,r14}
|
|
LDMFD r12,{r11,r12,r14} @ r11= osamp
|
|
@ r12= vol_l
|
|
@ r14= vol_r
|
|
LDMIA r2,{r0,r1,r2,r8} @ r0 = inPtr
|
|
@ r1 = inLen
|
|
@ r2 = opos
|
|
@ r8 = opos_inc
|
|
CMP r11,#0 @ if (osamp <= 0)
|
|
BLE SimpleRate_M_end @ bale
|
|
MOV r10,#0
|
|
ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
|
|
ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
|
|
SimpleRate_M_loop:
|
|
SUBS r1, r1, #1 @ r1 = inLen -= 1
|
|
BLT SimpleRate_M_read
|
|
SUBS r2, r2, #1 @ r2 = opos--
|
|
ADDGE r0, r0, #2 @ if (r2 >= 0) { sr.inPtr++
|
|
BGE SimpleRate_M_loop @ and loop }
|
|
SimpleRate_M_read_return:
|
|
LDRSH r5, [r0],#2 @ r5 = tmp1 = *inPtr++
|
|
LDRSH r6, [r3] @ r6 = obuf[0]
|
|
LDRSH r7, [r3,#2] @ r7 = obuf[1]
|
|
ADD r2, r2, r8 @ r2 = opos += opos_inc
|
|
MUL r4, r12,r5 @ r4 = tmp0*vol_l
|
|
MUL r5, r14,r5 @ r5 = tmp1*vol_r
|
|
|
|
ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
|
|
RSCVS r6, r10,#0x80000000 @ Clamp r6
|
|
ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
|
|
RSCVS r7, r10,#0x80000000 @ Clamp r7
|
|
|
|
MOV r6, r6, LSR #16 @ Shift back to halfword
|
|
MOV r7, r7, LSR #16 @ Shift back to halfword
|
|
|
|
STRH r6, [r3],#2 @ Store output value
|
|
STRH r7, [r3],#2 @ Store output value
|
|
|
|
SUBS r11,r11,#1 @ len--
|
|
BGT SimpleRate_M_loop @ and loop
|
|
SimpleRate_M_end:
|
|
LDR r14,[r13,#8] @ r14 = sr
|
|
ADD r13,r13,#12 @ Skip over r0-r2 on stack
|
|
STMIA r14,{r0,r1,r2} @ Store back updated values
|
|
|
|
MOV r0, r3 @ return obuf
|
|
|
|
LDMFD r13!,{r4-r8,r10-r11,PC}
|
|
SimpleRate_M_read:
|
|
LDR r0, [r13,#8] @ r0 = sr (8 = 4*2)
|
|
ADD r0, r0, #16 @ r0 = inPtr = inBuf
|
|
STMFD r13!,{r0,r2-r3,r12,r14}
|
|
|
|
MOV r1, r0 @ r1 = inBuf
|
|
LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
|
|
MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
|
|
|
|
@ Calling back into C++ here. WinCE is fairly easy about such things
|
|
@ but other OS are more awkward. r9 is preserved for Symbian, and
|
|
@ we have 3+8+5 = 16 things on the stack (an even number).
|
|
MOV r14,PC
|
|
LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
|
|
SUBS r1, r0, #1 @ r1 = inLen-1
|
|
LDMFD r13!,{r0,r2-r3,r12,r14}
|
|
BLT SimpleRate_M_end
|
|
SUBS r2, r2, #1 @ r2 = opos--
|
|
ADDGE r0, r0, #2 @ if (r2 >= 0) { sr.inPtr++
|
|
BGE SimpleRate_M_loop @ and loop }
|
|
B SimpleRate_M_read_return
|
|
|
|
|
|
.align 2
|
|
_ARM_SimpleRate_S:
|
|
@ r0 = AudioStream &input
|
|
@ r1 = input.readBuffer
|
|
@ r2 = input->sr
|
|
@ r3 = obuf
|
|
@ <> = osamp
|
|
@ <> = vol_l
|
|
@ <> = vol_r
|
|
MOV r12,r13
|
|
STMFD r13!,{r0-r2,r4-r8,r10-r11,r14}
|
|
LDMFD r12,{r11,r12,r14} @ r11= osamp
|
|
@ r12= vol_l
|
|
@ r14= vol_r
|
|
LDMIA r2,{r0,r1,r2,r8} @ r0 = inPtr
|
|
@ r1 = inLen
|
|
@ r2 = opos
|
|
@ r8 = opos_inc
|
|
CMP r11,#0 @ if (osamp <= 0)
|
|
BLE SimpleRate_S_end @ bale
|
|
MOV r10,#0
|
|
ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
|
|
ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
|
|
SimpleRate_S_loop:
|
|
SUBS r1, r1, #2 @ r1 = inLen -= 2
|
|
BLT SimpleRate_S_read
|
|
SUBS r2, r2, #1 @ r2 = opos--
|
|
ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2
|
|
BGE SimpleRate_S_loop @ and loop }
|
|
SimpleRate_S_read_return:
|
|
LDRSH r4, [r0],#2 @ r4 = tmp0 = *inPtr++
|
|
LDRSH r5, [r0],#2 @ r5 = tmp1 = *inPtr++
|
|
LDRSH r6, [r3] @ r6 = obuf[0]
|
|
LDRSH r7, [r3,#2] @ r7 = obuf[1]
|
|
ADD r2, r2, r8 @ r2 = opos += opos_inc
|
|
MUL r4, r12,r4 @ r4 = tmp0*vol_l
|
|
MUL r5, r14,r5 @ r5 = tmp1*vol_r
|
|
|
|
ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
|
|
RSCVS r6, r10,#0x80000000 @ Clamp r6
|
|
ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
|
|
RSCVS r7, r10,#0x80000000 @ Clamp r7
|
|
|
|
MOV r6, r6, LSR #16 @ Shift back to halfword
|
|
MOV r7, r7, LSR #16 @ Shift back to halfword
|
|
|
|
STRH r6, [r3],#2 @ Store output value
|
|
STRH r7, [r3],#2 @ Store output value
|
|
|
|
SUBS r11,r11,#1 @ osamp--
|
|
BGT SimpleRate_S_loop @ and loop
|
|
SimpleRate_S_end:
|
|
LDR r14,[r13,#8] @ r14 = sr
|
|
ADD r13,r13,#12 @ skip over r0-r2 on stack
|
|
STMIA r14,{r0,r1,r2} @ store back updated values
|
|
MOV r0, r3 @ return obuf
|
|
LDMFD r13!,{r4-r8,r10-r11,PC}
|
|
SimpleRate_S_read:
|
|
LDR r0, [r13,#8] @ r0 = sr (8 = 4*2)
|
|
ADD r0, r0, #16 @ r0 = inPtr = inBuf
|
|
STMFD r13!,{r0,r2-r3,r12,r14}
|
|
MOV r1, r0 @ r1 = inBuf
|
|
LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
|
|
MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
|
|
|
|
@ Calling back into C++ here. WinCE is fairly easy about such things
|
|
@ but other OS are more awkward. r9 is preserved for Symbian, and
|
|
@ we have 3+8+5 = 16 things on the stack (an even number).
|
|
MOV r14,PC
|
|
LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
|
|
SUBS r1, r0, #2 @ r1 = inLen-2
|
|
LDMFD r13!,{r0,r2-r3,r12,r14}
|
|
BLT SimpleRate_S_end
|
|
SUBS r2, r2, #1 @ r2 = opos--
|
|
ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2
|
|
BGE SimpleRate_S_loop @ and loop }
|
|
B SimpleRate_S_read_return
|
|
|
|
|
|
|
|
.align 2
|
|
_ARM_SimpleRate_R:
|
|
@ r0 = AudioStream &input
|
|
@ r1 = input.readBuffer
|
|
@ r2 = input->sr
|
|
@ r3 = obuf
|
|
@ <> = osamp
|
|
@ <> = vol_l
|
|
@ <> = vol_r
|
|
MOV r12,r13
|
|
STMFD r13!,{r0-r2,r4-r8,r10-r11,r14}
|
|
LDMFD r12,{r11,r12,r14} @ r11= osamp
|
|
@ r12= vol_l
|
|
@ r14= vol_r
|
|
LDMIA r2,{r0,r1,r2,r8} @ r0 = inPtr
|
|
@ r1 = inLen
|
|
@ r2 = opos
|
|
@ r8 = opos_inc
|
|
CMP r11,#0 @ if (osamp <= 0)
|
|
BLE SimpleRate_R_end @ bale
|
|
MOV r10,#0
|
|
ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
|
|
ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
|
|
SimpleRate_R_loop:
|
|
SUBS r1, r1, #2 @ r1 = inLen -= 2
|
|
BLT SimpleRate_R_read
|
|
SUBS r2, r2, #1 @ r2 = opos--
|
|
ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2
|
|
BGE SimpleRate_R_loop @ and loop }
|
|
SimpleRate_R_read_return:
|
|
LDRSH r4, [r0],#2 @ r4 = tmp0 = *inPtr++
|
|
LDRSH r5, [r0],#2 @ r5 = tmp1 = *inPtr++
|
|
LDRSH r6, [r3] @ r6 = obuf[0]
|
|
LDRSH r7, [r3,#2] @ r7 = obuf[1]
|
|
ADD r2, r2, r8 @ r2 = opos += opos_inc
|
|
MUL r4, r12,r4 @ r4 = tmp0*vol_l
|
|
MUL r5, r14,r5 @ r5 = tmp1*vol_r
|
|
|
|
ADDS r6, r5, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp1*vol_r
|
|
RSCVS r6, r10,#0x80000000 @ Clamp r6
|
|
ADDS r7, r4, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp0*vol_l
|
|
RSCVS r7, r10,#0x80000000 @ Clamp r7
|
|
|
|
MOV r6, r6, LSR #16 @ Shift back to halfword
|
|
MOV r7, r7, LSR #16 @ Shift back to halfword
|
|
|
|
STRH r6, [r3],#2 @ Store output value
|
|
STRH r7, [r3],#2 @ Store output value
|
|
|
|
SUBS r11,r11,#1 @ osamp--
|
|
BGT SimpleRate_R_loop @ and loop
|
|
SimpleRate_R_end:
|
|
LDR r14,[r13,#8] @ r14 = sr
|
|
ADD r13,r13,#12 @ skip over r0-r2 on stack
|
|
STMIA r14,{r0,r1,r2} @ store back updated values
|
|
MOV r0, r3 @ return obuf
|
|
LDMFD r13!,{r4-r8,r10-r11,PC}
|
|
SimpleRate_R_read:
|
|
LDR r0, [r13,#8] @ r0 = sr (8 = 4*2)
|
|
ADD r0, r0, #16 @ r0 = inPtr = inBuf
|
|
STMFD r13!,{r0,r2-r3,r12,r14}
|
|
MOV r1, r0 @ r1 = inBuf
|
|
LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
|
|
MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
|
|
|
|
@ Calling back into C++ here. WinCE is fairly easy about such things
|
|
@ but other OS are more awkward. r9 is preserved for Symbian, and
|
|
@ we have 3+8+5 = 16 things on the stack (an even number).
|
|
MOV r14,PC
|
|
LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
|
|
SUBS r1, r0, #2 @ r1 = inLen-2
|
|
LDMFD r13!,{r0,r2-r3,r12,r14}
|
|
BLT SimpleRate_R_end
|
|
SUBS r2, r2, #1 @ r2 = opos--
|
|
ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2
|
|
BGE SimpleRate_R_loop @ and loop }
|
|
B SimpleRate_R_read_return
|
|
|
|
|
|
.align 2
|
|
_ARM_LinearRate_M:
|
|
@ r0 = AudioStream &input
|
|
@ r1 = input.readBuffer
|
|
@ r2 = input->sr
|
|
@ r3 = obuf
|
|
@ <> = osamp
|
|
@ <> = vol_l
|
|
@ <> = vol_r
|
|
MOV r12,r13
|
|
STMFD r13!,{r0-r1,r4-r11,r14}
|
|
LDMFD r12,{r11,r12,r14} @ r11= osamp
|
|
@ r12= vol_l
|
|
@ r14= vol_r
|
|
LDMIA r2,{r0,r1,r8} @ r0 = inPtr
|
|
@ r1 = inLen
|
|
@ r8 = opos
|
|
MOV r10,#0
|
|
CMP r11,#0 @ if (osamp <= 0)
|
|
BLE LinearRate_M_end @ bale
|
|
ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
|
|
ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
|
|
CMP r1,#0
|
|
BGT LinearRate_M_part2
|
|
|
|
@ part1 - read input samples
|
|
LinearRate_M_loop:
|
|
SUBS r1, r1, #1 @ r1 = inLen -= 1
|
|
BLT LinearRate_M_read
|
|
LinearRate_M_read_return:
|
|
LDRH r4, [r2, #16] @ r4 = icur[0]
|
|
LDRSH r5, [r0],#2 @ r5 = tmp1 = *inPtr++
|
|
SUBS r8, r8, #65536 @ r8 = opos--
|
|
STRH r4, [r2,#22] @ ilast[0] = icur[0]
|
|
STRH r5, [r2,#16] @ icur[0] = tmp1
|
|
BGE LinearRate_M_loop
|
|
|
|
@ part2 - form output samples
|
|
LinearRate_M_part2:
|
|
@ We are guaranteed that opos < 0 here
|
|
LDR r6, [r2,#20] @ r6 = ilast[0]<<16 + 32768
|
|
LDRSH r5, [r2,#16] @ r5 = icur[0]
|
|
MOV r4, r8, LSL #16
|
|
MOV r4, r4, LSR #16
|
|
SUB r5, r5, r6, ASR #16 @ r5 = icur[0] - ilast[0]
|
|
MLA r6, r4, r5, r6 @ r6 = (icur[0]-ilast[0])*opos_frac+ilast[0]
|
|
|
|
LDRSH r4, [r3] @ r4 = obuf[0]
|
|
LDRSH r5, [r3,#2] @ r5 = obuf[1]
|
|
MOV r6, r6, ASR #15 @ r6 = tmp0 = tmp1 >>= 15
|
|
MUL r7, r12,r6 @ r7 = tmp0*vol_l
|
|
MUL r6, r14,r6 @ r6 = tmp1*vol_r
|
|
|
|
ADDS r7, r7, r4, LSL #15 @ r7 = obuf[0]<<15 + tmp0*vol_l
|
|
RSCVS r7, r10, #0x80000000 @ Clamp r7
|
|
ADDS r6, r6, r5, LSL #15 @ r6 = obuf[1]<<15 + tmp1*vol_r
|
|
RSCVS r6, r10, #0x80000000 @ Clamp r6
|
|
|
|
MOV r7, r7, LSR #15 @ Shift back to halfword
|
|
MOV r6, r6, LSR #15 @ Shift back to halfword
|
|
|
|
LDR r5, [r2,#12] @ r5 = opos_inc
|
|
STRH r7, [r3],#2 @ Store output value
|
|
STRH r6, [r3],#2 @ Store output value
|
|
SUBS r11, r11,#1 @ osamp--
|
|
BLE LinearRate_M_end @ end if needed
|
|
|
|
ADDS r8, r8, r5 @ r8 = opos += opos_inc
|
|
BLT LinearRate_M_part2
|
|
B LinearRate_M_loop
|
|
LinearRate_M_end:
|
|
ADD r13,r13,#8
|
|
STMIA r2,{r0,r1,r8}
|
|
MOV r0, r3 @ return obuf
|
|
LDMFD r13!,{r4-r11,PC}
|
|
LinearRate_M_read:
|
|
ADD r0, r2, #28 @ r0 = inPtr = inBuf
|
|
STMFD r13!,{r0,r2-r3,r12,r14}
|
|
|
|
MOV r1, r0 @ r1 = inBuf
|
|
LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
|
|
MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
|
|
|
|
@ Calling back into C++ here. WinCE is fairly easy about such things
|
|
@ but other OS are more awkward. r9 is preserved for Symbian, and
|
|
@ we have 2+9+5 = 16 things on the stack (an even number).
|
|
MOV r14,PC
|
|
LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
|
|
SUBS r1, r0, #1 @ r1 = inLen-1
|
|
LDMFD r13!,{r0,r2-r3,r12,r14}
|
|
BLT LinearRate_M_end
|
|
B LinearRate_M_read_return
|
|
|
|
.align 2
|
|
_ARM_LinearRate_S:
|
|
@ r0 = AudioStream &input
|
|
@ r1 = input.readBuffer
|
|
@ r2 = input->sr
|
|
@ r3 = obuf
|
|
@ <> = osamp
|
|
@ <> = vol_l
|
|
@ <> = vol_r
|
|
MOV r12,r13
|
|
STMFD r13!,{r0-r1,r4-r11,r14}
|
|
LDMFD r12,{r11,r12,r14} @ r11= osamp
|
|
@ r12= vol_l
|
|
@ r14= vol_r
|
|
LDMIA r2,{r0,r1,r8} @ r0 = inPtr
|
|
@ r1 = inLen
|
|
@ r8 = opos
|
|
CMP r11,#0 @ if (osamp <= 0)
|
|
BLE LinearRate_S_end @ bale
|
|
ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
|
|
ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
|
|
CMP r1,#0
|
|
BGT LinearRate_S_part2
|
|
|
|
@ part1 - read input samples
|
|
LinearRate_S_loop:
|
|
SUBS r1, r1, #2 @ r1 = inLen -= 2
|
|
BLT LinearRate_S_read
|
|
LinearRate_S_read_return:
|
|
LDR r10,[r2, #16] @ r10= icur[0,1]
|
|
LDRSH r5, [r0],#2 @ r5 = tmp0 = *inPtr++
|
|
LDRSH r6, [r0],#2 @ r6 = tmp1 = *inPtr++
|
|
SUBS r8, r8, #65536 @ r8 = opos--
|
|
STRH r10,[r2,#22] @ ilast[0] = icur[0]
|
|
MOV r10,r10,LSR #16
|
|
STRH r10,[r2,#26] @ ilast[1] = icur[1]
|
|
STRH r5, [r2,#16] @ icur[0] = tmp0
|
|
STRH r6, [r2,#18] @ icur[1] = tmp1
|
|
BGE LinearRate_S_loop
|
|
|
|
@ part2 - form output samples
|
|
LinearRate_S_part2:
|
|
@ We are guaranteed that opos < 0 here
|
|
LDR r6, [r2,#20] @ r6 = ilast[0]<<16 + 32768
|
|
LDRSH r5, [r2,#16] @ r5 = icur[0]
|
|
MOV r4, r8, LSL #16
|
|
MOV r4, r4, LSR #16
|
|
SUB r5, r5, r6, ASR #16 @ r5 = icur[0] - ilast[0]
|
|
MLA r6, r4, r5, r6 @ r6 = (icur[0]-ilast[0])*opos_frac+ilast[0]
|
|
|
|
LDR r7, [r2,#24] @ r7 = ilast[1]<<16 + 32768
|
|
LDRSH r5, [r2,#18] @ r5 = icur[1]
|
|
LDRSH r10,[r3] @ r10= obuf[0]
|
|
MOV r6, r6, ASR #15 @ r6 = tmp1 >>= 15
|
|
SUB r5, r5, r7, ASR #16 @ r5 = icur[1] - ilast[1]
|
|
MLA r7, r4, r5, r7 @ r7 = (icur[1]-ilast[1])*opos_frac+ilast[1]
|
|
|
|
LDRSH r5, [r3,#2] @ r5 = obuf[1]
|
|
MOV r7, r7, ASR #15 @ r7 = tmp0 >>= 15
|
|
MUL r7, r12,r7 @ r7 = tmp0*vol_l
|
|
MUL r6, r14,r6 @ r6 = tmp1*vol_r
|
|
|
|
ADDS r7, r7, r10, LSL #15 @ r7 = obuf[0]<<15 + tmp0*vol_l
|
|
MOV r4, #0
|
|
RSCVS r7, r4, #0x80000000 @ Clamp r7
|
|
ADDS r6, r6, r5, LSL #15 @ r6 = obuf[1]<<15 + tmp1*vol_r
|
|
RSCVS r6, r4, #0x80000000 @ Clamp r6
|
|
|
|
MOV r7, r7, LSR #15 @ Shift back to halfword
|
|
MOV r6, r6, LSR #15 @ Shift back to halfword
|
|
|
|
LDR r5, [r2,#12] @ r5 = opos_inc
|
|
STRH r7, [r3],#2 @ Store output value
|
|
STRH r6, [r3],#2 @ Store output value
|
|
SUBS r11, r11,#1 @ osamp--
|
|
BLE LinearRate_S_end @ and loop
|
|
|
|
ADDS r8, r8, r5 @ r8 = opos += opos_inc
|
|
BLT LinearRate_S_part2
|
|
B LinearRate_S_loop
|
|
LinearRate_S_end:
|
|
ADD r13,r13,#8
|
|
STMIA r2,{r0,r1,r8}
|
|
MOV r0, r3 @ return obuf
|
|
LDMFD r13!,{r4-r11,PC}
|
|
LinearRate_S_read:
|
|
ADD r0, r2, #28 @ r0 = inPtr = inBuf
|
|
STMFD r13!,{r0,r2-r3,r12,r14}
|
|
|
|
MOV r1, r0 @ r1 = inBuf
|
|
LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
|
|
MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
|
|
|
|
@ Calling back into C++ here. WinCE is fairly easy about such things
|
|
@ but other OS are more awkward. r9 is preserved for Symbian, and
|
|
@ we have 2+9+5 = 16 things on the stack (an even number).
|
|
MOV r14,PC
|
|
LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
|
|
SUBS r1, r0, #2 @ r1 = inLen-2
|
|
LDMFD r13!,{r0,r2-r3,r12,r14}
|
|
BLT LinearRate_S_end
|
|
B LinearRate_S_read_return
|
|
|
|
.align 2
|
|
_ARM_LinearRate_R:
|
|
@ r0 = AudioStream &input
|
|
@ r1 = input.readBuffer
|
|
@ r2 = input->sr
|
|
@ r3 = obuf
|
|
@ <> = osamp
|
|
@ <> = vol_l
|
|
@ <> = vol_r
|
|
MOV r12,r13
|
|
STMFD r13!,{r0-r1,r4-r11,r14}
|
|
LDMFD r12,{r11,r12,r14} @ r11= osamp
|
|
@ r12= vol_l
|
|
@ r14= vol_r
|
|
LDMIA r2,{r0,r1,r8} @ r0 = inPtr
|
|
@ r1 = inLen
|
|
@ r8 = opos
|
|
CMP r11,#0 @ if (osamp <= 0)
|
|
BLE LinearRate_R_end @ bale
|
|
ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
|
|
ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
|
|
CMP r1,#0
|
|
BGT LinearRate_R_part2
|
|
|
|
@ part1 - read input samples
|
|
LinearRate_R_loop:
|
|
SUBS r1, r1, #2 @ r1 = inLen -= 2
|
|
BLT LinearRate_R_read
|
|
LinearRate_R_read_return:
|
|
LDR r10,[r2, #16] @ r10= icur[0,1]
|
|
LDRSH r5, [r0],#2 @ r5 = tmp0 = *inPtr++
|
|
LDRSH r6, [r0],#2 @ r6 = tmp1 = *inPtr++
|
|
SUBS r8, r8, #65536 @ r8 = opos--
|
|
STRH r10,[r2,#22] @ ilast[0] = icur[0]
|
|
MOV r10,r10,LSR #16
|
|
STRH r10,[r2,#26] @ ilast[1] = icur[1]
|
|
STRH r5, [r2,#16] @ icur[0] = tmp0
|
|
STRH r6, [r2,#18] @ icur[1] = tmp1
|
|
BGE LinearRate_R_loop
|
|
|
|
@ part2 - form output samples
|
|
LinearRate_R_part2:
|
|
@ We are guaranteed that opos < 0 here
|
|
LDR r6, [r2,#20] @ r6 = ilast[0]<<16 + 32768
|
|
LDRSH r5, [r2,#16] @ r5 = icur[0]
|
|
MOV r4, r8, LSL #16
|
|
MOV r4, r4, LSR #16
|
|
SUB r5, r5, r6, ASR #16 @ r5 = icur[0] - ilast[0]
|
|
MLA r6, r4, r5, r6 @ r6 = (icur[0]-ilast[0])*opos_frac+ilast[0]
|
|
|
|
LDR r7, [r2,#24] @ r7 = ilast[1]<<16 + 32768
|
|
LDRSH r5, [r2,#18] @ r5 = icur[1]
|
|
LDRSH r10,[r3,#2] @ r10= obuf[1]
|
|
MOV r6, r6, ASR #15 @ r6 = tmp1 >>= 15
|
|
SUB r5, r5, r7, ASR #16 @ r5 = icur[1] - ilast[1]
|
|
MLA r7, r4, r5, r7 @ r7 = (icur[1]-ilast[1])*opos_frac+ilast[1]
|
|
|
|
LDRSH r5, [r3] @ r5 = obuf[0]
|
|
MOV r7, r7, ASR #15 @ r7 = tmp0 >>= 15
|
|
MUL r7, r12,r7 @ r7 = tmp0*vol_l
|
|
MUL r6, r14,r6 @ r6 = tmp1*vol_r
|
|
|
|
ADDS r7, r7, r10, LSL #15 @ r7 = obuf[1]<<15 + tmp0*vol_l
|
|
MOV r4, #0
|
|
RSCVS r7, r4, #0x80000000 @ Clamp r7
|
|
ADDS r6, r6, r5, LSL #15 @ r6 = obuf[0]<<15 + tmp1*vol_r
|
|
RSCVS r6, r4, #0x80000000 @ Clamp r6
|
|
|
|
MOV r7, r7, LSR #15 @ Shift back to halfword
|
|
MOV r6, r6, LSR #15 @ Shift back to halfword
|
|
|
|
LDR r5, [r2,#12] @ r5 = opos_inc
|
|
STRH r6, [r3],#2 @ Store output value
|
|
STRH r7, [r3],#2 @ Store output value
|
|
SUBS r11, r11,#1 @ osamp--
|
|
BLE LinearRate_R_end @ and loop
|
|
|
|
ADDS r8, r8, r5 @ r8 = opos += opos_inc
|
|
BLT LinearRate_R_part2
|
|
B LinearRate_R_loop
|
|
LinearRate_R_end:
|
|
ADD r13,r13,#8
|
|
STMIA r2,{r0,r1,r8}
|
|
MOV r0, r3 @ return obuf
|
|
LDMFD r13!,{r4-r11,PC}
|
|
LinearRate_R_read:
|
|
ADD r0, r2, #28 @ r0 = inPtr = inBuf
|
|
STMFD r13!,{r0,r2-r3,r12,r14}
|
|
|
|
MOV r1, r0 @ r1 = inBuf
|
|
LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
|
|
MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
|
|
|
|
@ Calling back into C++ here. WinCE is fairly easy about such things
|
|
@ but other OS are more awkward. r9 is preserved for Symbian, and
|
|
@ we have 2+9+5 = 16 things on the stack (an even number).
|
|
MOV r14,PC
|
|
LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
|
|
SUBS r1, r0, #2 @ r1 = inLen-2
|
|
LDMFD r13!,{r0,r2-r3,r12,r14}
|
|
BLT LinearRate_R_end
|
|
B LinearRate_R_read_return
|