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