diff options
author | Dave Hooper <dave@beermex.com> | 2010-02-21 15:36:35 +0000 |
---|---|---|
committer | Dave Hooper <dave@beermex.com> | 2010-02-21 15:36:35 +0000 |
commit | a3068ca8639d2fe3dd69fcfa3ee7276fc86a8735 (patch) | |
tree | a07ffcf85083502ab51b82fbafa4a62f4099f592 /apps/codecs | |
parent | dafcd1470acaced405fa1a67d008aa1b68d1b6dd (diff) | |
download | rockbox-a3068ca8639d2fe3dd69fcfa3ee7276fc86a8735.tar.gz rockbox-a3068ca8639d2fe3dd69fcfa3ee7276fc86a8735.zip |
Unroll and optimise channel coupling for arm gives 0.6Mhz speed for vorbis on pp(ipod video)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24808 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs')
-rw-r--r-- | apps/codecs/libtremor/mapping0.c | 91 |
1 files changed, 68 insertions, 23 deletions
diff --git a/apps/codecs/libtremor/mapping0.c b/apps/codecs/libtremor/mapping0.c index bd0e0322fe..13a8d75aef 100644 --- a/apps/codecs/libtremor/mapping0.c +++ b/apps/codecs/libtremor/mapping0.c | |||
@@ -178,7 +178,73 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb) | |||
178 | return(NULL); | 178 | return(NULL); |
179 | } | 179 | } |
180 | 180 | ||
181 | // static int seq = 0; | 181 | #ifdef CPU_ARM |
182 | #define MAGANG( _mag, _ang )\ | ||
183 | {\ | ||
184 | register int temp;\ | ||
185 | asm( "cmp %[mag], #0\n\t"\ | ||
186 | "cmpgt %[ang], #0\n\t"\ | ||
187 | "subgt %[temp], %[mag], %[ang]\n\t"\ | ||
188 | "bgt 1f\n\t"\ | ||
189 | "cmp %[mag], #0\n\t"\ | ||
190 | "cmple %[ang], #0\n\t"\ | ||
191 | "addgt %[temp], %[mag], %[ang]\n\t"\ | ||
192 | "suble %[temp], %[mag], %[ang]\n\t"\ | ||
193 | "1: cmp %[ang], #0\n\t"\ | ||
194 | "movle %[ang], %[mag]\n\t"\ | ||
195 | "movle %[mag], %[temp]\n\t"\ | ||
196 | "movgt %[ang], %[temp]\n\t"\ | ||
197 | : [mag] "+r" ( ( _mag ) ), [ang] "+r" ( ( _ang ) ), [temp] "=&r" (temp)\ | ||
198 | :\ | ||
199 | : "cc" );\ | ||
200 | } | ||
201 | |||
202 | static inline void channel_couple(ogg_int32_t *pcmM, ogg_int32_t *pcmA, int n) | ||
203 | { | ||
204 | ogg_int32_t * const pcmMend = pcmM + n/2; | ||
205 | while(LIKELY(pcmM < pcmMend)) | ||
206 | { | ||
207 | register int M0 asm("r2"),M1 asm("r3"),M2 asm("r4"),M3 asm("r5"); | ||
208 | register int A0 asm("r6"),A1 asm("r7"),A2 asm("r8"),A3 asm("r9"); | ||
209 | asm volatile( "ldmia %[pcmM], {%[M0], %[M1], %[M2], %[M3]}\n\t" | ||
210 | "ldmia %[pcmA], {%[A0], %[A1], %[A2], %[A3]}\n\t" | ||
211 | : [M0] "=r" (M0), [M1] "=r" (M1), [M2] "=r" (M2), [M3] "=r" (M3), | ||
212 | [A0] "=r" (A0), [A1] "=r" (A1), [A2] "=r" (A2), [A3] "=r" (A3) | ||
213 | : [pcmM] "r" (pcmM), [pcmA] "r" (pcmA) ); | ||
214 | MAGANG( M0, A0 ); | ||
215 | MAGANG( M1, A1 ); | ||
216 | MAGANG( M2, A2 ); | ||
217 | MAGANG( M3, A3 ); | ||
218 | asm volatile( "stmia %[pcmM]!, {%[M0], %[M1], %[M2], %[M3]}\n\t" | ||
219 | "stmia %[pcmA]!, {%[A0], %[A1], %[A2], %[A3]}\n\t" | ||
220 | : [pcmM] "+r" (pcmM), [pcmA] "+r" (pcmA) | ||
221 | : [M0] "r" (M0), [M1] "r" (M1), [M2] "r" (M2), [M3] "r" (M3), | ||
222 | [A0] "r" (A0), [A1] "r" (A1), [A2] "r" (A2), [A3] "r" (A3) ); | ||
223 | } | ||
224 | } | ||
225 | #else | ||
226 | static inline void channel_couple(ogg_int32_t *pcmM, ogg_int32_t *pcmA, int n) | ||
227 | { | ||
228 | int j; | ||
229 | for(j=0;j<n/2;j++){ | ||
230 | ogg_int32_t mag = pcmM[j], ang = pcmA[j]; | ||
231 | if(mag>0) | ||
232 | if(ang>0) | ||
233 | pcmA[j]=mag-ang; | ||
234 | else{ | ||
235 | pcmA[j]=mag; | ||
236 | pcmM[j]=mag+ang; | ||
237 | } | ||
238 | else | ||
239 | if(ang>0) | ||
240 | pcmA[j]=mag+ang; | ||
241 | else{ | ||
242 | pcmA[j]=mag; | ||
243 | pcmM[j]=mag-ang; | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | #endif | ||
182 | 248 | ||
183 | static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){ | 249 | static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){ |
184 | vorbis_dsp_state *vd=vb->vd; | 250 | vorbis_dsp_state *vd=vb->vd; |
@@ -249,28 +315,7 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){ | |||
249 | for(i=info->coupling_steps-1;i>=0;i--){ | 315 | for(i=info->coupling_steps-1;i>=0;i--){ |
250 | ogg_int32_t *pcmM=vb->pcm[info->coupling_mag[i]]; | 316 | ogg_int32_t *pcmM=vb->pcm[info->coupling_mag[i]]; |
251 | ogg_int32_t *pcmA=vb->pcm[info->coupling_ang[i]]; | 317 | ogg_int32_t *pcmA=vb->pcm[info->coupling_ang[i]]; |
252 | 318 | channel_couple(pcmM,pcmA,n); | |
253 | for(j=0;j<n/2;j++){ | ||
254 | ogg_int32_t mag=pcmM[j]; | ||
255 | ogg_int32_t ang=pcmA[j]; | ||
256 | |||
257 | if(mag>0) | ||
258 | if(ang>0){ | ||
259 | pcmM[j]=mag; | ||
260 | pcmA[j]=mag-ang; | ||
261 | }else{ | ||
262 | pcmA[j]=mag; | ||
263 | pcmM[j]=mag+ang; | ||
264 | } | ||
265 | else | ||
266 | if(ang>0){ | ||
267 | pcmM[j]=mag; | ||
268 | pcmA[j]=mag+ang; | ||
269 | }else{ | ||
270 | pcmA[j]=mag; | ||
271 | pcmM[j]=mag-ang; | ||
272 | } | ||
273 | } | ||
274 | } | 319 | } |
275 | 320 | ||
276 | //for(j=0;j<vi->channels;j++) | 321 | //for(j=0;j<vi->channels;j++) |