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/progs | |
parent | 01cccaf2d27dcd92a7a6d4b7f5658e780a6da68c (diff) | |
download | rockbox-c0cc9aa9e8d63d24c54d25bd32cdcc62208e8206.tar.gz rockbox-c0cc9aa9e8d63d24c54d25bd32cdcc62208e8206.zip |
quake: clean up asm mixer
Fixes my ugly formatting.
Diffstat (limited to 'apps/plugins/sdl/progs')
-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 @@ | |||
19 | * | 19 | * |
20 | ***************************************************************************/ | 20 | ***************************************************************************/ |
21 | 21 | ||
22 | /** Sound mixing code for ARM. **/ | 22 | /* |
23 | /* Takes 8-bit mono audio and outputs stereo 16-bit samples. | 23 | * Sound mixing code for ARM. |
24 | * stereo volumes are passed as arguments. | 24 | * |
25 | * | 25 | * Takes an array of 8-bit mono audio and outputs stereo 16-bit |
26 | * Bear with me. This is my first ARM assembly, ever. | 26 | * samples. Stereo volumes are passed as arguments r0 and r1. |
27 | */ | 27 | * |
28 | * Bear with me. This is my first ARM assembly, ever. | ||
29 | */ | ||
28 | 30 | ||
29 | .text | 31 | .text |
30 | .align 2 | 32 | .align 2 |
@@ -33,93 +35,74 @@ | |||
33 | 35 | ||
34 | #if defined(__ARM_ARCH_5TEJ__) | 36 | #if defined(__ARM_ARCH_5TEJ__) |
35 | SND_PaintChannelFrom8: | 37 | SND_PaintChannelFrom8: |
36 | // r0: int true_lvol | 38 | ;; r0: int true_lvol |
37 | // r1: int true_rvol | 39 | ;; r1: int true_rvol |
38 | // r2: char *sfx | 40 | ;; r2: char *sfx |
39 | // r3: int count | 41 | ;; r3: int count |
40 | 42 | ||
41 | stmfd sp!, {r4, r5, r6, r7, r8, sl} | 43 | stmfd sp!, {r4, r5, r6, r7, r8, sl} |
42 | 44 | ||
43 | ldr ip, =paintbuffer | 45 | ldr ip, =paintbuffer |
44 | ldr ip, [ip] | 46 | ldr ip, [ip] |
45 | 47 | ||
46 | mov r0, r0, asl #16 // pre-scale both volumes by 2^16 | 48 | mov r0, r0, asl #16 ; prescale by 2^16 |
47 | mov r1, r1, asl #16 | 49 | mov r1, r1, asl #16 |
48 | 50 | ||
49 | sub r3, r3, #1 // we'll count backwards | 51 | sub r3, r3, #1 ; count backwards |
50 | // sl = 0xffff0000 | ||
51 | ldrh sl, =0xffff | ||
52 | 52 | ||
53 | .loop: | 53 | ldrh sl, =0xffff ; halfword mask |
54 | ldrsb r4, [r2, r3] // load *sfx[i] -> r4 | ||
55 | 54 | ||
56 | // keep endianness in mind here | 55 | 1: |
57 | // buffer looks like [left_0, left_1, right_0, right_1] in memory | 56 | ldrsb r4, [r2, r3] ; load input sample |
58 | // but it is loaded as [right1, right0, left1, left0] to registers | 57 | ldr r8, [ip, r3, lsl #2] ; load output sample pair from paintbuffer |
59 | ldr r8, [ip, r3, lsl #2] // load paintbuffer[0:1] = RIGHTCHANNEL:LEFTCHANNEL | 58 | ; (left:right in memory -> right:left in register) |
59 | ;; right channel (high half) | ||
60 | mul r5, r4, r1 ; scaledright = sfx[i] * (true_rvol << 16) -- bottom half is zero | ||
61 | qadd r7, r5, r8 ; right = scaledright + right (in high half of word) | ||
62 | bic r7, r7, sl ; zero bottom half of r7 | ||
60 | 63 | ||
61 | // handle high half (right channel) first | 64 | ;; left channel (low half) |
62 | mul r5, r4, r1 // SCALEDRIGHT = SFXI * (true_rvol << 16) -- bottom half is zero | 65 | mul r5, r4, r0 ; scaledleft = sfx[i] * (true_rvol << 16) |
66 | mov r8, r8, lsl #16 ; extract original left channel from paintbuffer | ||
67 | qadd r8, r5, r8 ; left = scaledleft + left | ||
63 | 68 | ||
64 | // r7 holds right channel in high half (dirty bottom half) | 69 | orr r7, r7, r8, lsr #16 ; combine right:left in r7 |
65 | qadd r7, r5, r8 // RIGHTCHANORIG = SCALEDRIGHT + RIGHTCHANORIG (high half) | 70 | str r7, [ip, r3, lsl #2] ; write right:left to output buffer |
66 | |||
67 | bic r7, r7, sl // zero bottom bits of r7 | ||
68 | |||
69 | // trash r5, r6 and handle left channel | ||
70 | mul r5, r4, r0 // SCALEDLEFT = SFXI * (true_rvol << 16) | ||
71 | |||
72 | mov r8, r8, lsl #16 // extract original left channel from paintbuffer | ||
73 | |||
74 | // r8 holds left channel in high half with zero bottom half | ||
75 | qadd r8, r5, r8 | ||
76 | |||
77 | // combine the two 16-bit samples in r7 as 32-bit [left:right] | ||
78 | // (use lsr to not sign-extend the lower half) | ||
79 | orr r7, r7, r8, lsr #16 | ||
80 | |||
81 | str r7, [ip, r3, lsl #2] // write 32-bit to paintbuffer | ||
82 | subs r3, r3, #1 | 71 | subs r3, r3, #1 |
83 | bgt .loop // must use instead of bne because of the corner case count=1 | ||
84 | |||
85 | 72 | ||
73 | bgt 1b ; must use bgt instead of bne in case count=1 | ||
86 | 74 | ||
87 | ldmfd sp!, {r4, r5, r6, r7, r8, sl} | 75 | ldmfd sp!, {r4, r5, r6, r7, r8, sl} |
88 | 76 | ||
89 | bx lr | 77 | bx lr |
90 | 78 | ||
91 | #elif defined(__ARM_ARCH_6__) // ARMv6 with QADD16 (disabled) | 79 | #elif defined(__ARM_ARCH_6__) ; ARMv6 with QADD16 (disabled) |
92 | SND_PaintChannelFrom8: | 80 | SND_PaintChannelFrom8: |
93 | // r0: int true_lvol | 81 | ;; r0: int true_lvol |
94 | // r1: int true_rvol | 82 | ;; r1: int true_rvol |
95 | // r2: char *sfx | 83 | ;; r2: char *sfx |
96 | // r3: int count | 84 | ;; r3: int count |
97 | 85 | ||
98 | stmfd sp!, {r4, r5, r6, r7} | 86 | stmfd sp!, {r4, r5, r6, r7} |
99 | 87 | ||
100 | ldr ip, =paintbuffer | 88 | ldr ip, =paintbuffer |
101 | ldr ip, [ip] | 89 | ldr ip, [ip] ; load paintbuffer address |
102 | sub r3, r3, #1 // we'll count backwards | 90 | sub r3, r3, #1 ; we'll count backwards |
103 | .loop: | 91 | 1: |
104 | ldrsb r4, [r2, r3] // load *sfx[i] -> r4 | 92 | ldrsb r4, [r2, r3] ; load sfx[i] -> r4 |
105 | 93 | ldr r7, [ip, r3, lsl #2] ; load old sample pair | |
106 | // keep endianness in mind here | ||
107 | // buffer looks like [left_0, left_1, right_0, right_1] in memory | ||
108 | // but it is loaded as [right1, right0, left1, left0] to registers | ||
109 | ldr r7, [ip, r3, lsl #2] // load paintbuffer[0:1] = RIGHTCHANNEL:LEFTCHANNEL | ||
110 | 94 | ||
111 | // handle high half (right channel) first | 95 | mul r5, r4, r1 ; SCALEDRIGHT = SFXI * true_rvol |
112 | mul r5, r4, r1 // SCALEDRIGHT = SFXI * true_rvol | 96 | mul r6, r4, r0 ; SCALEDLEFT = SFXI * true_rvol |
113 | mul r6, r4, r0 // SCALEDLEFT = SFXI * true_rvol | ||
114 | 97 | ||
115 | orr r6, r6, r5, lsl #16 | 98 | orr r6, r6, r5, lsl #16 ; combine samples as 32-bit |
116 | 99 | ||
117 | qadd16 r6, r6, r7 | 100 | qadd16 r6, r6, r7 ; parallel 16-bit add |
118 | 101 | ||
119 | str r6, [ip, r3, lsl #2] // write 32-bit to paintbuffer | 102 | str r6, [ip, r3, lsl #2] ; write 32-bit to paintbuffer |
120 | 103 | ||
121 | subs r3, r3, #1 | 104 | subs r3, r3, #1 |
122 | bne .loop | 105 | bgt 1b |
123 | 106 | ||
124 | ldmfd sp!, {r4, r5, r6, r7} | 107 | ldmfd sp!, {r4, r5, r6, r7} |
125 | 108 | ||