diff options
author | Franklin Wei <franklin@rockbox.org> | 2019-10-07 14:48:21 -0400 |
---|---|---|
committer | Franklin Wei <franklin@rockbox.org> | 2019-10-07 14:52:30 -0400 |
commit | c0cc9aa9e8d63d24c54d25bd32cdcc62208e8206 (patch) | |
tree | 8440269bb0d5b92055496f56f58a23564f38cd3f /apps/plugins/sdl | |
parent | 01cccaf2d27dcd92a7a6d4b7f5658e780a6da68c (diff) |
quake: clean up asm mixer
Fixes my ugly formatting.
Diffstat (limited to 'apps/plugins/sdl')
-rw-r--r-- | apps/plugins/sdl/progs/quake/snd_mix_arm.S | 109 |
1 files changed, 46 insertions, 63 deletions
diff --git a/apps/plugins/sdl/progs/quake/snd_mix_arm.S b/apps/plugins/sdl/progs/quake/snd_mix_arm.S index 15733d8912..0573e85923 100644 --- a/apps/plugins/sdl/progs/quake/snd_mix_arm.S +++ b/apps/plugins/sdl/progs/quake/snd_mix_arm.S @@ -19,12 +19,14 @@ * ***************************************************************************/ - /** Sound mixing code for ARM. **/ - /* Takes 8-bit mono audio and outputs stereo 16-bit samples. - * stereo volumes are passed as arguments. - * - * Bear with me. This is my first ARM assembly, ever. - */ + /* + * Sound mixing code for ARM. + * + * Takes an array of 8-bit mono audio and outputs stereo 16-bit + * samples. Stereo volumes are passed as arguments r0 and r1. + * + * Bear with me. This is my first ARM assembly, ever. + */ .text .align 2 @@ -33,93 +35,74 @@ #if defined(__ARM_ARCH_5TEJ__) SND_PaintChannelFrom8: - // r0: int true_lvol - // r1: int true_rvol - // r2: char *sfx - // r3: int count + ;; r0: int true_lvol + ;; r1: int true_rvol + ;; r2: char *sfx + ;; r3: int count stmfd sp!, {r4, r5, r6, r7, r8, sl} ldr ip, =paintbuffer ldr ip, [ip] - mov r0, r0, asl #16 // pre-scale both volumes by 2^16 + mov r0, r0, asl #16 ; prescale by 2^16 mov r1, r1, asl #16 - sub r3, r3, #1 // we'll count backwards - // sl = 0xffff0000 - ldrh sl, =0xffff + sub r3, r3, #1 ; count backwards -.loop: - ldrsb r4, [r2, r3] // load *sfx[i] -> r4 + ldrh sl, =0xffff ; halfword mask - // keep endianness in mind here - // buffer looks like [left_0, left_1, right_0, right_1] in memory - // but it is loaded as [right1, right0, left1, left0] to registers - ldr r8, [ip, r3, lsl #2] // load paintbuffer[0:1] = RIGHTCHANNEL:LEFTCHANNEL +1: + ldrsb r4, [r2, r3] ; load input sample + ldr r8, [ip, r3, lsl #2] ; load output sample pair from paintbuffer + ; (left:right in memory -> right:left in register) + ;; right channel (high half) + mul r5, r4, r1 ; scaledright = sfx[i] * (true_rvol << 16) -- bottom half is zero + qadd r7, r5, r8 ; right = scaledright + right (in high half of word) + bic r7, r7, sl ; zero bottom half of r7 - // handle high half (right channel) first - mul r5, r4, r1 // SCALEDRIGHT = SFXI * (true_rvol << 16) -- bottom half is zero + ;; left channel (low half) + mul r5, r4, r0 ; scaledleft = sfx[i] * (true_rvol << 16) + mov r8, r8, lsl #16 ; extract original left channel from paintbuffer + qadd r8, r5, r8 ; left = scaledleft + left - // r7 holds right channel in high half (dirty bottom half) - qadd r7, r5, r8 // RIGHTCHANORIG = SCALEDRIGHT + RIGHTCHANORIG (high half) - - bic r7, r7, sl // zero bottom bits of r7 - - // trash r5, r6 and handle left channel - mul r5, r4, r0 // SCALEDLEFT = SFXI * (true_rvol << 16) - - mov r8, r8, lsl #16 // extract original left channel from paintbuffer - - // r8 holds left channel in high half with zero bottom half - qadd r8, r5, r8 - - // combine the two 16-bit samples in r7 as 32-bit [left:right] - // (use lsr to not sign-extend the lower half) - orr r7, r7, r8, lsr #16 - - str r7, [ip, r3, lsl #2] // write 32-bit to paintbuffer + orr r7, r7, r8, lsr #16 ; combine right:left in r7 + str r7, [ip, r3, lsl #2] ; write right:left to output buffer subs r3, r3, #1 - bgt .loop // must use instead of bne because of the corner case count=1 - + bgt 1b ; must use bgt instead of bne in case count=1 ldmfd sp!, {r4, r5, r6, r7, r8, sl} bx lr -#elif defined(__ARM_ARCH_6__) // ARMv6 with QADD16 (disabled) +#elif defined(__ARM_ARCH_6__) ; ARMv6 with QADD16 (disabled) SND_PaintChannelFrom8: - // r0: int true_lvol - // r1: int true_rvol - // r2: char *sfx - // r3: int count + ;; r0: int true_lvol + ;; r1: int true_rvol + ;; r2: char *sfx + ;; r3: int count stmfd sp!, {r4, r5, r6, r7} ldr ip, =paintbuffer - ldr ip, [ip] - sub r3, r3, #1 // we'll count backwards -.loop: - ldrsb r4, [r2, r3] // load *sfx[i] -> r4 - - // keep endianness in mind here - // buffer looks like [left_0, left_1, right_0, right_1] in memory - // but it is loaded as [right1, right0, left1, left0] to registers - ldr r7, [ip, r3, lsl #2] // load paintbuffer[0:1] = RIGHTCHANNEL:LEFTCHANNEL + ldr ip, [ip] ; load paintbuffer address + sub r3, r3, #1 ; we'll count backwards +1: + ldrsb r4, [r2, r3] ; load sfx[i] -> r4 + ldr r7, [ip, r3, lsl #2] ; load old sample pair - // handle high half (right channel) first - mul r5, r4, r1 // SCALEDRIGHT = SFXI * true_rvol - mul r6, r4, r0 // SCALEDLEFT = SFXI * true_rvol + mul r5, r4, r1 ; SCALEDRIGHT = SFXI * true_rvol + mul r6, r4, r0 ; SCALEDLEFT = SFXI * true_rvol - orr r6, r6, r5, lsl #16 + orr r6, r6, r5, lsl #16 ; combine samples as 32-bit - qadd16 r6, r6, r7 + qadd16 r6, r6, r7 ; parallel 16-bit add - str r6, [ip, r3, lsl #2] // write 32-bit to paintbuffer + str r6, [ip, r3, lsl #2] ; write 32-bit to paintbuffer subs r3, r3, #1 - bne .loop + bgt 1b ldmfd sp!, {r4, r5, r6, r7} |