added handling for bad sram headers
[picodrive.git] / Pico / sound / mix.s
CommitLineData
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
10mix_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*/
21m16_32_mo_unalw:
22 subs r2, r2, #4
23 bmi m16_32_end
24
25m16_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
38m16_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
48m16_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
63mix_16h_to_32_s1:
64 stmfd sp!, {r4-r6,lr}
65
66 subs r2, r2, #4
67 bmi m16_32_s1_end
68
69m16_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
83m16_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
93m16_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
108mix_16h_to_32_s2:
109 stmfd sp!, {r4-r6,lr}
110
111 subs r2, r2, #4
112 bmi m16_32_s2_end
113
114m16_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
128m16_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
138m16_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
183mix_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
192m32_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
211m32_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
224m32_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
232mix_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
247m32_16_mo_no_unalw:
248 subs r2, r2, #4
249 bmi m32_16_mo_end
250
251m32_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
270m32_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
284m32_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