4f265db7 |
1 | @ vim:filetype=armasm |
2 | |
4f265db7 |
3 | |
4 | @ this assumes src is word aligned |
5 | .global mix_16h_to_32 @ int *dest, short *src, int count |
6 | |
7 | mix_16h_to_32: |
8 | stmfd sp!, {r4-r6,lr} |
9 | /* |
10 | tst r1, #2 |
11 | beq m16_32_mo_unalw |
12 | ldrsh r4, [r1], #2 |
13 | ldr r3, [r0] |
14 | sub r2, r2, #1 |
15 | add r3, r3, r4, asr #1 |
16 | str r3, [r0], #4 |
17 | */ |
18 | m16_32_mo_unalw: |
19 | subs r2, r2, #4 |
20 | bmi m16_32_end |
21 | |
22 | m16_32_loop: |
23 | ldmia r0, {r3-r6} |
24 | ldmia r1!,{r12,lr} |
25 | subs r2, r2, #4 |
26 | add r4, r4, r12,asr #17 @ we use half volume |
27 | mov r12,r12,lsl #16 |
28 | add r3, r3, r12,asr #17 |
29 | add r6, r6, lr, asr #17 |
30 | mov lr, lr, lsl #16 |
31 | add r5, r5, lr, asr #17 |
32 | stmia r0!,{r3-r6} |
33 | bpl m16_32_loop |
34 | |
35 | m16_32_end: |
36 | tst r2, #2 |
37 | beq m16_32_no_unal2 |
38 | ldr r5, [r1], #4 |
39 | ldmia r0, {r3,r4} |
40 | mov r12,r5, lsl #16 |
41 | add r3, r3, r12,asr #17 |
42 | add r4, r4, r5, asr #17 |
43 | stmia r0!,{r3,r4} |
44 | |
45 | m16_32_no_unal2: |
46 | tst r2, #1 |
47 | ldmeqfd sp!, {r4-r6,pc} |
48 | ldrsh r4, [r1], #2 |
49 | ldr r3, [r0] |
50 | add r3, r3, r4, asr #1 |
51 | str r3, [r0], #4 |
52 | |
53 | ldmfd sp!, {r4-r6,lr} |
54 | bx lr |
55 | |
56 | |
57 | |
58 | .global mix_16h_to_32_s1 @ int *dest, short *src, int count |
59 | |
60 | mix_16h_to_32_s1: |
61 | stmfd sp!, {r4-r6,lr} |
62 | |
63 | subs r2, r2, #4 |
64 | bmi m16_32_s1_end |
65 | |
66 | m16_32_s1_loop: |
67 | ldmia r0, {r3-r6} |
68 | ldr r12,[r1], #8 |
69 | ldr lr, [r1], #8 |
70 | subs r2, r2, #4 |
71 | add r4, r4, r12,asr #17 |
72 | mov r12,r12,lsl #16 |
73 | add r3, r3, r12,asr #17 @ we use half volume |
74 | add r6, r6, lr, asr #17 |
75 | mov lr, lr, lsl #16 |
76 | add r5, r5, lr, asr #17 |
77 | stmia r0!,{r3-r6} |
78 | bpl m16_32_s1_loop |
79 | |
80 | m16_32_s1_end: |
81 | tst r2, #2 |
82 | beq m16_32_s1_no_unal2 |
83 | ldr r5, [r1], #8 |
84 | ldmia r0, {r3,r4} |
85 | mov r12,r5, lsl #16 |
86 | add r3, r3, r12,asr #17 |
87 | add r4, r4, r5, asr #17 |
88 | stmia r0!,{r3,r4} |
89 | |
90 | m16_32_s1_no_unal2: |
91 | tst r2, #1 |
92 | ldmeqfd sp!, {r4-r6,pc} |
93 | ldrsh r4, [r1], #2 |
94 | ldr r3, [r0] |
95 | add r3, r3, r4, asr #1 |
96 | str r3, [r0], #4 |
97 | |
98 | ldmfd sp!, {r4-r6,lr} |
99 | bx lr |
100 | |
101 | |
102 | |
103 | .global mix_16h_to_32_s2 @ int *dest, short *src, int count |
104 | |
105 | mix_16h_to_32_s2: |
106 | stmfd sp!, {r4-r6,lr} |
107 | |
108 | subs r2, r2, #4 |
109 | bmi m16_32_s2_end |
110 | |
111 | m16_32_s2_loop: |
112 | ldmia r0, {r3-r6} |
113 | ldr r12,[r1], #16 |
114 | ldr lr, [r1], #16 |
115 | subs r2, r2, #4 |
116 | add r4, r4, r12,asr #17 |
117 | mov r12,r12,lsl #16 |
118 | add r3, r3, r12,asr #17 @ we use half volume |
119 | add r6, r6, lr, asr #17 |
120 | mov lr, lr, lsl #16 |
121 | add r5, r5, lr, asr #17 |
122 | stmia r0!,{r3-r6} |
123 | bpl m16_32_s2_loop |
124 | |
125 | m16_32_s2_end: |
126 | tst r2, #2 |
127 | beq m16_32_s2_no_unal2 |
128 | ldr r5, [r1], #16 |
129 | ldmia r0, {r3,r4} |
130 | mov r12,r5, lsl #16 |
131 | add r3, r3, r12,asr #17 |
132 | add r4, r4, r5, asr #17 |
133 | stmia r0!,{r3,r4} |
134 | |
135 | m16_32_s2_no_unal2: |
136 | tst r2, #1 |
137 | ldmeqfd sp!, {r4-r6,pc} |
138 | ldrsh r4, [r1], #2 |
139 | ldr r3, [r0] |
140 | add r3, r3, r4, asr #1 |
141 | str r3, [r0], #4 |
142 | |
143 | ldmfd sp!, {r4-r6,lr} |
144 | bx lr |
145 | |
146 | |
147 | |
148 | @ limit |
149 | @ reg=int_sample, lr=1, r3=tmp, kills flags |
150 | .macro Limit reg |
7a93adeb |
151 | add r3, lr, \reg, asr #15 |
4f265db7 |
152 | bics r3, r3, #1 @ in non-overflow conditions r3 is 0 or 1 |
153 | movne \reg, #0x8000 |
7a93adeb |
154 | subpl \reg, \reg, #1 |
4f265db7 |
155 | .endm |
156 | |
157 | |
158 | @ limit and shift up by 16 |
159 | @ reg=int_sample, lr=1, r3=tmp, kills flags |
160 | .macro Limitsh reg |
161 | @ movs r4, r3, asr #16 |
162 | @ cmnne r4, #1 |
163 | @ beq c32_16_no_overflow |
164 | @ tst r4, r4 |
165 | @ mov r3, #0x8000 |
166 | @ subpl r3, r3, #1 |
167 | |
7a93adeb |
168 | add r3, lr, \reg, asr #15 |
4f265db7 |
169 | bics r3, r3, #1 @ in non-overflow conditions r3 is 0 or 1 |
170 | moveq \reg, \reg, lsl #16 |
171 | movne \reg, #0x80000000 |
7a93adeb |
172 | subpl \reg, \reg, #0x00010000 |
4f265db7 |
173 | .endm |
174 | |
175 | |
176 | @ mix 32bit audio (with 16bits really used, upper bits indicate overflow) with normal 16 bit audio with left channel only |
177 | @ warning: this function assumes dest is word aligned |
178 | .global mix_32_to_16l_stereo @ short *dest, int *src, int count |
179 | |
180 | mix_32_to_16l_stereo: |
181 | stmfd sp!, {r4-r8,lr} |
182 | |
183 | mov lr, #1 |
184 | |
185 | mov r2, r2, lsl #1 |
186 | subs r2, r2, #4 |
187 | bmi m32_16l_st_end |
188 | |
189 | m32_16l_st_loop: |
190 | ldmia r0, {r8,r12} |
191 | ldmia r1!, {r4-r7} |
192 | mov r8, r8, lsl #16 |
193 | mov r12,r12,lsl #16 |
194 | add r4, r4, r8, asr #16 |
195 | add r5, r5, r8, asr #16 |
196 | add r6, r6, r12,asr #16 |
197 | add r7, r7, r12,asr #16 |
198 | Limitsh r4 |
199 | Limitsh r5 |
200 | Limitsh r6 |
201 | Limitsh r7 |
202 | subs r2, r2, #4 |
203 | orr r4, r5, r4, lsr #16 |
204 | orr r5, r7, r6, lsr #16 |
205 | stmia r0!, {r4,r5} |
206 | bpl m32_16l_st_loop |
207 | |
208 | m32_16l_st_end: |
209 | @ check for remaining bytes to convert |
210 | tst r2, #2 |
211 | beq m32_16l_st_no_unal2 |
212 | ldrsh r6, [r0] |
213 | ldmia r1!,{r4,r5} |
214 | add r4, r4, r6 |
215 | add r5, r5, r6 |
216 | Limitsh r4 |
217 | Limitsh r5 |
218 | orr r4, r5, r4, lsr #16 |
219 | str r4, [r0], #4 |
220 | |
221 | m32_16l_st_no_unal2: |
222 | ldmfd sp!, {r4-r8,lr} |
223 | bx lr |
224 | |
225 | |
226 | @ mix 32bit audio (with 16bits really used, upper bits indicate overflow) with normal 16 bit audio (for mono sound) |
227 | .global mix_32_to_16_mono @ short *dest, int *src, int count |
228 | |
229 | mix_32_to_16_mono: |
230 | stmfd sp!, {r4-r8,lr} |
231 | |
232 | mov lr, #1 |
233 | |
234 | @ check if dest is word aligned |
235 | tst r0, #2 |
236 | beq m32_16_mo_no_unalw |
7a93adeb |
237 | ldrsh r5, [r0] |
4f265db7 |
238 | ldr r4, [r1], #4 |
239 | sub r2, r2, #1 |
240 | add r4, r4, r5 |
241 | Limit r4 |
242 | strh r4, [r0], #2 |
243 | |
244 | m32_16_mo_no_unalw: |
245 | subs r2, r2, #4 |
246 | bmi m32_16_mo_end |
247 | |
248 | m32_16_mo_loop: |
249 | ldmia r0, {r8,r12} |
250 | ldmia r1!, {r4-r7} |
251 | add r5, r5, r8, asr #16 |
252 | mov r8, r8, lsl #16 |
253 | add r4, r4, r8, asr #16 |
254 | add r7, r7, r12,asr #16 |
255 | mov r12,r12,lsl #16 |
256 | add r6, r6, r12,asr #16 |
257 | Limitsh r4 |
258 | Limitsh r5 |
259 | Limitsh r6 |
260 | Limitsh r7 |
261 | subs r2, r2, #4 |
262 | orr r4, r5, r4, lsr #16 |
263 | orr r5, r7, r6, lsr #16 |
264 | stmia r0!, {r4,r5} |
265 | bpl m32_16_mo_loop |
266 | |
267 | m32_16_mo_end: |
268 | @ check for remaining bytes to convert |
269 | tst r2, #2 |
270 | beq m32_16_mo_no_unal2 |
271 | ldr r6, [r0] |
272 | ldmia r1!,{r4,r5} |
273 | add r5, r5, r6, asr #16 |
274 | mov r6, r6, lsl #16 |
275 | add r4, r4, r6, asr #16 |
276 | Limitsh r4 |
277 | Limitsh r5 |
278 | orr r4, r5, r4, lsr #16 |
279 | str r4, [r0], #4 |
280 | |
281 | m32_16_mo_no_unal2: |
282 | tst r2, #1 |
283 | ldmeqfd sp!, {r4-r8,pc} |
7a93adeb |
284 | ldrsh r5, [r0] |
4f265db7 |
285 | ldr r4, [r1], #4 |
286 | add r4, r4, r5 |
287 | Limit r4 |
288 | strh r4, [r0], #2 |
289 | |
290 | ldmfd sp!, {r4-r8,lr} |
291 | bx lr |
292 | |